diff options
author | Alexander Orzechowski <alex@ozal.ski> | 2023-07-22 19:07:21 -0400 |
---|---|---|
committer | Alexander Orzechowski <alex@ozal.ski> | 2023-07-22 19:23:36 -0400 |
commit | a32180afa784c2d98e6be5377f9e86aee83d25d1 (patch) | |
tree | cfbce6189423f392d633041bc988e290e4f69056 | |
parent | 63f5851b6fdc630355510c44e875119c4755208d (diff) |
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.
-rw-r--r-- | types/scene/wlr_scene.c | 6 |
1 files 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); } |