[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

eric at webkit.org eric at webkit.org
Thu Apr 8 00:46:42 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit 3a7ff9c287463d39cbd22f04a4772c9dd9b5daa3
Author: eric at webkit.org <eric at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Tue Dec 22 23:00:20 2009 +0000

    2009-12-22  Kenneth Russell  <kbr at google.com>
    
            Reviewed by Eric Seidel.
    
            [Chromium] WebGL crashes intermittently on Linux
            https://bugs.webkit.org/show_bug.cgi?id=32845
    
            The dlclose'ing of libGL.so.1 and dlopen'ing of it each time a
            GraphicsContext3D was created was occasionally causing it to be
            re-mapped at a different base address. Since GLEW is not
            re-initialized every time, primarily for performance reasons, its
            cached function pointers were pointing to garbage. Stopped closing
            and re-opening libGL.so.1 each time; now it is loaded lazily, when
            the first 3D context is created. Also reused the X display
            connection since the GLX routines' correctness might hinge upon it
            not resulting in a change of GL implementation.
    
            * src/GraphicsContext3D.cpp:
            (WebCore::GraphicsContext3DInternal::GLConnection::chooseFBConfig):
            (WebCore::GraphicsContext3DInternal::GLConnection::createNewContext):
            (WebCore::GraphicsContext3DInternal::GLConnection::createPbuffer):
            (WebCore::GraphicsContext3DInternal::GLConnection::destroyPbuffer):
            (WebCore::GraphicsContext3DInternal::GLConnection::makeCurrent):
            (WebCore::GraphicsContext3DInternal::GLConnection::destroyContext):
            (WebCore::GraphicsContext3DInternal::GLConnection::getCurrentContext):
            (WebCore::GraphicsContext3DInternal::GLConnection::GLConnection):
            (WebCore::GraphicsContext3DInternal::GLConnection::tryLoad):
            (WebCore::GraphicsContext3DInternal::GLConnection::create):
            (WebCore::GraphicsContext3DInternal::GLConnection::~GLConnection):
            (WebCore::GraphicsContext3DInternal::GraphicsContext3DInternal):
            (WebCore::GraphicsContext3DInternal::~GraphicsContext3DInternal):
            (WebCore::GraphicsContext3DInternal::makeContextCurrent):
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@52504 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebKit/chromium/ChangeLog b/WebKit/chromium/ChangeLog
index 74e50d9..883abd5 100644
--- a/WebKit/chromium/ChangeLog
+++ b/WebKit/chromium/ChangeLog
@@ -1,3 +1,36 @@
+2009-12-22  Kenneth Russell  <kbr at google.com>
+
+        Reviewed by Eric Seidel.
+
+        [Chromium] WebGL crashes intermittently on Linux
+        https://bugs.webkit.org/show_bug.cgi?id=32845
+        
+        The dlclose'ing of libGL.so.1 and dlopen'ing of it each time a
+        GraphicsContext3D was created was occasionally causing it to be
+        re-mapped at a different base address. Since GLEW is not
+        re-initialized every time, primarily for performance reasons, its
+        cached function pointers were pointing to garbage. Stopped closing
+        and re-opening libGL.so.1 each time; now it is loaded lazily, when
+        the first 3D context is created. Also reused the X display
+        connection since the GLX routines' correctness might hinge upon it
+        not resulting in a change of GL implementation.
+
+        * src/GraphicsContext3D.cpp:
+        (WebCore::GraphicsContext3DInternal::GLConnection::chooseFBConfig):
+        (WebCore::GraphicsContext3DInternal::GLConnection::createNewContext):
+        (WebCore::GraphicsContext3DInternal::GLConnection::createPbuffer):
+        (WebCore::GraphicsContext3DInternal::GLConnection::destroyPbuffer):
+        (WebCore::GraphicsContext3DInternal::GLConnection::makeCurrent):
+        (WebCore::GraphicsContext3DInternal::GLConnection::destroyContext):
+        (WebCore::GraphicsContext3DInternal::GLConnection::getCurrentContext):
+        (WebCore::GraphicsContext3DInternal::GLConnection::GLConnection):
+        (WebCore::GraphicsContext3DInternal::GLConnection::tryLoad):
+        (WebCore::GraphicsContext3DInternal::GLConnection::create):
+        (WebCore::GraphicsContext3DInternal::GLConnection::~GLConnection):
+        (WebCore::GraphicsContext3DInternal::GraphicsContext3DInternal):
+        (WebCore::GraphicsContext3DInternal::~GraphicsContext3DInternal):
+        (WebCore::GraphicsContext3DInternal::makeContextCurrent):
+
 2009-12-22  Yaar Schnitman  <yaar at chromium.org>
 
         Reviewed by Darin Fisher.
diff --git a/WebKit/chromium/src/GraphicsContext3D.cpp b/WebKit/chromium/src/GraphicsContext3D.cpp
index 56b8333..557eb98 100644
--- a/WebKit/chromium/src/GraphicsContext3D.cpp
+++ b/WebKit/chromium/src/GraphicsContext3D.cpp
@@ -181,6 +181,7 @@ private:
     SkBitmap* m_resizingBitmap;
 #endif
 
+    static bool s_initializedGLEW;
 #if PLATFORM(WIN_OS)
     HWND  m_canvasWindow;
     HDC   m_canvasDC;
@@ -190,28 +191,167 @@ private:
     CGLContextObj m_contextObj;
     unsigned char* m_renderOutput;
 #elif PLATFORM(LINUX)
-    Display* m_display;
     GLXContext m_contextObj;
     GLXPbuffer m_pbuffer;
+
     // In order to avoid problems caused by linking against libGL, we
     // dynamically look up all the symbols we need.
     // http://code.google.com/p/chromium/issues/detail?id=16800
-    void* m_libGL;
-    PFNGLXCHOOSEFBCONFIGPROC m_glXChooseFBConfig;
-    PFNGLXCREATENEWCONTEXTPROC m_glXCreateNewContext;
-    PFNGLXCREATEPBUFFERPROC m_glXCreatePbuffer;
-    PFNGLXDESTROYPBUFFERPROC m_glXDestroyPbuffer;
-    typedef Bool (* PFNGLXMAKECURRENTPROC)(Display* dpy, GLXDrawable drawable, GLXContext ctx);
-    PFNGLXMAKECURRENTPROC m_glXMakeCurrent;
-    typedef void (* PFNGLXDESTROYCONTEXTPROC)(Display* dpy, GLXContext ctx);
-    PFNGLXDESTROYCONTEXTPROC m_glXDestroyContext;
-    typedef GLXContext (* PFNGLXGETCURRENTCONTEXTPROC)(void);
-    PFNGLXGETCURRENTCONTEXTPROC m_glXGetCurrentContext;
+    class GLConnection {
+      public:
+        ~GLConnection();
+
+        static GLConnection* create();
+
+        GLXFBConfig* chooseFBConfig(int screen, const int *attrib_list, int *nelements)
+        {
+            return m_glXChooseFBConfig(m_display, screen, attrib_list, nelements);
+        }
+
+        GLXContext createNewContext(GLXFBConfig config, int renderType, GLXContext shareList, Bool direct)
+        {
+            return m_glXCreateNewContext(m_display, config, renderType, shareList, direct);
+        }
+
+        GLXPbuffer createPbuffer(GLXFBConfig config, const int *attribList)
+        {
+            return m_glXCreatePbuffer(m_display, config, attribList);
+        }
+
+        void destroyPbuffer(GLXPbuffer pbuf)
+        {
+            m_glXDestroyPbuffer(m_display, pbuf);
+        }
+
+        Bool makeCurrent(GLXDrawable drawable, GLXContext ctx)
+        {
+            return m_glXMakeCurrent(m_display, drawable, ctx);
+        }
+
+        void destroyContext(GLXContext ctx)
+        {
+            m_glXDestroyContext(m_display, ctx);
+        }
+
+        GLXContext getCurrentContext()
+        {
+            return m_glXGetCurrentContext();
+        }
+
+      private:
+        Display* m_display;
+        void* m_libGL;
+        PFNGLXCHOOSEFBCONFIGPROC m_glXChooseFBConfig;
+        PFNGLXCREATENEWCONTEXTPROC m_glXCreateNewContext;
+        PFNGLXCREATEPBUFFERPROC m_glXCreatePbuffer;
+        PFNGLXDESTROYPBUFFERPROC m_glXDestroyPbuffer;
+        typedef Bool (* PFNGLXMAKECURRENTPROC)(Display* dpy, GLXDrawable drawable, GLXContext ctx);
+        PFNGLXMAKECURRENTPROC m_glXMakeCurrent;
+        typedef void (* PFNGLXDESTROYCONTEXTPROC)(Display* dpy, GLXContext ctx);
+        PFNGLXDESTROYCONTEXTPROC m_glXDestroyContext;
+        typedef GLXContext (* PFNGLXGETCURRENTCONTEXTPROC)(void);
+        PFNGLXGETCURRENTCONTEXTPROC m_glXGetCurrentContext;
+
+        GLConnection(Display* display,
+                     void* libGL,
+                     PFNGLXCHOOSEFBCONFIGPROC chooseFBConfig,
+                     PFNGLXCREATENEWCONTEXTPROC createNewContext,
+                     PFNGLXCREATEPBUFFERPROC createPbuffer,
+                     PFNGLXDESTROYPBUFFERPROC destroyPbuffer,
+                     PFNGLXMAKECURRENTPROC makeCurrent,
+                     PFNGLXDESTROYCONTEXTPROC destroyContext,
+                     PFNGLXGETCURRENTCONTEXTPROC getCurrentContext)
+            : m_libGL(libGL)
+            , m_display(display)
+            , m_glXChooseFBConfig(chooseFBConfig)
+            , m_glXCreateNewContext(createNewContext)
+            , m_glXCreatePbuffer(createPbuffer)
+            , m_glXDestroyPbuffer(destroyPbuffer)
+            , m_glXMakeCurrent(makeCurrent)
+            , m_glXDestroyContext(destroyContext)
+            , m_glXGetCurrentContext(getCurrentContext)
+        {
+        }
+
+        static void* tryLoad(const char* libName)
+        {
+            // We use RTLD_GLOBAL semantics so that GLEW initialization works;
+            // GLEW expects to be able to open the current process's handle
+            // and do dlsym's of GL entry points from there.
+            return dlopen(libName, RTLD_LAZY | RTLD_GLOBAL);
+        }
+    };
+
+    static GLConnection* s_gl;
 #else
     #error Must port GraphicsContext3D to your platform
 #endif
 };
 
