Title: [139725] trunk/Source/WebCore
Revision
139725
Author
commit-qu...@webkit.org
Date
2013-01-15 00:56:42 -0800 (Tue, 15 Jan 2013)

Log Message

[EFL][WebGL] Add error handling to carefully manage Window backing pixmaps.
https://bugs.webkit.org/show_bug.cgi?id=106582

Patch by Kondapally Kalyan <kalyan.kondapa...@intel.com> on 2013-01-15
Reviewed by Kenneth Rohde Christiansen.

We use XCompositeNameWindowPixmap to create a pixmap that serves as a reference to
the off-screen storage for a Window Handle. We expect the Window to be valid and
the created glx pixmap to be a valid drawable. This may not be true always.
This patch adds support for X Error checks and handles the generated errors.

Covered by existing WebGL layout tests.

* platform/graphics/surfaces/glx/GraphicsSurfaceGLX.cpp:
(WebCore):
(WebCore::handleXPixmapCreationError):
(ScopedXPixmapCreationErrorHandler):
(WebCore::ScopedXPixmapCreationErrorHandler::ScopedXPixmapCreationErrorHandler):
(WebCore::ScopedXPixmapCreationErrorHandler::~ScopedXPixmapCreationErrorHandler):
(WebCore::ScopedXPixmapCreationErrorHandler::isValidOperation):
Helper Class to catch XErrors.

(WebCore::GraphicsSurfacePrivate::~GraphicsSurfacePrivate):
(WebCore::GraphicsSurfacePrivate::createPixmap): Added support to check and handle generated XErrors.
(WebCore::GraphicsSurfacePrivate::findFBConfigWithAlpha):
(WebCore::GraphicsSurfacePrivate::clear): Destroys GL Resources.
(GraphicsSurfacePrivate):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (139724 => 139725)


--- trunk/Source/WebCore/ChangeLog	2013-01-15 08:54:59 UTC (rev 139724)
+++ trunk/Source/WebCore/ChangeLog	2013-01-15 08:56:42 UTC (rev 139725)
@@ -1,5 +1,34 @@
 2013-01-15  Kondapally Kalyan  <kalyan.kondapa...@intel.com>
 
+        [EFL][WebGL] Add error handling to carefully manage Window backing pixmaps.
+        https://bugs.webkit.org/show_bug.cgi?id=106582
+
+        Reviewed by Kenneth Rohde Christiansen.
+
+        We use XCompositeNameWindowPixmap to create a pixmap that serves as a reference to
+        the off-screen storage for a Window Handle. We expect the Window to be valid and
+        the created glx pixmap to be a valid drawable. This may not be true always.
+        This patch adds support for X Error checks and handles the generated errors.
+
+        Covered by existing WebGL layout tests.
+
+        * platform/graphics/surfaces/glx/GraphicsSurfaceGLX.cpp:
+        (WebCore):
+        (WebCore::handleXPixmapCreationError):
+        (ScopedXPixmapCreationErrorHandler):
+        (WebCore::ScopedXPixmapCreationErrorHandler::ScopedXPixmapCreationErrorHandler):
+        (WebCore::ScopedXPixmapCreationErrorHandler::~ScopedXPixmapCreationErrorHandler):
+        (WebCore::ScopedXPixmapCreationErrorHandler::isValidOperation):
+        Helper Class to catch XErrors.
+
+        (WebCore::GraphicsSurfacePrivate::~GraphicsSurfacePrivate):
+        (WebCore::GraphicsSurfacePrivate::createPixmap): Added support to check and handle generated XErrors.
+        (WebCore::GraphicsSurfacePrivate::findFBConfigWithAlpha):
+        (WebCore::GraphicsSurfacePrivate::clear): Destroys GL Resources.
+        (GraphicsSurfacePrivate):
+
+2013-01-15  Kondapally Kalyan  <kalyan.kondapa...@intel.com>
+
         [EFL] [WebGL] Minor cleanup in PlatformContext.
         https://bugs.webkit.org/show_bug.cgi?id=106758
 

Modified: trunk/Source/WebCore/platform/graphics/surfaces/glx/GraphicsSurfaceGLX.cpp (139724 => 139725)


--- trunk/Source/WebCore/platform/graphics/surfaces/glx/GraphicsSurfaceGLX.cpp	2013-01-15 08:54:59 UTC (rev 139724)
+++ trunk/Source/WebCore/platform/graphics/surfaces/glx/GraphicsSurfaceGLX.cpp	2013-01-15 08:56:42 UTC (rev 139725)
@@ -36,6 +36,7 @@
 
 #include <GL/glext.h>
 #include <GL/glx.h>
+#include <X11/Xlib.h>
 #include <X11/extensions/Xcomposite.h>
 #include <X11/extensions/Xrender.h>
 
@@ -51,6 +52,31 @@
 static PFNGLDELETEFRAMEBUFFERSPROC pGlDeleteFramebuffers = 0;
 static PFNGLFRAMEBUFFERTEXTURE2DPROC pGlFramebufferTexture2D = 0;
 
