From 9e71c88467fc41d6330bbd4b99f82f3df49ed4ac Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Thu, 7 Nov 2024 11:56:09 +0100 Subject: [PATCH] scene: unwrap wlr_client_buffer for direct scan-out Passing the wlr_client_buffer directly has a downsides because a fresh wlr_buffer pointer is passed each output commit instead of cycling through existing wlr_buffer objects: - The FDs are re-imported each time in the backend. - Any import failure is logged every output commit [1]. - The Wayland backend cannot handle import failures without roundtripping each output commit [2]. Instead, extract the source buffer from the wlr_client_buffer and pass that to the backend. [1]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4836 [2]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4841 --- types/scene/wlr_scene.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/types/scene/wlr_scene.c b/types/scene/wlr_scene.c index 766189485..370be2b3a 100644 --- a/types/scene/wlr_scene.c +++ b/types/scene/wlr_scene.c @@ -1872,7 +1872,13 @@ static bool scene_entry_try_direct_scanout(struct render_list_entry *entry, scene_node_get_size(node, &pending.buffer_dst_box.width, &pending.buffer_dst_box.height); transform_output_box(&pending.buffer_dst_box, data); - wlr_output_state_set_buffer(&pending, buffer->buffer); + struct wlr_buffer *wlr_buffer = buffer->buffer; + struct wlr_client_buffer *client_buffer = wlr_client_buffer_get(wlr_buffer); + if (client_buffer != NULL && client_buffer->source != NULL) { + wlr_buffer = client_buffer->source; + } + + wlr_output_state_set_buffer(&pending, wlr_buffer); if (buffer->wait_timeline != NULL) { wlr_output_state_set_wait_timeline(&pending, buffer->wait_timeline, buffer->wait_point); }