Compare commits

...

1 Commits

Author SHA1 Message Date
Alexander Larsson
8ecbd85acc gsk: Add GskRenderTree
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.
2017-01-11 16:39:39 +01:00
16 changed files with 420 additions and 373 deletions

View File

@@ -688,38 +688,38 @@ gsk_renderer_render_texture (GskRenderer *renderer,
/** /**
* gsk_renderer_render: * gsk_renderer_render:
* @renderer: a #GskRenderer * @renderer: a #GskRenderer
* @root: a #GskRenderNode * @root_node: a #GskRenderNode
* @context: The drawing context created via gsk_renderer_begin_draw_frame() * @context: The drawing context created via gsk_renderer_begin_draw_frame()
* *
* Renders the scene graph, described by a tree of #GskRenderNode instances, * Renders the scene graph, described by a tree of #GskRenderNode instances,
* using the given #GdkDrawingContext. * 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. * the rendering is in progress.
* *
* Since: 3.90 * Since: 3.90
*/ */
void void
gsk_renderer_render (GskRenderer *renderer, gsk_renderer_render (GskRenderer *renderer,
GskRenderNode *root, GskRenderNode *root_node,
GdkDrawingContext *context) GdkDrawingContext *context)
{ {
GskRendererPrivate *priv = gsk_renderer_get_instance_private (renderer); GskRendererPrivate *priv = gsk_renderer_get_instance_private (renderer);
g_return_if_fail (GSK_IS_RENDERER (renderer)); g_return_if_fail (GSK_IS_RENDERER (renderer));
g_return_if_fail (priv->is_realized); 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 (priv->root_node == NULL);
g_return_if_fail (GDK_IS_DRAWING_CONTEXT (context)); g_return_if_fail (GDK_IS_DRAWING_CONTEXT (context));
g_return_if_fail (context == priv->drawing_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 #ifdef G_ENABLE_DEBUG
gsk_profiler_reset (priv->profiler); gsk_profiler_reset (priv->profiler);
#endif #endif
GSK_RENDERER_GET_CLASS (renderer)->render (renderer, root); GSK_RENDERER_GET_CLASS (renderer)->render (renderer, root_node);
#ifdef G_ENABLE_DEBUG #ifdef G_ENABLE_DEBUG
if (GSK_DEBUG_CHECK (RENDERER)) if (GSK_DEBUG_CHECK (RENDERER))

View File

@@ -75,7 +75,7 @@ GdkDrawingContext * gsk_renderer_begin_draw_frame (GskRenderer
const cairo_region_t *region); const cairo_region_t *region);
GDK_AVAILABLE_IN_3_90 GDK_AVAILABLE_IN_3_90
void gsk_renderer_render (GskRenderer *renderer, void gsk_renderer_render (GskRenderer *renderer,
GskRenderNode *root, GskRenderNode *root_node,
GdkDrawingContext *context); GdkDrawingContext *context);
GDK_AVAILABLE_IN_3_90 GDK_AVAILABLE_IN_3_90
void gsk_renderer_end_draw_frame (GskRenderer *renderer, void gsk_renderer_end_draw_frame (GskRenderer *renderer,

View File

@@ -53,6 +53,113 @@
#include <gobject/gvaluecollector.h> #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) * 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_ref,
gsk_render_node_unref) 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 > /*< private >
* gsk_render_node_new: * gsk_render_tree_new_node:
* @node_class: class structure for this node * @node_class: class structure for this node
* *
* Returns: (transfer full): the newly created #GskRenderNode * Returns: (transfer full): the newly created #GskRenderNode
*/ */
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 != NULL, NULL);
g_return_val_if_fail (node_class->node_type != GSK_NOT_A_RENDER_NODE, 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); node = gsk_render_tree_allocate (self, node_class->struct_size + extra_size, 2*sizeof(gsize));
self->node_class = node_class; node->node_class = node_class;
node->tree = self;
node->min_filter = GSK_SCALING_FILTER_NEAREST;
node->mag_filter = GSK_SCALING_FILTER_NEAREST;
self->ref_count = 1; return node;
}
self->min_filter = GSK_SCALING_FILTER_NEAREST; GskRenderTree *
self->mag_filter = GSK_SCALING_FILTER_NEAREST; gsk_render_node_get_tree (GskRenderNode *self)
{
return self; return self->tree;
} }
/** /**
@@ -108,6 +207,10 @@ gsk_render_node_new (const GskRenderNodeClass *node_class, gsize extra_size)
* @node: a #GskRenderNode * @node: a #GskRenderNode
* *
* Acquires a reference on the given #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 * 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 * GskRenderNode *
gsk_render_node_ref (GskRenderNode *node) gsk_render_node_ref (GskRenderNode *node)
{ {
GskRenderTree *tree;
g_return_val_if_fail (GSK_IS_RENDER_NODE (node), NULL); 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; return node;
} }
@@ -137,10 +243,12 @@ gsk_render_node_ref (GskRenderNode *node)
void void
gsk_render_node_unref (GskRenderNode *node) gsk_render_node_unref (GskRenderNode *node)
{ {
GskRenderTree *tree;
g_return_if_fail (GSK_IS_RENDER_NODE (node)); g_return_if_fail (GSK_IS_RENDER_NODE (node));
if (g_atomic_int_dec_and_test (&node->ref_count)) tree = gsk_render_node_get_tree (node);
gsk_render_node_finalize (node); g_object_unref (tree);
} }
/** /**
@@ -209,10 +317,16 @@ void
gsk_render_node_set_name (GskRenderNode *node, gsk_render_node_set_name (GskRenderNode *node,
const char *name) const char *name)
{ {
GskRenderTree *tree;
char *new_name;
g_return_if_fail (GSK_IS_RENDER_NODE (node)); g_return_if_fail (GSK_IS_RENDER_NODE (node));
g_free (node->name); tree = gsk_render_node_get_tree (node);
node->name = g_strdup (name);
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; guint32 version, node_type;
GVariant *variant, *node_variant; GVariant *variant, *node_variant;
GskRenderNode *node = NULL; GskRenderNode *node = NULL;
GskRenderTree *tree;
variant = g_variant_new_from_bytes (G_VARIANT_TYPE ("(suuv)"), bytes, FALSE); variant = g_variant_new_from_bytes (G_VARIANT_TYPE ("(suuv)"), bytes, FALSE);
@@ -410,7 +525,10 @@ gsk_render_node_deserialize (GBytes *bytes,
goto out; 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: out:
g_free (id_string); g_free (id_string);

View File

@@ -28,12 +28,17 @@
G_BEGIN_DECLS 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_IS_RENDER_NODE(obj) ((obj) != NULL)
#define GSK_SERIALIZATION_ERROR (gsk_serialization_error_quark ()) #define GSK_SERIALIZATION_ERROR (gsk_serialization_error_quark ())
typedef struct _GskRenderTree GskRenderTree;
typedef struct _GskRenderNode GskRenderNode; typedef struct _GskRenderNode GskRenderNode;
typedef struct _GskColorStop GskColorStop; typedef struct _GskColorStop GskColorStop;
typedef struct _GskShadow GskShadow; typedef struct _GskShadow GskShadow;
@@ -53,10 +58,11 @@ struct _GskShadow
}; };
GDK_AVAILABLE_IN_3_90 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 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 GDK_AVAILABLE_IN_3_90
GskRenderNode * gsk_render_node_ref (GskRenderNode *node); 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); GskRenderNodeType gsk_render_node_get_node_type (GskRenderNode *node);
GDK_AVAILABLE_IN_3_90 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); const graphene_rect_t *bounds);
GDK_AVAILABLE_IN_3_90 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); const graphene_rect_t *bounds);
GDK_AVAILABLE_IN_3_90 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 *start,
const graphene_point_t *end, const graphene_point_t *end,
const GskColorStop *color_stops, const GskColorStop *color_stops,
gsize n_color_stops); gsize n_color_stops);
GDK_AVAILABLE_IN_3_90 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 *start,
const graphene_point_t *end, const graphene_point_t *end,
const GskColorStop *color_stops, const GskColorStop *color_stops,
gsize n_color_stops); gsize n_color_stops);
GDK_AVAILABLE_IN_3_90 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 float border_width[4],
const GdkRGBA border_color[4]); const GdkRGBA border_color[4]);
GDK_AVAILABLE_IN_3_90 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, const GdkRGBA *color,
float dx, float dx,
float dy, float dy,
float spread, float spread,
float blur_radius); float blur_radius);
GDK_AVAILABLE_IN_3_90 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, const GdkRGBA *color,
float dx, float dx,
float dy, float dy,
@@ -108,13 +121,15 @@ GskRenderNode * gsk_outset_shadow_node_new (const GskRounde
float blur_radius); float blur_radius);
GDK_AVAILABLE_IN_3_90 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 GDK_AVAILABLE_IN_3_90
cairo_t * gsk_cairo_node_get_draw_context (GskRenderNode *node, cairo_t * gsk_cairo_node_get_draw_context (GskRenderNode *node,
GskRenderer *renderer); GskRenderer *renderer);
GDK_AVAILABLE_IN_3_90 GDK_AVAILABLE_IN_3_90
GskRenderNode * gsk_container_node_new (GskRenderNode **children, GskRenderNode * gsk_container_node_new (GskRenderTree *tree,
GskRenderNode **children,
guint n_children); guint n_children);
GDK_AVAILABLE_IN_3_90 GDK_AVAILABLE_IN_3_90
guint gsk_container_node_get_n_children (GskRenderNode *node); guint gsk_container_node_get_n_children (GskRenderNode *node);
@@ -123,51 +138,60 @@ GskRenderNode * gsk_container_node_get_child (GskRenderNode
guint idx); guint idx);
GDK_AVAILABLE_IN_3_90 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); const graphene_matrix_t *transform);
GDK_AVAILABLE_IN_3_90 GDK_AVAILABLE_IN_3_90
GskRenderNode * gsk_transform_node_get_child (GskRenderNode *node); GskRenderNode * gsk_transform_node_get_child (GskRenderNode *node);
GDK_AVAILABLE_IN_3_90 GDK_AVAILABLE_IN_3_90
GskRenderNode * gsk_opacity_node_new (GskRenderNode *child, GskRenderNode * gsk_opacity_node_new (GskRenderTree *tree,
GskRenderNode *child,
double opacity); double opacity);
GDK_AVAILABLE_IN_3_90 GDK_AVAILABLE_IN_3_90
GskRenderNode * gsk_opacity_node_get_child (GskRenderNode *node); GskRenderNode * gsk_opacity_node_get_child (GskRenderNode *node);
GDK_AVAILABLE_IN_3_90 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_matrix_t *color_matrix,
const graphene_vec4_t *color_offset); const graphene_vec4_t *color_offset);
GDK_AVAILABLE_IN_3_90 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, GskRenderNode *child,
const graphene_rect_t *child_bounds); const graphene_rect_t *child_bounds);
GDK_AVAILABLE_IN_3_90 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); const graphene_rect_t *clip);
GDK_AVAILABLE_IN_3_90 GDK_AVAILABLE_IN_3_90
GskRenderNode * gsk_clip_node_get_child (GskRenderNode *node); GskRenderNode * gsk_clip_node_get_child (GskRenderNode *node);
GDK_AVAILABLE_IN_3_90 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); const GskRoundedRect *clip);
GDK_AVAILABLE_IN_3_90 GDK_AVAILABLE_IN_3_90
GskRenderNode * gsk_rounded_clip_node_get_child (GskRenderNode *node); GskRenderNode * gsk_rounded_clip_node_get_child (GskRenderNode *node);
GDK_AVAILABLE_IN_3_90 GDK_AVAILABLE_IN_3_90
GskRenderNode * gsk_shadow_node_new (GskRenderNode *child, GskRenderNode * gsk_shadow_node_new (GskRenderTree *tree,
GskRenderNode *child,
const GskShadow *shadows, const GskShadow *shadows,
gsize n_shadows); gsize n_shadows);
GDK_AVAILABLE_IN_3_90 GDK_AVAILABLE_IN_3_90
GskRenderNode * gsk_blend_node_new (GskRenderNode *bottom, GskRenderNode * gsk_blend_node_new (GskRenderTree *tree,
GskRenderNode *bottom,
GskRenderNode *top, GskRenderNode *top,
GskBlendMode blend_mode); GskBlendMode blend_mode);
GDK_AVAILABLE_IN_3_90 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, GskRenderNode *end,
double progress); double progress);

File diff suppressed because it is too large Load Diff

View File

@@ -13,8 +13,7 @@ typedef struct _GskRenderNodeClass GskRenderNodeClass;
struct _GskRenderNode struct _GskRenderNode
{ {
const GskRenderNodeClass *node_class; const GskRenderNodeClass *node_class;
GskRenderTree *tree;
volatile int ref_count;
/* Use for debugging */ /* Use for debugging */
char *name; char *name;
@@ -31,19 +30,23 @@ struct _GskRenderNodeClass
GskRenderNodeType node_type; GskRenderNodeType node_type;
gsize struct_size; gsize struct_size;
const char *type_name; const char *type_name;
void (* finalize) (GskRenderNode *node);
void (* draw) (GskRenderNode *node, void (* draw) (GskRenderNode *node,
cairo_t *cr); cairo_t *cr);
GVariant * (* serialize) (GskRenderNode *node); GVariant * (* serialize) (GskRenderNode *node);
GskRenderNode * (* deserialize) (GVariant *variant, GskRenderNode * (* deserialize) (GskRenderTree *tree,
GVariant *variant,
GError **error); 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); 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); double gsk_opacity_node_get_opacity (GskRenderNode *node);
GskRenderNode * gsk_color_matrix_node_get_child (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); float gsk_border_node_get_width (GskRenderNode *node, guint i);
const GdkRGBA * gsk_border_node_peek_color (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); cairo_surface_t *gsk_cairo_node_get_surface (GskRenderNode *node);
GskTexture *gsk_texture_node_get_texture (GskRenderNode *node); GskTexture *gsk_texture_node_get_texture (GskRenderNode *node);

