snapshot: Use one large GArray for all states

Allocating all of them separately shows up in profiles.
This commit is contained in:
Timm Bäder
2017-10-01 13:49:01 +02:00
parent d2afa1d72a
commit 8e59b3b387
2 changed files with 255 additions and 205 deletions

View File

@@ -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);
graphene_rect_offset_r (bounds, snapshot->state->translate_x, snapshot->state->translate_y, &state->data.repeat.bounds);
current_state = gtk_snapshot_get_previous_state (snapshot);
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;
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);
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;
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;
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);
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;
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;
/* We should have exactly our initial state */
if (snapshot->state_stack->len > 1)
{
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);
if (snapshot->state != NULL)
{
g_warning ("Too many gtk_snapshot_push() calls.");
}
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;
}
/**

View File

@@ -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,