+// Used for handling XError.
+static bool validOperation = true;
+static int handleXPixmapCreationError(Display*, XErrorEvent* event)
+{
+    if (event->error_code == BadMatch || event->error_code == BadWindow || event->error_code == BadAlloc) {
+        validOperation = false;
+
+        switch (event->error_code) {
+        case BadMatch:
+            LOG_ERROR("BadMatch.");
+            break;
+        case BadWindow:
+            LOG_ERROR("BadWindow.");
+            break;
+        case BadAlloc:
+            LOG_ERROR("BadAlloc.");
+            break;
+        default:
+            break;
+        }
+    }
+
+    return 0;
+}
+
 static int attributes[] = {
     GLX_LEVEL, 0,
     GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
@@ -65,6 +91,37 @@
     None
 };
 
+class ScopedXPixmapCreationErrorHandler {
+
+public:
+    ScopedXPixmapCreationErrorHandler(Display* display)
+        : m_display(display)
+    {
+        // XSync must be called to ensure that current errors are handled by the original handler.
+        XSync(m_display, false);
+        m_previousErrorHandler = XSetErrorHandler(handleXPixmapCreationError);
+    }
+
+    ~ScopedXPixmapCreationErrorHandler()
+    {
+        // Restore the original handler.
+        XSetErrorHandler(m_previousErrorHandler);
+    }
+
+    bool isValidOperation() const
+    {
+        validOperation = true;
+        // XSync is needed to catch possible errors as they are generated asynchronously.
+        XSync(m_display, false);
+        return validOperation;
+    }
+
+private:
+    XErrorHandler m_previousErrorHandler;
+    Display* m_display;
+};
+
+// FIXME: Take X11WindowResources and GLXConfigSelector into use.
 class OffScreenRootWindow {
 public:
     OffScreenRootWindow()
@@ -193,16 +250,7 @@
 
     ~GraphicsSurfacePrivate()
     {
-        if (m_glxPixmap)
-            glXDestroyPixmap(m_display, m_glxPixmap);
-        m_glxPixmap = 0;
-
-        if (m_xPixmap)
-            XFreePixmap(m_display, m_xPixmap);
-        m_xPixmap = 0;
-
-        if (m_glContext)
-            glXDestroyContext(m_display, m_glContext);
+        clear();
     }
 
     uint32_t createSurface(const IntSize& size)
@@ -239,6 +287,12 @@
         XWindowAttributes attr;
         if (!XGetWindowAttributes(m_display, winId, &attr))
             return;
+
+        // Ensure that the window is mapped.
+        if (attr.map_state == IsUnmapped || attr.map_state == IsUnviewable)
+            return;
+
+        ScopedXPixmapCreationErrorHandler handler(m_display);
         m_size = IntSize(attr.width, attr.height);
 
         XRenderPictFormat* format = XRenderFindVisualFormat(m_display, attr.visual);
@@ -253,9 +307,13 @@
         m_xPixmap = XCompositeNameWindowPixmap(m_display, winId);
         m_glxPixmap = glXCreatePixmap(m_display, config, m_xPixmap, glxAttributes);
 
-        uint inverted = 0;
-        glXQueryDrawable(m_display, m_glxPixmap, GLX_Y_INVERTED_EXT, &inverted);
-        m_textureIsYInverted = !!inverted;
+        if (!handler.isValidOperation())
+            clear();
+        else {
+            uint inverted = 0;
+            glXQueryDrawable(m_display, m_glxPixmap, GLX_Y_INVERTED_EXT, &inverted);
+            m_textureIsYInverted = !!inverted;
+        }
 
         XFree(configs);
     }
@@ -360,16 +418,33 @@
 
             XRenderPictFormat* format = XRenderFindVisualFormat(m_display, visualInfo->visual);
             XFree(visualInfo);
-            if (format && format->direct.alphaMask > 0) {
+
+            if (format && format->direct.alphaMask > 0)
                 return fbConfigs[i];
-                break;
-            }
         }
 
         // Return 1st config as a fallback with no alpha support.
         return fbConfigs[0];
     }
 
+    void clear()
+    {
+        if (m_glxPixmap) {
+            glXDestroyPixmap(m_display, m_glxPixmap);
+            m_glxPixmap = 0;
+        }
+
+        if (m_xPixmap) {
+            XFreePixmap(m_display, m_xPixmap);
+            m_xPixmap = 0;
+        }
+
+        if (m_glContext) {
+            glXDestroyContext(m_display, m_glContext);
+            m_glContext = 0;
+        }
+    }
+
     OffScreenRootWindow m_offScreenWindow;
     IntSize m_size;
     Display* m_display;
@@ -438,7 +513,6 @@
     m_private->copyFromTexture(texture, sourceRect);
 }
 
-
 void GraphicsSurface::platformPaintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& transform, float opacity, BitmapTexture* mask)
 {
     TextureMapperGL* texMapGL = static_cast<TextureMapperGL*>(textureMapper);
@@ -462,11 +536,12 @@
 
 uint32_t GraphicsSurface::platformSwapBuffers()
 {
-    if (m_private->isReceiver()) {
+    if (m_private->isReceiver() && platformGetTextureID()) {
         glBindTexture(GL_TEXTURE_2D, platformGetTextureID());
         // Release previous lock and rebind texture to surface to get frame update.
         pGlXReleaseTexImageEXT(m_private->display(), m_private->glxPixmap(), GLX_FRONT_EXT);
         pGlXBindTexImageEXT(m_private->display(), m_private->glxPixmap(), GLX_FRONT_EXT, 0);
+
         return 0;
     }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to