diff options
-rw-r--r-- | configure.ac | 11 | ||||
-rw-r--r-- | src/cairo-gl-dispatch.c | 54 |
2 files changed, 65 insertions, 0 deletions
diff --git a/configure.ac b/configure.ac index 9107b3e35..72caa0dcd 100644 --- a/configure.ac +++ b/configure.ac @@ -49,6 +49,9 @@ if test "x$have_dlsym" = "xno"; then fi AC_CHECK_HEADERS(dlfcn.h, [have_dlsym=yes], [have_dlsym=no]) AM_CONDITIONAL(CAIRO_HAS_DL, test "x$have_dl" = "xyes") +if test "x$have_dlsym" = "xyes"; then + AC_DEFINE([CAIRO_HAS_DLSYM], 1, [Define to 1 if dlsym is available]) +fi dnl =========================================================================== @@ -317,6 +320,10 @@ CAIRO_ENABLE_SURFACE_BACKEND(gl, OpenGL, no, [ gl_NONPKGCONFIG_LIBS="-lGL" fi]) + if test "x$have_dl" = "xyes" -a "x$have_dlsym" = "xyes"; then + gl_LIBS="$gl_LIBS -ldl" + fi + need_glx_functions=yes need_wgl_functions=yes need_egl_functions=yes @@ -333,6 +340,10 @@ CAIRO_ENABLE_SURFACE_BACKEND(glesv2, OpenGLESv2, no, [ glesv2_NONPKGCONFIG_LIBS="-lGLESv2" fi]) + if test "x$have_dl" = "xyes" -a "x$have_dlsym" = "xyes"; then + glesv2_LIBS="$glesv2_LIBS -ldl" + fi + need_egl_functions=yes ]) diff --git a/src/cairo-gl-dispatch.c b/src/cairo-gl-dispatch.c index 6277f53df..344b0ebba 100644 --- a/src/cairo-gl-dispatch.c +++ b/src/cairo-gl-dispatch.c @@ -32,6 +32,48 @@ #include "cairoint.h" #include "cairo-gl-private.h" #include "cairo-gl-dispatch-private.h" +#if CAIRO_HAS_DLSYM +#include <dlfcn.h> +#endif + +#if CAIRO_HAS_DLSYM +static void * +_cairo_gl_dispatch_open_lib (void) +{ + return dlopen (NULL, RTLD_LAZY); +} + +static void +_cairo_gl_dispatch_close_lib (void *handle) +{ + dlclose (handle); +} + +static cairo_gl_generic_func_t +_cairo_gl_dispatch_get_proc_addr (void *handle, const char *name) +{ + return (cairo_gl_generic_func_t) dlsym (handle, name); +} +#else +static void * +_cairo_gl_dispatch_open_lib (void) +{ + return NULL; +} + +static void +_cairo_gl_dispatch_close_lib (void *handle) +{ + return; +} + +static cairo_gl_generic_func_t +_cairo_gl_dispatch_get_proc_addr (void *handle, const char *name) +{ + return NULL; +} +#endif /* CAIRO_HAS_DLSYM */ + static void _cairo_gl_dispatch_init_entries (cairo_gl_dispatch_t *dispatch, @@ -40,18 +82,30 @@ _cairo_gl_dispatch_init_entries (cairo_gl_dispatch_t *dispatch, cairo_gl_dispatch_name_t dispatch_name) { cairo_gl_dispatch_entry_t *entry = entries; + void *handle = _cairo_gl_dispatch_open_lib (); while (entry->name[CAIRO_GL_DISPATCH_NAME_CORE] != NULL) { void *dispatch_ptr = &((char *) dispatch)[entry->offset]; const char *name = entry->name[dispatch_name]; + /* + * In strictly conforming EGL implementations, eglGetProcAddress() can + * be used only to get extension functions, but some of the functions + * we want belong to core GL(ES). If the *GetProcAddress function + * provided by the context fails, try to get the address of the wanted + * GL function using standard system facilities (eg dlsym() in *nix + * systems). + */ cairo_gl_generic_func_t func = get_proc_addr (name); + if (func == NULL) + func = _cairo_gl_dispatch_get_proc_addr (handle, name); *((cairo_gl_generic_func_t *) dispatch_ptr) = func; ++entry; } + _cairo_gl_dispatch_close_lib (handle); } static cairo_status_t |