From 40e91195ad8a20c073789dad192e7aaaf9af6eca Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Tue, 2 Feb 2016 14:36:25 -0500 Subject: [PATCH] wayland: don't handle buffer release centrally Right now we handle buffer releases coming from the compositor in a central place. We add a listener when first creating the shared buffers. This is problematic because a buffer can only have one listener on it at once so users of the buffer can't get notified when it's released. This commit moves the buffer listener code from the centrally managed display code to the cursor and window code. https://bugzilla.gnome.org/show_bug.cgi?id=761312 --- gdk/wayland/gdkcursor-wayland.c | 18 ++++++++++++++++++ gdk/wayland/gdkdisplay-wayland.c | 14 -------------- gdk/wayland/gdkwindow-wayland.c | 16 ++++++++++++++++ 3 files changed, 34 insertions(+), 14 deletions(-) diff --git a/gdk/wayland/gdkcursor-wayland.c b/gdk/wayland/gdkcursor-wayland.c index 4f938178be..4119633c79 100644 --- a/gdk/wayland/gdkcursor-wayland.c +++ b/gdk/wayland/gdkcursor-wayland.c @@ -401,6 +401,19 @@ _gdk_wayland_display_get_cursor_for_type (GdkDisplay *display, 1); } +static void +buffer_release_callback (void *_data, + struct wl_buffer *wl_buffer) +{ + cairo_surface_t *cairo_surface = _data; + + cairo_surface_destroy (cairo_surface); +} + +static const struct wl_buffer_listener buffer_listener = { + buffer_release_callback +}; + GdkCursor * _gdk_wayland_display_get_cursor_for_surface (GdkDisplay *display, cairo_surface_t *surface, @@ -409,6 +422,7 @@ _gdk_wayland_display_get_cursor_for_surface (GdkDisplay *display, { GdkWaylandCursor *cursor; GdkWaylandDisplay *wayland_display = GDK_WAYLAND_DISPLAY (display); + struct wl_buffer *buffer; cairo_t *cr; cursor = g_object_new (GDK_TYPE_WAYLAND_CURSOR, @@ -439,6 +453,10 @@ _gdk_wayland_display_get_cursor_for_surface (GdkDisplay *display, cursor->surface.width, cursor->surface.height, cursor->surface.scale); + + buffer = _gdk_wayland_shm_surface_get_wl_buffer (cursor->surface.cairo_surface); + wl_buffer_add_listener (buffer, &buffer_listener, cursor->surface.cairo_surface); + if (surface) { cr = cairo_create (cursor->surface.cairo_surface); diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c index 500e211c5d..db02c73d84 100644 --- a/gdk/wayland/gdkdisplay-wayland.c +++ b/gdk/wayland/gdkdisplay-wayland.c @@ -908,19 +908,6 @@ typedef struct _GdkWaylandCairoSurfaceData { uint32_t scale; } GdkWaylandCairoSurfaceData; -static void -buffer_release_callback (void *_data, - struct wl_buffer *wl_buffer) -{ - cairo_surface_t *surface = _data; - - cairo_surface_destroy (surface); -} - -static const struct wl_buffer_listener buffer_listener = { - buffer_release_callback -}; - static struct wl_shm_pool * create_shm_pool (struct wl_shm *shm, int size, @@ -1015,7 +1002,6 @@ _gdk_wayland_display_create_shm_surface (GdkWaylandDisplay *display, data->buffer = wl_shm_pool_create_buffer (data->pool, 0, width*scale, height*scale, stride, WL_SHM_FORMAT_ARGB8888); - wl_buffer_add_listener (data->buffer, &buffer_listener, surface); cairo_surface_set_user_data (surface, &gdk_wayland_shm_surface_cairo_key, data, gdk_wayland_cairo_surface_destroy); diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index 1c509e59cb..d0707c1cb2 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -580,6 +580,19 @@ gdk_wayland_window_attach_image (GdkWindow *window) impl->pending_commit = TRUE; } +static void +buffer_release_callback (void *_data, + struct wl_buffer *wl_buffer) +{ + cairo_surface_t *cairo_surface = _data; + + cairo_surface_destroy (cairo_surface); +} + +static const struct wl_buffer_listener buffer_listener = { + buffer_release_callback +}; + static void gdk_wayland_window_ensure_cairo_surface (GdkWindow *window) { @@ -601,11 +614,14 @@ gdk_wayland_window_ensure_cairo_surface (GdkWindow *window) else if (!impl->cairo_surface) { GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_window_get_display (impl->wrapper)); + struct wl_buffer *buffer; impl->cairo_surface = _gdk_wayland_display_create_shm_surface (display_wayland, impl->wrapper->width, impl->wrapper->height, impl->scale); + buffer = _gdk_wayland_shm_surface_get_wl_buffer (impl->cairo_surface); + wl_buffer_add_listener (buffer, &buffer_listener, impl->cairo_surface); } }