Mesa (master): egl_dri2: Look up _glapi_get_proc_address dynamically.

Chia-I Wu olv at kemper.freedesktop.org
Mon Jan 10 03:51:50 UTC 2011


Module: Mesa
Branch: master
Commit: fef5d14494ff19ea302e247ba593e189a8ab62bd
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=fef5d14494ff19ea302e247ba593e189a8ab62bd

Author: Chia-I Wu <olv at lunarg.com>
Date:   Fri Jan  7 15:02:41 2011 +0800

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(-)

diff --git a/src/egl/drivers/dri2/Makefile b/src/egl/drivers/dri2/Makefile
index 8a3c9b6..ec4d1bc 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 7592984..5223298 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -47,7 +47,6 @@
 #include <libudev.h>
 #endif
 
-#include <glapi/glapi.h>
 #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;
 }




More information about the mesa-commit mailing list