summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2014-05-01 14:36:54 +0200
committerSebastian Dröge <sebastian@centricular.com>2014-05-01 14:36:54 +0200
commitcad1bb32c8dc34290524e029cb27a930eb84fa78 (patch)
treeffcfc1a10e46d5251b27d88d0a84894b08cf924d
parent5681f78362cc2b20b4dd71d1836e25c27e3e410f (diff)
downloadgstreamer-plugins-bad-cad1bb32c8dc34290524e029cb27a930eb84fa78.tar.gz
gl: Try harder to load symbols from the correct place
This commit makes the loading of the GModules threadsafe, and always first tries to load the symbol for the GL library that is selected for the current context. Only then it falls back to looking into the current module (NULL), and only as a last resort the context specific function (e.g. eglGetProcAddress()) is called. Also add configure parameters to select the names of the library modules instead of using the defaults, and let the defaults be independent of the G_MODULE_SUFFIX. https://bugzilla.gnome.org/show_bug.cgi?id=728753
-rw-r--r--configure.ac18
-rw-r--r--gst-libs/gst/gl/egl/gstglcontext_egl.c42
-rw-r--r--gst-libs/gst/gl/gstglcontext.c106
-rw-r--r--gst-libs/gst/gl/win32/gstglcontext_wgl.c4
-rw-r--r--gst-libs/gst/gl/x11/gstglcontext_glx.c4
5 files changed, 128 insertions, 46 deletions
diff --git a/configure.ac b/configure.ac
index aad766c65..e73032f46 100644
--- a/configure.ac
+++ b/configure.ac
@@ -527,6 +527,12 @@ AC_ARG_ENABLE([opengl],
*) AC_MSG_ERROR([bad value ${enableval} for --enable-opengl]) ;;
esac],[NEED_GL=auto])
+AC_ARG_WITH([opengl-module-name],
+ AS_HELP_STRING([--with-opengl-module-name],[library module name for OpenGL (default: libGL)]))
+if test x$with_opengl_module_name != x; then
+ AC_DEFINE_UNQUOTED(GST_GL_LIBGL_MODULE_NAME, "$with_opengl_module_name", [OpenGL module name])
+fi
+
AC_ARG_ENABLE([gles2],
[ --enable-gles2 Enable OpenGL|ES 2.0 support @<:@default=auto@:>@],
[case "${enableval}" in
@@ -536,6 +542,12 @@ AC_ARG_ENABLE([gles2],
*) AC_MSG_ERROR([bad value ${enableval} for --enable-gles2]) ;;
esac],[NEED_GLES2=auto])
+AC_ARG_WITH([gles2-module-name],
+ AS_HELP_STRING([--with-gles2-module-name],[library module name for GLES2 (default: libGLESv2)]))
+if test x$with_gles2_module_name != x; then
+ AC_DEFINE_UNQUOTED(GST_GL_LIBGLESV2_MODULE_NAME, "$with_gles2_module_name", [GLES2 module name])
+fi
+
AC_ARG_ENABLE([egl],
[ --enable-egl Enable EGL support @<:@default=auto@:>@],
[case "${enableval}" in
@@ -545,6 +557,12 @@ AC_ARG_ENABLE([egl],
*) AC_MSG_ERROR([bad value ${enableval} for --enable-egl]) ;;
esac],[NEED_EGL=auto])
+AC_ARG_WITH([egl-module-name],
+ AS_HELP_STRING([--with-egl-module-name],[library module name for EGL (default: libEGL)]))
+if test x$with_egl_module_name != x; then
+ AC_DEFINE_UNQUOTED(GST_GL_LIBEGL_MODULE_NAME, "$with_egl_module_name", [EGL module name])
+fi
+
AC_ARG_ENABLE([wgl],
[ --enable-wgl Enable WGL support @<:@default=auto@:>@],
[case "${enableval}" in
diff --git a/gst-libs/gst/gl/egl/gstglcontext_egl.c b/gst-libs/gst/gl/egl/gstglcontext_egl.c
index f9a570d6f..06e7a9b61 100644
--- a/gst-libs/gst/gl/egl/gstglcontext_egl.c
+++ b/gst-libs/gst/gl/egl/gstglcontext_egl.c
@@ -22,6 +22,8 @@
#include "config.h"
#endif
+#include <gmodule.h>
+
/* FIXME: Sharing contexts requires the EGLDisplay to be the same
* may need to box it.
*/
@@ -478,22 +480,48 @@ gst_gl_context_egl_get_gl_platform (GstGLContext * context)
return GST_GL_PLATFORM_EGL;
}
+static GModule *module_egl;
+
+static gpointer
+load_egl_module (gpointer user_data)
+{
+#ifdef GST_GL_LIBEGL_MODULE_NAME
+ module_egl = g_module_open (GST_GL_LIBEGL_MODULE_NAME, G_MODULE_BIND_LAZY);
+#else
+ /* This automatically handles the suffix and even .la files */
+ module_egl = g_module_open ("libEGL", G_MODULE_BIND_LAZY);
+
+ /* On Linux the .so is only in -dev packages, try with a real soname
+ * Proper compilers will optimize away the strcmp */
+ if (!module_egl && strcmp (G_MODULE_SUFFIX, "so") == 0)
+ module_egl = g_module_open ("libEGL.so.1", G_MODULE_BIND_LAZY);
+#endif
+
+ return NULL;
+}
+
static gpointer
gst_gl_context_egl_get_proc_address (GstGLContext * context, const gchar * name)
{
gpointer result = NULL;
+ static GOnce g_once = G_ONCE_INIT;
+
+ result = gst_gl_context_default_get_proc_address (context, name);
+
+ g_once (&g_once, load_egl_module, NULL);
+
+ if (!result && module_egl) {
+ g_module_symbol (module_egl, name, &result);
+ }
/* FIXME: On Android this returns wrong addresses for non-EGL functions */
#if GST_GL_HAVE_WINDOW_ANDROID
- if (!(result = gst_gl_context_default_get_proc_address (context, name))) {
- if (g_str_has_prefix (name, "egl"))
- result = eglGetProcAddress (name);
- }
+ if (!result && g_str_has_prefix (name, "egl")) {
#else
- if (!(result = eglGetProcAddress (name))) {
- result = gst_gl_context_default_get_proc_address (context, name);
- }
+ if (!result) {
+ result = eglGetProcAddress (name);
#endif
+ }
return result;
}
diff --git a/gst-libs/gst/gl/gstglcontext.c b/gst-libs/gst/gl/gstglcontext.c
index 2b397f9ed..8b5ab293f 100644
--- a/gst-libs/gst/gl/gstglcontext.c
+++ b/gst-libs/gst/gl/gstglcontext.c
@@ -71,6 +71,59 @@
#define USING_GLES2(display) (display->gl_api & GST_GL_API_GLES2)
#define USING_GLES3(display) (display->gl_api & GST_GL_API_GLES3)
+static GModule *module_self;
+
+#if GST_GL_HAVE_OPENGL
+static GOnce module_opengl_gonce = G_ONCE_INIT;
+static GModule *module_opengl;
+
+static gpointer
+load_opengl_module (gpointer user_data)
+{
+#ifdef GST_GL_LIBGL_MODULE_NAME
+ module_opengl = g_module_open (GST_GL_LIBGL_MODULE_NAME, G_MODULE_BIND_LAZY);
+#else
+ /* This automatically handles the suffix and even .la files */
+ module_opengl = g_module_open ("libGL", G_MODULE_BIND_LAZY);
+
+ /* On Linux the .so is only in -dev packages, try with a real soname
+ * Proper compilers will optimize away the strcmp */
+ if (!module_opengl && strcmp (G_MODULE_SUFFIX, "so") == 0)
+ module_opengl = g_module_open ("libGL.so.1", G_MODULE_BIND_LAZY);
+#endif
+
+ return NULL;
+}
+#endif
+
+#if GST_GL_HAVE_GLES2
+static GOnce module_gles2_gonce = G_ONCE_INIT;
+static GModule *module_gles2;
+
+static gpointer
+load_gles2_module (gpointer user_data)
+{
+#ifdef GST_GL_LIBGLESV2_MODULE_NAME
+ module_gles2 =
+ g_module_open (GST_GL_LIBGLESV2_MODULE_NAME, G_MODULE_BIND_LAZY);
+#else
+ /* This automatically handles the suffix and even .la files */
+ module_gles2 = g_module_open ("libGLESv2", G_MODULE_BIND_LAZY);
+
+ /* On Linux the .so is only in -dev packages, try with a real soname
+ * Proper compilers will optimize away the strcmp */
+ if (!module_gles2 && strcmp (G_MODULE_SUFFIX, "so") == 0)
+ module_gles2 = g_module_open ("libGLESv2.so.2", G_MODULE_BIND_LAZY);
+#endif
+
+ return NULL;
+}
+#endif
+
+#if GST_GL_HAVE_GLES3
+#error "Add module loading support for GLES3"
+#endif
+
#define GST_CAT_DEFAULT gst_gl_context_debug
GST_DEBUG_CATEGORY (GST_CAT_DEFAULT);
@@ -98,7 +151,6 @@ struct _GstGLContextPrivate
gboolean alive;
GstGLContext *other_context;
- GstGLAPI gl_api;
GError **error;
gint gl_major;
@@ -171,6 +223,8 @@ gst_gl_context_class_init (GstGLContextClass * klass)
{
g_type_class_add_private (klass, sizeof (GstGLContextPrivate));
+ module_self = g_module_open (NULL, G_MODULE_BIND_LAZY);
+
klass->get_proc_address =
GST_DEBUG_FUNCPTR (gst_gl_context_default_get_proc_address);
@@ -412,46 +466,28 @@ gst_gl_context_default_get_proc_address (GstGLContext * context,
const gchar * name)
{
gpointer ret = NULL;
- static GModule *module = NULL;
-
-#if GST_GL_HAVE_PLATFORM_EGL
- static GModule *module_egl = NULL;
-
- if (!module_egl) {
- module_egl = g_module_open ("libEGL.so.1", G_MODULE_BIND_LAZY);
-
- /* fallback */
- if (!module_egl)
- module_egl = g_module_open (NULL, G_MODULE_BIND_LAZY);
- }
-
- if (module_egl) {
- if (!g_module_symbol (module_egl, name, &ret)) {
- ret = NULL;
- }
- }
+ GstGLAPI gl_api = gst_gl_context_get_gl_api (context);
- if (ret)
- return ret;
-#endif
-
- if (!module) {
- const gchar *name = NULL;
+ /* First try to load symbol from the selected GL API for this context */
#if GST_GL_HAVE_GLES2
- name = "libGLESv2.so.2";
+ if (!ret && (gl_api & GST_GL_API_GLES2)) {
+ g_once (&module_gles2_gonce, load_gles2_module, NULL);
+ if (module_gles2)
+ g_module_symbol (module_gles2, name, &ret);
+ }
#endif
- module = g_module_open (name, G_MODULE_BIND_LAZY);
- /* fallback */
- if (!module)
- module = g_module_open (NULL, G_MODULE_BIND_LAZY);
+#if GST_GL_HAVE_OPENGL
+ if (!ret && (gl_api & (GST_GL_API_OPENGL | GST_GL_API_OPENGL3))) {
+ g_once (&module_opengl_gonce, load_opengl_module, NULL);
+ if (module_opengl)
+ g_module_symbol (module_opengl, name, &ret);
}
+#endif
- if (module) {
- if (!g_module_symbol (module, name, &ret)) {
- return NULL;
- }
- }
+ /* Otherwise fall back to the current module */
+ if (!ret)
+ g_module_symbol (module_self, name, &ret);
return ret;
}
diff --git a/gst-libs/gst/gl/win32/gstglcontext_wgl.c b/gst-libs/gst/gl/win32/gstglcontext_wgl.c
index e237006f7..4886e9af5 100644
--- a/gst-libs/gst/gl/win32/gstglcontext_wgl.c
+++ b/gst-libs/gst/gl/win32/gstglcontext_wgl.c
@@ -290,8 +290,8 @@ gst_gl_context_wgl_get_proc_address (GstGLContext * context, const gchar * name)
{
gpointer result;
- if (!(result = wglGetProcAddress ((LPCSTR) name))) {
- result = gst_gl_context_default_get_proc_address (context, name);
+ if (!(result = gst_gl_context_default_get_proc_address (context, name))) {
+ result = wglGetProcAddress ((LPCSTR) name);
}
return result;
diff --git a/gst-libs/gst/gl/x11/gstglcontext_glx.c b/gst-libs/gst/gl/x11/gstglcontext_glx.c
index 22e79ef45..7487faf6e 100644
--- a/gst-libs/gst/gl/x11/gstglcontext_glx.c
+++ b/gst-libs/gst/gl/x11/gstglcontext_glx.c
@@ -421,8 +421,8 @@ gst_gl_context_glx_get_proc_address (GstGLContext * context, const gchar * name)
{
gpointer result;
- if (!(result = glXGetProcAddressARB ((const GLubyte *) name))) {
- result = gst_gl_context_default_get_proc_address (context, name);
+ if (!(result = gst_gl_context_default_get_proc_address (context, name))) {
+ result = glXGetProcAddressARB ((const GLubyte *) name);
}
return result;