aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--types/scene/wlr_scene.c36
1 files changed, 25 insertions, 11 deletions
diff --git a/types/scene/wlr_scene.c b/types/scene/wlr_scene.c
index 9516971a..5e5f8003 100644
--- a/types/scene/wlr_scene.c
+++ b/types/scene/wlr_scene.c
@@ -221,8 +221,8 @@ static bool scene_nodes_in_box(struct wlr_scene_node *node, struct wlr_box *box,
return _scene_nodes_in_box(node, box, iterator, user_data, x, y);
}
-static void scene_node_cull_hidden(struct wlr_scene_node *node, int x, int y,
- pixman_region32_t *visible) {
+static void scene_node_opaque_region(struct wlr_scene_node *node, int x, int y,
+ pixman_region32_t *opaque) {
if (node->type == WLR_SCENE_NODE_RECT) {
struct wlr_scene_rect *scene_rect = scene_rect_from_node(node);
if (scene_rect->color[3] != 1) {
@@ -236,19 +236,16 @@ static void scene_node_cull_hidden(struct wlr_scene_node *node, int x, int y,
}
if (!buffer_is_opaque(scene_buffer->buffer)) {
- pixman_region32_translate(visible, -x, -y);
- pixman_region32_subtract(visible, visible, &scene_buffer->opaque_region);
- pixman_region32_translate(visible, x, y);
+ pixman_region32_copy(opaque, &scene_buffer->opaque_region);
+ pixman_region32_translate(opaque, x, y);
return;
}
}
int width, height;
scene_node_get_size(node, &width, &height);
- pixman_region32_t opaque;
- pixman_region32_init_rect(&opaque, x, y, width, height);
- pixman_region32_subtract(visible, visible, &opaque);
- pixman_region32_fini(&opaque);
+ pixman_region32_fini(opaque);
+ pixman_region32_init_rect(opaque, x, y, width, height);
}
struct scene_update_data {
@@ -370,7 +367,11 @@ static bool scene_node_update_iterator(struct wlr_scene_node *node,
lx, ly, box.width, box.height);
if (data->calculate_visibility) {
- scene_node_cull_hidden(node, lx, ly, data->visible);
+ pixman_region32_t opaque;
+ pixman_region32_init(&opaque);
+ scene_node_opaque_region(node, lx, ly, &opaque);
+ pixman_region32_subtract(data->visible, data->visible, &opaque);
+ pixman_region32_fini(&opaque);
}
update_node_update_outputs(node, data->outputs, NULL);
@@ -1507,7 +1508,20 @@ bool wlr_scene_output_commit(struct wlr_scene_output *scene_output) {
struct wlr_scene_node *node = list_data[i];
int x, y;
wlr_scene_node_coords(node, &x, &y);
- scene_node_cull_hidden(node, x, y, &background);
+
+ // We must only cull opaque regions that are visible by the node.
+ // The node's visibility will have the knowledge of a black rect
+ // that may have been omitted from the render list via the black
+ // rect optimization. In order to ensure we don't cull background
+ // rendering in that black rect region, consider the node's visibility.
+ pixman_region32_t opaque;
+ pixman_region32_init(&opaque);
+ scene_node_opaque_region(node, x, y, &opaque);
+ pixman_region32_intersect(&opaque, &opaque, &node->visible);
+
+ wlr_region_scale(&opaque, &opaque, scene_output->output->scale);
+ pixman_region32_subtract(&background, &background, &opaque);
+ pixman_region32_fini(&opaque);
}
}