View File

@@ -139,29 +139,23 @@ gtk_css_image_cross_fade_snapshot (GtkCssImage *image,
if (start_node && end_node) 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) if (snapshot->record_names)
gsk_render_node_set_name (node, "CrossFade"); gsk_render_node_set_name (node, "CrossFade");
gtk_snapshot_append_node (snapshot, node); 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) else if (start_node)
{ {
gtk_snapshot_push_opacity (snapshot, 1.0 - cross_fade->progress, "CrossFadeStart"); gtk_snapshot_push_opacity (snapshot, 1.0 - cross_fade->progress, "CrossFadeStart");
gtk_snapshot_append_node (snapshot, start_node); gtk_snapshot_append_node (snapshot, start_node);
gtk_snapshot_pop_and_append (snapshot); gtk_snapshot_pop_and_append (snapshot);
gsk_render_node_unref (start_node);
} }
else if (end_node) else if (end_node)
{ {
gtk_snapshot_push_opacity (snapshot, cross_fade->progress, "CrossFadeEnd"); gtk_snapshot_push_opacity (snapshot, cross_fade->progress, "CrossFadeEnd");
gtk_snapshot_append_node (snapshot, end_node); gtk_snapshot_append_node (snapshot, end_node);
gtk_snapshot_pop_and_append (snapshot); gtk_snapshot_pop_and_append (snapshot);
gsk_render_node_unref (end_node);
} }
} }
} }

