From 38f0464ab0954ce37f35288e4c298d605b7e4e4d Mon Sep 17 00:00:00 2001 From: binary1248 Date: Tue, 13 Jan 2015 05:31:53 +0100 Subject: [PATCH] Added MESA and SGI swap interval implementations in order to fix v-sync not being set properly on some Unix systems (#727), added error message when setting v-sync fails on Windows systems. --- src/SFML/Window/Unix/GlxContext.cpp | 15 +++++++++++++ src/SFML/Window/Unix/GlxExtensions.cpp | 30 ++++++++++++++++++++++++-- src/SFML/Window/Unix/GlxExtensions.hpp | 11 ++++++++++ src/SFML/Window/Unix/GlxExtensions.txt | 2 ++ src/SFML/Window/Win32/WglContext.cpp | 5 ++++- 5 files changed, 60 insertions(+), 3 deletions(-) diff --git a/src/SFML/Window/Unix/GlxContext.cpp b/src/SFML/Window/Unix/GlxContext.cpp index 6b8d0198..906089b0 100644 --- a/src/SFML/Window/Unix/GlxContext.cpp +++ b/src/SFML/Window/Unix/GlxContext.cpp @@ -198,8 +198,23 @@ void GlxContext::setVerticalSyncEnabled(bool enabled) // Make sure that extensions are initialized ensureExtensionsInit(m_display, DefaultScreen(m_display)); + int result = 0; + + // Prioritize the EXT variant and fall back to MESA or SGI if needed + // We use the direct pointer to the MESA entry point instead of the alias + // because glx.h declares the entry point as an external function + // which would require us to link in an additional library if (sfglx_ext_EXT_swap_control == sfglx_LOAD_SUCCEEDED) glXSwapIntervalEXT(m_display, glXGetCurrentDrawable(), enabled ? 1 : 0); + else if (sfglx_ext_MESA_swap_control == sfglx_LOAD_SUCCEEDED) + result = sf_ptrc_glXSwapIntervalMESA(enabled ? 1 : 0); + else if (sfglx_ext_SGI_swap_control == sfglx_LOAD_SUCCEEDED) + result = glXSwapIntervalSGI(enabled ? 1 : 0); + else + err() << "Setting vertical sync not supported" << std::endl; + + if (result != 0) + err() << "Setting vertical sync failed" << std::endl; } diff --git a/src/SFML/Window/Unix/GlxExtensions.cpp b/src/SFML/Window/Unix/GlxExtensions.cpp index ecff851a..7a258a59 100644 --- a/src/SFML/Window/Unix/GlxExtensions.cpp +++ b/src/SFML/Window/Unix/GlxExtensions.cpp @@ -8,6 +8,8 @@ #define IntGetProcAddress(name) (*glXGetProcAddressARB)((const GLubyte*)name) int sfglx_ext_EXT_swap_control = sfglx_LOAD_FAILED; +int sfglx_ext_MESA_swap_control = sfglx_LOAD_FAILED; +int sfglx_ext_SGI_swap_control = sfglx_LOAD_FAILED; int sfglx_ext_ARB_multisample = sfglx_LOAD_FAILED; int sfglx_ext_ARB_create_context = sfglx_LOAD_FAILED; int sfglx_ext_ARB_create_context_profile = sfglx_LOAD_FAILED; @@ -22,6 +24,26 @@ static int Load_EXT_swap_control(void) return numFailed; } +int (CODEGEN_FUNCPTR *sf_ptrc_glXSwapIntervalMESA)(int) = NULL; + +static int Load_MESA_swap_control(void) +{ + int numFailed = 0; + sf_ptrc_glXSwapIntervalMESA = (int (CODEGEN_FUNCPTR *)(int))IntGetProcAddress("glXSwapIntervalMESA"); + if(!sf_ptrc_glXSwapIntervalMESA) numFailed++; + return numFailed; +} + +int (CODEGEN_FUNCPTR *sf_ptrc_glXSwapIntervalSGI)(int) = NULL; + +static int Load_SGI_swap_control(void) +{ + int numFailed = 0; + sf_ptrc_glXSwapIntervalSGI = (int (CODEGEN_FUNCPTR *)(int))IntGetProcAddress("glXSwapIntervalSGI"); + if(!sf_ptrc_glXSwapIntervalSGI) numFailed++; + return numFailed; +} + GLXContext (CODEGEN_FUNCPTR *sf_ptrc_glXCreateContextAttribsARB)(Display *, GLXFBConfig, GLXContext, Bool, const int *) = NULL; static int Load_ARB_create_context(void) @@ -40,14 +62,16 @@ typedef struct sfglx_StrToExtMap_s PFN_LOADFUNCPOINTERS LoadExtension; } sfglx_StrToExtMap; -static sfglx_StrToExtMap ExtensionMap[4] = { +static sfglx_StrToExtMap ExtensionMap[6] = { {"GLX_EXT_swap_control", &sfglx_ext_EXT_swap_control, Load_EXT_swap_control}, + {"GLX_MESA_swap_control", &sfglx_ext_MESA_swap_control, Load_MESA_swap_control}, + {"GLX_SGI_swap_control", &sfglx_ext_SGI_swap_control, Load_SGI_swap_control}, {"GLX_ARB_multisample", &sfglx_ext_ARB_multisample, NULL}, {"GLX_ARB_create_context", &sfglx_ext_ARB_create_context, Load_ARB_create_context}, {"GLX_ARB_create_context_profile", &sfglx_ext_ARB_create_context_profile, NULL}, }; -static int g_extensionMapSize = 4; +static int g_extensionMapSize = 6; static sfglx_StrToExtMap *FindExtEntry(const char *extensionName) { @@ -65,6 +89,8 @@ static sfglx_StrToExtMap *FindExtEntry(const char *extensionName) static void ClearExtensionVars(void) { sfglx_ext_EXT_swap_control = sfglx_LOAD_FAILED; + sfglx_ext_MESA_swap_control = sfglx_LOAD_FAILED; + sfglx_ext_SGI_swap_control = sfglx_LOAD_FAILED; sfglx_ext_ARB_multisample = sfglx_LOAD_FAILED; sfglx_ext_ARB_create_context = sfglx_LOAD_FAILED; sfglx_ext_ARB_create_context_profile = sfglx_LOAD_FAILED; diff --git a/src/SFML/Window/Unix/GlxExtensions.hpp b/src/SFML/Window/Unix/GlxExtensions.hpp index e635364a..7d1968d9 100644 --- a/src/SFML/Window/Unix/GlxExtensions.hpp +++ b/src/SFML/Window/Unix/GlxExtensions.hpp @@ -118,6 +118,8 @@ extern "C" { #endif /*__cplusplus*/ extern int sfglx_ext_EXT_swap_control; +extern int sfglx_ext_MESA_swap_control; +extern int sfglx_ext_SGI_swap_control; extern int sfglx_ext_ARB_multisample; extern int sfglx_ext_ARB_create_context; extern int sfglx_ext_ARB_create_context_profile; @@ -144,6 +146,15 @@ extern void (CODEGEN_FUNCPTR *sf_ptrc_glXSwapIntervalEXT)(Display *, GLXDrawable #define glXSwapIntervalEXT sf_ptrc_glXSwapIntervalEXT #endif /*GLX_EXT_swap_control*/ +// Declare entry point even if GLX header already provides glXSwapIntervalMESA +// We won't make use of an alias here +extern int (CODEGEN_FUNCPTR *sf_ptrc_glXSwapIntervalMESA)(int); + +#ifndef GLX_SGI_swap_control +#define GLX_SGI_swap_control 1 +extern int (CODEGEN_FUNCPTR *sf_ptrc_glXSwapIntervalSGI)(int); +#define glXSwapIntervalSGI sf_ptrc_glXSwapIntervalSGI +#endif /*GLX_SGI_swap_control*/ #ifndef GLX_ARB_create_context #define GLX_ARB_create_context 1 diff --git a/src/SFML/Window/Unix/GlxExtensions.txt b/src/SFML/Window/Unix/GlxExtensions.txt index ff7ed23d..b6b06fa9 100644 --- a/src/SFML/Window/Unix/GlxExtensions.txt +++ b/src/SFML/Window/Unix/GlxExtensions.txt @@ -4,6 +4,8 @@ // lua LoadGen.lua -style=pointer_c -spec=glX -indent=space -prefix=sf -extfile=GlxExtensions.txt GlxExtensions EXT_swap_control +// MESA_swap_control +SGI_swap_control GLX_ARB_multisample GLX_ARB_create_context GLX_ARB_create_context_profile \ No newline at end of file diff --git a/src/SFML/Window/Win32/WglContext.cpp b/src/SFML/Window/Win32/WglContext.cpp index a9afa023..bcdd9448 100644 --- a/src/SFML/Window/Win32/WglContext.cpp +++ b/src/SFML/Window/Win32/WglContext.cpp @@ -175,7 +175,10 @@ void WglContext::setVerticalSyncEnabled(bool enabled) ensureExtensionsInit(m_deviceContext); if (sfwgl_ext_EXT_swap_control == sfwgl_LOAD_SUCCEEDED) - wglSwapIntervalEXT(enabled ? 1 : 0); + { + if (wglSwapIntervalEXT(enabled ? 1 : 0) == FALSE) + err() << "Setting vertical sync failed" << std::endl; + } else { // wglSwapIntervalEXT not supported