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 557232a785da3f49
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
     1.1 --- a/src/video/x11/SDL_x11opengl.c	Mon Jul 18 14:31:37 2011 -0700
     1.2 +++ b/src/video/x11/SDL_x11opengl.c	Mon Jul 18 14:34:19 2011 -0700
     1.3 @@ -138,6 +138,9 @@
     1.4      _this->gl_data->glXSwapBuffers =
     1.5          (void (*)(Display *, GLXDrawable))
     1.6              X11_GL_GetProcAddress(_this, "glXSwapBuffers");
     1.7 +    _this->gl_data->glXQueryDrawable =
     1.8 +        (void (*)(Display*,GLXDrawable,int,unsigned int*))
     1.9 +            X11_GL_GetProcAddress(_this, "glXQueryDrawable");
    1.10  
    1.11      if (!_this->gl_data->glXChooseVisual ||
    1.12          !_this->gl_data->glXCreateContext ||
    1.13 @@ -254,22 +257,28 @@
    1.14          extensions = NULL;
    1.15      }
    1.16  
    1.17 -    /* Check for SGI_swap_control */
    1.18 -    if (HasExtension("GLX_SGI_swap_control", extensions)) {
    1.19 -        _this->gl_data->glXSwapIntervalSGI =
    1.20 -            (int (*)(int)) X11_GL_GetProcAddress(_this, "glXSwapIntervalSGI");
    1.21 +    /* Check for GLX_EXT_swap_control */
    1.22 +    if (HasExtension("GLX_EXT_swap_control", extensions)) {
    1.23 +        _this->gl_data->glXSwapIntervalEXT =
    1.24 +            (void (*)(Display*,GLXDrawable,int))
    1.25 +                X11_GL_GetProcAddress(_this, "glXSwapIntervalEXT");
    1.26      }
    1.27  
    1.28      /* Check for GLX_MESA_swap_control */
    1.29      if (HasExtension("GLX_MESA_swap_control", extensions)) {
    1.30          _this->gl_data->glXSwapIntervalMESA =
    1.31 -            (GLint(*)(unsigned)) X11_GL_GetProcAddress(_this,
    1.32 -                                                       "glXSwapIntervalMESA");
    1.33 +            (int(*)(int)) X11_GL_GetProcAddress(_this, "glXSwapIntervalMESA");
    1.34          _this->gl_data->glXGetSwapIntervalMESA =
    1.35 -            (GLint(*)(void)) X11_GL_GetProcAddress(_this,
    1.36 +            (int(*)(void)) X11_GL_GetProcAddress(_this,
    1.37                                                     "glXGetSwapIntervalMESA");
    1.38      }
    1.39  
    1.40 +    /* Check for GLX_SGI_swap_control */
    1.41 +    if (HasExtension("GLX_SGI_swap_control", extensions)) {
    1.42 +        _this->gl_data->glXSwapIntervalSGI =
    1.43 +            (int (*)(int)) X11_GL_GetProcAddress(_this, "glXSwapIntervalSGI");
    1.44 +    }
    1.45 +
    1.46      /* Check for GLX_EXT_visual_rating */
    1.47      if (HasExtension("GLX_EXT_visual_rating", extensions)) {
    1.48          _this->gl_data->HAS_GLX_EXT_visual_rating = SDL_TRUE;
    1.49 @@ -506,12 +515,11 @@
    1.50  }
    1.51  
    1.52  /* 
    1.53 -   0 is a valid argument to glxSwapIntervalMESA and setting it to 0
    1.54 -   with the MESA version of the extension will undo the effect of a
    1.55 -   previous call with a value that is greater than zero (or at least
    1.56 -   that is what the FM says. OTOH, 0 is an invalid argument to
    1.57 -   glxSwapIntervalSGI and it returns an error if you call it with 0 as
    1.58 -   an argument.
    1.59 +   0 is a valid argument to glxSwapInterval(MESA|EXT) and setting it to 0
    1.60 +   will undo the effect of a previous call with a value that is greater
    1.61 +   than zero (or at least that is what the docs say). OTOH, 0 is an invalid
    1.62 +   argument to glxSwapIntervalSGI and it returns an error if you call it
    1.63 +   with 0 as an argument.
    1.64  */
    1.65  
    1.66  static int swapinterval = -1;
    1.67 @@ -520,7 +528,15 @@
    1.68  {
    1.69      int status;
    1.70  
    1.71 -    if (_this->gl_data->glXSwapIntervalMESA) {
    1.72 +    if (_this->gl_data->glXSwapIntervalEXT) {
    1.73 +        Display *display = ((SDL_VideoData *) _this->driverdata)->display;
    1.74 +        const SDL_WindowData *windowdata = (SDL_WindowData *)
    1.75 +            _this->current_glwin->driverdata;
    1.76 +        Window drawable = windowdata->xwindow;
    1.77 +        _this->gl_data->glXSwapIntervalEXT(display, drawable, interval);
    1.78 +        status = 0;  /* always succeeds, apparently. */
    1.79 +        swapinterval = interval;
    1.80 +    } else if (_this->gl_data->glXSwapIntervalMESA) {
    1.81          status = _this->gl_data->glXSwapIntervalMESA(interval);
    1.82          if (status != 0) {
    1.83              SDL_SetError("glxSwapIntervalMESA failed");
    1.84 @@ -546,7 +562,16 @@
    1.85  int
    1.86  X11_GL_GetSwapInterval(_THIS)
    1.87  {
    1.88 -    if (_this->gl_data->glXGetSwapIntervalMESA) {
    1.89 +    if (_this->gl_data->glXSwapIntervalEXT) {
    1.90 +        Display *display = ((SDL_VideoData *) _this->driverdata)->display;
    1.91 +        const SDL_WindowData *windowdata = (SDL_WindowData *)
    1.92 +            _this->current_glwin->driverdata;
    1.93 +        Window drawable = windowdata->xwindow;
    1.94 +        unsigned int value = 0;
    1.95 +        _this->gl_data->glXQueryDrawable(display, drawable,
    1.96 +                                         GLX_SWAP_INTERVAL_EXT, &value);
    1.97 +        return (int) value;
    1.98 +    } else if (_this->gl_data->glXGetSwapIntervalMESA) {
    1.99          return _this->gl_data->glXGetSwapIntervalMESA();
   1.100      } else {
   1.101          return swapinterval;
     2.1 --- a/src/video/x11/SDL_x11opengl.h	Mon Jul 18 14:31:37 2011 -0700
     2.2 +++ b/src/video/x11/SDL_x11opengl.h	Mon Jul 18 14:34:19 2011 -0700
     2.3 @@ -31,26 +31,17 @@
     2.4  {
     2.5      SDL_bool HAS_GLX_EXT_visual_rating;
     2.6  
     2.7 -    void *(*glXGetProcAddress) (const GLubyte * procName);
     2.8 -
     2.9 -    XVisualInfo *(*glXChooseVisual)
    2.10 -      (Display * dpy, int screen, int *attribList);
    2.11 -
    2.12 -      GLXContext(*glXCreateContext)
    2.13 -      (Display * dpy, XVisualInfo * vis, GLXContext shareList, Bool direct);
    2.14 -
    2.15 -    void (*glXDestroyContext)
    2.16 -      (Display * dpy, GLXContext ctx);
    2.17 -
    2.18 -      Bool(*glXMakeCurrent)
    2.19 -      (Display * dpy, GLXDrawable drawable, GLXContext ctx);
    2.20 -
    2.21 -    void (*glXSwapBuffers)
    2.22 -      (Display * dpy, GLXDrawable drawable);
    2.23 -
    2.24 -    int (*glXSwapIntervalSGI) (int interval);
    2.25 -      GLint(*glXSwapIntervalMESA) (unsigned interval);
    2.26 -      GLint(*glXGetSwapIntervalMESA) (void);
    2.27 +    void *(*glXGetProcAddress) (const GLubyte*);
    2.28 +    XVisualInfo *(*glXChooseVisual) (Display*,int,int*);
    2.29 +    GLXContext (*glXCreateContext) (Display*,XVisualInfo*,GLXContext,Bool);
    2.30 +    void (*glXDestroyContext) (Display*, GLXContext);
    2.31 +    Bool(*glXMakeCurrent) (Display*,GLXDrawable,GLXContext);
    2.32 +    void (*glXSwapBuffers) (Display*, GLXDrawable);
    2.33 +    void (*glXQueryDrawable) (Display*,GLXDrawable,int,unsigned int*);
    2.34 +    void (*glXSwapIntervalEXT) (Display*,GLXDrawable,int);
    2.35 +    int (*glXSwapIntervalSGI) (int);
    2.36 +    int (*glXSwapIntervalMESA) (int);
    2.37 +    int (*glXGetSwapIntervalMESA) (void);
    2.38  };
    2.39  
    2.40  /* OpenGL functions */