View File

@@ -238,6 +238,7 @@ gtk_css_image_linear_snapshot (GtkCssImage *image,
if (linear->repeating) if (linear->repeating)
{ {
node = gsk_repeating_linear_gradient_node_new ( node = gsk_repeating_linear_gradient_node_new (
gtk_snapshot_get_tree (snapshot),
&GRAPHENE_RECT_INIT (off_x, off_y, width, height), &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 * (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)), &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 else
{ {
node = gsk_linear_gradient_node_new ( node = gsk_linear_gradient_node_new (
gtk_snapshot_get_tree (snapshot),
&GRAPHENE_RECT_INIT (off_x, off_y, width, height), &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 * (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)), &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); gtk_snapshot_append_node (snapshot, node);
gsk_render_node_unref (node);
} }

View File

@@ -1051,7 +1051,8 @@ gtk_css_shadow_value_snapshot_outset (const GtkCssValue *shadow,
gsk_rounded_rect_init_copy (&outline, border_box); gsk_rounded_rect_init_copy (&outline, border_box);
gsk_rounded_rect_offset (&outline, off_x, off_y); 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_rgba_value_get_rgba (shadow->color),
_gtk_css_number_value_get (shadow->hoffset, 0), _gtk_css_number_value_get (shadow->hoffset, 0),
_gtk_css_number_value_get (shadow->voffset, 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) if (snapshot->record_names)
gsk_render_node_set_name (node, "Outset Shadow"); gsk_render_node_set_name (node, "Outset Shadow");
gtk_snapshot_append_node (snapshot, node); gtk_snapshot_append_node (snapshot, node);
gsk_render_node_unref (node);
} }
void 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_init_copy (&outline, padding_box);
gsk_rounded_rect_offset (&outline, off_x, off_y); 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_rgba_value_get_rgba (shadow->color),
_gtk_css_number_value_get (shadow->hoffset, 0), _gtk_css_number_value_get (shadow->hoffset, 0),
_gtk_css_number_value_get (shadow->voffset, 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) if (snapshot->record_names)
gsk_render_node_set_name (node, "Inset Shadow"); gsk_render_node_set_name (node, "Inset Shadow");
gtk_snapshot_append_node (snapshot, node); gtk_snapshot_append_node (snapshot, node);
gsk_render_node_unref (node);
} }

View File

@@ -7024,6 +7024,8 @@ gtk_icon_view_create_drag_icon (GtkIconView *icon_view,
gsk_render_node_draw (node, cr); gsk_render_node_draw (node, cr);
cairo_destroy (cr); cairo_destroy (cr);
gsk_render_node_unref (node);
return surface; return surface;
} }
} }