+bool GraphicsContext3DInternal::s_initializedGLEW = false;
+#if PLATFORM(LINUX)
+GraphicsContext3DInternal::GLConnection* GraphicsContext3DInternal::s_gl = 0;
+#endif
+
+GraphicsContext3DInternal::GLConnection* GraphicsContext3DInternal::GLConnection::create()
+{
+    Display* dpy = XOpenDisplay(0);
+    if (!dpy) {
+        printf("GraphicsContext3D: error opening X display\n");
+        return 0;
+    }
+
+    void* libGL = 0;
+    const char* libNames[] = {
+        "/usr/lib/libGL.so.1",
+        "/usr/lib32/libGL.so.1",
+        "/usr/lib64/libGL.so.1",
+    };
+    for (int i = 0; i < sizeof(libNames) / sizeof(const char*); i++) {
+        libGL = tryLoad(libNames[i]);
+        if (libGL)
+            break;
+    }
+    if (!libGL) {
+        printf("GraphicsContext3D: error opening libGL.so.1\n");
+        printf("GraphicsContext3D: tried:\n");
+        for (int i = 0; i < sizeof(libNames) / sizeof(const char*); i++)
+            printf(" %s\n", libNames[i]);
+        return 0;
+    }
+
+    PFNGLXCHOOSEFBCONFIGPROC chooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC) dlsym(libGL, "glXChooseFBConfig");
+    PFNGLXCREATENEWCONTEXTPROC createNewContext = (PFNGLXCREATENEWCONTEXTPROC) dlsym(libGL, "glXCreateNewContext");
+    PFNGLXCREATEPBUFFERPROC createPbuffer = (PFNGLXCREATEPBUFFERPROC) dlsym(libGL, "glXCreatePbuffer");
+    PFNGLXDESTROYPBUFFERPROC destroyPbuffer = (PFNGLXDESTROYPBUFFERPROC) dlsym(libGL, "glXDestroyPbuffer");
+    PFNGLXMAKECURRENTPROC makeCurrent = (PFNGLXMAKECURRENTPROC) dlsym(libGL, "glXMakeCurrent");
+    PFNGLXDESTROYCONTEXTPROC destroyContext = (PFNGLXDESTROYCONTEXTPROC) dlsym(libGL, "glXDestroyContext");
+    PFNGLXGETCURRENTCONTEXTPROC getCurrentContext = (PFNGLXGETCURRENTCONTEXTPROC) dlsym(libGL, "glXGetCurrentContext");
+    if (!chooseFBConfig || !createNewContext || !createPbuffer
+        || !destroyPbuffer || !makeCurrent || !destroyContext
+        || !getCurrentContext) {
+        XCloseDisplay(dpy);
+        dlclose(libGL);
+        printf("GraphicsContext3D: error looking up bootstrapping entry points\n");
+        return 0;
+    }
+    return new GLConnection(dpy,
+                            libGL,
+                            chooseFBConfig,
+                            createNewContext,
+                            createPbuffer,
+                            destroyPbuffer,
+                            makeCurrent,
+                            destroyContext,
+                            getCurrentContext);
+}
+
+GraphicsContext3DInternal::GLConnection::~GLConnection()
+{
+    XCloseDisplay(m_display);
+    dlclose(m_libGL);
+}
+
 GraphicsContext3DInternal::VertexAttribPointerState::VertexAttribPointerState()
     : enabled(false)
     , buffer(0)
