compositor: add wlr_compositor_set_renderer()

Allows compositors to switch the wlr_renderer at runtime.

Useful for handling GPU resets.
This commit is contained in:
Simon Ser 2024-03-14 14:34:44 +01:00
parent 3075e6a6f9
commit 0e5034d8ba
2 changed files with 24 additions and 6 deletions

View file

@ -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, struct wlr_compositor *wlr_compositor_create(struct wl_display *display,
uint32_t version, struct wlr_renderer *renderer); 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 #endif

View file

@ -1342,9 +1342,7 @@ static void compositor_handle_renderer_destroy(
struct wl_listener *listener, void *data) { struct wl_listener *listener, void *data) {
struct wlr_compositor *compositor = struct wlr_compositor *compositor =
wl_container_of(listener, compositor, renderer_destroy); wl_container_of(listener, compositor, renderer_destroy);
compositor->renderer = NULL; wlr_compositor_set_renderer(compositor, NULL);
wl_list_remove(&compositor->renderer_destroy.link);
wl_list_init(&compositor->renderer_destroy.link);
} }
struct wlr_compositor *wlr_compositor_create(struct wl_display *display, 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); free(compositor);
return NULL; return NULL;
} }
compositor->renderer = renderer;
wl_signal_init(&compositor->events.new_surface); wl_signal_init(&compositor->events.new_surface);
wl_signal_init(&compositor->events.destroy); wl_signal_init(&compositor->events.destroy);
wl_list_init(&compositor->renderer_destroy.link);
compositor->display_destroy.notify = compositor_handle_display_destroy; compositor->display_destroy.notify = compositor_handle_display_destroy;
wl_display_add_destroy_listener(display, &compositor->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) { if (renderer != NULL) {
compositor->renderer_destroy.notify = compositor_handle_renderer_destroy; compositor->renderer_destroy.notify = compositor_handle_renderer_destroy;
wl_signal_add(&renderer->events.destroy, &compositor->renderer_destroy); wl_signal_add(&renderer->events.destroy, &compositor->renderer_destroy);
} else { } else {
wl_list_init(&compositor->renderer_destroy.link); wl_list_init(&compositor->renderer_destroy.link);
} }
return compositor;
} }
static bool surface_state_add_synced(struct wlr_surface_state *state, void *value) { static bool surface_state_add_synced(struct wlr_surface_state *state, void *value) {