[gegl] Made point filter and composers able to operate in-place.



commit 1bb5a9c74a958646b6391afbdd0e24f204878402
Author: �yvind Kolås <pippin gimp org>
Date:   Thu Nov 12 22:33:52 2009 +0000

    Made point filter and composers able to operate in-place.
    
    If the incoming buffer is not a gegl_cache, it is of the correct format
    and large enough to satisfy the entire result rect and we are the only
    consumer of this pad we can operate directly on the passed input buffer
    instead of making a copy.

 gegl/operation/gegl-operation-filter.c         |   40 +++++++++++++++++++++++-
 gegl/operation/gegl-operation-point-composer.c |   20 +++++++++---
 2 files changed, 54 insertions(+), 6 deletions(-)
---
diff --git a/gegl/operation/gegl-operation-filter.c b/gegl/operation/gegl-operation-filter.c
index d0341c4..8c85024 100644
--- a/gegl/operation/gegl-operation-filter.c
+++ b/gegl/operation/gegl-operation-filter.c
@@ -24,6 +24,7 @@
 #include "gegl.h"
 #include "gegl-types-internal.h"
 #include "gegl-operation-filter.h"
+#include "gegl-operation-point-filter.h"
 #include "gegl-utils.h"
 #include "graph/gegl-node.h"
 #include "graph/gegl-connection.h"
@@ -178,6 +179,33 @@ set_property (GObject      *object,
     }
 }
 
+gboolean gegl_can_passthrough (GeglOperation       *operation,
+                               GeglBuffer          *input,
+                               const GeglRectangle *result);
+
+gboolean gegl_can_passthrough (GeglOperation       *operation,
+                               GeglBuffer          *input,
+                               const GeglRectangle *result)
+{
+  if (!input || 
+      GEGL_IS_CACHE (input))
+    return FALSE;
+  if (input->format == gegl_operation_get_format (operation, "output") &&
+      gegl_rectangle_contains (gegl_buffer_get_extent (input), result))
+    {
+      GeglPad *pad;
+      gchar *outpad;
+      gint connections;
+      GeglNode *producer = gegl_node_get_producer (operation->node, "input", &outpad);
+      g_assert (producer);
+      pad = gegl_node_get_pad (producer, outpad);
+      connections = gegl_pad_get_num_connections (pad);
+      if (connections == 1)
+        return TRUE;
+    }
+  return FALSE;
+}
+
 
 static gboolean
 gegl_operation_filter_process (GeglOperation   *operation,
@@ -203,7 +231,17 @@ gegl_operation_filter_process (GeglOperation   *operation,
     }
 
   input  = gegl_operation_context_get_source (context, "input");
-  output = gegl_operation_context_get_target (context, "output");
+  if (GEGL_IS_OPERATION_POINT_FILTER (operation) &&
+      gegl_can_passthrough (operation, input, result))
+    {
+      output = g_object_ref (input);
+      gegl_operation_context_take_object (context, "output", G_OBJECT (output));
+    }
+  else
+    {
+      output = gegl_operation_context_get_target (context, "output");
+    }
+
     {
       success = klass->process (operation, input, output, result);
 
diff --git a/gegl/operation/gegl-operation-point-composer.c b/gegl/operation/gegl-operation-point-composer.c
index 52775c2..2edaae5 100644
--- a/gegl/operation/gegl-operation-point-composer.c
+++ b/gegl/operation/gegl-operation-point-composer.c
@@ -71,14 +71,18 @@ gegl_operation_point_composer_init (GeglOperationPointComposer *self)
 
 }
 
+gboolean gegl_can_passthrough (GeglOperation       *operation,
+                               GeglBuffer          *input,
+                               const GeglRectangle *result);
+
 /* we replicate the process function from GeglOperationComposer to be
  * able to bail out earlier for some common processing time pitfalls
  */
 static gboolean
-gegl_operation_composer_process2 (GeglOperation       *operation,
-                                  GeglOperationContext     *context,
-                                  const gchar         *output_prop,
-                                  const GeglRectangle *result)
+gegl_operation_composer_process2 (GeglOperation        *operation,
+                                  GeglOperationContext *context,
+                                  const gchar          *output_prop,
+                                  const GeglRectangle  *result)
 {
   GeglOperationComposerClass *klass   = GEGL_OPERATION_COMPOSER_GET_CLASS (operation);
   GeglBuffer                 *input;
@@ -95,7 +99,13 @@ gegl_operation_composer_process2 (GeglOperation       *operation,
   input = gegl_operation_context_get_source (context, "input");
   aux   = gegl_operation_context_get_source (context, "aux");
 
-  output = gegl_operation_context_get_target (context, "output");
+  if (can_passthrough (operation, input, result))
+    {
+      output = g_object_ref (input);
+      gegl_operation_context_take_object (context, "output", G_OBJECT (output));
+    }
+  else
+    output = gegl_operation_context_get_target (context, "output");
     
     {
       gboolean done = FALSE;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]