View File

@@ -676,20 +676,16 @@ gtk_css_style_snapshot_background (GtkCssStyle *style,
/* XXX: Is this necessary? Do we need a NULL node? */ /* XXX: Is this necessary? Do we need a NULL node? */
if (top == NULL) 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) 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) if (snapshot->record_names)
gsk_render_node_set_name (blend, "BackgroundBlend"); gsk_render_node_set_name (blend, "BackgroundBlend");
gtk_snapshot_push (snapshot, TRUE, "BackgroundBlendGroup"); gtk_snapshot_push (snapshot, TRUE, "BackgroundBlendGroup");
gtk_snapshot_append_node (snapshot, blend); gtk_snapshot_append_node (snapshot, blend);
gsk_render_node_unref (blend);
gsk_render_node_unref (top);
gsk_render_node_unref (bottom);
} }
} }

View File

@@ -437,11 +437,10 @@ snapshot_frame_fill (GtkSnapshot *snapshot,
gsk_rounded_rect_init_copy (&offset_outline, outline); gsk_rounded_rect_init_copy (&offset_outline, outline);
gsk_rounded_rect_offset (&offset_outline, off_x, off_y); 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) if (snapshot->record_names)
gsk_render_node_set_name (node, "Border"); gsk_render_node_set_name (node, "Border");
gtk_snapshot_append_node (snapshot, node); gtk_snapshot_append_node (snapshot, node);
gsk_render_node_unref (node);
} }
static void static void

