mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-20 00:31:13 +00:00
gldisplay: add gst_gl_display_create_context
It also emits a create-context signal so that an application can provide an external GstGLContext backend. https://bugzilla.gnome.org/show_bug.cgi?id=750310
This commit is contained in:
parent
38a1939ea1
commit
76983d4454
3 changed files with 112 additions and 35 deletions
|
@ -696,22 +696,37 @@ _ensure_gl_setup (GstGLImageSink * gl_sink)
|
||||||
if (!gl_sink->context) {
|
if (!gl_sink->context) {
|
||||||
GST_OBJECT_LOCK (gl_sink->display);
|
GST_OBJECT_LOCK (gl_sink->display);
|
||||||
do {
|
do {
|
||||||
GstGLContext *other_context;
|
GstGLContext *other_context = NULL;
|
||||||
GstGLWindow *window;
|
GstGLWindow *window = NULL;
|
||||||
|
|
||||||
if (gl_sink->context)
|
if (gl_sink->context) {
|
||||||
gst_object_unref (gl_sink->context);
|
gst_object_unref (gl_sink->context);
|
||||||
|
gl_sink->context = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (gl_sink,
|
GST_DEBUG_OBJECT (gl_sink,
|
||||||
"No current context, creating one for %" GST_PTR_FORMAT,
|
"No current context, creating one for %" GST_PTR_FORMAT,
|
||||||
gl_sink->display);
|
gl_sink->display);
|
||||||
|
|
||||||
gl_sink->context = gst_gl_context_new (gl_sink->display);
|
if (gl_sink->other_context) {
|
||||||
if (!gl_sink->context) {
|
other_context = gst_object_ref (gl_sink->other_context);
|
||||||
GST_OBJECT_UNLOCK (gl_sink->display);
|
} else {
|
||||||
goto context_creation_error;
|
other_context =
|
||||||
|
gst_gl_display_get_gl_context_for_thread (gl_sink->display, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!gst_gl_display_create_context (gl_sink->display,
|
||||||
|
other_context, &gl_sink->context, &error)) {
|
||||||
|
if (other_context)
|
||||||
|
gst_object_unref (other_context);
|
||||||
|
GST_OBJECT_UNLOCK (gl_sink->display);
|
||||||
|
goto context_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (gl_sink,
|
||||||
|
"created context %" GST_PTR_FORMAT " from other context %"
|
||||||
|
GST_PTR_FORMAT, gl_sink->context, gl_sink->other_context);
|
||||||
|
|
||||||
window = gst_gl_context_get_window (gl_sink->context);
|
window = gst_gl_context_get_window (gl_sink->context);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (gl_sink, "got window %" GST_PTR_FORMAT, window);
|
GST_DEBUG_OBJECT (gl_sink, "got window %" GST_PTR_FORMAT, window);
|
||||||
|
@ -729,25 +744,6 @@ _ensure_gl_setup (GstGLImageSink * gl_sink)
|
||||||
gst_gl_window_set_window_handle (window, gl_sink->window_id);
|
gst_gl_window_set_window_handle (window, gl_sink->window_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gl_sink->other_context) {
|
|
||||||
other_context = gst_object_ref (gl_sink->other_context);
|
|
||||||
} else {
|
|
||||||
other_context =
|
|
||||||
gst_gl_display_get_gl_context_for_thread (gl_sink->display, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (gl_sink,
|
|
||||||
"creating context %" GST_PTR_FORMAT " from other context %"
|
|
||||||
GST_PTR_FORMAT, gl_sink->context, other_context);
|
|
||||||
|
|
||||||
if (!gst_gl_context_create (gl_sink->context, other_context, &error)) {
|
|
||||||
if (other_context)
|
|
||||||
gst_object_unref (other_context);
|
|
||||||
gst_object_unref (window);
|
|
||||||
GST_OBJECT_UNLOCK (gl_sink->display);
|
|
||||||
goto context_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
gst_gl_window_handle_events (window, gl_sink->handle_events);
|
gst_gl_window_handle_events (window, gl_sink->handle_events);
|
||||||
|
|
||||||
/* setup callbacks */
|
/* setup callbacks */
|
||||||
|
@ -782,19 +778,21 @@ _ensure_gl_setup (GstGLImageSink * gl_sink)
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
context_creation_error:
|
|
||||||
{
|
|
||||||
GST_ELEMENT_ERROR (gl_sink, RESOURCE, NOT_FOUND,
|
|
||||||
("Failed to create GL context"), (NULL));
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
context_error:
|
context_error:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (gl_sink, RESOURCE, NOT_FOUND, ("%s", error->message),
|
GST_ELEMENT_ERROR (gl_sink, RESOURCE, NOT_FOUND, ("%s", error->message),
|
||||||
(NULL));
|
(NULL));
|
||||||
gst_object_unref (gl_sink->context);
|
|
||||||
gl_sink->context = NULL;
|
if (gl_sink->context) {
|
||||||
|
gst_object_unref (gl_sink->context);
|
||||||
|
gl_sink->context = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
g_error_free (error);
|
||||||
|
error = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,6 +84,15 @@ G_DEFINE_TYPE_WITH_CODE (GstGLDisplay, gst_gl_display, GST_TYPE_OBJECT,
|
||||||
#define GST_GL_DISPLAY_GET_PRIVATE(o) \
|
#define GST_GL_DISPLAY_GET_PRIVATE(o) \
|
||||||
(G_TYPE_INSTANCE_GET_PRIVATE((o), GST_TYPE_GL_DISPLAY, GstGLDisplayPrivate))
|
(G_TYPE_INSTANCE_GET_PRIVATE((o), GST_TYPE_GL_DISPLAY, GstGLDisplayPrivate))
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
SIGNAL_0,
|
||||||
|
CREATE_CONTEXT,
|
||||||
|
LAST_SIGNAL
|
||||||
|
};
|
||||||
|
|
||||||
|
static guint gst_gl_display_signals[LAST_SIGNAL] = { 0 };
|
||||||
|
|
||||||
static void gst_gl_display_finalize (GObject * object);
|
static void gst_gl_display_finalize (GObject * object);
|
||||||
static guintptr gst_gl_display_default_get_handle (GstGLDisplay * display);
|
static guintptr gst_gl_display_default_get_handle (GstGLDisplay * display);
|
||||||
|
|
||||||
|
@ -99,6 +108,22 @@ gst_gl_display_class_init (GstGLDisplayClass * klass)
|
||||||
{
|
{
|
||||||
g_type_class_add_private (klass, sizeof (GstGLDisplayPrivate));
|
g_type_class_add_private (klass, sizeof (GstGLDisplayPrivate));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GstGLDisplay::create-context:
|
||||||
|
* @object: the #GstGLDisplay
|
||||||
|
* @context: other context to share resources with.
|
||||||
|
*
|
||||||
|
* Overrides the @GstGLContext creation mechanism.
|
||||||
|
* It can be called in any thread and it is emitted with
|
||||||
|
* display's object lock held.
|
||||||
|
*
|
||||||
|
* Returns: the new context.
|
||||||
|
*/
|
||||||
|
gst_gl_display_signals[CREATE_CONTEXT] =
|
||||||
|
g_signal_new ("create-context", G_TYPE_FROM_CLASS (klass),
|
||||||
|
G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_generic,
|
||||||
|
GST_GL_TYPE_CONTEXT, 1, GST_GL_TYPE_CONTEXT);
|
||||||
|
|
||||||
klass->get_handle = gst_gl_display_default_get_handle;
|
klass->get_handle = gst_gl_display_default_get_handle;
|
||||||
|
|
||||||
G_OBJECT_CLASS (klass)->finalize = gst_gl_display_finalize;
|
G_OBJECT_CLASS (klass)->finalize = gst_gl_display_finalize;
|
||||||
|
@ -341,6 +366,58 @@ gst_context_get_gl_display (GstContext * context, GstGLDisplay ** display)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_gl_display_create_context:
|
||||||
|
* @display: a #GstGLDisplay
|
||||||
|
* @other_context: other #GstGLContext to share resources with.
|
||||||
|
* @p_context: resulting #GstGLContext
|
||||||
|
* @error: resulting #GError
|
||||||
|
*
|
||||||
|
* It requires the display's object lock to be held.
|
||||||
|
*
|
||||||
|
* Returns: whether a new context could be created.
|
||||||
|
*
|
||||||
|
* Since: 1.6
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
gst_gl_display_create_context (GstGLDisplay * display,
|
||||||
|
GstGLContext * other_context, GstGLContext ** p_context, GError ** error)
|
||||||
|
{
|
||||||
|
GstGLContext *context = NULL;
|
||||||
|
gboolean ret = FALSE;
|
||||||
|
|
||||||
|
g_return_val_if_fail (display != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (p_context != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (error != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (*error == NULL, FALSE);
|
||||||
|
|
||||||
|
g_signal_emit (display, gst_gl_display_signals[CREATE_CONTEXT], 0,
|
||||||
|
other_context, &context);
|
||||||
|
|
||||||
|
if (context) {
|
||||||
|
*p_context = context;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
context = gst_gl_context_new (display);
|
||||||
|
if (!context) {
|
||||||
|
g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_FAILED,
|
||||||
|
"Failed to create GL context");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (display,
|
||||||
|
"creating context %" GST_PTR_FORMAT " from other context %"
|
||||||
|
GST_PTR_FORMAT, context, other_context);
|
||||||
|
|
||||||
|
ret = gst_gl_context_create (context, other_context, error);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
*p_context = context;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static GstGLContext *
|
static GstGLContext *
|
||||||
_get_gl_context_for_thread_unlocked (GstGLDisplay * display, GThread * thread)
|
_get_gl_context_for_thread_unlocked (GstGLDisplay * display, GThread * thread)
|
||||||
{
|
{
|
||||||
|
|
|
@ -92,6 +92,8 @@ GstGLAPI gst_gl_display_get_gl_api_unlocked (GstGLDisplay * display);
|
||||||
void gst_context_set_gl_display (GstContext * context, GstGLDisplay * display);
|
void gst_context_set_gl_display (GstContext * context, GstGLDisplay * display);
|
||||||
gboolean gst_context_get_gl_display (GstContext * context, GstGLDisplay ** display);
|
gboolean gst_context_get_gl_display (GstContext * context, GstGLDisplay ** display);
|
||||||
|
|
||||||
|
gboolean gst_gl_display_create_context (GstGLDisplay * display,
|
||||||
|
GstGLContext * other_context, GstGLContext ** p_context, GError **error);
|
||||||
GstGLContext * gst_gl_display_get_gl_context_for_thread (GstGLDisplay * display,
|
GstGLContext * gst_gl_display_get_gl_context_for_thread (GstGLDisplay * display,
|
||||||
GThread * thread);
|
GThread * thread);
|
||||||
gboolean gst_gl_display_add_context (GstGLDisplay * display,
|
gboolean gst_gl_display_add_context (GstGLDisplay * display,
|
||||||
|
|
Loading…
Reference in a new issue