From 859373b2539b747906b7b1bc1addd3466d7ec946 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Thu, 14 Mar 2024 14:05:55 +0100 Subject: [PATCH] scene: listen to renderer destroy in wlr_scene_buffer When a renderer is destroyed, so are all textures. Reset the texture in that case. --- include/wlr/types/wlr_scene.h | 1 + types/scene/wlr_scene.c | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/include/wlr/types/wlr_scene.h b/include/wlr/types/wlr_scene.h index 0d6d97a3..9ae3d943 100644 --- a/include/wlr/types/wlr_scene.h +++ b/include/wlr/types/wlr_scene.h @@ -191,6 +191,7 @@ struct wlr_scene_buffer { bool buffer_is_opaque; struct wl_listener buffer_release; + struct wl_listener renderer_destroy; }; /** A viewport for an output in the scene-graph */ diff --git a/types/scene/wlr_scene.c b/types/scene/wlr_scene.c index 722e0fd2..514c0e15 100644 --- a/types/scene/wlr_scene.c +++ b/types/scene/wlr_scene.c @@ -637,10 +637,24 @@ static void scene_buffer_set_buffer(struct wlr_scene_buffer *scene_buffer, wl_signal_add(&buffer->events.release, &scene_buffer->buffer_release); } +static void scene_buffer_handle_renderer_destroy(struct wl_listener *listener, + void *data) { + struct wlr_scene_buffer *scene_buffer = wl_container_of(listener, scene_buffer, renderer_destroy); + scene_buffer_set_texture(scene_buffer, NULL); +} + static void scene_buffer_set_texture(struct wlr_scene_buffer *scene_buffer, struct wlr_texture *texture) { + wl_list_remove(&scene_buffer->renderer_destroy.link); wlr_texture_destroy(scene_buffer->texture); scene_buffer->texture = texture; + + if (texture != NULL) { + scene_buffer->renderer_destroy.notify = scene_buffer_handle_renderer_destroy; + wl_signal_add(&texture->renderer->events.destroy, &scene_buffer->renderer_destroy); + } else { + wl_list_init(&scene_buffer->renderer_destroy.link); + } } struct wlr_scene_buffer *wlr_scene_buffer_create(struct wlr_scene_tree *parent, @@ -659,6 +673,7 @@ struct wlr_scene_buffer *wlr_scene_buffer_create(struct wlr_scene_tree *parent, wl_signal_init(&scene_buffer->events.frame_done); pixman_region32_init(&scene_buffer->opaque_region); wl_list_init(&scene_buffer->buffer_release.link); + wl_list_init(&scene_buffer->renderer_destroy.link); scene_buffer->opacity = 1; scene_buffer_set_buffer(scene_buffer, buffer);