aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDevin J. Pohly <djpohly@gmail.com>2021-08-13 15:18:29 -0500
committerSimon Ser <contact@emersion.fr>2021-09-02 19:05:02 +0200
commit526652a554e941f4c86f3be5affe953ded84dacd (patch)
tree49a5c24a715a6b62820c31bf58619c2de5017bfc
parentb0972a94c38dd7996b083e8d665e64645337fb73 (diff)
scene: iterate nodes instead of surfaces when rendering
This will allow us to create node types which are rendered but not surface-based, such as a solid color or image.
-rw-r--r--include/wlr/types/wlr_scene.h3
-rw-r--r--types/wlr_scene.c64
2 files changed, 49 insertions, 18 deletions
diff --git a/include/wlr/types/wlr_scene.h b/include/wlr/types/wlr_scene.h
index a489d6af..6e0aebf8 100644
--- a/include/wlr/types/wlr_scene.h
+++ b/include/wlr/types/wlr_scene.h
@@ -67,6 +67,9 @@ struct wlr_scene_surface {
struct wl_listener surface_destroy;
};
+typedef void (*wlr_scene_node_iterator_func_t)(struct wlr_scene_node *node,
+ int sx, int sy, void *data);
+
/**
* Immediately destroy the scene-graph node.
*/
diff --git a/types/wlr_scene.c b/types/wlr_scene.c
index ee9215d2..dfd221b2 100644
--- a/types/wlr_scene.c
+++ b/types/wlr_scene.c
@@ -270,32 +270,60 @@ struct render_data {
pixman_region32_t *damage;
};
-static void render_surface_iterator(struct wlr_surface *surface,
+static void render_node_iterator(struct wlr_scene_node *node,
int x, int y, void *_data) {
struct render_data *data = _data;
struct wlr_output *output = data->output;
pixman_region32_t *output_damage = data->damage;
- struct wlr_texture *texture = wlr_surface_get_texture(surface);
- if (texture == NULL) {
+ switch (node->type) {
+ case WLR_SCENE_NODE_ROOT:;
+ /* Root node has nothing to render itself */
+ break;
+ case WLR_SCENE_NODE_SURFACE:;
+ struct wlr_scene_surface *scene_surface = scene_surface_from_node(node);
+ struct wlr_surface *surface = scene_surface->surface;
+
+ struct wlr_texture *texture = wlr_surface_get_texture(surface);
+ if (texture == NULL) {
+ return;
+ }
+
+ struct wlr_box box = {
+ .x = x,
+ .y = y,
+ .width = surface->current.width,
+ .height = surface->current.height,
+ };
+ scale_box(&box, output->scale);
+
+ float matrix[9];
+ enum wl_output_transform transform =
+ wlr_output_transform_invert(surface->current.transform);
+ wlr_matrix_project_box(matrix, &box, transform, 0.0,
+ output->transform_matrix);
+
+ render_texture(output, output_damage, texture, &box, matrix);
+ break;
+ }
+}
+
+static void scene_node_for_each_node(struct wlr_scene_node *node,
+ int lx, int ly, wlr_scene_node_iterator_func_t user_iterator,
+ void *user_data) {
+ if (!node->state.enabled) {
return;
}
- struct wlr_box box = {
- .x = x,
- .y = y,
- .width = surface->current.width,
- .height = surface->current.height,
- };
- scale_box(&box, output->scale);
+ lx += node->state.x;
+ ly += node->state.y;
- float matrix[9];
- enum wl_output_transform transform =
- wlr_output_transform_invert(surface->current.transform);
- wlr_matrix_project_box(matrix, &box, transform, 0.0,
- output->transform_matrix);
+ user_iterator(node, lx, ly, user_data);
- render_texture(output, output_damage, texture, &box, matrix);
+ struct wlr_scene_node *child;
+ wl_list_for_each(child, &node->state.children, state.link) {
+ scene_node_for_each_node(child, lx, ly, user_iterator, user_data);
+ }
}
void wlr_scene_render_output(struct wlr_scene *scene, struct wlr_output *output,
@@ -315,8 +343,8 @@ void wlr_scene_render_output(struct wlr_scene *scene, struct wlr_output *output,
.output = output,
.damage = damage,
};
- scene_node_for_each_surface(&scene->node, lx, ly,
- render_surface_iterator, &data);
+ scene_node_for_each_node(&scene->node, lx, ly,
+ render_node_iterator, &data);
wlr_renderer_scissor(renderer, NULL);
}