[gtk+] snapshot: Use one large GArray for all states
- From: Timm Bäder <baedert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] snapshot: Use one large GArray for all states
- Date: Mon, 2 Oct 2017 13:11:38 +0000 (UTC)
commit 8e59b3b387791ad8a40710956217c71c2e06f818
Author: Timm Bäder <mail baedert org>
Date: Sun Oct 1 13:49:01 2017 +0200
snapshot: Use one large GArray for all states
Allocating all of them separately shows up in profiles.
gtk/gtksnapshot.c | 454 ++++++++++++++++++++++++++--------------------
gtk/gtksnapshotprivate.h | 8 +-
2 files changed, 256 insertions(+), 206 deletions(-)
---
diff --git a/gtk/gtksnapshot.c b/gtk/gtksnapshot.c
index 293046b..0abc881 100644
--- a/gtk/gtksnapshot.c
+++ b/gtk/gtksnapshot.c
@@ -51,7 +51,8 @@
*/
static GskRenderNode *
-gtk_snapshot_collect_default (GtkSnapshotState *state,
+gtk_snapshot_collect_default (GtkSnapshot *snapshot,
+ GtkSnapshotState *state,
GskRenderNode **nodes,
guint n_nodes,
const char *name)
@@ -77,26 +78,19 @@ gtk_snapshot_collect_default (GtkSnapshotState *state,
}
static GtkSnapshotState *
-gtk_snapshot_state_new (GtkSnapshotState *parent,
- char *name,
- cairo_region_t *clip,
- int translate_x,
- int translate_y,
- GtkSnapshotCollectFunc collect_func)
+gtk_snapshot_push_state (GtkSnapshot *snapshot,
+ char *name,
+ cairo_region_t *clip,
+ int translate_x,
+ int translate_y,
+ GtkSnapshotCollectFunc collect_func)
{
GtkSnapshotState *state;
- if (parent != NULL && parent->cached_state != NULL)
- {
- state = parent->cached_state;
- parent->cached_state = NULL;
- }
- else
- {
- state = g_slice_new0 (GtkSnapshotState);
- state->nodes = g_ptr_array_new_with_free_func ((GDestroyNotify) gsk_render_node_unref);
- state->parent = parent;
- }
+ g_array_set_size (snapshot->state_stack, snapshot->state_stack->len + 1);
+ state = &g_array_index (snapshot->state_stack, GtkSnapshotState, snapshot->state_stack->len - 1);
+
+ state->nodes = g_ptr_array_new_with_free_func ((GDestroyNotify) gsk_render_node_unref);
state->name = name;
if (clip)
@@ -108,22 +102,28 @@ gtk_snapshot_state_new (GtkSnapshotState *parent,
return state;
}
-static void
-gtk_snapshot_state_clear (GtkSnapshotState *state)
+static GtkSnapshotState *
+gtk_snapshot_get_current_state (const GtkSnapshot *snapshot)
{
- g_ptr_array_set_size (state->nodes, 0);
- g_clear_pointer (&state->clip_region, cairo_region_destroy);
- g_clear_pointer (&state->name, g_free);
+ g_assert (snapshot->state_stack->len > 0);
+
+ return &g_array_index (snapshot->state_stack, GtkSnapshotState, snapshot->state_stack->len - 1);
+}
+
+static GtkSnapshotState *
+gtk_snapshot_get_previous_state (const GtkSnapshot *snapshot)
+{
+ g_assert (snapshot->state_stack->len > 1);
+
+ return &g_array_index (snapshot->state_stack, GtkSnapshotState, snapshot->state_stack->len - 2);
}
static void
-gtk_snapshot_state_free (GtkSnapshotState *state)
+gtk_snapshot_state_clear (GtkSnapshotState *state)
{
- if (state->cached_state)
- gtk_snapshot_state_free (state->cached_state);
- gtk_snapshot_state_clear (state);
g_ptr_array_unref (state->nodes);
- g_slice_free (GtkSnapshotState, state);
+ g_clear_pointer (&state->clip_region, cairo_region_destroy);
+ g_clear_pointer (&state->name, g_free);
}
void
@@ -136,9 +136,10 @@ gtk_snapshot_init (GtkSnapshot *snapshot,
{
char *str;
- snapshot->state = NULL;
snapshot->record_names = record_names;
snapshot->renderer = renderer;
+ snapshot->state_stack = g_array_new (FALSE, TRUE, sizeof (GtkSnapshotState));
+ g_array_set_clear_func (snapshot->state_stack, (GDestroyNotify)gtk_snapshot_state_clear);
if (name && record_names)
{
@@ -151,11 +152,11 @@ gtk_snapshot_init (GtkSnapshot *snapshot,
else
str = NULL;
- snapshot->state = gtk_snapshot_state_new (NULL,
- str,
- (cairo_region_t *) clip,
- 0, 0,
- gtk_snapshot_collect_default);
+ gtk_snapshot_push_state (snapshot,
+ str,
+ (cairo_region_t *) clip,
+ 0, 0,
+ gtk_snapshot_collect_default);
}
/**
@@ -193,32 +194,35 @@ gtk_snapshot_push (GtkSnapshot *snapshot,
if (keep_coordinates)
{
- snapshot->state = gtk_snapshot_state_new (snapshot->state,
- str,
- snapshot->state->clip_region,
- snapshot->state->translate_x,
- snapshot->state->translate_y,
- gtk_snapshot_collect_default);
+ GtkSnapshotState *state = gtk_snapshot_get_current_state (snapshot);
+
+ gtk_snapshot_push_state (snapshot,
+ g_strdup (str),
+ state->clip_region,
+ state->translate_x,
+ state->translate_y,
+ gtk_snapshot_collect_default);
+
}
else
{
- snapshot->state = gtk_snapshot_state_new (snapshot->state,
- str,
- NULL,
- 0, 0,
- gtk_snapshot_collect_default);
+ gtk_snapshot_push_state (snapshot,
+ g_strdup (str),
+ NULL, 0, 0,
+ gtk_snapshot_collect_default);
}
}
static GskRenderNode *
-gtk_snapshot_collect_transform (GtkSnapshotState *state,
+gtk_snapshot_collect_transform (GtkSnapshot *snapshot,
+ GtkSnapshotState *state,
GskRenderNode **nodes,
guint n_nodes,
const char *name)
{
GskRenderNode *node, *transform_node;
- node = gtk_snapshot_collect_default (state, nodes, n_nodes, name);
+ node = gtk_snapshot_collect_default (snapshot, state, nodes, n_nodes, name);
if (node == NULL)
return NULL;
@@ -237,6 +241,7 @@ gtk_snapshot_push_transform (GtkSnapshot *snapshot,
const char *name,
...)
{
+ GtkSnapshotState *previous_state;
GtkSnapshotState *state;
graphene_matrix_t offset;
char *str;
@@ -252,33 +257,34 @@ gtk_snapshot_push_transform (GtkSnapshot *snapshot,
else
str = NULL;
- state = gtk_snapshot_state_new (snapshot->state,
- str,
- NULL,
- 0, 0,
- gtk_snapshot_collect_transform);
+ state = gtk_snapshot_push_state (snapshot,
+ str,
+ NULL,
+ 0, 0,
+ gtk_snapshot_collect_transform);
+
+ previous_state = gtk_snapshot_get_previous_state (snapshot);
graphene_matrix_init_translate (&offset,
&GRAPHENE_POINT3D_INIT(
- snapshot->state->translate_x,
- snapshot->state->translate_y,
+ previous_state->translate_x,
+ previous_state->translate_y,
0
));
graphene_matrix_multiply (transform, &offset, &state->data.transform.transform);
-
- snapshot->state = state;
}
static GskRenderNode *
-gtk_snapshot_collect_opacity (GtkSnapshotState *state,
+gtk_snapshot_collect_opacity (GtkSnapshot *snapshot,
+ GtkSnapshotState *state,
GskRenderNode **nodes,
guint n_nodes,
const char *name)
{
GskRenderNode *node, *opacity_node;
- node = gtk_snapshot_collect_default (state, nodes, n_nodes, name);
+ node = gtk_snapshot_collect_default (snapshot, state, nodes, n_nodes, name);
if (node == NULL)
return NULL;
@@ -297,6 +303,7 @@ gtk_snapshot_push_opacity (GtkSnapshot *snapshot,
const char *name,
...)
{
+ GtkSnapshotState *current_state = gtk_snapshot_get_current_state (snapshot);
GtkSnapshotState *state;
char *str;
@@ -311,25 +318,25 @@ gtk_snapshot_push_opacity (GtkSnapshot *snapshot,
else
str = NULL;
- state = gtk_snapshot_state_new (snapshot->state,
- str,
- snapshot->state->clip_region,
- snapshot->state->translate_x,
- snapshot->state->translate_y,
- gtk_snapshot_collect_opacity);
+ state = gtk_snapshot_push_state (snapshot,
+ str,
+ current_state->clip_region,
+ current_state->translate_x,
+ current_state->translate_y,
+ gtk_snapshot_collect_opacity);
state->data.opacity.opacity = opacity;
- snapshot->state = state;
}
static GskRenderNode *
-gtk_snapshot_collect_blur (GtkSnapshotState *state,
+gtk_snapshot_collect_blur (GtkSnapshot *snapshot,
+ GtkSnapshotState *state,
GskRenderNode **nodes,
guint n_nodes,
const char *name)
{
GskRenderNode *node, *blur_node;
- node = gtk_snapshot_collect_default (state, nodes, n_nodes, name);
+ node = gtk_snapshot_collect_default (snapshot, state, nodes, n_nodes, name);
if (node == NULL)
return NULL;
@@ -348,6 +355,7 @@ gtk_snapshot_push_blur (GtkSnapshot *snapshot,
const char *name,
...)
{
+ const GtkSnapshotState *current_state = gtk_snapshot_get_current_state (snapshot);
GtkSnapshotState *state;
char *str;
@@ -362,25 +370,26 @@ gtk_snapshot_push_blur (GtkSnapshot *snapshot,
else
str = NULL;
- state = gtk_snapshot_state_new (snapshot->state,
- str,
- snapshot->state->clip_region,
- snapshot->state->translate_x,
- snapshot->state->translate_y,
- gtk_snapshot_collect_blur);
+ state = gtk_snapshot_push_state (snapshot,
+ str,
+ current_state->clip_region,
+ current_state->translate_x,
+ current_state->translate_y,
+ gtk_snapshot_collect_blur);
state->data.blur.radius = radius;
- snapshot->state = state;
+ current_state = state;
}
static GskRenderNode *
-gtk_snapshot_collect_color_matrix (GtkSnapshotState *state,
+gtk_snapshot_collect_color_matrix (GtkSnapshot *snapshot,
+ GtkSnapshotState *state,
GskRenderNode **nodes,
guint n_nodes,
const char *name)
{
GskRenderNode *node, *color_matrix_node;
- node = gtk_snapshot_collect_default (state, nodes, n_nodes, name);
+ node = gtk_snapshot_collect_default (snapshot, state, nodes, n_nodes, name);
if (node == NULL)
return NULL;
@@ -402,6 +411,7 @@ gtk_snapshot_push_color_matrix (GtkSnapshot *snapshot,
const char *name,
...)
{
+ const GtkSnapshotState *current_state = gtk_snapshot_get_current_state (snapshot);
GtkSnapshotState *state;
char *str;
@@ -416,16 +426,16 @@ gtk_snapshot_push_color_matrix (GtkSnapshot *snapshot,
else
str = NULL;
- state = gtk_snapshot_state_new (snapshot->state,
+ state = gtk_snapshot_push_state (snapshot,
str,
- snapshot->state->clip_region,
- snapshot->state->translate_x,
- snapshot->state->translate_y,
+ current_state->clip_region,
+ current_state->translate_x,
+ current_state->translate_y,
gtk_snapshot_collect_color_matrix);
graphene_matrix_init_from_matrix (&state->data.color_matrix.matrix, color_matrix);
graphene_vec4_init_from_vec4 (&state->data.color_matrix.offset, color_offset);
- snapshot->state = state;
+ current_state = state;
}
static void
@@ -439,7 +449,8 @@ rectangle_init_from_graphene (cairo_rectangle_int_t *cairo,
}
static GskRenderNode *
-gtk_snapshot_collect_repeat (GtkSnapshotState *state,
+gtk_snapshot_collect_repeat (GtkSnapshot *snapshot,
+ GtkSnapshotState *state,
GskRenderNode **nodes,
guint n_nodes,
const char *name)
@@ -448,7 +459,7 @@ gtk_snapshot_collect_repeat (GtkSnapshotState *state,
graphene_rect_t *bounds = &state->data.repeat.bounds;
graphene_rect_t *child_bounds = &state->data.repeat.child_bounds;
- node = gtk_snapshot_collect_default (state, nodes, n_nodes, name);
+ node = gtk_snapshot_collect_default (snapshot, state, nodes, n_nodes, name);
if (node == NULL)
return NULL;
@@ -470,6 +481,7 @@ gtk_snapshot_push_repeat (GtkSnapshot *snapshot,
const char *name,
...)
{
+ const GtkSnapshotState *current_state = gtk_snapshot_get_current_state (snapshot);
GtkSnapshotState *state;
cairo_region_t *clip = NULL;
graphene_rect_t real_child_bounds = { { 0 } };
@@ -489,36 +501,39 @@ gtk_snapshot_push_repeat (GtkSnapshot *snapshot,
if (child_bounds)
{
cairo_rectangle_int_t rect;
- graphene_rect_offset_r (child_bounds, snapshot->state->translate_x, snapshot->state->translate_y,
&real_child_bounds);
+ graphene_rect_offset_r (child_bounds, current_state->translate_x, current_state->translate_y,
&real_child_bounds);
rectangle_init_from_graphene (&rect, &real_child_bounds);
clip = cairo_region_create_rectangle (&rect);
}
- state = gtk_snapshot_state_new (snapshot->state,
- str,
- clip,
- snapshot->state->translate_x,
- snapshot->state->translate_y,
- gtk_snapshot_collect_repeat);
+ state = gtk_snapshot_push_state (snapshot,
+ str,
+ clip,
+ current_state->translate_x,
+ current_state->translate_y,
+ gtk_snapshot_collect_repeat);
+
+ current_state = gtk_snapshot_get_previous_state (snapshot);
- graphene_rect_offset_r (bounds, snapshot->state->translate_x, snapshot->state->translate_y,
&state->data.repeat.bounds);
+ graphene_rect_offset_r (bounds, current_state->translate_x, current_state->translate_y,
&state->data.repeat.bounds);
state->data.repeat.child_bounds = real_child_bounds;
- snapshot->state = state;
+ current_state = state;
if (clip)
cairo_region_destroy (clip);
}
static GskRenderNode *
-gtk_snapshot_collect_clip (GtkSnapshotState *state,
+gtk_snapshot_collect_clip (GtkSnapshot *snapshot,
+ GtkSnapshotState *state,
GskRenderNode **nodes,
guint n_nodes,
const char *name)
{
GskRenderNode *node, *clip_node;
- node = gtk_snapshot_collect_default (state, nodes, n_nodes, name);
+ node = gtk_snapshot_collect_default (snapshot, state, nodes, n_nodes, name);
if (node == NULL)
return NULL;
@@ -537,13 +552,14 @@ gtk_snapshot_push_clip (GtkSnapshot *snapshot,
const char *name,
...)
{
+ const GtkSnapshotState *current_state = gtk_snapshot_get_current_state (snapshot);
GtkSnapshotState *state;
graphene_rect_t real_bounds;
cairo_region_t *clip;
cairo_rectangle_int_t rect;
char *str;
- graphene_rect_offset_r (bounds, snapshot->state->translate_x, snapshot->state->translate_y, &real_bounds);
+ graphene_rect_offset_r (bounds, current_state->translate_x, current_state->translate_y, &real_bounds);
if (name && snapshot->record_names)
{
@@ -557,38 +573,37 @@ gtk_snapshot_push_clip (GtkSnapshot *snapshot,
str = NULL;
rectangle_init_from_graphene (&rect, &real_bounds);
- if (snapshot->state->clip_region)
+ if (current_state->clip_region)
{
- clip = cairo_region_copy (snapshot->state->clip_region);
+ clip = cairo_region_copy (current_state->clip_region);
cairo_region_intersect_rectangle (clip, &rect);
}
else
{
clip = cairo_region_create_rectangle (&rect);
}
- state = gtk_snapshot_state_new (snapshot->state,
+ state = gtk_snapshot_push_state (snapshot,
str,
clip,
- snapshot->state->translate_x,
- snapshot->state->translate_y,
+ current_state->translate_x,
+ current_state->translate_y,
gtk_snapshot_collect_clip);
state->data.clip.bounds = real_bounds;
- snapshot->state = state;
-
cairo_region_destroy (clip);
}
static GskRenderNode *
-gtk_snapshot_collect_rounded_clip (GtkSnapshotState *state,
+gtk_snapshot_collect_rounded_clip (GtkSnapshot *snapshot,
+ GtkSnapshotState *state,
GskRenderNode **nodes,
guint n_nodes,
const char *name)
{
GskRenderNode *node, *clip_node;
- node = gtk_snapshot_collect_default (state, nodes, n_nodes, name);
+ node = gtk_snapshot_collect_default (snapshot, state, nodes, n_nodes, name);
if (node == NULL)
return NULL;
@@ -607,6 +622,7 @@ gtk_snapshot_push_rounded_clip (GtkSnapshot *snapshot,
const char *name,
...)
{
+ const GtkSnapshotState *current_state = gtk_snapshot_get_current_state (snapshot);
GtkSnapshotState *state;
GskRoundedRect real_bounds;
cairo_region_t *clip;
@@ -614,7 +630,7 @@ gtk_snapshot_push_rounded_clip (GtkSnapshot *snapshot,
char *str;
gsk_rounded_rect_init_copy (&real_bounds, bounds);
- gsk_rounded_rect_offset (&real_bounds, snapshot->state->translate_x, snapshot->state->translate_y);
+ gsk_rounded_rect_offset (&real_bounds, current_state->translate_x, current_state->translate_y);
if (name && snapshot->record_names)
{
@@ -628,9 +644,9 @@ gtk_snapshot_push_rounded_clip (GtkSnapshot *snapshot,
str = NULL;
rectangle_init_from_graphene (&rect, &real_bounds.bounds);
- if (snapshot->state->clip_region)
+ if (current_state->clip_region)
{
- clip = cairo_region_copy (snapshot->state->clip_region);
+ clip = cairo_region_copy (current_state->clip_region);
cairo_region_intersect_rectangle (clip, &rect);
}
else
@@ -638,39 +654,43 @@ gtk_snapshot_push_rounded_clip (GtkSnapshot *snapshot,
clip = cairo_region_create_rectangle (&rect);
}
- state = gtk_snapshot_state_new (snapshot->state,
+ state = gtk_snapshot_push_state (snapshot,
str,
clip,
- snapshot->state->translate_x,
- snapshot->state->translate_y,
+ current_state->translate_x,
+ current_state->translate_y,
gtk_snapshot_collect_rounded_clip);
state->data.rounded_clip.bounds = real_bounds;
- snapshot->state = state;
+ current_state = state;
cairo_region_destroy (clip);
}
static GskRenderNode *
-gtk_snapshot_collect_shadow (GtkSnapshotState *state,
+gtk_snapshot_collect_shadow (GtkSnapshot *snapshot,
+ GtkSnapshotState *state,
GskRenderNode **nodes,
guint n_nodes,
const char *name)
{
GskRenderNode *node, *shadow_node;
- node = gtk_snapshot_collect_default (state, nodes, n_nodes, name);
+ node = gtk_snapshot_collect_default (snapshot, state, nodes, n_nodes, name);
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 (node,
+ state->data.shadow.shadows != NULL ?
+ state->data.shadow.shadows :
+ &state->data.shadow.a_shadow,
+ 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);
+ g_free (state->data.shadow.shadows);
return shadow_node;
}
@@ -682,6 +702,7 @@ gtk_snapshot_push_shadow (GtkSnapshot *snapshot,
const char *name,
...)
{
+ const GtkSnapshotState *current_state = gtk_snapshot_get_current_state (snapshot);
GtkSnapshotState *state;
char *str;
@@ -696,32 +717,37 @@ gtk_snapshot_push_shadow (GtkSnapshot *snapshot,
else
str = NULL;
- state = gtk_snapshot_state_new (snapshot->state,
- str,
- snapshot->state->clip_region,
- snapshot->state->translate_x,
- snapshot->state->translate_y,
- gtk_snapshot_collect_shadow);
+ state = gtk_snapshot_push_state (snapshot,
+ str,
+ current_state->clip_region,
+ current_state->translate_x,
+ current_state->translate_y,
+ gtk_snapshot_collect_shadow);
state->data.shadow.n_shadows = n_shadows;
if (n_shadows == 1)
- state->data.shadow.shadows = &state->data.shadow.a_shadow;
+ {
+ state->data.shadow.shadows = NULL;
+ memcpy (&state->data.shadow.a_shadow, shadow, sizeof (GskShadow));
+ }
else
- state->data.shadow.shadows = g_malloc (sizeof (GskShadow) * n_shadows);
- memcpy (state->data.shadow.shadows, shadow, sizeof (GskShadow) * n_shadows);
+ {
+ state->data.shadow.shadows = g_malloc (sizeof (GskShadow) * n_shadows);
+ memcpy (state->data.shadow.shadows, shadow, sizeof (GskShadow) * n_shadows);
+ }
- snapshot->state = state;
}
static GskRenderNode *
-gtk_snapshot_collect_blend_top (GtkSnapshotState *state,
+gtk_snapshot_collect_blend_top (GtkSnapshot *snapshot,
+ GtkSnapshotState *state,
GskRenderNode **nodes,
guint n_nodes,
const char *name)
{
GskRenderNode *bottom_node, *top_node, *blend_node;
- top_node = gtk_snapshot_collect_default (state, nodes, n_nodes, name);
+ top_node = gtk_snapshot_collect_default (snapshot, state, nodes, n_nodes, name);
bottom_node = state->data.blend.bottom_node;
/* XXX: Is this necessary? Do we need a NULL node? */
@@ -740,13 +766,18 @@ gtk_snapshot_collect_blend_top (GtkSnapshotState *state,
}
static GskRenderNode *
-gtk_snapshot_collect_blend_bottom (GtkSnapshotState *state,
+gtk_snapshot_collect_blend_bottom (GtkSnapshot *snapshot,
+ GtkSnapshotState *state,
GskRenderNode **nodes,
guint n_nodes,
const char *name)
{
- state->parent->data.blend.bottom_node = gtk_snapshot_collect_default (state, nodes, n_nodes, name);
-
+ GtkSnapshotState *prev_state = gtk_snapshot_get_current_state (snapshot);
+
+ g_assert (prev_state->collect_func == gtk_snapshot_collect_blend_top);
+
+ prev_state->data.blend.bottom_node = gtk_snapshot_collect_default (snapshot, state, nodes, n_nodes, name);
+
return NULL;
}
@@ -771,7 +802,9 @@ gtk_snapshot_push_blend (GtkSnapshot *snapshot,
const char *name,
...)
{
- GtkSnapshotState *state;
+ GtkSnapshotState *current_state = gtk_snapshot_get_current_state (snapshot);
+ GtkSnapshotState *bottom_state;
+ GtkSnapshotState *top_state;
char *str;
if (name && snapshot->record_names)
@@ -785,34 +818,32 @@ gtk_snapshot_push_blend (GtkSnapshot *snapshot,
else
str = NULL;
- state = gtk_snapshot_state_new (snapshot->state,
- str,
- snapshot->state->clip_region,
- snapshot->state->translate_x,
- snapshot->state->translate_y,
- gtk_snapshot_collect_blend_top);
- state->data.blend.blend_mode = blend_mode;
- state->data.blend.bottom_node = NULL;
-
- state = gtk_snapshot_state_new (state,
- g_strdup (str),
- state->clip_region,
- state->translate_x,
- state->translate_y,
- gtk_snapshot_collect_blend_bottom);
-
- snapshot->state = state;
+ bottom_state = gtk_snapshot_push_state (snapshot,
+ str,
+ current_state->clip_region,
+ current_state->translate_x,
+ current_state->translate_y,
+ gtk_snapshot_collect_blend_top);
+
+ top_state = gtk_snapshot_push_state (snapshot,
+ g_strdup (str),
+ bottom_state->clip_region,
+ bottom_state->translate_x,
+ bottom_state->translate_y,
+ gtk_snapshot_collect_blend_bottom);
+ top_state->data.blend.blend_mode = blend_mode;
}
static GskRenderNode *
-gtk_snapshot_collect_cross_fade_end (GtkSnapshotState *state,
+gtk_snapshot_collect_cross_fade_end (GtkSnapshot *snapshot,
+ GtkSnapshotState *state,
GskRenderNode **nodes,
guint n_nodes,
const char *name)
{
GskRenderNode *start_node, *end_node, *node;
- end_node = gtk_snapshot_collect_default (state, nodes, n_nodes, name);
+ end_node = gtk_snapshot_collect_default (snapshot, state, nodes, n_nodes, name);
start_node = state->data.cross_fade.start_node;
if (state->data.cross_fade.progress <= 0.0)
@@ -860,13 +891,18 @@ gtk_snapshot_collect_cross_fade_end (GtkSnapshotState *state,
}
static GskRenderNode *
-gtk_snapshot_collect_cross_fade_start (GtkSnapshotState *state,
+gtk_snapshot_collect_cross_fade_start (GtkSnapshot *snapshot,
+ GtkSnapshotState *state,
GskRenderNode **nodes,
guint n_nodes,
const char *name)
{
- state->parent->data.cross_fade.start_node = gtk_snapshot_collect_default (state, nodes, n_nodes, name);
-
+ GtkSnapshotState *prev_state = gtk_snapshot_get_previous_state (snapshot);
+
+ g_assert (prev_state->collect_func == gtk_snapshot_collect_cross_fade_end);
+
+ prev_state->data.cross_fade.start_node = gtk_snapshot_collect_default (snapshot, state, nodes, n_nodes,
name);
+
return NULL;
}
@@ -892,7 +928,9 @@ gtk_snapshot_push_cross_fade (GtkSnapshot *snapshot,
const char *name,
...)
{
- GtkSnapshotState *state;
+ const GtkSnapshotState *current_state = gtk_snapshot_get_current_state (snapshot);
+ GtkSnapshotState *start_state;
+ GtkSnapshotState *end_state;
char *str;
if (name && snapshot->record_names)
@@ -906,52 +944,45 @@ gtk_snapshot_push_cross_fade (GtkSnapshot *snapshot,
else
str = NULL;
- state = gtk_snapshot_state_new (snapshot->state,
- str,
- snapshot->state->clip_region,
- snapshot->state->translate_x,
- snapshot->state->translate_y,
- gtk_snapshot_collect_cross_fade_end);
- state->data.cross_fade.progress = progress;
- state->data.cross_fade.start_node = NULL;
-
- state = gtk_snapshot_state_new (state,
- g_strdup (str),
- state->clip_region,
- state->translate_x,
- state->translate_y,
- gtk_snapshot_collect_cross_fade_start);
-
- snapshot->state = state;
+ start_state = gtk_snapshot_push_state (snapshot,
+ str,
+ current_state->clip_region,
+ current_state->translate_x,
+ current_state->translate_y,
+ gtk_snapshot_collect_cross_fade_end);
+
+ end_state = gtk_snapshot_push_state (snapshot,
+ g_strdup (str),
+ start_state->clip_region,
+ start_state->translate_x,
+ start_state->translate_y,
+ gtk_snapshot_collect_cross_fade_start);
+ end_state->data.cross_fade.progress = progress;
}
static GskRenderNode *
gtk_snapshot_pop_internal (GtkSnapshot *snapshot)
{
GtkSnapshotState *state;
+ guint state_index;
GskRenderNode *node;
- if (snapshot->state == NULL)
+ if (snapshot->state_stack->len == 0)
{
g_warning ("Too many gtk_snapshot_pop() calls.");
return NULL;
}
- state = snapshot->state;
- snapshot->state = state->parent;
+ state = gtk_snapshot_get_current_state (snapshot);
+ state_index = snapshot->state_stack->len - 1;
- node = state->collect_func (state,
+ node = state->collect_func (snapshot,
+ state,
(GskRenderNode **) state->nodes->pdata,
state->nodes->len,
state->name);
- if (snapshot->state == NULL)
- gtk_snapshot_state_free (state);
- else
- {
- gtk_snapshot_state_clear (state);
- snapshot->state->cached_state = state;
- }
+ g_array_remove_index (snapshot->state_stack, state_index);
return node;
}
@@ -960,14 +991,24 @@ GskRenderNode *
gtk_snapshot_finish (GtkSnapshot *snapshot)
{
GskRenderNode *result;
-
- result = gtk_snapshot_pop_internal (snapshot);
- if (snapshot->state != NULL)
+ /* We should have exactly our initial state */
+ if (snapshot->state_stack->len > 1)
{
- g_warning ("Too many gtk_snapshot_push() calls.");
+ gint i;
+
+ g_warning ("Too many gtk_snapshot_push() calls. Still there:");
+ for (i = snapshot->state_stack->len - 1; i >= 0; i --)
+ {
+ const GtkSnapshotState *s = &g_array_index (snapshot->state_stack, GtkSnapshotState, i);
+
+ g_warning ("%s", s->name);
+ }
}
+
+ result = gtk_snapshot_pop_internal (snapshot);
+ g_array_free (snapshot->state_stack, TRUE);
return result;
}
@@ -1025,8 +1066,10 @@ gtk_snapshot_offset (GtkSnapshot *snapshot,
int x,
int y)
{
- snapshot->state->translate_x += x;
- snapshot->state->translate_y += y;
+ GtkSnapshotState *current_state = gtk_snapshot_get_current_state (snapshot);
+
+ current_state->translate_x += x;
+ current_state->translate_y += y;
}
/**
@@ -1051,11 +1094,13 @@ gtk_snapshot_get_offset (GtkSnapshot *snapshot,
int *x,
int *y)
{
+ const GtkSnapshotState *current_state = gtk_snapshot_get_current_state (snapshot);
+
if (x)
- *x = snapshot->state->translate_x;
+ *x = current_state->translate_x;
if (y)
- *y = snapshot->state->translate_y;
+ *y = current_state->translate_y;
}
/**
@@ -1072,12 +1117,15 @@ void
gtk_snapshot_append_node (GtkSnapshot *snapshot,
GskRenderNode *node)
{
+ GtkSnapshotState *current_state;
g_return_if_fail (snapshot != NULL);
g_return_if_fail (GSK_IS_RENDER_NODE (node));
- if (snapshot->state)
+ current_state = gtk_snapshot_get_current_state (snapshot);
+
+ if (current_state)
{
- g_ptr_array_add (snapshot->state->nodes, gsk_render_node_ref (node));
+ g_ptr_array_add (current_state->nodes, gsk_render_node_ref (node));
}
else
{
@@ -1106,6 +1154,7 @@ gtk_snapshot_append_cairo (GtkSnapshot *snapshot,
const char *name,
...)
{
+ const GtkSnapshotState *current_state = gtk_snapshot_get_current_state (snapshot);
GskRenderNode *node;
graphene_rect_t real_bounds;
cairo_t *cr;
@@ -1113,7 +1162,7 @@ gtk_snapshot_append_cairo (GtkSnapshot *snapshot,
g_return_val_if_fail (snapshot != 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, current_state->translate_x, current_state->translate_y, &real_bounds);
node = gsk_cairo_node_new (&real_bounds);
if (name && snapshot->record_names)
@@ -1135,7 +1184,7 @@ gtk_snapshot_append_cairo (GtkSnapshot *snapshot,
cr = gsk_cairo_node_get_draw_context (node, snapshot->renderer);
- cairo_translate (cr, snapshot->state->translate_x, snapshot->state->translate_y);
+ cairo_translate (cr, current_state->translate_x, current_state->translate_y);
return cr;
}
@@ -1158,6 +1207,7 @@ gtk_snapshot_append_texture (GtkSnapshot *snapshot,
const char *name,
...)
{
+ GtkSnapshotState *current_state = gtk_snapshot_get_current_state (snapshot);
GskRenderNode *node;
graphene_rect_t real_bounds;
@@ -1165,7 +1215,7 @@ gtk_snapshot_append_texture (GtkSnapshot *snapshot,
g_return_if_fail (GSK_IS_TEXTURE (texture));
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, current_state->translate_x, current_state->translate_y, &real_bounds);
node = gsk_texture_node_new (texture, &real_bounds);
if (name && snapshot->record_names)
@@ -1206,6 +1256,7 @@ gtk_snapshot_append_color (GtkSnapshot *snapshot,
const char *name,
...)
{
+ const GtkSnapshotState *current_state = gtk_snapshot_get_current_state (snapshot);
GskRenderNode *node;
graphene_rect_t real_bounds;
@@ -1213,7 +1264,7 @@ gtk_snapshot_append_color (GtkSnapshot *snapshot,
g_return_if_fail (color != 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, current_state->translate_x, current_state->translate_y, &real_bounds);
node = gsk_color_node_new (color, &real_bounds);
if (name && snapshot->record_names)
@@ -1249,17 +1300,18 @@ gboolean
gtk_snapshot_clips_rect (GtkSnapshot *snapshot,
const cairo_rectangle_int_t *rect)
{
+ const GtkSnapshotState *current_state = gtk_snapshot_get_current_state (snapshot);
cairo_rectangle_int_t offset_rect;
- if (snapshot->state->clip_region == NULL)
+ if (current_state->clip_region == NULL)
return FALSE;
- offset_rect.x = rect->x + snapshot->state->translate_x;
- offset_rect.y = rect->y + snapshot->state->translate_y;
+ offset_rect.x = rect->x + current_state->translate_x;
+ offset_rect.y = rect->y + current_state->translate_y;
offset_rect.width = rect->width;
offset_rect.height = rect->height;
- return cairo_region_contains_rectangle (snapshot->state->clip_region, &offset_rect) ==
CAIRO_REGION_OVERLAP_OUT;
+ return cairo_region_contains_rectangle (current_state->clip_region, &offset_rect) ==
CAIRO_REGION_OVERLAP_OUT;
}
/**
diff --git a/gtk/gtksnapshotprivate.h b/gtk/gtksnapshotprivate.h
index deffbc1..c929376 100644
--- a/gtk/gtksnapshotprivate.h
+++ b/gtk/gtksnapshotprivate.h
@@ -24,15 +24,13 @@ G_BEGIN_DECLS
typedef struct _GtkSnapshotState GtkSnapshotState;
-typedef GskRenderNode * (* GtkSnapshotCollectFunc) (GtkSnapshotState *state,
+typedef GskRenderNode * (* GtkSnapshotCollectFunc) (GtkSnapshot *snapshot,
+ GtkSnapshotState *state,
GskRenderNode **nodes,
guint n_nodes,
const char *name);
struct _GtkSnapshotState {
- GtkSnapshotState *parent;
- GtkSnapshotState *cached_state; /* A cleared state object we can (re)use */
-
char *name;
GPtrArray *nodes;
@@ -82,9 +80,9 @@ struct _GtkSnapshotState {
};
struct _GtkSnapshot {
- GtkSnapshotState *state;
gboolean record_names;
GskRenderer *renderer;
+ GArray *state_stack;
};
void gtk_snapshot_init (GtkSnapshot *state,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]