View File

@@ -62,11 +62,11 @@ gtk_snapshot_collect_default (GtkSnapshotState *state,
} }
else if (n_nodes == 1) else if (n_nodes == 1)
{ {
node = gsk_render_node_ref (nodes[0]); node = nodes[0];
} }
else else
{ {
node = gsk_container_node_new (nodes, n_nodes); node = gsk_container_node_new (state->tree, nodes, n_nodes);
if (name) if (name)
gsk_render_node_set_name (node, name); gsk_render_node_set_name (node, name);
} }
@@ -77,6 +77,7 @@ gtk_snapshot_collect_default (GtkSnapshotState *state,
static GtkSnapshotState * static GtkSnapshotState *
gtk_snapshot_state_new (GtkSnapshotState *parent, gtk_snapshot_state_new (GtkSnapshotState *parent,
char *name, char *name,
GskRenderTree *tree,
cairo_region_t *clip, cairo_region_t *clip,
int translate_x, int translate_x,
int translate_y, int translate_y,
@@ -92,11 +93,12 @@ gtk_snapshot_state_new (GtkSnapshotState *parent,
else else
{ {
state = g_slice_new0 (GtkSnapshotState); 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->parent = parent;
} }
state->name = name; state->name = name;
state->tree = tree;
if (clip) if (clip)
state->clip_region = cairo_region_reference (clip); state->clip_region = cairo_region_reference (clip);
state->translate_x = translate_x; state->translate_x = translate_x;
@@ -137,6 +139,7 @@ gtk_snapshot_init (GtkSnapshot *snapshot,
snapshot->state = NULL; snapshot->state = NULL;
snapshot->record_names = record_names; snapshot->record_names = record_names;
snapshot->renderer = renderer; snapshot->renderer = renderer;
snapshot->tree = gsk_render_tree_new ();
if (name && record_names) if (name && record_names)
{ {
@@ -151,6 +154,7 @@ gtk_snapshot_init (GtkSnapshot *snapshot,
snapshot->state = gtk_snapshot_state_new (NULL, snapshot->state = gtk_snapshot_state_new (NULL,
str, str,
snapshot->tree,
(cairo_region_t *) clip, (cairo_region_t *) clip,
0, 0, 0, 0,
gtk_snapshot_collect_default); gtk_snapshot_collect_default);
@@ -168,6 +172,9 @@ gtk_snapshot_finish (GtkSnapshot *snapshot)
g_warning ("Too many gtk_snapshot_push() calls."); g_warning ("Too many gtk_snapshot_push() calls.");
} }
gsk_render_node_ref (result);
g_clear_object (&snapshot->tree);
return result; return result;
} }
@@ -208,6 +215,7 @@ gtk_snapshot_push (GtkSnapshot *snapshot,
{ {
snapshot->state = gtk_snapshot_state_new (snapshot->state, snapshot->state = gtk_snapshot_state_new (snapshot->state,
str, str,
snapshot->state->tree,
snapshot->state->clip_region, snapshot->state->clip_region,
snapshot->state->translate_x, snapshot->state->translate_x,
snapshot->state->translate_y, snapshot->state->translate_y,
@@ -217,6 +225,7 @@ gtk_snapshot_push (GtkSnapshot *snapshot,
{ {
snapshot->state = gtk_snapshot_state_new (snapshot->state, snapshot->state = gtk_snapshot_state_new (snapshot->state,
str, str,
snapshot->state->tree,
NULL, NULL,
0, 0, 0, 0,
gtk_snapshot_collect_default); gtk_snapshot_collect_default);
@@ -235,12 +244,10 @@ gtk_snapshot_collect_transform (GtkSnapshotState *state,
if (node == NULL) if (node == NULL)
return 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) if (name)
gsk_render_node_set_name (transform_node, name); gsk_render_node_set_name (transform_node, name);
gsk_render_node_unref (node);
return transform_node; return transform_node;
} }
@@ -267,6 +274,7 @@ gtk_snapshot_push_transform (GtkSnapshot *snapshot,
state = gtk_snapshot_state_new (snapshot->state, state = gtk_snapshot_state_new (snapshot->state,
str, str,
snapshot->state->tree,
NULL, NULL,
0, 0, 0, 0,
gtk_snapshot_collect_transform); gtk_snapshot_collect_transform);
@@ -295,12 +303,10 @@ gtk_snapshot_collect_opacity (GtkSnapshotState *state,
if (node == NULL) if (node == NULL)
return 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) if (name)
gsk_render_node_set_name (opacity_node, name); gsk_render_node_set_name (opacity_node, name);
gsk_render_node_unref (node);
return opacity_node; return opacity_node;
} }
@@ -326,6 +332,7 @@ gtk_snapshot_push_opacity (GtkSnapshot *snapshot,
state = gtk_snapshot_state_new (snapshot->state, state = gtk_snapshot_state_new (snapshot->state,
str, str,
snapshot->state->tree,
snapshot->state->clip_region, snapshot->state->clip_region,
snapshot->state->translate_x, snapshot->state->translate_x,
snapshot->state->translate_y, snapshot->state->translate_y,
@@ -346,14 +353,12 @@ gtk_snapshot_collect_color_matrix (GtkSnapshotState *state,
if (node == NULL) if (node == NULL)
return 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.matrix,
&state->data.color_matrix.offset); &state->data.color_matrix.offset);
if (name) if (name)
gsk_render_node_set_name (color_matrix_node, name); gsk_render_node_set_name (color_matrix_node, name);
gsk_render_node_unref (node);
return color_matrix_node; return color_matrix_node;
} }
@@ -380,6 +385,7 @@ gtk_snapshot_push_color_matrix (GtkSnapshot *snapshot,
state = gtk_snapshot_state_new (snapshot->state, state = gtk_snapshot_state_new (snapshot->state,
str, str,
snapshot->state->tree,
snapshot->state->clip_region, snapshot->state->clip_region,
snapshot->state->translate_x, snapshot->state->translate_x,
snapshot->state->translate_y, snapshot->state->translate_y,
@@ -414,14 +420,12 @@ gtk_snapshot_collect_repeat (GtkSnapshotState *state,
if (node == NULL) if (node == NULL)
return NULL; return NULL;
repeat_node = gsk_repeat_node_new (bounds, repeat_node = gsk_repeat_node_new (state->tree, bounds,
node, node,
child_bounds->size.width > 0 ? child_bounds : NULL); child_bounds->size.width > 0 ? child_bounds : NULL);
if (name) if (name)
gsk_render_node_set_name (repeat_node, name); gsk_render_node_set_name (repeat_node, name);
gsk_render_node_unref (node);
return repeat_node; return repeat_node;
} }
@@ -458,6 +462,7 @@ gtk_snapshot_push_repeat (GtkSnapshot *snapshot,
state = gtk_snapshot_state_new (snapshot->state, state = gtk_snapshot_state_new (snapshot->state,
str, str,
snapshot->state->tree,
clip, clip,
snapshot->state->translate_x, snapshot->state->translate_x,
snapshot->state->translate_y, snapshot->state->translate_y,
@@ -484,12 +489,10 @@ gtk_snapshot_collect_clip (GtkSnapshotState *state,
if (node == NULL) if (node == NULL)
return 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) if (name)
gsk_render_node_set_name (clip_node, name); gsk_render_node_set_name (clip_node, name);
gsk_render_node_unref (node);
return clip_node; return clip_node;
} }
@@ -530,6 +533,7 @@ gtk_snapshot_push_clip (GtkSnapshot *snapshot,
} }
state = gtk_snapshot_state_new (snapshot->state, state = gtk_snapshot_state_new (snapshot->state,
str, str,
snapshot->state->tree,
clip, clip,
snapshot->state->translate_x, snapshot->state->translate_x,
snapshot->state->translate_y, snapshot->state->translate_y,
@@ -554,12 +558,10 @@ gtk_snapshot_collect_rounded_clip (GtkSnapshotState *state,
if (node == NULL) if (node == NULL)
return 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) if (name)
gsk_render_node_set_name (clip_node, name); gsk_render_node_set_name (clip_node, name);
gsk_render_node_unref (node);
return clip_node; return clip_node;
} }
@@ -602,6 +604,7 @@ gtk_snapshot_push_rounded_clip (GtkSnapshot *snapshot,
state = gtk_snapshot_state_new (snapshot->state, state = gtk_snapshot_state_new (snapshot->state,
str, str,
snapshot->state->tree,
clip, clip,
snapshot->state->translate_x, snapshot->state->translate_x,
snapshot->state->translate_y, snapshot->state->translate_y,
@@ -626,11 +629,10 @@ gtk_snapshot_collect_shadow (GtkSnapshotState *state,
if (node == NULL) if (node == NULL)
return 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) if (name)
gsk_render_node_set_name (shadow_node, name); gsk_render_node_set_name (shadow_node, name);
gsk_render_node_unref (node);
if (state->data.shadow.shadows != &state->data.shadow.a_shadow) if (state->data.shadow.shadows != &state->data.shadow.a_shadow)
g_free (state->data.shadow.shadows); g_free (state->data.shadow.shadows);
@@ -661,6 +663,7 @@ gtk_snapshot_push_shadow (GtkSnapshot *snapshot,
state = gtk_snapshot_state_new (snapshot->state, state = gtk_snapshot_state_new (snapshot->state,
str, str,
snapshot->state->tree,
snapshot->state->clip_region, snapshot->state->clip_region,
snapshot->state->translate_x, snapshot->state->translate_x,
snapshot->state->translate_y, snapshot->state->translate_y,
@@ -736,10 +739,7 @@ gtk_snapshot_pop_and_append (GtkSnapshot *snapshot)
node = gtk_snapshot_pop (snapshot); node = gtk_snapshot_pop (snapshot);
if (node) if (node)
{
gtk_snapshot_append_node (snapshot, node); gtk_snapshot_append_node (snapshot, node);
gsk_render_node_unref (node);
}
} }
/** /**
@@ -807,6 +807,12 @@ gtk_snapshot_get_offset (GtkSnapshot *snapshot,
*y = snapshot->state->translate_y; *y = snapshot->state->translate_y;
} }
GskRenderTree *
gtk_snapshot_get_tree (GtkSnapshot *snapshot)
{
return snapshot->tree;
}
/** /**
* gtk_snapshot_append_node: * gtk_snapshot_append_node:
* @snapshot: a #GtkSnapshot * @snapshot: a #GtkSnapshot
@@ -826,7 +832,7 @@ gtk_snapshot_append_node (GtkSnapshot *snapshot,
if (snapshot->state) if (snapshot->state)
{ {
g_ptr_array_add (snapshot->state->nodes, gsk_render_node_ref (node)); g_ptr_array_add (snapshot->state->nodes, node);
} }
else else
{ {
@@ -863,7 +869,7 @@ gtk_snapshot_append_cairo_node (GtkSnapshot *snapshot,
g_return_val_if_fail (bounds != NULL, NULL); g_return_val_if_fail (bounds != NULL, NULL);
graphene_rect_offset_r (bounds, snapshot->state->translate_x, snapshot->state->translate_y, &real_bounds); 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) if (name && snapshot->record_names)
{ {
@@ -880,7 +886,6 @@ gtk_snapshot_append_cairo_node (GtkSnapshot *snapshot,
} }
gtk_snapshot_append_node (snapshot, node); gtk_snapshot_append_node (snapshot, node);
gsk_render_node_unref (node);
cr = gsk_cairo_node_get_draw_context (node, snapshot->renderer); 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); g_return_if_fail (bounds != NULL);
graphene_rect_offset_r (bounds, snapshot->state->translate_x, snapshot->state->translate_y, &real_bounds); 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) if (name && snapshot->record_names)
{ {
@@ -932,7 +937,6 @@ gtk_snapshot_append_texture_node (GtkSnapshot *snapshot,
} }
gtk_snapshot_append_node (snapshot, node); 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); g_return_if_fail (bounds != NULL);
graphene_rect_offset_r (bounds, snapshot->state->translate_x, snapshot->state->translate_y, &real_bounds); 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) if (name && snapshot->record_names)
{ {
@@ -980,7 +984,6 @@ gtk_snapshot_append_color_node (GtkSnapshot *snapshot,
} }
gtk_snapshot_append_node (snapshot, node); gtk_snapshot_append_node (snapshot, node);
gsk_render_node_unref (node);
} }
/** /**

View File

@@ -92,6 +92,8 @@ GDK_AVAILABLE_IN_3_90
void gtk_snapshot_get_offset (GtkSnapshot *snapshot, void gtk_snapshot_get_offset (GtkSnapshot *snapshot,
int *x, int *x,
int *y); int *y);
GDK_AVAILABLE_IN_3_90
GskRenderTree *gtk_snapshot_get_tree (GtkSnapshot *snapshot);
GDK_AVAILABLE_IN_3_90 GDK_AVAILABLE_IN_3_90
void gtk_snapshot_append_node (GtkSnapshot *snapshot, void gtk_snapshot_append_node (GtkSnapshot *snapshot,

View File

@@ -34,6 +34,7 @@ struct _GtkSnapshotState {
GtkSnapshotState *cached_state; /* A cleared state object we can (re)use */ GtkSnapshotState *cached_state; /* A cleared state object we can (re)use */
char *name; char *name;
GskRenderTree *tree;
GPtrArray *nodes; GPtrArray *nodes;
cairo_region_t *clip_region; cairo_region_t *clip_region;
@@ -74,6 +75,7 @@ struct _GtkSnapshot {
GtkSnapshotState *state; GtkSnapshotState *state;
gboolean record_names; gboolean record_names;
GskRenderer *renderer; GskRenderer *renderer;
GskRenderTree *tree;
}; };
void gtk_snapshot_init (GtkSnapshot *state, void gtk_snapshot_init (GtkSnapshot *state,

View File

@@ -1933,12 +1933,11 @@ gtk_stack_snapshot_crossfade (GtkWidget *widget,
gtk_snapshot_push_transform (snapshot, &identity, "CrossFadeStart"); gtk_snapshot_push_transform (snapshot, &identity, "CrossFadeStart");
gtk_snapshot_append_node (snapshot, priv->last_visible_node); gtk_snapshot_append_node (snapshot, priv->last_visible_node);
start_node = gtk_snapshot_pop (snapshot); start_node = gtk_snapshot_pop (snapshot);
node = gsk_cross_fade_node_new (start_node, end_node, progress); node = gsk_cross_fade_node_new (gtk_snapshot_get_tree (snapshot), start_node, end_node, progress);
gsk_render_node_unref (start_node);
} }
else 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) if (snapshot->record_names)
@@ -1949,9 +1948,6 @@ gtk_stack_snapshot_crossfade (GtkWidget *widget,
} }
gtk_snapshot_append_node (snapshot, node); gtk_snapshot_append_node (snapshot, node);
gsk_render_node_unref (node);
gsk_render_node_unref (end_node);
} }
static void static void