From fef5d14494ff19ea302e247ba593e189a8ab62bd Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Fri, 7 Jan 2011 15:02:41 +0800 Subject: egl_dri2: Look up _glapi_get_proc_address dynamically. In preparation for making egl_dri2 built-in. It also handles symbol lookup error: /usr/local/lib/egl/egl_dri2.so: undefined symbol: _glapi_get_proc_address more gracefully. --- src/egl/drivers/dri2/Makefile | 2 +- src/egl/drivers/dri2/egl_dri2.c | 60 ++++++++++++++++++++++++++++++----------- 2 files changed, 46 insertions(+), 16 deletions(-) (limited to 'src/egl') diff --git a/src/egl/drivers/dri2/Makefile b/src/egl/drivers/dri2/Makefile index 8a3c9b6a0aa..ec4d1bcd9be 100644 --- a/src/egl/drivers/dri2/Makefile +++ b/src/egl/drivers/dri2/Makefile @@ -15,6 +15,6 @@ EGL_INCLUDES = \ $(LIBUDEV_CFLAGS) \ $(LIBDRM_CFLAGS) -EGL_LIBS = $(XCB_DRI2_LIBS) $(LIBUDEV_LIBS) $(LIBDRM_LIBS) +EGL_LIBS = $(XCB_DRI2_LIBS) $(LIBUDEV_LIBS) $(DLOPEN_LIBS) $(LIBDRM_LIB) include ../Makefile.template diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c index 7592984c99e..52232980207 100644 --- a/src/egl/drivers/dri2/egl_dri2.c +++ b/src/egl/drivers/dri2/egl_dri2.c @@ -47,7 +47,6 @@ #include #endif -#include #include "eglconfig.h" #include "eglcontext.h" #include "egldisplay.h" @@ -63,6 +62,7 @@ struct dri2_egl_driver { _EGLDriver base; + _EGLProc (*get_proc_address)(const char *procname); void (*glFlush)(void); }; @@ -1867,11 +1867,9 @@ dri2_swap_buffers_region(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw, static _EGLProc dri2_get_proc_address(_EGLDriver *drv, const char *procname) { - (void) drv; - - /* FIXME: Do we need to support lookup of EGL symbols too? */ + struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv); - return (_EGLProc) _glapi_get_proc_address(procname); + return dri2_drv->get_proc_address(procname); } static EGLBoolean @@ -1903,13 +1901,6 @@ dri2_wait_native(_EGLDriver *drv, _EGLDisplay *disp, EGLint engine) return EGL_TRUE; } -static void -dri2_unload(_EGLDriver *drv) -{ - struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv); - free(dri2_drv); -} - static EGLBoolean dri2_copy_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf, EGLNativePixmapType target) @@ -2337,6 +2328,45 @@ dri2_export_drm_image_mesa(_EGLDriver *drv, _EGLDisplay *disp, _EGLImage *img, return EGL_TRUE; } +static void +dri2_unload(_EGLDriver *drv) +{ + struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv); + free(dri2_drv); +} + +static EGLBoolean +dri2_load(_EGLDriver *drv) +{ + struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv); + void *handle; + + handle = dlopen(NULL, RTLD_LAZY | RTLD_GLOBAL); + if (handle) { + dri2_drv->get_proc_address = (_EGLProc (*)(const char *)) + dlsym(handle, "_glapi_get_proc_address"); + /* no need to keep a reference */ + dlclose(handle); + } + + /* + * If glapi is not available, loading DRI drivers will fail. Ideally, we + * should load one of libGL, libGLESv1_CM, or libGLESv2 and go on. But if + * the app has loaded another one of them with RTLD_LOCAL, there may be + * unexpected behaviors later because there will be two copies of glapi + * (with global variables of the same names!) in the memory. + */ + if (!dri2_drv->get_proc_address) { + _eglLog(_EGL_WARNING, "DRI2: failed to find _glapi_get_proc_address"); + return EGL_FALSE; + } + + dri2_drv->glFlush = (void (*)(void)) + dri2_drv->get_proc_address("glFlush"); + + return EGL_TRUE; +} + /** * This is the main entrypoint into the driver, called by libEGL. * Create a new _EGLDriver object and init its dispatch table. @@ -2352,6 +2382,9 @@ _eglMain(const char *args) if (!dri2_drv) return NULL; + if (!dri2_load(&dri2_drv->base)) + return NULL; + memset(dri2_drv, 0, sizeof *dri2_drv); _eglInitDriverFallbacks(&dri2_drv->base); dri2_drv->base.API.Initialize = dri2_initialize; @@ -2378,8 +2411,5 @@ _eglMain(const char *args) dri2_drv->base.Name = "DRI2"; dri2_drv->base.Unload = dri2_unload; - dri2_drv->glFlush = - (void (*)(void)) dri2_get_proc_address(&dri2_drv->base, "glFlush"); - return &dri2_drv->base; } -- cgit v1.2.3