Implemented bug #2, 117:
Date: Mon, 21 Mar 2005 12:06:14 +0100 From: Per Inge Mathisen Subject: Re: [SDL] Outstanding patches? The patch adds support for setting SDL_GL_SWAP_CONTROL to Windows and X11. In Windows you can also query this enum to check that it is working, or see what the default is - such functionality does not exist in GLX. For more information on the standards implemented: http://oss.sgi.com/projects/ogl-sample/registry/SGI/swap_control.txt http://oss.sgi.com/projects/ogl-sample/registry/EXT/wgl_swap_control.txt --HG-- extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%401671
This commit is contained in:
parent
f1c75141ad
commit
b32d3f9c24
10 changed files with 114 additions and 10 deletions
2
WhatsNew
2
WhatsNew
|
@ -4,6 +4,8 @@ This is a list of API changes in SDL's version history.
|
||||||
Version 1.0:
|
Version 1.0:
|
||||||
|
|
||||||
1.2.10:
|
1.2.10:
|
||||||
|
Added SDL_GL_SWAP_CONTROL to wait for vsync in OpenGL applications.
|
||||||
|
|
||||||
Added current_w and current_h to the SDL_VideoInfo structure,
|
Added current_w and current_h to the SDL_VideoInfo structure,
|
||||||
which is set to the desktop resolution during video intialization,
|
which is set to the desktop resolution during video intialization,
|
||||||
and then set to the current resolution when a video mode is set.
|
and then set to the current resolution when a video mode is set.
|
||||||
|
|
|
@ -213,7 +213,8 @@ typedef enum {
|
||||||
SDL_GL_ACCUM_ALPHA_SIZE,
|
SDL_GL_ACCUM_ALPHA_SIZE,
|
||||||
SDL_GL_STEREO,
|
SDL_GL_STEREO,
|
||||||
SDL_GL_MULTISAMPLEBUFFERS,
|
SDL_GL_MULTISAMPLEBUFFERS,
|
||||||
SDL_GL_MULTISAMPLESAMPLES
|
SDL_GL_MULTISAMPLESAMPLES,
|
||||||
|
SDL_GL_SWAP_CONTROL
|
||||||
} SDL_GLattr;
|
} SDL_GLattr;
|
||||||
|
|
||||||
/* flags for SDL_SetPalette() */
|
/* flags for SDL_SetPalette() */
|
||||||
|
|
|
@ -292,6 +292,7 @@ struct SDL_VideoDevice {
|
||||||
int stereo;
|
int stereo;
|
||||||
int multisamplebuffers;
|
int multisamplebuffers;
|
||||||
int multisamplesamples;
|
int multisamplesamples;
|
||||||
|
int swap_control;
|
||||||
int driver_loaded;
|
int driver_loaded;
|
||||||
char driver_path[256];
|
char driver_path[256];
|
||||||
void* dll_handle;
|
void* dll_handle;
|
||||||
|
|
|
@ -233,6 +233,7 @@ int SDL_VideoInit (const char *driver_name, Uint32 flags)
|
||||||
video->gl_config.stereo = 0;
|
video->gl_config.stereo = 0;
|
||||||
video->gl_config.multisamplebuffers = 0;
|
video->gl_config.multisamplebuffers = 0;
|
||||||
video->gl_config.multisamplesamples = 0;
|
video->gl_config.multisamplesamples = 0;
|
||||||
|
video->gl_config.swap_control = -1; /* not known, don't set */
|
||||||
|
|
||||||
/* Initialize the video subsystem */
|
/* Initialize the video subsystem */
|
||||||
SDL_memset(&vformat, 0, sizeof(vformat));
|
SDL_memset(&vformat, 0, sizeof(vformat));
|
||||||
|
@ -1474,6 +1475,9 @@ int SDL_GL_SetAttribute( SDL_GLattr attr, int value )
|
||||||
case SDL_GL_MULTISAMPLESAMPLES:
|
case SDL_GL_MULTISAMPLESAMPLES:
|
||||||
video->gl_config.multisamplesamples = value;
|
video->gl_config.multisamplesamples = value;
|
||||||
break;
|
break;
|
||||||
|
case SDL_GL_SWAP_CONTROL:
|
||||||
|
video->gl_config.swap_control = value;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
SDL_SetError("Unknown OpenGL attribute");
|
SDL_SetError("Unknown OpenGL attribute");
|
||||||
retval = -1;
|
retval = -1;
|
||||||
|
|
|
@ -132,6 +132,17 @@ int QZ_SetupOpenGL (_THIS, int bpp, Uint32 flags) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Synchronize QZ_GL_SwapBuffers() to vertical retrace.
|
||||||
|
* (Apple's documentation is not completely clear about what this setting
|
||||||
|
* exactly does, IMHO - for a detailed explanation see
|
||||||
|
* http://lists.apple.com/archives/mac-opengl/2006/Jan/msg00080.html )
|
||||||
|
*/
|
||||||
|
if ( this->gl_config.swap_control >= 0 ) {
|
||||||
|
long value;
|
||||||
|
value = this->gl_config.swap_control;
|
||||||
|
[ gl_context setValues: &value forParameter: NSOpenGLCPSwapInterval ];
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wisdom from Apple engineer in reference to UT2003's OpenGL performance:
|
* Wisdom from Apple engineer in reference to UT2003's OpenGL performance:
|
||||||
* "You are blowing a couple of the internal OpenGL function caches. This
|
* "You are blowing a couple of the internal OpenGL function caches. This
|
||||||
|
|
|
@ -177,6 +177,7 @@ int WIN_GL_SetupWindow(_THIS)
|
||||||
int iAttribs[64];
|
int iAttribs[64];
|
||||||
int *iAttr;
|
int *iAttr;
|
||||||
float fAttribs[1] = { 0 };
|
float fAttribs[1] = { 0 };
|
||||||
|
const char *wglext;
|
||||||
|
|
||||||
/* load the gl driver from a default path */
|
/* load the gl driver from a default path */
|
||||||
if ( ! this->gl_config.driver_loaded ) {
|
if ( ! this->gl_config.driver_loaded ) {
|
||||||
|
@ -323,7 +324,25 @@ int WIN_GL_SetupWindow(_THIS)
|
||||||
SDL_SetError("Unable to create GL context");
|
SDL_SetError("Unable to create GL context");
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
if ( WIN_GL_MakeCurrent(this) < 0 ) {
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
gl_active = 1;
|
gl_active = 1;
|
||||||
|
|
||||||
|
/* Vsync control under Windows. Checking glGetString here is
|
||||||
|
* somewhat a documented and reliable hack - it was originally
|
||||||
|
* as a feature added by mistake, but since so many people rely
|
||||||
|
* on it, it will not be removed. strstr should be safe here.*/
|
||||||
|
wglext = (const char *)this->glGetString(GL_EXTENSIONS);
|
||||||
|
if ( !SDL_strstr(wglext, "WGL_EXT_swap_control") ) {
|
||||||
|
this->gl_data->wglSwapIntervalEXT = NULL;
|
||||||
|
this->gl_data->wglGetSwapIntervalEXT = NULL;
|
||||||
|
}
|
||||||
|
if ( this->gl_config.swap_control >= 0 ) {
|
||||||
|
if ( this->gl_data->wglSwapIntervalEXT ) {
|
||||||
|
this->gl_data->wglSwapIntervalEXT(this->gl_config.swap_control);
|
||||||
|
}
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
SDL_SetError("WIN driver not configured with OpenGL");
|
SDL_SetError("WIN driver not configured with OpenGL");
|
||||||
#endif
|
#endif
|
||||||
|
@ -423,6 +442,12 @@ int WIN_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value)
|
||||||
case SDL_GL_MULTISAMPLESAMPLES:
|
case SDL_GL_MULTISAMPLESAMPLES:
|
||||||
wgl_attrib = WGL_SAMPLES_ARB;
|
wgl_attrib = WGL_SAMPLES_ARB;
|
||||||
break;
|
break;
|
||||||
|
case SDL_GL_SWAP_CONTROL:
|
||||||
|
if ( this->gl_data->wglGetSwapIntervalEXT ) {
|
||||||
|
return this->gl_data->wglGetSwapIntervalEXT();
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
@ -509,6 +534,8 @@ void WIN_GL_UnloadLibrary(_THIS)
|
||||||
this->gl_data->wglMakeCurrent = NULL;
|
this->gl_data->wglMakeCurrent = NULL;
|
||||||
this->gl_data->wglChoosePixelFormatARB = NULL;
|
this->gl_data->wglChoosePixelFormatARB = NULL;
|
||||||
this->gl_data->wglGetPixelFormatAttribivARB = NULL;
|
this->gl_data->wglGetPixelFormatAttribivARB = NULL;
|
||||||
|
this->gl_data->wglSwapIntervalEXT = NULL;
|
||||||
|
this->gl_data->wglGetSwapIntervalEXT = NULL;
|
||||||
|
|
||||||
this->gl_config.dll_handle = NULL;
|
this->gl_config.dll_handle = NULL;
|
||||||
this->gl_config.driver_loaded = 0;
|
this->gl_config.driver_loaded = 0;
|
||||||
|
@ -547,6 +574,10 @@ int WIN_GL_LoadLibrary(_THIS, const char* path)
|
||||||
GetProcAddress(handle, "wglDeleteContext");
|
GetProcAddress(handle, "wglDeleteContext");
|
||||||
this->gl_data->wglMakeCurrent = (BOOL (WINAPI *)(HDC, HGLRC))
|
this->gl_data->wglMakeCurrent = (BOOL (WINAPI *)(HDC, HGLRC))
|
||||||
GetProcAddress(handle, "wglMakeCurrent");
|
GetProcAddress(handle, "wglMakeCurrent");
|
||||||
|
this->gl_data->wglSwapIntervalEXT = (void (WINAPI *)(int))
|
||||||
|
GetProcAddress(handle, "wglSwapIntervalEXT");
|
||||||
|
this->gl_data->wglGetSwapIntervalEXT = (int (WINAPI *)(void))
|
||||||
|
GetProcAddress(handle, "wglGetSwapIntervalEXT");
|
||||||
|
|
||||||
if ( (this->gl_data->wglGetProcAddress == NULL) ||
|
if ( (this->gl_data->wglGetProcAddress == NULL) ||
|
||||||
(this->gl_data->wglCreateContext == NULL) ||
|
(this->gl_data->wglCreateContext == NULL) ||
|
||||||
|
|
|
@ -53,6 +53,8 @@ struct SDL_PrivateGLData {
|
||||||
UINT nAttributes,
|
UINT nAttributes,
|
||||||
const int *piAttributes,
|
const int *piAttributes,
|
||||||
int *piValues);
|
int *piValues);
|
||||||
|
void (WINAPI *wglSwapIntervalEXT)(int interval);
|
||||||
|
int (WINAPI *wglGetSwapIntervalEXT)(void);
|
||||||
#endif /* SDL_VIDEO_OPENGL */
|
#endif /* SDL_VIDEO_OPENGL */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -205,6 +205,8 @@ int X11_GL_CreateContext(_THIS)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
#if SDL_VIDEO_OPENGL_GLX
|
#if SDL_VIDEO_OPENGL_GLX
|
||||||
|
const char *glXext;
|
||||||
|
|
||||||
/* We do this to create a clean separation between X and GLX errors. */
|
/* We do this to create a clean separation between X and GLX errors. */
|
||||||
XSync( SDL_Display, False );
|
XSync( SDL_Display, False );
|
||||||
glx_context = this->gl_data->glXCreateContext(GFX_Display,
|
glx_context = this->gl_data->glXCreateContext(GFX_Display,
|
||||||
|
@ -213,10 +215,29 @@ int X11_GL_CreateContext(_THIS)
|
||||||
|
|
||||||
if ( glx_context == NULL ) {
|
if ( glx_context == NULL ) {
|
||||||
SDL_SetError("Could not create GL context");
|
SDL_SetError("Could not create GL context");
|
||||||
return -1;
|
return(-1);
|
||||||
|
}
|
||||||
|
if ( X11_GL_MakeCurrent(this) < 0 ) {
|
||||||
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
gl_active = 1;
|
gl_active = 1;
|
||||||
|
|
||||||
|
/* The use of strstr here should be safe */
|
||||||
|
glXext = this->gl_data->glXQueryExtensionsString(GFX_Display, DefaultScreen(GFX_Display));
|
||||||
|
if ( !SDL_strstr(glXext, "SGI_swap_control") ) {
|
||||||
|
this->gl_data->glXSwapIntervalSGI = NULL;
|
||||||
|
}
|
||||||
|
if ( !SDL_strstr(glXext, "GLX_MESA_swap_control") ) {
|
||||||
|
this->gl_data->glXSwapIntervalMESA = NULL;
|
||||||
|
this->gl_data->glXGetSwapIntervalMESA = NULL;
|
||||||
|
}
|
||||||
|
if ( this->gl_config.swap_control >= 0 ) {
|
||||||
|
if ( this->gl_data->glXSwapIntervalMESA ) {
|
||||||
|
this->gl_data->glXSwapIntervalMESA(this->gl_config.swap_control);
|
||||||
|
} else if ( this->gl_data->glXSwapIntervalSGI ) {
|
||||||
|
this->gl_data->glXSwapIntervalSGI(this->gl_config.swap_control);
|
||||||
|
}
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
SDL_SetError("X11 driver not configured with OpenGL");
|
SDL_SetError("X11 driver not configured with OpenGL");
|
||||||
#endif
|
#endif
|
||||||
|
@ -319,6 +340,13 @@ int X11_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value)
|
||||||
case SDL_GL_MULTISAMPLESAMPLES:
|
case SDL_GL_MULTISAMPLESAMPLES:
|
||||||
glx_attrib = GLX_SAMPLES_ARB;
|
glx_attrib = GLX_SAMPLES_ARB;
|
||||||
break;
|
break;
|
||||||
|
case SDL_GL_SWAP_CONTROL:
|
||||||
|
if ( this->gl_data->glXGetSwapIntervalMESA ) {
|
||||||
|
return this->gl_data->glXGetSwapIntervalMESA();
|
||||||
|
} else {
|
||||||
|
return -1 /*(this->gl_config.swap_control > 0)*/;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
@ -348,6 +376,9 @@ void X11_GL_UnloadLibrary(_THIS)
|
||||||
this->gl_data->glXDestroyContext = NULL;
|
this->gl_data->glXDestroyContext = NULL;
|
||||||
this->gl_data->glXMakeCurrent = NULL;
|
this->gl_data->glXMakeCurrent = NULL;
|
||||||
this->gl_data->glXSwapBuffers = NULL;
|
this->gl_data->glXSwapBuffers = NULL;
|
||||||
|
this->gl_data->glXSwapIntervalSGI = NULL;
|
||||||
|
this->gl_data->glXSwapIntervalMESA = NULL;
|
||||||
|
this->gl_data->glXGetSwapIntervalMESA = NULL;
|
||||||
|
|
||||||
this->gl_config.dll_handle = NULL;
|
this->gl_config.dll_handle = NULL;
|
||||||
this->gl_config.driver_loaded = 0;
|
this->gl_config.driver_loaded = 0;
|
||||||
|
@ -400,7 +431,12 @@ int X11_GL_LoadLibrary(_THIS, const char* path)
|
||||||
(int (*)(Display *, XVisualInfo *, int, int *)) SDL_LoadFunction(handle, "glXGetConfig");
|
(int (*)(Display *, XVisualInfo *, int, int *)) SDL_LoadFunction(handle, "glXGetConfig");
|
||||||
this->gl_data->glXQueryExtensionsString =
|
this->gl_data->glXQueryExtensionsString =
|
||||||
(const char *(*)(Display *, int)) SDL_LoadFunction(handle, "glXQueryExtensionsString");
|
(const char *(*)(Display *, int)) SDL_LoadFunction(handle, "glXQueryExtensionsString");
|
||||||
|
this->gl_data->glXSwapIntervalSGI =
|
||||||
|
(int (*)(int)) SDL_LoadFunction(handle, "glXSwapIntervalSGI");
|
||||||
|
this->gl_data->glXSwapIntervalMESA =
|
||||||
|
(GLint (*)(unsigned)) SDL_LoadFunction(handle, "glXSwapIntervalMESA");
|
||||||
|
this->gl_data->glXGetSwapIntervalMESA =
|
||||||
|
(GLint (*)(void)) SDL_LoadFunction(handle, "glXGetSwapIntervalMESA");
|
||||||
|
|
||||||
if ( (this->gl_data->glXChooseVisual == NULL) ||
|
if ( (this->gl_data->glXChooseVisual == NULL) ||
|
||||||
(this->gl_data->glXCreateContext == NULL) ||
|
(this->gl_data->glXCreateContext == NULL) ||
|
||||||
|
|
|
@ -71,6 +71,9 @@ struct SDL_PrivateGLData {
|
||||||
( Display* dpy,
|
( Display* dpy,
|
||||||
int screen );
|
int screen );
|
||||||
|
|
||||||
|
int (*glXSwapIntervalSGI) ( int interval );
|
||||||
|
GLint (*glXSwapIntervalMESA) ( unsigned interval );
|
||||||
|
GLint (*glXGetSwapIntervalMESA) ( void );
|
||||||
|
|
||||||
#endif /* SDL_VIDEO_OPENGL_GLX */
|
#endif /* SDL_VIDEO_OPENGL_GLX */
|
||||||
};
|
};
|
||||||
|
|
|
@ -445,7 +445,7 @@ void DrawLogoBlit(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
int RunGLTest( int argc, char* argv[],
|
int RunGLTest( int argc, char* argv[],
|
||||||
int logo, int logocursor, int slowly, int bpp, float gamma, int noframe, int fsaa )
|
int logo, int logocursor, int slowly, int bpp, float gamma, int noframe, int fsaa, int sync )
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int rgb_size[3];
|
int rgb_size[3];
|
||||||
|
@ -531,6 +531,11 @@ int RunGLTest( int argc, char* argv[],
|
||||||
SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 1 );
|
SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 1 );
|
||||||
SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, fsaa );
|
SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, fsaa );
|
||||||
}
|
}
|
||||||
|
if ( sync ) {
|
||||||
|
SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, 1 );
|
||||||
|
} else {
|
||||||
|
SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, 0 );
|
||||||
|
}
|
||||||
if ( SDL_SetVideoMode( w, h, bpp, video_flags ) == NULL ) {
|
if ( SDL_SetVideoMode( w, h, bpp, video_flags ) == NULL ) {
|
||||||
fprintf(stderr, "Couldn't set GL mode: %s\n", SDL_GetError());
|
fprintf(stderr, "Couldn't set GL mode: %s\n", SDL_GetError());
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
|
@ -561,6 +566,10 @@ int RunGLTest( int argc, char* argv[],
|
||||||
SDL_GL_GetAttribute( SDL_GL_MULTISAMPLESAMPLES, &value );
|
SDL_GL_GetAttribute( SDL_GL_MULTISAMPLESAMPLES, &value );
|
||||||
printf("SDL_GL_MULTISAMPLESAMPLES: requested %d, got %d\n", fsaa, value );
|
printf("SDL_GL_MULTISAMPLESAMPLES: requested %d, got %d\n", fsaa, value );
|
||||||
}
|
}
|
||||||
|
if ( sync ) {
|
||||||
|
SDL_GL_GetAttribute( SDL_GL_SWAP_CONTROL, &value );
|
||||||
|
printf( "SDL_GL_SWAP_CONTROL: requested 1, got %d\n", value );
|
||||||
|
}
|
||||||
|
|
||||||
/* Set the window manager title bar */
|
/* Set the window manager title bar */
|
||||||
SDL_WM_SetCaption( "SDL GL test", "testgl" );
|
SDL_WM_SetCaption( "SDL GL test", "testgl" );
|
||||||
|
@ -770,6 +779,7 @@ int main(int argc, char *argv[])
|
||||||
float gamma = 0.0;
|
float gamma = 0.0;
|
||||||
int noframe = 0;
|
int noframe = 0;
|
||||||
int fsaa = 0;
|
int fsaa = 0;
|
||||||
|
int sync = 0;
|
||||||
|
|
||||||
logo = 0;
|
logo = 0;
|
||||||
slowly = 0;
|
slowly = 0;
|
||||||
|
@ -804,6 +814,9 @@ int main(int argc, char *argv[])
|
||||||
if ( strcmp(argv[i], "-fsaa") == 0 ) {
|
if ( strcmp(argv[i], "-fsaa") == 0 ) {
|
||||||
++fsaa;
|
++fsaa;
|
||||||
}
|
}
|
||||||
|
if ( strcmp(argv[i], "-sync") == 0 ) {
|
||||||
|
++sync;
|
||||||
|
}
|
||||||
if ( strncmp(argv[i], "-h", 2) == 0 ) {
|
if ( strncmp(argv[i], "-h", 2) == 0 ) {
|
||||||
printf(
|
printf(
|
||||||
"Usage: %s [-twice] [-logo] [-logocursor] [-slow] [-bpp n] [-gamma n] [-noframe] [-fsaa] [-fullscreen]\n",
|
"Usage: %s [-twice] [-logo] [-logocursor] [-slow] [-bpp n] [-gamma n] [-noframe] [-fsaa] [-fullscreen]\n",
|
||||||
|
@ -812,7 +825,7 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for ( i=0; i<numtests; ++i ) {
|
for ( i=0; i<numtests; ++i ) {
|
||||||
RunGLTest(argc, argv, logo, logocursor, slowly, bpp, gamma, noframe, fsaa);
|
RunGLTest(argc, argv, logo, logocursor, slowly, bpp, gamma, noframe, fsaa, sync);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue