diff --git a/include/wlr/types/wlr_scene.h b/include/wlr/types/wlr_scene.h index efdd6061..d6b89156 100644 --- a/include/wlr/types/wlr_scene.h +++ b/include/wlr/types/wlr_scene.h @@ -156,6 +156,7 @@ struct wlr_scene_buffer { struct wlr_fbox src_box; int dst_width, dst_height; enum wl_output_transform transform; + pixman_region32_t opaque_region; }; struct wlr_scene_output_render_list { @@ -346,6 +347,13 @@ void wlr_scene_buffer_set_buffer(struct wlr_scene_buffer *scene_buffer, void wlr_scene_buffer_set_buffer_with_damage(struct wlr_scene_buffer *scene_buffer, struct wlr_buffer *buffer, pixman_region32_t *region); +/** + * Sets the buffer's opaque region. This is an optimization hint used to + * determine if buffers which reside under this one need to be rendered or not. + */ +void wlr_scene_buffer_set_opaque_region(struct wlr_scene_buffer *scene_buffer, + pixman_region32_t *region); + /** * Set the source rectangle describing the region of the buffer which will be * sampled to render this node. This allows cropping the buffer. diff --git a/types/scene/wlr_scene.c b/types/scene/wlr_scene.c index e5605472..36a12a0b 100644 --- a/types/scene/wlr_scene.c +++ b/types/scene/wlr_scene.c @@ -103,6 +103,7 @@ void wlr_scene_node_destroy(struct wlr_scene_node *node) { wlr_texture_destroy(scene_buffer->texture); wlr_buffer_unlock(scene_buffer->buffer); + pixman_region32_fini(&scene_buffer->opaque_region); } else if (node->type == WLR_SCENE_NODE_TREE) { struct wlr_scene_tree *scene_tree = scene_tree_from_node(node); @@ -502,6 +503,7 @@ struct wlr_scene_buffer *wlr_scene_buffer_create(struct wlr_scene_tree *parent, wl_signal_init(&scene_buffer->events.output_leave); wl_signal_init(&scene_buffer->events.output_present); wl_signal_init(&scene_buffer->events.frame_done); + pixman_region32_init(&scene_buffer->opaque_region); scene_node_update(&scene_buffer->node, NULL); @@ -603,6 +605,16 @@ void wlr_scene_buffer_set_buffer(struct wlr_scene_buffer *scene_buffer, wlr_scene_buffer_set_buffer_with_damage(scene_buffer, buffer, NULL); } +void wlr_scene_buffer_set_opaque_region(struct wlr_scene_buffer *scene_buffer, + pixman_region32_t *region) { + if (pixman_region32_equal(&scene_buffer->opaque_region, region)) { + return; + } + + pixman_region32_copy(&scene_buffer->opaque_region, region); + scene_node_update(&scene_buffer->node, NULL); +} + void wlr_scene_buffer_set_source_box(struct wlr_scene_buffer *scene_buffer, const struct wlr_fbox *box) { struct wlr_fbox *cur = &scene_buffer->src_box;