@@ -224,16 +364,6 @@ GraphicsContext3DInternal::VertexAttribPointerState::VertexAttribPointerState()
 {
 }
 
-#if PLATFORM(LINUX)
-static void* tryLoad(const char* libName)
-{
-    // We use RTLD_GLOBAL semantics so that GLEW initialization works;
-    // GLEW expects to be able to open the current process's handle
-    // and do dlsym's of GL entry points from there.
-    return dlopen(libName, RTLD_LAZY | RTLD_GLOBAL);
-}
-#endif
-
 GraphicsContext3DInternal::GraphicsContext3DInternal()
     : m_texture(0)
     , m_fbo(0)
@@ -255,16 +385,8 @@ GraphicsContext3DInternal::GraphicsContext3DInternal()
     , m_contextObj(0)
     , m_renderOutput(0)
 #elif PLATFORM(LINUX)
-    , m_display(0)
     , m_contextObj(0)
     , m_pbuffer(0)
-    , m_glXChooseFBConfig(0)
-    , m_glXCreateNewContext(0)
-    , m_glXCreatePbuffer(0)
-    , m_glXDestroyPbuffer(0)
-    , m_glXMakeCurrent(0)
-    , m_glXDestroyContext(0)
-    , m_glXGetCurrentContext(0)
 #else
 #error Must port to your platform
 #endif
