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
This commit is contained in:
Consolatis 2024-08-14 20:17:50 +02:00 committed by Johan Malm
parent 00512d055f
commit 6a1ecd6b7d

View file

@ -4,6 +4,8 @@
#include <wlr/types/wlr_output.h>
#include <wlr/types/wlr_scene.h>
#include <wlr/util/log.h>
#include <wlr/util/region.h>
#include <wlr/util/transform.h>
#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(&region,
additional_damage.x, additional_damage.y,
additional_damage.width, additional_damage.height);
scene_output_damage(scene_output, &region);
pixman_region32_fini(&region);
}
return true;
}