Changeset 104651 in webkit


Ignore:
Timestamp:
Jan 10, 2012 4:42:11 PM (12 years ago)
Author:
ostapenko.viatcheslav@nokia.com
Message:

[Qt][WK2]REGRESSION(r102435): It made tst_QQuickWebView::show() crash
https://bugs.webkit.org/show_bug.cgi?id=74176

Reviewed by Noam Rosenthal.

Source/WebCore:

Replaces static global GL resource holder with holder shared between
TextureMapperGL instances created on the same GL context. Also adds
deallocation of GL resources when last TextureMapperGL instance on the
current GL context gets deleted.

Tested by multipleWebViewWindows and multipleWebViews Qt WK2 API tests.

  • platform/graphics/opengl/TextureMapperGL.cpp:

(WebCore::TextureMapperGLData::SharedGLData::getCurrentGLContext):
(WebCore::TextureMapperGLData::SharedGLData::glContextDataMap):
(WebCore::TextureMapperGLData::SharedGLData::currentSharedGLData):
(WebCore::TextureMapperGLData::SharedGLData::ProgramInfo::ProgramInfo):
(WebCore::TextureMapperGLData::SharedGLData::createShaderProgram):
(WebCore::TextureMapperGLData::SharedGLData::deleteShaderProgram):
(WebCore::TextureMapperGLData::SharedGLData::SharedGLData):
(WebCore::TextureMapperGLData::SharedGLData::~SharedGLData):
(WebCore::TextureMapperGLData::sharedGLData):
(WebCore::TextureMapperGLData::TextureMapperGLData):
(WebCore::TextureMapperGLData::SharedGLData::initializeShaders):
(WebCore::TextureMapperGL::beginPainting):
(WebCore::TextureMapperGL::drawTexture):
(WebCore::BitmapTextureGL::bind):
(WebCore::TextureMapperGL::bindSurface):
(WebCore::TextureMapperGL::beginClip):
(WebCore::TextureMapperGL::endClip):

  • platform/graphics/opengl/TextureMapperGL.h:

Source/WebKit2:

Check texture mapper exists already in ensureRootLayer to avoid recrecation.
Check if root layer was deleted already in purgeGLResources.
Added multipleWebViewWindows and multipleWebViews API tests.

  • UIProcess/API/qt/tests/qquickwebview/tst_qquickwebview.cpp:

(tst_QQuickWebView::multipleWebViewWindows):
(tst_QQuickWebView::multipleWebViews):

  • UIProcess/qt/LayerTreeHostProxyQt.cpp:

(WebKit::LayerTreeHostProxy::ensureRootLayer):
(WebKit::LayerTreeHostProxy::purgeGLResources):

