mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-25 15:36:42 +00:00
glcontext: allow wrapped contexts to be utilised like non-wrapped contexts
Fill in the missing pieces like get_proc_address, the gl function vtable
This commit is contained in:
parent
50a11e4a77
commit
bef3f020a6
3 changed files with 185 additions and 91 deletions
|
@ -372,6 +372,7 @@ gst_gl_context_new_wrapped (GstGLDisplay * display, guintptr handle,
|
||||||
if (context_type == GST_GL_PLATFORM_CGL) {
|
if (context_type == GST_GL_PLATFORM_CGL) {
|
||||||
context_class->get_current_context =
|
context_class->get_current_context =
|
||||||
gst_gl_context_cocoa_get_current_context;
|
gst_gl_context_cocoa_get_current_context;
|
||||||
|
context_class->get_proc_address = _default_get_proc_address;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if GST_GL_HAVE_PLATFORM_WGL
|
#if GST_GL_HAVE_PLATFORM_WGL
|
||||||
|
@ -384,9 +385,16 @@ gst_gl_context_new_wrapped (GstGLDisplay * display, guintptr handle,
|
||||||
if (context_type == GST_GL_PLATFORM_EAGL) {
|
if (context_type == GST_GL_PLATFORM_EAGL) {
|
||||||
context_class->get_current_context =
|
context_class->get_current_context =
|
||||||
gst_gl_context_eagl_get_current_context;
|
gst_gl_context_eagl_get_current_context;
|
||||||
|
context_class->get_proc_address = _default_get_proc_address;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (!context_class->get_current_context) {
|
||||||
|
/* we don't have API support */
|
||||||
|
gst_object_unref (context);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -698,7 +706,6 @@ gst_gl_context_get_proc_address (GstGLContext * context, const gchar * name)
|
||||||
GstGLContextClass *context_class;
|
GstGLContextClass *context_class;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_GL_IS_CONTEXT (context), NULL);
|
g_return_val_if_fail (GST_GL_IS_CONTEXT (context), NULL);
|
||||||
g_return_val_if_fail (!GST_GL_IS_WRAPPED_CONTEXT (context), NULL);
|
|
||||||
context_class = GST_GL_CONTEXT_GET_CLASS (context);
|
context_class = GST_GL_CONTEXT_GET_CLASS (context);
|
||||||
g_return_val_if_fail (context_class->get_proc_address != NULL, NULL);
|
g_return_val_if_fail (context_class->get_proc_address != NULL, NULL);
|
||||||
|
|
||||||
|
@ -1168,7 +1175,6 @@ gst_gl_context_create_thread (GstGLContext * context)
|
||||||
GstGLContextClass *context_class;
|
GstGLContextClass *context_class;
|
||||||
GstGLWindowClass *window_class;
|
GstGLWindowClass *window_class;
|
||||||
GstGLFuncs *gl;
|
GstGLFuncs *gl;
|
||||||
gboolean ret = FALSE;
|
|
||||||
GstGLAPI compiled_api, user_api, gl_api, display_api;
|
GstGLAPI compiled_api, user_api, gl_api, display_api;
|
||||||
gchar *api_string;
|
gchar *api_string;
|
||||||
gchar *compiled_api_s;
|
gchar *compiled_api_s;
|
||||||
|
@ -1177,8 +1183,6 @@ gst_gl_context_create_thread (GstGLContext * context)
|
||||||
const gchar *user_choice;
|
const gchar *user_choice;
|
||||||
GError **error;
|
GError **error;
|
||||||
GstGLContext *other_context;
|
GstGLContext *other_context;
|
||||||
GString *ext_g_str = NULL;
|
|
||||||
const gchar *ext_const_c_str = NULL;
|
|
||||||
|
|
||||||
g_mutex_lock (&context->priv->render_lock);
|
g_mutex_lock (&context->priv->render_lock);
|
||||||
|
|
||||||
|
@ -1247,7 +1251,7 @@ gst_gl_context_create_thread (GstGLContext * context)
|
||||||
}
|
}
|
||||||
GST_INFO ("created context");
|
GST_INFO ("created context");
|
||||||
|
|
||||||
if (!context_class->activate (context, TRUE)) {
|
if (!gst_gl_context_activate (context, TRUE)) {
|
||||||
g_set_error (error, GST_GL_CONTEXT_ERROR,
|
g_set_error (error, GST_GL_CONTEXT_ERROR,
|
||||||
GST_GL_CONTEXT_ERROR_RESOURCE_UNAVAILABLE,
|
GST_GL_CONTEXT_ERROR_RESOURCE_UNAVAILABLE,
|
||||||
"Failed to activate the GL Context");
|
"Failed to activate the GL Context");
|
||||||
|
@ -1280,6 +1284,116 @@ gst_gl_context_create_thread (GstGLContext * context)
|
||||||
g_free (user_api_s);
|
g_free (user_api_s);
|
||||||
g_free (display_api_s);
|
g_free (display_api_s);
|
||||||
|
|
||||||
|
gst_gl_context_fill_info (context, error);
|
||||||
|
|
||||||
|
context->priv->alive = TRUE;
|
||||||
|
|
||||||
|
if (gl->DebugMessageCallback) {
|
||||||
|
#if !defined(GST_DISABLE_GST_DEBUG)
|
||||||
|
GST_INFO ("Enabling GL context debugging");
|
||||||
|
/* enable them all */
|
||||||
|
gl->DebugMessageControl (GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, 0,
|
||||||
|
GL_TRUE);
|
||||||
|
gl->DebugMessageCallback (_gst_gl_debug_callback, context);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (other_context)
|
||||||
|
gst_object_unref (other_context);
|
||||||
|
|
||||||
|
g_cond_signal (&context->priv->create_cond);
|
||||||
|
|
||||||
|
// g_mutex_unlock (&context->priv->render_lock);
|
||||||
|
gst_gl_window_send_message_async (context->window,
|
||||||
|
(GstGLWindowCB) _unlock_create_thread, context, NULL);
|
||||||
|
|
||||||
|
gst_gl_window_run (context->window);
|
||||||
|
|
||||||
|
GST_INFO ("loop exited\n");
|
||||||
|
|
||||||
|
g_mutex_lock (&context->priv->render_lock);
|
||||||
|
|
||||||
|
context->priv->alive = FALSE;
|
||||||
|
|
||||||
|
gst_gl_context_activate (context, FALSE);
|
||||||
|
|
||||||
|
context_class->destroy_context (context);
|
||||||
|
|
||||||
|
/* User supplied callback */
|
||||||
|
if (context->window->close)
|
||||||
|
context->window->close (context->window->close_data);
|
||||||
|
|
||||||
|
/* window specific shutdown */
|
||||||
|
if (window_class->close) {
|
||||||
|
window_class->close (context->window);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_cond_signal (&context->priv->destroy_cond);
|
||||||
|
|
||||||
|
g_mutex_unlock (&context->priv->render_lock);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
failure:
|
||||||
|
{
|
||||||
|
if (other_context)
|
||||||
|
gst_object_unref (other_context);
|
||||||
|
|
||||||
|
g_cond_signal (&context->priv->create_cond);
|
||||||
|
g_mutex_unlock (&context->priv->render_lock);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_gl_context_destroy:
|
||||||
|
* @context: a #GstGLContext:
|
||||||
|
*
|
||||||
|
* Destroys an OpenGL context.
|
||||||
|
*
|
||||||
|
* Should only be called after gst_gl_context_create() has been successfully
|
||||||
|
* called for this context.
|
||||||
|
*
|
||||||
|
* Since: 1.6
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
gst_gl_context_destroy (GstGLContext * context)
|
||||||
|
{
|
||||||
|
GstGLContextClass *context_class;
|
||||||
|
|
||||||
|
g_return_if_fail (GST_GL_IS_CONTEXT (context));
|
||||||
|
context_class = GST_GL_CONTEXT_GET_CLASS (context);
|
||||||
|
g_return_if_fail (context_class->destroy_context != NULL);
|
||||||
|
|
||||||
|
context_class->destroy_context (context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_gl_context_fill_info:
|
||||||
|
* @context: a #GstGLContext:
|
||||||
|
*
|
||||||
|
* Fills @context's info (version, extensions, vtable, etc) from the GL
|
||||||
|
* context in the current thread. Typically used with wrapped contexts to
|
||||||
|
* allow wrapped contexts to be used as regular #GstGLContext's.
|
||||||
|
*
|
||||||
|
* Since: 1.6
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
gst_gl_context_fill_info (GstGLContext * context, GError ** error)
|
||||||
|
{
|
||||||
|
GstGLFuncs *gl;
|
||||||
|
GString *ext_g_str = NULL;
|
||||||
|
const gchar *ext_const_c_str = NULL;
|
||||||
|
GstGLAPI gl_api;
|
||||||
|
gboolean ret;
|
||||||
|
|
||||||
|
g_return_val_if_fail (GST_GL_IS_CONTEXT (context), FALSE);
|
||||||
|
g_return_val_if_fail (context->priv->active_thread == g_thread_self (),
|
||||||
|
FALSE);
|
||||||
|
|
||||||
|
gl = context->gl_vtable;
|
||||||
|
gl_api = gst_gl_context_get_gl_api (context);
|
||||||
|
|
||||||
gl->GetError = gst_gl_context_get_proc_address (context, "glGetError");
|
gl->GetError = gst_gl_context_get_proc_address (context, "glGetError");
|
||||||
gl->GetString = gst_gl_context_get_proc_address (context, "glGetString");
|
gl->GetString = gst_gl_context_get_proc_address (context, "glGetString");
|
||||||
gl->GetStringi = gst_gl_context_get_proc_address (context, "glGetStringi");
|
gl->GetStringi = gst_gl_context_get_proc_address (context, "glGetStringi");
|
||||||
|
@ -1331,86 +1445,10 @@ gst_gl_context_create_thread (GstGLContext * context)
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
context->priv->alive = TRUE;
|
return TRUE;
|
||||||
|
|
||||||
if (gl->DebugMessageCallback) {
|
|
||||||
#if !defined(GST_DISABLE_GST_DEBUG)
|
|
||||||
GST_INFO ("Enabling GL context debugging");
|
|
||||||
/* enable them all */
|
|
||||||
gl->DebugMessageControl (GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, 0,
|
|
||||||
GL_TRUE);
|
|
||||||
gl->DebugMessageCallback (_gst_gl_debug_callback, context);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (other_context)
|
|
||||||
gst_object_unref (other_context);
|
|
||||||
|
|
||||||
g_cond_signal (&context->priv->create_cond);
|
|
||||||
|
|
||||||
// g_mutex_unlock (&context->priv->render_lock);
|
|
||||||
gst_gl_window_send_message_async (context->window,
|
|
||||||
(GstGLWindowCB) _unlock_create_thread, context, NULL);
|
|
||||||
|
|
||||||
gst_gl_window_run (context->window);
|
|
||||||
|
|
||||||
GST_INFO ("loop exited\n");
|
|
||||||
|
|
||||||
g_mutex_lock (&context->priv->render_lock);
|
|
||||||
|
|
||||||
context->priv->alive = FALSE;
|
|
||||||
|
|
||||||
context_class->activate (context, FALSE);
|
|
||||||
|
|
||||||
context_class->destroy_context (context);
|
|
||||||
|
|
||||||
/* User supplied callback */
|
|
||||||
if (context->window->close)
|
|
||||||
context->window->close (context->window->close_data);
|
|
||||||
|
|
||||||
/* window specific shutdown */
|
|
||||||
if (window_class->close) {
|
|
||||||
window_class->close (context->window);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_cond_signal (&context->priv->destroy_cond);
|
|
||||||
|
|
||||||
g_mutex_unlock (&context->priv->render_lock);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
failure:
|
failure:
|
||||||
{
|
return FALSE;
|
||||||
if (other_context)
|
|
||||||
gst_object_unref (other_context);
|
|
||||||
|
|
||||||
g_cond_signal (&context->priv->create_cond);
|
|
||||||
g_mutex_unlock (&context->priv->render_lock);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* gst_gl_context_destroy:
|
|
||||||
* @context: a #GstGLContext:
|
|
||||||
*
|
|
||||||
* Destroys an OpenGL context.
|
|
||||||
*
|
|
||||||
* Should only be called after gst_gl_context_create() has been successfully
|
|
||||||
* called for this context.
|
|
||||||
*
|
|
||||||
* Since: 1.6
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
gst_gl_context_destroy (GstGLContext * context)
|
|
||||||
{
|
|
||||||
GstGLContextClass *context_class;
|
|
||||||
|
|
||||||
g_return_if_fail (GST_GL_IS_CONTEXT (context));
|
|
||||||
context_class = GST_GL_CONTEXT_GET_CLASS (context);
|
|
||||||
g_return_if_fail (context_class->destroy_context != NULL);
|
|
||||||
|
|
||||||
context_class->destroy_context (context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1512,7 +1550,12 @@ gst_gl_context_thread_add (GstGLContext * context,
|
||||||
|
|
||||||
g_return_if_fail (GST_GL_IS_CONTEXT (context));
|
g_return_if_fail (GST_GL_IS_CONTEXT (context));
|
||||||
g_return_if_fail (func != NULL);
|
g_return_if_fail (func != NULL);
|
||||||
g_return_if_fail (!GST_GL_IS_WRAPPED_CONTEXT (context));
|
|
||||||
|
if (GST_GL_IS_WRAPPED_CONTEXT (context)) {
|
||||||
|
g_return_if_fail (context->priv->active_thread == g_thread_self ());
|
||||||
|
func (context, data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
rdata.context = context;
|
rdata.context = context;
|
||||||
rdata.data = data;
|
rdata.data = data;
|
||||||
|
@ -1642,9 +1685,12 @@ gst_gl_wrapped_context_get_gl_platform (GstGLContext * context)
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_gl_wrapped_context_activate (GstGLContext * context, gboolean activate)
|
gst_gl_wrapped_context_activate (GstGLContext * context, gboolean activate)
|
||||||
{
|
{
|
||||||
g_assert_not_reached ();
|
if (activate)
|
||||||
|
context->priv->gl_thread = g_thread_self ();
|
||||||
|
else
|
||||||
|
context->priv->gl_thread = NULL;
|
||||||
|
|
||||||
return FALSE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -145,6 +145,8 @@ gboolean gst_gl_context_check_feature (GstGLContext *context, const gchar *
|
||||||
guintptr gst_gl_context_get_current_gl_context (GstGLPlatform platform);
|
guintptr gst_gl_context_get_current_gl_context (GstGLPlatform platform);
|
||||||
GstGLAPI gst_gl_context_get_current_gl_api (guint *major, guint *minor);
|
GstGLAPI gst_gl_context_get_current_gl_api (guint *major, guint *minor);
|
||||||
|
|
||||||
|
gboolean gst_gl_context_fill_info (GstGLContext * context, GError ** error);
|
||||||
|
|
||||||
/* FIXME: remove */
|
/* FIXME: remove */
|
||||||
void gst_gl_context_thread_add (GstGLContext * context,
|
void gst_gl_context_thread_add (GstGLContext * context,
|
||||||
GstGLContextThreadFunc func, gpointer data);
|
GstGLContextThreadFunc func, gpointer data);
|
||||||
|
|
|
@ -281,15 +281,49 @@ GST_START_TEST (test_share)
|
||||||
|
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
|
||||||
|
static void
|
||||||
|
accum_true (GstGLContext * context, gpointer data)
|
||||||
|
{
|
||||||
|
gint *i = data;
|
||||||
|
*i = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
check_wrapped (gpointer data)
|
||||||
|
{
|
||||||
|
GstGLContext *wrapped_context = data;
|
||||||
|
GError *error = NULL;
|
||||||
|
gint i = 0;
|
||||||
|
gboolean ret;
|
||||||
|
|
||||||
|
/* check that scheduling on an unactivated wrapped context asserts */
|
||||||
|
ASSERT_CRITICAL (gst_gl_context_thread_add (wrapped_context,
|
||||||
|
(GstGLContextThreadFunc) accum_true, &i));
|
||||||
|
fail_if (i != 0);
|
||||||
|
|
||||||
|
/* check that scheduling on an activated context succeeds */
|
||||||
|
gst_gl_context_activate (wrapped_context, TRUE);
|
||||||
|
gst_gl_context_thread_add (wrapped_context,
|
||||||
|
(GstGLContextThreadFunc) accum_true, &i);
|
||||||
|
fail_if (i != 1);
|
||||||
|
|
||||||
|
/* check filling out the wrapped context's info */
|
||||||
|
fail_if (wrapped_context->gl_vtable->TexImage2D != NULL);
|
||||||
|
ret = gst_gl_context_fill_info (wrapped_context, &error);
|
||||||
|
fail_if (!ret, "error received %s\n",
|
||||||
|
error ? error->message : "Unknown error");
|
||||||
|
fail_if (wrapped_context->gl_vtable->TexImage2D == NULL);
|
||||||
|
}
|
||||||
|
|
||||||
GST_START_TEST (test_wrapped_context)
|
GST_START_TEST (test_wrapped_context)
|
||||||
{
|
{
|
||||||
GstGLContext *context, *other_context, *wrapped_context;
|
GstGLContext *context, *other_context, *wrapped_context;
|
||||||
GstGLWindow *window, *other_window;
|
GstGLWindow *window, *other_window;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
gint i = 0;
|
gint i = 0;
|
||||||
guintptr handle;
|
guintptr handle, handle2;
|
||||||
GstGLPlatform platform;
|
GstGLPlatform platform, platform2;
|
||||||
GstGLAPI apis;
|
GstGLAPI apis, apis2;
|
||||||
|
|
||||||
context = gst_gl_context_new (display);
|
context = gst_gl_context_new (display);
|
||||||
|
|
||||||
|
@ -308,6 +342,14 @@ GST_START_TEST (test_wrapped_context)
|
||||||
wrapped_context =
|
wrapped_context =
|
||||||
gst_gl_context_new_wrapped (display, handle, platform, apis);
|
gst_gl_context_new_wrapped (display, handle, platform, apis);
|
||||||
|
|
||||||
|
handle2 = gst_gl_context_get_gl_context (wrapped_context);
|
||||||
|
platform2 = gst_gl_context_get_gl_platform (wrapped_context);
|
||||||
|
apis2 = gst_gl_context_get_gl_api (wrapped_context);
|
||||||
|
|
||||||
|
fail_if (handle != handle2);
|
||||||
|
fail_if (platform != platform2);
|
||||||
|
fail_if (apis != apis2);
|
||||||
|
|
||||||
other_context = gst_gl_context_new (display);
|
other_context = gst_gl_context_new (display);
|
||||||
other_window = gst_gl_window_new (display);
|
other_window = gst_gl_window_new (display);
|
||||||
gst_gl_context_set_window (other_context, other_window);
|
gst_gl_context_set_window (other_context, other_window);
|
||||||
|
@ -330,11 +372,15 @@ GST_START_TEST (test_wrapped_context)
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gst_object_unref (other_context);
|
||||||
|
|
||||||
|
gst_gl_window_send_message (window, GST_GL_WINDOW_CB (check_wrapped),
|
||||||
|
wrapped_context);
|
||||||
|
|
||||||
gst_gl_window_send_message (other_window, GST_GL_WINDOW_CB (deinit), context);
|
gst_gl_window_send_message (other_window, GST_GL_WINDOW_CB (deinit), context);
|
||||||
|
|
||||||
gst_object_unref (window);
|
|
||||||
gst_object_unref (other_window);
|
gst_object_unref (other_window);
|
||||||
gst_object_unref (other_context);
|
gst_object_unref (window);
|
||||||
gst_object_unref (context);
|
gst_object_unref (context);
|
||||||
gst_object_unref (wrapped_context);
|
gst_object_unref (wrapped_context);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue