[gimp] app: maintain warp tool graph structure during undo/redo
- From: N/A <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: maintain warp tool graph structure during undo/redo
- Date: Wed, 17 May 2017 00:39:15 +0000 (UTC)
commit 9c7cae6220ead9061e6368a8a3ca07a4a9db38f1
Author: Ell <ell_se yahoo com>
Date: Tue May 16 19:34:22 2017 -0400
app: maintain warp tool graph structure during undo/redo
When undoing a warp stroke, don't disconnect the current warp node
from its predecessor; rather, keep the graph as-is, and only
reconnect the render_node to the previous node. This avoids
invalidating the undone node, so that redoing it (which, likewise,
only involves reconnecting the render_node) doesn't require
reprocessing, making it much faster.
app/tools/gimpwarptool.c | 37 +++++++++++++++++++++++++++++--------
1 files changed, 29 insertions(+), 8 deletions(-)
---
diff --git a/app/tools/gimpwarptool.c b/app/tools/gimpwarptool.c
index 1359a71..b34deaa 100644
--- a/app/tools/gimpwarptool.c
+++ b/app/tools/gimpwarptool.c
@@ -121,6 +121,7 @@ static void gimp_warp_tool_add_op (GimpWarpTool *wt,
GeglNode *op);
static void gimp_warp_tool_remove_op (GimpWarpTool *wt,
GeglNode *op);
+static void gimp_warp_tool_free_op (GeglNode *op);
static void gimp_warp_tool_animate (GimpWarpTool *wt);
@@ -304,7 +305,7 @@ gimp_warp_tool_button_release (GimpTool *tool,
gimp_warp_tool_undo (tool, display);
/* the just undone stroke has no business on the redo stack */
- g_object_unref (wt->redo_stack->data);
+ gimp_warp_tool_free_op (wt->redo_stack->data);
wt->redo_stack = g_list_remove_link (wt->redo_stack, wt->redo_stack);
}
else
@@ -312,7 +313,8 @@ gimp_warp_tool_button_release (GimpTool *tool,
if (wt->redo_stack)
{
/* the redo stack becomes invalid by actually doing a stroke */
- g_list_free_full (wt->redo_stack, (GDestroyNotify) g_object_unref);
+ g_list_free_full (wt->redo_stack,
+ (GDestroyNotify) gimp_warp_tool_free_op);
wt->redo_stack = NULL;
}
@@ -483,6 +485,7 @@ gimp_warp_tool_undo (GimpTool *tool,
{
GimpWarpTool *wt = GIMP_WARP_TOOL (tool);
GeglNode *to_delete;
+ GeglNode *prev_node;
const gchar *type;
if (! wt->render_node)
@@ -494,11 +497,17 @@ gimp_warp_tool_undo (GimpTool *tool,
if (strcmp (type, "gegl:warp"))
return FALSE;
- wt->redo_stack = g_list_prepend (wt->redo_stack, g_object_ref (to_delete));
+ wt->redo_stack = g_list_prepend (wt->redo_stack, to_delete);
- gimp_warp_tool_remove_op (wt, to_delete);
+ /* we connect render_node to the previous node, but keep the current node
+ * in the graph, connected to the previous node as well, so that it doesn't
+ * get invalidated and maintains its cache. this way, redoing it doesn't
+ * require reprocessing.
+ */
+ prev_node = gegl_node_get_producer (to_delete, "input", NULL);
- gegl_node_remove_child (wt->graph, to_delete);
+ gegl_node_connect_to (prev_node, "output",
+ wt->render_node, "aux");
gimp_warp_tool_update_stroke (wt, to_delete);
@@ -517,8 +526,8 @@ gimp_warp_tool_redo (GimpTool *tool,
to_add = wt->redo_stack->data;
- gimp_warp_tool_add_op (wt, to_add);
- g_object_unref (to_add);
+ gegl_node_connect_to (to_add, "output",
+ wt->render_node, "aux");
wt->redo_stack = g_list_remove_link (wt->redo_stack, wt->redo_stack);
@@ -651,7 +660,7 @@ gimp_warp_tool_halt (GimpWarpTool *wt)
if (wt->redo_stack)
{
- g_list_free_full (wt->redo_stack, (GDestroyNotify) g_object_unref);
+ g_list_free (wt->redo_stack);
wt->redo_stack = NULL;
}
@@ -871,6 +880,18 @@ gimp_warp_tool_remove_op (GimpWarpTool *wt,
}
static void
+gimp_warp_tool_free_op (GeglNode *op)
+{
+ GeglNode *parent;
+
+ parent = gegl_node_get_parent (op);
+
+ g_assert (parent != NULL);
+
+ gegl_node_remove_child (parent, op);
+}
+
+static void
gimp_warp_tool_animate (GimpWarpTool *wt)
{
GimpTool *tool = GIMP_TOOL (wt);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]