From 9c30bb4213d89413a65d11fc4ab39266e911da6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=98yvind=20Kol=C3=A5s?= Date: Mon, 14 Jul 2014 00:17:17 +0200 Subject: [PATCH] GeglNode: added passthrough property This boolean, which lives on the node; not the operation makes the contained op act like gegl:nop. --- gegl/gegl-xml.c | 8 +++++++ gegl/graph/gegl-node-private.h | 2 ++ gegl/graph/gegl-node.c | 37 ++++++++++++++++++++++++++++++++- gegl/graph/gegl-node.h | 6 ++++++ gegl/operation/gegl-operation.c | 35 +++++++++++++++++++++++++++++-- 5 files changed, 85 insertions(+), 3 deletions(-) diff --git a/gegl/gegl-xml.c b/gegl/gegl-xml.c index 41ca7e40..96815cdc 100644 --- a/gegl/gegl-xml.c +++ b/gegl/gegl-xml.c @@ -1073,6 +1073,10 @@ add_stack (SerializeState *ss, xml_attr (ss->buf, "operation", class); if (id != NULL) xml_attr (ss->buf, "id", id); + + if (gegl_node_get_passthrough (iter) == TRUE) + xml_attr (ss->buf, "passthrough", "true"); + g_free (name); g_free (class); } @@ -1103,6 +1107,10 @@ add_stack (SerializeState *ss, xml_attr (ss->buf, "operation", class); if (id != NULL) xml_attr (ss->buf, "id", id); + + if (gegl_node_get_passthrough (iter) == TRUE) + xml_attr (ss->buf, "passthrough", "true"); + g_free (name); g_free (class); } diff --git a/gegl/graph/gegl-node-private.h b/gegl/graph/gegl-node-private.h index 222d141d..f4581765 100644 --- a/gegl/graph/gegl-node-private.h +++ b/gegl/graph/gegl-node-private.h @@ -79,6 +79,8 @@ struct _GeglNode GMutex mutex; + gint passthrough; + /*< private >*/ GeglNodePrivate *priv; }; diff --git a/gegl/graph/gegl-node.c b/gegl/graph/gegl-node.c index 8fc8edc9..4ab21038 100644 --- a/gegl/graph/gegl-node.c +++ b/gegl/graph/gegl-node.c @@ -50,7 +50,8 @@ enum PROP_OPERATION, PROP_NAME, PROP_DONT_CACHE, - PROP_USE_OPENCL + PROP_USE_OPENCL, + PROP_PASSTHROUGH }; enum @@ -172,6 +173,14 @@ gegl_node_class_init (GeglNodeClass *klass) G_PARAM_CONSTRUCT | G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, PROP_PASSTHROUGH, + g_param_spec_boolean ("passthrough", + "Passthrough", + "Act as a nop, passing input unmodifed through to ouput.", + FALSE, + G_PARAM_CONSTRUCT | + G_PARAM_READWRITE)); + gegl_node_signals[INVALIDATED] = g_signal_new ("invalidated", G_TYPE_FROM_CLASS (klass), @@ -305,6 +314,10 @@ gegl_node_local_set_property (GObject *gobject, node->dont_cache = g_value_get_boolean (value); break; + case PROP_PASSTHROUGH: + node->passthrough = g_value_get_boolean (value); + break; + case PROP_USE_OPENCL: node->use_opencl = g_value_get_boolean (value); break; @@ -351,6 +364,10 @@ gegl_node_local_get_property (GObject *gobject, g_value_set_boolean (value, node->dont_cache); break; + case PROP_PASSTHROUGH: + g_value_set_boolean (value, node->passthrough); + break; + case PROP_USE_OPENCL: g_value_set_boolean (value, node->use_opencl); break; @@ -2128,3 +2145,21 @@ gegl_node_new (void) { return g_object_new (GEGL_TYPE_NODE, NULL); } + +gboolean +gegl_node_get_passthrough (GeglNode *node) +{ + g_return_val_if_fail (GEGL_IS_NODE (node), FALSE); + + return node->passthrough; +} + +void +gegl_node_set_passthrough (GeglNode *node, + gboolean passthrough) +{ + g_return_if_fail (GEGL_IS_NODE (node)); + + gegl_node_invalidated (node, NULL, TRUE); + node->passthrough = passthrough; +} diff --git a/gegl/graph/gegl-node.h b/gegl/graph/gegl-node.h index 5af5afe1..df76656e 100644 --- a/gegl/graph/gegl-node.h +++ b/gegl/graph/gegl-node.h @@ -667,6 +667,12 @@ GeglNode * gegl_node_new_from_file (const gchar *path); gchar * gegl_node_to_xml (GeglNode *node, const gchar *path_root); +gboolean gegl_node_get_passthrough (GeglNode *node); + +void gegl_node_set_passthrough (GeglNode *node, + gboolean passthrough); + + G_END_DECLS #endif /* __GEGL_NODE_H__ */ diff --git a/gegl/operation/gegl-operation.c b/gegl/operation/gegl-operation.c index add450af..4bcf0294 100644 --- a/gegl/operation/gegl-operation.c +++ b/gegl/operation/gegl-operation.c @@ -14,7 +14,7 @@ * License along with GEGL; if not, see . * * Copyright 2003 Calvin Williamson - * 2005-2008 Øyvind Kolås + * 2005-2009,2011-2014 Øyvind Kolås */ #include "config.h" @@ -159,6 +159,13 @@ gegl_operation_process (GeglOperation *operation, return TRUE; } + if (operation->node->passthrough) + { + GeglBuffer *input = GEGL_BUFFER (gegl_operation_context_get_object (context, "input")); + gegl_operation_context_take_object (context, output_pad, g_object_ref (G_OBJECT (input))); + return TRUE; + } + g_return_val_if_fail (klass->process, FALSE); return klass->process (operation, context, output_pad, result, level); @@ -173,7 +180,16 @@ gegl_operation_get_bounding_box (GeglOperation *self) GeglOperationClass *klass = GEGL_OPERATION_GET_CLASS (self); GeglRectangle rect = { 0, 0, 0, 0 }; - if (klass->get_bounding_box) + if (self->node->passthrough) + { + GeglRectangle result = { 0, 0, 0, 0 }; + GeglRectangle *in_rect; + in_rect = gegl_operation_source_get_bounding_box (self, "input"); + if (in_rect) + return *in_rect; + return result; + } + else if (klass->get_bounding_box) return klass->get_bounding_box (self); return rect; @@ -191,6 +207,9 @@ gegl_operation_get_invalidated_by_change (GeglOperation *self, g_return_val_if_fail (input_pad != NULL, retval); g_return_val_if_fail (input_region != NULL, retval); + if (self->node && self->node->passthrough) + return *input_region; + klass = GEGL_OPERATION_GET_CLASS (self); if (input_region->width == 0 || @@ -208,6 +227,9 @@ get_required_for_output (GeglOperation *operation, const gchar *input_pad, const GeglRectangle *roi) { + if (operation->node->passthrough) + return *roi; + if (operation->node->is_graph) { return gegl_operation_get_required_for_output (operation, input_pad, roi); @@ -227,6 +249,9 @@ gegl_operation_get_required_for_output (GeglOperation *operation, roi->height == 0) return *roi; + if (operation->node->passthrough) + return *roi; + g_assert (klass->get_required_for_output); return klass->get_required_for_output (operation, input_pad, roi); @@ -240,6 +265,9 @@ gegl_operation_get_cached_region (GeglOperation *operation, { GeglOperationClass *klass = GEGL_OPERATION_GET_CLASS (operation); + if (operation->node->passthrough) + return *roi; + if (!klass->get_cached_region) { return *roi; @@ -280,6 +308,9 @@ gegl_operation_prepare (GeglOperation *self) g_return_if_fail (GEGL_IS_OPERATION (self)); + if (self->node->passthrough) + return; + klass = GEGL_OPERATION_GET_CLASS (self); /* build OpenCL kernel */