mirror of
https://github.com/bkaradzic/bgfx.git
synced 2026-02-17 20:52:36 +01:00
Check for GLX vblank extensions more properly.
Previously, the code checked for an extension by checking if the pointer returned from
glXGetProcAddress was NULL or not.
But in truth, you can get a non-NULL pointer even if that extension is not supported.
Now, we parse the glXQueryExtensionsString() results.
GLFW code that does similar checks, for reference: 51bb76c7c3/src/glx_context.c (L208)
fixes #1367
This commit is contained in:
@@ -57,6 +57,32 @@ namespace bgfx { namespace gl
|
||||
GLXContext m_context;
|
||||
};
|
||||
|
||||
static bool haveGlxExtension(const char* _ext, const char* _extList)
|
||||
{
|
||||
// _extList is assumed to be a space-separated, null-terminated list of
|
||||
// extension names, and no extension name ever contains a space.
|
||||
const char* end = _extList + bx::strLen(_extList);
|
||||
const char* searchStart = _extList;
|
||||
for(;;)
|
||||
{
|
||||
bx::StringView found = bx::strFind(searchStart, _ext);
|
||||
if (found.isEmpty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// We found the substring, but need an exact match, with a word
|
||||
// boundary at both the front and back of the found spot.
|
||||
if ((found.getPtr() == _extList || *(found.getPtr() - 1) == ' ')
|
||||
&& (found.getTerm() == end || *found.getTerm() == ' '))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
// else, keep searching
|
||||
searchStart = found.getTerm();
|
||||
}
|
||||
}
|
||||
|
||||
void GlContext::create(uint32_t _width, uint32_t _height)
|
||||
{
|
||||
BX_UNUSED(_width, _height);
|
||||
@@ -196,27 +222,35 @@ namespace bgfx { namespace gl
|
||||
glXMakeCurrent(m_display, (::Window)g_platformData.nwh, m_context);
|
||||
m_current = NULL;
|
||||
|
||||
glXSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)glXGetProcAddress( (const GLubyte*)"glXSwapIntervalEXT");
|
||||
if (NULL != glXSwapIntervalEXT)
|
||||
const char* extensions = glXQueryExtensionsString(m_display, DefaultScreen(m_display));
|
||||
if (NULL != extensions)
|
||||
{
|
||||
BX_TRACE("Using glXSwapIntervalEXT.");
|
||||
glXSwapIntervalEXT(m_display, (::Window)g_platformData.nwh, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
glXSwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC)glXGetProcAddress( (const GLubyte*)"glXSwapIntervalMESA");
|
||||
if (NULL != glXSwapIntervalMESA)
|
||||
{
|
||||
BX_TRACE("Using glXSwapIntervalMESA.");
|
||||
glXSwapIntervalMESA(0);
|
||||
bool foundSwapControl = false;
|
||||
if (haveGlxExtension("GLX_EXT_swap_control", extensions)) {
|
||||
glXSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)glXGetProcAddress( (const GLubyte*)"glXSwapIntervalEXT");
|
||||
if (NULL != glXSwapIntervalEXT)
|
||||
{
|
||||
BX_TRACE("Using glXSwapIntervalEXT.");
|
||||
glXSwapIntervalEXT(m_display, (::Window)g_platformData.nwh, 0);
|
||||
foundSwapControl = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!foundSwapControl && haveGlxExtension("GLX_MESA_swap_control", extensions)) {
|
||||
glXSwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC)glXGetProcAddress( (const GLubyte*)"glXSwapIntervalMESA");
|
||||
if (NULL != glXSwapIntervalMESA)
|
||||
{
|
||||
BX_TRACE("Using glXSwapIntervalMESA.");
|
||||
glXSwapIntervalMESA(0);
|
||||
foundSwapControl = true;
|
||||
}
|
||||
}
|
||||
if (!foundSwapControl && haveGlxExtension("GLX_SGI_swap_control", extensions)) {
|
||||
glXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)glXGetProcAddress( (const GLubyte*)"glXSwapIntervalSGI");
|
||||
if (NULL != glXSwapIntervalSGI)
|
||||
{
|
||||
BX_TRACE("Using glXSwapIntervalSGI.");
|
||||
glXSwapIntervalSGI(0);
|
||||
foundSwapControl = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user