targets/egl-static: allow st/mesa to be dynamically loaded
authorChia-I Wu <olv@lunarg.com>
Thu, 23 Jun 2011 11:08:53 +0000 (20:08 +0900)
committerChia-I Wu <olv@lunarg.com>
Fri, 24 Jun 2011 07:43:03 +0000 (16:43 +0900)
When shared glapi is not enabled, there are two glapi providers and we
cannot decide which one to link to at build time.  It results in
unresolved symbols in st/mesa.  This commit makes st/mesa a loadable
module when shared glapi is not enabled, and hopes that the apps will
link to one of the glapi providers (GL or GLES).

src/gallium/targets/egl-static/egl.c
src/gallium/targets/egl-static/egl_st.c
src/gallium/targets/egl-static/egl_st.h
src/gallium/targets/egl-static/st_GL.c [new file with mode: 0644]

index eee97a5ca053e271f10a90326e5c49b0f33702c2..2caad0e1ee0fd0e1ea46540c11013caa6d93604e 100644 (file)
@@ -170,7 +170,7 @@ loader_fini(void)
       struct st_module *stmod = &st_modules[i];
 
       if (stmod->stapi) {
-         stmod->stapi->destroy(stmod->stapi);
+         egl_st_destroy_api(stmod->stapi);
          stmod->stapi = NULL;
       }
       stmod->initialized = FALSE;
index 3db52621defb83b32aeed34da82260a28e08c9ed..81d7bb4756820ff8c2b585e2f730244472acb7d4 100644 (file)
 #include "state_tracker/st_api.h"
 #include "egl_st.h"
 
-/* for st/mesa */
+#if FEATURE_GL || FEATURE_ES1 || FEATURE_ES2
 #include "state_tracker/st_gl_api.h"
-/* for st/vega */
+#endif
+
+#if FEATURE_VG
 #include "vg_api.h"
+#endif
+
+#if _EGL_EXTERNAL_GL
+
+#include "util/u_string.h"
+#include "util/u_dl.h"
+#include "egldriver.h"
+#include "egllog.h"
+
+static struct util_dl_library *egl_st_gl_lib;
+
+static EGLBoolean
+dlopen_gl_lib_cb(const char *dir, size_t len, void *callback_data)
+{
+   const char *name = (const char *) callback_data;
+   char path[1024];
+   int ret;
+
+   if (len) {
+      ret = util_snprintf(path, sizeof(path), "%.*s/%s" UTIL_DL_EXT,
+            len, dir, name);
+   }
+   else {
+      ret = util_snprintf(path, sizeof(path), "%s" UTIL_DL_EXT, name);
+   }
+
+   if (ret > 0 && ret < sizeof(path)) {
+      egl_st_gl_lib = util_dl_open(path);
+      if (egl_st_gl_lib)
+         _eglLog(_EGL_DEBUG, "loaded %s", path);
+   }
+
+   return !egl_st_gl_lib;
+}
 
 static struct st_api *
-st_GL_create_api(void)
+load_gl(const char *name, const char *procname)
 {
-#if FEATURE_GL || FEATURE_ES1 || FEATURE_ES2
-   return st_gl_api_create();
-#else
-   return NULL;
-#endif
+   struct st_api *(*create_api)(void);
+   struct st_api *stapi = NULL;
+
+   _eglSearchPathForEach(dlopen_gl_lib_cb, (void *) name);
+   if (!egl_st_gl_lib)
+      return NULL;
+
+   create_api = (struct st_api *(*)(void))
+      util_dl_get_proc_address(egl_st_gl_lib, procname);
+   if (create_api)
+      stapi = create_api();
+
+   if (!stapi) {
+      util_dl_close(egl_st_gl_lib);
+      egl_st_gl_lib = NULL;
+   }
+
+   return stapi;
 }
 
 static struct st_api *
-st_OpenVG_create_api(void)
+egl_st_load_gl(void)
 {
-#if FEATURE_VG
-   return (struct st_api *) vg_api_get();
-#else
-   return NULL;
-#endif
+   const char module[] = "st_GL";
+   const char symbol[] = "st_api_create_OpenGL";
+   struct st_api *stapi;
+
+   stapi = load_gl(module, symbol);
+
+   /* try again with libglapi.so loaded */
+   if (!stapi) {
+      struct util_dl_library *glapi = util_dl_open("libglapi" UTIL_DL_EXT);
+
+      if (glapi) {
+         _eglLog(_EGL_DEBUG, "retry with libglapi" UTIL_DL_EXT " loaded");
+
+         stapi = load_gl(module, symbol);
+         util_dl_close(glapi);
+      }
+   }
+   if (!stapi)
+      _eglLog(_EGL_WARNING, "unable to load %s" UTIL_DL_EXT, module);
+
+   return stapi;
 }
 
+#endif /* _EGL_EXTERNAL_GL */
+
 struct st_api *
 egl_st_create_api(enum st_api_type api)
 {
-   struct st_api *stapi;
+   struct st_api *stapi = NULL;
 
    switch (api) {
    case ST_API_OPENGL:
-      stapi = st_GL_create_api();
+#if FEATURE_GL || FEATURE_ES1 || FEATURE_ES2
+#if _EGL_EXTERNAL_GL
+      stapi = egl_st_load_gl();
+#else
+      stapi = st_gl_api_create();
+#endif
+#endif
       break;
    case ST_API_OPENVG:
-      stapi = st_OpenVG_create_api();
+#if FEATURE_VG
+      stapi = (struct st_api *) vg_api_get();
+#endif
       break;
    default:
       assert(!"Unknown API Type\n");
-      stapi = NULL;
       break;
    }
 
    return stapi;
 }
 
+void
+egl_st_destroy_api(struct st_api *stapi)
+{
+#if _EGL_EXTERNAL_GL
+   boolean is_gl = (stapi->api == ST_API_OPENGL);
+
+   stapi->destroy(stapi);
+
+   if (is_gl) {
+      util_dl_close(egl_st_gl_lib);
+      egl_st_gl_lib = NULL;
+   }
+#else
+   stapi->destroy(stapi);
+#endif
+}
+
 uint
 egl_st_get_profile_mask(enum st_api_type api)
 {
index ba82faf0b0e50ee662bcb6e3a6bff6ab4ed73502..7a3773c6ba2caa788a1992459791b774f4093caa 100644 (file)
@@ -34,6 +34,9 @@
 struct st_api *
 egl_st_create_api(enum st_api_type api);
 
+void
+egl_st_destroy_api(struct st_api *stapi);
+
 uint
 egl_st_get_profile_mask(enum st_api_type api);
 
diff --git a/src/gallium/targets/egl-static/st_GL.c b/src/gallium/targets/egl-static/st_GL.c
new file mode 100644 (file)
index 0000000..d9ca834
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.10
+ *
+ * Copyright (C) 2011 LunarG Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Chia-I Wu <olv@lunarg.com>
+ */
+#include "state_tracker/st_gl_api.h"
+#include "pipe/p_compiler.h"
+
+PUBLIC struct st_api *
+st_api_create_OpenGL(void)
+{
+   return st_gl_api_create();
+}