From 32f2a68cba3f5ec4f5117121393ed381eec31c1d Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 18 Jul 2011 14:34:19 -0700 Subject: [PATCH] Added support for GLX_EXT_swap_control, and cleaned up some other extensions. This allows the Nvidia Linux drivers to use SDL_GL_SetSwapInterval(0). --- src/video/x11/SDL_x11opengl.c | 55 +++++++++++++++++++++++++---------- src/video/x11/SDL_x11opengl.h | 31 +++++++------------- 2 files changed, 51 insertions(+), 35 deletions(-) diff --git a/src/video/x11/SDL_x11opengl.c b/src/video/x11/SDL_x11opengl.c index 1c446167b..cc5770947 100644 --- a/src/video/x11/SDL_x11opengl.c +++ b/src/video/x11/SDL_x11opengl.c @@ -138,6 +138,9 @@ X11_GL_LoadLibrary(_THIS, const char *path) _this->gl_data->glXSwapBuffers = (void (*)(Display *, GLXDrawable)) X11_GL_GetProcAddress(_this, "glXSwapBuffers"); + _this->gl_data->glXQueryDrawable = + (void (*)(Display*,GLXDrawable,int,unsigned int*)) + X11_GL_GetProcAddress(_this, "glXQueryDrawable"); if (!_this->gl_data->glXChooseVisual || !_this->gl_data->glXCreateContext || @@ -254,22 +257,28 @@ X11_GL_InitExtensions(_THIS) extensions = NULL; } - /* Check for SGI_swap_control */ - if (HasExtension("GLX_SGI_swap_control", extensions)) { - _this->gl_data->glXSwapIntervalSGI = - (int (*)(int)) X11_GL_GetProcAddress(_this, "glXSwapIntervalSGI"); + /* Check for GLX_EXT_swap_control */ + if (HasExtension("GLX_EXT_swap_control", extensions)) { + _this->gl_data->glXSwapIntervalEXT = + (void (*)(Display*,GLXDrawable,int)) + X11_GL_GetProcAddress(_this, "glXSwapIntervalEXT"); } /* Check for GLX_MESA_swap_control */ if (HasExtension("GLX_MESA_swap_control", extensions)) { _this->gl_data->glXSwapIntervalMESA = - (GLint(*)(unsigned)) X11_GL_GetProcAddress(_this, - "glXSwapIntervalMESA"); + (int(*)(int)) X11_GL_GetProcAddress(_this, "glXSwapIntervalMESA"); _this->gl_data->glXGetSwapIntervalMESA = - (GLint(*)(void)) X11_GL_GetProcAddress(_this, + (int(*)(void)) X11_GL_GetProcAddress(_this, "glXGetSwapIntervalMESA"); } + /* Check for GLX_SGI_swap_control */ + if (HasExtension("GLX_SGI_swap_control", extensions)) { + _this->gl_data->glXSwapIntervalSGI = + (int (*)(int)) X11_GL_GetProcAddress(_this, "glXSwapIntervalSGI"); + } + /* Check for GLX_EXT_visual_rating */ if (HasExtension("GLX_EXT_visual_rating", extensions)) { _this->gl_data->HAS_GLX_EXT_visual_rating = SDL_TRUE; @@ -506,12 +515,11 @@ X11_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context) } /* - 0 is a valid argument to glxSwapIntervalMESA and setting it to 0 - with the MESA version of the extension will undo the effect of a - previous call with a value that is greater than zero (or at least - that is what the FM says. OTOH, 0 is an invalid argument to - glxSwapIntervalSGI and it returns an error if you call it with 0 as - an argument. + 0 is a valid argument to glxSwapInterval(MESA|EXT) and setting it to 0 + will undo the effect of a previous call with a value that is greater + than zero (or at least that is what the docs say). OTOH, 0 is an invalid + argument to glxSwapIntervalSGI and it returns an error if you call it + with 0 as an argument. */ static int swapinterval = -1; @@ -520,7 +528,15 @@ X11_GL_SetSwapInterval(_THIS, int interval) { int status; - if (_this->gl_data->glXSwapIntervalMESA) { + if (_this->gl_data->glXSwapIntervalEXT) { + Display *display = ((SDL_VideoData *) _this->driverdata)->display; + const SDL_WindowData *windowdata = (SDL_WindowData *) + _this->current_glwin->driverdata; + Window drawable = windowdata->xwindow; + _this->gl_data->glXSwapIntervalEXT(display, drawable, interval); + status = 0; /* always succeeds, apparently. */ + swapinterval = interval; + } else if (_this->gl_data->glXSwapIntervalMESA) { status = _this->gl_data->glXSwapIntervalMESA(interval); if (status != 0) { SDL_SetError("glxSwapIntervalMESA failed"); @@ -546,7 +562,16 @@ X11_GL_SetSwapInterval(_THIS, int interval) int X11_GL_GetSwapInterval(_THIS) { - if (_this->gl_data->glXGetSwapIntervalMESA) { + if (_this->gl_data->glXSwapIntervalEXT) { + Display *display = ((SDL_VideoData *) _this->driverdata)->display; + const SDL_WindowData *windowdata = (SDL_WindowData *) + _this->current_glwin->driverdata; + Window drawable = windowdata->xwindow; + unsigned int value = 0; + _this->gl_data->glXQueryDrawable(display, drawable, + GLX_SWAP_INTERVAL_EXT, &value); + return (int) value; + } else if (_this->gl_data->glXGetSwapIntervalMESA) { return _this->gl_data->glXGetSwapIntervalMESA(); } else { return swapinterval; diff --git a/src/video/x11/SDL_x11opengl.h b/src/video/x11/SDL_x11opengl.h index 037232117..730566446 100644 --- a/src/video/x11/SDL_x11opengl.h +++ b/src/video/x11/SDL_x11opengl.h @@ -31,26 +31,17 @@ struct SDL_GLDriverData { SDL_bool HAS_GLX_EXT_visual_rating; - void *(*glXGetProcAddress) (const GLubyte * procName); - - XVisualInfo *(*glXChooseVisual) - (Display * dpy, int screen, int *attribList); - - GLXContext(*glXCreateContext) - (Display * dpy, XVisualInfo * vis, GLXContext shareList, Bool direct); - - void (*glXDestroyContext) - (Display * dpy, GLXContext ctx); - - Bool(*glXMakeCurrent) - (Display * dpy, GLXDrawable drawable, GLXContext ctx); - - void (*glXSwapBuffers) - (Display * dpy, GLXDrawable drawable); - - int (*glXSwapIntervalSGI) (int interval); - GLint(*glXSwapIntervalMESA) (unsigned interval); - GLint(*glXGetSwapIntervalMESA) (void); + void *(*glXGetProcAddress) (const GLubyte*); + XVisualInfo *(*glXChooseVisual) (Display*,int,int*); + GLXContext (*glXCreateContext) (Display*,XVisualInfo*,GLXContext,Bool); + void (*glXDestroyContext) (Display*, GLXContext); + Bool(*glXMakeCurrent) (Display*,GLXDrawable,GLXContext); + void (*glXSwapBuffers) (Display*, GLXDrawable); + void (*glXQueryDrawable) (Display*,GLXDrawable,int,unsigned int*); + void (*glXSwapIntervalEXT) (Display*,GLXDrawable,int); + int (*glXSwapIntervalSGI) (int); + int (*glXSwapIntervalMESA) (int); + int (*glXGetSwapIntervalMESA) (void); }; /* OpenGL functions */