From fc33db952bbb6e64929eed789d416265e52dd305 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20Poisot?= Date: Sat, 28 Mar 2026 10:34:33 +0000 Subject: [PATCH] ext_image_capture_source_v1/scene: allow direct scanout Accomodate the constraints of wlr_scene for direct scanout in the virtual output : - Cannot use it on a commit that sets the mode --- types/ext_image_capture_source_v1/scene.c | 25 +++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/types/ext_image_capture_source_v1/scene.c b/types/ext_image_capture_source_v1/scene.c index 7d4b8928a..e9a2da2e9 100644 --- a/types/ext_image_capture_source_v1/scene.c +++ b/types/ext_image_capture_source_v1/scene.c @@ -20,6 +20,7 @@ struct scene_node_source { struct wlr_scene_output *scene_output; size_t num_started; + bool resizing; struct wl_listener node_destroy; struct wl_listener scene_output_destroy; @@ -85,13 +86,25 @@ static void source_render(struct scene_node_source *source) { return; } + struct wlr_output_state state; + bool ok = true; + if (!source->output.enabled || source->output.current_mode == NULL + || source->output.current_mode->width != extents.width + || source->output.current_mode->height != extents.height) { + // Scene cannot attempt direct scanout on a commit that sets the mode + source->resizing = true; + wlr_output_state_init(&state); + wlr_output_state_set_enabled(&state, true); + wlr_output_state_set_custom_mode(&state, extents.width, extents.height, 0); + ok &= wlr_output_commit_state(scene_output->output, &state); + wlr_output_state_finish(&state); + source->resizing = false; + } + wlr_scene_output_set_position(scene_output, extents.x, extents.y); - struct wlr_output_state state; wlr_output_state_init(&state); - wlr_output_state_set_enabled(&state, true); - wlr_output_state_set_custom_mode(&state, extents.width, extents.height, 0); - bool ok = wlr_scene_output_build_state(scene_output, &state, NULL) && + ok &= wlr_scene_output_build_state(scene_output, &state, NULL) && wlr_output_commit_state(scene_output->output, &state); wlr_output_state_finish(&state); @@ -217,6 +230,10 @@ static bool output_commit(struct wlr_output *output, const struct wlr_output_sta source_update_buffer_constraints(source, state); } + if (source->resizing) { + return true; + } + if (!(state->committed & WLR_OUTPUT_STATE_BUFFER)) { wlr_log(WLR_DEBUG, "Failed to commit capture output: missing buffer"); return false;