From 6a1ecd6b7dbb4ec5314d60b05aa12e86a5d04626 Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Wed, 14 Aug 2024 20:17:50 +0200 Subject: [PATCH] scene-helpers: use pending_commit_damage, chases wlr!4253 Using the output damage_ring for early out will break VRR in direct scanout mode. The reason being that the damage_ring will be completely ignored in that mode so we need to check `output->pending_commit_damage` instead. This matches with what wlroots has been doing since [0] and it was missed in the initial port to wlroots 0.18.x. However, that would then break the magnifier which only adds its damage to the damage ring. After some discussion with the wlroots devs we came up with a solution that should work for both, wlroots 0.18.0 and when [1] is backported to 0.18.1. Note that even with this PR, VRR in direct scanout mode is broken in 0.18.0 from the wlroots side and will be fixed once [1] is backported to the 0.18 branch and 0.18.1 is released. Fixes: #2078 [0] https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4253 [1] https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4753 --- src/common/scene-helpers.c | 49 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/src/common/scene-helpers.c b/src/common/scene-helpers.c index fb627719..2d12d570 100644 --- a/src/common/scene-helpers.c +++ b/src/common/scene-helpers.c @@ -4,6 +4,8 @@ #include #include #include +#include +#include #include "common/scene-helpers.h" #include "labwc.h" #include "magnifier.h" @@ -37,6 +39,43 @@ lab_wlr_scene_get_prev_node(struct wlr_scene_node *node) return prev; } +/* + * This is a slightly modified copy of scene_output_damage(), + * required to properly add the magnifier damage to scene_output + * ->damage_ring and scene_output->pending_commit_damage. + * + * The only difference is code style and removal of wlr_output_schedule_frame(). + */ +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)) { + return; + } + + 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); +} + /* * This is a copy of wlr_scene_output_commit() * as it doesn't use the pending state at all. @@ -58,7 +97,7 @@ lab_wlr_scene_output_commit(struct wlr_scene_output *scene_output, * We also need to verify the necessity of wants_magnification. */ if (!wlr_output->needs_frame && !pixman_region32_not_empty( - &scene_output->damage_ring.current) && !wants_magnification) { + &scene_output->pending_commit_damage) && !wants_magnification) { return true; } @@ -86,7 +125,13 @@ lab_wlr_scene_output_commit(struct wlr_scene_output *scene_output, } if (!wlr_box_empty(&additional_damage)) { - wlr_damage_ring_add_box(&scene_output->damage_ring, &additional_damage); + pixman_region32_t region; + pixman_region32_init_rect(®ion, + additional_damage.x, additional_damage.y, + additional_damage.width, additional_damage.height); + scene_output_damage(scene_output, ®ion); + pixman_region32_fini(®ion); } + return true; }