summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gsk/gskrenderer.c50
-rw-r--r--gsk/gskrenderer.h3
-rw-r--r--gsk/gskrendernode.c39
-rw-r--r--gsk/gskrendernode.h2
-rw-r--r--gsk/gskrendernodeprivate.h4
-rw-r--r--gtk/gtkwidget.c4
6 files changed, 95 insertions, 7 deletions
diff --git a/gsk/gskrenderer.c b/gsk/gskrenderer.c
index f9a9fedccb..f5ea2d9092 100644
--- a/gsk/gskrenderer.c
+++ b/gsk/gskrenderer.c
@@ -72,6 +72,9 @@ typedef struct
int scale_factor;
+ GPtrArray *render_nodes;
+ int last_render_node;
+
gboolean is_realized : 1;
gboolean auto_clear : 1;
gboolean use_alpha : 1;
@@ -867,6 +870,11 @@ gsk_renderer_realize (GskRenderer *renderer)
return TRUE;
priv->is_realized = GSK_RENDERER_GET_CLASS (renderer)->realize (renderer);
+ if (priv->is_realized)
+ {
+ priv->render_nodes = g_ptr_array_new_with_free_func ((GDestroyNotify) gsk_render_node_unref);
+ priv->last_render_node = 0;
+ }
return priv->is_realized;
}
@@ -891,6 +899,9 @@ gsk_renderer_unrealize (GskRenderer *renderer)
GSK_RENDERER_GET_CLASS (renderer)->unrealize (renderer);
+ g_clear_pointer (&priv->render_nodes, g_ptr_array_unref);
+ priv->last_render_node = 0;
+
priv->is_realized = FALSE;
}
@@ -930,6 +941,7 @@ gsk_renderer_render (GskRenderer *renderer,
g_clear_object (&priv->drawing_context);
g_clear_pointer (&priv->root_node, gsk_render_node_unref);
+ priv->last_render_node = 0;
}
/**
@@ -1081,3 +1093,41 @@ gsk_renderer_get_for_display (GdkDisplay *display)
return g_object_new (renderer_type, "display", display, NULL);
}
+
+/**
+ * gsk_renderer_create_render_node:
+ * @renderer: a #GskRenderer
+ *
+ * Creates a new #GskRenderNode.
+ *
+ * Returns: (transfer full): the newly created #GskRenderNode
+ *
+ * Since: 3.22
+ */
+GskRenderNode *
+gsk_renderer_create_render_node (GskRenderer *renderer)
+{
+ GskRendererPrivate *priv = gsk_renderer_get_instance_private (renderer);
+ GskRenderNode *res;
+
+ g_return_val_if_fail (GSK_IS_RENDERER (renderer), NULL);
+
+ if (priv->last_render_node < priv->render_nodes->len)
+ {
+ int idx = priv->last_render_node;
+
+ priv->last_render_node += 1;
+
+ res = g_ptr_array_index (priv->render_nodes, idx);
+ gsk_render_node_clear (res);
+ }
+ else
+ {
+ res = gsk_render_node_new ();
+ g_ptr_array_add (priv->render_nodes, res);
+
+ priv->last_render_node = priv->render_nodes->len - 1;
+ }
+
+ return gsk_render_node_ref (res);
+}
diff --git a/gsk/gskrenderer.h b/gsk/gskrenderer.h
index ec1d3aacc2..b8cf446f9e 100644
--- a/gsk/gskrenderer.h
+++ b/gsk/gskrenderer.h
@@ -101,6 +101,9 @@ void gsk_renderer_render (GskRenderer
GskRenderNode *root,
GdkDrawingContext *context);
+GDK_AVAILABLE_IN_3_22
+GskRenderNode * gsk_renderer_create_render_node (GskRenderer *renderer);
+
G_END_DECLS
#endif /* __GSK_RENDERER_H__ */
diff --git a/gsk/gskrendernode.c b/gsk/gskrendernode.c
index 9fe76d64f7..04f2bbdc66 100644
--- a/gsk/gskrendernode.c
+++ b/gsk/gskrendernode.c
@@ -144,10 +144,15 @@ gsk_render_node_finalize (GskRenderNode *self)
{
GskRenderNodeIter iter;
+ /* We need to drop the reference on each child
+ * before clearing the node
+ */
gsk_render_node_iter_init (&iter, self);
while (gsk_render_node_iter_next (&iter, NULL))
gsk_render_node_iter_remove (&iter);
+ gsk_render_node_clear (self);
+
g_type_free_instance ((GTypeInstance *) self);
}
@@ -231,14 +236,12 @@ gsk_render_node_get_type (void)
return gsk_render_node_type__volatile;
}
-/**
+/*< private >
* gsk_render_node_new:
*
* Creates a new #GskRenderNode, to be used with #GskRenderer.
*
* Returns: (transfer full): the newly created #GskRenderNode
- *
- * Since: 3.22
*/
GskRenderNode *
gsk_render_node_new (void)
@@ -246,6 +249,36 @@ gsk_render_node_new (void)
return (GskRenderNode *) g_type_create_instance (GSK_TYPE_RENDER_NODE);
}
+void
+gsk_render_node_clear (GskRenderNode *self)
+{
+ graphene_rect_init_from_rect (&self->bounds, graphene_rect_zero ());
+
+ graphene_matrix_init_identity (&self->transform);
+ graphene_matrix_init_identity (&self->child_transform);
+
+ self->opacity = 1.0;
+
+ self->is_mutable = TRUE;
+ self->opaque = FALSE;
+ self->hidden = FALSE;
+ self->needs_world_matrix_update = TRUE;
+
+ self->parent = NULL;
+ self->first_child = NULL;
+ self->last_child = NULL;
+ self->prev_sibling = NULL;
+ self->next_sibling = NULL;
+ self->n_children = 0;
+
+ self->age = 0;
+
+ g_free (self->name);
+ self->name = NULL;
+
+ g_clear_pointer (&self->surface, cairo_surface_destroy);
+}
+
/**
* gsk_render_node_ref:
* @node: a #GskRenderNode
diff --git a/gsk/gskrendernode.h b/gsk/gskrendernode.h
index a4709ff453..8cbd243497 100644
--- a/gsk/gskrendernode.h
+++ b/gsk/gskrendernode.h
@@ -39,8 +39,6 @@ GDK_AVAILABLE_IN_3_22
GType gsk_render_node_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_3_22
-GskRenderNode * gsk_render_node_new (void);
-GDK_AVAILABLE_IN_3_22
GskRenderNode * gsk_render_node_ref (GskRenderNode *node);
GDK_AVAILABLE_IN_3_22
void gsk_render_node_unref (GskRenderNode *node);
diff --git a/gsk/gskrendernodeprivate.h b/gsk/gskrendernodeprivate.h
index 9893f962c1..e1b796416f 100644
--- a/gsk/gskrendernodeprivate.h
+++ b/gsk/gskrendernodeprivate.h
@@ -86,6 +86,10 @@ void gsk_render_node_update_world_matrix (GskRenderNode *node,
void gsk_render_node_get_world_matrix (GskRenderNode *node,
graphene_matrix_t *mv);
+GskRenderNode *gsk_render_node_new (void);
+
+void gsk_render_node_clear (GskRenderNode *node);
+
int gsk_render_node_get_size (GskRenderNode *root);
G_END_DECLS
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 90e0f2616e..fd3c728718 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -17479,7 +17479,7 @@ gtk_widget_get_render_node (GtkWidget *widget,
GskRenderNode *tmp;
cairo_t *cr;
- tmp = gsk_render_node_new ();
+ tmp = gsk_renderer_create_render_node (renderer);
gsk_render_node_set_bounds (tmp, &bounds);
gsk_render_node_set_transform (tmp, &m);
cr = gsk_render_node_get_draw_context (tmp);
@@ -17501,7 +17501,7 @@ gtk_widget_get_render_node (GtkWidget *widget,
gboolean result;
cairo_t *cr;
- tmp = gsk_render_node_new ();
+ tmp = gsk_renderer_create_render_node (renderer);
gsk_render_node_set_bounds (tmp, &bounds);
gsk_render_node_set_transform (tmp, &m);
cr = gsk_render_node_get_draw_context (tmp);