Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Commit

Permalink
Added support for GLX_EXT_swap_control, and cleaned up some other ext…
Browse files Browse the repository at this point in the history
…ensions.

This allows the Nvidia Linux drivers to use SDL_GL_SetSwapInterval(0).
  • Loading branch information
icculus committed Jul 18, 2011
1 parent 379fcdc commit 32f2a68
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 35 deletions.
55 changes: 40 additions & 15 deletions src/video/x11/SDL_x11opengl.c
Expand Up @@ -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 ||
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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");
Expand All @@ -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;
Expand Down
31 changes: 11 additions & 20 deletions src/video/x11/SDL_x11opengl.h
Expand Up @@ -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 */
Expand Down

0 comments on commit 32f2a68

Please sign in to comment.