From 368dcfb9f6a26d6286ada74cf23b72e01fceb47e Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Sun, 4 Jan 2026 17:41:17 +0100 Subject: [PATCH] ext_image_capture_source_v1: wait for capture client before sending frame event We were sending an output frame event as soon as we were done rendering. As a result, the output would render in a busy loop when a client was using the capture output for frame pacing purposes. Instead, use the request_frame hook introduced in the previous commit to throttle output frame events. Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/4036 --- types/ext_image_capture_source_v1/scene.c | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/types/ext_image_capture_source_v1/scene.c b/types/ext_image_capture_source_v1/scene.c index 9f6104be9..ab0a86cac 100644 --- a/types/ext_image_capture_source_v1/scene.c +++ b/types/ext_image_capture_source_v1/scene.c @@ -19,7 +19,6 @@ struct scene_node_source { struct wlr_output output; struct wlr_scene_output *scene_output; - struct wl_event_source *idle_frame; size_t num_started; struct wl_listener node_destroy; @@ -131,6 +130,9 @@ static void source_stop(struct wlr_ext_image_capture_source_v1 *base) { static void source_request_frame(struct wlr_ext_image_capture_source_v1 *base, bool schedule_frame) { struct scene_node_source *source = wl_container_of(base, source, base); + if (source->output.frame_pending) { + wlr_output_send_frame(&source->output); + } if (schedule_frame) { wlr_output_update_needs_frame(&source->output); } @@ -170,12 +172,6 @@ static void source_update_buffer_constraints(struct scene_node_source *source, output->swapchain, output->renderer); } -static void source_handle_idle_frame(void *data) { - struct scene_node_source *source = data; - source->idle_frame = NULL; - wlr_output_send_frame(&source->output); -} - static bool output_test(struct wlr_output *output, const struct wlr_output_state *state) { struct scene_node_source *source = wl_container_of(output, source, output); @@ -211,11 +207,6 @@ static bool output_test(struct wlr_output *output, const struct wlr_output_state static bool output_commit(struct wlr_output *output, const struct wlr_output_state *state) { struct scene_node_source *source = wl_container_of(output, source, output); - if (source->idle_frame != NULL) { - wlr_log(WLR_DEBUG, "Failed to commit capture output: a frame is still pending"); - return false; - } - if ((state->committed & WLR_OUTPUT_STATE_ENABLED) && !state->enabled) { return true; } @@ -253,9 +244,6 @@ static bool output_commit(struct wlr_output *output, const struct wlr_output_sta pixman_region32_fini(&full_damage); - source->idle_frame = - wl_event_loop_add_idle(output->event_loop, source_handle_idle_frame, source); - return true; }