Changeset 139725 in webkit


Ignore:
Timestamp:
Jan 15, 2013 12:56:42 AM (11 years ago)
Author:
commit-queue@webkit.org
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.kondapally@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):

Location:
trunk/Source/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r139724 r139725  
     12013-01-15  Kondapally Kalyan  <kalyan.kondapally@intel.com>
     2
     3        [EFL][WebGL] Add error handling to carefully manage Window backing pixmaps.
     4        https://bugs.webkit.org/show_bug.cgi?id=106582
     5
     6        Reviewed by Kenneth Rohde Christiansen.
     7
     8        We use XCompositeNameWindowPixmap to create a pixmap that serves as a reference to
     9        the off-screen storage for a Window Handle. We expect the Window to be valid and
     10        the created glx pixmap to be a valid drawable. This may not be true always.
     11        This patch adds support for X Error checks and handles the generated errors.
     12
     13        Covered by existing WebGL layout tests.
     14
     15        * platform/graphics/surfaces/glx/GraphicsSurfaceGLX.cpp:
     16        (WebCore):
     17        (WebCore::handleXPixmapCreationError):
     18        (ScopedXPixmapCreationErrorHandler):
     19        (WebCore::ScopedXPixmapCreationErrorHandler::ScopedXPixmapCreationErrorHandler):
     20        (WebCore::ScopedXPixmapCreationErrorHandler::~ScopedXPixmapCreationErrorHandler):
     21        (WebCore::ScopedXPixmapCreationErrorHandler::isValidOperation):
     22        Helper Class to catch XErrors.
     23
     24        (WebCore::GraphicsSurfacePrivate::~GraphicsSurfacePrivate):
     25        (WebCore::GraphicsSurfacePrivate::createPixmap): Added support to check and handle generated XErrors.
     26        (WebCore::GraphicsSurfacePrivate::findFBConfigWithAlpha):
     27        (WebCore::GraphicsSurfacePrivate::clear): Destroys GL Resources.
     28        (GraphicsSurfacePrivate):
     29
    1302013-01-15  Kondapally Kalyan  <kalyan.kondapally@intel.com>
    231
  • trunk/Source/WebCore/platform/graphics/surfaces/glx/GraphicsSurfaceGLX.cpp

    r139030 r139725  
    3737#include <GL/glext.h>
    3838#include <GL/glx.h>
     39#include <X11/Xlib.h>
    3940#include <X11/extensions/Xcomposite.h>
    4041#include <X11/extensions/Xrender.h>
     
    5152static PFNGLDELETEFRAMEBUFFERSPROC pGlDeleteFramebuffers = 0;
    5253static PFNGLFRAMEBUFFERTEXTURE2DPROC pGlFramebufferTexture2D = 0;
     54
     55// Used for handling XError.
     56static bool validOperation = true;
     57static int handleXPixmapCreationError(Display*, XErrorEvent* event)
     58{
     59    if (event->error_code == BadMatch || event->error_code == BadWindow || event->error_code == BadAlloc) {
     60        validOperation = false;
     61
     62        switch (event->error_code) {
     63        case BadMatch:
     64            LOG_ERROR("BadMatch.");
     65            break;
     66        case BadWindow:
     67            LOG_ERROR("BadWindow.");
     68            break;
     69        case BadAlloc:
     70            LOG_ERROR("BadAlloc.");
     71            break;
     72        default:
     73            break;
     74        }
     75    }
     76
     77    return 0;
     78}
    5379
    5480static int attributes[] = {
     
    6692};
    6793
     94class ScopedXPixmapCreationErrorHandler {
     95
     96public:
     97    ScopedXPixmapCreationErrorHandler(Display* display)
     98        : m_display(display)
     99    {
     100        // XSync must be called to ensure that current errors are handled by the original handler.
     101        XSync(m_display, false);
     102        m_previousErrorHandler = XSetErrorHandler(handleXPixmapCreationError);
     103    }
     104
     105    ~ScopedXPixmapCreationErrorHandler()
     106    {
     107        // Restore the original handler.
     108        XSetErrorHandler(m_previousErrorHandler);
     109    }
     110
     111    bool isValidOperation() const
     112    {
     113        validOperation = true;
     114        // XSync is needed to catch possible errors as they are generated asynchronously.
     115        XSync(m_display, false);
     116        return validOperation;
     117    }
     118
     119private:
     120    XErrorHandler m_previousErrorHandler;
     121    Display* m_display;
     122};
     123
     124// FIXME: Take X11WindowResources and GLXConfigSelector into use.
    68125class OffScreenRootWindow {
    69126public:
     
    194251    ~GraphicsSurfacePrivate()
    195252    {
    196         if (m_glxPixmap)
    197             glXDestroyPixmap(m_display, m_glxPixmap);
    198         m_glxPixmap = 0;
    199 
    200         if (m_xPixmap)
    201             XFreePixmap(m_display, m_xPixmap);
    202         m_xPixmap = 0;
    203 
    204         if (m_glContext)
    205             glXDestroyContext(m_display, m_glContext);
     253        clear();
    206254    }
    207255
     
    240288        if (!XGetWindowAttributes(m_display, winId, &attr))
    241289            return;
     290
     291        // Ensure that the window is mapped.
     292        if (attr.map_state == IsUnmapped || attr.map_state == IsUnviewable)
     293            return;
     294
     295        ScopedXPixmapCreationErrorHandler handler(m_display);
    242296        m_size = IntSize(attr.width, attr.height);
    243297
     
    254308        m_glxPixmap = glXCreatePixmap(m_display, config, m_xPixmap, glxAttributes);
    255309
    256         uint inverted = 0;
    257         glXQueryDrawable(m_display, m_glxPixmap, GLX_Y_INVERTED_EXT, &inverted);
    258         m_textureIsYInverted = !!inverted;
     310        if (!handler.isValidOperation())
     311            clear();
     312        else {
     313            uint inverted = 0;
     314            glXQueryDrawable(m_display, m_glxPixmap, GLX_Y_INVERTED_EXT, &inverted);
     315            m_textureIsYInverted = !!inverted;
     316        }
    259317
    260318        XFree(configs);
     
    361419            XRenderPictFormat* format = XRenderFindVisualFormat(m_display, visualInfo->visual);
    362420            XFree(visualInfo);
    363             if (format && format->direct.alphaMask > 0) {
     421
     422            if (format && format->direct.alphaMask > 0)
    364423                return fbConfigs[i];
    365                 break;
    366             }
    367424        }
    368425
    369426        // Return 1st config as a fallback with no alpha support.
    370427        return fbConfigs[0];
     428    }
     429
     430    void clear()
     431    {
     432        if (m_glxPixmap) {
     433            glXDestroyPixmap(m_display, m_glxPixmap);
     434            m_glxPixmap = 0;
     435        }
     436
     437        if (m_xPixmap) {
     438            XFreePixmap(m_display, m_xPixmap);
     439            m_xPixmap = 0;
     440        }
     441
     442        if (m_glContext) {
     443            glXDestroyContext(m_display, m_glContext);
     444            m_glContext = 0;
     445        }
    371446    }
    372447
     
    439514}
    440515
    441 
    442516void GraphicsSurface::platformPaintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& transform, float opacity, BitmapTexture* mask)
    443517{
     
    463537uint32_t GraphicsSurface::platformSwapBuffers()
    464538{
    465     if (m_private->isReceiver()) {
     539    if (m_private->isReceiver() && platformGetTextureID()) {
    466540        glBindTexture(GL_TEXTURE_2D, platformGetTextureID());
    467541        // Release previous lock and rebind texture to surface to get frame update.
    468542        pGlXReleaseTexImageEXT(m_private->display(), m_private->glxPixmap(), GLX_FRONT_EXT);
    469543        pGlXBindTexImageEXT(m_private->display(), m_private->glxPixmap(), GLX_FRONT_EXT, 0);
     544
    470545        return 0;
    471546    }
Note: See TracChangeset for help on using the changeset viewer.