mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-28 03:00:35 +00:00
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
This commit is contained in:
parent
b1fc846f83
commit
8c56e1bba7
4 changed files with 110 additions and 46 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
GstGLAPI gl_api = gst_gl_context_get_gl_api (context);
|
||||
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue