From 147c5c37e3fdf287818f3b1683f99d6d6a315798 Mon Sep 17 00:00:00 2001 From: Alexander Orzechowski Date: Wed, 14 Aug 2024 11:23:01 -0400 Subject: [PATCH] wlr_scene: Immediately apply pending output commit damage There were two problems with the old implementation: 1. wlr_scene_output_commit would bail early if a frame wasn't requested and there was no commit damage, however commit damage could never accumulate until rendering happens. The check was subtly wrong as a result. 2. Previously, we would fill the pending commit damage based on the current state of the damage ring. However, during direct scanout, the damage would accumulate which would mean we would submit damage from previous frames even if we didn't need to. --- types/scene/wlr_scene.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/types/scene/wlr_scene.c b/types/scene/wlr_scene.c index 52fed109..140d1b14 100644 --- a/types/scene/wlr_scene.c +++ b/types/scene/wlr_scene.c @@ -332,6 +332,27 @@ static void scene_output_damage(struct wlr_scene_output *scene_output, const pixman_region32_t *region) { if (wlr_damage_ring_add(&scene_output->damage_ring, region)) { wlr_output_schedule_frame(scene_output->output); + + struct wlr_output *output = scene_output->output; + enum wl_output_transform transform = + wlr_output_transform_invert(scene_output->output->transform); + + int width = output->width; + int height = output->height; + if (transform & WL_OUTPUT_TRANSFORM_90) { + width = output->height; + height = output->width; + } + + pixman_region32_t frame_damage; + pixman_region32_init(&frame_damage); + wlr_region_transform(&frame_damage, region, transform, width, height); + + pixman_region32_union(&scene_output->pending_commit_damage, + &scene_output->pending_commit_damage, &frame_damage); + pixman_region32_intersect_rect(&scene_output->pending_commit_damage, + &scene_output->pending_commit_damage, 0, 0, output->width, output->height); + pixman_region32_fini(&frame_damage); } } @@ -1654,14 +1675,6 @@ static void output_state_apply_damage(const struct render_data *data, struct wlr_output_state *state) { struct wlr_scene_output *output = data->output; - pixman_region32_t frame_damage; - pixman_region32_init(&frame_damage); - pixman_region32_copy(&frame_damage, &output->damage_ring.current); - transform_output_damage(&frame_damage, data); - pixman_region32_union(&output->pending_commit_damage, - &output->pending_commit_damage, &frame_damage); - pixman_region32_fini(&frame_damage); - wlr_output_state_set_damage(state, &output->pending_commit_damage); }