summaryrefslogtreecommitdiffstats
path: root/src/gallium/targets/egl-static/egl_st.c
diff options
context:
space:
mode:
authorChristian König <[email protected]>2011-07-04 15:04:41 +0200
committerChristian König <[email protected]>2011-07-04 15:04:41 +0200
commitc3b2230b71cb3a00a7f4c0987197d397bada650b (patch)
tree018f5df0f8b5976ddb56ef4f13e9466587838998 /src/gallium/targets/egl-static/egl_st.c
parent003401f95c9b59471c22368b7da16fe7a951e490 (diff)
parent424b1210d951c206e7c2fb8f2778acbd384eb247 (diff)
Merge remote-tracking branch 'origin/master' into pipe-video
Conflicts: configure.ac src/gallium/drivers/r600/r600_state_inlines.h src/gallium/tests/trivial/Makefile src/gallium/winsys/g3dvl/dri/XF86dri.c src/gallium/winsys/g3dvl/dri/driclient.c src/gallium/winsys/g3dvl/dri/driclient.h src/gallium/winsys/g3dvl/dri/xf86dri.h src/gallium/winsys/g3dvl/dri/xf86dristr.h src/gallium/winsys/r600/drm/r600_bo.c
Diffstat (limited to 'src/gallium/targets/egl-static/egl_st.c')
-rw-r--r--src/gallium/targets/egl-static/egl_st.c127
1 files changed, 109 insertions, 18 deletions
diff --git a/src/gallium/targets/egl-static/egl_st.c b/src/gallium/targets/egl-static/egl_st.c
index 3db52621def..81d7bb47568 100644
--- a/src/gallium/targets/egl-static/egl_st.c
+++ b/src/gallium/targets/egl-static/egl_st.c
@@ -29,52 +29,143 @@
#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)
{