From da3a77b4e3bda3496fbc2d8d35ed6894bf6106b5 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Thu, 27 Aug 2015 15:11:48 +0200 Subject: [PATCH] Add dynamic client library loading to EGL backend Fixes #586. --- README.md | 2 ++ src/egl_context.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++ src/egl_context.h | 2 ++ 3 files changed, 90 insertions(+) diff --git a/README.md b/README.md index 19764a9c..3176fba5 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,8 @@ GLFW bundles a number of dependencies in the `deps/` directory. - [GLX] Removed `_GLFW_HAS_GLXGETPROCADDRESS*` and `_GLFW_HAS_DLOPEN` compile-time options - [EGL] Made all EGL functions dynamically loaded + - [EGL] Bugfix: `glfwGetProcAddress` did not return the addresses of core + functions ## Contact diff --git a/src/egl_context.c b/src/egl_context.c index 452c0e46..2fb90983 100644 --- a/src/egl_context.c +++ b/src/egl_context.c @@ -455,6 +455,70 @@ int _glfwCreateContext(_GLFWwindow* window, window->egl.config = config; + // Load the appropriate client library + { + int i; + const char** sonames; + const char* es1sonames[] = + { +#if defined(_GLFW_WIN32) + "GLESv1_CM.dll", + "libGLES_CM.dll", +#elif defined(_GLFW_COCOA) + "libGLESv1_CM.dylib", +#else + "libGLESv1_CM.so.1", + "libGLES_CM.so.1", +#endif + NULL + }; + const char* es2sonames[] = + { +#if defined(_GLFW_WIN32) + "GLESv2.dll", + "libGLESv2.dll", +#elif defined(_GLFW_COCOA) + "libGLESv2.dylib", +#else + "libGLESv2.so.2", +#endif + NULL + }; + const char* glsonames[] = + { +#if defined(_GLFW_WIN32) +#elif defined(_GLFW_COCOA) +#else + "libGL.so.1", +#endif + NULL + }; + + if (ctxconfig->api == GLFW_OPENGL_ES_API) + { + if (ctxconfig->major == 1) + sonames = es1sonames; + else + sonames = es2sonames; + } + else + sonames = glsonames; + + for (i = 0; sonames[i]; i++) + { + window->egl.client = _glfw_dlopen(sonames[i]); + if (window->egl.client) + break; + } + + if (!window->egl.client) + { + _glfwInputError(GLFW_API_UNAVAILABLE, + "EGL: Failed to load client library"); + return GL_FALSE; + } + } + return GL_TRUE; } @@ -464,6 +528,19 @@ int _glfwCreateContext(_GLFWwindow* window, // void _glfwDestroyContext(_GLFWwindow* window) { +#if defined(_GLFW_X11) + // NOTE: Do not unload libGL.so.1 while the X11 display is still open, + // as it will make XCloseDisplay segfault + if (window->context.api != GLFW_OPENGL_API) +#endif // _GLFW_X11 + { + if (window->egl.client) + { + _glfw_dlclose(window->egl.client); + window->egl.client = NULL; + } + } + #if defined(_GLFW_X11) if (window->egl.visual) { @@ -563,6 +640,15 @@ int _glfwPlatformExtensionSupported(const char* extension) GLFWglproc _glfwPlatformGetProcAddress(const char* procname) { + _GLFWwindow* window = _glfwPlatformGetCurrentContext(); + + if (window->egl.client) + { + GLFWglproc proc = (GLFWglproc) _glfw_dlsym(window->egl.client, procname); + if (proc) + return proc; + } + return _glfw_eglGetProcAddress(procname); } diff --git a/src/egl_context.h b/src/egl_context.h index d1dbf220..a37cbc65 100644 --- a/src/egl_context.h +++ b/src/egl_context.h @@ -97,6 +97,8 @@ typedef struct _GLFWcontextEGL XVisualInfo* visual; #endif + void* client; + } _GLFWcontextEGL;