Changeset 209982 in webkit


Ignore:
Timestamp:
Dec 19, 2016 7:41:28 AM (7 years ago)
Author:
magomez@igalia.com
Message:

[GTK] GLXBadFBConfig error when creating an OpenGL context
https://bugs.webkit.org/show_bug.cgi?id=165200

Reviewed by Carlos Garcia Campos.

glXCreateContextAttribsARB causes a GLXBadFBConfig X error when it's not able to provide the
OpenGL version >= 3.2 we are requesting. Due to this, the app crashes instead of falling back to
the legacy path.
The patch modifies GLX context creation using a XErrorTrapper, so the first time a context is created
we don't crash if OpenGL >= 3.2 is not available.
If the gotten context is not valid, we fall back to whatever version glXCreateContextAttribsARB is
able to provide.
The legacy glXCreateContext is only used if the GLX_ARB_create_context extension is not available.

Covered by existent tests.

  • platform/graphics/glx/GLContextGLX.cpp:

(WebCore::tryCreateGLXARBContext):
(WebCore::GLContextGLX::createWindowContext):
(WebCore::GLContextGLX::createPbufferContext):

Location:
trunk/Source/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r209977 r209982  
     12016-12-19  Miguel Gomez  <magomez@igalia.com>
     2
     3        [GTK] GLXBadFBConfig error when creating an OpenGL context
     4        https://bugs.webkit.org/show_bug.cgi?id=165200
     5
     6        Reviewed by Carlos Garcia Campos.
     7
     8        glXCreateContextAttribsARB causes a GLXBadFBConfig X error when it's not able to provide the
     9        OpenGL version >= 3.2 we are requesting. Due to this, the app crashes instead of falling back to
     10        the legacy path.
     11        The patch modifies GLX context creation using a XErrorTrapper, so the first time a context is created
     12        we don't crash if OpenGL >= 3.2 is not available.
     13        If the gotten context is not valid, we fall back to whatever version glXCreateContextAttribsARB is
     14        able to provide.
     15        The legacy glXCreateContext is only used if the GLX_ARB_create_context extension is not available.
     16
     17        Covered by existent tests.
     18
     19        * platform/graphics/glx/GLContextGLX.cpp:
     20        (WebCore::tryCreateGLXARBContext):
     21        (WebCore::GLContextGLX::createWindowContext):
     22        (WebCore::GLContextGLX::createPbufferContext):
     23
    1242016-12-18  Brady Eidson  <beidson@apple.com>
    225
  • trunk/Source/WebCore/platform/graphics/glx/GLContextGLX.cpp

    r208997 r209982  
    2424#include "OpenGLShims.h"
    2525#include "PlatformDisplayX11.h"
     26#include "XErrorTrapper.h"
    2627#include <GL/glx.h>
    2728#include <cairo.h>
     
    6970    glXCreateContextAttribsARB = reinterpret_cast<PFNGLXCREATECONTEXTATTRIBSARBPROC>(glXGetProcAddress(reinterpret_cast<const unsigned char*>("glXCreateContextAttribsARB")));
    7071    return !!glXCreateContextAttribsARB;
     72}
     73
     74static GLXContext createGLXARBContext(Display* display, GLXFBConfig config, GLXContext sharingContext)
     75{
     76    // We want to create a context with version >= 3.2 core profile, cause that ensures that the i965 driver won't
     77    // use the software renderer. If that doesn't work, we will use whatever version available. Unfortunately,
     78    // there's no way to know whether glXCreateContextAttribsARB can provide an OpenGL version >= 3.2 until
     79    // we actually call it and check the return value. To make things more fun, if a version >= 3.2 cannot be
     80    // provided, glXCreateContextAttribsARB will throw a GLXBadFBConfig X error, causing the app to crash.
     81    // So, the first time a context is requested, we set a X error trap to disable crashes with GLXBadFBConfig
     82    // and then check whether the return value is a context or not.
     83
     84    static bool canCreate320Context = false;
     85    static bool canCreate320ContextInitialized = false;
     86
     87    static const int contextAttributes[] = {
     88        GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
     89        GLX_CONTEXT_MINOR_VERSION_ARB, 2,
     90        0
     91    };
     92
     93    if (!canCreate320ContextInitialized) {
     94        canCreate320ContextInitialized = true;
     95
     96        {
     97            // Set an X error trapper that ignores errors to avoid crashing on GLXBadFBConfig. Use a scope
     98            // here to limit the error trap to just this context creation call.
     99            XErrorTrapper trapper(display, XErrorTrapper::Policy::Ignore);
     100            GLXContext context = glXCreateContextAttribsARB(display, config, sharingContext, GL_TRUE, contextAttributes);
     101            if (context) {
     102                canCreate320Context = true;
     103                return context;
     104            }
     105        }
     106
     107        // Creating the 3.2 context failed, so use whatever is available.
     108        return glXCreateContextAttribsARB(display, config, sharingContext, GL_TRUE, nullptr);
     109    }
     110
     111    if (canCreate320Context)
     112        return glXCreateContextAttribsARB(display, config, sharingContext, GL_TRUE, contextAttributes);
     113
     114    return glXCreateContextAttribsARB(display, config, sharingContext, GL_TRUE, nullptr);
    71115}
    72116
     
    97141
    98142    XUniqueGLXContext context;
    99     if (hasGLXARBCreateContextExtension(display)) {
    100         // Request OpenGL version 3.2 and core profile, which guarantees that the i965 driver doesn't use the software renderer.
    101         static const int contextAttributes[] = {
    102             GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
    103             GLX_CONTEXT_MINOR_VERSION_ARB, 2,
    104             0
    105         };
    106         context.reset(glXCreateContextAttribsARB(display, config, sharingContext, GL_TRUE, contextAttributes));
    107     }
    108 
    109     if (!context) {
    110         // Fallback to legacy OpenGL version.
     143    if (hasGLXARBCreateContextExtension(display))
     144        context.reset(createGLXARBContext(display, config, sharingContext));
     145    else {
     146        // Legacy OpenGL version.
    111147        XUniquePtr<XVisualInfo> visualInfoList(glXGetVisualFromFBConfig(display, config));
    112148        context.reset(glXCreateContext(display, visualInfoList.get(), sharingContext, True));
     
    145181
    146182    XUniqueGLXContext context;
    147 
    148     if (hasGLXARBCreateContextExtension(display)) {
    149         // Request OpenGL version 3.2 and core profile, which guarantees that the i965 driver doesn't use the software renderer.
    150         static const int contextAttributes[] = {
    151             GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
    152             GLX_CONTEXT_MINOR_VERSION_ARB, 2,
    153             0
    154         };
    155         context.reset(glXCreateContextAttribsARB(display, configs.get()[0], sharingContext, GL_TRUE, contextAttributes));
    156     }
    157 
    158     if (!context) {
    159         // Fallback to legacy OpenGL version.
     183    if (hasGLXARBCreateContextExtension(display))
     184        context.reset(createGLXARBContext(display, configs.get()[0], sharingContext));
     185    else {
     186        // Legacy OpenGL version.
    160187        context.reset(glXCreateNewContext(display, configs.get()[0], GLX_RGBA_TYPE, sharingContext, GL_TRUE));
    161188    }
Note: See TracChangeset for help on using the changeset viewer.