From 072183ce616760c8859d5c14f3a440be003891bf Mon Sep 17 00:00:00 2001 From: Julien Isorce Date: Tue, 26 May 2015 18:38:39 +0100 Subject: [PATCH] glwindow: provides some default implementations to factorize with all backends --- gst-libs/gst/gl/gstglwindow.c | 230 ++++++++++++++++++++++-------------------- 1 file changed, 121 insertions(+), 109 deletions(-) diff --git a/gst-libs/gst/gl/gstglwindow.c b/gst-libs/gst/gl/gstglwindow.c index 42de9ab..1b2309d 100644 --- a/gst-libs/gst/gl/gstglwindow.c +++ b/gst-libs/gst/gl/gstglwindow.c @@ -77,8 +77,13 @@ G_DEFINE_ABSTRACT_TYPE (GstGLWindow, gst_gl_window, GST_TYPE_OBJECT); #define GST_GL_WINDOW_GET_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE((o), GST_GL_TYPE_WINDOW, GstGLWindowPrivate)) +static void gst_gl_window_default_draw (GstGLWindow * window); +static void gst_gl_window_default_run (GstGLWindow * window); +static void gst_gl_window_default_quit (GstGLWindow * window); static void gst_gl_window_default_send_message (GstGLWindow * window, GstGLWindowCB callback, gpointer data); +static void gst_gl_window_default_send_message_async (GstGLWindow * window, + GstGLWindowCB callback, gpointer data, GDestroyNotify destroy); static gpointer gst_gl_window_navigation_thread (GstGLWindow * window); void gst_gl_window_run_navigation (GstGLWindow * window); void gst_gl_window_open_navigation (GstGLWindow * window); @@ -87,6 +92,8 @@ void gst_gl_window_quit_navigation (GstGLWindow * window); struct _GstGLWindowPrivate { + GMainContext *main_context; + GMainLoop *loop; GThread *navigation_thread; gboolean alive; @@ -99,9 +106,6 @@ typedef struct _GstGLDummyWindow GstGLWindow parent; guintptr handle; - - GMainContext *main_context; - GMainLoop *loop; } GstGLDummyWindow; typedef struct _GstGLDummyWindowCass @@ -127,6 +131,39 @@ gst_gl_window_error_quark (void) return g_quark_from_static_string ("gst-gl-window-error-quark"); } +static gboolean +gst_gl_window_default_open (GstGLWindow * window, GError ** error) +{ + GstGLWindowPrivate *priv = window->priv; + + if (g_main_context_get_thread_default ()) { + priv->main_context = g_main_context_ref_thread_default (); + priv->loop = NULL; + priv->alive = TRUE; + } else { + priv->main_context = g_main_context_new (); + g_main_context_push_thread_default (priv->main_context); + priv->loop = g_main_loop_new (priv->main_context, FALSE); + } + + return TRUE; +} + +static void +gst_gl_window_default_close (GstGLWindow * window) +{ + GstGLWindowPrivate *priv = window->priv; + + if (priv->loop) + g_main_loop_unref (priv->loop); + else + priv->alive = FALSE; + + g_main_context_pop_thread_default (priv->main_context); + + g_main_context_unref (priv->main_context); +} + static void gst_gl_window_init (GstGLWindow * window) { @@ -148,7 +185,15 @@ gst_gl_window_class_init (GstGLWindowClass * klass) { g_type_class_add_private (klass, sizeof (GstGLWindowPrivate)); + klass->open = GST_DEBUG_FUNCPTR (gst_gl_window_default_open); + klass->close = GST_DEBUG_FUNCPTR (gst_gl_window_default_close); + klass->run = GST_DEBUG_FUNCPTR (gst_gl_window_default_run); + klass->quit = GST_DEBUG_FUNCPTR (gst_gl_window_default_quit); + klass->draw_unlocked = GST_DEBUG_FUNCPTR (gst_gl_window_default_draw); + klass->draw = GST_DEBUG_FUNCPTR (gst_gl_window_default_draw); klass->send_message = GST_DEBUG_FUNCPTR (gst_gl_window_default_send_message); + klass->send_message_async = + GST_DEBUG_FUNCPTR (gst_gl_window_default_send_message_async); G_OBJECT_CLASS (klass)->finalize = gst_gl_window_finalize; @@ -364,6 +409,29 @@ gst_gl_window_set_window_handle (GstGLWindow * window, guintptr handle) /* window_class->set_window_handle (window, handle); */ } +static void +draw_cb (gpointer data) +{ + GstGLWindow *window = GST_GL_WINDOW (data); + GstGLContext *context = gst_gl_window_get_context (window); + GstGLContextClass *context_class = GST_GL_CONTEXT_GET_CLASS (context); + + if (window->draw) + window->draw (window->draw_data); + + if (context_class->swap_buffers) + context_class->swap_buffers (context); + + gst_object_unref (context); +} + +static void +gst_gl_window_default_draw (GstGLWindow * window) +{ + gst_gl_window_send_message (window, (GstGLWindowCB) draw_cb, window); +} + + /** * gst_gl_window_draw_unlocked: * @window: a #GstGLWindow @@ -452,6 +520,12 @@ gst_gl_window_show (GstGLWindow * window) window_class->show (window); } +static void +gst_gl_window_default_run (GstGLWindow * window) +{ + g_main_loop_run (window->priv->loop); +} + /** * gst_gl_window_run: * @window: a #GstGLWindow @@ -490,6 +564,12 @@ gst_gl_window_run_navigation (GstGLWindow * window) g_main_loop_run (window->navigation_loop); } +static void +gst_gl_window_default_quit (GstGLWindow * window) +{ + g_main_loop_quit (window->priv->loop); +} + /** * gst_gl_window_quit: * @window: a #GstGLWindow @@ -592,6 +672,42 @@ gst_gl_window_send_message (GstGLWindow * window, GstGLWindowCB callback, window_class->send_message (window, callback, data); } +typedef struct _GstGLAsyncMessage +{ + GstGLWindowCB callback; + gpointer data; + GDestroyNotify destroy; +} GstGLAsyncMessage; + +static gboolean +_run_message_async (GstGLAsyncMessage * message) +{ + if (message->callback) + message->callback (message->data); + + if (message->destroy) + message->destroy (message->data); + + g_slice_free (GstGLAsyncMessage, message); + + return FALSE; +} + +static void +gst_gl_window_default_send_message_async (GstGLWindow * window, + GstGLWindowCB callback, gpointer data, GDestroyNotify destroy) +{ + GstGLWindowPrivate *priv = window->priv; + GstGLAsyncMessage *message = g_slice_new (GstGLAsyncMessage); + + message->callback = callback; + message->data = data; + message->destroy = destroy; + + g_main_context_invoke (priv->main_context, (GSourceFunc) _run_message_async, + message); +} + /** * gst_gl_window_send_message_async: * @window: a #GstGLWindow @@ -716,7 +832,8 @@ gst_gl_window_set_close_callback (GstGLWindow * window, GstGLWindowCB callback, gboolean gst_gl_window_is_running (GstGLWindow * window) { - return window->priv->alive; + GstGLWindowPrivate *priv = window->priv; + return priv->alive && (!priv->loop || g_main_loop_is_running (priv->loop)); } /** @@ -798,42 +915,6 @@ GType gst_gl_dummy_window_get_type (void); G_DEFINE_TYPE (GstGLDummyWindow, gst_gl_dummy_window, GST_GL_TYPE_WINDOW); -static gboolean -gst_gl_dummy_window_open (GstGLWindow * window, GError ** error) -{ - GstGLDummyWindow *dummy = (GstGLDummyWindow *) window; - - dummy->main_context = g_main_context_new (); - dummy->loop = g_main_loop_new (dummy->main_context, FALSE); - - return TRUE; -} - -static void -gst_gl_dummy_window_close (GstGLWindow * window) -{ - GstGLDummyWindow *dummy = (GstGLDummyWindow *) window; - - g_main_loop_unref (dummy->loop); - g_main_context_unref (dummy->main_context); -} - -static void -gst_gl_dummy_window_quit (GstGLWindow * window) -{ - GstGLDummyWindow *dummy = (GstGLDummyWindow *) window; - - g_main_loop_quit (dummy->loop); -} - -static void -gst_gl_dummy_window_run (GstGLWindow * window) -{ - GstGLDummyWindow *dummy = (GstGLDummyWindow *) window; - - g_main_loop_run (dummy->loop); -} - void gst_gl_window_open_navigation (GstGLWindow * window) { @@ -882,45 +963,6 @@ gst_gl_window_navigation_thread (GstGLWindow * window) return NULL; } -typedef struct _GstGLMessage -{ - GstGLWindowCB callback; - gpointer data; - GDestroyNotify destroy; -} GstGLMessage; - -static gboolean -_run_message (GstGLMessage * message) -{ - if (message->callback) - message->callback (message->data); - - if (message->destroy) - message->destroy (message->data); - - g_slice_free (GstGLMessage, message); - - return FALSE; -} - -static void -gst_gl_dummy_window_send_message_async (GstGLWindow * window, - GstGLWindowCB callback, gpointer data, GDestroyNotify destroy) -{ - GstGLDummyWindow *dummy; - GstGLMessage *message; - - dummy = (GstGLDummyWindow *) window; - message = g_slice_new (GstGLMessage); - - message->callback = callback; - message->data = data; - message->destroy = destroy; - - g_main_context_invoke (dummy->main_context, (GSourceFunc) _run_message, - message); -} - static void gst_gl_dummy_window_set_window_handle (GstGLWindow * window, guintptr handle) { @@ -937,28 +979,6 @@ gst_gl_dummy_window_get_window_handle (GstGLWindow * window) return (guintptr) dummy->handle; } -static void -draw_cb (gpointer data) -{ - GstGLDummyWindow *dummy = data; - GstGLWindow *window = GST_GL_WINDOW (dummy); - GstGLContext *context = gst_gl_window_get_context (window); - GstGLContextClass *context_class = GST_GL_CONTEXT_GET_CLASS (context); - - if (window->draw) - window->draw (window->draw_data); - - context_class->swap_buffers (context); - - gst_object_unref (context); -} - -static void -gst_gl_dummy_window_draw (GstGLWindow * window) -{ - gst_gl_window_send_message (window, (GstGLWindowCB) draw_cb, window); -} - static guintptr gst_gl_dummy_window_get_display (GstGLWindow * window) { @@ -982,14 +1002,6 @@ gst_gl_dummy_window_class_init (GstGLDummyWindowClass * klass) GST_DEBUG_FUNCPTR (gst_gl_dummy_window_get_window_handle); window_class->set_window_handle = GST_DEBUG_FUNCPTR (gst_gl_dummy_window_set_window_handle); - window_class->draw_unlocked = GST_DEBUG_FUNCPTR (gst_gl_dummy_window_draw); - window_class->draw = GST_DEBUG_FUNCPTR (gst_gl_dummy_window_draw); - window_class->run = GST_DEBUG_FUNCPTR (gst_gl_dummy_window_run); - window_class->quit = GST_DEBUG_FUNCPTR (gst_gl_dummy_window_quit); - window_class->send_message_async = - GST_DEBUG_FUNCPTR (gst_gl_dummy_window_send_message_async); - window_class->open = GST_DEBUG_FUNCPTR (gst_gl_dummy_window_open); - window_class->close = GST_DEBUG_FUNCPTR (gst_gl_dummy_window_close); window_class->get_surface_dimensions = GST_DEBUG_FUNCPTR (gst_gl_dummy_window_get_surface_dimensions); } -- 2.7.4