mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-01-16 15:50:42 +01:00
Merge branch 'scene-snapshot' into 'master'
scene: add wlr_scene_node_snapshot() See merge request wlroots/wlroots!4558
This commit is contained in:
commit
89ec249be1
2 changed files with 89 additions and 0 deletions
|
|
@ -348,6 +348,15 @@ void wlr_scene_node_for_each_buffer(struct wlr_scene_node *node,
|
|||
*/
|
||||
struct wlr_scene_node *wlr_scene_node_at(struct wlr_scene_node *node,
|
||||
double lx, double ly, double *nx, double *ny);
|
||||
/**
|
||||
* Create a new scene node which represents a snapshot of another node.
|
||||
*
|
||||
* The snapshot displays the same contents as the source node at the time of
|
||||
* its creation. The snapshot is completely independent from the source node:
|
||||
* when the source node is updated, the snapshot will stay as-is.
|
||||
*/
|
||||
struct wlr_scene_node *wlr_scene_node_snapshot(struct wlr_scene_node *node,
|
||||
struct wlr_scene_tree *parent);
|
||||
|
||||
/**
|
||||
* Create a new scene-graph.
|
||||
|
|
|
|||
|
|
@ -2670,3 +2670,83 @@ void wlr_scene_output_for_each_buffer(struct wlr_scene_output *scene_output,
|
|||
scene_output_for_each_scene_buffer(&box, &scene_output->scene->tree.node, 0, 0,
|
||||
iterator, user_data);
|
||||
}
|
||||
|
||||
static bool scene_node_snapshot(struct wlr_scene_node *node, int lx, int ly,
|
||||
struct wlr_scene_tree *snapshot_tree) {
|
||||
if (!node->enabled) {
|
||||
return true;
|
||||
}
|
||||
|
||||
lx += node->x;
|
||||
ly += node->y;
|
||||
|
||||
struct wlr_scene_node *snapshot_node = NULL;
|
||||
switch (node->type) {
|
||||
case WLR_SCENE_NODE_TREE:;
|
||||
struct wlr_scene_tree *scene_tree = wlr_scene_tree_from_node(node);
|
||||
|
||||
struct wlr_scene_node *child;
|
||||
wl_list_for_each(child, &scene_tree->children, link) {
|
||||
scene_node_snapshot(node, lx, ly, snapshot_tree);
|
||||
}
|
||||
break;
|
||||
case WLR_SCENE_NODE_RECT:;
|
||||
struct wlr_scene_rect *scene_rect = wlr_scene_rect_from_node(node);
|
||||
|
||||
struct wlr_scene_rect *snapshot_rect = wlr_scene_rect_create(snapshot_tree,
|
||||
scene_rect->width, scene_rect->height, scene_rect->color);
|
||||
if (snapshot_rect == NULL) {
|
||||
return false;
|
||||
}
|
||||
snapshot_node = &snapshot_rect->node;
|
||||
break;
|
||||
case WLR_SCENE_NODE_BUFFER:;
|
||||
struct wlr_scene_buffer *scene_buffer = wlr_scene_buffer_from_node(node);
|
||||
|
||||
struct wlr_scene_buffer *snapshot_buffer = wlr_scene_buffer_create(snapshot_tree, NULL);
|
||||
if (snapshot_buffer == NULL) {
|
||||
return false;
|
||||
}
|
||||
snapshot_node = &snapshot_buffer->node;
|
||||
|
||||
wlr_scene_buffer_set_dest_size(snapshot_buffer, scene_buffer->dst_width, scene_buffer->dst_height);
|
||||
wlr_scene_buffer_set_opaque_region(snapshot_buffer, &scene_buffer->opaque_region);
|
||||
wlr_scene_buffer_set_source_box(snapshot_buffer, &scene_buffer->src_box);
|
||||
wlr_scene_buffer_set_transform(snapshot_buffer, scene_buffer->transform);
|
||||
|
||||
struct wlr_scene_surface *scene_surface = wlr_scene_surface_try_from_buffer(scene_buffer);
|
||||
if (scene_surface != NULL && scene_surface->surface->buffer != NULL) {
|
||||
wlr_scene_buffer_set_buffer(snapshot_buffer, &scene_surface->surface->buffer->base);
|
||||
} else {
|
||||
wlr_scene_buffer_set_buffer(snapshot_buffer, scene_buffer->buffer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (snapshot_node != NULL) {
|
||||
wlr_scene_node_set_position(snapshot_node, lx, ly);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
struct wlr_scene_node *wlr_scene_node_snapshot(struct wlr_scene_node *node,
|
||||
struct wlr_scene_tree *parent) {
|
||||
struct wlr_scene_tree *snapshot = wlr_scene_tree_create(parent);
|
||||
if (snapshot == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Disable and enable the snapshot tree like so to atomically update
|
||||
// the scene-graph. This will prevent over-damaging or other weirdness.
|
||||
wlr_scene_node_set_enabled(&snapshot->node, false);
|
||||
|
||||
if (!scene_node_snapshot(node, 0, 0, snapshot)) {
|
||||
wlr_scene_node_destroy(&snapshot->node);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wlr_scene_node_set_enabled(&snapshot->node, true);
|
||||
|
||||
return &snapshot->node;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue