[gtk+/wip/otte/rendernode: 33/100] snapshot: Change how gtk_snapshot_push/pop works
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/otte/rendernode: 33/100] snapshot: Change how gtk_snapshot_push/pop works
- Date: Sun, 18 Dec 2016 06:31:28 +0000 (UTC)
commit 44c55ff37c5547874212fc85d23c6adea031419d
Author: Benjamin Otte <otte redhat com>
Date: Tue Dec 13 02:33:15 2016 +0100
snapshot: Change how gtk_snapshot_push/pop works
Instead of appending a container node and adding the nodes to it as they
come in, we now collect the nodes until gtk_snapshot_pop() is called and
then hand them out in a container node.
The caller of gtk_snapshot_push() is then responsible for doing whatever
he wants with the created node.
Another addigion is the keep_coordinates flag to gtk_snapshot_push()
which allows callers to keep the current offset and clip region or
discard it. Discarding is useful when doing transforms, keeping it is
useful when inserting effect nodes (like the ones I'm about to add).
docs/reference/gsk/gsk4-sections.txt | 1 -
gsk/gskrendernode.h | 12 ++--
gsk/gskrendernodeimpl.c | 64 +++++++------------
gtk/gtkrendericon.c | 15 ++--
gtk/gtksnapshot.c | 117 ++++++++++++++++++++--------------
gtk/gtksnapshot.h | 8 +--
gtk/gtksnapshotprivate.h | 4 +-
7 files changed, 112 insertions(+), 109 deletions(-)
---
diff --git a/docs/reference/gsk/gsk4-sections.txt b/docs/reference/gsk/gsk4-sections.txt
index 102d084..4bbeba5 100644
--- a/docs/reference/gsk/gsk4-sections.txt
+++ b/docs/reference/gsk/gsk4-sections.txt
@@ -38,7 +38,6 @@ gsk_texture_node_new
gsk_cairo_node_new
gsk_cairo_node_get_draw_context
gsk_container_node_new
-gsk_container_node_append_child
gsk_container_node_get_n_children
gsk_container_node_get_child
gsk_transform_node_new
diff --git a/gsk/gskrendernode.h b/gsk/gskrendernode.h
index b98bd56..93a100e 100644
--- a/gsk/gskrendernode.h
+++ b/gsk/gskrendernode.h
@@ -55,15 +55,13 @@ cairo_t * gsk_cairo_node_get_draw_context (GskRenderNode
GskRenderer *renderer);
GDK_AVAILABLE_IN_3_90
-GskRenderNode * gsk_container_node_new (void);
+GskRenderNode * gsk_container_node_new (GskRenderNode **children,
+ guint n_children);
GDK_AVAILABLE_IN_3_90
-GskRenderNode * gsk_container_node_append_child (GskRenderNode *node,
- GskRenderNode *child);
+guint gsk_container_node_get_n_children (GskRenderNode *node);
GDK_AVAILABLE_IN_3_90
-guint gsk_container_node_get_n_children (GskRenderNode *node);
-GDK_AVAILABLE_IN_3_90
-GskRenderNode * gsk_container_node_get_child (GskRenderNode *node,
- guint idx);
+GskRenderNode * gsk_container_node_get_child (GskRenderNode *node,
+ guint idx);
GDK_AVAILABLE_IN_3_90
GskRenderNode * gsk_transform_node_new (GskRenderNode *child,
diff --git a/gsk/gskrendernodeimpl.c b/gsk/gskrendernodeimpl.c
index e719a1d..d23d18d 100644
--- a/gsk/gskrendernodeimpl.c
+++ b/gsk/gskrendernodeimpl.c
@@ -285,15 +285,20 @@ struct _GskContainerNode
{
GskRenderNode render_node;
- GPtrArray *children;
+ GskRenderNode **children;
+ guint n_children;
};
static void
gsk_container_node_finalize (GskRenderNode *node)
{
GskContainerNode *container = (GskContainerNode *) node;
+ guint i;
+
+ for (i = 0; i < container->n_children; i++)
+ gsk_render_node_unref (container->children[i]);
- g_ptr_array_unref (container->children);
+ g_free (container->children);
}
static void
@@ -302,9 +307,9 @@ gsk_container_node_make_immutable (GskRenderNode *node)
GskContainerNode *container = (GskContainerNode *) node;
guint i;
- for (i = 1; i < container->children->len; i++)
+ for (i = 1; i < container->n_children; i++)
{
- gsk_render_node_make_immutable (g_ptr_array_index (container->children, i));
+ gsk_render_node_make_immutable (container->children[i]);
}
}
@@ -343,53 +348,32 @@ static const GskRenderNodeClass GSK_CONTAINER_NODE_CLASS = {
/**
* gsk_container_node_new:
+ * @children: (array length=n_children) (transfer none): The children of the node
+ * @n_children: Number of children in the @children array
*
- * Creates a new #GskRenderNode instance for holding multiple different
- * render nodes. You can use gsk_container_node_append_child() to add
- * nodes to the container.
+ * Creates a new #GskRenderNode instance for holding the given @children.
+ * The new node will acquire a reference to each of the children.
*
* Returns: (transfer full): the new #GskRenderNode
*
* Since: 3.90
*/
GskRenderNode *
-gsk_container_node_new (void)
+gsk_container_node_new (GskRenderNode **children,
+ guint n_children)
{
GskContainerNode *container;
+ guint i;
container = (GskContainerNode *) gsk_render_node_new (&GSK_CONTAINER_NODE_CLASS);
- container->children = g_ptr_array_new_with_free_func ((GDestroyNotify) gsk_render_node_unref);
+ container->children = g_memdup (children, sizeof (GskRenderNode *) * n_children);
+ container->n_children = n_children;
- return &container->render_node;
-}
+ for (i = 0; i < container->n_children; i++)
+ gsk_render_node_ref (container->children[i]);
-/**
- * gsk_container_node_append_child:
- * @node: a container node
- * @child: a #GskRenderNode
- *
- * Appends @child to the list of children of @node.
- *
- * This function acquires a reference on @child.
- *
- * Returns: (transfer none): the #GskRenderNode
- *
- * Since: 3.90
- */
-GskRenderNode *
-gsk_container_node_append_child (GskRenderNode *node,
- GskRenderNode *child)
-{
- GskContainerNode *container = (GskContainerNode *) node;
-
- g_return_val_if_fail (GSK_IS_RENDER_NODE_TYPE (node, GSK_CONTAINER_NODE), NULL);
- g_return_val_if_fail (GSK_IS_RENDER_NODE (child), node);
- g_return_val_if_fail (node->is_mutable, node);
-
- g_ptr_array_add (container->children, gsk_render_node_ref (child));
-
- return node;
+ return &container->render_node;
}
/**
@@ -409,7 +393,7 @@ gsk_container_node_get_n_children (GskRenderNode *node)
g_return_val_if_fail (GSK_IS_RENDER_NODE_TYPE (node, GSK_CONTAINER_NODE), 0);
- return container->children->len;
+ return container->n_children;
}
GskRenderNode *
@@ -419,9 +403,9 @@ gsk_container_node_get_child (GskRenderNode *node,
GskContainerNode *container = (GskContainerNode *) node;
g_return_val_if_fail (GSK_IS_RENDER_NODE_TYPE (node, GSK_CONTAINER_NODE), NULL);
- g_return_val_if_fail (idx < container->children->len, 0);
+ g_return_val_if_fail (idx < container->n_children, 0);
- return g_ptr_array_index (container->children, idx);
+ return container->children[idx];
}
/*** GSK_TRANSFORM_NODE ***/
diff --git a/gtk/gtkrendericon.c b/gtk/gtkrendericon.c
index 0304f0d..082f87d 100644
--- a/gtk/gtkrendericon.c
+++ b/gtk/gtkrendericon.c
@@ -126,7 +126,7 @@ gtk_css_style_snapshot_icon (GtkCssStyle *style,
else
{
graphene_matrix_t m1, m2, m3;
- GskRenderNode *transform_node, *container_node;
+ GskRenderNode *transform_node, *icon_node;
double offset_x, offset_y;
gtk_snapshot_get_offset (snapshot, &offset_x, &offset_y);
@@ -136,15 +136,16 @@ gtk_css_style_snapshot_icon (GtkCssStyle *style,
graphene_matrix_init_translate (&m2, &GRAPHENE_POINT3D_INIT(- width / 2.0, - height / 2.0, 0));
graphene_matrix_multiply (&m2, &m3, &m1);
- container_node = gsk_container_node_new ();
- gsk_render_node_set_name (container_node, "CSS Icon Transform Container");
- transform_node = gsk_transform_node_new (container_node, &m1);
+ gtk_snapshot_push (snapshot, FALSE, "CSS Icon Transform Container");
+ gtk_css_image_builtin_snapshot (image, snapshot, width, height, builtin_type);
+ icon_node = gtk_snapshot_pop (snapshot);
+
+ transform_node = gsk_transform_node_new (icon_node, &m1);
gsk_render_node_set_name (transform_node, "CSS Icon Transform");
gtk_snapshot_append_node (snapshot, transform_node);
- gtk_snapshot_push_node (snapshot, container_node);
- gtk_css_image_builtin_snapshot (image, snapshot, width, height, builtin_type);
- gtk_snapshot_pop (snapshot);
+ gsk_render_node_unref (transform_node);
+ gsk_render_node_unref (icon_node);
}
}
diff --git a/gtk/gtksnapshot.c b/gtk/gtksnapshot.c
index 331e980..ff0eda2 100644
--- a/gtk/gtksnapshot.c
+++ b/gtk/gtksnapshot.c
@@ -50,15 +50,21 @@
static GtkSnapshotState *
gtk_snapshot_state_new (GtkSnapshotState *parent,
+ char *name,
cairo_region_t *clip,
- GskRenderNode *node)
+ double translate_x,
+ double translate_y)
{
GtkSnapshotState *state;
state = g_slice_new0 (GtkSnapshotState);
- state->node = node;
+ state->nodes = g_ptr_array_new_with_free_func ((GDestroyNotify) gsk_render_node_unref);
+
state->parent = parent;
+ state->name = name;
+ state->translate_x = translate_x;
+ state->translate_y = translate_y;
if (clip)
state->clip_region = cairo_region_reference (clip);
@@ -68,9 +74,13 @@ gtk_snapshot_state_new (GtkSnapshotState *parent,
static void
gtk_snapshot_state_free (GtkSnapshotState *state)
{
+ g_ptr_array_unref (state->nodes);
+
if (state->clip_region)
cairo_region_destroy (state->clip_region);
+ g_free (state->name);
+
g_slice_free (GtkSnapshotState, state);
}
@@ -81,66 +91,49 @@ gtk_snapshot_init (GtkSnapshot *snapshot,
const char *name,
...)
{
- cairo_rectangle_int_t extents;
-
- cairo_region_get_extents (clip, &extents);
+ char *str;
snapshot->state = NULL;
snapshot->renderer = renderer;
- snapshot->root = gsk_container_node_new ();
if (name)
{
va_list args;
- char *str;
va_start (args, name);
str = g_strdup_vprintf (name, args);
va_end (args);
-
- gsk_render_node_set_name (snapshot->root, str);
-
- g_free (str);
}
+ else
+ str = NULL;
- snapshot->state = gtk_snapshot_state_new (NULL, (cairo_region_t *) clip, snapshot->root);
+ snapshot->state = gtk_snapshot_state_new (NULL,
+ str,
+ (cairo_region_t *) clip,
+ 0, 0);
}
GskRenderNode *
gtk_snapshot_finish (GtkSnapshot *snapshot)
{
- gtk_snapshot_pop (snapshot);
+ GskRenderNode *result;
+
+ result = gtk_snapshot_pop (snapshot);
if (snapshot->state != NULL)
{
g_warning ("Too many gtk_snapshot_push() calls.");
}
- return snapshot->root;
-}
-
-/**
- * gtk_snapshot_push_node:
- * @snapshot: a #GtkSnapshot
- * @node: the render node to push
- *
- * Makes @node the new current render node. You are responsible for adding
- * @node to the snapshot.
- *
- * Since: 3.90
- */
-void
-gtk_snapshot_push_node (GtkSnapshot *snapshot,
- GskRenderNode *node)
-{
- g_return_if_fail (gsk_render_node_get_node_type (node) == GSK_CONTAINER_NODE);
-
- snapshot->state = gtk_snapshot_state_new (snapshot->state, snapshot->state->clip_region, node);
+ return result;
}
/**
* gtk_snapshot_push:
* @snapshot: a #GtkSnapshot
+ * @keep_coordinates: If %TRUE, the current offset and clip will be kept.
+ * Otherwise, the clip will be unset and the offset will be reset to
+ * (0, 0).
* @bounds: the bounds for the new node
* @name: (transfer none): a printf() style format string for the name for the new node
* @...: arguments to insert into the format string
@@ -152,30 +145,38 @@ gtk_snapshot_push_node (GtkSnapshot *snapshot,
*/
void
gtk_snapshot_push (GtkSnapshot *snapshot,
+ gboolean keep_coordinates,
const char *name,
...)
{
- GskRenderNode *node;
-
- node = gsk_container_node_new ();
+ char *str;
if (name)
{
va_list args;
- char *str;
va_start (args, name);
str = g_strdup_vprintf (name, args);
va_end (args);
-
- gsk_render_node_set_name (node, str);
-
- g_free (str);
}
+ else
+ str = NULL;
- gtk_snapshot_append_node (snapshot, node);
- gtk_snapshot_push_node (snapshot, node);
- gsk_render_node_unref (node);
+ if (keep_coordinates)
+ {
+ snapshot->state = gtk_snapshot_state_new (snapshot->state,
+ str,
+ snapshot->state->clip_region,
+ snapshot->state->translate_x,
+ snapshot->state->translate_y);
+ }
+ else
+ {
+ snapshot->state = gtk_snapshot_state_new (snapshot->state,
+ str,
+ NULL,
+ 0, 0);
+ }
}
/**
@@ -185,23 +186,45 @@ gtk_snapshot_push (GtkSnapshot *snapshot,
* Removes the top element from the stack of render nodes,
* making the node underneath the current node again.
*
+ * Returns: (transfer full) (allow none): A #GskRenderNode for
+ * the contents that were rendered to @snapshot since
+ * the corresponding gtk_snapshot_push() call
+ *
* Since: 3.90
*/
-void
+GskRenderNode *
gtk_snapshot_pop (GtkSnapshot *snapshot)
{
GtkSnapshotState *state;
+ GskRenderNode *node;
if (snapshot->state == NULL)
{
g_warning ("Too many gtk_snapshot_pop() calls.");
- return;
+ return NULL;
}
state = snapshot->state;
snapshot->state = state->parent;
+ if (state->nodes->len == 0)
+ {
+ node = NULL;
+ }
+ else if (state->nodes->len == 1)
+ {
+ node = gsk_render_node_ref (g_ptr_array_index (state->nodes, 0));
+ }
+ else
+ {
+ node = gsk_container_node_new ((GskRenderNode **) state->nodes->pdata,
+ state->nodes->len);
+ gsk_render_node_set_name (node, state->name);
+ }
+
gtk_snapshot_state_free (state);
+
+ return node;
}
/**
@@ -288,7 +311,7 @@ gtk_snapshot_append_node (GtkSnapshot *snapshot,
if (snapshot->state)
{
- gsk_container_node_append_child (snapshot->state->node, node);
+ g_ptr_array_add (snapshot->state->nodes, gsk_render_node_ref (node));
}
else
{
diff --git a/gtk/gtksnapshot.h b/gtk/gtksnapshot.h
index 6acb5aa..2c62533 100644
--- a/gtk/gtksnapshot.h
+++ b/gtk/gtksnapshot.h
@@ -41,13 +41,11 @@ GskRenderer * gtk_snapshot_get_renderer (const GtkSnapshot
GDK_AVAILABLE_IN_3_90
void gtk_snapshot_push (GtkSnapshot *snapshot,
+ gboolean keep_coordinates,
const char *name,
- ...) G_GNUC_PRINTF(2, 3);
+ ...) G_GNUC_PRINTF (3, 4);
GDK_AVAILABLE_IN_3_90
-void gtk_snapshot_push_node (GtkSnapshot *snapshot,
- GskRenderNode *node);
-GDK_AVAILABLE_IN_3_90
-void gtk_snapshot_pop (GtkSnapshot *snapshot);
+GskRenderNode * gtk_snapshot_pop (GtkSnapshot *snapshot)
G_GNUC_WARN_UNUSED_RESULT;
GDK_AVAILABLE_IN_3_90
void gtk_snapshot_translate_2d (GtkSnapshot *snapshot,
diff --git a/gtk/gtksnapshotprivate.h b/gtk/gtksnapshotprivate.h
index 54b3a6b..eb8cbac 100644
--- a/gtk/gtksnapshotprivate.h
+++ b/gtk/gtksnapshotprivate.h
@@ -27,7 +27,8 @@ typedef struct _GtkSnapshotState GtkSnapshotState;
struct _GtkSnapshotState {
GtkSnapshotState *parent;
- GskRenderNode *node;
+ char *name;
+ GPtrArray *nodes;
cairo_region_t *clip_region;
double translate_x;
@@ -37,7 +38,6 @@ struct _GtkSnapshotState {
struct _GtkSnapshot {
GtkSnapshotState *state;
- GskRenderNode *root;
GskRenderer *renderer;
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]