diff options
author | Alexander Larsson <alexl@redhat.com> | 2016-12-21 20:39:07 +0100 |
---|---|---|
committer | Alexander Larsson <alexl@redhat.com> | 2017-01-11 16:39:39 +0100 |
commit | 8ecbd85acc181378e6ed335541c556fcf6cc09f8 (patch) | |
tree | 555177ce5dfdc8ed95174f3e86a08abdc7ca6303 | |
parent | c00f8dce9f8076e3e914210dda62e7fd2207d1e4 (diff) | |
download | gtk+-wip/alexl/rendertree.tar.gz |
gsk: Add GskRenderTreewip/alexl/rendertree
A render tree owns all the nodes that are created during a frame,
and they are allocated with a custom allocator. All the resources
allocated for the tree are kept until destruction, and then
it is all released at the same time.
Allocation happes in chunks which makes both allocation and
freeing very efficient, and also quite cache efficient.
This somewhat changes the memory management of GskRenderNode. All
nodes created by the tree are owned by the tree, and normally you
don't need to ref them. If you want to keep them around you can still
ref them, but that actually refs the entire tree.
-rw-r--r-- | gsk/gskrenderer.c | 12 | ||||
-rw-r--r-- | gsk/gskrenderer.h | 2 | ||||
-rw-r--r-- | gsk/gskrendernode.c | 174 | ||||
-rw-r--r-- | gsk/gskrendernode.h | 66 | ||||
-rw-r--r-- | gsk/gskrendernodeimpl.c | 402 | ||||
-rw-r--r-- | gsk/gskrendernodeprivate.h | 17 | ||||
-rw-r--r-- | gtk/gtkcssimagecrossfade.c | 8 | ||||
-rw-r--r-- | gtk/gtkcssimagelinear.c | 4 | ||||
-rw-r--r-- | gtk/gtkcssshadowvalue.c | 8 | ||||
-rw-r--r-- | gtk/gtkiconview.c | 2 | ||||
-rw-r--r-- | gtk/gtkrenderbackground.c | 10 | ||||
-rw-r--r-- | gtk/gtkrenderborder.c | 3 | ||||
-rw-r--r-- | gtk/gtksnapshot.c | 73 | ||||
-rw-r--r-- | gtk/gtksnapshot.h | 2 | ||||
-rw-r--r-- | gtk/gtksnapshotprivate.h | 2 | ||||
-rw-r--r-- | gtk/gtkstack.c | 8 |
16 files changed, 420 insertions, 373 deletions
diff --git a/gsk/gskrenderer.c b/gsk/gskrenderer.c index bba01532c9..12c04860ef 100644 --- a/gsk/gskrenderer.c +++ b/gsk/gskrenderer.c @@ -688,38 +688,38 @@ gsk_renderer_render_texture (GskRenderer *renderer, /** * gsk_renderer_render: * @renderer: a #GskRenderer - * @root: a #GskRenderNode + * @root_node: a #GskRenderNode * @context: The drawing context created via gsk_renderer_begin_draw_frame() * * Renders the scene graph, described by a tree of #GskRenderNode instances, * using the given #GdkDrawingContext. * - * The @renderer will acquire a reference on the #GskRenderNode tree while + * The @renderer will acquire a reference on the #GskRenderNode while * the rendering is in progress. * * Since: 3.90 */ void gsk_renderer_render (GskRenderer *renderer, - GskRenderNode *root, + GskRenderNode *root_node, GdkDrawingContext *context) { GskRendererPrivate *priv = gsk_renderer_get_instance_private (renderer); g_return_if_fail (GSK_IS_RENDERER (renderer)); g_return_if_fail (priv->is_realized); - g_return_if_fail (GSK_IS_RENDER_NODE (root)); + g_return_if_fail (GSK_IS_RENDER_NODE (root_node)); g_return_if_fail (priv->root_node == NULL); g_return_if_fail (GDK_IS_DRAWING_CONTEXT (context)); g_return_if_fail (context == priv->drawing_context); - priv->root_node = gsk_render_node_ref (root); + priv->root_node = gsk_render_node_ref (root_node); #ifdef G_ENABLE_DEBUG gsk_profiler_reset (priv->profiler); #endif - GSK_RENDERER_GET_CLASS (renderer)->render (renderer, root); + GSK_RENDERER_GET_CLASS (renderer)->render (renderer, root_node); #ifdef G_ENABLE_DEBUG if (GSK_DEBUG_CHECK (RENDERER)) diff --git a/gsk/gskrenderer.h b/gsk/gskrenderer.h index 0873cf76fa..62f5adb8d4 100644 --- a/gsk/gskrenderer.h +++ b/gsk/gskrenderer.h @@ -75,7 +75,7 @@ GdkDrawingContext * gsk_renderer_begin_draw_frame (GskRenderer const cairo_region_t *region); GDK_AVAILABLE_IN_3_90 void gsk_renderer_render (GskRenderer *renderer, - GskRenderNode *root, + GskRenderNode *root_node, GdkDrawingContext *context); GDK_AVAILABLE_IN_3_90 void gsk_renderer_end_draw_frame (GskRenderer *renderer, diff --git a/gsk/gskrendernode.c b/gsk/gskrendernode.c index ab14c151bc..dfbd92fdd0 100644 --- a/gsk/gskrendernode.c +++ b/gsk/gskrendernode.c @@ -53,6 +53,113 @@ #include <gobject/gvaluecollector.h> +#define ALLOCATE_CHUNK_SIZE (16*1024 - 2*sizeof(gsize)) + +#define ALIGN(size, base) ((base) * (gsize) (((size) + (base) - 1) / (base))) + +struct _GskRenderTree +{ + GObject parent_instance; + + guint8 *chunk; + gsize chunk_offset; + int chunk_count; + + GPtrArray *destroy_list; +}; + +G_DEFINE_TYPE (GskRenderTree, gsk_render_tree, G_TYPE_OBJECT) +G_DEFINE_QUARK (gsk-serialization-error-quark, gsk_serialization_error) + +static void +gsk_render_tree_finalize (GObject *gobject) +{ + GskRenderTree *self = GSK_RENDER_TREE (gobject); + int i; + + /* We free in reverse order, because the notify may touch + something allocated before it */ + for (i = self->destroy_list->len - 2; i >= 0 ; i -= 2) + { + GDestroyNotify notify = g_ptr_array_index (self->destroy_list, i); + gpointer data = g_ptr_array_index (self->destroy_list, i + 1); + notify (data); + } + + g_ptr_array_free (self->destroy_list, TRUE); + + G_OBJECT_CLASS (gsk_render_tree_parent_class)->finalize (gobject); +} + +static void +gsk_render_tree_class_init (GskRenderTreeClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->finalize = gsk_render_tree_finalize; +} + +static void +gsk_render_tree_init (GskRenderTree *self) +{ + self->destroy_list = g_ptr_array_new (); +} + +void +gsk_render_tree_add_cleanup (GskRenderTree *self, + GDestroyNotify notify, + gpointer data) +{ + g_ptr_array_add (self->destroy_list, notify); + g_ptr_array_add (self->destroy_list, data); +} + +/* Note: Align-size must be a power of two */ +gpointer +gsk_render_tree_allocate (GskRenderTree *self, gsize n_bytes, gsize align_size) +{ + gpointer data = NULL; + + if (n_bytes >= ALLOCATE_CHUNK_SIZE / 4) + { + data = g_malloc0 (n_bytes); + gsk_render_tree_add_cleanup (self, g_free, data); + } + else + { + self->chunk_offset = (self->chunk_offset + align_size - 1) & ~(align_size - 1); + if (self->chunk == NULL || (ALLOCATE_CHUNK_SIZE - self->chunk_offset) < n_bytes) + { + self->chunk = g_malloc (ALLOCATE_CHUNK_SIZE); + gsk_render_tree_add_cleanup (self, g_free, self->chunk); + self->chunk_offset = 0; + } + + data = self->chunk + self->chunk_offset; + self->chunk_offset += n_bytes; + memset (data, 0, n_bytes); + } + + return data; +} + +GskRenderNode * +gsk_render_tree_ref_foreign (GskRenderTree *tree, GskRenderNode *node) +{ + if (node->tree != tree) + gsk_render_tree_add_cleanup (tree, (GDestroyNotify)gsk_render_node_unref, gsk_render_node_ref (node)); + + return node; +} + + +GskRenderTree * +gsk_render_tree_new () +{ + return g_object_new (GSK_TYPE_RENDER_TREE, + NULL); +} + /** * GskRenderNode: (ref-func gsk_render_node_ref) (unref-func gsk_render_node_unref) * @@ -65,42 +172,34 @@ G_DEFINE_BOXED_TYPE (GskRenderNode, gsk_render_node, gsk_render_node_ref, gsk_render_node_unref) -G_DEFINE_QUARK (gsk-serialization-error-quark, gsk_serialization_error) - -static void -gsk_render_node_finalize (GskRenderNode *self) -{ - self->node_class->finalize (self); - - g_clear_pointer (&self->name, g_free); - - g_free (self); -} - /*< private > - * gsk_render_node_new: + * gsk_render_tree_new_node: * @node_class: class structure for this node * * Returns: (transfer full): the newly created #GskRenderNode */ GskRenderNode * -gsk_render_node_new (const GskRenderNodeClass *node_class, gsize extra_size) +gsk_render_tree_new_node (GskRenderTree *self, const GskRenderNodeClass *node_class, gsize extra_size) { - GskRenderNode *self; + GskRenderNode *node; g_return_val_if_fail (node_class != NULL, NULL); g_return_val_if_fail (node_class->node_type != GSK_NOT_A_RENDER_NODE, NULL); - self = g_malloc0 (node_class->struct_size + extra_size); - - self->node_class = node_class; + node = gsk_render_tree_allocate (self, node_class->struct_size + extra_size, 2*sizeof(gsize)); - self->ref_count = 1; + node->node_class = node_class; + node->tree = self; + node->min_filter = GSK_SCALING_FILTER_NEAREST; + node->mag_filter = GSK_SCALING_FILTER_NEAREST; - self->min_filter = GSK_SCALING_FILTER_NEAREST; - self->mag_filter = GSK_SCALING_FILTER_NEAREST; + return node; +} - return self; +GskRenderTree * +gsk_render_node_get_tree (GskRenderNode *self) +{ + return self->tree; } /** @@ -108,6 +207,10 @@ gsk_render_node_new (const GskRenderNodeClass *node_class, gsize extra_size) * @node: a #GskRenderNode * * Acquires a reference on the given #GskRenderNode. + * All nodes are owned by the tree they are part of, so normally you don't + * need to ref individual nodes. + * + * Note: This keeps the whole tree alive for the lifetime of the node. * * Returns: (transfer none): the #GskRenderNode with an additional reference * @@ -116,9 +219,12 @@ gsk_render_node_new (const GskRenderNodeClass *node_class, gsize extra_size) GskRenderNode * gsk_render_node_ref (GskRenderNode *node) { + GskRenderTree *tree; + g_return_val_if_fail (GSK_IS_RENDER_NODE (node), NULL); - g_atomic_int_inc (&node->ref_count); + tree = gsk_render_node_get_tree (node); + g_object_ref (tree); return node; } @@ -137,10 +243,12 @@ gsk_render_node_ref (GskRenderNode *node) void gsk_render_node_unref (GskRenderNode *node) { + GskRenderTree *tree; + g_return_if_fail (GSK_IS_RENDER_NODE (node)); - if (g_atomic_int_dec_and_test (&node->ref_count)) - gsk_render_node_finalize (node); + tree = gsk_render_node_get_tree (node); + g_object_unref (tree); } /** @@ -209,10 +317,16 @@ void gsk_render_node_set_name (GskRenderNode *node, const char *name) { + GskRenderTree *tree; + char *new_name; + g_return_if_fail (GSK_IS_RENDER_NODE (node)); - g_free (node->name); - node->name = g_strdup (name); + tree = gsk_render_node_get_tree (node); + + new_name = gsk_render_tree_allocate (tree, strlen (name) + 1, 1); + strcpy (new_name, name); + node->name = new_name; } /** @@ -391,6 +505,7 @@ gsk_render_node_deserialize (GBytes *bytes, guint32 version, node_type; GVariant *variant, *node_variant; GskRenderNode *node = NULL; + GskRenderTree *tree; variant = g_variant_new_from_bytes (G_VARIANT_TYPE ("(suuv)"), bytes, FALSE); @@ -410,7 +525,10 @@ gsk_render_node_deserialize (GBytes *bytes, goto out; } - node = gsk_render_node_deserialize_node (node_type, node_variant, error); + tree = gsk_render_tree_new (); + node = gsk_render_node_deserialize_node (tree, node_type, node_variant, error); + gsk_render_node_ref (node); + g_object_unref (tree); out: g_free (id_string); diff --git a/gsk/gskrendernode.h b/gsk/gskrendernode.h index f46c283ba1..3e1016e0ea 100644 --- a/gsk/gskrendernode.h +++ b/gsk/gskrendernode.h @@ -28,12 +28,17 @@ G_BEGIN_DECLS -#define GSK_TYPE_RENDER_NODE (gsk_render_node_get_type ()) +#define GSK_TYPE_RENDER_TREE (gsk_render_tree_get_type ()) + +GDK_AVAILABLE_IN_3_90 +G_DECLARE_FINAL_TYPE (GskRenderTree, gsk_render_tree, GSK, RENDER_TREE, GObject) +#define GSK_TYPE_RENDER_NODE (gsk_render_node_get_type ()) #define GSK_IS_RENDER_NODE(obj) ((obj) != NULL) #define GSK_SERIALIZATION_ERROR (gsk_serialization_error_quark ()) +typedef struct _GskRenderTree GskRenderTree; typedef struct _GskRenderNode GskRenderNode; typedef struct _GskColorStop GskColorStop; typedef struct _GskShadow GskShadow; @@ -53,10 +58,11 @@ struct _GskShadow }; GDK_AVAILABLE_IN_3_90 -GType gsk_render_node_get_type (void) G_GNUC_CONST; +GQuark gsk_serialization_error_quark (void); +GskRenderTree * gsk_render_tree_new (void); GDK_AVAILABLE_IN_3_90 -GQuark gsk_serialization_error_quark (void); +GType gsk_render_node_get_type (void) G_GNUC_CONST; GDK_AVAILABLE_IN_3_90 GskRenderNode * gsk_render_node_ref (GskRenderNode *node); @@ -67,40 +73,47 @@ GDK_AVAILABLE_IN_3_90 GskRenderNodeType gsk_render_node_get_node_type (GskRenderNode *node); GDK_AVAILABLE_IN_3_90 -GskRenderNode * gsk_color_node_new (const GdkRGBA *rgba, +GskRenderNode * gsk_color_node_new (GskRenderTree *tree, + const GdkRGBA *rgba, const graphene_rect_t *bounds); GDK_AVAILABLE_IN_3_90 -GskRenderNode * gsk_texture_node_new (GskTexture *texture, +GskRenderNode * gsk_texture_node_new (GskRenderTree *tree, + GskTexture *texture, const graphene_rect_t *bounds); GDK_AVAILABLE_IN_3_90 -GskRenderNode * gsk_linear_gradient_node_new (const graphene_rect_t *bounds, +GskRenderNode * gsk_linear_gradient_node_new (GskRenderTree *tree, + const graphene_rect_t *bounds, const graphene_point_t *start, const graphene_point_t *end, const GskColorStop *color_stops, gsize n_color_stops); GDK_AVAILABLE_IN_3_90 -GskRenderNode * gsk_repeating_linear_gradient_node_new (const graphene_rect_t *bounds, +GskRenderNode * gsk_repeating_linear_gradient_node_new (GskRenderTree *tree, + const graphene_rect_t *bounds, const graphene_point_t *start, const graphene_point_t *end, const GskColorStop *color_stops, gsize n_color_stops); GDK_AVAILABLE_IN_3_90 -GskRenderNode * gsk_border_node_new (const GskRoundedRect *outline, +GskRenderNode * gsk_border_node_new (GskRenderTree *tree, + const GskRoundedRect *outline, const float border_width[4], const GdkRGBA border_color[4]); GDK_AVAILABLE_IN_3_90 -GskRenderNode * gsk_inset_shadow_node_new (const GskRoundedRect *outline, +GskRenderNode * gsk_inset_shadow_node_new (GskRenderTree *tree, + const GskRoundedRect *outline, const GdkRGBA *color, float dx, float dy, float spread, float blur_radius); GDK_AVAILABLE_IN_3_90 -GskRenderNode * gsk_outset_shadow_node_new (const GskRoundedRect *outline, +GskRenderNode * gsk_outset_shadow_node_new (GskRenderTree *tree, + const GskRoundedRect *outline, const GdkRGBA *color, float dx, float dy, @@ -108,13 +121,15 @@ GskRenderNode * gsk_outset_shadow_node_new (const GskRounde float blur_radius); GDK_AVAILABLE_IN_3_90 -GskRenderNode * gsk_cairo_node_new (const graphene_rect_t *bounds); +GskRenderNode * gsk_cairo_node_new (GskRenderTree *tree, + const graphene_rect_t *bounds); GDK_AVAILABLE_IN_3_90 cairo_t * gsk_cairo_node_get_draw_context (GskRenderNode *node, GskRenderer *renderer); GDK_AVAILABLE_IN_3_90 -GskRenderNode * gsk_container_node_new (GskRenderNode **children, +GskRenderNode * gsk_container_node_new (GskRenderTree *tree, + GskRenderNode **children, guint n_children); GDK_AVAILABLE_IN_3_90 guint gsk_container_node_get_n_children (GskRenderNode *node); @@ -123,51 +138,60 @@ GskRenderNode * gsk_container_node_get_child (GskRenderNode guint idx); GDK_AVAILABLE_IN_3_90 -GskRenderNode * gsk_transform_node_new (GskRenderNode *child, +GskRenderNode * gsk_transform_node_new (GskRenderTree *tree, + GskRenderNode *child, const graphene_matrix_t *transform); GDK_AVAILABLE_IN_3_90 GskRenderNode * gsk_transform_node_get_child (GskRenderNode *node); GDK_AVAILABLE_IN_3_90 -GskRenderNode * gsk_opacity_node_new (GskRenderNode *child, +GskRenderNode * gsk_opacity_node_new (GskRenderTree *tree, + GskRenderNode *child, double opacity); GDK_AVAILABLE_IN_3_90 GskRenderNode * gsk_opacity_node_get_child (GskRenderNode *node); GDK_AVAILABLE_IN_3_90 -GskRenderNode * gsk_color_matrix_node_new (GskRenderNode *child, +GskRenderNode * gsk_color_matrix_node_new (GskRenderTree *tree, + GskRenderNode *child, const graphene_matrix_t *color_matrix, const graphene_vec4_t *color_offset); GDK_AVAILABLE_IN_3_90 -GskRenderNode * gsk_repeat_node_new (const graphene_rect_t *bounds, +GskRenderNode * gsk_repeat_node_new (GskRenderTree *tree, + const graphene_rect_t *bounds, GskRenderNode *child, const graphene_rect_t *child_bounds); GDK_AVAILABLE_IN_3_90 -GskRenderNode * gsk_clip_node_new (GskRenderNode *child, +GskRenderNode * gsk_clip_node_new (GskRenderTree *tree, + GskRenderNode *child, const graphene_rect_t *clip); GDK_AVAILABLE_IN_3_90 GskRenderNode * gsk_clip_node_get_child (GskRenderNode *node); GDK_AVAILABLE_IN_3_90 -GskRenderNode * gsk_rounded_clip_node_new (GskRenderNode *child, +GskRenderNode * gsk_rounded_clip_node_new (GskRenderTree *tree, + GskRenderNode *child, const GskRoundedRect *clip); GDK_AVAILABLE_IN_3_90 GskRenderNode * gsk_rounded_clip_node_get_child (GskRenderNode *node); GDK_AVAILABLE_IN_3_90 -GskRenderNode * gsk_shadow_node_new (GskRenderNode *child, +GskRenderNode * gsk_shadow_node_new (GskRenderTree *tree, + GskRenderNode *child, const GskShadow *shadows, gsize n_shadows); GDK_AVAILABLE_IN_3_90 -GskRenderNode * gsk_blend_node_new (GskRenderNode *bottom, +GskRenderNode * gsk_blend_node_new (GskRenderTree *tree, + GskRenderNode *bottom, GskRenderNode *top, GskBlendMode blend_mode); GDK_AVAILABLE_IN_3_90 -GskRenderNode * gsk_cross_fade_node_new (GskRenderNode *start, +GskRenderNode * gsk_cross_fade_node_new (GskRenderTree *tree, + GskRenderNode *start, GskRenderNode *end, double progress); diff --git a/gsk/gskrendernodeimpl.c b/gsk/gskrendernodeimpl.c index af356d5798..0791f54660 100644 --- a/gsk/gskrendernodeimpl.c +++ b/gsk/gskrendernodeimpl.c @@ -54,11 +54,6 @@ struct _GskColorNode }; static void -gsk_color_node_finalize (GskRenderNode *node) -{ -} - -static void gsk_color_node_draw (GskRenderNode *node, cairo_t *cr) { @@ -87,7 +82,8 @@ gsk_color_node_serialize (GskRenderNode *node) } static GskRenderNode * -gsk_color_node_deserialize (GVariant *variant, +gsk_color_node_deserialize (GskRenderTree *tree, + GVariant *variant, GError **error) { double x, y, w, h; @@ -100,14 +96,13 @@ gsk_color_node_deserialize (GVariant *variant, &color.red, &color.green, &color.blue, &color.alpha, &x, &y, &w, &h); - return gsk_color_node_new (&color, &GRAPHENE_RECT_INIT (x, y, w, h)); + return gsk_color_node_new (tree, &color, &GRAPHENE_RECT_INIT (x, y, w, h)); } static const GskRenderNodeClass GSK_COLOR_NODE_CLASS = { GSK_COLOR_NODE, sizeof (GskColorNode), "GskColorNode", - gsk_color_node_finalize, gsk_color_node_draw, gsk_color_node_serialize, gsk_color_node_deserialize, @@ -134,7 +129,8 @@ gsk_color_node_peek_color (GskRenderNode *node) * Since: 3.90 */ GskRenderNode * -gsk_color_node_new (const GdkRGBA *rgba, +gsk_color_node_new (GskRenderTree *tree, + const GdkRGBA *rgba, const graphene_rect_t *bounds) { GskColorNode *self; @@ -142,7 +138,7 @@ gsk_color_node_new (const GdkRGBA *rgba, g_return_val_if_fail (rgba != NULL, NULL); g_return_val_if_fail (bounds != NULL, NULL); - self = (GskColorNode *) gsk_render_node_new (&GSK_COLOR_NODE_CLASS, 0); + self = (GskColorNode *) gsk_render_tree_new_node (tree, &GSK_COLOR_NODE_CLASS, 0); self->color = *rgba; graphene_rect_init_from_rect (&self->render_node.bounds, bounds); @@ -166,11 +162,6 @@ struct _GskLinearGradientNode }; static void -gsk_linear_gradient_node_finalize (GskRenderNode *node) -{ -} - -static void gsk_linear_gradient_node_draw (GskRenderNode *node, cairo_t *cr) { @@ -230,7 +221,8 @@ gsk_linear_gradient_node_serialize (GskRenderNode *node) } static GskRenderNode * -gsk_linear_gradient_node_real_deserialize (GVariant *variant, +gsk_linear_gradient_node_real_deserialize (GskRenderTree *tree, + GVariant *variant, gboolean repeating, GError **error) { @@ -260,7 +252,8 @@ gsk_linear_gradient_node_real_deserialize (GVariant *variant, g_variant_iter_free (iter); return (repeating ? gsk_repeating_linear_gradient_node_new : gsk_linear_gradient_node_new) - (&GRAPHENE_RECT_INIT (x, y, w, h), + (tree, + &GRAPHENE_RECT_INIT (x, y, w, h), &GRAPHENE_POINT_INIT (start_x, start_y), &GRAPHENE_POINT_INIT (end_x, end_y), stops, @@ -268,24 +261,25 @@ gsk_linear_gradient_node_real_deserialize (GVariant *variant, } static GskRenderNode * -gsk_linear_gradient_node_deserialize (GVariant *variant, +gsk_linear_gradient_node_deserialize (GskRenderTree *tree, + GVariant *variant, GError **error) { - return gsk_linear_gradient_node_real_deserialize (variant, FALSE, error); + return gsk_linear_gradient_node_real_deserialize (tree, variant, FALSE, error); } static GskRenderNode * -gsk_repeating_linear_gradient_node_deserialize (GVariant *variant, +gsk_repeating_linear_gradient_node_deserialize (GskRenderTree *tree, + GVariant *variant, GError **error) { - return gsk_linear_gradient_node_real_deserialize (variant, TRUE, error); + return gsk_linear_gradient_node_real_deserialize (tree, variant, TRUE, error); } static const GskRenderNodeClass GSK_LINEAR_GRADIENT_NODE_CLASS = { GSK_LINEAR_GRADIENT_NODE, sizeof (GskLinearGradientNode), "GskLinearGradientNode", - gsk_linear_gradient_node_finalize, gsk_linear_gradient_node_draw, gsk_linear_gradient_node_serialize, gsk_linear_gradient_node_deserialize, @@ -295,7 +289,6 @@ static const GskRenderNodeClass GSK_REPEATING_LINEAR_GRADIENT_NODE_CLASS = { GSK_REPEATING_LINEAR_GRADIENT_NODE, sizeof (GskLinearGradientNode), "GskLinearGradientNode", - gsk_linear_gradient_node_finalize, gsk_linear_gradient_node_draw, gsk_linear_gradient_node_serialize, gsk_repeating_linear_gradient_node_deserialize, @@ -314,7 +307,8 @@ static const GskRenderNodeClass GSK_REPEATING_LINEAR_GRADIENT_NODE_CLASS = { * Since: 3.90 */ GskRenderNode * -gsk_linear_gradient_node_new (const graphene_rect_t *bounds, +gsk_linear_gradient_node_new (GskRenderTree *tree, + const graphene_rect_t *bounds, const graphene_point_t *start, const graphene_point_t *end, const GskColorStop *color_stops, @@ -336,7 +330,7 @@ gsk_linear_gradient_node_new (const graphene_rect_t *bounds, } g_return_val_if_fail (color_stops[n_color_stops - 1].offset <= 1, NULL); - self = (GskLinearGradientNode *) gsk_render_node_new (&GSK_LINEAR_GRADIENT_NODE_CLASS, sizeof (GskColorStop) * n_color_stops); + self = (GskLinearGradientNode *) gsk_render_tree_new_node (tree, &GSK_LINEAR_GRADIENT_NODE_CLASS, sizeof (GskColorStop) * n_color_stops); graphene_rect_init_from_rect (&self->render_node.bounds, bounds); graphene_point_init_from_point (&self->start, start); @@ -349,7 +343,8 @@ gsk_linear_gradient_node_new (const graphene_rect_t *bounds, } GskRenderNode * -gsk_repeating_linear_gradient_node_new (const graphene_rect_t *bounds, +gsk_repeating_linear_gradient_node_new (GskRenderTree *tree, + const graphene_rect_t *bounds, const graphene_point_t *start, const graphene_point_t *end, const GskColorStop *color_stops, @@ -371,7 +366,7 @@ gsk_repeating_linear_gradient_node_new (const graphene_rect_t *bounds, } g_return_val_if_fail (color_stops[n_color_stops - 1].offset <= 1, NULL); - self = (GskLinearGradientNode *) gsk_render_node_new (&GSK_REPEATING_LINEAR_GRADIENT_NODE_CLASS, sizeof (GskColorStop) * n_color_stops); + self = (GskLinearGradientNode *) gsk_render_tree_new_node (tree, &GSK_REPEATING_LINEAR_GRADIENT_NODE_CLASS, sizeof (GskColorStop) * n_color_stops); graphene_rect_init_from_rect (&self->render_node.bounds, bounds); graphene_point_init_from_point (&self->start, start); @@ -429,11 +424,6 @@ struct _GskBorderNode }; static void -gsk_border_node_finalize (GskRenderNode *node) -{ -} - -static void gsk_border_node_draw (GskRenderNode *node, cairo_t *cr) { @@ -543,7 +533,8 @@ gsk_border_node_serialize (GskRenderNode *node) } static GskRenderNode * -gsk_border_node_deserialize (GVariant *variant, +gsk_border_node_deserialize (GskRenderTree *tree, + GVariant *variant, GError **error) { double doutline[12], dwidths[4]; @@ -562,7 +553,8 @@ gsk_border_node_deserialize (GVariant *variant, &colors[2].red, &colors[2].green, &colors[2].blue, &colors[2].alpha, &colors[3].red, &colors[3].green, &colors[3].blue, &colors[3].alpha); - return gsk_border_node_new (&(GskRoundedRect) { + return gsk_border_node_new (tree, + &(GskRoundedRect) { .bounds = GRAPHENE_RECT_INIT(doutline[0], doutline[1], doutline[2], doutline[3]), .corner = { GRAPHENE_SIZE_INIT (doutline[4], doutline[5]), @@ -579,7 +571,6 @@ static const GskRenderNodeClass GSK_BORDER_NODE_CLASS = { GSK_BORDER_NODE, sizeof (GskBorderNode), "GskBorderNode", - gsk_border_node_finalize, gsk_border_node_draw, gsk_border_node_serialize, gsk_border_node_deserialize @@ -627,7 +618,8 @@ gsk_border_node_peek_color (GskRenderNode *node, * Since: 3.90 */ GskRenderNode * -gsk_border_node_new (const GskRoundedRect *outline, +gsk_border_node_new (GskRenderTree *tree, + const GskRoundedRect *outline, const float border_width[4], const GdkRGBA border_color[4]) { @@ -637,7 +629,7 @@ gsk_border_node_new (const GskRoundedRect *outline, g_return_val_if_fail (border_width != NULL, NULL); g_return_val_if_fail (border_color != NULL, NULL); - self = (GskBorderNode *) gsk_render_node_new (&GSK_BORDER_NODE_CLASS, 0); + self = (GskBorderNode *) gsk_render_tree_new_node (tree, &GSK_BORDER_NODE_CLASS, 0); gsk_rounded_rect_init_copy (&self->outline, outline); memcpy (self->border_width, border_width, sizeof (self->border_width)); @@ -660,14 +652,6 @@ struct _GskTextureNode }; static void -gsk_texture_node_finalize (GskRenderNode *node) -{ - GskTextureNode *self = (GskTextureNode *) node; - - g_object_unref (self->texture); -} - -static void gsk_texture_node_draw (GskRenderNode *node, cairo_t *cr) { @@ -721,7 +705,8 @@ gsk_texture_node_serialize (GskRenderNode *node) } static GskRenderNode * -gsk_texture_node_deserialize (GVariant *variant, +gsk_texture_node_deserialize (GskRenderTree *tree, + GVariant *variant, GError **error) { GskRenderNode *node; @@ -743,7 +728,7 @@ gsk_texture_node_deserialize (GVariant *variant, width, height, width * 4); g_variant_unref (pixel_variant); - node = gsk_texture_node_new (texture, &GRAPHENE_RECT_INIT(bounds[0], bounds[1], bounds[2], bounds[3])); + node = gsk_texture_node_new (tree, texture, &GRAPHENE_RECT_INIT(bounds[0], bounds[1], bounds[2], bounds[3])); g_object_unref (texture); @@ -754,7 +739,6 @@ static const GskRenderNodeClass GSK_TEXTURE_NODE_CLASS = { GSK_TEXTURE_NODE, sizeof (GskTextureNode), "GskTextureNode", - gsk_texture_node_finalize, gsk_texture_node_draw, gsk_texture_node_serialize, gsk_texture_node_deserialize @@ -783,7 +767,8 @@ gsk_texture_node_get_texture (GskRenderNode *node) * Since: 3.90 */ GskRenderNode * -gsk_texture_node_new (GskTexture *texture, +gsk_texture_node_new (GskRenderTree *tree, + GskTexture *texture, const graphene_rect_t *bounds) { GskTextureNode *self; @@ -791,9 +776,11 @@ gsk_texture_node_new (GskTexture *texture, g_return_val_if_fail (GSK_IS_TEXTURE (texture), NULL); g_return_val_if_fail (bounds != NULL, NULL); - self = (GskTextureNode *) gsk_render_node_new (&GSK_TEXTURE_NODE_CLASS, 0); + self = (GskTextureNode *) gsk_render_tree_new_node (tree, &GSK_TEXTURE_NODE_CLASS, 0); + + gsk_render_tree_add_cleanup (tree, (GDestroyNotify)g_object_unref, g_object_ref (texture)); - self->texture = g_object_ref (texture); + self->texture = texture; graphene_rect_init_from_rect (&self->render_node.bounds, bounds); return &self->render_node; @@ -815,11 +802,6 @@ struct _GskInsetShadowNode float blur_radius; }; -static void -gsk_inset_shadow_node_finalize (GskRenderNode *node) -{ -} - static gboolean has_empty_clip (cairo_t *cr) { @@ -1224,7 +1206,8 @@ gsk_inset_shadow_node_serialize (GskRenderNode *node) } static GskRenderNode * -gsk_inset_shadow_node_deserialize (GVariant *variant, +gsk_inset_shadow_node_deserialize (GskRenderTree *tree, + GVariant *variant, GError **error) { double doutline[12], dx, dy, spread, radius; @@ -1240,7 +1223,8 @@ gsk_inset_shadow_node_deserialize (GVariant *variant, &color.red, &color.green, &color.blue, &color.alpha, &dx, &dy, &spread, &radius); - return gsk_inset_shadow_node_new (&(GskRoundedRect) { + return gsk_inset_shadow_node_new (tree, + &(GskRoundedRect) { .bounds = GRAPHENE_RECT_INIT(doutline[0], doutline[1], doutline[2], doutline[3]), .corner = { GRAPHENE_SIZE_INIT (doutline[4], doutline[5]), @@ -1256,7 +1240,6 @@ static const GskRenderNodeClass GSK_INSET_SHADOW_NODE_CLASS = { GSK_INSET_SHADOW_NODE, sizeof (GskInsetShadowNode), "GskInsetShadowNode", - gsk_inset_shadow_node_finalize, gsk_inset_shadow_node_draw, gsk_inset_shadow_node_serialize, gsk_inset_shadow_node_deserialize @@ -1279,7 +1262,8 @@ static const GskRenderNodeClass GSK_INSET_SHADOW_NODE_CLASS = { * Since: 3.90 */ GskRenderNode * -gsk_inset_shadow_node_new (const GskRoundedRect *outline, +gsk_inset_shadow_node_new (GskRenderTree *tree, + const GskRoundedRect *outline, const GdkRGBA *color, float dx, float dy, @@ -1291,7 +1275,7 @@ gsk_inset_shadow_node_new (const GskRoundedRect *outline, g_return_val_if_fail (outline != NULL, NULL); g_return_val_if_fail (color != NULL, NULL); - self = (GskInsetShadowNode *) gsk_render_node_new (&GSK_INSET_SHADOW_NODE_CLASS, 0); + self = (GskInsetShadowNode *) gsk_render_tree_new_node (tree, &GSK_INSET_SHADOW_NODE_CLASS, 0); gsk_rounded_rect_init_copy (&self->outline, outline); self->color = *color; @@ -1322,11 +1306,6 @@ struct _GskOutsetShadowNode }; static void -gsk_outset_shadow_node_finalize (GskRenderNode *node) -{ -} - -static void gsk_outset_shadow_get_extents (GskOutsetShadowNode *self, float *top, float *right, @@ -1467,7 +1446,8 @@ gsk_outset_shadow_node_serialize (GskRenderNode *node) } static GskRenderNode * -gsk_outset_shadow_node_deserialize (GVariant *variant, +gsk_outset_shadow_node_deserialize (GskRenderTree *tree, + GVariant *variant, GError **error) { double doutline[12], dx, dy, spread, radius; @@ -1483,7 +1463,8 @@ gsk_outset_shadow_node_deserialize (GVariant *variant, &color.red, &color.green, &color.blue, &color.alpha, &dx, &dy, &spread, &radius); - return gsk_outset_shadow_node_new (&(GskRoundedRect) { + return gsk_outset_shadow_node_new (tree, + &(GskRoundedRect) { .bounds = GRAPHENE_RECT_INIT(doutline[0], doutline[1], doutline[2], doutline[3]), .corner = { GRAPHENE_SIZE_INIT (doutline[4], doutline[5]), @@ -1499,7 +1480,6 @@ static const GskRenderNodeClass GSK_OUTSET_SHADOW_NODE_CLASS = { GSK_OUTSET_SHADOW_NODE, sizeof (GskOutsetShadowNode), "GskOutsetShadowNode", - gsk_outset_shadow_node_finalize, gsk_outset_shadow_node_draw, gsk_outset_shadow_node_serialize, gsk_outset_shadow_node_deserialize @@ -1522,7 +1502,8 @@ static const GskRenderNodeClass GSK_OUTSET_SHADOW_NODE_CLASS = { * Since: 3.90 */ GskRenderNode * -gsk_outset_shadow_node_new (const GskRoundedRect *outline, +gsk_outset_shadow_node_new (GskRenderTree *tree, + const GskRoundedRect *outline, const GdkRGBA *color, float dx, float dy, @@ -1535,7 +1516,7 @@ gsk_outset_shadow_node_new (const GskRoundedRect *outline, g_return_val_if_fail (outline != NULL, NULL); g_return_val_if_fail (color != NULL, NULL); - self = (GskOutsetShadowNode *) gsk_render_node_new (&GSK_OUTSET_SHADOW_NODE_CLASS, 0); + self = (GskOutsetShadowNode *) gsk_render_tree_new_node (tree, &GSK_OUTSET_SHADOW_NODE_CLASS, 0); gsk_rounded_rect_init_copy (&self->outline, outline); self->color = *color; @@ -1568,15 +1549,6 @@ struct _GskCairoNode }; static void -gsk_cairo_node_finalize (GskRenderNode *node) -{ - GskCairoNode *self = (GskCairoNode *) node; - - if (self->surface) - cairo_surface_destroy (self->surface); -} - -static void gsk_cairo_node_draw (GskRenderNode *node, cairo_t *cr) { @@ -1628,7 +1600,8 @@ gsk_cairo_node_serialize (GskRenderNode *node) const cairo_user_data_key_t gsk_surface_variant_key; static GskRenderNode * -gsk_cairo_node_deserialize (GVariant *variant, +gsk_cairo_node_deserialize (GskRenderTree *tree, + GVariant *variant, GError **error) { GskRenderNode *result; @@ -1649,7 +1622,7 @@ gsk_cairo_node_deserialize (GVariant *variant, if (surface_width == 0 || surface_height == 0) { g_variant_unref (pixel_variant); - return gsk_cairo_node_new (&GRAPHENE_RECT_INIT (x, y, width, height)); + return gsk_cairo_node_new (tree, &GRAPHENE_RECT_INIT (x, y, width, height)); } /* XXX: Make this work without copying the data */ @@ -1661,7 +1634,7 @@ gsk_cairo_node_deserialize (GVariant *variant, pixel_variant, (cairo_destroy_func_t) g_variant_unref); - result = gsk_cairo_node_new_for_surface (&GRAPHENE_RECT_INIT (x, y, width, height), surface); + result = gsk_cairo_node_new_for_surface (tree, &GRAPHENE_RECT_INIT (x, y, width, height), surface); cairo_surface_destroy (surface); @@ -1672,7 +1645,6 @@ static const GskRenderNodeClass GSK_CAIRO_NODE_CLASS = { GSK_CAIRO_NODE, sizeof (GskCairoNode), "GskCairoNode", - gsk_cairo_node_finalize, gsk_cairo_node_draw, gsk_cairo_node_serialize, gsk_cairo_node_deserialize @@ -1697,17 +1669,20 @@ gsk_cairo_node_get_surface (GskRenderNode *node) } GskRenderNode * -gsk_cairo_node_new_for_surface (const graphene_rect_t *bounds, +gsk_cairo_node_new_for_surface (GskRenderTree *tree, + const graphene_rect_t *bounds, cairo_surface_t *surface) { GskCairoNode *self; g_return_val_if_fail (bounds != NULL, NULL); - self = (GskCairoNode *) gsk_render_node_new (&GSK_CAIRO_NODE_CLASS, 0); + self = (GskCairoNode *) gsk_render_tree_new_node (tree, &GSK_CAIRO_NODE_CLASS, 0); graphene_rect_init_from_rect (&self->render_node.bounds, bounds); + self->surface = cairo_surface_reference (surface); + gsk_render_tree_add_cleanup (tree, (GDestroyNotify)cairo_surface_destroy, self->surface); return &self->render_node; } @@ -1725,13 +1700,14 @@ gsk_cairo_node_new_for_surface (const graphene_rect_t *bounds, * Since: 3.90 */ GskRenderNode * -gsk_cairo_node_new (const graphene_rect_t *bounds) +gsk_cairo_node_new (GskRenderTree *tree, + const graphene_rect_t *bounds) { GskCairoNode *self; g_return_val_if_fail (bounds != NULL, NULL); - self = (GskCairoNode *) gsk_render_node_new (&GSK_CAIRO_NODE_CLASS, 0); + self = (GskCairoNode *) gsk_render_tree_new_node (tree, &GSK_CAIRO_NODE_CLASS, 0); graphene_rect_init_from_rect (&self->render_node.bounds, bounds); @@ -1775,6 +1751,8 @@ gsk_cairo_node_get_draw_context (GskRenderNode *node, } else if (self->surface == NULL) { + GskRenderTree *tree = gsk_render_node_get_tree (node); + if (renderer) { self->surface = gsk_renderer_create_cairo_surface (renderer, @@ -1788,6 +1766,7 @@ gsk_cairo_node_get_draw_context (GskRenderNode *node, ceilf (node->bounds.size.width), ceilf (node->bounds.size.height)); } + gsk_render_tree_add_cleanup (tree, (GDestroyNotify)cairo_surface_destroy, self->surface); res = cairo_create (self->surface); } else @@ -1835,16 +1814,6 @@ struct _GskContainerNode }; static void -gsk_container_node_finalize (GskRenderNode *node) -{ - GskContainerNode *container = (GskContainerNode *) node; - guint i; - - for (i = 0; i < container->n_children; i++) - gsk_render_node_unref (container->children[i]); -} - -static void gsk_container_node_draw (GskRenderNode *node, cairo_t *cr) { @@ -1896,7 +1865,8 @@ gsk_container_node_serialize (GskRenderNode *node) } static GskRenderNode * -gsk_container_node_deserialize (GVariant *variant, +gsk_container_node_deserialize (GskRenderTree *tree, + GVariant *variant, GError **error) { GskRenderNode *result; @@ -1914,7 +1884,7 @@ gsk_container_node_deserialize (GVariant *variant, while (g_variant_iter_loop (&iter, "(uv)", &child_type, &child_variant)) { - children[i] = gsk_render_node_deserialize_node (child_type, child_variant, error); + children[i] = gsk_render_node_deserialize_node (tree, child_type, child_variant, error); if (children[i] == NULL) { guint j; @@ -1926,7 +1896,7 @@ gsk_container_node_deserialize (GVariant *variant, i++; } - result = gsk_container_node_new (children, n_children); + result = gsk_container_node_new (tree, children, n_children); for (i = 0; i < n_children; i++) gsk_render_node_unref (children[i]); @@ -1938,7 +1908,6 @@ static const GskRenderNodeClass GSK_CONTAINER_NODE_CLASS = { GSK_CONTAINER_NODE, sizeof (GskContainerNode), "GskContainerNode", - gsk_container_node_finalize, gsk_container_node_draw, gsk_container_node_serialize, gsk_container_node_deserialize @@ -1957,18 +1926,19 @@ static const GskRenderNodeClass GSK_CONTAINER_NODE_CLASS = { * Since: 3.90 */ GskRenderNode * -gsk_container_node_new (GskRenderNode **children, +gsk_container_node_new (GskRenderTree *tree, + GskRenderNode **children, guint n_children) { GskContainerNode *container; guint i; - container = (GskContainerNode *) gsk_render_node_new (&GSK_CONTAINER_NODE_CLASS, sizeof (GskRenderNode *) * n_children); + container = (GskContainerNode *) gsk_render_tree_new_node (tree, &GSK_CONTAINER_NODE_CLASS, sizeof (GskRenderNode *) * n_children); container->n_children = n_children; for (i = 0; i < container->n_children; i++) - container->children[i] = gsk_render_node_ref (children[i]); + container->children[i] = gsk_render_tree_ref_foreign (tree, children[i]); gsk_container_node_get_bounds (container, &container->render_node.bounds); @@ -2020,14 +1990,6 @@ struct _GskTransformNode }; static void -gsk_transform_node_finalize (GskRenderNode *node) -{ - GskTransformNode *self = (GskTransformNode *) node; - - gsk_render_node_unref (self->child); -} - -static void gsk_transform_node_draw (GskRenderNode *node, cairo_t *cr) { @@ -2072,7 +2034,8 @@ gsk_transform_node_serialize (GskRenderNode *node) } static GskRenderNode * -gsk_transform_node_deserialize (GVariant *variant, +gsk_transform_node_deserialize (GskRenderTree *tree, + GVariant *variant, GError **error) { graphene_matrix_t transform; @@ -2091,7 +2054,7 @@ gsk_transform_node_deserialize (GVariant *variant, &mat[12], &mat[13], &mat[14], &mat[15], &child_type, &child_variant); - child = gsk_render_node_deserialize_node (child_type, child_variant, error); + child = gsk_render_node_deserialize_node (tree, child_type, child_variant, error); g_variant_unref (child_variant); if (child == NULL) @@ -2105,7 +2068,7 @@ gsk_transform_node_deserialize (GVariant *variant, mat[12], mat[13], mat[14], mat[15] }); - result = gsk_transform_node_new (child, &transform); + result = gsk_transform_node_new (tree, child, &transform); gsk_render_node_unref (child); @@ -2116,7 +2079,6 @@ static const GskRenderNodeClass GSK_TRANSFORM_NODE_CLASS = { GSK_TRANSFORM_NODE, sizeof (GskTransformNode), "GskTransformNode", - gsk_transform_node_finalize, gsk_transform_node_draw, gsk_transform_node_serialize, gsk_transform_node_deserialize @@ -2135,7 +2097,8 @@ static const GskRenderNodeClass GSK_TRANSFORM_NODE_CLASS = { * Since: 3.90 */ GskRenderNode * -gsk_transform_node_new (GskRenderNode *child, +gsk_transform_node_new (GskRenderTree *tree, + GskRenderNode *child, const graphene_matrix_t *transform) { GskTransformNode *self; @@ -2143,9 +2106,9 @@ gsk_transform_node_new (GskRenderNode *child, g_return_val_if_fail (GSK_IS_RENDER_NODE (child), NULL); g_return_val_if_fail (transform != NULL, NULL); - self = (GskTransformNode *) gsk_render_node_new (&GSK_TRANSFORM_NODE_CLASS, 0); + self = (GskTransformNode *) gsk_render_tree_new_node (tree, &GSK_TRANSFORM_NODE_CLASS, 0); - self->child = gsk_render_node_ref (child); + self->child = gsk_render_tree_ref_foreign (tree, child); graphene_matrix_init_from_matrix (&self->transform, transform); graphene_matrix_transform_bounds (&self->transform, @@ -2196,14 +2159,6 @@ struct _GskOpacityNode }; static void -gsk_opacity_node_finalize (GskRenderNode *node) -{ - GskOpacityNode *self = (GskOpacityNode *) node; - - gsk_render_node_unref (self->child); -} - -static void gsk_opacity_node_draw (GskRenderNode *node, cairo_t *cr) { @@ -2240,7 +2195,8 @@ gsk_opacity_node_serialize (GskRenderNode *node) } static GskRenderNode * -gsk_opacity_node_deserialize (GVariant *variant, +gsk_opacity_node_deserialize (GskRenderTree *tree, + GVariant *variant, GError **error) { double opacity; @@ -2255,13 +2211,13 @@ gsk_opacity_node_deserialize (GVariant *variant, &opacity, &child_type, &child_variant); - child = gsk_render_node_deserialize_node (child_type, child_variant, error); + child = gsk_render_node_deserialize_node (tree, child_type, child_variant, error); g_variant_unref (child_variant); if (child == NULL) return NULL; - result = gsk_opacity_node_new (child, opacity); + result = gsk_opacity_node_new (tree, child, opacity); gsk_render_node_unref (child); @@ -2272,7 +2228,6 @@ static const GskRenderNodeClass GSK_OPACITY_NODE_CLASS = { GSK_OPACITY_NODE, sizeof (GskOpacityNode), "GskOpacityNode", - gsk_opacity_node_finalize, gsk_opacity_node_draw, gsk_opacity_node_serialize, gsk_opacity_node_deserialize @@ -2291,16 +2246,17 @@ static const GskRenderNodeClass GSK_OPACITY_NODE_CLASS = { * Since: 3.90 */ GskRenderNode * -gsk_opacity_node_new (GskRenderNode *child, +gsk_opacity_node_new (GskRenderTree *tree, + GskRenderNode *child, double opacity) { GskOpacityNode *self; g_return_val_if_fail (GSK_IS_RENDER_NODE (child), NULL); - self = (GskOpacityNode *) gsk_render_node_new (&GSK_OPACITY_NODE_CLASS, 0); + self = (GskOpacityNode *) gsk_render_tree_new_node (tree, &GSK_OPACITY_NODE_CLASS, 0); - self->child = gsk_render_node_ref (child); + self->child = gsk_render_tree_ref_foreign (tree, child); self->opacity = CLAMP (opacity, 0.0, 1.0); graphene_rect_init_from_rect (&self->render_node.bounds, &child->bounds); @@ -2349,13 +2305,6 @@ struct _GskColorMatrixNode graphene_vec4_t color_offset; }; -static void -gsk_color_matrix_node_finalize (GskRenderNode *node) -{ - GskColorMatrixNode *self = (GskColorMatrixNode *) node; - - gsk_render_node_unref (self->child); -} static void gsk_color_matrix_node_draw (GskRenderNode *node, @@ -2461,7 +2410,8 @@ gsk_color_matrix_node_serialize (GskRenderNode *node) } static GskRenderNode * -gsk_color_matrix_node_deserialize (GVariant *variant, +gsk_color_matrix_node_deserialize (GskRenderTree *tree, + GVariant *variant, GError **error) { double mat[16], vec[4]; @@ -2482,7 +2432,7 @@ gsk_color_matrix_node_deserialize (GVariant *variant, &vec[0], &vec[1], &vec[2], &vec[3], &child_type, &child_variant); - child = gsk_render_node_deserialize_node (child_type, child_variant, error); + child = gsk_render_node_deserialize_node (tree, child_type, child_variant, error); g_variant_unref (child_variant); if (child == NULL) @@ -2497,7 +2447,7 @@ gsk_color_matrix_node_deserialize (GVariant *variant, }); graphene_vec4_init (&offset, vec[0], vec[1], vec[2], vec[3]); - result = gsk_color_matrix_node_new (child, &matrix, &offset); + result = gsk_color_matrix_node_new (tree, child, &matrix, &offset); gsk_render_node_unref (child); @@ -2508,7 +2458,6 @@ static const GskRenderNodeClass GSK_COLOR_MATRIX_NODE_CLASS = { GSK_COLOR_MATRIX_NODE, sizeof (GskColorMatrixNode), "GskColorMatrixNode", - gsk_color_matrix_node_finalize, gsk_color_matrix_node_draw, gsk_color_matrix_node_serialize, gsk_color_matrix_node_deserialize @@ -2532,7 +2481,8 @@ static const GskRenderNodeClass GSK_COLOR_MATRIX_NODE_CLASS = { * Since: 3.90 */ GskRenderNode * -gsk_color_matrix_node_new (GskRenderNode *child, +gsk_color_matrix_node_new (GskRenderTree *tree, + GskRenderNode *child, const graphene_matrix_t *color_matrix, const graphene_vec4_t *color_offset) { @@ -2540,9 +2490,9 @@ gsk_color_matrix_node_new (GskRenderNode *child, g_return_val_if_fail (GSK_IS_RENDER_NODE (child), NULL); - self = (GskColorMatrixNode *) gsk_render_node_new (&GSK_COLOR_MATRIX_NODE_CLASS, 0); + self = (GskColorMatrixNode *) gsk_render_tree_new_node (tree, &GSK_COLOR_MATRIX_NODE_CLASS, 0); - self->child = gsk_render_node_ref (child); + self->child = gsk_render_tree_ref_foreign (tree, child); graphene_matrix_init_from_matrix (&self->color_matrix, color_matrix); graphene_vec4_init_from_vec4 (&self->color_offset, color_offset); @@ -2594,14 +2544,6 @@ struct _GskRepeatNode }; static void -gsk_repeat_node_finalize (GskRenderNode *node) -{ - GskRepeatNode *self = (GskRepeatNode *) node; - - gsk_render_node_unref (self->child); -} - -static void gsk_repeat_node_draw (GskRenderNode *node, cairo_t *cr) { @@ -2655,7 +2597,8 @@ gsk_repeat_node_serialize (GskRenderNode *node) } static GskRenderNode * -gsk_repeat_node_deserialize (GVariant *variant, +gsk_repeat_node_deserialize (GskRenderTree *tree, + GVariant *variant, GError **error) { double x, y, width, height, child_x, child_y, child_width, child_height; @@ -2671,13 +2614,14 @@ gsk_repeat_node_deserialize (GVariant *variant, &child_x, &child_y, &child_width, &child_height, &child_type, &child_variant); - child = gsk_render_node_deserialize_node (child_type, child_variant, error); + child = gsk_render_node_deserialize_node (tree, child_type, child_variant, error); g_variant_unref (child_variant); if (child == NULL) return NULL; - result = gsk_repeat_node_new (&GRAPHENE_RECT_INIT (x, y, width, height), + result = gsk_repeat_node_new (tree, + &GRAPHENE_RECT_INIT (x, y, width, height), child, &GRAPHENE_RECT_INIT (child_x, child_y, child_width, child_height)); @@ -2690,7 +2634,6 @@ static const GskRenderNodeClass GSK_REPEAT_NODE_CLASS = { GSK_REPEAT_NODE, sizeof (GskRepeatNode), "GskRepeatNode", - gsk_repeat_node_finalize, gsk_repeat_node_draw, gsk_repeat_node_serialize, gsk_repeat_node_deserialize @@ -2711,7 +2654,8 @@ static const GskRenderNodeClass GSK_REPEAT_NODE_CLASS = { * Since: 3.90 */ GskRenderNode * -gsk_repeat_node_new (const graphene_rect_t *bounds, +gsk_repeat_node_new (GskRenderTree *tree, + const graphene_rect_t *bounds, GskRenderNode *child, const graphene_rect_t *child_bounds) { @@ -2720,10 +2664,10 @@ gsk_repeat_node_new (const graphene_rect_t *bounds, g_return_val_if_fail (bounds != NULL, NULL); g_return_val_if_fail (GSK_IS_RENDER_NODE (child), NULL); - self = (GskRepeatNode *) gsk_render_node_new (&GSK_REPEAT_NODE_CLASS, 0); + self = (GskRepeatNode *) gsk_render_tree_new_node (tree, &GSK_REPEAT_NODE_CLASS, 0); graphene_rect_init_from_rect (&self->render_node.bounds, bounds); - self->child = gsk_render_node_ref (child); + self->child = gsk_render_tree_ref_foreign (tree, child); if (child_bounds) graphene_rect_init_from_rect (&self->child_bounds, child_bounds); else @@ -2765,14 +2709,6 @@ struct _GskClipNode }; static void -gsk_clip_node_finalize (GskRenderNode *node) -{ - GskClipNode *self = (GskClipNode *) node; - - gsk_render_node_unref (self->child); -} - -static void gsk_clip_node_draw (GskRenderNode *node, cairo_t *cr) { @@ -2805,7 +2741,8 @@ gsk_clip_node_serialize (GskRenderNode *node) } static GskRenderNode * -gsk_clip_node_deserialize (GVariant *variant, +gsk_clip_node_deserialize (GskRenderTree *tree, + GVariant *variant, GError **error) { double x, y, width, height; @@ -2820,13 +2757,13 @@ gsk_clip_node_deserialize (GVariant *variant, &x, &y, &width, &height, &child_type, &child_variant); - child = gsk_render_node_deserialize_node (child_type, child_variant, error); + child = gsk_render_node_deserialize_node (tree, child_type, child_variant, error); g_variant_unref (child_variant); if (child == NULL) return NULL; - result = gsk_clip_node_new (child, &GRAPHENE_RECT_INIT(x, y, width, height)); + result = gsk_clip_node_new (tree, child, &GRAPHENE_RECT_INIT(x, y, width, height)); gsk_render_node_unref (child); @@ -2837,7 +2774,6 @@ static const GskRenderNodeClass GSK_CLIP_NODE_CLASS = { GSK_CLIP_NODE, sizeof (GskClipNode), "GskClipNode", - gsk_clip_node_finalize, gsk_clip_node_draw, gsk_clip_node_serialize, gsk_clip_node_deserialize @@ -2856,7 +2792,8 @@ static const GskRenderNodeClass GSK_CLIP_NODE_CLASS = { * Since: 3.90 */ GskRenderNode * -gsk_clip_node_new (GskRenderNode *child, +gsk_clip_node_new (GskRenderTree *tree, + GskRenderNode *child, const graphene_rect_t *clip) { GskClipNode *self; @@ -2864,9 +2801,9 @@ gsk_clip_node_new (GskRenderNode *child, g_return_val_if_fail (GSK_IS_RENDER_NODE (child), NULL); g_return_val_if_fail (clip != NULL, NULL); - self = (GskClipNode *) gsk_render_node_new (&GSK_CLIP_NODE_CLASS, 0); + self = (GskClipNode *) gsk_render_tree_new_node (tree, &GSK_CLIP_NODE_CLASS, 0); - self->child = gsk_render_node_ref (child); + self->child = gsk_render_tree_ref_foreign (tree, child); graphene_rect_normalize_r (clip, &self->clip); graphene_rect_intersection (&self->clip, &child->bounds, &self->render_node.bounds); @@ -2915,14 +2852,6 @@ struct _GskRoundedClipNode }; static void -gsk_rounded_clip_node_finalize (GskRenderNode *node) -{ - GskRoundedClipNode *self = (GskRoundedClipNode *) node; - - gsk_render_node_unref (self->child); -} - -static void gsk_rounded_clip_node_draw (GskRenderNode *node, cairo_t *cr) { @@ -2957,7 +2886,8 @@ gsk_rounded_clip_node_serialize (GskRenderNode *node) } static GskRenderNode * -gsk_rounded_clip_node_deserialize (GVariant *variant, +gsk_rounded_clip_node_deserialize (GskRenderTree *tree, + GVariant *variant, GError **error) { double doutline[12]; @@ -2974,13 +2904,13 @@ gsk_rounded_clip_node_deserialize (GVariant *variant, &doutline[8], &doutline[9], &doutline[10], &doutline[11], &child_type, &child_variant); - child = gsk_render_node_deserialize_node (child_type, child_variant, error); + child = gsk_render_node_deserialize_node (tree, child_type, child_variant, error); g_variant_unref (child_variant); if (child == NULL) return NULL; - result = gsk_rounded_clip_node_new (child, + result = gsk_rounded_clip_node_new (tree, child, &(GskRoundedRect) { .bounds = GRAPHENE_RECT_INIT(doutline[0], doutline[1], doutline[2], doutline[3]), .corner = { @@ -3000,7 +2930,6 @@ static const GskRenderNodeClass GSK_ROUNDED_CLIP_NODE_CLASS = { GSK_ROUNDED_CLIP_NODE, sizeof (GskRoundedClipNode), "GskRoundedClipNode", - gsk_rounded_clip_node_finalize, gsk_rounded_clip_node_draw, gsk_rounded_clip_node_serialize, gsk_rounded_clip_node_deserialize @@ -3019,7 +2948,8 @@ static const GskRenderNodeClass GSK_ROUNDED_CLIP_NODE_CLASS = { * Since: 3.90 */ GskRenderNode * -gsk_rounded_clip_node_new (GskRenderNode *child, +gsk_rounded_clip_node_new (GskRenderTree *tree, + GskRenderNode *child, const GskRoundedRect *clip) { GskRoundedClipNode *self; @@ -3027,9 +2957,9 @@ gsk_rounded_clip_node_new (GskRenderNode *child, g_return_val_if_fail (GSK_IS_RENDER_NODE (child), NULL); g_return_val_if_fail (clip != NULL, NULL); - self = (GskRoundedClipNode *) gsk_render_node_new (&GSK_ROUNDED_CLIP_NODE_CLASS, 0); + self = (GskRoundedClipNode *) gsk_render_tree_new_node (tree, &GSK_ROUNDED_CLIP_NODE_CLASS, 0); - self->child = gsk_render_node_ref (child); + self->child = gsk_render_tree_ref_foreign (tree, child); gsk_rounded_rect_init_copy (&self->clip, clip); graphene_rect_intersection (&self->clip.bounds, &child->bounds, &self->render_node.bounds); @@ -3080,14 +3010,6 @@ struct _GskShadowNode }; static void -gsk_shadow_node_finalize (GskRenderNode *node) -{ - GskShadowNode *self = (GskShadowNode *) node; - - gsk_render_node_unref (self->child); -} - -static void gsk_shadow_node_draw (GskRenderNode *node, cairo_t *cr) { @@ -3174,7 +3096,8 @@ gsk_shadow_node_serialize (GskRenderNode *node) } static GskRenderNode * -gsk_shadow_node_deserialize (GVariant *variant, +gsk_shadow_node_deserialize (GskRenderTree *tree, + GVariant *variant, GError **error) { gsize n_shadows; @@ -3190,7 +3113,7 @@ gsk_shadow_node_deserialize (GVariant *variant, g_variant_get (variant, GSK_SHADOW_NODE_VARIANT_TYPE, &child_type, &child_variant, &iter); - child = gsk_render_node_deserialize_node (child_type, child_variant, error); + child = gsk_render_node_deserialize_node (tree, child_type, child_variant, error); g_variant_unref (child_variant); if (child == NULL) @@ -3214,7 +3137,7 @@ gsk_shadow_node_deserialize (GVariant *variant, } g_variant_iter_free (iter); - result = gsk_shadow_node_new (child, shadows, n_shadows); + result = gsk_shadow_node_new (tree, child, shadows, n_shadows); gsk_render_node_unref (child); @@ -3225,7 +3148,6 @@ static const GskRenderNodeClass GSK_SHADOW_NODE_CLASS = { GSK_SHADOW_NODE, sizeof (GskShadowNode), "GskShadowNode", - gsk_shadow_node_finalize, gsk_shadow_node_draw, gsk_shadow_node_serialize, gsk_shadow_node_deserialize @@ -3245,7 +3167,8 @@ static const GskRenderNodeClass GSK_SHADOW_NODE_CLASS = { * Since: 3.90 */ GskRenderNode * -gsk_shadow_node_new (GskRenderNode *child, +gsk_shadow_node_new (GskRenderTree *tree, + GskRenderNode *child, const GskShadow *shadows, gsize n_shadows) { @@ -3255,9 +3178,9 @@ gsk_shadow_node_new (GskRenderNode *child, g_return_val_if_fail (shadows != NULL, NULL); g_return_val_if_fail (n_shadows > 0, NULL); - self = (GskShadowNode *) gsk_render_node_new (&GSK_SHADOW_NODE_CLASS, n_shadows * sizeof (GskShadow)); + self = (GskShadowNode *) gsk_render_tree_new_node (tree, &GSK_SHADOW_NODE_CLASS, n_shadows * sizeof (GskShadow)); - self->child = gsk_render_node_ref (child); + self->child = gsk_render_tree_ref_foreign (tree, child); memcpy (&self->shadows, shadows, n_shadows * sizeof (GskShadow)); self->n_shadows = n_shadows; @@ -3354,15 +3277,6 @@ gsk_blend_mode_to_cairo_operator (GskBlendMode blend_mode) } static void -gsk_blend_node_finalize (GskRenderNode *node) -{ - GskBlendNode *self = (GskBlendNode *) node; - - gsk_render_node_unref (self->bottom); - gsk_render_node_unref (self->top); -} - -static void gsk_blend_node_draw (GskRenderNode *node, cairo_t *cr) { @@ -3398,7 +3312,8 @@ gsk_blend_node_serialize (GskRenderNode *node) } static GskRenderNode * -gsk_blend_node_deserialize (GVariant *variant, +gsk_blend_node_deserialize (GskRenderTree *tree, + GVariant *variant, GError **error) { guint32 bottom_child_type, top_child_type, blend_mode; @@ -3413,7 +3328,7 @@ gsk_blend_node_deserialize (GVariant *variant, &top_child_type, &top_child_variant, &blend_mode); - bottom_child = gsk_render_node_deserialize_node (bottom_child_type, bottom_child_variant, error); + bottom_child = gsk_render_node_deserialize_node (tree, bottom_child_type, bottom_child_variant, error); g_variant_unref (bottom_child_variant); if (bottom_child == NULL) { @@ -3421,7 +3336,7 @@ gsk_blend_node_deserialize (GVariant *variant, return NULL; } - top_child = gsk_render_node_deserialize_node (top_child_type, top_child_variant, error); + top_child = gsk_render_node_deserialize_node (tree, top_child_type, top_child_variant, error); g_variant_unref (top_child_variant); if (top_child == NULL) { @@ -3429,7 +3344,7 @@ gsk_blend_node_deserialize (GVariant *variant, return NULL; } - result = gsk_blend_node_new (bottom_child, top_child, blend_mode); + result = gsk_blend_node_new (tree, bottom_child, top_child, blend_mode); gsk_render_node_unref (top_child); gsk_render_node_unref (bottom_child); @@ -3441,7 +3356,6 @@ static const GskRenderNodeClass GSK_BLEND_NODE_CLASS = { GSK_BLEND_NODE, sizeof (GskBlendNode), "GskBlendNode", - gsk_blend_node_finalize, gsk_blend_node_draw, gsk_blend_node_serialize, gsk_blend_node_deserialize @@ -3461,7 +3375,8 @@ static const GskRenderNodeClass GSK_BLEND_NODE_CLASS = { * Since: 3.90 */ GskRenderNode * -gsk_blend_node_new (GskRenderNode *bottom, +gsk_blend_node_new (GskRenderTree *tree, + GskRenderNode *bottom, GskRenderNode *top, GskBlendMode blend_mode) { @@ -3470,10 +3385,10 @@ gsk_blend_node_new (GskRenderNode *bottom, g_return_val_if_fail (GSK_IS_RENDER_NODE (bottom), NULL); g_return_val_if_fail (GSK_IS_RENDER_NODE (top), NULL); - self = (GskBlendNode *) gsk_render_node_new (&GSK_BLEND_NODE_CLASS, 0); + self = (GskBlendNode *) gsk_render_tree_new_node (tree, &GSK_BLEND_NODE_CLASS, 0); - self->bottom = gsk_render_node_ref (bottom); - self->top = gsk_render_node_ref (top); + self->bottom = gsk_render_tree_ref_foreign (tree, bottom); + self->top = gsk_render_tree_ref_foreign (tree, top); self->blend_mode = blend_mode; graphene_rect_union (&bottom->bounds, &top->bounds, &self->render_node.bounds); @@ -3525,15 +3440,6 @@ struct _GskCrossFadeNode }; static void -gsk_cross_fade_node_finalize (GskRenderNode *node) -{ - GskCrossFadeNode *self = (GskCrossFadeNode *) node; - - gsk_render_node_unref (self->start); - gsk_render_node_unref (self->end); -} - -static void gsk_cross_fade_node_draw (GskRenderNode *node, cairo_t *cr) { @@ -3569,7 +3475,8 @@ gsk_cross_fade_node_serialize (GskRenderNode *node) } static GskRenderNode * -gsk_cross_fade_node_deserialize (GVariant *variant, +gsk_cross_fade_node_deserialize (GskRenderTree *tree, + GVariant *variant, GError **error) { guint32 start_child_type, end_child_type; @@ -3585,7 +3492,7 @@ gsk_cross_fade_node_deserialize (GVariant *variant, &end_child_type, &end_child_variant, &progress); - start_child = gsk_render_node_deserialize_node (start_child_type, start_child_variant, error); + start_child = gsk_render_node_deserialize_node (tree, start_child_type, start_child_variant, error); g_variant_unref (start_child_variant); if (start_child == NULL) { @@ -3593,7 +3500,7 @@ gsk_cross_fade_node_deserialize (GVariant *variant, return NULL; } - end_child = gsk_render_node_deserialize_node (end_child_type, end_child_variant, error); + end_child = gsk_render_node_deserialize_node (tree, end_child_type, end_child_variant, error); g_variant_unref (end_child_variant); if (end_child == NULL) { @@ -3601,7 +3508,7 @@ gsk_cross_fade_node_deserialize (GVariant *variant, return NULL; } - result = gsk_cross_fade_node_new (start_child, end_child, progress); + result = gsk_cross_fade_node_new (tree, start_child, end_child, progress); gsk_render_node_unref (end_child); gsk_render_node_unref (start_child); @@ -3613,7 +3520,6 @@ static const GskRenderNodeClass GSK_CROSS_FADE_NODE_CLASS = { GSK_CROSS_FADE_NODE, sizeof (GskCrossFadeNode), "GskCrossFadeNode", - gsk_cross_fade_node_finalize, gsk_cross_fade_node_draw, gsk_cross_fade_node_serialize, gsk_cross_fade_node_deserialize @@ -3633,7 +3539,8 @@ static const GskRenderNodeClass GSK_CROSS_FADE_NODE_CLASS = { * Since: 3.90 */ GskRenderNode * -gsk_cross_fade_node_new (GskRenderNode *start, +gsk_cross_fade_node_new (GskRenderTree *tree, + GskRenderNode *start, GskRenderNode *end, double progress) { @@ -3642,10 +3549,10 @@ gsk_cross_fade_node_new (GskRenderNode *start, g_return_val_if_fail (GSK_IS_RENDER_NODE (start), NULL); g_return_val_if_fail (GSK_IS_RENDER_NODE (end), NULL); - self = (GskCrossFadeNode *) gsk_render_node_new (&GSK_CROSS_FADE_NODE_CLASS, 0); + self = (GskCrossFadeNode *) gsk_render_tree_new_node (tree, &GSK_CROSS_FADE_NODE_CLASS, 0); - self->start = gsk_render_node_ref (start); - self->end = gsk_render_node_ref (end); + self->start = gsk_render_tree_ref_foreign (tree, start); + self->end = gsk_render_tree_ref_foreign (tree, end); self->progress = CLAMP (progress, 0.0, 1.0); graphene_rect_union (&start->bounds, &end->bounds, &self->render_node.bounds); @@ -3704,7 +3611,8 @@ static const GskRenderNodeClass *klasses[] = { }; GskRenderNode * -gsk_render_node_deserialize_node (GskRenderNodeType type, +gsk_render_node_deserialize_node (GskRenderTree *tree, + GskRenderNodeType type, GVariant *variant, GError **error) { @@ -3723,7 +3631,7 @@ gsk_render_node_deserialize_node (GskRenderNodeType type, return NULL; } - result = klass->deserialize (variant, error); + result = klass->deserialize (tree, variant, error); return result; } diff --git a/gsk/gskrendernodeprivate.h b/gsk/gskrendernodeprivate.h index 938c948002..ebdfb53cde 100644 --- a/gsk/gskrendernodeprivate.h +++ b/gsk/gskrendernodeprivate.h @@ -13,8 +13,7 @@ typedef struct _GskRenderNodeClass GskRenderNodeClass; struct _GskRenderNode { const GskRenderNodeClass *node_class; - - volatile int ref_count; + GskRenderTree *tree; /* Use for debugging */ char *name; @@ -31,19 +30,23 @@ struct _GskRenderNodeClass GskRenderNodeType node_type; gsize struct_size; const char *type_name; - void (* finalize) (GskRenderNode *node); void (* draw) (GskRenderNode *node, cairo_t *cr); GVariant * (* serialize) (GskRenderNode *node); - GskRenderNode * (* deserialize) (GVariant *variant, + GskRenderNode * (* deserialize) (GskRenderTree *tree, + GVariant *variant, GError **error); }; -GskRenderNode *gsk_render_node_new (const GskRenderNodeClass *node_class, gsize extra_size); +GskRenderNode *gsk_render_tree_new_node (GskRenderTree *tree, const GskRenderNodeClass *node_class, gsize extra_size); +gpointer gsk_render_tree_allocate (GskRenderTree *self, gsize n_bytes, gsize align_size); +void gsk_render_tree_add_cleanup (GskRenderTree *tree, GDestroyNotify notify, gpointer data); +GskRenderNode *gsk_render_tree_ref_foreign (GskRenderTree *tree, GskRenderNode *node); GVariant * gsk_render_node_serialize_node (GskRenderNode *node); -GskRenderNode * gsk_render_node_deserialize_node (GskRenderNodeType type, GVariant *variant, GError **error); +GskRenderNode * gsk_render_node_deserialize_node (GskRenderTree *tree, GskRenderNodeType type, GVariant *variant, GError **error); +GskRenderTree *gsk_render_node_get_tree (GskRenderNode *self); double gsk_opacity_node_get_opacity (GskRenderNode *node); GskRenderNode * gsk_color_matrix_node_get_child (GskRenderNode *node); @@ -62,7 +65,7 @@ const GskRoundedRect * gsk_border_node_peek_outline (GskRenderNode *node); float gsk_border_node_get_width (GskRenderNode *node, guint i); const GdkRGBA * gsk_border_node_peek_color (GskRenderNode *node, guint i); -GskRenderNode *gsk_cairo_node_new_for_surface (const graphene_rect_t *bounds, cairo_surface_t *surface); +GskRenderNode *gsk_cairo_node_new_for_surface (GskRenderTree *tree, const graphene_rect_t *bounds, cairo_surface_t *surface); cairo_surface_t *gsk_cairo_node_get_surface (GskRenderNode *node); GskTexture *gsk_texture_node_get_texture (GskRenderNode *node); diff --git a/gtk/gtkcssimagecrossfade.c b/gtk/gtkcssimagecrossfade.c index 2b9aab1271..ca4829bf90 100644 --- a/gtk/gtkcssimagecrossfade.c +++ b/gtk/gtkcssimagecrossfade.c @@ -139,29 +139,23 @@ gtk_css_image_cross_fade_snapshot (GtkCssImage *image, if (start_node && end_node) { - GskRenderNode *node = gsk_cross_fade_node_new (start_node, end_node, cross_fade->progress); + GskRenderNode *node = gsk_cross_fade_node_new (gtk_snapshot_get_tree (snapshot), start_node, end_node, cross_fade->progress); if (snapshot->record_names) gsk_render_node_set_name (node, "CrossFade"); gtk_snapshot_append_node (snapshot, node); - - gsk_render_node_unref (node); - gsk_render_node_unref (start_node); - gsk_render_node_unref (end_node); } else if (start_node) { gtk_snapshot_push_opacity (snapshot, 1.0 - cross_fade->progress, "CrossFadeStart"); gtk_snapshot_append_node (snapshot, start_node); gtk_snapshot_pop_and_append (snapshot); - gsk_render_node_unref (start_node); } else if (end_node) { gtk_snapshot_push_opacity (snapshot, cross_fade->progress, "CrossFadeEnd"); gtk_snapshot_append_node (snapshot, end_node); gtk_snapshot_pop_and_append (snapshot); - gsk_render_node_unref (end_node); } } } diff --git a/gtk/gtkcssimagelinear.c b/gtk/gtkcssimagelinear.c index 7200c48951..1536205f27 100644 --- a/gtk/gtkcssimagelinear.c +++ b/gtk/gtkcssimagelinear.c @@ -238,6 +238,7 @@ gtk_css_image_linear_snapshot (GtkCssImage *image, if (linear->repeating) { node = gsk_repeating_linear_gradient_node_new ( + gtk_snapshot_get_tree (snapshot), &GRAPHENE_RECT_INIT (off_x, off_y, width, height), &GRAPHENE_POINT_INIT (off_x + width / 2 + x * (start - 0.5), off_y + height / 2 + y * (start - 0.5)), &GRAPHENE_POINT_INIT (off_x + width / 2 + x * (end - 0.5), off_y + height / 2 + y * (end - 0.5)), @@ -247,6 +248,7 @@ gtk_css_image_linear_snapshot (GtkCssImage *image, else { node = gsk_linear_gradient_node_new ( + gtk_snapshot_get_tree (snapshot), &GRAPHENE_RECT_INIT (off_x, off_y, width, height), &GRAPHENE_POINT_INIT (off_x + width / 2 + x * (start - 0.5), off_y + height / 2 + y * (start - 0.5)), &GRAPHENE_POINT_INIT (off_x + width / 2 + x * (end - 0.5), off_y + height / 2 + y * (end - 0.5)), @@ -262,8 +264,6 @@ gtk_css_image_linear_snapshot (GtkCssImage *image, } gtk_snapshot_append_node (snapshot, node); - - gsk_render_node_unref (node); } diff --git a/gtk/gtkcssshadowvalue.c b/gtk/gtkcssshadowvalue.c index ed56504166..ec37300836 100644 --- a/gtk/gtkcssshadowvalue.c +++ b/gtk/gtkcssshadowvalue.c @@ -1051,7 +1051,8 @@ gtk_css_shadow_value_snapshot_outset (const GtkCssValue *shadow, gsk_rounded_rect_init_copy (&outline, border_box); gsk_rounded_rect_offset (&outline, off_x, off_y); - node = gsk_outset_shadow_node_new (&outline, + node = gsk_outset_shadow_node_new (gtk_snapshot_get_tree (snapshot), + &outline, _gtk_css_rgba_value_get_rgba (shadow->color), _gtk_css_number_value_get (shadow->hoffset, 0), _gtk_css_number_value_get (shadow->voffset, 0), @@ -1060,7 +1061,6 @@ gtk_css_shadow_value_snapshot_outset (const GtkCssValue *shadow, if (snapshot->record_names) gsk_render_node_set_name (node, "Outset Shadow"); gtk_snapshot_append_node (snapshot, node); - gsk_render_node_unref (node); } void @@ -1082,7 +1082,8 @@ gtk_css_shadow_value_snapshot_inset (const GtkCssValue *shadow, gsk_rounded_rect_init_copy (&outline, padding_box); gsk_rounded_rect_offset (&outline, off_x, off_y); - node = gsk_inset_shadow_node_new (&outline, + node = gsk_inset_shadow_node_new (gtk_snapshot_get_tree (snapshot), + &outline, _gtk_css_rgba_value_get_rgba (shadow->color), _gtk_css_number_value_get (shadow->hoffset, 0), _gtk_css_number_value_get (shadow->voffset, 0), @@ -1091,6 +1092,5 @@ gtk_css_shadow_value_snapshot_inset (const GtkCssValue *shadow, if (snapshot->record_names) gsk_render_node_set_name (node, "Inset Shadow"); gtk_snapshot_append_node (snapshot, node); - gsk_render_node_unref (node); } diff --git a/gtk/gtkiconview.c b/gtk/gtkiconview.c index 2cbc6802aa..b4315590cb 100644 --- a/gtk/gtkiconview.c +++ b/gtk/gtkiconview.c @@ -7024,6 +7024,8 @@ gtk_icon_view_create_drag_icon (GtkIconView *icon_view, gsk_render_node_draw (node, cr); cairo_destroy (cr); + gsk_render_node_unref (node); + return surface; } } diff --git a/gtk/gtkrenderbackground.c b/gtk/gtkrenderbackground.c index e52d1de3b7..84f2949b69 100644 --- a/gtk/gtkrenderbackground.c +++ b/gtk/gtkrenderbackground.c @@ -676,20 +676,16 @@ gtk_css_style_snapshot_background (GtkCssStyle *style, /* XXX: Is this necessary? Do we need a NULL node? */ if (top == NULL) - top = gsk_container_node_new (NULL, 0); + top = gsk_container_node_new (gtk_snapshot_get_tree (snapshot), NULL, 0); if (bottom == NULL) - bottom = gsk_container_node_new (NULL, 0); + bottom = gsk_container_node_new (gtk_snapshot_get_tree (snapshot), NULL, 0); - blend = gsk_blend_node_new (bottom, top, blend_mode); + blend = gsk_blend_node_new (gtk_snapshot_get_tree (snapshot), bottom, top, blend_mode); if (snapshot->record_names) gsk_render_node_set_name (blend, "BackgroundBlend"); gtk_snapshot_push (snapshot, TRUE, "BackgroundBlendGroup"); gtk_snapshot_append_node (snapshot, blend); - - gsk_render_node_unref (blend); - gsk_render_node_unref (top); - gsk_render_node_unref (bottom); } } diff --git a/gtk/gtkrenderborder.c b/gtk/gtkrenderborder.c index a42f74e42b..1201ab5b82 100644 --- a/gtk/gtkrenderborder.c +++ b/gtk/gtkrenderborder.c @@ -437,11 +437,10 @@ snapshot_frame_fill (GtkSnapshot *snapshot, gsk_rounded_rect_init_copy (&offset_outline, outline); gsk_rounded_rect_offset (&offset_outline, off_x, off_y); - node = gsk_border_node_new (&offset_outline, border_width, colors); + node = gsk_border_node_new (snapshot->tree, &offset_outline, border_width, colors); if (snapshot->record_names) gsk_render_node_set_name (node, "Border"); gtk_snapshot_append_node (snapshot, node); - gsk_render_node_unref (node); } static void diff --git a/gtk/gtksnapshot.c b/gtk/gtksnapshot.c index 08db8c5b63..703a3b01e6 100644 --- a/gtk/gtksnapshot.c +++ b/gtk/gtksnapshot.c @@ -62,11 +62,11 @@ gtk_snapshot_collect_default (GtkSnapshotState *state, } else if (n_nodes == 1) { - node = gsk_render_node_ref (nodes[0]); + node = nodes[0]; } else { - node = gsk_container_node_new (nodes, n_nodes); + node = gsk_container_node_new (state->tree, nodes, n_nodes); if (name) gsk_render_node_set_name (node, name); } @@ -77,6 +77,7 @@ gtk_snapshot_collect_default (GtkSnapshotState *state, static GtkSnapshotState * gtk_snapshot_state_new (GtkSnapshotState *parent, char *name, + GskRenderTree *tree, cairo_region_t *clip, int translate_x, int translate_y, @@ -92,11 +93,12 @@ gtk_snapshot_state_new (GtkSnapshotState *parent, else { state = g_slice_new0 (GtkSnapshotState); - state->nodes = g_ptr_array_new_with_free_func ((GDestroyNotify) gsk_render_node_unref); + state->nodes = g_ptr_array_new (); state->parent = parent; } state->name = name; + state->tree = tree; if (clip) state->clip_region = cairo_region_reference (clip); state->translate_x = translate_x; @@ -137,6 +139,7 @@ gtk_snapshot_init (GtkSnapshot *snapshot, snapshot->state = NULL; snapshot->record_names = record_names; snapshot->renderer = renderer; + snapshot->tree = gsk_render_tree_new (); if (name && record_names) { @@ -151,6 +154,7 @@ gtk_snapshot_init (GtkSnapshot *snapshot, snapshot->state = gtk_snapshot_state_new (NULL, str, + snapshot->tree, (cairo_region_t *) clip, 0, 0, gtk_snapshot_collect_default); @@ -160,7 +164,7 @@ GskRenderNode * gtk_snapshot_finish (GtkSnapshot *snapshot) { GskRenderNode *result; - + result = gtk_snapshot_pop (snapshot); if (snapshot->state != NULL) @@ -168,6 +172,9 @@ gtk_snapshot_finish (GtkSnapshot *snapshot) g_warning ("Too many gtk_snapshot_push() calls."); } + gsk_render_node_ref (result); + g_clear_object (&snapshot->tree); + return result; } @@ -208,6 +215,7 @@ gtk_snapshot_push (GtkSnapshot *snapshot, { snapshot->state = gtk_snapshot_state_new (snapshot->state, str, + snapshot->state->tree, snapshot->state->clip_region, snapshot->state->translate_x, snapshot->state->translate_y, @@ -217,6 +225,7 @@ gtk_snapshot_push (GtkSnapshot *snapshot, { snapshot->state = gtk_snapshot_state_new (snapshot->state, str, + snapshot->state->tree, NULL, 0, 0, gtk_snapshot_collect_default); @@ -235,12 +244,10 @@ gtk_snapshot_collect_transform (GtkSnapshotState *state, if (node == NULL) return NULL; - transform_node = gsk_transform_node_new (node, &state->data.transform.transform); + transform_node = gsk_transform_node_new (state->tree, node, &state->data.transform.transform); if (name) gsk_render_node_set_name (transform_node, name); - gsk_render_node_unref (node); - return transform_node; } @@ -267,6 +274,7 @@ gtk_snapshot_push_transform (GtkSnapshot *snapshot, state = gtk_snapshot_state_new (snapshot->state, str, + snapshot->state->tree, NULL, 0, 0, gtk_snapshot_collect_transform); @@ -295,12 +303,10 @@ gtk_snapshot_collect_opacity (GtkSnapshotState *state, if (node == NULL) return NULL; - opacity_node = gsk_opacity_node_new (node, state->data.opacity.opacity); + opacity_node = gsk_opacity_node_new (state->tree, node, state->data.opacity.opacity); if (name) gsk_render_node_set_name (opacity_node, name); - gsk_render_node_unref (node); - return opacity_node; } @@ -326,6 +332,7 @@ gtk_snapshot_push_opacity (GtkSnapshot *snapshot, state = gtk_snapshot_state_new (snapshot->state, str, + snapshot->state->tree, snapshot->state->clip_region, snapshot->state->translate_x, snapshot->state->translate_y, @@ -346,14 +353,12 @@ gtk_snapshot_collect_color_matrix (GtkSnapshotState *state, if (node == NULL) return NULL; - color_matrix_node = gsk_color_matrix_node_new (node, + color_matrix_node = gsk_color_matrix_node_new (state->tree, node, &state->data.color_matrix.matrix, &state->data.color_matrix.offset); if (name) gsk_render_node_set_name (color_matrix_node, name); - gsk_render_node_unref (node); - return color_matrix_node; } @@ -380,6 +385,7 @@ gtk_snapshot_push_color_matrix (GtkSnapshot *snapshot, state = gtk_snapshot_state_new (snapshot->state, str, + snapshot->state->tree, snapshot->state->clip_region, snapshot->state->translate_x, snapshot->state->translate_y, @@ -414,14 +420,12 @@ gtk_snapshot_collect_repeat (GtkSnapshotState *state, if (node == NULL) return NULL; - repeat_node = gsk_repeat_node_new (bounds, + repeat_node = gsk_repeat_node_new (state->tree, bounds, node, child_bounds->size.width > 0 ? child_bounds : NULL); if (name) gsk_render_node_set_name (repeat_node, name); - gsk_render_node_unref (node); - return repeat_node; } @@ -458,6 +462,7 @@ gtk_snapshot_push_repeat (GtkSnapshot *snapshot, state = gtk_snapshot_state_new (snapshot->state, str, + snapshot->state->tree, clip, snapshot->state->translate_x, snapshot->state->translate_y, @@ -484,12 +489,10 @@ gtk_snapshot_collect_clip (GtkSnapshotState *state, if (node == NULL) return NULL; - clip_node = gsk_clip_node_new (node, &state->data.clip.bounds); + clip_node = gsk_clip_node_new (state->tree, node, &state->data.clip.bounds); if (name) gsk_render_node_set_name (clip_node, name); - gsk_render_node_unref (node); - return clip_node; } @@ -530,6 +533,7 @@ gtk_snapshot_push_clip (GtkSnapshot *snapshot, } state = gtk_snapshot_state_new (snapshot->state, str, + snapshot->state->tree, clip, snapshot->state->translate_x, snapshot->state->translate_y, @@ -554,12 +558,10 @@ gtk_snapshot_collect_rounded_clip (GtkSnapshotState *state, if (node == NULL) return NULL; - clip_node = gsk_rounded_clip_node_new (node, &state->data.rounded_clip.bounds); + clip_node = gsk_rounded_clip_node_new (state->tree, node, &state->data.rounded_clip.bounds); if (name) gsk_render_node_set_name (clip_node, name); - gsk_render_node_unref (node); - return clip_node; } @@ -602,6 +604,7 @@ gtk_snapshot_push_rounded_clip (GtkSnapshot *snapshot, state = gtk_snapshot_state_new (snapshot->state, str, + snapshot->state->tree, clip, snapshot->state->translate_x, snapshot->state->translate_y, @@ -626,11 +629,10 @@ gtk_snapshot_collect_shadow (GtkSnapshotState *state, if (node == NULL) return NULL; - shadow_node = gsk_shadow_node_new (node, state->data.shadow.shadows, state->data.shadow.n_shadows); + shadow_node = gsk_shadow_node_new (state->tree, node, state->data.shadow.shadows, state->data.shadow.n_shadows); if (name) gsk_render_node_set_name (shadow_node, name); - gsk_render_node_unref (node); if (state->data.shadow.shadows != &state->data.shadow.a_shadow) g_free (state->data.shadow.shadows); @@ -661,6 +663,7 @@ gtk_snapshot_push_shadow (GtkSnapshot *snapshot, state = gtk_snapshot_state_new (snapshot->state, str, + snapshot->state->tree, snapshot->state->clip_region, snapshot->state->translate_x, snapshot->state->translate_y, @@ -736,10 +739,7 @@ gtk_snapshot_pop_and_append (GtkSnapshot *snapshot) node = gtk_snapshot_pop (snapshot); if (node) - { - gtk_snapshot_append_node (snapshot, node); - gsk_render_node_unref (node); - } + gtk_snapshot_append_node (snapshot, node); } /** @@ -807,6 +807,12 @@ gtk_snapshot_get_offset (GtkSnapshot *snapshot, *y = snapshot->state->translate_y; } +GskRenderTree * +gtk_snapshot_get_tree (GtkSnapshot *snapshot) +{ + return snapshot->tree; +} + /** * gtk_snapshot_append_node: * @snapshot: a #GtkSnapshot @@ -826,7 +832,7 @@ gtk_snapshot_append_node (GtkSnapshot *snapshot, if (snapshot->state) { - g_ptr_array_add (snapshot->state->nodes, gsk_render_node_ref (node)); + g_ptr_array_add (snapshot->state->nodes, node); } else { @@ -863,7 +869,7 @@ gtk_snapshot_append_cairo_node (GtkSnapshot *snapshot, g_return_val_if_fail (bounds != NULL, NULL); graphene_rect_offset_r (bounds, snapshot->state->translate_x, snapshot->state->translate_y, &real_bounds); - node = gsk_cairo_node_new (&real_bounds); + node = gsk_cairo_node_new (snapshot->tree, &real_bounds); if (name && snapshot->record_names) { @@ -880,7 +886,6 @@ gtk_snapshot_append_cairo_node (GtkSnapshot *snapshot, } gtk_snapshot_append_node (snapshot, node); - gsk_render_node_unref (node); cr = gsk_cairo_node_get_draw_context (node, snapshot->renderer); @@ -915,7 +920,7 @@ gtk_snapshot_append_texture_node (GtkSnapshot *snapshot, g_return_if_fail (bounds != NULL); graphene_rect_offset_r (bounds, snapshot->state->translate_x, snapshot->state->translate_y, &real_bounds); - node = gsk_texture_node_new (texture, &real_bounds); + node = gsk_texture_node_new (snapshot->tree, texture, &real_bounds); if (name && snapshot->record_names) { @@ -932,7 +937,6 @@ gtk_snapshot_append_texture_node (GtkSnapshot *snapshot, } gtk_snapshot_append_node (snapshot, node); - gsk_render_node_unref (node); } /** @@ -963,7 +967,7 @@ gtk_snapshot_append_color_node (GtkSnapshot *snapshot, g_return_if_fail (bounds != NULL); graphene_rect_offset_r (bounds, snapshot->state->translate_x, snapshot->state->translate_y, &real_bounds); - node = gsk_color_node_new (color, &real_bounds); + node = gsk_color_node_new (snapshot->tree, color, &real_bounds); if (name && snapshot->record_names) { @@ -980,7 +984,6 @@ gtk_snapshot_append_color_node (GtkSnapshot *snapshot, } gtk_snapshot_append_node (snapshot, node); - gsk_render_node_unref (node); } /** diff --git a/gtk/gtksnapshot.h b/gtk/gtksnapshot.h index 0b691c3486..6f391444b0 100644 --- a/gtk/gtksnapshot.h +++ b/gtk/gtksnapshot.h @@ -92,6 +92,8 @@ GDK_AVAILABLE_IN_3_90 void gtk_snapshot_get_offset (GtkSnapshot *snapshot, int *x, int *y); +GDK_AVAILABLE_IN_3_90 +GskRenderTree *gtk_snapshot_get_tree (GtkSnapshot *snapshot); GDK_AVAILABLE_IN_3_90 void gtk_snapshot_append_node (GtkSnapshot *snapshot, diff --git a/gtk/gtksnapshotprivate.h b/gtk/gtksnapshotprivate.h index 91d1b66ef6..ea7663ee7e 100644 --- a/gtk/gtksnapshotprivate.h +++ b/gtk/gtksnapshotprivate.h @@ -34,6 +34,7 @@ struct _GtkSnapshotState { GtkSnapshotState *cached_state; /* A cleared state object we can (re)use */ char *name; + GskRenderTree *tree; GPtrArray *nodes; cairo_region_t *clip_region; @@ -74,6 +75,7 @@ struct _GtkSnapshot { GtkSnapshotState *state; gboolean record_names; GskRenderer *renderer; + GskRenderTree *tree; }; void gtk_snapshot_init (GtkSnapshot *state, diff --git a/gtk/gtkstack.c b/gtk/gtkstack.c index d1f4767ed8..dea41c837f 100644 --- a/gtk/gtkstack.c +++ b/gtk/gtkstack.c @@ -1933,12 +1933,11 @@ gtk_stack_snapshot_crossfade (GtkWidget *widget, gtk_snapshot_push_transform (snapshot, &identity, "CrossFadeStart"); gtk_snapshot_append_node (snapshot, priv->last_visible_node); start_node = gtk_snapshot_pop (snapshot); - node = gsk_cross_fade_node_new (start_node, end_node, progress); - gsk_render_node_unref (start_node); + node = gsk_cross_fade_node_new (gtk_snapshot_get_tree (snapshot), start_node, end_node, progress); } else { - node = gsk_opacity_node_new (end_node, 1.0 - progress); + node = gsk_opacity_node_new (gtk_snapshot_get_tree (snapshot), end_node, 1.0 - progress); } if (snapshot->record_names) @@ -1949,9 +1948,6 @@ gtk_stack_snapshot_crossfade (GtkWidget *widget, } gtk_snapshot_append_node (snapshot, node); - - gsk_render_node_unref (node); - gsk_render_node_unref (end_node); } static void |