From a32180afa784c2d98e6be5377f9e86aee83d25d1 Mon Sep 17 00:00:00 2001 From: Alexander Orzechowski Date: Sat, 22 Jul 2023 19:07:21 -0400 Subject: [PATCH] wlr_scene: Fix damage tracking with non atomic opaque region configuration We need to intersect the opaque region with the node size or else we'll get damage tracking effects with compositors attempting to use wlr_scene_buffer_set_opaque_region() along with resizing the buffer at the same time in a certain order. Consider this: I have a new buffer that I want to commit to my scene buffer that is smaller than the old one. However, I still have the old opaque region that is the size of the old larger buffer, so that means that for the small moment between when we reconfigure the opaque region for the new buffer the opaque region will be oversized. Scene logic will then try to apply occluding optimizations outside of the node boundaries causing damage artifacts. --- types/scene/wlr_scene.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/types/scene/wlr_scene.c b/types/scene/wlr_scene.c index d840e2de..a25cdd64 100644 --- a/types/scene/wlr_scene.c +++ b/types/scene/wlr_scene.c @@ -232,6 +232,9 @@ static bool scene_nodes_in_box(struct wlr_scene_node *node, struct wlr_box *box, static void scene_node_opaque_region(struct wlr_scene_node *node, int x, int y, pixman_region32_t *opaque) { + int width, height; + scene_node_get_size(node, &width, &height); + if (node->type == WLR_SCENE_NODE_RECT) { struct wlr_scene_rect *scene_rect = wlr_scene_rect_from_node(node); if (scene_rect->color[3] != 1) { @@ -250,13 +253,12 @@ static void scene_node_opaque_region(struct wlr_scene_node *node, int x, int y, if (!buffer_is_opaque(scene_buffer->buffer)) { pixman_region32_copy(opaque, &scene_buffer->opaque_region); + pixman_region32_intersect_rect(opaque, opaque, 0, 0, width, height); pixman_region32_translate(opaque, x, y); return; } } - int width, height; - scene_node_get_size(node, &width, &height); pixman_region32_fini(opaque); pixman_region32_init_rect(opaque, x, y, width, height); }