mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-04 05:22:30 +00:00
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
This commit is contained in:
parent
ee637bef1e
commit
bc7a7259f3
5 changed files with 99 additions and 73 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue