From e566fc8192c991730477c97a465566acb8a9c077 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 23 Jul 2013 19:20:03 -0700 Subject: [PATCH] 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 | 23 +++++++++++++++++++---- src/video/x11/SDL_x11opengl.h | 3 +++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/video/x11/SDL_x11opengl.c b/src/video/x11/SDL_x11opengl.c index 1ccc66c4e..2eaed8698 100644 --- a/src/video/x11/SDL_x11opengl.c +++ b/src/video/x11/SDL_x11opengl.c @@ -133,6 +133,7 @@ static void X11_GL_InitExtensions(_THIS); int X11_GL_LoadLibrary(_THIS, const char *path) { + Display *display; void *handle; if (_this->gl_data) { @@ -186,6 +187,9 @@ X11_GL_LoadLibrary(_THIS, const char *path) /* 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 @@ X11_GL_LoadLibrary(_THIS, const char *path) (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 @@ X11_GL_LoadLibrary(_THIS, const char *path) 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 @@ X11_GL_GetVisual(_THIS, Display * display, int screen) #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 @@ X11_GL_CreateContext(_THIS, SDL_Window * window) /* 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; diff --git a/src/video/x11/SDL_x11opengl.h b/src/video/x11/SDL_x11opengl.h index 69ad1c2b9..db1b3152e 100644 --- a/src/video/x11/SDL_x11opengl.h +++ b/src/video/x11/SDL_x11opengl.h @@ -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);