gl/wayland: run each window on a separate queue

Based on patch by Julien Isorce <julien.isorce@collabora.co.uk>

https://bugzilla.gnome.org/show_bug.cgi?id=709747
This commit is contained in:
Matthew Waters 2015-05-22 16:07:49 +10:00 committed by Tim-Philipp Müller
parent 0f6b04c91d
commit 00cff1f9e4
4 changed files with 54 additions and 5 deletions

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -33,7 +33,10 @@
#include <wayland-client.h>
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__ */