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] Removed `GLFW_USE_DWM_SWAP_INTERVAL` compile-time option
- [WGL] Bugfix: Swap interval was ignored when DWM was enabled - [WGL] Bugfix: Swap interval was ignored when DWM was enabled
- [GLX] Added dependency on `libdl` on systems where it provides `dlopen` - [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` - [GLX] Removed `_GLFW_HAS_GLXGETPROCADDRESS*` and `_GLFW_HAS_DLOPEN`
compile-time options compile-time options

View File

@ -42,7 +42,7 @@
static int getFBConfigAttrib(GLXFBConfig fbconfig, int attrib) static int getFBConfigAttrib(GLXFBConfig fbconfig, int attrib)
{ {
int value; int value;
glXGetFBConfigAttrib(_glfw.x11.display, fbconfig, attrib, &value); _glfw_glXGetFBConfigAttrib(_glfw.x11.display, fbconfig, attrib, &value);
return value; return value;
} }
@ -59,12 +59,12 @@ static GLboolean chooseFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* resul
// HACK: This is a (hopefully temporary) workaround for Chromium // HACK: This is a (hopefully temporary) workaround for Chromium
// (VirtualBox GL) not setting the window bit on any GLXFBConfigs // (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) if (strcmp(vendor, "Chromium") == 0)
trustWindowBit = GL_FALSE; trustWindowBit = GL_FALSE;
nativeConfigs = glXGetFBConfigs(_glfw.x11.display, _glfw.x11.screen, nativeConfigs = _glfw_glXGetFBConfigs(_glfw.x11.display, _glfw.x11.screen,
&nativeCount); &nativeCount);
if (!nativeCount) if (!nativeCount)
{ {
_glfwInputError(GLFW_API_UNAVAILABLE, "GLX: No GLXFBConfigs returned"); _glfwInputError(GLFW_API_UNAVAILABLE, "GLX: No GLXFBConfigs returned");
@ -140,11 +140,11 @@ static GLXContext createLegacyContext(_GLFWwindow* window,
GLXFBConfig fbconfig, GLXFBConfig fbconfig,
GLXContext share) GLXContext share)
{ {
return glXCreateNewContext(_glfw.x11.display, return _glfw_glXCreateNewContext(_glfw.x11.display,
fbconfig, fbconfig,
GLX_RGBA_TYPE, GLX_RGBA_TYPE,
share, share,
True); True);
} }
@ -172,20 +172,44 @@ int _glfwInitContextAPI(void)
return GL_FALSE; 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 = _glfw.glx.GetProcAddress =
dlsym(_glfw.glx.handle, "glXGetProcAddress"); dlsym(_glfw.glx.handle, "glXGetProcAddress");
_glfw.glx.GetProcAddressARB = _glfw.glx.GetProcAddressARB =
dlsym(_glfw.glx.handle, "glXGetProcAddressARB"); dlsym(_glfw.glx.handle, "glXGetProcAddressARB");
if (!glXQueryExtension(_glfw.x11.display, if (!_glfw_glXQueryExtension(_glfw.x11.display,
&_glfw.glx.errorBase, &_glfw.glx.errorBase,
&_glfw.glx.eventBase)) &_glfw.glx.eventBase))
{ {
_glfwInputError(GLFW_API_UNAVAILABLE, "GLX: GLX extension not found"); _glfwInputError(GLFW_API_UNAVAILABLE, "GLX: GLX extension not found");
return GL_FALSE; 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, _glfwInputError(GLFW_API_UNAVAILABLE,
"GLX: Failed to query GLX version"); "GLX: Failed to query GLX version");
@ -263,6 +287,9 @@ int _glfwInitContextAPI(void)
// //
void _glfwTerminateContextAPI(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) if (_glfw.glx.handle)
{ {
dlclose(_glfw.glx.handle); dlclose(_glfw.glx.handle);
@ -299,7 +326,8 @@ int _glfwCreateContext(_GLFWwindow* window,
return GL_FALSE; return GL_FALSE;
} }
window->glx.visual = glXGetVisualFromFBConfig(_glfw.x11.display, native); window->glx.visual = _glfw_glXGetVisualFromFBConfig(_glfw.x11.display,
native);
if (!window->glx.visual) if (!window->glx.visual)
{ {
_glfwInputError(GLFW_PLATFORM_ERROR, _glfwInputError(GLFW_PLATFORM_ERROR,
@ -465,7 +493,7 @@ void _glfwDestroyContext(_GLFWwindow* window)
if (window->glx.context) if (window->glx.context)
{ {
glXDestroyContext(_glfw.x11.display, window->glx.context); _glfw_glXDestroyContext(_glfw.x11.display, window->glx.context);
window->glx.context = NULL; window->glx.context = NULL;
} }
} }
@ -479,19 +507,19 @@ void _glfwPlatformMakeContextCurrent(_GLFWwindow* window)
{ {
if (window) if (window)
{ {
glXMakeCurrent(_glfw.x11.display, _glfw_glXMakeCurrent(_glfw.x11.display,
window->x11.handle, window->x11.handle,
window->glx.context); window->glx.context);
} }
else else
glXMakeCurrent(_glfw.x11.display, None, NULL); _glfw_glXMakeCurrent(_glfw.x11.display, None, NULL);
_glfwSetContextTLS(window); _glfwSetContextTLS(window);
} }
void _glfwPlatformSwapBuffers(_GLFWwindow* window) void _glfwPlatformSwapBuffers(_GLFWwindow* window)
{ {
glXSwapBuffers(_glfw.x11.display, window->x11.handle); _glfw_glXSwapBuffers(_glfw.x11.display, window->x11.handle);
} }
void _glfwPlatformSwapInterval(int interval) void _glfwPlatformSwapInterval(int interval)
@ -515,8 +543,8 @@ void _glfwPlatformSwapInterval(int interval)
int _glfwPlatformExtensionSupported(const char* extension) int _glfwPlatformExtensionSupported(const char* extension)
{ {
const char* extensions = glXQueryExtensionsString(_glfw.x11.display, const char* extensions =
_glfw.x11.screen); _glfw_glXQueryExtensionsString(_glfw.x11.display, _glfw.x11.screen);
if (extensions) if (extensions)
{ {
if (_glfwStringInExtensionString(extension, extensions)) if (_glfwStringInExtensionString(extension, extensions))

View File

@ -37,6 +37,27 @@
#define GLX_GLXEXT_PROTOTYPES #define GLX_GLXEXT_PROTOTYPES
#include "../deps/GL/glxext.h" #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_FBCONFIG GLXFBConfig glx
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextGLX glx #define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextGLX glx
#define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryGLX glx #define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryGLX glx
@ -69,13 +90,26 @@ typedef struct _GLFWlibraryGLX
// dlopen handle for libGL.so.1 // dlopen handle for libGL.so.1
void* handle; void* handle;
// GLX extensions // GLX 1.3 functions
PFNGLXGETPROCADDRESSPROC GetProcAddress; PFNGLXGETFBCONFIGSPROC GetFBConfigs;
PFNGLXGETPROCADDRESSPROC GetProcAddressARB; PFNGLXGETFBCONFIGATTRIBPROC GetFBConfigAttrib;
PFNGLXSWAPINTERVALSGIPROC SwapIntervalSGI; PFNGLXGETCLIENTSTRINGPROC GetClientString;
PFNGLXSWAPINTERVALEXTPROC SwapIntervalEXT; PFNGLXQUERYEXTENSIONPROC QueryExtension;
PFNGLXSWAPINTERVALMESAPROC SwapIntervalMESA; PFNGLXQUERYVERSIONPROC QueryVersion;
PFNGLXCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB; PFNGLXDESTROYCONTEXTPROC DestroyContext;
PFNGLXMAKECURRENTPROC MakeCurrent;
PFNGLXSWAPBUFFERSPROC SwapBuffers;
PFNGLXQUERYEXTENSIONSSTRINGPROC QueryExtensionsString;
PFNGLXCREATENEWCONTEXTPROC CreateNewContext;
PFNGLXGETVISUALFROMFBCONFIGPROC GetVisualFromFBConfig;
// GLX 1.4 and extension functions
PFNGLXGETPROCADDRESSPROC GetProcAddress;
PFNGLXGETPROCADDRESSPROC GetProcAddressARB;
PFNGLXSWAPINTERVALSGIPROC SwapIntervalSGI;
PFNGLXSWAPINTERVALEXTPROC SwapIntervalEXT;
PFNGLXSWAPINTERVALMESAPROC SwapIntervalMESA;
PFNGLXCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB;
GLboolean SGI_swap_control; GLboolean SGI_swap_control;
GLboolean EXT_swap_control; GLboolean EXT_swap_control;
GLboolean MESA_swap_control; GLboolean MESA_swap_control;

View File

@ -786,13 +786,16 @@ void _glfwPlatformTerminate(void)
} }
_glfwTerminateJoysticks(); _glfwTerminateJoysticks();
_glfwTerminateContextAPI();
if (_glfw.x11.display) if (_glfw.x11.display)
{ {
XCloseDisplay(_glfw.x11.display); XCloseDisplay(_glfw.x11.display);
_glfw.x11.display = NULL; _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) const char* _glfwPlatformGetVersionString(void)