#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);
struct _GstGLWindowPrivate
{
+ GMainContext *main_context;
+ GMainLoop *loop;
GThread *navigation_thread;
gboolean alive;
GstGLWindow parent;
guintptr handle;
-
- GMainContext *main_context;
- GMainLoop *loop;
} GstGLDummyWindow;
typedef struct _GstGLDummyWindowCass
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)
{
{
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;
/* 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
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
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
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
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));
}
/**
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)
{
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)
{
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)
{
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);
}