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
This commit is contained in:
Ray Strode 2016-02-02 14:36:25 -05:00
parent 2c300081c4
commit 40e91195ad
3 changed files with 34 additions and 14 deletions

View File

@ -401,6 +401,19 @@ _gdk_wayland_display_get_cursor_for_type (GdkDisplay *display,
1); 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 * GdkCursor *
_gdk_wayland_display_get_cursor_for_surface (GdkDisplay *display, _gdk_wayland_display_get_cursor_for_surface (GdkDisplay *display,
cairo_surface_t *surface, cairo_surface_t *surface,
@ -409,6 +422,7 @@ _gdk_wayland_display_get_cursor_for_surface (GdkDisplay *display,
{ {
GdkWaylandCursor *cursor; GdkWaylandCursor *cursor;
GdkWaylandDisplay *wayland_display = GDK_WAYLAND_DISPLAY (display); GdkWaylandDisplay *wayland_display = GDK_WAYLAND_DISPLAY (display);
struct wl_buffer *buffer;
cairo_t *cr; cairo_t *cr;
cursor = g_object_new (GDK_TYPE_WAYLAND_CURSOR, 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.width,
cursor->surface.height, cursor->surface.height,
cursor->surface.scale); 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) if (surface)
{ {
cr = cairo_create (cursor->surface.cairo_surface); cr = cairo_create (cursor->surface.cairo_surface);

View File

@ -908,19 +908,6 @@ typedef struct _GdkWaylandCairoSurfaceData {
uint32_t scale; uint32_t scale;
} GdkWaylandCairoSurfaceData; } 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 * static struct wl_shm_pool *
create_shm_pool (struct wl_shm *shm, create_shm_pool (struct wl_shm *shm,
int size, int size,
@ -1015,7 +1002,6 @@ _gdk_wayland_display_create_shm_surface (GdkWaylandDisplay *display,
data->buffer = wl_shm_pool_create_buffer (data->pool, 0, data->buffer = wl_shm_pool_create_buffer (data->pool, 0,
width*scale, height*scale, width*scale, height*scale,
stride, WL_SHM_FORMAT_ARGB8888); 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, cairo_surface_set_user_data (surface, &gdk_wayland_shm_surface_cairo_key,
data, gdk_wayland_cairo_surface_destroy); data, gdk_wayland_cairo_surface_destroy);

View File

@ -580,6 +580,19 @@ gdk_wayland_window_attach_image (GdkWindow *window)
impl->pending_commit = TRUE; 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 static void
gdk_wayland_window_ensure_cairo_surface (GdkWindow *window) 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) else if (!impl->cairo_surface)
{ {
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_window_get_display (impl->wrapper)); 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->cairo_surface = _gdk_wayland_display_create_shm_surface (display_wayland,
impl->wrapper->width, impl->wrapper->width,
impl->wrapper->height, impl->wrapper->height,
impl->scale); impl->scale);
buffer = _gdk_wayland_shm_surface_get_wl_buffer (impl->cairo_surface);
wl_buffer_add_listener (buffer, &buffer_listener, impl->cairo_surface);
} }
} }