@@ -382,42 +504,12 @@ GraphicsContext3DInternal::GraphicsContext3DInternal()
     m_pbuffer = pbuffer;
     m_contextObj = context;
 #elif PLATFORM(LINUX)
-    m_display = XOpenDisplay(0);
-    if (!m_display) {
-        printf("GraphicsContext3D: error opening X display\n");
-        return;
+    if (!s_gl) {
+        s_gl = GLConnection::create();
+        if (!s_gl)
+            return;
     }
 
-    const char* libNames[] = {
-        "/usr/lib/libGL.so.1",
-        "/usr/lib32/libGL.so.1",
-        "/usr/lib64/libGL.so.1",
-    };
-    for (int i = 0; i < sizeof(libNames) / sizeof(const char*); i++) {
-        m_libGL = tryLoad(libNames[i]);
-        if (m_libGL)
-            break;
-    }
-    if (!m_libGL) {
-        printf("GraphicsContext3D: error opening libGL.so.1\n");
-        printf("GraphicsContext3D: tried:");
-        for (int i = 0; i < sizeof(libNames) / sizeof(const char*); i++)
-            printf(" %s", libNames[i]);
-        return;
-    }
-    m_glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC) dlsym(m_libGL, "glXChooseFBConfig");
-    m_glXCreateNewContext = (PFNGLXCREATENEWCONTEXTPROC) dlsym(m_libGL, "glXCreateNewContext");
-    m_glXCreatePbuffer = (PFNGLXCREATEPBUFFERPROC) dlsym(m_libGL, "glXCreatePbuffer");
-    m_glXDestroyPbuffer = (PFNGLXDESTROYPBUFFERPROC) dlsym(m_libGL, "glXDestroyPbuffer");
-    m_glXMakeCurrent = (PFNGLXMAKECURRENTPROC) dlsym(m_libGL, "glXMakeCurrent");
-    m_glXDestroyContext = (PFNGLXDESTROYCONTEXTPROC) dlsym(m_libGL, "glXDestroyContext");
-    m_glXGetCurrentContext = (PFNGLXGETCURRENTCONTEXTPROC) dlsym(m_libGL, "glXGetCurrentContext");
-    if (!m_glXChooseFBConfig || !m_glXCreateNewContext || !m_glXCreatePbuffer
-        || !m_glXDestroyPbuffer || !m_glXMakeCurrent || !m_glXDestroyContext
-        || !m_glXGetCurrentContext) {
-        printf("GraphicsContext3D: error looking up bootstrapping entry points\n");
-        return;
-    }
     int configAttrs[] = {
         GLX_DRAWABLE_TYPE,
         GLX_PBUFFER_BIT,
@@ -428,7 +520,7 @@ GraphicsContext3DInternal::GraphicsContext3DInternal()
         0
     };
     int nelements = 0;