Location:
trunk/Source
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r104647 r104651  
     12012-01-10  Viatcheslav Ostapenko  <ostapenko.viatcheslav@nokia.com>
     2
     3        [Qt][WK2]REGRESSION(r102435): It made tst_QQuickWebView::show() crash
     4        https://bugs.webkit.org/show_bug.cgi?id=74176
     5
     6        Reviewed by Noam Rosenthal.
     7
     8        Replaces static global GL resource holder with holder shared between
     9        TextureMapperGL instances created on the same GL context. Also adds
     10        deallocation of GL resources when last TextureMapperGL instance on the
     11        current GL context gets deleted.
     12
     13        Tested by multipleWebViewWindows and multipleWebViews Qt WK2 API tests.
     14
     15        * platform/graphics/opengl/TextureMapperGL.cpp:
     16        (WebCore::TextureMapperGLData::SharedGLData::getCurrentGLContext):
     17        (WebCore::TextureMapperGLData::SharedGLData::glContextDataMap):
     18        (WebCore::TextureMapperGLData::SharedGLData::currentSharedGLData):
     19        (WebCore::TextureMapperGLData::SharedGLData::ProgramInfo::ProgramInfo):
     20        (WebCore::TextureMapperGLData::SharedGLData::createShaderProgram):
     21        (WebCore::TextureMapperGLData::SharedGLData::deleteShaderProgram):
     22        (WebCore::TextureMapperGLData::SharedGLData::SharedGLData):
     23        (WebCore::TextureMapperGLData::SharedGLData::~SharedGLData):
     24        (WebCore::TextureMapperGLData::sharedGLData):
     25        (WebCore::TextureMapperGLData::TextureMapperGLData):
     26        (WebCore::TextureMapperGLData::SharedGLData::initializeShaders):
     27        (WebCore::TextureMapperGL::beginPainting):
     28        (WebCore::TextureMapperGL::drawTexture):
     29        (WebCore::BitmapTextureGL::bind):
     30        (WebCore::TextureMapperGL::bindSurface):
     31        (WebCore::TextureMapperGL::beginClip):
     32        (WebCore::TextureMapperGL::endClip):
     33        * platform/graphics/opengl/TextureMapperGL.h:
     34
    1352012-01-10  Simon Fraser  <simon.fraser@apple.com>
    236
  • trunk/Source/WebCore/platform/graphics/opengl/TextureMapperGL.cpp

    r104255 r104651  
    4040#else
    4141#include <GL/gl.h>
     42#endif
     43
     44#if defined(TEXMAP_OPENGL_ES_2)
     45#include <EGL/egl.h>
     46#elif OS(WINDOWS)
     47#include <windows.h>
     48#elif OS(MAC_OS_X)
     49#include <AGL/agl.h>
     50#elif defined(XP_UNIX)
     51#include <GL/glx.h>
    4252#endif
    4353
     
    104114
    105115struct TextureMapperGLData {
    106     static struct GlobalGLData {
     116    struct SharedGLData : public RefCounted<SharedGLData> {
     117#if defined(TEXMAP_OPENGL_ES_2)
     118        typedef EGLContext GLContext;
     119        static GLContext getCurrentGLContext()
     120        {
     121            return eglGetCurrentContext();
     122        }
     123#elif OS(WINDOWS)
     124        typedef HGLRC GLContext;
     125        static GLContext getCurrentGLContext()
     126        {
     127            return wglGetCurrentContext();
     128        }
     129#elif OS(MAC_OS_X)
     130        typedef AGLContext GLContext;
     131        static GLContext getCurrentGLContext()
     132        {
     133            return aglGetCurrentContext();
     134        }
     135#elif defined(XP_UNIX)
     136        typedef GLXContext GLContext;
     137        static GLContext getCurrentGLContext()
     138        {
     139            return glXGetCurrentContext();
     140        }
     141#else
     142        // Default implementation for unknown opengl.
     143        // Returns always increasing number and disables GL context data sharing.
     144        typedef unsigned int GLContext;
     145        static GLContext getCurrentGLContext()
     146        {
     147            static GLContext dummyContextCounter = 0;
     148            return ++dummyContextCounter;
     149        }
     150
     151#endif
     152
     153        typedef HashMap<GLContext, SharedGLData*> GLContextDataMap;
     154        static GLContextDataMap& glContextDataMap()
     155        {
     156            static GLContextDataMap map;
     157            return map;
     158        }
     159
     160        static PassRefPtr<SharedGLData> currentSharedGLData()
     161        {
     162            GLContext currentGLConext = getCurrentGLContext();
     163            GLContextDataMap::iterator it = glContextDataMap().find(currentGLConext);
     164            if (it != glContextDataMap().end())
     165                return it->second;
     166
     167            return adoptRef(new SharedGLData(getCurrentGLContext()));
     168        }
     169
    107170        enum ShaderProgramIndex {
    108171            NoProgram = -1,
     
    129192            GLuint vertexAttrib;
    130193            GLint vars[VariableCount];
     194            GLuint vertexShader;
     195            GLuint fragmentShader;
     196            ProgramInfo() : id(0) { }
    131197        };
    132198
     
    150216            programs[index].vertexAttrib = glGetAttribLocation(programID, "InVertex");
    151217            programs[index].id = programID;
    152         }
     218            programs[index].vertexShader = vertexShader;
     219            programs[index].fragmentShader = fragmentShader;
     220        }
     221
     222        void deleteShaderProgram(ShaderProgramIndex index)
     223        {
     224            ProgramInfo& programInfo = programs[index];
     225            GLuint programID = programInfo.id;
     226            if (!programID)
     227                return;
     228
     229            GL_CMD(glDetachShader(programID, programInfo.vertexShader))
     230            GL_CMD(glDeleteShader(programInfo.vertexShader))
     231            GL_CMD(glDetachShader(programID, programInfo.fragmentShader))
     232            GL_CMD(glDeleteShader(programInfo.fragmentShader))
     233            GL_CMD(glDeleteProgram(programID))
     234        }
     235
     236        void initializeShaders();
    153237
    154238        ProgramInfo programs[ProgramCount];
     
    156240        int stencilIndex;
    157241
    158         GlobalGLData()
    159             : stencilIndex(1)
    160         { }
    161     } globalGLData;
     242        SharedGLData(GLContext glContext) : stencilIndex(1)
     243        {
     244            glContextDataMap().add(glContext, this);
     245            initializeShaders();
     246        }
     247
     248        ~SharedGLData()
     249        {
     250            for (int i = SimpleProgram; i < ProgramCount; ++i)
     251                deleteShaderProgram(ShaderProgramIndex(i));
     252
     253            GLContextDataMap::const_iterator end = glContextDataMap().end();
     254            GLContextDataMap::iterator it;
     255            for (it = glContextDataMap().begin(); it != end; ++it) {
     256                if (it->second == this)
     257                    break;
     258            }
     259
     260            ASSERT(it != end);
     261            glContextDataMap().remove(it);
     262        }
     263
     264    };
    162265
    163266    struct DirectlyCompositedImageRepository {
     
    212315    } directlyCompositedImages;
    213316
     317    SharedGLData& sharedGLData() const
     318    {
     319        return *(m_sharedGLData.get());
     320    }
     321
    214322    TextureMapperGLData()
    215         : currentProgram(TextureMapperGLData::GlobalGLData::NoProgram)
     323        : currentProgram(SharedGLData::NoProgram)
     324        , m_sharedGLData(TextureMapperGLData::SharedGLData::currentSharedGLData())
    216325    { }
    217326
     
    219328    int currentProgram;
    220329    int previousProgram;
     330    RefPtr<SharedGLData> m_sharedGLData;
    221331};
    222 
    223 TextureMapperGLData::GlobalGLData TextureMapperGLData::globalGLData;
    224332
    225333class BitmapTextureGL : public BitmapTexture {
     
    290398
    291399#define TEXMAP_GET_SHADER_VAR_LOCATION(prog, var) \
    292     if (TextureMapperGLData::globalGLData.getUniformLocation(TextureMapperGLData::globalGLData.prog##Program, TextureMapperGLData::globalGLData.var##Variable, #var) < 0) \
     400    if (getUniformLocation(prog##Program, var##Variable, #var) < 0) \
    293401            LOG_ERROR("Couldn't find variable "#var" in program "#prog"\n");
    294402
    295403#define TEXMAP_BUILD_SHADER(program) \
    296     TextureMapperGLData::globalGLData.createShaderProgram(vertexShaderSource##program, fragmentShaderSource##program, TextureMapperGLData::globalGLData.program##Program);
     404    createShaderProgram(vertexShaderSource##program, fragmentShaderSource##program, program##Program);
    297405
    298406TextureMapperGL::TextureMapperGL()
     
    302410}
    303411
    304 void TextureMapperGL::initializeShaders()
    305 {
    306     static bool shadersCompiled = false;
    307     if (shadersCompiled)
    308         return;
    309     shadersCompiled = true;
     412void TextureMapperGLData::SharedGLData::initializeShaders()
     413{
    310414#ifndef TEXMAP_OPENGL_ES_2
    311415#define OES2_PRECISION_DEFINITIONS \
     
    322426                                OES2_FRAGMENT_SHADER_DEFAULT_PRECISION\
    323427                                #src
     428
     429    if (!initializeOpenGLShims())
     430        return;
    324431
    325432    const char* fragmentShaderSourceOpacityAndMask =
     
    427534    bindSurface(0);
    428535#endif
    429     initializeShaders();
    430536}
    431537
     
    455561void TextureMapperGL::drawTexture(uint32_t texture, bool opaque, const FloatSize& relativeSize, const FloatRect& targetRect, const TransformationMatrix& modelViewMatrix, float opacity, const BitmapTexture* maskTexture, bool flip)
    456562{
    457     TextureMapperGLData::GlobalGLData::ShaderProgramIndex program;
     563    TextureMapperGLData::SharedGLData::ShaderProgramIndex program;
    458564    if (maskTexture)
    459         program = TextureMapperGLData::GlobalGLData::OpacityAndMaskProgram;
     565        program = TextureMapperGLData::SharedGLData::OpacityAndMaskProgram;
    460566    else
    461         program = TextureMapperGLData::GlobalGLData::SimpleProgram;
    462 
    463     const TextureMapperGLData::GlobalGLData::ProgramInfo& programInfo = data().globalGLData.programs[program];
     567        program = TextureMapperGLData::SharedGLData::SimpleProgram;
     568
     569    const TextureMapperGLData::SharedGLData::ProgramInfo& programInfo = data().sharedGLData().programs[program];
    464570    GL_CMD(glUseProgram(programInfo.id))
    465571    data().currentProgram = program;
     
    488594                                     0, flip ? relativeSize.height() : 0, 0, 1};
    489595
    490     GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::GlobalGLData::InMatrixVariable], 1, GL_FALSE, m4))
    491     GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::GlobalGLData::InSourceMatrixVariable], 1, GL_FALSE, m4src))
    492     GL_CMD(glUniform1i(programInfo.vars[TextureMapperGLData::GlobalGLData::SourceTextureVariable], 0))
    493     GL_CMD(glUniform1f(programInfo.vars[TextureMapperGLData::GlobalGLData::OpacityVariable], opacity))
     596    GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::SharedGLData::InMatrixVariable], 1, GL_FALSE, m4))
     597    GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::SharedGLData::InSourceMatrixVariable], 1, GL_FALSE, m4src))
     598    GL_CMD(glUniform1i(programInfo.vars[TextureMapperGLData::SharedGLData::SourceTextureVariable], 0))
     599    GL_CMD(glUniform1f(programInfo.vars[TextureMapperGLData::SharedGLData::OpacityVariable], opacity))
    494600
    495601    if (maskTexture && maskTexture->isValid()) {
     
    501607                                         0, 0, 1, 0,
    502608                                         0, 0, 0, 1};
    503         GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::GlobalGLData::InMaskMatrixVariable], 1, GL_FALSE, m4mask));
    504         GL_CMD(glUniform1i(programInfo.vars[TextureMapperGLData::GlobalGLData::MaskTextureVariable], 1))
     609        GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::SharedGLData::InMaskMatrixVariable], 1, GL_FALSE, m4mask));
     610        GL_CMD(glUniform1i(programInfo.vars[TextureMapperGLData::SharedGLData::MaskTextureVariable], 1))
    505611        GL_CMD(glActiveTexture(GL_TEXTURE0))
    506612    }
     
    671777void BitmapTextureGL::bind()
    672778{
    673     int& stencilIndex = TextureMapperGLData::globalGLData.stencilIndex;
     779    int& stencilIndex = m_textureMapper->data().sharedGLData().stencilIndex;
    674780    if (m_surfaceNeedsReset || !m_fbo) {
    675781        if (!m_fbo)
     
    744850        GL_CMD(glBindFramebuffer(GL_FRAMEBUFFER, 0))
    745851        data().projectionMatrix = createProjectionMatrix(viewportSize(), true).multiply(transform());
    746         GL_CMD(glStencilFunc(data().globalGLData.stencilIndex > 1 ? GL_EQUAL : GL_ALWAYS, data().globalGLData.stencilIndex - 1, data().globalGLData.stencilIndex - 1))
     852        GL_CMD(glStencilFunc(data().sharedGLData().stencilIndex > 1 ? GL_EQUAL : GL_ALWAYS, data().sharedGLData().stencilIndex - 1, data().sharedGLData().stencilIndex - 1))
    747853        GL_CMD(glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP))
    748854        GL_CMD(glViewport(0, 0, viewportSize().width(), viewportSize().height()))
     
    755861void TextureMapperGL::beginClip(const TransformationMatrix& modelViewMatrix, const FloatRect& targetRect)
    756862{
    757     TextureMapperGLData::GlobalGLData::ShaderProgramIndex program = TextureMapperGLData::GlobalGLData::ClipProgram;
    758     const TextureMapperGLData::GlobalGLData::ProgramInfo& programInfo = data().globalGLData.programs[program];
     863    TextureMapperGLData::SharedGLData::ShaderProgramIndex program = TextureMapperGLData::SharedGLData::ClipProgram;
     864    const TextureMapperGLData::SharedGLData::ProgramInfo& programInfo = data().sharedGLData().programs[program];
    759865    GL_CMD(glUseProgram(programInfo.id))
    760866    GL_CMD(glEnableVertexAttribArray(programInfo.vertexAttrib))
     
    776882    };
    777883
    778     int& stencilIndex = data().globalGLData.stencilIndex;
    779 
    780     GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::GlobalGLData::InMatrixVariable], 1, GL_FALSE, m4))
     884    int& stencilIndex = data().sharedGLData().stencilIndex;
     885
     886    GL_CMD(glUniformMatrix4fv(programInfo.vars[TextureMapperGLData::SharedGLData::InMatrixVariable], 1, GL_FALSE, m4))
    781887    GL_CMD(glEnable(GL_STENCIL_TEST))
    782888    GL_CMD(glStencilFunc(GL_NEVER, stencilIndex, stencilIndex))
     
    792898void TextureMapperGL::endClip()
    793899{
    794     data().globalGLData.stencilIndex >>= 1;
    795     glStencilFunc(data().globalGLData.stencilIndex > 1 ? GL_EQUAL : GL_ALWAYS, data().globalGLData.stencilIndex - 1, data().globalGLData.stencilIndex - 1);
     900    data().sharedGLData().stencilIndex >>= 1;
     901    glStencilFunc(data().sharedGLData().stencilIndex > 1 ? GL_EQUAL : GL_ALWAYS, data().sharedGLData().stencilIndex - 1, data().sharedGLData().stencilIndex - 1);
    796902}
    797903
  • trunk/Source/WebCore/platform/graphics/opengl/TextureMapperGL.h

    r97703 r104651  
    5656
    5757private:
    58     void initializeShaders();
    5958    inline TextureMapperGLData& data() { return *m_data; }
    6059    TextureMapperGLData* m_data;
  • trunk/Source/WebKit2/ChangeLog

    r104635 r104651  
     12012-01-10  Viatcheslav Ostapenko  <ostapenko.viatcheslav@nokia.com>
     2
     3        [Qt][WK2]REGRESSION(r102435): It made tst_QQuickWebView::show() crash
     4        https://bugs.webkit.org/show_bug.cgi?id=74176
     5
     6        Reviewed by Noam Rosenthal.
     7
     8        Check texture mapper exists already in ensureRootLayer to avoid recrecation.
     9        Check if root layer was deleted already in purgeGLResources.
     10        Added multipleWebViewWindows and multipleWebViews API tests.
     11
     12        * UIProcess/API/qt/tests/qquickwebview/tst_qquickwebview.cpp:
     13        (tst_QQuickWebView::multipleWebViewWindows):
     14        (tst_QQuickWebView::multipleWebViews):
     15        * UIProcess/qt/LayerTreeHostProxyQt.cpp:
     16        (WebKit::LayerTreeHostProxy::ensureRootLayer):
     17        (WebKit::LayerTreeHostProxy::purgeGLResources):
     18
    1192012-01-10  Ryosuke Niwa  <rniwa@webkit.org>
    220
  • trunk/Source/WebKit2/UIProcess/API/qt/tests/qquickwebview/tst_qquickwebview.cpp

    r104450 r104651  
    5252    void showWebView();
    5353    void removeFromCanvas();
     54    void multipleWebViewWindows();
     55    void multipleWebViews();
    5456
    5557private:
     
    271273}
    272274
     275void tst_QQuickWebView::multipleWebViewWindows()
     276{
     277    showWebView();
     278
     279    // This should not crash.
     280    QQuickWebView* webView1 = new QQuickWebView();
     281    QScopedPointer<TestWindow> window1(new TestWindow(webView1));
     282    QQuickWebView* webView2 = new QQuickWebView();
     283    QScopedPointer<TestWindow> window2(new TestWindow(webView2));
     284
     285    webView1->setSize(QSizeF(300, 400));
     286    webView1->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/scroll.html")));
     287    QVERIFY(waitForSignal(webView1, SIGNAL(loadSucceeded())));
     288    window1->show();
     289    webView1->setVisible(true);
     290
     291    webView2->setSize(QSizeF(300, 400));
     292    webView2->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html")));
     293    QVERIFY(waitForSignal(webView2, SIGNAL(loadSucceeded())));
     294    window2->show();
     295    webView2->setVisible(true);
     296    QTest::qWait(200);
     297}
     298
     299void tst_QQuickWebView::multipleWebViews()
     300{
     301    showWebView();
     302
     303    // This should not crash.
     304    QScopedPointer<QQuickWebView> webView1(new QQuickWebView());
     305    webView1->setParentItem(m_window->rootItem());
     306    QScopedPointer<QQuickWebView> webView2(new QQuickWebView());
     307    webView2->setParentItem(m_window->rootItem());
     308
     309    webView1->setSize(QSizeF(300, 400));
     310    webView1->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/scroll.html")));
     311    QVERIFY(waitForSignal(webView1.data(), SIGNAL(loadSucceeded())));
     312    webView1->setVisible(true);
     313
     314    webView2->setSize(QSizeF(300, 400));
     315    webView2->load(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "/html/basic_page.html")));
     316    QVERIFY(waitForSignal(webView2.data(), SIGNAL(loadSucceeded())));
     317    webView2->setVisible(true);
     318    QTest::qWait(200);
     319}
     320
    273321void tst_QQuickWebView::scrollRequest()
    274322{
  • trunk/Source/WebKit2/UIProcess/qt/LayerTreeHostProxyQt.cpp

    r102435 r104651  
    461461    // The root layer should not have zero size, or it would be optimized out.
    462462    m_rootLayer->setSize(FloatSize(1.0, 1.0));
    463     m_textureMapper = TextureMapperGL::create();
     463    if (!m_textureMapper)
     464        m_textureMapper = TextureMapperGL::create();
    464465    toTextureMapperNode(m_rootLayer.get())->setTextureMapper(m_textureMapper.get());
    465466}
     
    624625    TextureMapperNode* node = toTextureMapperNode(rootLayer());
    625626
    626     node->purgeNodeTexturesRecursive();
     627    if (node)
     628        node->purgeNodeTexturesRecursive();
     629
    627630    m_directlyCompositedImages.clear();
    628631
Note: See TracChangeset for help on using the changeset viewer.