mirror of
https://gitlab.freedesktop.org/wayland/weston.git
synced 2026-05-08 04:18:05 +02:00
pixman: Destroy pixman images when underlying buffer is destroyed
While the pixman image might be attached, the underlying buffer might be already gone under certain circumstances. This is easily reproduced by attempting to resize gnome-terminal on a fbdev backend. $ WAYLAND_DEBUG=1 strace -emunmap weston --backend=fbdev-backend.so ... [1524826.942] wl_shm@7.create_pool(new id wl_shm_pool@23, fd 40, 1563540) [1524827.315] wl_shm_pool@23.create_buffer(new id wl_buffer@24, 0, 759, 515, 3036, 0) ... [1524829.488] wl_surface@14.attach(wl_buffer@24, 0, 0) [1524829.766] wl_surface@14.set_buffer_scale(1) [1524829.904] wl_surface@14.damage(0, 0, 759, 515) [1524830.248] wl_surface@14.frame(new id wl_callback@25) [1524830.450] wl_surface@14.commit() ... [1524846.706] wl_shm@7.create_pool(new id wl_shm_pool@26, fd 40, 1545000) [1524847.215] wl_shm_pool@26.create_buffer(new id wl_buffer@27, 0, 750, 515, 3000, 0) [1524847.735] wl_buffer@24.destroy() [1524847.953] -> wl_display@1.delete_id(24) [1524848.144] wl_shm_pool@23.destroy() munmap(0xb5b2e000, 1563540) = 0 [1524849.021] -> wl_display@1.delete_id(23) [1524849.425] wl_surface@14.attach(wl_buffer@27, 0, 0) [1524849.730] wl_surface@14.set_buffer_scale(1) [1524849.821] wl_surface@14.damage(0, 0, 750, 515) <No commit yet, so drawing is attempted from older buffer that used to be attached to the surface, which happens to come from a destroyed pool, resulting it an invalid read from address 0xb5b2e000> Signed-off-by: Lubomir Rintel <lkundrak@v3.sk>
This commit is contained in:
parent
24dff2b704
commit
ddc2b1ec32
1 changed files with 31 additions and 1 deletions
|
|
@ -42,6 +42,7 @@ struct pixman_surface_state {
|
|||
pixman_image_t *image;
|
||||
struct weston_buffer_reference buffer_ref;
|
||||
|
||||
struct wl_listener buffer_destroy_listener;
|
||||
struct wl_listener surface_destroy_listener;
|
||||
struct wl_listener renderer_destroy_listener;
|
||||
};
|
||||
|
|
@ -467,6 +468,22 @@ pixman_renderer_flush_damage(struct weston_surface *surface)
|
|||
/* No-op for pixman renderer */
|
||||
}
|
||||
|
||||
static void
|
||||
buffer_state_handle_buffer_destroy(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct pixman_surface_state *ps;
|
||||
|
||||
ps = container_of(listener, struct pixman_surface_state,
|
||||
buffer_destroy_listener);
|
||||
|
||||
if (ps->image) {
|
||||
pixman_image_unref(ps->image);
|
||||
ps->image = NULL;
|
||||
}
|
||||
|
||||
ps->buffer_destroy_listener.notify = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
pixman_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
|
||||
{
|
||||
|
|
@ -476,6 +493,11 @@ pixman_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
|
|||
|
||||
weston_buffer_reference(&ps->buffer_ref, buffer);
|
||||
|
||||
if (ps->buffer_destroy_listener.notify) {
|
||||
wl_list_remove(&ps->buffer_destroy_listener.link);
|
||||
ps->buffer_destroy_listener.notify = NULL;
|
||||
}
|
||||
|
||||
if (ps->image) {
|
||||
pixman_image_unref(ps->image);
|
||||
ps->image = NULL;
|
||||
|
|
@ -517,6 +539,11 @@ pixman_renderer_attach(struct weston_surface *es, struct weston_buffer *buffer)
|
|||
buffer->width, buffer->height,
|
||||
wl_shm_buffer_get_data(shm_buffer),
|
||||
wl_shm_buffer_get_stride(shm_buffer));
|
||||
|
||||
ps->buffer_destroy_listener.notify =
|
||||
buffer_state_handle_buffer_destroy;
|
||||
wl_signal_add(&buffer->destroy_signal,
|
||||
&ps->buffer_destroy_listener);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -524,7 +551,10 @@ pixman_renderer_surface_state_destroy(struct pixman_surface_state *ps)
|
|||
{
|
||||
wl_list_remove(&ps->surface_destroy_listener.link);
|
||||
wl_list_remove(&ps->renderer_destroy_listener.link);
|
||||
|
||||
if (ps->buffer_destroy_listener.notify) {
|
||||
wl_list_remove(&ps->buffer_destroy_listener.link);
|
||||
ps->buffer_destroy_listener.notify = NULL;
|
||||
}
|
||||
|
||||
ps->surface->renderer_state = NULL;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue