Fix for recent GLX error bug
authorSam Lantinga <slouken@libsdl.org>
Tue, 23 Jul 2013 19:20:03 -0700
changeset 7512 462839f2f408
parent 7511 4ce3cc948a00
child 7513 ec0c3f1eb2de
Fix for recent GLX error bug Lee Salzman I messed up in the patch I sent you regarding gobbling up the GLX error codes signaled when trying to create a context. After reading the spec I realized those error codes are relative to a base error that needs to be queried when setting up the GLX extension... So I have made a patch that fixes it for a user I had who was still getting the bug with my old patch. Without this patch my previous one won't work, so it is recommended to merge this...
src/video/x11/SDL_x11opengl.c
src/video/x11/SDL_x11opengl.h
--- a/src/video/x11/SDL_x11opengl.c	Tue Jul 23 19:18:01 2013 -0700
+++ b/src/video/x11/SDL_x11opengl.c	Tue Jul 23 19:20:03 2013 -0700
@@ -133,6 +133,7 @@
 int
 X11_GL_LoadLibrary(_THIS, const char *path)
 {
+    Display *display;
     void *handle;
 
     if (_this->gl_data) {
@@ -186,6 +187,9 @@
 
     /* Load function pointers */
     handle = _this->gl_config.dll_handle;
+    _this->gl_data->glXQueryExtension =
+        (Bool (*)(Display *, int *, int *))
+            GL_LoadFunction(handle, "glXQueryExtension");
     _this->gl_data->glXGetProcAddress =
         (void *(*)(const GLubyte *))
             GL_LoadFunction(handle, "glXGetProcAddressARB");
@@ -208,7 +212,8 @@
         (void (*)(Display*,GLXDrawable,int,unsigned int*))
             X11_GL_GetProcAddress(_this, "glXQueryDrawable");
 
-    if (!_this->gl_data->glXChooseVisual ||
+    if (!_this->gl_data->glXQueryExtension ||
+        !_this->gl_data->glXChooseVisual ||
         !_this->gl_data->glXCreateContext ||
         !_this->gl_data->glXDestroyContext ||
         !_this->gl_data->glXMakeCurrent ||
@@ -216,6 +221,11 @@
         return SDL_SetError("Could not retrieve OpenGL functions");
     }
 
+    display = ((SDL_VideoData *) _this->driverdata)->display;
+    if (!_this->gl_data->glXQueryExtension(display, &_this->gl_data->errorBase, &_this->gl_data->eventBase)) {
+        return SDL_SetError("GLX is not supported");
+    }
+
     /* Initialize extensions */
     X11_GL_InitExtensions(_this);
 
@@ -504,19 +514,23 @@
 #define GLXBadProfileARB 13
 #endif
 static int (*handler) (Display *, XErrorEvent *) = NULL;
+static int errorBase = 0;
 static int
 X11_GL_CreateContextErrorHandler(Display * d, XErrorEvent * e)
 {
     switch (e->error_code) {
-    case GLXBadContext:
-    case GLXBadFBConfig:
-    case GLXBadProfileARB:
     case BadRequest:
     case BadMatch:
     case BadValue:
     case BadAlloc:
         return (0);
     default:
+        if (errorBase && 
+            (e->error_code == errorBase + GLXBadContext ||
+             e->error_code == errorBase + GLXBadFBConfig ||
+             e->error_code == errorBase + GLXBadProfileARB)) {
+            return (0);
+        }
         return (handler(d, e));
     }
 }
@@ -541,6 +555,7 @@
 
     /* We do this to create a clean separation between X and GLX errors. */
     XSync(display, False);
+    errorBase = _this->gl_data->errorBase;
     handler = XSetErrorHandler(X11_GL_CreateContextErrorHandler);
     XGetWindowAttributes(display, data->xwindow, &xattr);
     v.screen = screen;
--- a/src/video/x11/SDL_x11opengl.h	Tue Jul 23 19:18:01 2013 -0700
+++ b/src/video/x11/SDL_x11opengl.h	Tue Jul 23 19:20:03 2013 -0700
@@ -29,10 +29,13 @@
 
 struct SDL_GLDriverData
 {
+    int errorBase, eventBase;
+
     SDL_bool HAS_GLX_EXT_visual_rating;
     SDL_bool HAS_GLX_EXT_visual_info;
     SDL_bool HAS_GLX_EXT_swap_control_tear;
 
+    Bool (*glXQueryExtension) (Display*,int*,int*);
     void *(*glXGetProcAddress) (const GLubyte*);
     XVisualInfo *(*glXChooseVisual) (Display*,int,int*);
     GLXContext (*glXCreateContext) (Display*,XVisualInfo*,GLXContext,Bool);