From 0e5034d8ba4aa5e21838e39cce0c389a249a11b7 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Thu, 14 Mar 2024 14:34:44 +0100 Subject: [PATCH] compositor: add wlr_compositor_set_renderer() Allows compositors to switch the wlr_renderer at runtime. Useful for handling GPU resets. --- include/wlr/types/wlr_compositor.h | 12 ++++++++++++ types/wlr_compositor.c | 18 ++++++++++++------ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/include/wlr/types/wlr_compositor.h b/include/wlr/types/wlr_compositor.h index 3f57a6cb..19db8032 100644 --- a/include/wlr/types/wlr_compositor.h +++ b/include/wlr/types/wlr_compositor.h @@ -524,4 +524,16 @@ const pixman_region32_t *wlr_region_from_resource(struct wl_resource *resource); struct wlr_compositor *wlr_compositor_create(struct wl_display *display, uint32_t version, struct wlr_renderer *renderer); +/** + * Set the renderer used for creating struct wlr_texture objects from client + * buffers on surface commit. + * + * The renderer may be NULL, in which case no textures are created. + * + * Calling this function does not update existing textures, it only affects + * future surface commits. + */ +void wlr_compositor_set_renderer(struct wlr_compositor *compositor, + struct wlr_renderer *renderer); + #endif diff --git a/types/wlr_compositor.c b/types/wlr_compositor.c index 3fde1dad..c5044ce4 100644 --- a/types/wlr_compositor.c +++ b/types/wlr_compositor.c @@ -1342,9 +1342,7 @@ static void compositor_handle_renderer_destroy( struct wl_listener *listener, void *data) { struct wlr_compositor *compositor = wl_container_of(listener, compositor, renderer_destroy); - compositor->renderer = NULL; - wl_list_remove(&compositor->renderer_destroy.link); - wl_list_init(&compositor->renderer_destroy.link); + wlr_compositor_set_renderer(compositor, NULL); } struct wlr_compositor *wlr_compositor_create(struct wl_display *display, @@ -1362,22 +1360,30 @@ struct wlr_compositor *wlr_compositor_create(struct wl_display *display, free(compositor); return NULL; } - compositor->renderer = renderer; wl_signal_init(&compositor->events.new_surface); wl_signal_init(&compositor->events.destroy); + wl_list_init(&compositor->renderer_destroy.link); compositor->display_destroy.notify = compositor_handle_display_destroy; wl_display_add_destroy_listener(display, &compositor->display_destroy); + wlr_compositor_set_renderer(compositor, renderer); + + return compositor; +} + +void wlr_compositor_set_renderer(struct wlr_compositor *compositor, + struct wlr_renderer *renderer) { + wl_list_remove(&compositor->renderer_destroy.link); + compositor->renderer = renderer; + if (renderer != NULL) { compositor->renderer_destroy.notify = compositor_handle_renderer_destroy; wl_signal_add(&renderer->events.destroy, &compositor->renderer_destroy); } else { wl_list_init(&compositor->renderer_destroy.link); } - - return compositor; } static bool surface_state_add_synced(struct wlr_surface_state *state, void *value) {