Added support for GLX_EXT_swap_control, and cleaned up some other extensions.
authorRyan C. Gordon <icculus@icculus.org>
Mon, 18 Jul 2011 14:34:19 -0700
changeset 5572 32a785da3f49
parent 5571 a036283f779d
child 5573 7dd4caf23bf5
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
src/video/x11/SDL_x11opengl.h
--- a/src/video/x11/SDL_x11opengl.c	Mon Jul 18 14:31:37 2011 -0700
+++ b/src/video/x11/SDL_x11opengl.c	Mon Jul 18 14:34:19 2011 -0700
@@ -138,6 +138,9 @@
     _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 @@
         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 @@
 }
 
 /* 
-   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 @@
 {
     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 @@
 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;
--- a/src/video/x11/SDL_x11opengl.h	Mon Jul 18 14:31:37 2011 -0700
+++ b/src/video/x11/SDL_x11opengl.h	Mon Jul 18 14:34:19 2011 -0700
@@ -31,26 +31,17 @@
 {
     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 */