-    GLXFBConfig* config = m_glXChooseFBConfig(m_display, 0, configAttrs, &nelements);
+    GLXFBConfig* config = s_gl->chooseFBConfig(0, configAttrs, &nelements);
     if (!config) {
         printf("GraphicsContext3D: glXChooseFBConfig failed\n");
         return;
@@ -438,7 +530,7 @@ GraphicsContext3DInternal::GraphicsContext3DInternal()
         XFree(config);
         return;
     }
-    GLXContext context = m_glXCreateNewContext(m_display, config[0], GLX_RGBA_TYPE, 0, True);
+    GLXContext context = s_gl->createNewContext(config[0], GLX_RGBA_TYPE, 0, True);
     if (!context) {
         printf("GraphicsContext3D: glXCreateNewContext failed\n");
         XFree(config);
@@ -451,13 +543,13 @@ GraphicsContext3DInternal::GraphicsContext3DInternal()
         1,
         0
     };
-    GLXPbuffer pbuffer = m_glXCreatePbuffer(m_display, config[0], pbufferAttrs);
+    GLXPbuffer pbuffer = s_gl->createPbuffer(config[0], pbufferAttrs);
     XFree(config);
     if (!pbuffer) {
         printf("GraphicsContext3D: glxCreatePbuffer failed\n");
         return;
     }
-    if (!m_glXMakeCurrent(m_display, pbuffer, context)) {
+    if (!s_gl->makeCurrent(pbuffer, context)) {
         printf("GraphicsContext3D: glXMakeCurrent failed\n");
         return;
     }
@@ -467,8 +559,7 @@ GraphicsContext3DInternal::GraphicsContext3DInternal()
 #error Must port to your platform
 #endif
 
-    static bool initializedGLEW = false;
-    if (!initializedGLEW) {
+    if (!s_initializedGLEW) {
         // Initialize GLEW and check for GL 2.0 support by the drivers.
         GLenum glewInitResult = glewInit();
         if (glewInitResult != GLEW_OK) {
@@ -479,7 +570,7 @@ GraphicsContext3DInternal::GraphicsContext3DInternal()
             printf("GraphicsContext3D: OpenGL 2.0 not supported\n");
             return;
         }
-        initializedGLEW = true;
+        s_initializedGLEW = true;
     }
 }
 
@@ -511,11 +602,9 @@ GraphicsContext3DInternal::~GraphicsContext3DInternal()
     if (m_renderOutput)
         delete[] m_renderOutput;
 #elif PLATFORM(LINUX)
-    m_glXMakeCurrent(m_display, 0, 0);
-    m_glXDestroyContext(m_display, m_contextObj);
-    m_glXDestroyPbuffer(m_display, m_pbuffer);
-    XCloseDisplay(m_display);
-    dlclose(m_libGL);
+    s_gl->makeCurrent(0, 0);
+    s_gl->destroyContext(m_contextObj);
+    s_gl->destroyPbuffer(m_pbuffer);
 #else
 #error Must port to your platform
 #endif
@@ -533,8 +622,8 @@ bool GraphicsContext3DInternal::makeContextCurrent()
         if (CGLSetCurrentContext(m_contextObj) == kCGLNoError)
             return true;
 #elif PLATFORM(LINUX)
-    if (m_glXGetCurrentContext() != m_contextObj)
-        if (m_glXMakeCurrent(m_display, m_pbuffer, m_contextObj))
+    if (s_gl->getCurrentContext() != m_contextObj)
+        if (s_gl->makeCurrent(m_pbuffer, m_contextObj))
             return true;
 #else
 #error Must port to your platform

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list