wlr_scene: Refactor wlr_scene (the root element) to encase a wlr_scene_tree

Co-authored-by: Isaac Freund <mail@isaacfreund.com>
This commit is contained in:
Alexander Orzechowski 2022-05-30 19:26:08 -04:00 committed by Isaac Freund
parent 2563b79dc2
commit 9eb71146ae
5 changed files with 55 additions and 55 deletions

View File

@ -122,12 +122,12 @@ static void server_handle_new_surface(struct wl_listener *listener,
wl_signal_add(&wlr_surface->events.destroy, &surface->destroy); wl_signal_add(&wlr_surface->events.destroy, &surface->destroy);
/* Border dimensions will be set in surface.commit handler */ /* Border dimensions will be set in surface.commit handler */
surface->border = wlr_scene_rect_create(&server->scene->node, surface->border = wlr_scene_rect_create(&server->scene->tree.node,
0, 0, (float[4]){ 0.5f, 0.5f, 0.5f, 1 }); 0, 0, (float[4]){ 0.5f, 0.5f, 0.5f, 1 });
wlr_scene_node_set_position(&surface->border->node, pos, pos); wlr_scene_node_set_position(&surface->border->node, pos, pos);
surface->scene_surface = surface->scene_surface =
wlr_scene_surface_create(&server->scene->node, wlr_surface); wlr_scene_surface_create(&server->scene->tree.node, wlr_surface);
wlr_scene_node_set_position(&surface->scene_surface->buffer->node, wlr_scene_node_set_position(&surface->scene_surface->buffer->node,
pos + border_width, pos + border_width); pos + border_width, pos + border_width);

View File

@ -41,7 +41,6 @@ typedef void (*wlr_scene_buffer_iterator_func_t)(
struct wlr_scene_buffer *buffer, int sx, int sy, void *user_data); struct wlr_scene_buffer *buffer, int sx, int sy, void *user_data);
enum wlr_scene_node_type { enum wlr_scene_node_type {
WLR_SCENE_NODE_ROOT,
WLR_SCENE_NODE_TREE, WLR_SCENE_NODE_TREE,
WLR_SCENE_NODE_RECT, WLR_SCENE_NODE_RECT,
WLR_SCENE_NODE_BUFFER, WLR_SCENE_NODE_BUFFER,
@ -77,9 +76,14 @@ enum wlr_scene_debug_damage_option {
WLR_SCENE_DEBUG_DAMAGE_HIGHLIGHT WLR_SCENE_DEBUG_DAMAGE_HIGHLIGHT
}; };
/** A sub-tree in the scene-graph. */
struct wlr_scene_tree {
struct wlr_scene_node node;
};
/** The root scene-graph node. */ /** The root scene-graph node. */
struct wlr_scene { struct wlr_scene {
struct wlr_scene_node node; struct wlr_scene_tree tree;
struct wl_list outputs; // wlr_scene_output.link struct wl_list outputs; // wlr_scene_output.link
@ -94,11 +98,6 @@ struct wlr_scene {
struct wl_list damage_highlight_regions; struct wl_list damage_highlight_regions;
}; };
/** A sub-tree in the scene-graph. */
struct wlr_scene_tree {
struct wlr_scene_node node;
};
/** A scene-graph node displaying a single surface. */ /** A scene-graph node displaying a single surface. */
struct wlr_scene_surface { struct wlr_scene_surface {
struct wlr_scene_buffer *buffer; struct wlr_scene_buffer *buffer;

View File

@ -340,7 +340,7 @@ static struct tinywl_view *desktop_view_at(
* we only care about surface nodes as we are specifically looking for a * we only care about surface nodes as we are specifically looking for a
* surface in the surface tree of a tinywl_view. */ * surface in the surface tree of a tinywl_view. */
struct wlr_scene_node *node = wlr_scene_node_at( struct wlr_scene_node *node = wlr_scene_node_at(
&server->scene->node, lx, ly, sx, sy); &server->scene->tree.node, lx, ly, sx, sy);
if (node == NULL || node->type != WLR_SCENE_NODE_BUFFER) { if (node == NULL || node->type != WLR_SCENE_NODE_BUFFER) {
return NULL; return NULL;
} }
@ -760,7 +760,7 @@ static void server_new_xdg_surface(struct wl_listener *listener, void *data) {
view->server = server; view->server = server;
view->xdg_toplevel = xdg_surface->toplevel; view->xdg_toplevel = xdg_surface->toplevel;
view->scene_node = wlr_scene_xdg_surface_create( view->scene_node = wlr_scene_xdg_surface_create(
&view->server->scene->node, view->xdg_toplevel->base); &view->server->scene->tree.node, view->xdg_toplevel->base);
view->scene_node->data = view; view->scene_node->data = view;
xdg_surface->data = view->scene_node; xdg_surface->data = view->scene_node;

View File

@ -99,7 +99,7 @@ bool wlr_scene_attach_output_layout(struct wlr_scene *scene,
wl_signal_add(&output_layout->events.add, &sol->layout_add); wl_signal_add(&output_layout->events.add, &sol->layout_add);
sol->scene_destroy.notify = scene_output_layout_handle_scene_destroy; sol->scene_destroy.notify = scene_output_layout_handle_scene_destroy;
wl_signal_add(&scene->node.events.destroy, &sol->scene_destroy); wl_signal_add(&scene->tree.node.events.destroy, &sol->scene_destroy);
return true; return true;
} }

View File

@ -17,11 +17,6 @@
#define HIGHLIGHT_DAMAGE_FADEOUT_TIME 250 #define HIGHLIGHT_DAMAGE_FADEOUT_TIME 250
static struct wlr_scene *scene_root_from_node(struct wlr_scene_node *node) {
assert(node->type == WLR_SCENE_NODE_ROOT);
return (struct wlr_scene *)node;
}
static struct wlr_scene_rect *scene_rect_from_node( static struct wlr_scene_rect *scene_rect_from_node(
struct wlr_scene_node *node) { struct wlr_scene_node *node) {
assert(node->type == WLR_SCENE_NODE_RECT); assert(node->type == WLR_SCENE_NODE_RECT);
@ -38,7 +33,7 @@ struct wlr_scene *scene_node_get_root(struct wlr_scene_node *node) {
while (node->parent != NULL) { while (node->parent != NULL) {
node = node->parent; node = node->parent;
} }
return scene_root_from_node(node); return (struct wlr_scene *)node;
} }
static void scene_node_state_init(struct wlr_scene_node_state *state) { static void scene_node_state_init(struct wlr_scene_node_state *state) {
@ -54,8 +49,6 @@ static void scene_node_state_finish(struct wlr_scene_node_state *state) {
static void scene_node_init(struct wlr_scene_node *node, static void scene_node_init(struct wlr_scene_node *node,
enum wlr_scene_node_type type, struct wlr_scene_node *parent) { enum wlr_scene_node_type type, struct wlr_scene_node *parent) {
assert(type == WLR_SCENE_NODE_ROOT || parent != NULL);
memset(node, 0, sizeof(*node)); memset(node, 0, sizeof(*node));
node->type = type; node->type = type;
node->parent = parent; node->parent = parent;
@ -96,26 +89,12 @@ void wlr_scene_node_destroy(struct wlr_scene_node *node) {
wlr_signal_emit_safe(&node->events.destroy, NULL); wlr_signal_emit_safe(&node->events.destroy, NULL);
struct wlr_scene *scene = scene_node_get_root(node); struct wlr_scene *scene = scene_node_get_root(node);
struct wlr_scene_output *scene_output; if (node->type == WLR_SCENE_NODE_BUFFER) {
switch (node->type) {
case WLR_SCENE_NODE_ROOT:;
struct wlr_scene_output *scene_output_tmp;
wl_list_for_each_safe(scene_output, scene_output_tmp, &scene->outputs, link) {
wlr_scene_output_destroy(scene_output);
}
struct highlight_region *damage, *tmp_damage;
wl_list_for_each_safe(damage, tmp_damage, &scene->damage_highlight_regions, link) {
highlight_region_destroy(damage);
}
wl_list_remove(&scene->presentation_destroy.link);
break;
case WLR_SCENE_NODE_BUFFER:;
struct wlr_scene_buffer *scene_buffer = wlr_scene_buffer_from_node(node); struct wlr_scene_buffer *scene_buffer = wlr_scene_buffer_from_node(node);
uint64_t active = scene_buffer->active_outputs; uint64_t active = scene_buffer->active_outputs;
if (active) { if (active) {
struct wlr_scene_output *scene_output;
wl_list_for_each(scene_output, &scene->outputs, link) { wl_list_for_each(scene_output, &scene->outputs, link) {
if (active & (1ull << scene_output->index)) { if (active & (1ull << scene_output->index)) {
wlr_signal_emit_safe(&scene_buffer->events.output_leave, wlr_signal_emit_safe(&scene_buffer->events.output_leave,
@ -126,10 +105,23 @@ void wlr_scene_node_destroy(struct wlr_scene_node *node) {
wlr_texture_destroy(scene_buffer->texture); wlr_texture_destroy(scene_buffer->texture);
wlr_buffer_unlock(scene_buffer->buffer); wlr_buffer_unlock(scene_buffer->buffer);
break; } else if (node->type == WLR_SCENE_NODE_TREE) {
case WLR_SCENE_NODE_TREE: if (node == &scene->tree.node) {
case WLR_SCENE_NODE_RECT: assert(!node->parent);
break; struct wlr_scene_output *scene_output, *scene_output_tmp;
wl_list_for_each_safe(scene_output, scene_output_tmp, &scene->outputs, link) {
wlr_scene_output_destroy(scene_output);
}
struct highlight_region *damage, *tmp_damage;
wl_list_for_each_safe(damage, tmp_damage, &scene->damage_highlight_regions, link) {
highlight_region_destroy(damage);
}
wl_list_remove(&scene->presentation_destroy.link);
} else {
assert(node->parent);
}
} }
struct wlr_scene_node *child, *child_tmp; struct wlr_scene_node *child, *child_tmp;
@ -143,12 +135,20 @@ void wlr_scene_node_destroy(struct wlr_scene_node *node) {
free(node); free(node);
} }
static void scene_tree_init(struct wlr_scene_tree *tree,
struct wlr_scene_node *parent) {
memset(tree, 0, sizeof(*tree));
scene_node_init(&tree->node, WLR_SCENE_NODE_TREE, parent);
}
struct wlr_scene *wlr_scene_create(void) { struct wlr_scene *wlr_scene_create(void) {
struct wlr_scene *scene = calloc(1, sizeof(struct wlr_scene)); struct wlr_scene *scene = calloc(1, sizeof(struct wlr_scene));
if (scene == NULL) { if (scene == NULL) {
return NULL; return NULL;
} }
scene_node_init(&scene->node, WLR_SCENE_NODE_ROOT, NULL);
scene_tree_init(&scene->tree, NULL);
wl_list_init(&scene->outputs); wl_list_init(&scene->outputs);
wl_list_init(&scene->presentation_destroy.link); wl_list_init(&scene->presentation_destroy.link);
wl_list_init(&scene->damage_highlight_regions); wl_list_init(&scene->damage_highlight_regions);
@ -173,12 +173,14 @@ struct wlr_scene *wlr_scene_create(void) {
} }
struct wlr_scene_tree *wlr_scene_tree_create(struct wlr_scene_node *parent) { struct wlr_scene_tree *wlr_scene_tree_create(struct wlr_scene_node *parent) {
assert(parent);
struct wlr_scene_tree *tree = calloc(1, sizeof(struct wlr_scene_tree)); struct wlr_scene_tree *tree = calloc(1, sizeof(struct wlr_scene_tree));
if (tree == NULL) { if (tree == NULL) {
return NULL; return NULL;
} }
scene_node_init(&tree->node, WLR_SCENE_NODE_TREE, parent);
scene_tree_init(tree, parent);
return tree; return tree;
} }
@ -256,6 +258,7 @@ struct wlr_scene_rect *wlr_scene_rect_create(struct wlr_scene_node *parent,
if (scene_rect == NULL) { if (scene_rect == NULL) {
return NULL; return NULL;
} }
assert(parent);
scene_node_init(&scene_rect->node, WLR_SCENE_NODE_RECT, parent); scene_node_init(&scene_rect->node, WLR_SCENE_NODE_RECT, parent);
scene_rect->width = width; scene_rect->width = width;
@ -293,6 +296,7 @@ struct wlr_scene_buffer *wlr_scene_buffer_create(struct wlr_scene_node *parent,
if (scene_buffer == NULL) { if (scene_buffer == NULL) {
return NULL; return NULL;
} }
assert(parent);
scene_node_init(&scene_buffer->node, WLR_SCENE_NODE_BUFFER, parent); scene_node_init(&scene_buffer->node, WLR_SCENE_NODE_BUFFER, parent);
if (buffer) { if (buffer) {
@ -473,7 +477,6 @@ static void scene_node_get_size(struct wlr_scene_node *node,
*height = 0; *height = 0;
switch (node->type) { switch (node->type) {
case WLR_SCENE_NODE_ROOT:
case WLR_SCENE_NODE_TREE: case WLR_SCENE_NODE_TREE:
return; return;
case WLR_SCENE_NODE_RECT:; case WLR_SCENE_NODE_RECT:;
@ -630,7 +633,7 @@ void wlr_scene_node_lower_to_bottom(struct wlr_scene_node *node) {
void wlr_scene_node_reparent(struct wlr_scene_node *node, void wlr_scene_node_reparent(struct wlr_scene_node *node,
struct wlr_scene_node *new_parent) { struct wlr_scene_node *new_parent) {
assert(node->type != WLR_SCENE_NODE_ROOT && new_parent != NULL); assert(new_parent != NULL);
if (node->parent == new_parent) { if (node->parent == new_parent) {
return; return;
@ -716,7 +719,6 @@ struct wlr_scene_node *wlr_scene_node_at(struct wlr_scene_node *node,
bool intersects = false; bool intersects = false;
switch (node->type) { switch (node->type) {
case WLR_SCENE_NODE_ROOT:
case WLR_SCENE_NODE_TREE: case WLR_SCENE_NODE_TREE:
break; break;
case WLR_SCENE_NODE_RECT:; case WLR_SCENE_NODE_RECT:;
@ -845,7 +847,6 @@ static void render_node_iterator(struct wlr_scene_node *node,
float matrix[9]; float matrix[9];
enum wl_output_transform transform; enum wl_output_transform transform;
switch (node->type) { switch (node->type) {
case WLR_SCENE_NODE_ROOT:
case WLR_SCENE_NODE_TREE: case WLR_SCENE_NODE_TREE:
/* Root or tree node has nothing to render itself */ /* Root or tree node has nothing to render itself */
break; break;
@ -933,14 +934,14 @@ static void scene_output_handle_commit(struct wl_listener *listener, void *data)
if (event->committed & (WLR_OUTPUT_STATE_MODE | if (event->committed & (WLR_OUTPUT_STATE_MODE |
WLR_OUTPUT_STATE_TRANSFORM | WLR_OUTPUT_STATE_TRANSFORM |
WLR_OUTPUT_STATE_SCALE)) { WLR_OUTPUT_STATE_SCALE)) {
scene_node_update_outputs(&scene_output->scene->node); scene_node_update_outputs(&scene_output->scene->tree.node);
} }
} }
static void scene_output_handle_mode(struct wl_listener *listener, void *data) { static void scene_output_handle_mode(struct wl_listener *listener, void *data) {
struct wlr_scene_output *scene_output = wl_container_of(listener, struct wlr_scene_output *scene_output = wl_container_of(listener,
scene_output, output_mode); scene_output, output_mode);
scene_node_update_outputs(&scene_output->scene->node); scene_node_update_outputs(&scene_output->scene->tree.node);
} }
struct wlr_scene_output *wlr_scene_output_create(struct wlr_scene *scene, struct wlr_scene_output *wlr_scene_output_create(struct wlr_scene *scene,
@ -984,7 +985,7 @@ struct wlr_scene_output *wlr_scene_output_create(struct wlr_scene *scene,
wl_signal_add(&output->events.mode, &scene_output->output_mode); wl_signal_add(&output->events.mode, &scene_output->output_mode);
wlr_output_damage_add_whole(scene_output->damage); wlr_output_damage_add_whole(scene_output->damage);
scene_node_update_outputs(&scene->node); scene_node_update_outputs(&scene->tree.node);
return scene_output; return scene_output;
} }
@ -1012,7 +1013,7 @@ void wlr_scene_output_destroy(struct wlr_scene_output *scene_output) {
return; return;
} }
scene_node_remove_output(&scene_output->scene->node, scene_output); scene_node_remove_output(&scene_output->scene->tree.node, scene_output);
wlr_addon_finish(&scene_output->addon); wlr_addon_finish(&scene_output->addon);
wl_list_remove(&scene_output->link); wl_list_remove(&scene_output->link);
@ -1044,7 +1045,7 @@ void wlr_scene_output_set_position(struct wlr_scene_output *scene_output,
scene_output->y = ly; scene_output->y = ly;
wlr_output_damage_add_whole(scene_output->damage); wlr_output_damage_add_whole(scene_output->damage);
scene_node_update_outputs(&scene_output->scene->node); scene_node_update_outputs(&scene_output->scene->tree.node);
} }
struct check_scanout_data { struct check_scanout_data {
@ -1094,7 +1095,7 @@ static bool scene_output_scanout(struct wlr_scene_output *scene_output) {
struct check_scanout_data check_scanout_data = { struct check_scanout_data check_scanout_data = {
.viewport_box = viewport_box, .viewport_box = viewport_box,
}; };
scene_node_for_each_node(&scene_output->scene->node, 0, 0, scene_node_for_each_node(&scene_output->scene->tree.node, 0, 0,
check_scanout_iterator, &check_scanout_data); check_scanout_iterator, &check_scanout_data);
if (check_scanout_data.n != 1 || check_scanout_data.node == NULL) { if (check_scanout_data.n != 1 || check_scanout_data.node == NULL) {
return false; return false;
@ -1222,7 +1223,7 @@ bool wlr_scene_output_commit(struct wlr_scene_output *scene_output) {
.scene_output = scene_output, .scene_output = scene_output,
.damage = &damage, .damage = &damage,
}; };
scene_node_for_each_node(&scene_output->scene->node, scene_node_for_each_node(&scene_output->scene->tree.node,
-scene_output->x, -scene_output->y, -scene_output->x, -scene_output->y,
render_node_iterator, &data); render_node_iterator, &data);
wlr_renderer_scissor(renderer, NULL); wlr_renderer_scissor(renderer, NULL);
@ -1302,7 +1303,7 @@ static void scene_node_send_frame_done(struct wlr_scene_node *node,
void wlr_scene_output_send_frame_done(struct wlr_scene_output *scene_output, void wlr_scene_output_send_frame_done(struct wlr_scene_output *scene_output,
struct timespec *now) { struct timespec *now) {
scene_node_send_frame_done(&scene_output->scene->node, scene_node_send_frame_done(&scene_output->scene->tree.node,
scene_output, now); scene_output, now);
} }
@ -1340,6 +1341,6 @@ void wlr_scene_output_for_each_buffer(struct wlr_scene_output *scene_output,
struct wlr_box box = { .x = scene_output->x, .y = scene_output->y }; struct wlr_box box = { .x = scene_output->x, .y = scene_output->y };
wlr_output_effective_resolution(scene_output->output, wlr_output_effective_resolution(scene_output->output,
&box.width, &box.height); &box.width, &box.height);
scene_output_for_each_scene_buffer(&box, &scene_output->scene->node, 0, 0, scene_output_for_each_scene_buffer(&box, &scene_output->scene->tree.node, 0, 0,
iterator, user_data); iterator, user_data);
} }