summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Waters <matthew@centricular.com>2015-03-06 15:31:18 +1100
committerMatthew Waters <matthew@centricular.com>2015-03-11 13:52:15 +0000
commitbc7a7259f357b0065dd94e0668b5a895d83fa53a (patch)
tree946b60bb79d93d6f35ce5bb3e209608e7b770494
parentee637bef1ea87b7b1a9691bddff9454224aae56f (diff)
downloadgstreamer-plugins-bad-bc7a7259f357b0065dd94e0668b5a895d83fa53a.tar.gz
gl/window: create the main loop/context on init/finalize
Avoids races setting the window handle from the main thread. https://bugzilla.gnome.org/show_bug.cgi?id=745633
-rw-r--r--gst-libs/gst/gl/android/gstglwindow_android_egl.c25
-rw-r--r--gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m26
-rw-r--r--gst-libs/gst/gl/eagl/gstglwindow_eagl.m37
-rw-r--r--gst-libs/gst/gl/wayland/gstglwindow_wayland_egl.c30
-rw-r--r--gst-libs/gst/gl/x11/gstglwindow_x11.c54
5 files changed, 99 insertions, 73 deletions
diff --git a/gst-libs/gst/gl/android/gstglwindow_android_egl.c b/gst-libs/gst/gl/android/gstglwindow_android_egl.c
index 202aba08e..cbc0f7b2e 100644
--- a/gst-libs/gst/gl/android/gstglwindow_android_egl.c
+++ b/gst-libs/gst/gl/android/gstglwindow_android_egl.c
@@ -38,6 +38,7 @@
#define gst_gl_window_android_egl_parent_class parent_class
G_DEFINE_TYPE (GstGLWindowAndroidEGL, gst_gl_window_android_egl,
GST_GL_TYPE_WINDOW);
+static void gst_gl_window_android_egl_finalize (GObject * object);
static guintptr gst_gl_window_android_egl_get_display (GstGLWindow * window);
static guintptr gst_gl_window_android_egl_get_window_handle (GstGLWindow *
@@ -57,6 +58,7 @@ static void
gst_gl_window_android_egl_class_init (GstGLWindowAndroidEGLClass * klass)
{
GstGLWindowClass *window_class = (GstGLWindowClass *) klass;
+ GObjectClass *gobject_class = (GObjectClass *) klass;
window_class->get_display =
GST_DEBUG_FUNCPTR (gst_gl_window_android_egl_get_display);
@@ -73,11 +75,26 @@ gst_gl_window_android_egl_class_init (GstGLWindowAndroidEGLClass * klass)
GST_DEBUG_FUNCPTR (gst_gl_window_android_egl_send_message_async);
window_class->open = GST_DEBUG_FUNCPTR (gst_gl_window_android_egl_open);
window_class->close = GST_DEBUG_FUNCPTR (gst_gl_window_android_egl_close);
+
+ gobject_class->finalize = gst_gl_window_android_egl_finalize;
}
static void
gst_gl_window_android_egl_init (GstGLWindowAndroidEGL * window)
{
+ window->main_context = g_main_context_new ();
+ window->loop = g_main_loop_new (window->main_context, FALSE);
+}
+
+static void
+gst_gl_window_android_egl_finalize (GObject * object)
+{
+ GstGLWindowAndroidEGL *window_egl GST_GL_WINDOW_ANDROID_EGL (object);
+
+ g_main_loop_unref (window_egl->loop);
+ g_main_context_unref (window_egl->main_context);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
/* Must be called in the gl thread */
@@ -98,11 +115,6 @@ gst_gl_window_android_egl_open (GstGLWindow * window, GError ** error)
{
GstGLWindowAndroidEGL *window_egl;
- window_egl = GST_GL_WINDOW_ANDROID_EGL (window);
-
- window_egl->main_context = g_main_context_new ();
- window_egl->loop = g_main_loop_new (window_egl->main_context, FALSE);
-
return TRUE;
}
@@ -112,9 +124,6 @@ gst_gl_window_android_egl_close (GstGLWindow * window)
GstGLWindowAndroidEGL *window_egl;
window_egl = GST_GL_WINDOW_ANDROID_EGL (window);
-
- g_main_loop_unref (window_egl->loop);
- g_main_context_unref (window_egl->main_context);
}
static void
diff --git a/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m b/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m
index 17ded0467..1da6d63d7 100644
--- a/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m
+++ b/gst-libs/gst/gl/cocoa/gstglwindow_cocoa.m
@@ -65,6 +65,7 @@ GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
GST_DEBUG_CATEGORY_GET (GST_CAT_DEFAULT, "glwindow");
#define gst_gl_window_cocoa_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstGLWindowCocoa, gst_gl_window_cocoa, GST_GL_TYPE_WINDOW, DEBUG_INIT);
+static void gst_gl_window_cocoa_finalize (GObject * object);
static gboolean gst_gl_window_cocoa_open (GstGLWindow *window, GError **err);
static void gst_gl_window_cocoa_close (GstGLWindow *window);
@@ -96,9 +97,8 @@ struct _GstGLWindowCocoaPrivate
static void
gst_gl_window_cocoa_class_init (GstGLWindowCocoaClass * klass)
{
- GstGLWindowClass *window_class;
-
- window_class = (GstGLWindowClass *) klass;
+ GstGLWindowClass *window_class = (GstGLWindowClass *) klass;
+ GObjectClass *gobject_class = (GObjectClass *) klass;
g_type_class_add_private (klass, sizeof (GstGLWindowCocoaPrivate));
@@ -117,6 +117,8 @@ gst_gl_window_cocoa_class_init (GstGLWindowCocoaClass * klass)
window_class->set_preferred_size =
GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_set_preferred_size);
window_class->show = GST_DEBUG_FUNCPTR (gst_gl_window_cocoa_show);
+
+ gobject_class->finalize = gst_gl_window_cocoa_finalize;
}
static void
@@ -126,6 +128,20 @@ gst_gl_window_cocoa_init (GstGLWindowCocoa * window)
window->priv->preferred_width = 320;
window->priv->preferred_height = 240;
+
+ window->priv->main_context = g_main_context_new ();
+ window->priv->loop =g_main_loop_new (window->priv->main_context, FALSE);
+}
+
+static void
+gst_gl_window_cocoa_finalize (GObject * object)
+{
+ GstGLWindowCocoa *window_cocoa = GST_GL_WINDOW_COCOA (object);
+
+ g_main_loop_unref (window_cocoa->priv->loop);
+ g_main_context_unref (window_cocoa->priv->main_context);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
/* Must be called in the gl thread */
@@ -174,10 +190,6 @@ gst_gl_window_cocoa_open (GstGLWindow *window, GError **err)
window_cocoa = GST_GL_WINDOW_COCOA (window);
- window_cocoa->priv->main_context = g_main_context_new ();
- window_cocoa->priv->loop =
- g_main_loop_new (window_cocoa->priv->main_context, FALSE);
-
return TRUE;
}
diff --git a/gst-libs/gst/gl/eagl/gstglwindow_eagl.m b/gst-libs/gst/gl/eagl/gstglwindow_eagl.m
index edb0cb4c8..5f748d3e3 100644
--- a/gst-libs/gst/gl/eagl/gstglwindow_eagl.m
+++ b/gst-libs/gst/gl/eagl/gstglwindow_eagl.m
@@ -40,6 +40,7 @@ GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
#define gst_gl_window_eagl_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstGLWindowEagl, gst_gl_window_eagl,
GST_GL_TYPE_WINDOW, DEBUG_INIT);
+static void gst_gl_window_eagl_finalize (GObject * object);
static guintptr gst_gl_window_eagl_get_display (GstGLWindow * window);
static guintptr gst_gl_window_eagl_get_window_handle (GstGLWindow * window);
@@ -68,9 +69,8 @@ struct _GstGLWindowEaglPrivate
static void
gst_gl_window_eagl_class_init (GstGLWindowEaglClass * klass)
{
- GstGLWindowClass *window_class;
-
- window_class = (GstGLWindowClass *) klass;
+ GstGLWindowClass *window_class = (GstGLWindowClass *) klass;
+ GObjectClass *gobject_class = (GObjectClass *) klass;
g_type_class_add_private (klass, sizeof (GstGLWindowEaglPrivate));
@@ -90,12 +90,29 @@ gst_gl_window_eagl_class_init (GstGLWindowEaglClass * klass)
window_class->close = GST_DEBUG_FUNCPTR (gst_gl_window_eagl_close);
window_class->set_preferred_size =
GST_DEBUG_FUNCPTR (gst_gl_window_eagl_set_preferred_size);
+
+ gobject_class->finalize = gst_gl_window_eagl_finalize;
}
static void
gst_gl_window_eagl_init (GstGLWindowEagl * window)
{
window->priv = GST_GL_WINDOW_EAGL_GET_PRIVATE (window);
+
+ window_eagl->priv->main_context = g_main_context_new ();
+ window_eagl->priv->loop =
+ g_main_loop_new (window_eagl->priv->main_context, FALSE);
+}
+
+static void
+gst_gl_window_eagl_finalize (GObject * object)
+{
+ GstGLWindowWaylandEagl *window_eagl = GST_GL_WINDOW_EAGL (object);
+
+ g_main_loop_unref (window_eagl->priv->loop);
+ g_main_context_unref (window_egl->priv->main_context);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
/* Must be called in the gl thread */
@@ -132,26 +149,12 @@ gst_gl_window_eagl_set_window_handle (GstGLWindow * window, guintptr handle)
static gboolean
gst_gl_window_eagl_open (GstGLWindow * window, GError ** error)
{
- GstGLWindowEagl *window_eagl;
-
- window_eagl = GST_GL_WINDOW_EAGL (window);
-
- window_eagl->priv->main_context = g_main_context_new ();
- window_eagl->priv->loop =
- g_main_loop_new (window_eagl->priv->main_context, FALSE);
-
return TRUE;
}
static void
gst_gl_window_eagl_close (GstGLWindow * window)
{
- GstGLWindowEagl *window_eagl;
-
- window_eagl = GST_GL_WINDOW_EAGL (window);
-
- g_main_loop_unref (window_eagl->priv->loop);
- g_main_context_unref (window_eagl->priv->main_context);
}
static void
diff --git a/gst-libs/gst/gl/wayland/gstglwindow_wayland_egl.c b/gst-libs/gst/gl/wayland/gstglwindow_wayland_egl.c
index a0fa6207a..271a67799 100644
--- a/gst-libs/gst/gl/wayland/gstglwindow_wayland_egl.c
+++ b/gst-libs/gst/gl/wayland/gstglwindow_wayland_egl.c
@@ -41,6 +41,7 @@ const gchar *WlEGLErrorString ();
#define gst_gl_window_wayland_egl_parent_class parent_class
G_DEFINE_TYPE (GstGLWindowWaylandEGL, gst_gl_window_wayland_egl,
GST_GL_TYPE_WINDOW);
+static void gst_gl_window_wayland_egl_finalize (GObject * object);
static guintptr gst_gl_window_wayland_egl_get_window_handle (GstGLWindow *
window);
@@ -268,13 +269,6 @@ destroy_surface (GstGLWindowWaylandEGL * window_egl)
if (window_egl->window.callback)
wl_callback_destroy (window_egl->window.callback);
-
- g_source_destroy (window_egl->wl_source);
- g_source_unref (window_egl->wl_source);
- window_egl->wl_source = NULL;
- g_main_loop_unref (window_egl->loop);
- window_egl->loop = NULL, g_main_context_unref (window_egl->main_context);
- window_egl->main_context = NULL;
}
static void
@@ -311,6 +305,7 @@ static void
gst_gl_window_wayland_egl_class_init (GstGLWindowWaylandEGLClass * klass)
{
GstGLWindowClass *window_class = (GstGLWindowClass *) klass;
+ GObjectClass *gobject_class = (GObjectClass *) klass;
window_class->get_window_handle =
GST_DEBUG_FUNCPTR (gst_gl_window_wayland_egl_get_window_handle);
@@ -327,11 +322,26 @@ gst_gl_window_wayland_egl_class_init (GstGLWindowWaylandEGLClass * klass)
window_class->open = GST_DEBUG_FUNCPTR (gst_gl_window_wayland_egl_open);
window_class->get_display =
GST_DEBUG_FUNCPTR (gst_gl_window_wayland_egl_get_display);
+
+ gobject_class->finalize = gst_gl_window_wayland_egl_finalize;
}
static void
gst_gl_window_wayland_egl_init (GstGLWindowWaylandEGL * window)
{
+ window->main_context = g_main_context_new ();
+ window->loop = g_main_loop_new (window->main_context, FALSE);
+}
+
+static void
+gst_gl_window_wayland_egl_finalize (GObject * object)
+{
+ GstGLWindowWaylandEGL *window_egl = GST_GL_WINDOW_WAYLAND_EGL (object);
+
+ g_main_loop_unref (window_egl->loop);
+ g_main_context_unref (window_egl->main_context);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
}
/* Must be called in the gl thread */
@@ -372,6 +382,10 @@ gst_gl_window_wayland_egl_close (GstGLWindow * window)
wl_display_flush (window_egl->display.display);
wl_display_disconnect (window_egl->display.display);
}
+
+ g_source_destroy (window_egl->wl_source);
+ g_source_unref (window_egl->wl_source);
+ window_egl->wl_source = NULL;
}
static gboolean
@@ -401,8 +415,6 @@ gst_gl_window_wayland_egl_open (GstGLWindow * window, GError ** error)
window_egl->wl_source =
wayland_event_source_new (window_egl->display.display);
- window_egl->main_context = g_main_context_new ();
- window_egl->loop = g_main_loop_new (window_egl->main_context, FALSE);
g_source_attach (window_egl->wl_source, window_egl->main_context);
diff --git a/gst-libs/gst/gl/x11/gstglwindow_x11.c b/gst-libs/gst/gl/x11/gstglwindow_x11.c
index c5e7355f2..41a3983d4 100644
--- a/gst-libs/gst/gl/x11/gstglwindow_x11.c
+++ b/gst-libs/gst/gl/x11/gstglwindow_x11.c
@@ -90,7 +90,17 @@ void gst_gl_window_x11_handle_events (GstGLWindow * window,
static void
gst_gl_window_x11_finalize (GObject * object)
{
- g_return_if_fail (GST_GL_IS_WINDOW_X11 (object));
+ GstGLWindowX11 *window_x11 = GST_GL_WINDOW_X11 (object);
+
+ if (window_x11->loop) {
+ g_main_loop_unref (window_x11->loop);
+ window_x11->loop = NULL;
+ }
+ if (window_x11->main_context) {
+ g_main_context_unref (window_x11->main_context);
+ window_x11->main_context = NULL;
+ }
+
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -131,6 +141,9 @@ static void
gst_gl_window_x11_init (GstGLWindowX11 * window)
{
window->priv = GST_GL_WINDOW_X11_GET_PRIVATE (window);
+
+ window->main_context = g_main_context_new ();
+ window->loop = g_main_loop_new (window->main_context, FALSE);
}
/* Must be called in the gl thread */
@@ -186,8 +199,6 @@ gst_gl_window_x11_open (GstGLWindow * window, GError ** error)
DisplayHeight (window_x11->device, window_x11->screen_num);
window_x11->x11_source = x11_event_source_new (window_x11);
- window_x11->main_context = g_main_context_new ();
- window_x11->loop = g_main_loop_new (window_x11->main_context, FALSE);
g_source_attach (window_x11->x11_source, window_x11->main_context);
@@ -306,20 +317,21 @@ gst_gl_window_x11_close (GstGLWindow * window)
g_source_destroy (window_x11->x11_source);
g_source_unref (window_x11->x11_source);
window_x11->x11_source = NULL;
- g_main_loop_unref (window_x11->loop);
- window_x11->loop = NULL;
- g_main_context_unref (window_x11->main_context);
- window_x11->main_context = NULL;
window_x11->running = FALSE;
}
-static void
-set_window_handle_cb (gpointer data)
+/* called by the gl thread */
+void
+gst_gl_window_x11_set_window_handle (GstGLWindow * window, guintptr id)
{
- GstGLWindowX11 *window_x11 = GST_GL_WINDOW_X11 (data);
+ GstGLWindowX11 *window_x11;
XWindowAttributes attr;
+ window_x11 = GST_GL_WINDOW_X11 (window);
+
+ window_x11->parent_win = (Window) id;
+
XGetWindowAttributes (window_x11->device, window_x11->parent_win, &attr);
XResizeWindow (window_x11->device, window_x11->internal_win_id,
@@ -331,28 +343,6 @@ set_window_handle_cb (gpointer data)
XSync (window_x11->device, FALSE);
}
-/* Not called by the gl thread */
-void
-gst_gl_window_x11_set_window_handle (GstGLWindow * window, guintptr id)
-{
- GstGLWindowX11 *window_x11;
-
- window_x11 = GST_GL_WINDOW_X11 (window);
-
- window_x11->parent_win = (Window) id;
-
- /* The loop may not exist yet because it's created in GstGLWindow::open
- * which is only called when going from READY to PAUSED state.
- * If no loop then the parent is directly set in XCreateWindow
- */
- if (window_x11->loop && g_main_loop_is_running (window_x11->loop)) {
- GST_LOG ("set parent window id: %" G_GUINTPTR_FORMAT, id);
-
- gst_gl_window_send_message (window, (GstGLWindowCB) set_window_handle_cb,
- window_x11);
- }
-}
-
guintptr
gst_gl_window_x11_get_window_handle (GstGLWindow * window)
{