GLInterface: Use EXT_swap_control or MESA_swap_control over SGI
The SGI extension does not define calling SwapInterval with a parameter of zero as valid. It was just lucky that drivers interpreted this as vsync off. The EXT_swap_control extension defines zero as a valid value. Mesa does not appear to support the EXT variant, so we fall back to MESA_swap_control here, which also supports zero.
This commit is contained in:
parent
97e4d3d56f
commit
c82be53d5c
|
@ -13,10 +13,12 @@
|
||||||
|
|
||||||
typedef GLXContext (*PFNGLXCREATECONTEXTATTRIBSPROC)(Display*, GLXFBConfig, GLXContext, Bool,
|
typedef GLXContext (*PFNGLXCREATECONTEXTATTRIBSPROC)(Display*, GLXFBConfig, GLXContext, Bool,
|
||||||
const int*);
|
const int*);
|
||||||
typedef int (*PFNGLXSWAPINTERVALSGIPROC)(int interval);
|
typedef void (*PFNGLXSWAPINTERVALEXTPROC)(Display*, GLXDrawable, int);
|
||||||
|
typedef int (*PFNGLXSWAPINTERVALMESAPROC)(unsigned int);
|
||||||
|
|
||||||
static PFNGLXCREATECONTEXTATTRIBSPROC glXCreateContextAttribs = nullptr;
|
static PFNGLXCREATECONTEXTATTRIBSPROC glXCreateContextAttribs = nullptr;
|
||||||
static PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI = nullptr;
|
static PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXTPtr = nullptr;
|
||||||
|
static PFNGLXSWAPINTERVALMESAPROC glXSwapIntervalMESAPtr = nullptr;
|
||||||
|
|
||||||
static PFNGLXCREATEGLXPBUFFERSGIXPROC glXCreateGLXPbufferSGIX = nullptr;
|
static PFNGLXCREATEGLXPBUFFERSGIXPROC glXCreateGLXPbufferSGIX = nullptr;
|
||||||
static PFNGLXDESTROYGLXPBUFFERSGIXPROC glXDestroyGLXPbufferSGIX = nullptr;
|
static PFNGLXDESTROYGLXPBUFFERSGIXPROC glXDestroyGLXPbufferSGIX = nullptr;
|
||||||
|
@ -30,11 +32,18 @@ static int ctxErrorHandler(Display* dpy, XErrorEvent* ev)
|
||||||
|
|
||||||
void cInterfaceGLX::SwapInterval(int Interval)
|
void cInterfaceGLX::SwapInterval(int Interval)
|
||||||
{
|
{
|
||||||
if (glXSwapIntervalSGI && m_has_handle)
|
if (!m_has_handle)
|
||||||
glXSwapIntervalSGI(Interval);
|
return;
|
||||||
|
|
||||||
|
// Try EXT_swap_control, then MESA_swap_control.
|
||||||
|
if (glXSwapIntervalEXTPtr)
|
||||||
|
glXSwapIntervalEXTPtr(dpy, win, Interval);
|
||||||
|
else if (glXSwapIntervalMESAPtr)
|
||||||
|
glXSwapIntervalMESAPtr(static_cast<unsigned int>(Interval));
|
||||||
else
|
else
|
||||||
ERROR_LOG(VIDEO, "No support for SwapInterval (framerate clamped to monitor refresh rate).");
|
ERROR_LOG(VIDEO, "No support for SwapInterval (framerate clamped to monitor refresh rate).");
|
||||||
}
|
}
|
||||||
|
|
||||||
void* cInterfaceGLX::GetFuncAddress(const std::string& name)
|
void* cInterfaceGLX::GetFuncAddress(const std::string& name)
|
||||||
{
|
{
|
||||||
return (void*)glXGetProcAddress((const GLubyte*)name.c_str());
|
return (void*)glXGetProcAddress((const GLubyte*)name.c_str());
|
||||||
|
@ -152,21 +161,34 @@ bool cInterfaceGLX::Create(void* window_handle, bool stereo, bool core)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glXSwapIntervalEXTPtr = nullptr;
|
||||||
|
glXSwapIntervalMESAPtr = nullptr;
|
||||||
|
glXCreateGLXPbufferSGIX = nullptr;
|
||||||
|
glXDestroyGLXPbufferSGIX = nullptr;
|
||||||
|
m_supports_pbuffer = false;
|
||||||
|
|
||||||
std::string tmp;
|
std::string tmp;
|
||||||
std::istringstream buffer(glXQueryExtensionsString(dpy, screen));
|
std::istringstream buffer(glXQueryExtensionsString(dpy, screen));
|
||||||
while (buffer >> tmp)
|
while (buffer >> tmp)
|
||||||
{
|
{
|
||||||
if (tmp == "GLX_SGIX_pbuffer")
|
if (tmp == "GLX_SGIX_pbuffer")
|
||||||
m_supports_pbuffer = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_supports_pbuffer)
|
|
||||||
{
|
{
|
||||||
// Get the function pointers we require
|
glXCreateGLXPbufferSGIX = reinterpret_cast<PFNGLXCREATEGLXPBUFFERSGIXPROC>(
|
||||||
glXCreateGLXPbufferSGIX =
|
GetFuncAddress("glXCreateGLXPbufferSGIX"));
|
||||||
(PFNGLXCREATEGLXPBUFFERSGIXPROC)GetFuncAddress("glXCreateGLXPbufferSGIX");
|
glXDestroyGLXPbufferSGIX = reinterpret_cast<PFNGLXDESTROYGLXPBUFFERSGIXPROC>(
|
||||||
glXDestroyGLXPbufferSGIX =
|
GetFuncAddress("glXDestroyGLXPbufferSGIX"));
|
||||||
(PFNGLXDESTROYGLXPBUFFERSGIXPROC)GetFuncAddress("glXDestroyGLXPbufferSGIX");
|
m_supports_pbuffer = glXCreateGLXPbufferSGIX && glXDestroyGLXPbufferSGIX;
|
||||||
|
}
|
||||||
|
else if (tmp == "GLX_EXT_swap_control")
|
||||||
|
{
|
||||||
|
glXSwapIntervalEXTPtr =
|
||||||
|
reinterpret_cast<PFNGLXSWAPINTERVALEXTPROC>(GetFuncAddress("glXSwapIntervalEXT"));
|
||||||
|
}
|
||||||
|
else if (tmp == "GLX_MESA_swap_control")
|
||||||
|
{
|
||||||
|
glXSwapIntervalMESAPtr =
|
||||||
|
reinterpret_cast<PFNGLXSWAPINTERVALMESAPROC>(GetFuncAddress("glXSwapIntervalMESA"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CreateWindowSurface())
|
if (!CreateWindowSurface())
|
||||||
|
@ -267,14 +289,7 @@ void cInterfaceGLX::DestroyWindowSurface()
|
||||||
|
|
||||||
bool cInterfaceGLX::MakeCurrent()
|
bool cInterfaceGLX::MakeCurrent()
|
||||||
{
|
{
|
||||||
bool success = glXMakeCurrent(dpy, win, ctx);
|
return glXMakeCurrent(dpy, win, ctx);
|
||||||
if (success && !glXSwapIntervalSGI)
|
|
||||||
{
|
|
||||||
// load this function based on the current bound context
|
|
||||||
glXSwapIntervalSGI =
|
|
||||||
(PFNGLXSWAPINTERVALSGIPROC)GLInterface->GetFuncAddress("glXSwapIntervalSGI");
|
|
||||||
}
|
|
||||||
return success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cInterfaceGLX::ClearCurrent()
|
bool cInterfaceGLX::ClearCurrent()
|
||||||
|
|
Loading…
Reference in New Issue