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.

This commit is contained in:
binary1248 2015-01-13 05:31:53 +01:00
parent 3e397bff4b
commit 38f0464ab0
5 changed files with 60 additions and 3 deletions

View File

@ -198,8 +198,23 @@ void GlxContext::setVerticalSyncEnabled(bool enabled)
// Make sure that extensions are initialized // Make sure that extensions are initialized
ensureExtensionsInit(m_display, DefaultScreen(m_display)); 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) if (sfglx_ext_EXT_swap_control == sfglx_LOAD_SUCCEEDED)
glXSwapIntervalEXT(m_display, glXGetCurrentDrawable(), enabled ? 1 : 0); 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;
} }

View File

@ -8,6 +8,8 @@
#define IntGetProcAddress(name) (*glXGetProcAddressARB)((const GLubyte*)name) #define IntGetProcAddress(name) (*glXGetProcAddressARB)((const GLubyte*)name)
int sfglx_ext_EXT_swap_control = sfglx_LOAD_FAILED; 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_multisample = sfglx_LOAD_FAILED;
int sfglx_ext_ARB_create_context = sfglx_LOAD_FAILED; int sfglx_ext_ARB_create_context = sfglx_LOAD_FAILED;
int sfglx_ext_ARB_create_context_profile = 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; 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; GLXContext (CODEGEN_FUNCPTR *sf_ptrc_glXCreateContextAttribsARB)(Display *, GLXFBConfig, GLXContext, Bool, const int *) = NULL;
static int Load_ARB_create_context(void) static int Load_ARB_create_context(void)
@ -40,14 +62,16 @@ typedef struct sfglx_StrToExtMap_s
PFN_LOADFUNCPOINTERS LoadExtension; PFN_LOADFUNCPOINTERS LoadExtension;
} sfglx_StrToExtMap; } 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_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_multisample", &sfglx_ext_ARB_multisample, NULL},
{"GLX_ARB_create_context", &sfglx_ext_ARB_create_context, Load_ARB_create_context}, {"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}, {"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) static sfglx_StrToExtMap *FindExtEntry(const char *extensionName)
{ {
@ -65,6 +89,8 @@ static sfglx_StrToExtMap *FindExtEntry(const char *extensionName)
static void ClearExtensionVars(void) static void ClearExtensionVars(void)
{ {
sfglx_ext_EXT_swap_control = sfglx_LOAD_FAILED; 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_multisample = sfglx_LOAD_FAILED;
sfglx_ext_ARB_create_context = sfglx_LOAD_FAILED; sfglx_ext_ARB_create_context = sfglx_LOAD_FAILED;
sfglx_ext_ARB_create_context_profile = sfglx_LOAD_FAILED; sfglx_ext_ARB_create_context_profile = sfglx_LOAD_FAILED;

View File

@ -118,6 +118,8 @@ extern "C" {
#endif /*__cplusplus*/ #endif /*__cplusplus*/
extern int sfglx_ext_EXT_swap_control; 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_multisample;
extern int sfglx_ext_ARB_create_context; extern int sfglx_ext_ARB_create_context;
extern int sfglx_ext_ARB_create_context_profile; 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 #define glXSwapIntervalEXT sf_ptrc_glXSwapIntervalEXT
#endif /*GLX_EXT_swap_control*/ #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 #ifndef GLX_ARB_create_context
#define GLX_ARB_create_context 1 #define GLX_ARB_create_context 1

View File

@ -4,6 +4,8 @@
// lua LoadGen.lua -style=pointer_c -spec=glX -indent=space -prefix=sf -extfile=GlxExtensions.txt GlxExtensions // lua LoadGen.lua -style=pointer_c -spec=glX -indent=space -prefix=sf -extfile=GlxExtensions.txt GlxExtensions
EXT_swap_control EXT_swap_control
// MESA_swap_control
SGI_swap_control
GLX_ARB_multisample GLX_ARB_multisample
GLX_ARB_create_context GLX_ARB_create_context
GLX_ARB_create_context_profile GLX_ARB_create_context_profile

View File

@ -175,7 +175,10 @@ void WglContext::setVerticalSyncEnabled(bool enabled)
ensureExtensionsInit(m_deviceContext); ensureExtensionsInit(m_deviceContext);
if (sfwgl_ext_EXT_swap_control == sfwgl_LOAD_SUCCEEDED) 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 else
{ {
// wglSwapIntervalEXT not supported // wglSwapIntervalEXT not supported