From 00cff1f9e4830663961847bb64115771d0eb0fa9 Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Fri, 22 May 2015 16:07:49 +1000 Subject: [PATCH] gl/wayland: run each window on a separate queue Based on patch by Julien Isorce https://bugzilla.gnome.org/show_bug.cgi?id=709747 --- .../gst/gl/wayland/gstglwindow_wayland_egl.c | 10 ++++- .../gst/gl/wayland/gstglwindow_wayland_egl.h | 1 + .../gst/gl/wayland/wayland_event_source.c | 41 ++++++++++++++++++- .../gst/gl/wayland/wayland_event_source.h | 7 +++- 4 files changed, 54 insertions(+), 5 deletions(-) diff --git a/gst-libs/gst/gl/wayland/gstglwindow_wayland_egl.c b/gst-libs/gst/gl/wayland/gstglwindow_wayland_egl.c index 34f0a0660e..6679abc500 100644 --- a/gst-libs/gst/gl/wayland/gstglwindow_wayland_egl.c +++ b/gst-libs/gst/gl/wayland/gstglwindow_wayland_egl.c @@ -236,8 +236,13 @@ create_surface (GstGLWindowWaylandEGL * window_egl) window_egl->window.surface = wl_compositor_create_surface (display->compositor); + wl_proxy_set_queue ((struct wl_proxy *) window_egl->window.surface, + window_egl->window.queue); + window_egl->window.shell_surface = wl_shell_get_shell_surface (display->shell, window_egl->window.surface); + wl_proxy_set_queue ((struct wl_proxy *) window_egl->window.shell_surface, + window_egl->window.queue); wl_shell_surface_add_listener (window_egl->window.shell_surface, &shell_surface_listener, window_egl); @@ -358,11 +363,14 @@ gst_gl_window_wayland_egl_open (GstGLWindow * window, GError ** error) return FALSE; } + window_egl->window.queue = wl_display_create_queue (display->display); + wl_display_roundtrip (display->display); create_surface (window_egl); - window_egl->wl_source = wayland_event_source_new (display->display); + window_egl->wl_source = wayland_event_source_new (display->display, + window_egl->window.queue); g_source_attach (window_egl->wl_source, window_egl->main_context); diff --git a/gst-libs/gst/gl/wayland/gstglwindow_wayland_egl.h b/gst-libs/gst/gl/wayland/gstglwindow_wayland_egl.h index b4f66d05b5..845b9254b1 100644 --- a/gst-libs/gst/gl/wayland/gstglwindow_wayland_egl.h +++ b/gst-libs/gst/gl/wayland/gstglwindow_wayland_egl.h @@ -63,6 +63,7 @@ struct display { struct window { struct display *display; + struct wl_event_queue *queue; struct wl_egl_window *native; struct wl_surface *surface; struct wl_shell_surface *shell_surface; diff --git a/gst-libs/gst/gl/wayland/wayland_event_source.c b/gst-libs/gst/gl/wayland/wayland_event_source.c index aaed61a084..ba853f0659 100644 --- a/gst-libs/gst/gl/wayland/wayland_event_source.c +++ b/gst-libs/gst/gl/wayland/wayland_event_source.c @@ -38,12 +38,47 @@ #include "wayland_event_source.h" +static void +sync_callback (void *data, struct wl_callback *callback, uint32_t serial) +{ + gboolean *done = data; + + *done = TRUE; + wl_callback_destroy (callback); +} + +static const struct wl_callback_listener sync_listener = { + sync_callback +}; + +gint +gst_gl_wl_display_roundtrip_queue (struct wl_display *display, + struct wl_event_queue *queue) +{ + struct wl_callback *callback = wl_display_sync (display); + gboolean done = FALSE; + gint ret = 0; + + if (callback == NULL) + return -1; + wl_callback_add_listener (callback, &sync_listener, &done); + wl_proxy_set_queue ((struct wl_proxy *) callback, queue); + while (!done && ret >= 0) + ret = wl_display_dispatch_queue (display, queue); + + if (ret == -1 && !done) + wl_callback_destroy (callback); + + return ret; +} + typedef struct _WaylandEventSource { GSource source; GPollFD pfd; uint32_t mask; struct wl_display *display; + struct wl_event_queue *queue; } WaylandEventSource; static gboolean @@ -79,7 +114,7 @@ wayland_event_source_dispatch (GSource * base, WaylandEventSource *source = (WaylandEventSource *) base; if (source->pfd.revents) { - wl_display_roundtrip (source->display); + wl_display_roundtrip_queue (source->display, source->queue); source->pfd.revents = 0; } @@ -97,13 +132,15 @@ static GSourceFuncs wayland_event_source_funcs = { }; GSource * -wayland_event_source_new (struct wl_display *display) +wayland_event_source_new (struct wl_display *display, + struct wl_event_queue *queue) { WaylandEventSource *source; source = (WaylandEventSource *) g_source_new (&wayland_event_source_funcs, sizeof (WaylandEventSource)); source->display = display; + source->queue = queue; source->pfd.fd = wl_display_get_fd (display); source->pfd.events = G_IO_IN | G_IO_ERR; g_source_add_poll (&source->source, &source->pfd); diff --git a/gst-libs/gst/gl/wayland/wayland_event_source.h b/gst-libs/gst/gl/wayland/wayland_event_source.h index e70d5681c5..940a5e0168 100644 --- a/gst-libs/gst/gl/wayland/wayland_event_source.h +++ b/gst-libs/gst/gl/wayland/wayland_event_source.h @@ -33,7 +33,10 @@ #include -GSource * -wayland_event_source_new (struct wl_display *display); +GSource * wayland_event_source_new (struct wl_display *display, + struct wl_event_queue *queue); + +gint gst_gl_wl_display_roundtrip_queue (struct wl_display *display, + struct wl_event_queue *queue); #endif /* __WAYLAND_EVENT_SOURCE_H__ */