summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/libs/gst-plugins-bad-libs-sections.txt2
-rw-r--r--gst-libs/gst/gl/cocoa/gstglcontext_cocoa.h1
-rw-r--r--gst-libs/gst/gl/cocoa/gstglcontext_cocoa.m6
-rw-r--r--gst-libs/gst/gl/eagl/gstglcontext_eagl.h1
-rw-r--r--gst-libs/gst/gl/eagl/gstglcontext_eagl.m5
-rw-r--r--gst-libs/gst/gl/egl/gstglcontext_egl.c11
-rw-r--r--gst-libs/gst/gl/egl/gstglcontext_egl.h1
-rw-r--r--gst-libs/gst/gl/gstglcontext.c169
-rw-r--r--gst-libs/gst/gl/gstglcontext.h6
-rw-r--r--gst-libs/gst/gl/win32/gstglcontext_wgl.c9
-rw-r--r--gst-libs/gst/gl/win32/gstglcontext_wgl.h1
-rw-r--r--gst-libs/gst/gl/x11/gstglcontext_glx.c13
-rw-r--r--gst-libs/gst/gl/x11/gstglcontext_glx.h1
-rw-r--r--tests/check/libs/gstglcontext.c55
14 files changed, 268 insertions, 13 deletions
diff --git a/docs/libs/gst-plugins-bad-libs-sections.txt b/docs/libs/gst-plugins-bad-libs-sections.txt
index f9051fa57..939004e00 100644
--- a/docs/libs/gst-plugins-bad-libs-sections.txt
+++ b/docs/libs/gst-plugins-bad-libs-sections.txt
@@ -804,6 +804,8 @@ gst_gl_context_get_display
gst_gl_context_get_gl_api
gst_gl_context_get_gl_context
gst_gl_context_get_gl_platform
+gst_gl_context_get_current_gl_context
+gst_gl_context_get_current_gl_api
gst_gl_context_get_thread
gst_gl_context_can_share
gst_gl_context_check_feature
diff --git a/gst-libs/gst/gl/cocoa/gstglcontext_cocoa.h b/gst-libs/gst/gl/cocoa/gstglcontext_cocoa.h
index d7f0e044c..1c5d66deb 100644
--- a/gst-libs/gst/gl/cocoa/gstglcontext_cocoa.h
+++ b/gst-libs/gst/gl/cocoa/gstglcontext_cocoa.h
@@ -61,6 +61,7 @@ struct _GstGLContextCocoaClass {
GType gst_gl_context_cocoa_get_type (void);
GstGLContextCocoa * gst_gl_context_cocoa_new (void);
+guintptr gst_gl_context_cocoa_get_current_context (void);
G_END_DECLS
diff --git a/gst-libs/gst/gl/cocoa/gstglcontext_cocoa.m b/gst-libs/gst/gl/cocoa/gstglcontext_cocoa.m
index 7a12650cc..94da0bca9 100644
--- a/gst-libs/gst/gl/cocoa/gstglcontext_cocoa.m
+++ b/gst-libs/gst/gl/cocoa/gstglcontext_cocoa.m
@@ -363,3 +363,9 @@ gst_gl_context_cocoa_get_gl_platform (GstGLContext * context)
{
return GST_GL_PLATFORM_CGL;
}
+
+guintptr
+gst_gl_context_cocoa_get_current_context (void)
+{
+ return (guintptr) [NSOpenGLContext currentContext];
+}
diff --git a/gst-libs/gst/gl/eagl/gstglcontext_eagl.h b/gst-libs/gst/gl/eagl/gstglcontext_eagl.h
index bc4618cf2..fca51772a 100644
--- a/gst-libs/gst/gl/eagl/gstglcontext_eagl.h
+++ b/gst-libs/gst/gl/eagl/gstglcontext_eagl.h
@@ -61,6 +61,7 @@ GstGLContextEagl * gst_gl_context_eagl_new (void);
void gst_gl_context_eagl_prepare_draw (GstGLContextEagl * context);
void gst_gl_context_eagl_finish_draw (GstGLContextEagl * context);
+guintptr gst_gl_context_eagl_get_current_context (void);
G_END_DECLS
diff --git a/gst-libs/gst/gl/eagl/gstglcontext_eagl.m b/gst-libs/gst/gl/eagl/gstglcontext_eagl.m
index e3b71f355..ab8691277 100644
--- a/gst-libs/gst/gl/eagl/gstglcontext_eagl.m
+++ b/gst-libs/gst/gl/eagl/gstglcontext_eagl.m
@@ -341,3 +341,8 @@ gst_gl_context_eagl_get_gl_platform (GstGLContext * context)
return GST_GL_PLATFORM_EAGL;
}
+guintptr
+gst_gl_context_eagl_get_current_context (void)
+{
+ return (guintptr) [EAGLContext currentContext];
+}
diff --git a/gst-libs/gst/gl/egl/gstglcontext_egl.c b/gst-libs/gst/gl/egl/gstglcontext_egl.c
index 16adff928..aebbdd57d 100644
--- a/gst-libs/gst/gl/egl/gstglcontext_egl.c
+++ b/gst-libs/gst/gl/egl/gstglcontext_egl.c
@@ -82,6 +82,8 @@ gst_gl_context_egl_class_init (GstGLContextEGLClass * klass)
GST_DEBUG_FUNCPTR (gst_gl_context_egl_get_proc_address);
context_class->check_feature =
GST_DEBUG_FUNCPTR (gst_gl_context_egl_check_feature);
+ context_class->get_current_context =
+ GST_DEBUG_FUNCPTR (gst_gl_context_egl_get_current_context);
}
static void
@@ -550,8 +552,9 @@ gst_gl_context_egl_get_proc_address (GstGLContext * context, const gchar * name)
{
gpointer result = NULL;
static GOnce g_once = G_ONCE_INIT;
+ GstGLAPI gl_api = gst_gl_context_get_gl_api (context);
- result = gst_gl_context_default_get_proc_address (context, name);
+ result = gst_gl_context_default_get_proc_address (gl_api, name);
g_once (&g_once, load_egl_module, NULL);
@@ -583,3 +586,9 @@ gst_gl_context_egl_check_feature (GstGLContext * context, const gchar * feature)
return FALSE;
}
+
+guintptr
+gst_gl_context_egl_get_current_context (void)
+{
+ return (guintptr) eglGetCurrentContext ();
+}
diff --git a/gst-libs/gst/gl/egl/gstglcontext_egl.h b/gst-libs/gst/gl/egl/gstglcontext_egl.h
index 96018655a..2f950f8b0 100644
--- a/gst-libs/gst/gl/egl/gstglcontext_egl.h
+++ b/gst-libs/gst/gl/egl/gstglcontext_egl.h
@@ -57,6 +57,7 @@ struct _GstGLContextEGLClass {
GType gst_gl_context_egl_get_type (void);
GstGLContextEGL * gst_gl_context_egl_new (void);
+guintptr gst_gl_context_egl_get_current_context (void);
/* TODO:
* add support for EGL_NO_CONTEXT
diff --git a/gst-libs/gst/gl/gstglcontext.c b/gst-libs/gst/gl/gstglcontext.c
index 783fb0450..2393a532e 100644
--- a/gst-libs/gst/gl/gstglcontext.c
+++ b/gst-libs/gst/gl/gstglcontext.c
@@ -67,6 +67,7 @@
GST_DEBUG_CATEGORY_STATIC (gst_performance);
static GModule *module_self;
+static GOnce module_self_gonce = G_ONCE_INIT;
#if GST_GL_HAVE_OPENGL
static GOnce module_opengl_gonce = G_ONCE_INIT;
@@ -118,6 +119,14 @@ load_gles2_module (gpointer user_data)
}
#endif
+static gpointer
+load_self_module (gpointer user_data)
+{
+ module_self = g_module_open (NULL, G_MODULE_BIND_LAZY);
+
+ return NULL;
+}
+
#if GST_GL_HAVE_GLES3
#error "Add module loading support for GLES3"
#endif
@@ -132,6 +141,8 @@ G_DEFINE_ABSTRACT_TYPE (GstGLContext, gst_gl_context, GST_TYPE_OBJECT);
(G_TYPE_INSTANCE_GET_PRIVATE((o), GST_GL_TYPE_CONTEXT, GstGLContextPrivate))
static gpointer gst_gl_context_create_thread (GstGLContext * context);
+static gpointer _default_get_proc_address (GstGLContext * context,
+ const gchar * name);
static void gst_gl_context_finalize (GObject * object);
struct _GstGLContextPrivate
@@ -226,10 +237,7 @@ 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);
+ klass->get_proc_address = GST_DEBUG_FUNCPTR (_default_get_proc_address);
G_OBJECT_CLASS (klass)->finalize = gst_gl_context_finalize;
}
@@ -339,6 +347,144 @@ gst_gl_context_new_wrapped (GstGLDisplay * display, guintptr handle,
return context;
}
+/**
+ * gst_gl_context_get_current_gl_context:
+ * @context_type: a #GstGLPlatform specifying the type of context to retreive
+ *
+ * Returns: The OpenGL context handle current in the calling thread or %NULL
+ */
+guintptr
+gst_gl_context_get_current_gl_context (GstGLPlatform context_type)
+{
+ guintptr handle = 0;
+
+ _init_debug ();
+
+#if GST_GL_HAVE_PLATFORM_GLX
+ if (!handle && (context_type & GST_GL_PLATFORM_GLX) != 0)
+ handle = gst_gl_context_glx_get_current_context ();
+#endif
+#if GST_GL_HAVE_PLATFORM_EGL
+ if (!handle && (context_type & GST_GL_PLATFORM_EGL) != 0)
+ handle = gst_gl_context_egl_get_current_context ();
+#endif
+#if GST_GL_HAVE_PLATFORM_CGL
+ if (!handle && (context_type & GST_GL_PLATFORM_CGL) != 0)
+ handle = gst_gl_context_cocoa_get_current_context ();
+#endif
+#if GST_GL_HAVE_PLATFORM_WGL
+ if (!handle && (context_type & GST_GL_PLATFORM_WGL) != 0)
+ handle = gst_gl_context_wgl_get_current_context ();
+#endif
+#if GST_GL_HAVE_PLATFORM_EAGL
+ if (!handle && (context_type & GST_GL_PLATFORM_EAGL) != 0)
+ handle = gst_gl_context_eagl_get_current_context ();
+#endif
+
+ if (!handle)
+ GST_WARNING ("Could not retreive current context");
+
+ return handle;
+}
+
+/**
+ * gst_gl_context_get_current_gl_api:
+ * @context_type: a #GstGLPlatform specifying the type of context to retreive
+ * @major: (out): (allow-none): the major version
+ * @minor: (out): (allow-none): the minor version
+ *
+ * If an error occurs, @major and @minor aren't modified and %GST_GL_API_NONE is
+ * returned.
+ *
+ * Returns: The version supported by the OpenGL context current in the calling
+ * thread or %GST_GL_API_NONE
+ */
+GstGLAPI
+gst_gl_context_get_current_gl_api (guint * major, guint * minor)
+{
+ const GLubyte *(*GetString) (GLenum name);
+ void (*GetIntegerv) (GLenum name, GLuint * n);
+ const gchar *version;
+ gint maj, min, n;
+ GstGLAPI ret = (1 << 31);
+
+ _init_debug ();
+
+ while (ret != GST_GL_API_NONE) {
+ /* FIXME: attempt to delve into the platform specific GetProcAddress */
+ GetString = gst_gl_context_default_get_proc_address (ret, "glGetString");
+ GetIntegerv =
+ gst_gl_context_default_get_proc_address (ret, "glGetIntegerv");
+ if (!GetString) {
+ goto next;
+ }
+
+ version = (const gchar *) GetString (GL_VERSION);
+ if (!version)
+ goto next;
+
+ /* strlen (x.x) == 3 */
+ n = strlen (version);
+ if (n < 3)
+ goto next;
+
+ if (g_strstr_len (version, 9, "OpenGL ES")) {
+ /* strlen (OpenGL ES x.x) == 13 */
+ if (n < 13)
+ goto next;
+
+ sscanf (&version[10], "%d.%d", &maj, &min);
+
+ if (maj <= 0 || min < 0)
+ goto next;
+
+ if (maj == 1) {
+ ret = GST_GL_API_GLES1;
+ break;
+ } else if (maj == 2 || maj == 3) {
+ ret = GST_GL_API_GLES2;
+ break;
+ }
+
+ goto next;
+ } else {
+ GLuint context_flags = 0;
+ sscanf (version, "%d.%d", &maj, &min);
+
+ if (maj <= 0 || min < 0)
+ goto next;
+
+#if GST_GL_HAVE_OPENGL
+ if (GetIntegerv && (maj > 3 || (maj == 3 && min > 1))) {
+ ret = GST_GL_API_NONE;
+ GetIntegerv (GL_CONTEXT_PROFILE_MASK, &context_flags);
+ if (context_flags & GL_CONTEXT_CORE_PROFILE_BIT)
+ ret |= GST_GL_API_OPENGL3;
+ if (context_flags & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT)
+ ret |= GST_GL_API_OPENGL;
+ break;
+ }
+#endif
+ ret = GST_GL_API_OPENGL;
+ break;
+ }
+
+ next:
+ /* iterate through the apis */
+ ret >>= 1;
+ }
+
+ if (ret == GST_GL_API_NONE)
+ return GST_GL_API_NONE;
+
+ if (major)
+ *major = maj;
+ if (minor)
+ *minor = min;
+
+ return ret;
+}
+
static void
gst_gl_context_finalize (GObject * object)
{
@@ -466,6 +612,14 @@ gst_gl_context_get_gl_api (GstGLContext * context)
return context_class->get_gl_api (context);
}
+static gpointer
+_default_get_proc_address (GstGLContext * context, const gchar * name)
+{
+ GstGLAPI gl_api = gst_gl_context_get_gl_api (context);
+
+ return gst_gl_context_default_get_proc_address (gl_api, name);
+}
+
/**
* gst_gl_context_get_proc_address:
* @context: a #GstGLContext
@@ -496,11 +650,9 @@ gst_gl_context_get_proc_address (GstGLContext * context, const gchar * name)
}
gpointer
-gst_gl_context_default_get_proc_address (GstGLContext * context,
- const gchar * name)
+gst_gl_context_default_get_proc_address (GstGLAPI gl_api, const gchar * name)
{
gpointer ret = NULL;
- GstGLAPI gl_api = gst_gl_context_get_gl_api (context);
/* First try to load symbol from the selected GL API for this context */
#if GST_GL_HAVE_GLES2
@@ -520,6 +672,7 @@ gst_gl_context_default_get_proc_address (GstGLContext * context,
#endif
/* Otherwise fall back to the current module */
+ g_once (&module_self_gonce, load_self_module, NULL);
if (!ret)
g_module_symbol (module_self, name, &ret);
@@ -1281,7 +1434,7 @@ void
gst_gl_context_get_gl_version (GstGLContext * context, gint * maj, gint * min)
{
g_return_if_fail (GST_GL_IS_CONTEXT (context));
- g_return_if_fail (maj == NULL && min == NULL);
+ g_return_if_fail (maj != NULL && min != NULL);
if (maj)
*maj = context->priv->gl_major;
diff --git a/gst-libs/gst/gl/gstglcontext.h b/gst-libs/gst/gl/gstglcontext.h
index d2acc0dee..9d243d1c6 100644
--- a/gst-libs/gst/gl/gstglcontext.h
+++ b/gst-libs/gst/gl/gstglcontext.h
@@ -95,6 +95,7 @@ struct _GstGLContext {
struct _GstGLContextClass {
GstObjectClass parent_class;
+ guintptr (*get_current_context) (void);
guintptr (*get_gl_context) (GstGLContext *context);
GstGLAPI (*get_gl_api) (GstGLContext *context);
GstGLPlatform (*get_gl_platform) (GstGLContext *context);
@@ -132,7 +133,7 @@ gboolean gst_gl_context_can_share (GstGLContext * context, GstGLCont
gboolean gst_gl_context_create (GstGLContext *context, GstGLContext *other_context, GError ** error);
void gst_gl_context_destroy (GstGLContext *context);
-gpointer gst_gl_context_default_get_proc_address (GstGLContext *context, const gchar *name);
+gpointer gst_gl_context_default_get_proc_address (GstGLAPI gl_api, const gchar *name);
gboolean gst_gl_context_set_window (GstGLContext *context, GstGLWindow *window);
GstGLWindow * gst_gl_context_get_window (GstGLContext *context);
@@ -141,6 +142,9 @@ void gst_gl_context_get_gl_version (GstGLContext *context, gint *maj, g
gboolean gst_gl_context_check_gl_version (GstGLContext * context, GstGLAPI api, gint maj, gint min);
gboolean gst_gl_context_check_feature (GstGLContext *context, const gchar *feature);
+guintptr gst_gl_context_get_current_gl_context (GstGLPlatform platform);
+GstGLAPI gst_gl_context_get_current_gl_api (guint *major, guint *minor);
+
/* FIXME: remove */
void gst_gl_context_thread_add (GstGLContext * context,
GstGLContextThreadFunc func, gpointer data);
diff --git a/gst-libs/gst/gl/win32/gstglcontext_wgl.c b/gst-libs/gst/gl/win32/gstglcontext_wgl.c
index 4886e9af5..7547b4727 100644
--- a/gst-libs/gst/gl/win32/gstglcontext_wgl.c
+++ b/gst-libs/gst/gl/win32/gstglcontext_wgl.c
@@ -289,10 +289,17 @@ static gpointer
gst_gl_context_wgl_get_proc_address (GstGLContext * context, const gchar * name)
{
gpointer result;
+ GstGLAPI gl_api = gst_gl_context_get_gl_api (context);
- if (!(result = gst_gl_context_default_get_proc_address (context, name))) {
+ if (!(result = gst_gl_context_default_get_proc_address (gl_api, name))) {
result = wglGetProcAddress ((LPCSTR) name);
}
return result;
}
+
+guintptr
+gst_gl_context_wgl_get_current_context (void)
+{
+ return (guintptr) wglGetCurrentContext ();
+}
diff --git a/gst-libs/gst/gl/win32/gstglcontext_wgl.h b/gst-libs/gst/gl/win32/gstglcontext_wgl.h
index b996dc7cb..d840175e1 100644
--- a/gst-libs/gst/gl/win32/gstglcontext_wgl.h
+++ b/gst-libs/gst/gl/win32/gstglcontext_wgl.h
@@ -56,6 +56,7 @@ struct _GstGLContextWGLClass {
GType gst_gl_context_wgl_get_type (void);
GstGLContextWGL * gst_gl_context_wgl_new (void);
+guintptr gst_gl_context_wgl_get_current_context (void);
G_END_DECLS
diff --git a/gst-libs/gst/gl/x11/gstglcontext_glx.c b/gst-libs/gst/gl/x11/gstglcontext_glx.c
index 00aa546ce..6614dddf7 100644
--- a/gst-libs/gst/gl/x11/gstglcontext_glx.c
+++ b/gst-libs/gst/gl/x11/gstglcontext_glx.c
@@ -96,6 +96,8 @@ gst_gl_context_glx_class_init (GstGLContextGLXClass * klass)
GST_DEBUG_FUNCPTR (gst_gl_context_glx_get_gl_platform);
context_class->get_proc_address =
GST_DEBUG_FUNCPTR (gst_gl_context_glx_get_proc_address);
+ context_class->get_current_context =
+ GST_DEBUG_FUNCPTR (gst_gl_context_glx_get_current_context);
}
static void
@@ -197,7 +199,7 @@ gst_gl_context_glx_create_context (GstGLContext * context,
context_attribs_3);
x_error = gst_gl_window_x11_untrap_x_errors ();
- context_glx->priv->context_api = GST_GL_API_OPENGL3 | GST_GL_API_OPENGL;
+ context_glx->priv->context_api = GST_GL_API_OPENGL;
if (!context_glx->glx_context || x_error != 0) {
GST_DEBUG ("Failed to create an Opengl 3 context. trying a legacy one");
@@ -423,10 +425,17 @@ static gpointer
gst_gl_context_glx_get_proc_address (GstGLContext * context, const gchar * name)
{
gpointer result;
+ GstGLAPI gl_api = gst_gl_context_get_gl_api (context);
- if (!(result = gst_gl_context_default_get_proc_address (context, name))) {
+ if (!(result = gst_gl_context_default_get_proc_address (gl_api, name))) {
result = glXGetProcAddressARB ((const GLubyte *) name);
}
return result;
}
+
+guintptr
+gst_gl_context_glx_get_current_context (void)
+{
+ return (guintptr) glXGetCurrentContext ();
+}
diff --git a/gst-libs/gst/gl/x11/gstglcontext_glx.h b/gst-libs/gst/gl/x11/gstglcontext_glx.h
index eca8d7f5d..0c08f24b8 100644
--- a/gst-libs/gst/gl/x11/gstglcontext_glx.h
+++ b/gst-libs/gst/gl/x11/gstglcontext_glx.h
@@ -60,6 +60,7 @@ struct _GstGLContextGLXClass {
GType gst_gl_context_glx_get_type (void);
GstGLContextGLX * gst_gl_context_glx_new (void);
+guintptr gst_gl_context_glx_get_current_context (void);
G_END_DECLS
diff --git a/tests/check/libs/gstglcontext.c b/tests/check/libs/gstglcontext.c
index bb7e295b0..d9249e921 100644
--- a/tests/check/libs/gstglcontext.c
+++ b/tests/check/libs/gstglcontext.c
@@ -341,6 +341,60 @@ GST_START_TEST (test_wrapped_context)
GST_END_TEST;
+struct context_info
+{
+ GstGLAPI api;
+ guint major;
+ guint minor;
+ GstGLPlatform platform;
+ guintptr handle;
+};
+
+static void
+_fill_context_info (GstGLContext * context, struct context_info *info)
+{
+ info->handle = gst_gl_context_get_current_gl_context (info->platform);
+ info->api = gst_gl_context_get_current_gl_api (&info->major, &info->minor);
+}
+
+GST_START_TEST (test_current_context)
+{
+ GstGLContext *context;
+ GError *error = NULL;
+ guintptr handle;
+ GstGLPlatform platform;
+ GstGLAPI api;
+ gint major, minor;
+ struct context_info info;
+
+ context = gst_gl_context_new (display);
+
+ gst_gl_context_create (context, 0, &error);
+
+ fail_if (error != NULL, "Error creating master context %s\n",
+ error ? error->message : "Unknown Error");
+
+ handle = gst_gl_context_get_gl_context (context);
+ platform = gst_gl_context_get_gl_platform (context);
+ api = gst_gl_context_get_gl_api (context);
+ gst_gl_context_get_gl_version (context, &major, &minor);
+
+ info.platform = platform;
+
+ gst_gl_context_thread_add (context,
+ (GstGLContextThreadFunc) _fill_context_info, &info);
+
+ fail_if (info.platform != platform);
+ fail_if (info.api != api);
+ fail_if (info.major != major);
+ fail_if (info.minor != minor);
+ fail_if (info.handle != handle);
+
+ gst_object_unref (context);
+}
+
+GST_END_TEST;
+
static Suite *
gst_gl_context_suite (void)
@@ -352,6 +406,7 @@ gst_gl_context_suite (void)
tcase_add_checked_fixture (tc_chain, setup, teardown);
tcase_add_test (tc_chain, test_share);
tcase_add_test (tc_chain, test_wrapped_context);
+ tcase_add_test (tc_chain, test_current_context);
return s;
}