diff --git a/docs/reference/gsk/gsk4-sections.txt b/docs/reference/gsk/gsk4-sections.txt index f2fc3c32b9..1fe5cdd3d6 100644 --- a/docs/reference/gsk/gsk4-sections.txt +++ b/docs/reference/gsk/gsk4-sections.txt @@ -28,12 +28,6 @@ gsk_render_node_ref gsk_render_node_unref GskRenderNodeType gsk_render_node_get_node_type -gsk_render_node_get_first_child -gsk_render_node_get_last_child -gsk_render_node_get_next_sibling -gsk_render_node_get_previous_sibling -gsk_render_node_append_child -gsk_render_node_get_n_children gsk_render_node_set_transform gsk_render_node_set_opacity GskBlendMode @@ -45,6 +39,9 @@ gsk_texture_node_new gsk_cairo_node_new gsk_cairo_node_get_draw_context gsk_container_node_new +gsk_container_node_append_child +gsk_container_node_get_n_children +gsk_container_node_get_child GSK_IS_RENDER_NODE GSK_RENDER_NODE diff --git a/gsk/gskcairorenderer.c b/gsk/gskcairorenderer.c index 185d976f46..7d4dcff496 100644 --- a/gsk/gskcairorenderer.c +++ b/gsk/gskcairorenderer.c @@ -51,7 +51,6 @@ gsk_cairo_renderer_render_node (GskCairoRenderer *self, GskRenderNode *node, cairo_t *cr) { - GskRenderNode *child; gboolean pop_group = FALSE; graphene_matrix_t mat; cairo_matrix_t ctm; @@ -103,18 +102,16 @@ gsk_cairo_renderer_render_node (GskCairoRenderer *self, break; case GSK_CONTAINER_NODE: - if (gsk_render_node_get_n_children (node) != 0) - { - GSK_NOTE (CAIRO, g_print ("Drawing %d children of node [%p]\n", - gsk_render_node_get_n_children (node), - node)); - for (child = gsk_render_node_get_first_child (node); - child != NULL; - child = gsk_render_node_get_next_sibling (child)) - { - gsk_cairo_renderer_render_node (self, child, cr); - } - } + { + guint i; + GSK_NOTE (CAIRO, g_print ("Drawing %d children of node [%p]\n", + gsk_container_node_get_n_children (node), + node)); + for (i = 0; i < gsk_container_node_get_n_children (node); i++) + { + gsk_cairo_renderer_render_node (self, gsk_container_node_get_child (node, i), cr); + } + } break; case GSK_TEXTURE_NODE: diff --git a/gsk/gskglrenderer.c b/gsk/gskglrenderer.c index eb0eacda18..36b158fee3 100644 --- a/gsk/gskglrenderer.c +++ b/gsk/gskglrenderer.c @@ -611,7 +611,6 @@ gsk_gl_renderer_add_render_item (GskGLRenderer *self, graphene_rect_t viewport; graphene_matrix_t mv, transform; graphene_rect_t bounds; - GskRenderNode *child; RenderItem item; RenderItem *ritem = NULL; int program_id; @@ -693,8 +692,7 @@ gsk_gl_renderer_add_render_item (GskGLRenderer *self, gsk_gl_driver_init_texture_empty (self->gl_driver, item.render_data.render_target_id); gsk_gl_driver_create_render_target (self->gl_driver, item.render_data.render_target_id, TRUE, TRUE); - item.children = g_array_sized_new (FALSE, FALSE, sizeof (RenderItem), - gsk_render_node_get_n_children (node)); + item.children = g_array_new (FALSE, FALSE, sizeof (RenderItem)); } else { @@ -738,10 +736,21 @@ gsk_gl_renderer_add_render_item (GskGLRenderer *self, } break; + case GSK_CONTAINER_NODE: + { + guint i; + + for (i = 0; i < gsk_container_node_get_n_children (node); i++) + { + GskRenderNode *child = gsk_container_node_get_child (node, i); + gsk_gl_renderer_add_render_item (self, projection, &mv, render_items, child, ritem); + } + } + return; + + case GSK_NOT_A_RENDER_NODE: default: - /* If the node does not draw anything, we skip it */ - if (item.render_data.render_target_id == 0) - goto out; + return; } /* Create the vertex buffers holding the geometry of the quad */ @@ -772,14 +781,6 @@ gsk_gl_renderer_add_render_item (GskGLRenderer *self, if (item.children != NULL) render_items = item.children; - -out: - for (child = gsk_render_node_get_first_child (node); - child != NULL; - child = gsk_render_node_get_next_sibling (child)) - { - gsk_gl_renderer_add_render_item (self, projection, &mv, render_items, child, ritem); - } } static gboolean diff --git a/gsk/gskrendernode.c b/gsk/gskrendernode.c index 41a9101026..641ab2f653 100644 --- a/gsk/gskrendernode.c +++ b/gsk/gskrendernode.c @@ -65,10 +65,6 @@ G_DEFINE_BOXED_TYPE (GskRenderNode, gsk_render_node, gsk_render_node_ref, gsk_render_node_unref) -static GskRenderNode * -gsk_render_node_remove_child (GskRenderNode *node, - GskRenderNode *child); - static void gsk_render_node_finalize (GskRenderNode *self) { @@ -78,9 +74,6 @@ gsk_render_node_finalize (GskRenderNode *self) g_clear_pointer (&self->name, g_free); - while (self->first_child) - gsk_render_node_remove_child (self, self->first_child); - g_slice_free1 (self->node_class->struct_size, self); } @@ -174,269 +167,6 @@ gsk_render_node_get_node_type (GskRenderNode *node) return node->node_class->node_type; } -/** - * gsk_render_node_get_first_child: - * @node: a #GskRenderNode - * - * Returns the first child of @node. - * - * Returns: (transfer none): the first child of the #GskRenderNode - * - * Since: 3.90 - */ -GskRenderNode * -gsk_render_node_get_first_child (GskRenderNode *node) -{ - g_return_val_if_fail (GSK_IS_RENDER_NODE (node), NULL); - - return node->first_child; -} - -/** - * gsk_render_node_get_last_child: - * @node: a #GskRenderNode - * - * Returns the last child of @node. - * - * Returns: (transfer none): the last child of the #GskRenderNode - * - * Since: 3.90 - */ -GskRenderNode * -gsk_render_node_get_last_child (GskRenderNode *node) -{ - g_return_val_if_fail (GSK_IS_RENDER_NODE (node), NULL); - - return node->last_child; -} - -/** - * gsk_render_node_get_next_sibling: - * @node: a #GskRenderNode - * - * Returns the next sibling of @node. - * - * Returns: (transfer none): the next sibling of the #GskRenderNode - * - * Since: 3.90 - */ -GskRenderNode * -gsk_render_node_get_next_sibling (GskRenderNode *node) -{ - g_return_val_if_fail (GSK_IS_RENDER_NODE (node), NULL); - - return node->next_sibling; -} - -/** - * gsk_render_node_get_previous_sibling: - * @node: a #GskRenderNode - * - * Returns the previous sibling of @node. - * - * Returns: (transfer none): the previous sibling of the #GskRenderNode - * - * Since: 3.90 - */ -GskRenderNode * -gsk_render_node_get_previous_sibling (GskRenderNode *node) -{ - g_return_val_if_fail (GSK_IS_RENDER_NODE (node), NULL); - - return node->prev_sibling; -} - -typedef void (* InsertChildFunc) (GskRenderNode *node, - GskRenderNode *child, - gpointer user_data); - -static void -gsk_render_node_insert_child_internal (GskRenderNode *node, - GskRenderNode *child, - InsertChildFunc insert_func, - gpointer insert_func_data) -{ - if (node == child) - { - g_critical ("The render node of type '%s' cannot be added to itself.", - G_OBJECT_TYPE_NAME (node)); - return; - } - - if (!node->is_mutable) - { - g_critical ("The render node of type '%s' is immutable.", - G_OBJECT_TYPE_NAME (node)); - return; - } - - insert_func (node, child, insert_func_data); - - gsk_render_node_ref (child); - - child->age = 0; - - node->n_children += 1; - node->age += 1; - - if (child->prev_sibling == NULL) - node->first_child = child; - if (child->next_sibling == NULL) - node->last_child = child; -} - -static void -insert_child_at_pos (GskRenderNode *node, - GskRenderNode *child, - gpointer user_data) -{ - int pos = GPOINTER_TO_INT (user_data); - - if (pos == 0) - { - GskRenderNode *tmp = node->first_child; - - if (tmp != NULL) - tmp->prev_sibling = child; - - child->prev_sibling = NULL; - child->next_sibling = tmp; - - return; - } - - if (pos < 0 || pos >= node->n_children) - { - GskRenderNode *tmp = node->last_child; - - if (tmp != NULL) - tmp->next_sibling = child; - - child->prev_sibling = tmp; - child->next_sibling = NULL; - - return; - } - - { - GskRenderNode *iter; - int i; - - for (iter = node->first_child, i = 0; - iter != NULL; - iter = iter->next_sibling, i++) - { - if (i == pos) - { - GskRenderNode *tmp = iter->prev_sibling; - - child->prev_sibling = tmp; - child->next_sibling = iter; - - iter->prev_sibling = child; - - if (tmp != NULL) - tmp->next_sibling = child; - - break; - } - } - } -} - -/** - * gsk_render_node_append_child: - * @node: a #GskRenderNode - * @child: a #GskRenderNode - * - * Appends @child to the list of children of @node. - * - * This function acquires a reference on @child. - * - * Returns: (transfer none): the #GskRenderNode - * - * Since: 3.90 - */ -GskRenderNode * -gsk_render_node_append_child (GskRenderNode *node, - GskRenderNode *child) -{ - g_return_val_if_fail (GSK_IS_RENDER_NODE_TYPE (node, GSK_CONTAINER_NODE), NULL); - g_return_val_if_fail (GSK_IS_RENDER_NODE (child), node); - g_return_val_if_fail (node->is_mutable, node); - - gsk_render_node_insert_child_internal (node, child, - insert_child_at_pos, - GINT_TO_POINTER (node->n_children)); - - return node; -} - -/** - * gsk_render_node_remove_child: - * @node: a #GskRenderNode - * @child: a #GskRenderNode child of @node - * - * Removes @child from the list of children of @node. - * - * This function releases the reference acquired when adding @child to the - * list of children. - * - * Returns: (transfer none): the #GskRenderNode - */ -static GskRenderNode * -gsk_render_node_remove_child (GskRenderNode *node, - GskRenderNode *child) -{ - GskRenderNode *prev_sibling, *next_sibling; - - g_return_val_if_fail (GSK_IS_RENDER_NODE (node), NULL); - g_return_val_if_fail (GSK_IS_RENDER_NODE (child), node); - g_return_val_if_fail (node->is_mutable, node); - - prev_sibling = child->prev_sibling; - next_sibling = child->next_sibling; - - child->prev_sibling = NULL; - child->next_sibling = NULL; - child->age = 0; - - if (prev_sibling) - prev_sibling->next_sibling = next_sibling; - if (next_sibling) - next_sibling->prev_sibling = prev_sibling; - - node->age += 1; - node->n_children -= 1; - - if (node->first_child == child) - node->first_child = next_sibling; - if (node->last_child == child) - node->last_child = prev_sibling; - - gsk_render_node_unref (child); - - return node; -} - -/** - * gsk_render_node_get_n_children: - * @node: a #GskRenderNode - * - * Retrieves the number of direct children of @node. - * - * Returns: the number of children of the #GskRenderNode - * - * Since: 3.90 - */ -guint -gsk_render_node_get_n_children (GskRenderNode *node) -{ - g_return_val_if_fail (GSK_IS_RENDER_NODE (node), 0); - - return node->n_children; -} - /** * gsk_render_node_get_bounds: * @node: a #GskRenderNode diff --git a/gsk/gskrendernode.h b/gsk/gskrendernode.h index abe6100b2e..70d26a553e 100644 --- a/gsk/gskrendernode.h +++ b/gsk/gskrendernode.h @@ -56,21 +56,14 @@ cairo_t * gsk_cairo_node_get_draw_context (GskRenderNode GDK_AVAILABLE_IN_3_90 GskRenderNode * gsk_container_node_new (void); - GDK_AVAILABLE_IN_3_90 -GskRenderNode * gsk_render_node_get_first_child (GskRenderNode *node); +GskRenderNode * gsk_container_node_append_child (GskRenderNode *node, + GskRenderNode *child); GDK_AVAILABLE_IN_3_90 -GskRenderNode * gsk_render_node_get_last_child (GskRenderNode *node); +guint gsk_container_node_get_n_children (GskRenderNode *node); GDK_AVAILABLE_IN_3_90 -GskRenderNode * gsk_render_node_get_next_sibling (GskRenderNode *node); -GDK_AVAILABLE_IN_3_90 -GskRenderNode * gsk_render_node_get_previous_sibling (GskRenderNode *node); - -GDK_AVAILABLE_IN_3_90 -GskRenderNode * gsk_render_node_append_child (GskRenderNode *node, - GskRenderNode *child); -GDK_AVAILABLE_IN_3_90 -guint gsk_render_node_get_n_children (GskRenderNode *node); +GskRenderNode * gsk_container_node_get_child (GskRenderNode *node, + guint idx); GDK_AVAILABLE_IN_3_90 void gsk_render_node_set_transform (GskRenderNode *node, diff --git a/gsk/gskrendernodeimpl.c b/gsk/gskrendernodeimpl.c index 267a81261d..40c2ad6365 100644 --- a/gsk/gskrendernodeimpl.c +++ b/gsk/gskrendernodeimpl.c @@ -279,21 +279,32 @@ gsk_cairo_node_get_draw_context (GskRenderNode *node, /**** GSK_CONTAINER_NODE ***/ +typedef struct _GskContainerNode GskContainerNode; + +struct _GskContainerNode +{ + GskRenderNode render_node; + + GPtrArray *children; +}; + static void gsk_container_node_finalize (GskRenderNode *node) { + GskContainerNode *container = (GskContainerNode *) node; + + g_ptr_array_unref (container->children); } static void gsk_container_node_make_immutable (GskRenderNode *node) { - GskRenderNode *child; + GskContainerNode *container = (GskContainerNode *) node; + guint i; - for (child = gsk_render_node_get_first_child (node); - child != NULL; - child = gsk_render_node_get_next_sibling (child)) + for (i = 1; i < container->children->len; i++) { - gsk_render_node_make_immutable (child); + gsk_render_node_make_immutable (g_ptr_array_index (container->children, i)); } } @@ -301,33 +312,29 @@ static void gsk_container_node_get_bounds (GskRenderNode *node, graphene_rect_t *bounds) { - GskRenderNode *child; + GskContainerNode *container = (GskContainerNode *) node; + guint i; - child = gsk_render_node_get_first_child (node); - - if (child == NULL) + if (container->n_children == 0) { graphene_rect_init_from_rect (bounds, graphene_rect_zero()); return; } - gsk_render_node_get_bounds (child, bounds); + gsk_render_node_get_bounds (container->children[0], bounds); - for (child = gsk_render_node_get_next_sibling (child); - child; - child = gsk_render_node_get_next_sibling (child)) + for (i = 1; i < container->n_children; i++) { - graphene_rect_t child_bounds, union_bounds; + graphene_rect_t child_bounds; - gsk_render_node_get_bounds (child, &child_bounds); - graphene_rect_union (bounds, &child_bounds, &union_bounds); - graphene_rect_init_from_rect (bounds, &union_bounds); + gsk_render_node_get_bounds (container->children[i], &child_bounds); + graphene_rect_union (bounds, &child_bounds, bounds); } } static const GskRenderNodeClass GSK_CONTAINER_NODE_CLASS = { GSK_CONTAINER_NODE, - sizeof (GskRenderNode), + sizeof (GskContainerNode), "GskContainerNode", gsk_container_node_finalize, gsk_container_node_make_immutable, @@ -348,6 +355,72 @@ static const GskRenderNodeClass GSK_CONTAINER_NODE_CLASS = { GskRenderNode * gsk_container_node_new (void) { - return gsk_render_node_new (&GSK_CONTAINER_NODE_CLASS); + GskContainerNode *container; + + container = (GskContainerNode *) gsk_render_node_new (&GSK_CONTAINER_NODE_CLASS); + + container->children = g_ptr_array_new_with_free_func ((GDestroyNotify) gsk_render_node_unref); + + return &container->render_node; +} + +/** + * gsk_container_node_append_child: + * @node: a container node + * @child: a #GskRenderNode + * + * Appends @child to the list of children of @node. + * + * This function acquires a reference on @child. + * + * Returns: (transfer none): the #GskRenderNode + * + * Since: 3.90 + */ +GskRenderNode * +gsk_container_node_append_child (GskRenderNode *node, + GskRenderNode *child) +{ + GskContainerNode *container = (GskContainerNode *) node; + + g_return_val_if_fail (GSK_IS_RENDER_NODE_TYPE (node, GSK_CONTAINER_NODE), NULL); + g_return_val_if_fail (GSK_IS_RENDER_NODE (child), node); + g_return_val_if_fail (node->is_mutable, node); + + g_ptr_array_add (container->children, gsk_render_node_ref (child)); + + return node; +} + +/** + * gsk_container_node_get_n_children: + * @node: a container #GskRenderNode + * + * Retrieves the number of direct children of @node. + * + * Returns: the number of children of the #GskRenderNode + * + * Since: 3.90 + */ +guint +gsk_container_node_get_n_children (GskRenderNode *node) +{ + GskContainerNode *container = (GskContainerNode *) node; + + g_return_val_if_fail (GSK_IS_RENDER_NODE_TYPE (node, GSK_CONTAINER_NODE), 0); + + return container->children->len; +} + +GskRenderNode * +gsk_container_node_get_child (GskRenderNode *node, + guint idx) +{ + GskContainerNode *container = (GskContainerNode *) node; + + g_return_val_if_fail (GSK_IS_RENDER_NODE_TYPE (node, GSK_CONTAINER_NODE), NULL); + g_return_val_if_fail (idx < container->children->len, 0); + + return g_ptr_array_index (container->children, idx); } diff --git a/gsk/gskrendernodeprivate.h b/gsk/gskrendernodeprivate.h index ca4a793e46..5e35396f91 100644 --- a/gsk/gskrendernodeprivate.h +++ b/gsk/gskrendernodeprivate.h @@ -16,21 +16,9 @@ struct _GskRenderNode volatile int ref_count; - /* The graph */ - GskRenderNode *parent; - GskRenderNode *first_child; - GskRenderNode *last_child; - GskRenderNode *prev_sibling; - GskRenderNode *next_sibling; - - int n_children; - /* Use for debugging */ char *name; - /* Tag updated when adding/removing children */ - gint64 age; - /* Paint opacity */ double opacity; diff --git a/gsk/gskvulkanrenderpass.c b/gsk/gskvulkanrenderpass.c index 3dc3700071..f9398f2973 100644 --- a/gsk/gskvulkanrenderpass.c +++ b/gsk/gskvulkanrenderpass.c @@ -84,12 +84,14 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self, break; case GSK_CONTAINER_NODE: - for (GskRenderNode *child = gsk_render_node_get_first_child (node); - child; - child = gsk_render_node_get_next_sibling (child)) - { - gsk_vulkan_render_pass_add_node (self, render, child); - } + { + guint i; + + for (i = 0; i < gsk_container_node_get_n_children (node); i++) + { + gsk_vulkan_render_pass_add_node (self, render, gsk_container_node_get_child (node, i)); + } + } break; } diff --git a/gtk/gtksnapshot.c b/gtk/gtksnapshot.c index 3f3192a1c3..63d5a6a7d5 100644 --- a/gtk/gtksnapshot.c +++ b/gtk/gtksnapshot.c @@ -156,6 +156,8 @@ void gtk_snapshot_push_node (GtkSnapshot *snapshot, GskRenderNode *node) { + g_return_if_fail (gsk_render_node_get_node_type (node) == GSK_CONTAINER_NODE); + gtk_snapshot_append_node (snapshot, node); snapshot->state = gtk_snapshot_state_new (snapshot->state, node); @@ -324,7 +326,7 @@ gtk_snapshot_append_node (GtkSnapshot *snapshot, if (snapshot->state) { - gsk_render_node_append_child (snapshot->state->node, node); + gsk_container_node_append_child (snapshot->state->node, node); gsk_render_node_set_transform (node, &snapshot->state->transform); } else diff --git a/gtk/inspector/gtktreemodelrendernode.c b/gtk/inspector/gtktreemodelrendernode.c index 9e5c8a9684..5f15586f8c 100644 --- a/gtk/inspector/gtktreemodelrendernode.c +++ b/gtk/inspector/gtktreemodelrendernode.c @@ -527,15 +527,13 @@ append_node (GtkTreeModelRenderNode *nodemodel, case GSK_CONTAINER_NODE: { - GskRenderNode *child; gint elt_index; + guint i; elt_index = priv->nodes->len - 1; - for (child = gsk_render_node_get_first_child (node); - child; - child = gsk_render_node_get_next_sibling (child)) + for (i = 0; i < gsk_container_node_get_n_children (node); i++) { - append_node (nodemodel, child, elt_index); + append_node (nodemodel, gsk_container_node_get_child (node, i), elt_index); } } break; @@ -579,7 +577,7 @@ gtk_tree_model_render_node_set_root_node (GtkTreeModelRenderNode *model, iter_from_element (model, &iter, 0); path = gtk_tree_path_new_first (); gtk_tree_model_row_inserted (GTK_TREE_MODEL (model), path, &iter); - if (gsk_render_node_get_first_child (node)) + if (priv->nodes->len > 1) gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (model), path, &iter); gtk_tree_path_free (path); }