mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-11-22 12:55:58 +01:00
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.
This commit is contained in:
parent
63f5851b6f
commit
a32180afa7
1 changed files with 4 additions and 2 deletions
|
@ -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,
|
static void scene_node_opaque_region(struct wlr_scene_node *node, int x, int y,
|
||||||
pixman_region32_t *opaque) {
|
pixman_region32_t *opaque) {
|
||||||
|
int width, height;
|
||||||
|
scene_node_get_size(node, &width, &height);
|
||||||
|
|
||||||
if (node->type == WLR_SCENE_NODE_RECT) {
|
if (node->type == WLR_SCENE_NODE_RECT) {
|
||||||
struct wlr_scene_rect *scene_rect = wlr_scene_rect_from_node(node);
|
struct wlr_scene_rect *scene_rect = wlr_scene_rect_from_node(node);
|
||||||
if (scene_rect->color[3] != 1) {
|
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)) {
|
if (!buffer_is_opaque(scene_buffer->buffer)) {
|
||||||
pixman_region32_copy(opaque, &scene_buffer->opaque_region);
|
pixman_region32_copy(opaque, &scene_buffer->opaque_region);
|
||||||
|
pixman_region32_intersect_rect(opaque, opaque, 0, 0, width, height);
|
||||||
pixman_region32_translate(opaque, x, y);
|
pixman_region32_translate(opaque, x, y);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int width, height;
|
|
||||||
scene_node_get_size(node, &width, &height);
|
|
||||||
pixman_region32_fini(opaque);
|
pixman_region32_fini(opaque);
|
||||||
pixman_region32_init_rect(opaque, x, y, width, height);
|
pixman_region32_init_rect(opaque, x, y, width, height);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue