Skip to content

Commit

Permalink
x11: Catch fatal X errors when calling glXMakeCurrent().
Browse files Browse the repository at this point in the history
In extremely rare cases, probably due to misconfigured drivers, one might
see this happen, and rather than terminate the process, we try to recover
by reporting an error to the app.

Fixes Bugzilla #3068.
  • Loading branch information
icculus committed Jul 28, 2015
1 parent c344b73 commit f5cf867
Showing 1 changed file with 19 additions and 5 deletions.
24 changes: 19 additions & 5 deletions src/video/x11/SDL_x11opengl.c
Expand Up @@ -529,10 +529,11 @@ X11_GL_GetVisual(_THIS, Display * display, int screen)
#define GLXBadProfileARB 13
#endif
static int (*handler) (Display *, XErrorEvent *) = NULL;
static const char *errorHandlerOperation = NULL;
static int errorBase = 0;
static int errorCode = 0;
static int
X11_GL_CreateContextErrorHandler(Display * d, XErrorEvent * e)
X11_GL_ErrorHandler(Display * d, XErrorEvent * e)
{
char *x11_error = NULL;
char x11_error_locale[256];
Expand All @@ -545,12 +546,12 @@ X11_GL_CreateContextErrorHandler(Display * d, XErrorEvent * e)

if (x11_error)
{
SDL_SetError("Could not create GL context: %s", x11_error);
SDL_SetError("Could not %s: %s", errorHandlerOperation, x11_error);
SDL_free(x11_error);
}
else
{
SDL_SetError("Could not create GL context: %i (Base %i)\n", errorCode, errorBase);
SDL_SetError("Could not %s: %i (Base %i)\n", errorHandlerOperation, errorCode, errorBase);
}

return (0);
Expand All @@ -576,9 +577,10 @@ X11_GL_CreateContext(_THIS, SDL_Window * window)

/* We do this to create a clean separation between X and GLX errors. */
X11_XSync(display, False);
errorHandlerOperation = "create GL context";
errorBase = _this->gl_data->errorBase;
errorCode = Success;
handler = X11_XSetErrorHandler(X11_GL_CreateContextErrorHandler);
handler = X11_XSetErrorHandler(X11_GL_ErrorHandler);
X11_XGetWindowAttributes(display, data->xwindow, &xattr);
v.screen = screen;
v.visualid = X11_XVisualIDFromVisual(xattr.visual);
Expand Down Expand Up @@ -676,12 +678,24 @@ X11_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
Window drawable =
(context ? ((SDL_WindowData *) window->driverdata)->xwindow : None);
GLXContext glx_context = (GLXContext) context;
int rc;

if (!_this->gl_data) {
return SDL_SetError("OpenGL not initialized");
}

if (!_this->gl_data->glXMakeCurrent(display, drawable, glx_context)) {
/* We do this to create a clean separation between X and GLX errors. */
X11_XSync(display, False);
errorHandlerOperation = "make GL context current";
errorBase = _this->gl_data->errorBase;
errorCode = Success;
handler = X11_XSetErrorHandler(X11_GL_ErrorHandler);
rc = _this->gl_data->glXMakeCurrent(display, drawable, glx_context);
X11_XSetErrorHandler(handler);

if (errorCode != Success) { /* uhoh, an X error was thrown! */
return -1; /* the error handler called SDL_SetError() already. */
} else if (!rc) { /* glxMakeCurrent() failed without throwing an X error */
return SDL_SetError("Unable to make GL context current");
}

Expand Down

0 comments on commit f5cf867

Please sign in to comment.