diff options
-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 |