diff options
| author | Chia-I Wu <olv@lunarg.com> | 2011-01-30 05:09:06 +0800 | 
|---|---|---|
| committer | Chia-I Wu <olv@lunarg.com> | 2011-01-30 05:28:24 +0800 | 
| commit | 218381d92755fa080bbb5635c0c4ed6d5296b79c (patch) | |
| tree | 9566380058c5df94f3990d758c8d9b56343cf92f | |
| parent | f36cba6cf3d51a3937d3bb429609d258399751a0 (diff) | |
egl_dri2: Export glapi symbols for DRI drivers.
When an app loads libEGL.so dynamically with RTLD_LOCAL, loading DRI
drivers would fail because of missing glapi symbols.  This commit makes
egl_dri2 load libglapi.so with RTLD_GLOBAL to export glapi symbols for
future symbol resolutions.
The same trick can be found in GLX.  However, egl_dri2 can only do so
when --enable-shared-glapi is given.  Because, otherwise, both libGL.so
and libglapi.so define glapi symbols and egl_dri2 cannot tell which
library to load.
| -rw-r--r-- | src/egl/drivers/dri2/Makefile | 4 | ||||
| -rw-r--r-- | src/egl/drivers/dri2/egl_dri2.c | 33 | 
2 files changed, 27 insertions, 10 deletions
diff --git a/src/egl/drivers/dri2/Makefile b/src/egl/drivers/dri2/Makefile index 553ee8771f..bd3d702933 100644 --- a/src/egl/drivers/dri2/Makefile +++ b/src/egl/drivers/dri2/Makefile @@ -20,4 +20,8 @@ EGL_LIBS = $(XCB_DRI2_LIBS) $(LIBUDEV_LIBS) $(DLOPEN_LIBS) $(LIBDRM_LIB)  EGL_CFLAGS = -D_EGL_MAIN=_eglBuiltInDriverDRI2  EGL_BUILTIN = true +ifeq ($(SHARED_GLAPI),1) +EGL_CFLAGS += -DHAVE_SHARED_GLAPI +endif +  include ../Makefile.template diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c index 6fc1e49e77..92fc9df54a 100644 --- a/src/egl/drivers/dri2/egl_dri2.c +++ b/src/egl/drivers/dri2/egl_dri2.c @@ -62,6 +62,7 @@ struct dri2_egl_driver  {     _EGLDriver base; +   void *handle;     _EGLProc (*get_proc_address)(const char *procname);     void (*glFlush)(void);  }; @@ -2337,6 +2338,9 @@ static void  dri2_unload(_EGLDriver *drv)  {     struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv); + +   if (dri2_drv->handle) +      dlclose(dri2_drv->handle);     free(dri2_drv);  } @@ -2344,23 +2348,30 @@ static EGLBoolean  dri2_load(_EGLDriver *drv)  {     struct dri2_egl_driver *dri2_drv = dri2_egl_driver(drv); +#ifdef HAVE_SHARED_GLAPI +   const char *libname = "libglapi.so.0"; +#else +   /* +    * Both libGL.so and libglapi.so are glapi providers.  There is no way to +    * tell which one to load. +    */ +   const char *libname = NULL; +#endif     void *handle; -   handle = dlopen(NULL, RTLD_LAZY | RTLD_GLOBAL); +   /* RTLD_GLOBAL to make sure glapi symbols are visible to DRI drivers */ +   handle = dlopen(libname, 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 (!dri2_drv->get_proc_address || !libname) { +         /* no need to keep a reference */ +         dlclose(handle); +         handle = NULL; +      }     } -   /* -    * 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 glapi is not available, loading DRI drivers will fail */     if (!dri2_drv->get_proc_address) {        _eglLog(_EGL_WARNING, "DRI2: failed to find _glapi_get_proc_address");        return EGL_FALSE; @@ -2369,6 +2380,8 @@ dri2_load(_EGLDriver *drv)     dri2_drv->glFlush = (void (*)(void))        dri2_drv->get_proc_address("glFlush"); +   dri2_drv->handle = handle; +     return EGL_TRUE;  }  | 
