diff --git a/src/dispatch_common.c b/src/dispatch_common.c index 244938b..dedf664 100644 --- a/src/dispatch_common.c +++ b/src/dispatch_common.c @@ -175,6 +175,7 @@ #ifdef __APPLE__ #define GLX_LIB "/opt/X11/lib/libGL.1.dylib" +#define OPENGL_LIB "/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL" #elif defined(__ANDROID__) #define GLX_LIB "libGLESv2.so" #else @@ -190,6 +191,7 @@ #define EGL_LIB "libEGL.dll" #define GLES1_LIB "libGLES_CM.dll" #define GLES2_LIB "libGLESv2.dll" +#define OPENGL_LIB "OPENGL32" #else #define EGL_LIB "libEGL.so.1" #define GLES1_LIB "libGLESv1_CM.so.1" @@ -290,7 +292,7 @@ library_init(void) } static bool -get_dlopen_handle(void **handle, const char *lib_name, bool exit_on_fail) +get_dlopen_handle(void **handle, const char *lib_name, bool exit_on_fail, bool load) { if (*handle) return true; @@ -306,7 +308,7 @@ get_dlopen_handle(void **handle, const char *lib_name, bool exit_on_fail) pthread_mutex_lock(&api.mutex); if (!*handle) { int flags = RTLD_LAZY | RTLD_LOCAL; - if (!exit_on_fail) + if (!load) flags |= RTLD_NOLOAD; *handle = dlopen(lib_name, flags); @@ -326,15 +328,11 @@ get_dlopen_handle(void **handle, const char *lib_name, bool exit_on_fail) } static void * -do_dlsym(void **handle, const char *lib_name, const char *name, - bool exit_on_fail) +do_dlsym(void **handle, const char *name, bool exit_on_fail) { void *result; const char *error = ""; - if (!get_dlopen_handle(handle, lib_name, exit_on_fail)) - return NULL; - #ifdef _WIN32 result = GetProcAddress(*handle, name); #else @@ -343,7 +341,7 @@ do_dlsym(void **handle, const char *lib_name, const char *name, error = dlerror(); #endif if (!result && exit_on_fail) { - fprintf(stderr,"%s() not found in %s: %s\n", name, lib_name, error); + fprintf(stderr, "%s() not found: %s\n", name, error); exit(1); } @@ -552,16 +550,27 @@ epoxy_internal_has_gl_extension(const char *ext, bool invalid_op_mode) } } -void * -epoxy_conservative_glx_dlsym(const char *name, bool exit_if_fails) +bool +epoxy_load_glx(bool exit_if_fails, bool load) { #ifdef GLVND_GLX_LIB /* prefer the glvnd library if it exists */ if (!api.glx_handle) - get_dlopen_handle(&api.glx_handle, GLVND_GLX_LIB, false); + get_dlopen_handle(&api.glx_handle, GLVND_GLX_LIB, false, load); #endif + if (!api.glx_handle) + get_dlopen_handle(&api.glx_handle, GLX_LIB, exit_if_fails, load); + + return api.glx_handle != NULL; +} + +void * +epoxy_conservative_glx_dlsym(const char *name, bool exit_if_fails) +{ + if (epoxy_load_glx(exit_if_fails, exit_if_fails)) + return do_dlsym(&api.glx_handle, name, exit_if_fails); - return do_dlsym(&api.glx_handle, GLX_LIB, name, exit_if_fails); + return NULL; } /** @@ -624,10 +633,19 @@ epoxy_conservative_has_gl_extension(const char *ext) return epoxy_internal_has_gl_extension(ext, true); } +bool +epoxy_load_egl(bool exit_if_fails, bool load) +{ + return get_dlopen_handle(&api.egl_handle, EGL_LIB, exit_if_fails, load); +} + void * epoxy_conservative_egl_dlsym(const char *name, bool exit_if_fails) { - return do_dlsym(&api.egl_handle, EGL_LIB, name, exit_if_fails); + if (epoxy_load_egl(exit_if_fails, exit_if_fails)) + return do_dlsym(&api.egl_handle, name, exit_if_fails); + + return NULL; } void * @@ -642,31 +660,32 @@ epoxy_glx_dlsym(const char *name) return epoxy_conservative_glx_dlsym(name, true); } -void * -epoxy_gl_dlsym(const char *name) +static void +epoxy_load_gl(void) { -#ifdef _WIN32 - return do_dlsym(&api.gl_handle, "OPENGL32", name, true); -#elif defined(__APPLE__) - return do_dlsym(&api.gl_handle, - "/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", - name, true); + if (api.gl_handle) + return; + +#if defined(_WIN32) || defined(__APPLE__) + get_dlopen_handle(&api.gl_handle, OPENGL_LIB, true, true); #else - void *sym; -# if defined(OPENGL_LIB) +#if defined(OPENGL_LIB) if (!api.gl_handle) - get_dlopen_handle(&api.gl_handle, OPENGL_LIB, false); -# endif + get_dlopen_handle(&api.gl_handle, OPENGL_LIB, false, true); +#endif - if (api.gl_handle) - return do_dlsym(&api.gl_handle, NULL, name, true); + get_dlopen_handle(&api.glx_handle, GLX_LIB, true, true); + api.gl_handle = api.glx_handle; +#endif +} - sym = do_dlsym(&api.glx_handle, GLX_LIB, name, true); - api.gl_handle = api.glx_handle; /* skip the dlopen next time */ +void * +epoxy_gl_dlsym(const char *name) +{ + epoxy_load_gl(); - return sym; -#endif + return do_dlsym(&api.gl_handle, name, true); } void * @@ -675,7 +694,8 @@ epoxy_gles1_dlsym(const char *name) if (epoxy_current_context_is_glx()) { return epoxy_get_proc_address(name); } else { - return do_dlsym(&api.gles1_handle, GLES1_LIB, name, true); + get_dlopen_handle(&api.gles1_handle, GLES1_LIB, true, true); + return do_dlsym(&api.gles1_handle, name, true); } } @@ -685,7 +705,8 @@ epoxy_gles2_dlsym(const char *name) if (epoxy_current_context_is_glx()) { return epoxy_get_proc_address(name); } else { - return do_dlsym(&api.gles2_handle, GLES2_LIB, name, true); + get_dlopen_handle(&api.gles2_handle, GLES2_LIB, true, true); + return do_dlsym(&api.gles2_handle, name, true); } } @@ -705,10 +726,12 @@ epoxy_gles3_dlsym(const char *name) if (epoxy_current_context_is_glx()) { return epoxy_get_proc_address(name); } else { - void *func = do_dlsym(&api.gles2_handle, GLES2_LIB, name, false); + if (get_dlopen_handle(&api.gles2_handle, GLES2_LIB, false, true)) { + void *func = do_dlsym(&api.gles2_handle, GLES2_LIB, false); - if (func) - return func; + if (func) + return func; + } return epoxy_get_proc_address(name); } @@ -783,7 +806,7 @@ epoxy_get_bootstrap_proc_address(const char *name) * non-X11 ES2 context from loading a bunch of X11 junk). */ #if PLATFORM_HAS_EGL - get_dlopen_handle(&api.egl_handle, EGL_LIB, false); + get_dlopen_handle(&api.egl_handle, EGL_LIB, false, true); if (api.egl_handle) { int version = 0; switch (epoxy_egl_get_current_gl_context_api()) { diff --git a/src/dispatch_common.h b/src/dispatch_common.h index 9675cff..fc99635 100644 --- a/src/dispatch_common.h +++ b/src/dispatch_common.h @@ -172,6 +172,9 @@ bool epoxy_conservative_has_wgl_extension(const char *name); void *epoxy_conservative_egl_dlsym(const char *name, bool exit_if_fails); void *epoxy_conservative_glx_dlsym(const char *name, bool exit_if_fails); +bool epoxy_load_glx(bool exit_if_fails, bool load); +bool epoxy_load_egl(bool exit_if_fails, bool load); + #define glBegin_unwrapped epoxy_glBegin_unwrapped #define glEnd_unwrapped epoxy_glEnd_unwrapped extern void UNWRAPPED_PROTO(glBegin_unwrapped)(GLenum primtype); diff --git a/src/dispatch_egl.c b/src/dispatch_egl.c index f555a58..3f0c789 100644 --- a/src/dispatch_egl.c +++ b/src/dispatch_egl.c @@ -109,11 +109,13 @@ epoxy_has_egl(void) #if !PLATFORM_HAS_EGL return false; #else - EGLDisplay* (* pf_eglGetCurrentDisplay) (void); + if (epoxy_load_egl(false, true)) { + EGLDisplay* (* pf_eglGetCurrentDisplay) (void); - pf_eglGetCurrentDisplay = epoxy_conservative_egl_dlsym("eglGetCurrentDisplay", false); - if (pf_eglGetCurrentDisplay) - return true; + pf_eglGetCurrentDisplay = epoxy_conservative_egl_dlsym("eglGetCurrentDisplay", false); + if (pf_eglGetCurrentDisplay) + return true; + } return false; #endif /* PLATFORM_HAS_EGL */ diff --git a/src/dispatch_glx.c b/src/dispatch_glx.c index b5ad42e..e395564 100644 --- a/src/dispatch_glx.c +++ b/src/dispatch_glx.c @@ -158,12 +158,14 @@ epoxy_has_glx(Display *dpy) #if !PLATFORM_HAS_GLX return false; #else - Bool (* pf_glXQueryExtension) (Display *, int *, int *); - int error_base, event_base; - - pf_glXQueryExtension = epoxy_conservative_glx_dlsym("glXQueryExtension", false); - if (pf_glXQueryExtension && pf_glXQueryExtension(dpy, &error_base, &event_base)) - return true; + if (epoxy_load_glx(false, true)) { + Bool (* pf_glXQueryExtension) (Display *, int *, int *); + int error_base, event_base; + + pf_glXQueryExtension = epoxy_conservative_glx_dlsym("glXQueryExtension", false); + if (pf_glXQueryExtension && pf_glXQueryExtension(dpy, &error_base, &event_base)) + return true; + } return false; #endif /* !PLATFORM_HAS_GLX */