Make all GLX functions dynamically loaded

This commit is contained in:
Camilla Berglund 2015-08-13 00:21:33 +02:00
parent 8db7528ac7
commit afe4aadade
4 changed files with 96 additions and 30 deletions

View File

@ -99,6 +99,7 @@ GLFW bundles a number of dependencies in the `deps/` directory.
- [WGL] Removed `GLFW_USE_DWM_SWAP_INTERVAL` compile-time option
- [WGL] Bugfix: Swap interval was ignored when DWM was enabled
- [GLX] Added dependency on `libdl` on systems where it provides `dlopen`
- [GLX] Made all GLX functions dynamically loaded
- [GLX] Removed `_GLFW_HAS_GLXGETPROCADDRESS*` and `_GLFW_HAS_DLOPEN`
compile-time options

View File

@ -42,7 +42,7 @@
static int getFBConfigAttrib(GLXFBConfig fbconfig, int attrib)
{
int value;
glXGetFBConfigAttrib(_glfw.x11.display, fbconfig, attrib, &value);
_glfw_glXGetFBConfigAttrib(_glfw.x11.display, fbconfig, attrib, &value);
return value;
}
@ -59,11 +59,11 @@ static GLboolean chooseFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* resul
// HACK: This is a (hopefully temporary) workaround for Chromium
// (VirtualBox GL) not setting the window bit on any GLXFBConfigs
vendor = glXGetClientString(_glfw.x11.display, GLX_VENDOR);
vendor = _glfw_glXGetClientString(_glfw.x11.display, GLX_VENDOR);
if (strcmp(vendor, "Chromium") == 0)
trustWindowBit = GL_FALSE;
nativeConfigs = glXGetFBConfigs(_glfw.x11.display, _glfw.x11.screen,
nativeConfigs = _glfw_glXGetFBConfigs(_glfw.x11.display, _glfw.x11.screen,
&nativeCount);
if (!nativeCount)
{
@ -140,7 +140,7 @@ static GLXContext createLegacyContext(_GLFWwindow* window,
GLXFBConfig fbconfig,
GLXContext share)
{
return glXCreateNewContext(_glfw.x11.display,
return _glfw_glXCreateNewContext(_glfw.x11.display,
fbconfig,
GLX_RGBA_TYPE,
share,
@ -172,12 +172,34 @@ int _glfwInitContextAPI(void)
return GL_FALSE;
}
_glfw.glx.GetFBConfigs =
dlsym(_glfw.glx.handle, "glXGetFBConfigs");
_glfw.glx.GetFBConfigAttrib =
dlsym(_glfw.glx.handle, "glXGetFBConfigAttrib");
_glfw.glx.GetClientString =
dlsym(_glfw.glx.handle, "glXGetClientString");
_glfw.glx.QueryExtension =
dlsym(_glfw.glx.handle, "glXQueryExtension");
_glfw.glx.QueryVersion =
dlsym(_glfw.glx.handle, "glXQueryVersion");
_glfw.glx.DestroyContext =
dlsym(_glfw.glx.handle, "glXDestroyContext");
_glfw.glx.MakeCurrent =
dlsym(_glfw.glx.handle, "glXMakeCurrent");
_glfw.glx.SwapBuffers =
dlsym(_glfw.glx.handle, "glXSwapBuffers");
_glfw.glx.QueryExtensionsString =
dlsym(_glfw.glx.handle, "glXQueryExtensionsString");
_glfw.glx.CreateNewContext =
dlsym(_glfw.glx.handle, "glXCreateNewContext");
_glfw.glx.GetVisualFromFBConfig =
dlsym(_glfw.glx.handle, "glXGetVisualFromFBConfig");
_glfw.glx.GetProcAddress =
dlsym(_glfw.glx.handle, "glXGetProcAddress");
_glfw.glx.GetProcAddressARB =
dlsym(_glfw.glx.handle, "glXGetProcAddressARB");
if (!glXQueryExtension(_glfw.x11.display,
if (!_glfw_glXQueryExtension(_glfw.x11.display,
&_glfw.glx.errorBase,
&_glfw.glx.eventBase))
{
@ -185,7 +207,9 @@ int _glfwInitContextAPI(void)
return GL_FALSE;
}
if (!glXQueryVersion(_glfw.x11.display, &_glfw.glx.major, &_glfw.glx.minor))
if (!_glfw_glXQueryVersion(_glfw.x11.display,
&_glfw.glx.major,
&_glfw.glx.minor))
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"GLX: Failed to query GLX version");
@ -263,6 +287,9 @@ int _glfwInitContextAPI(void)
//
void _glfwTerminateContextAPI(void)
{
// NOTE: This function may not call any X11 functions, as it is called after
// XCloseDisplay (see _glfwPlatformTerminate for details)
if (_glfw.glx.handle)
{
dlclose(_glfw.glx.handle);
@ -299,7 +326,8 @@ int _glfwCreateContext(_GLFWwindow* window,
return GL_FALSE;
}
window->glx.visual = glXGetVisualFromFBConfig(_glfw.x11.display, native);
window->glx.visual = _glfw_glXGetVisualFromFBConfig(_glfw.x11.display,
native);
if (!window->glx.visual)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
@ -465,7 +493,7 @@ void _glfwDestroyContext(_GLFWwindow* window)
if (window->glx.context)
{
glXDestroyContext(_glfw.x11.display, window->glx.context);
_glfw_glXDestroyContext(_glfw.x11.display, window->glx.context);
window->glx.context = NULL;
}
}
@ -479,19 +507,19 @@ void _glfwPlatformMakeContextCurrent(_GLFWwindow* window)
{
if (window)
{
glXMakeCurrent(_glfw.x11.display,
_glfw_glXMakeCurrent(_glfw.x11.display,
window->x11.handle,
window->glx.context);
}
else
glXMakeCurrent(_glfw.x11.display, None, NULL);
_glfw_glXMakeCurrent(_glfw.x11.display, None, NULL);
_glfwSetContextTLS(window);
}
void _glfwPlatformSwapBuffers(_GLFWwindow* window)
{
glXSwapBuffers(_glfw.x11.display, window->x11.handle);
_glfw_glXSwapBuffers(_glfw.x11.display, window->x11.handle);
}
void _glfwPlatformSwapInterval(int interval)
@ -515,8 +543,8 @@ void _glfwPlatformSwapInterval(int interval)
int _glfwPlatformExtensionSupported(const char* extension)
{
const char* extensions = glXQueryExtensionsString(_glfw.x11.display,
_glfw.x11.screen);
const char* extensions =
_glfw_glXQueryExtensionsString(_glfw.x11.display, _glfw.x11.screen);
if (extensions)
{
if (_glfwStringInExtensionString(extension, extensions))

View File

@ -37,6 +37,27 @@
#define GLX_GLXEXT_PROTOTYPES
#include "../deps/GL/glxext.h"
// libGL.so function pointer typedefs
typedef int (*PFNGLXGETFBCONFIGATTRIBPROC)(Display*,GLXFBConfig,int,int*);
typedef const char* (*PFNGLXGETCLIENTSTRINGPROC)(Display*,int);
typedef Bool (*PFNGLXQUERYEXTENSIONPROC)(Display*,int*,int*);
typedef Bool (*PFNGLXQUERYVERSIONPROC)(Display*,int*,int*);
typedef void (*PFNGLXDESTROYCONTEXTPROC)(Display*,GLXContext);
typedef Bool (*PFNGLXMAKECURRENTPROC)(Display*,GLXDrawable,GLXContext);
typedef void (*PFNGLXSWAPBUFFERSPROC)(Display*,GLXDrawable);
typedef const char* (*PFNGLXQUERYEXTENSIONSSTRINGPROC)(Display*,int);
#define _glfw_glXGetFBConfigs _glfw.glx.GetFBConfigs
#define _glfw_glXGetFBConfigAttrib _glfw.glx.GetFBConfigAttrib
#define _glfw_glXGetClientString _glfw.glx.GetClientString
#define _glfw_glXQueryExtension _glfw.glx.QueryExtension
#define _glfw_glXQueryVersion _glfw.glx.QueryVersion
#define _glfw_glXDestroyContext _glfw.glx.DestroyContext
#define _glfw_glXMakeCurrent _glfw.glx.MakeCurrent
#define _glfw_glXSwapBuffers _glfw.glx.SwapBuffers
#define _glfw_glXQueryExtensionsString _glfw.glx.QueryExtensionsString
#define _glfw_glXCreateNewContext _glfw.glx.CreateNewContext
#define _glfw_glXGetVisualFromFBConfig _glfw.glx.GetVisualFromFBConfig
#define _GLFW_PLATFORM_FBCONFIG GLXFBConfig glx
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextGLX glx
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryGLX glx
@ -69,7 +90,20 @@ typedef struct _GLFWlibraryGLX
// dlopen handle for libGL.so.1
void* handle;
// GLX extensions
// GLX 1.3 functions
PFNGLXGETFBCONFIGSPROC GetFBConfigs;
PFNGLXGETFBCONFIGATTRIBPROC GetFBConfigAttrib;
PFNGLXGETCLIENTSTRINGPROC GetClientString;
PFNGLXQUERYEXTENSIONPROC QueryExtension;
PFNGLXQUERYVERSIONPROC QueryVersion;
PFNGLXDESTROYCONTEXTPROC DestroyContext;
PFNGLXMAKECURRENTPROC MakeCurrent;
PFNGLXSWAPBUFFERSPROC SwapBuffers;
PFNGLXQUERYEXTENSIONSSTRINGPROC QueryExtensionsString;
PFNGLXCREATENEWCONTEXTPROC CreateNewContext;
PFNGLXGETVISUALFROMFBCONFIGPROC GetVisualFromFBConfig;
// GLX 1.4 and extension functions
PFNGLXGETPROCADDRESSPROC GetProcAddress;
PFNGLXGETPROCADDRESSPROC GetProcAddressARB;
PFNGLXSWAPINTERVALSGIPROC SwapIntervalSGI;

View File

@ -786,13 +786,16 @@ void _glfwPlatformTerminate(void)
}
_glfwTerminateJoysticks();
_glfwTerminateContextAPI();
if (_glfw.x11.display)
{
XCloseDisplay(_glfw.x11.display);
_glfw.x11.display = NULL;
}
// NOTE: This needs to be done after XCloseDisplay, as libGL registers
// internal cleanup callbacks in libX11
_glfwTerminateContextAPI();
}
const char* _glfwPlatformGetVersionString(void)