mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-28 06:21:14 +00:00
gdkwindow-wayland: Obey Wayland buffer semantics
We can't destroy buffers if they're in-use by the compositor. Well, technically we can, but that is considered undefined by Wayland and mutter won't cope with it very well -- it simply kills the client. To solve this, we need to delay the destroy operation until the compositor tells us that it's released the buffer. To do this, hold an extra ref on the cairo surface as long as the surface is in-use by the compositor.
This commit is contained in:
parent
04b58bcf3e
commit
8061df1544
@ -417,7 +417,11 @@ on_frame_clock_after_paint (GdkFrameClock *clock,
|
|||||||
|
|
||||||
data = cairo_surface_get_user_data (impl->cairo_surface,
|
data = cairo_surface_get_user_data (impl->cairo_surface,
|
||||||
&gdk_wayland_cairo_key);
|
&gdk_wayland_cairo_key);
|
||||||
data->busy = TRUE;
|
if (!data->busy)
|
||||||
|
{
|
||||||
|
data->busy = TRUE;
|
||||||
|
cairo_surface_reference (impl->cairo_surface);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -610,7 +614,6 @@ gdk_wayland_cairo_surface_destroy (void *p)
|
|||||||
g_free (data);
|
g_free (data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct wl_shm_pool *
|
struct wl_shm_pool *
|
||||||
_create_shm_pool (struct wl_shm *shm,
|
_create_shm_pool (struct wl_shm *shm,
|
||||||
int width,
|
int width,
|
||||||
@ -667,9 +670,11 @@ static void
|
|||||||
buffer_release_callback (void *_data,
|
buffer_release_callback (void *_data,
|
||||||
struct wl_buffer *wl_buffer)
|
struct wl_buffer *wl_buffer)
|
||||||
{
|
{
|
||||||
GdkWaylandCairoSurfaceData *data = _data;
|
cairo_surface_t *surface = _data;
|
||||||
|
GdkWaylandCairoSurfaceData *data = cairo_surface_get_user_data (surface, &gdk_wayland_cairo_key);
|
||||||
|
|
||||||
data->busy = FALSE;
|
data->busy = FALSE;
|
||||||
|
cairo_surface_destroy (surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct wl_buffer_listener buffer_listener = {
|
static const struct wl_buffer_listener buffer_listener = {
|
||||||
@ -702,17 +707,17 @@ gdk_wayland_create_cairo_surface (GdkWaylandDisplay *display,
|
|||||||
&data->buf_length,
|
&data->buf_length,
|
||||||
&data->buf);
|
&data->buf);
|
||||||
|
|
||||||
data->buffer = wl_shm_pool_create_buffer (data->pool, 0,
|
|
||||||
width*scale, height*scale,
|
|
||||||
stride*scale, WL_SHM_FORMAT_ARGB8888);
|
|
||||||
wl_buffer_add_listener (data->buffer, &buffer_listener, data);
|
|
||||||
|
|
||||||
surface = cairo_image_surface_create_for_data (data->buf,
|
surface = cairo_image_surface_create_for_data (data->buf,
|
||||||
CAIRO_FORMAT_ARGB32,
|
CAIRO_FORMAT_ARGB32,
|
||||||
width*scale,
|
width*scale,
|
||||||
height*scale,
|
height*scale,
|
||||||
stride*scale);
|
stride*scale);
|
||||||
|
|
||||||
|
data->buffer = wl_shm_pool_create_buffer (data->pool, 0,
|
||||||
|
width*scale, height*scale,
|
||||||
|
stride*scale, WL_SHM_FORMAT_ARGB8888);
|
||||||
|
wl_buffer_add_listener (data->buffer, &buffer_listener, surface);
|
||||||
|
|
||||||
cairo_surface_set_user_data (surface, &gdk_wayland_cairo_key,
|
cairo_surface_set_user_data (surface, &gdk_wayland_cairo_key,
|
||||||
data, gdk_wayland_cairo_surface_destroy);
|
data, gdk_wayland_cairo_surface_destroy);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user