Workaround for NVIDIA bug in glXSwapIntervalEXT.
This works around a bug in NVIDIA's implementation of
glXSwapIntervalEXT, where it ignores updates to what it *thinks* is the
current value, even though glXQueryDrawable returns a different value.
Bug reported to NVIDIA and will hopefully be a part of 319.xx.
Also a fix for invalidly treating glXSwapIntervalEXT as having an int
return value (it's void).
--- a/src/video/x11/SDL_x11opengl.c Mon Feb 11 16:51:00 2013 -0800
+++ b/src/video/x11/SDL_x11opengl.c Mon Feb 11 17:02:13 2013 -0800
@@ -332,7 +332,7 @@
_this->gl_data->HAS_GLX_EXT_swap_control_tear = SDL_FALSE;
if (HasExtension("GLX_EXT_swap_control", extensions)) {
_this->gl_data->glXSwapIntervalEXT =
- (int (*)(Display*,GLXDrawable,int))
+ (void (*)(Display*,GLXDrawable,int))
X11_GL_GetProcAddress(_this, "glXSwapIntervalEXT");
if (HasExtension("GLX_EXT_swap_control_tear", extensions)) {
_this->gl_data->HAS_GLX_EXT_swap_control_tear = SDL_TRUE;
@@ -667,13 +667,23 @@
Display *display = ((SDL_VideoData *) _this->driverdata)->display;
const SDL_WindowData *windowdata = (SDL_WindowData *)
_this->current_glwin->driverdata;
+
Window drawable = windowdata->xwindow;
- status = _this->gl_data->glXSwapIntervalEXT(display,drawable,interval);
- if (status != 0) {
- SDL_SetError("glxSwapIntervalEXT failed");
- } else {
- swapinterval = interval;
- }
+
+ /*
+ * This is a workaround for a bug in NVIDIA drivers. Bug has been reported
+ * and will be fixed in a future release (probably 319.xx).
+ *
+ * There's a bug where glXSetSwapIntervalEXT ignores updates because
+ * it has the wrong value cached. To work around it, we just run a no-op
+ * update to the current value.
+ */
+ int currentInterval = _this, X11_GL_GetSwapInterval(_this);
+ _this->gl_data->glXSwapIntervalEXT(display, drawable, currentInterval);
+ _this->gl_data->glXSwapIntervalEXT(display, drawable, interval);
+
+ status = 0;
+ swapinterval = interval;
} else if (_this->gl_data->glXSwapIntervalMESA) {
status = _this->gl_data->glXSwapIntervalMESA(interval);
if (status != 0) {
--- a/src/video/x11/SDL_x11opengl.h Mon Feb 11 16:51:00 2013 -0800
+++ b/src/video/x11/SDL_x11opengl.h Mon Feb 11 17:02:13 2013 -0800
@@ -40,7 +40,7 @@
Bool(*glXMakeCurrent) (Display*,GLXDrawable,GLXContext);
void (*glXSwapBuffers) (Display*, GLXDrawable);
void (*glXQueryDrawable) (Display*,GLXDrawable,int,unsigned int*);
- int (*glXSwapIntervalEXT) (Display*,GLXDrawable,int);
+ void (*glXSwapIntervalEXT) (Display*,GLXDrawable,int);
int (*glXSwapIntervalSGI) (int);
int (*glXSwapIntervalMESA) (int);
int (*glXGetSwapIntervalMESA) (void);