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.
|
* \brief Set the swap interval for the current OpenGL context.
|
||||||
*
|
*
|
||||||
* \param interval 0 for immediate updates, 1 for updates synchronized with the
|
* \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.
|
* \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.
|
* \brief Get the swap interval for the current OpenGL context.
|
||||||
*
|
*
|
||||||
* \return 0 if there is no vertical retrace synchronization, 1 if the buffer
|
* \return 0 if there is no vertical retrace synchronization, 1 if the buffer
|
||||||
* swap is synchronized with the vertical retrace, and -1 if getting
|
* swap is synchronized with the vertical retrace, and -1 if late
|
||||||
* the swap interval is not supported.
|
* 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()
|
* \sa SDL_GL_SetSwapInterval()
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2578,16 +2578,13 @@ int
|
||||||
SDL_GL_GetSwapInterval(void)
|
SDL_GL_GetSwapInterval(void)
|
||||||
{
|
{
|
||||||
if (!_this) {
|
if (!_this) {
|
||||||
SDL_UninitializedVideo();
|
return 0;
|
||||||
return -1;
|
|
||||||
} else if (_this->current_glctx == NULL) {
|
} else if (_this->current_glctx == NULL) {
|
||||||
SDL_SetError("No OpenGL context has been made current");
|
return 0;
|
||||||
return -1;
|
|
||||||
} else if (_this->GL_GetSwapInterval) {
|
} else if (_this->GL_GetSwapInterval) {
|
||||||
return _this->GL_GetSwapInterval(_this);
|
return _this->GL_GetSwapInterval(_this);
|
||||||
} else {
|
} else {
|
||||||
SDL_SetError("Getting the swap interval is not supported");
|
return 0;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -250,7 +250,7 @@ Cocoa_GL_GetSwapInterval(_THIS)
|
||||||
NSAutoreleasePool *pool;
|
NSAutoreleasePool *pool;
|
||||||
NSOpenGLContext *nscontext;
|
NSOpenGLContext *nscontext;
|
||||||
GLint value;
|
GLint value;
|
||||||
int status;
|
int status = 0;
|
||||||
|
|
||||||
pool = [[NSAutoreleasePool alloc] init];
|
pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
|
||||||
|
@ -258,9 +258,6 @@ Cocoa_GL_GetSwapInterval(_THIS)
|
||||||
if (nscontext != nil) {
|
if (nscontext != nil) {
|
||||||
[nscontext getValues:&value forParameter:NSOpenGLCPSwapInterval];
|
[nscontext getValues:&value forParameter:NSOpenGLCPSwapInterval];
|
||||||
status = (int)value;
|
status = (int)value;
|
||||||
} else {
|
|
||||||
SDL_SetError("No current OpenGL context");
|
|
||||||
status = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[pool release];
|
[pool release];
|
||||||
|
|
|
@ -250,8 +250,7 @@ DirectFB_GL_SetSwapInterval(_THIS, int interval)
|
||||||
int
|
int
|
||||||
DirectFB_GL_GetSwapInterval(_THIS)
|
DirectFB_GL_GetSwapInterval(_THIS)
|
||||||
{
|
{
|
||||||
SDL_Unsupported();
|
return 0;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -796,15 +796,7 @@ PND_gl_setswapinterval(_THIS, int interval)
|
||||||
int
|
int
|
||||||
PND_gl_getswapinterval(_THIS)
|
PND_gl_getswapinterval(_THIS)
|
||||||
{
|
{
|
||||||
SDL_VideoData *phdata = (SDL_VideoData *) _this->driverdata;
|
return ((SDL_VideoData *) _this->driverdata)->swapinterval;
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -112,10 +112,6 @@ 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 ||
|
if (!_this->gl_data->wglGetProcAddress ||
|
||||||
!_this->gl_data->wglCreateContext ||
|
!_this->gl_data->wglCreateContext ||
|
||||||
|
@ -341,7 +337,7 @@ WIN_GL_InitExtensions(_THIS, HDC hdc)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for WGL_ARB_pixel_format */
|
/* 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)) {
|
if (HasExtension("WGL_ARB_pixel_format", extensions)) {
|
||||||
_this->gl_data->wglChoosePixelFormatARB = (BOOL(WINAPI *)
|
_this->gl_data->wglChoosePixelFormatARB = (BOOL(WINAPI *)
|
||||||
(HDC, const int *,
|
(HDC, const int *,
|
||||||
|
@ -354,16 +350,20 @@ WIN_GL_InitExtensions(_THIS, HDC hdc)
|
||||||
|
|
||||||
if ((_this->gl_data->wglChoosePixelFormatARB != NULL) &&
|
if ((_this->gl_data->wglChoosePixelFormatARB != NULL) &&
|
||||||
(_this->gl_data->wglGetPixelFormatAttribivARB != 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 */
|
/* Check for WGL_EXT_swap_control */
|
||||||
|
_this->gl_data->HAS_WGL_EXT_swap_control_tear = SDL_FALSE;
|
||||||
if (HasExtension("WGL_EXT_swap_control", extensions)) {
|
if (HasExtension("WGL_EXT_swap_control", extensions)) {
|
||||||
_this->gl_data->wglSwapIntervalEXT =
|
_this->gl_data->wglSwapIntervalEXT =
|
||||||
WIN_GL_GetProcAddress(_this, "wglSwapIntervalEXT");
|
WIN_GL_GetProcAddress(_this, "wglSwapIntervalEXT");
|
||||||
_this->gl_data->wglGetSwapIntervalEXT =
|
_this->gl_data->wglGetSwapIntervalEXT =
|
||||||
WIN_GL_GetProcAddress(_this, "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 {
|
} else {
|
||||||
_this->gl_data->wglSwapIntervalEXT = NULL;
|
_this->gl_data->wglSwapIntervalEXT = NULL;
|
||||||
_this->gl_data->wglGetSwapIntervalEXT = NULL;
|
_this->gl_data->wglGetSwapIntervalEXT = NULL;
|
||||||
|
@ -397,7 +397,7 @@ WIN_GL_ChoosePixelFormatARB(_THIS, int *iAttribs, float *fAttribs)
|
||||||
|
|
||||||
WIN_GL_InitExtensions(_this, hdc);
|
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,
|
_this->gl_data->wglChoosePixelFormatARB(hdc, iAttribs, fAttribs,
|
||||||
1, &pixel_format,
|
1, &pixel_format,
|
||||||
&matching);
|
&matching);
|
||||||
|
@ -611,7 +611,9 @@ WIN_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
|
||||||
int
|
int
|
||||||
WIN_GL_SetSwapInterval(_THIS, int interval)
|
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);
|
_this->gl_data->wglSwapIntervalEXT(interval);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -626,8 +628,8 @@ WIN_GL_GetSwapInterval(_THIS)
|
||||||
if (_this->gl_data->wglGetSwapIntervalEXT) {
|
if (_this->gl_data->wglGetSwapIntervalEXT) {
|
||||||
return _this->gl_data->wglGetSwapIntervalEXT();
|
return _this->gl_data->wglGetSwapIntervalEXT();
|
||||||
} else {
|
} else {
|
||||||
SDL_Unsupported();
|
/*SDL_Unsupported();*/
|
||||||
return -1;
|
return 0; /* just say we're unsync'd. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,8 @@
|
||||||
|
|
||||||
struct SDL_GLDriverData
|
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);
|
void *(WINAPI * wglGetProcAddress) (const char *proc);
|
||||||
HGLRC(WINAPI * wglCreateContext) (HDC hdc);
|
HGLRC(WINAPI * wglCreateContext) (HDC hdc);
|
||||||
|
|
|
@ -105,6 +105,10 @@ typedef GLXContext(*PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display * dpy,
|
||||||
#define GLX_MAX_SWAP_INTERVAL_EXT 0x20F2
|
#define GLX_MAX_SWAP_INTERVAL_EXT 0x20F2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef GLX_EXT_swap_control_tear
|
||||||
|
#define GLX_LATE_SWAPS_TEAR_EXT 0x20F3
|
||||||
|
#endif
|
||||||
|
|
||||||
#define OPENGL_REQUIRES_DLOPEN
|
#define OPENGL_REQUIRES_DLOPEN
|
||||||
#if defined(OPENGL_REQUIRES_DLOPEN) && defined(SDL_LOADSO_DLOPEN)
|
#if defined(OPENGL_REQUIRES_DLOPEN) && defined(SDL_LOADSO_DLOPEN)
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
@ -318,11 +322,15 @@ X11_GL_InitExtensions(_THIS)
|
||||||
extensions = NULL;
|
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)) {
|
if (HasExtension("GLX_EXT_swap_control", extensions)) {
|
||||||
_this->gl_data->glXSwapIntervalEXT =
|
_this->gl_data->glXSwapIntervalEXT =
|
||||||
(int (*)(Display*,GLXDrawable,int))
|
(int (*)(Display*,GLXDrawable,int))
|
||||||
X11_GL_GetProcAddress(_this, "glXSwapIntervalEXT");
|
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 */
|
/* Check for GLX_MESA_swap_control */
|
||||||
|
@ -615,9 +623,11 @@ static int swapinterval = -1;
|
||||||
int
|
int
|
||||||
X11_GL_SetSwapInterval(_THIS, int interval)
|
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;
|
Display *display = ((SDL_VideoData *) _this->driverdata)->display;
|
||||||
const SDL_WindowData *windowdata = (SDL_WindowData *)
|
const SDL_WindowData *windowdata = (SDL_WindowData *)
|
||||||
_this->current_glwin->driverdata;
|
_this->current_glwin->driverdata;
|
||||||
|
@ -625,7 +635,6 @@ X11_GL_SetSwapInterval(_THIS, int interval)
|
||||||
status = _this->gl_data->glXSwapIntervalEXT(display,drawable,interval);
|
status = _this->gl_data->glXSwapIntervalEXT(display,drawable,interval);
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
SDL_SetError("glxSwapIntervalEXT failed");
|
SDL_SetError("glxSwapIntervalEXT failed");
|
||||||
status = -1;
|
|
||||||
} else {
|
} else {
|
||||||
swapinterval = interval;
|
swapinterval = interval;
|
||||||
}
|
}
|
||||||
|
@ -633,7 +642,6 @@ X11_GL_SetSwapInterval(_THIS, int interval)
|
||||||
status = _this->gl_data->glXSwapIntervalMESA(interval);
|
status = _this->gl_data->glXSwapIntervalMESA(interval);
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
SDL_SetError("glxSwapIntervalMESA failed");
|
SDL_SetError("glxSwapIntervalMESA failed");
|
||||||
status = -1;
|
|
||||||
} else {
|
} else {
|
||||||
swapinterval = interval;
|
swapinterval = interval;
|
||||||
}
|
}
|
||||||
|
@ -641,13 +649,11 @@ X11_GL_SetSwapInterval(_THIS, int interval)
|
||||||
status = _this->gl_data->glXSwapIntervalSGI(interval);
|
status = _this->gl_data->glXSwapIntervalSGI(interval);
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
SDL_SetError("glxSwapIntervalSGI failed");
|
SDL_SetError("glxSwapIntervalSGI failed");
|
||||||
status = -1;
|
|
||||||
} else {
|
} else {
|
||||||
swapinterval = interval;
|
swapinterval = interval;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SDL_Unsupported();
|
SDL_Unsupported();
|
||||||
status = -1;
|
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -660,10 +666,23 @@ X11_GL_GetSwapInterval(_THIS)
|
||||||
const SDL_WindowData *windowdata = (SDL_WindowData *)
|
const SDL_WindowData *windowdata = (SDL_WindowData *)
|
||||||
_this->current_glwin->driverdata;
|
_this->current_glwin->driverdata;
|
||||||
Window drawable = windowdata->xwindow;
|
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,
|
_this->gl_data->glXQueryDrawable(display, drawable,
|
||||||
GLX_SWAP_INTERVAL_EXT, &value);
|
GLX_LATE_SWAPS_TEAR_EXT,
|
||||||
return (int) value;
|
&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) {
|
} else if (_this->gl_data->glXGetSwapIntervalMESA) {
|
||||||
return _this->gl_data->glXGetSwapIntervalMESA();
|
return _this->gl_data->glXGetSwapIntervalMESA();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
struct SDL_GLDriverData
|
struct SDL_GLDriverData
|
||||||
{
|
{
|
||||||
SDL_bool HAS_GLX_EXT_visual_rating;
|
SDL_bool HAS_GLX_EXT_visual_rating;
|
||||||
|
SDL_bool HAS_GLX_EXT_swap_control_tear;
|
||||||
|
|
||||||
void *(*glXGetProcAddress) (const GLubyte*);
|
void *(*glXGetProcAddress) (const GLubyte*);
|
||||||
XVisualInfo *(*glXChooseVisual) (Display*,int,int*);
|
XVisualInfo *(*glXChooseVisual) (Display*,int,int*);
|
||||||
|
|
|
@ -240,18 +240,21 @@ main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state->render_flags & SDL_RENDERER_PRESENTVSYNC) {
|
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);
|
SDL_GL_SetSwapInterval(1);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
SDL_GL_SetSwapInterval(0);
|
SDL_GL_SetSwapInterval(0); /* disable vsync. */
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_GetCurrentDisplayMode(0, &mode);
|
SDL_GetCurrentDisplayMode(0, &mode);
|
||||||
printf("Screen BPP : %d\n", SDL_BITSPERPIXEL(mode.format));
|
printf("Screen BPP : %d\n", SDL_BITSPERPIXEL(mode.format));
|
||||||
|
printf("Swap Interval : %d\n", SDL_GL_GetSwapInterval());
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf("Vendor : %s\n", glGetString(GL_VENDOR));
|
printf("Vendor : %s\n", glGetString(GL_VENDOR));
|
||||||
printf("Renderer : %s\n", glGetString(GL_RENDERER));
|
printf("Renderer : %s\n", glGetString(GL_RENDERER));
|
||||||
printf("Version : %s\n", glGetString(GL_VERSION));
|
printf("Version : %s\n", glGetString(GL_VERSION));
|
||||||
printf("Extensions : %s\n", glGetString(GL_EXTENSIONS));
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
status = SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &value);
|
status = SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &value);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue