glwindow: provides some default implementations to factorize with all backends
authorJulien Isorce <j.isorce@samsung.com>
Tue, 26 May 2015 17:38:39 +0000 (18:38 +0100)
committerTim-Philipp Müller <tim@centricular.com>
Sat, 9 Dec 2017 19:32:02 +0000 (19:32 +0000)
gst-libs/gst/gl/gstglwindow.c

index 42de9ab..1b2309d 100644 (file)
@@ -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);
 }