diff options
-rw-r--r-- | gsk/gskrenderer.c | 50 | ||||
-rw-r--r-- | gsk/gskrenderer.h | 3 | ||||
-rw-r--r-- | gsk/gskrendernode.c | 39 | ||||
-rw-r--r-- | gsk/gskrendernode.h | 2 | ||||
-rw-r--r-- | gsk/gskrendernodeprivate.h | 4 | ||||
-rw-r--r-- | gtk/gtkwidget.c | 4 |
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); |