Add support for (GLX|WGL)_EXT_swap_control_tear.
This required a small public API change: SDL_GL_SetSwapInterval() now accepts negative values, and SDL_GL_GetSwapInterval() doesn't report errors anymore (if it can't work, it'll return zero as a reasonable default). If you need to test for errors, such as a lack of swap_control_tear support, check the results of SDL_GL_SetSwapInterval() when you set your desired value.
This commit is contained in:
parent
706ea79345
commit
2cd5fc4e97
10 changed files with 67 additions and 52 deletions
|
@ -789,7 +789,9 @@ extern DECLSPEC int SDLCALL SDL_GL_MakeCurrent(SDL_Window * window,
|
|||
* \brief Set the swap interval for the current OpenGL context.
|
||||
*
|
||||
* \param interval 0 for immediate updates, 1 for updates synchronized with the
|
||||
* vertical retrace.
|
||||
* vertical retrace. If the system supports it, you may
|
||||
* specify -1 to allow late swaps to happen immediately
|
||||
* instead of waiting for the next retrace.
|
||||
*
|
||||
* \return 0 on success, or -1 if setting the swap interval is not supported.
|
||||
*
|
||||
|
@ -801,8 +803,10 @@ extern DECLSPEC int SDLCALL SDL_GL_SetSwapInterval(int interval);
|
|||
* \brief Get the swap interval for the current OpenGL context.
|
||||
*
|
||||
* \return 0 if there is no vertical retrace synchronization, 1 if the buffer
|
||||
* swap is synchronized with the vertical retrace, and -1 if getting
|
||||
* the swap interval is not supported.
|
||||
* swap is synchronized with the vertical retrace, and -1 if late
|
||||
* swaps happen immediately instead of waiting for the next retrace.
|
||||
* If the system can't determine the swap interval, or there isn't a
|
||||
* valid current context, this will return 0 as a safe default.
|
||||
*
|
||||
* \sa SDL_GL_SetSwapInterval()
|
||||
*/
|
||||
|
|
|
@ -2578,16 +2578,13 @@ int
|
|||
SDL_GL_GetSwapInterval(void)
|
||||
{
|
||||
if (!_this) {
|
||||
SDL_UninitializedVideo();
|
||||
return -1;
|
||||
return 0;
|
||||
} else if (_this->current_glctx == NULL) {
|
||||
SDL_SetError("No OpenGL context has been made current");
|
||||
return -1;
|
||||
return 0;
|
||||
} else if (_this->GL_GetSwapInterval) {
|
||||
return _this->GL_GetSwapInterval(_this);
|
||||
} else {
|
||||
SDL_SetError("Getting the swap interval is not supported");
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -250,7 +250,7 @@ Cocoa_GL_GetSwapInterval(_THIS)
|
|||
NSAutoreleasePool *pool;
|
||||
NSOpenGLContext *nscontext;
|
||||
GLint value;
|
||||
int status;
|
||||
int status = 0;
|
||||
|
||||
pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
|
@ -258,9 +258,6 @@ Cocoa_GL_GetSwapInterval(_THIS)
|
|||
if (nscontext != nil) {
|
||||
[nscontext getValues:&value forParameter:NSOpenGLCPSwapInterval];
|
||||
status = (int)value;
|
||||
} else {
|
||||
SDL_SetError("No current OpenGL context");
|
||||
status = -1;
|
||||
}
|
||||
|
||||
[pool release];
|
||||
|
|
|
@ -250,8 +250,7 @@ DirectFB_GL_SetSwapInterval(_THIS, int interval)
|
|||
int
|
||||
DirectFB_GL_GetSwapInterval(_THIS)
|
||||
{
|
||||
SDL_Unsupported();
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -796,15 +796,7 @@ PND_gl_setswapinterval(_THIS, int interval)
|
|||
int
|
||||
PND_gl_getswapinterval(_THIS)
|
||||
{
|
||||
SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
|
||||
|
||||
if (phdata->egl_initialized != SDL_TRUE) {
|
||||
SDL_SetError("PND: GLES initialization failed, no OpenGL ES support");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Return default swap interval value */
|
||||
return phdata->swapinterval;
|
||||
return ((SDL_VideoData *) _this->driverdata)->swapinterval;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -112,10 +112,6 @@ WIN_GL_LoadLibrary(_THIS, const char *path)
|
|||
GetProcAddress(handle, "wglDeleteContext");
|
||||
_this->gl_data->wglMakeCurrent = (BOOL(WINAPI *) (HDC, HGLRC))
|
||||
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 ||
|
||||
!_this->gl_data->wglCreateContext ||
|
||||
|
@ -341,7 +337,7 @@ WIN_GL_InitExtensions(_THIS, HDC hdc)
|
|||
}
|
||||
|
||||
/* Check for WGL_ARB_pixel_format */
|
||||
_this->gl_data->WGL_ARB_pixel_format = 0;
|
||||
_this->gl_data->HAS_WGL_ARB_pixel_format = SDL_FALSE;
|
||||
if (HasExtension("WGL_ARB_pixel_format", extensions)) {
|
||||
_this->gl_data->wglChoosePixelFormatARB = (BOOL(WINAPI *)
|
||||
(HDC, const int *,
|
||||
|
@ -354,16 +350,20 @@ WIN_GL_InitExtensions(_THIS, HDC hdc)
|
|||
|
||||
if ((_this->gl_data->wglChoosePixelFormatARB != NULL) &&
|
||||
(_this->gl_data->wglGetPixelFormatAttribivARB != NULL)) {
|
||||
_this->gl_data->WGL_ARB_pixel_format = 1;
|
||||
_this->gl_data->HAS_WGL_ARB_pixel_format = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for WGL_EXT_swap_control */
|
||||
_this->gl_data->HAS_WGL_EXT_swap_control_tear = SDL_FALSE;
|
||||
if (HasExtension("WGL_EXT_swap_control", extensions)) {
|
||||
_this->gl_data->wglSwapIntervalEXT =
|
||||
WIN_GL_GetProcAddress(_this, "wglSwapIntervalEXT");
|
||||
_this->gl_data->wglGetSwapIntervalEXT =
|
||||
WIN_GL_GetProcAddress(_this, "wglGetSwapIntervalEXT");
|
||||
if (HasExtension("WGL_EXT_swap_control_tear", extensions)) {
|
||||
_this->gl_data->HAS_WGL_EXT_swap_control_tear = SDL_TRUE;
|
||||
}
|
||||
} else {
|
||||
_this->gl_data->wglSwapIntervalEXT = NULL;
|
||||
_this->gl_data->wglGetSwapIntervalEXT = NULL;
|
||||
|
@ -397,7 +397,7 @@ WIN_GL_ChoosePixelFormatARB(_THIS, int *iAttribs, float *fAttribs)
|
|||
|
||||
WIN_GL_InitExtensions(_this, hdc);
|
||||
|
||||
if (_this->gl_data->WGL_ARB_pixel_format) {
|
||||
if (_this->gl_data->HAS_WGL_ARB_pixel_format) {
|
||||
_this->gl_data->wglChoosePixelFormatARB(hdc, iAttribs, fAttribs,
|
||||
1, &pixel_format,
|
||||
&matching);
|
||||
|
@ -611,7 +611,9 @@ WIN_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
|
|||
int
|
||||
WIN_GL_SetSwapInterval(_THIS, int interval)
|
||||
{
|
||||
if (_this->gl_data->wglSwapIntervalEXT) {
|
||||
if ((interval < 0) && (!_this->gl_data->HAS_WGL_EXT_swap_control_tear)) {
|
||||
SDL_SetError("Negative swap interval unsupported in this GL");
|
||||
} else if (_this->gl_data->wglSwapIntervalEXT) {
|
||||
_this->gl_data->wglSwapIntervalEXT(interval);
|
||||
return 0;
|
||||
} else {
|
||||
|
@ -626,8 +628,8 @@ WIN_GL_GetSwapInterval(_THIS)
|
|||
if (_this->gl_data->wglGetSwapIntervalEXT) {
|
||||
return _this->gl_data->wglGetSwapIntervalEXT();
|
||||
} else {
|
||||
SDL_Unsupported();
|
||||
return -1;
|
||||
/*SDL_Unsupported();*/
|
||||
return 0; /* just say we're unsync'd. */
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,8 @@
|
|||
|
||||
struct SDL_GLDriverData
|
||||
{
|
||||
int WGL_ARB_pixel_format;
|
||||
SDL_bool HAS_WGL_ARB_pixel_format;
|
||||
SDL_bool HAS_WGL_EXT_swap_control_tear;
|
||||
|
||||
void *(WINAPI * wglGetProcAddress) (const char *proc);
|
||||
HGLRC(WINAPI * wglCreateContext) (HDC hdc);
|
||||
|
|
|
@ -105,6 +105,10 @@ typedef GLXContext(*PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display * dpy,
|
|||
#define GLX_MAX_SWAP_INTERVAL_EXT 0x20F2
|
||||
#endif
|
||||
|
||||
#ifndef GLX_EXT_swap_control_tear
|
||||
#define GLX_LATE_SWAPS_TEAR_EXT 0x20F3
|
||||
#endif
|
||||
|
||||
#define OPENGL_REQUIRES_DLOPEN
|
||||
#if defined(OPENGL_REQUIRES_DLOPEN) && defined(SDL_LOADSO_DLOPEN)
|
||||
#include <dlfcn.h>
|
||||
|
@ -318,11 +322,15 @@ X11_GL_InitExtensions(_THIS)
|
|||
extensions = NULL;
|
||||
}
|
||||
|
||||
/* Check for GLX_EXT_swap_control */
|
||||
/* Check for GLX_EXT_swap_control(_tear) */
|
||||
_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))
|
||||
X11_GL_GetProcAddress(_this, "glXSwapIntervalEXT");
|
||||
if (HasExtension("GLX_EXT_swap_control_tear", extensions)) {
|
||||
_this->gl_data->HAS_GLX_EXT_swap_control_tear = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for GLX_MESA_swap_control */
|
||||
|
@ -615,9 +623,11 @@ static int swapinterval = -1;
|
|||
int
|
||||
X11_GL_SetSwapInterval(_THIS, int interval)
|
||||
{
|
||||
int status;
|
||||
int status = -1;
|
||||
|
||||
if (_this->gl_data->glXSwapIntervalEXT) {
|
||||
if ((interval < 0) && (!_this->gl_data->HAS_GLX_EXT_swap_control_tear)) {
|
||||
SDL_SetError("Negative swap interval unsupported in this GL");
|
||||
} else if (_this->gl_data->glXSwapIntervalEXT) {
|
||||
Display *display = ((SDL_VideoData *) _this->driverdata)->display;
|
||||
const SDL_WindowData *windowdata = (SDL_WindowData *)
|
||||
_this->current_glwin->driverdata;
|
||||
|
@ -625,7 +635,6 @@ X11_GL_SetSwapInterval(_THIS, int interval)
|
|||
status = _this->gl_data->glXSwapIntervalEXT(display,drawable,interval);
|
||||
if (status != 0) {
|
||||
SDL_SetError("glxSwapIntervalEXT failed");
|
||||
status = -1;
|
||||
} else {
|
||||
swapinterval = interval;
|
||||
}
|
||||
|
@ -633,7 +642,6 @@ X11_GL_SetSwapInterval(_THIS, int interval)
|
|||
status = _this->gl_data->glXSwapIntervalMESA(interval);
|
||||
if (status != 0) {
|
||||
SDL_SetError("glxSwapIntervalMESA failed");
|
||||
status = -1;
|
||||
} else {
|
||||
swapinterval = interval;
|
||||
}
|
||||
|
@ -641,13 +649,11 @@ X11_GL_SetSwapInterval(_THIS, int interval)
|
|||
status = _this->gl_data->glXSwapIntervalSGI(interval);
|
||||
if (status != 0) {
|
||||
SDL_SetError("glxSwapIntervalSGI failed");
|
||||
status = -1;
|
||||
} else {
|
||||
swapinterval = interval;
|
||||
}
|
||||
} else {
|
||||
SDL_Unsupported();
|
||||
status = -1;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
@ -660,10 +666,23 @@ X11_GL_GetSwapInterval(_THIS)
|
|||
const SDL_WindowData *windowdata = (SDL_WindowData *)
|
||||
_this->current_glwin->driverdata;
|
||||
Window drawable = windowdata->xwindow;
|
||||
unsigned int value = 0;
|
||||
unsigned int allow_late_swap_tearing = 0;
|
||||
unsigned int interval = 0;
|
||||
|
||||
if (_this->gl_data->HAS_GLX_EXT_swap_control_tear) {
|
||||
_this->gl_data->glXQueryDrawable(display, drawable,
|
||||
GLX_SWAP_INTERVAL_EXT, &value);
|
||||
return (int) value;
|
||||
GLX_LATE_SWAPS_TEAR_EXT,
|
||||
&allow_late_swap_tearing);
|
||||
}
|
||||
|
||||
_this->gl_data->glXQueryDrawable(display, drawable,
|
||||
GLX_SWAP_INTERVAL_EXT, &interval);
|
||||
|
||||
if ((allow_late_swap_tearing) && (interval > 0)) {
|
||||
return -((int) interval);
|
||||
}
|
||||
|
||||
return (int) interval;
|
||||
} else if (_this->gl_data->glXGetSwapIntervalMESA) {
|
||||
return _this->gl_data->glXGetSwapIntervalMESA();
|
||||
} else {
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
struct SDL_GLDriverData
|
||||
{
|
||||
SDL_bool HAS_GLX_EXT_visual_rating;
|
||||
SDL_bool HAS_GLX_EXT_swap_control_tear;
|
||||
|
||||
void *(*glXGetProcAddress) (const GLubyte*);
|
||||
XVisualInfo *(*glXChooseVisual) (Display*,int,int*);
|
||||
|
|
|
@ -240,18 +240,21 @@ main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
if (state->render_flags & SDL_RENDERER_PRESENTVSYNC) {
|
||||
/* try late-swap-tearing first. If not supported, try normal vsync. */
|
||||
if (SDL_GL_SetSwapInterval(-1) == -1) {
|
||||
SDL_GL_SetSwapInterval(1);
|
||||
}
|
||||
} else {
|
||||
SDL_GL_SetSwapInterval(0);
|
||||
SDL_GL_SetSwapInterval(0); /* disable vsync. */
|
||||
}
|
||||
|
||||
SDL_GetCurrentDisplayMode(0, &mode);
|
||||
printf("Screen BPP : %d\n", SDL_BITSPERPIXEL(mode.format));
|
||||
printf("Swap Interval : %d\n", SDL_GL_GetSwapInterval());
|
||||
printf("\n");
|
||||
printf("Vendor : %s\n", glGetString(GL_VENDOR));
|
||||
printf("Renderer : %s\n", glGetString(GL_RENDERER));
|
||||
printf("Version : %s\n", glGetString(GL_VERSION));
|
||||
printf("Extensions : %s\n", glGetString(GL_EXTENSIONS));
|
||||
printf("\n");
|
||||
|
||||
status = SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &value);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue