[gegl] Annotate temporary buffers to restrict in-place processing.



commit eb7fb2bf212d5f823e87649c2e138a6bfe85031b
Author: �yvind Kolås <pippin gimp org>
Date:   Sun Dec 6 16:58:22 2009 +0000

    Annotate temporary buffers to restrict in-place processing.
    
    In place processing should not occur on buffers that are used in other
    parts of the graph (and potentially also do in place processing on
    the input). gegl-eval-visitor set's a "no in-place" data on

 gegl/operation/gegl-operation-context.c      |    4 +---
 gegl/operation/gegl-operation-context.h      |    2 ++
 gegl/operation/gegl-operation-point-filter.c |   17 +++++------------
 gegl/process/gegl-eval-visitor.c             |   16 ++++++++++++++++
 operations/affine/affine.c                   |    6 ++++++
 operations/core/crop.c                       |    4 ++++
 6 files changed, 34 insertions(+), 15 deletions(-)
---
diff --git a/gegl/operation/gegl-operation-context.c b/gegl/operation/gegl-operation-context.c
index 1fbc65c..3e21908 100644
--- a/gegl/operation/gegl-operation-context.c
+++ b/gegl/operation/gegl-operation-context.c
@@ -32,8 +32,6 @@
 
 #include "operation/gegl-operation.h"
 
-static GValue * gegl_operation_context_get_value    (GeglOperationContext *self,
-                                                const gchar     *property_name);
 static GValue *
 gegl_operation_context_add_value (GeglOperationContext *self,
                                   const gchar          *property_name,
@@ -149,7 +147,7 @@ lookup_property (gconstpointer a,
   return strcmp (property->name, property_name);
 }
 
-static GValue *
+GValue *
 gegl_operation_context_get_value (GeglOperationContext *self,
                                   const gchar          *property_name)
 {
diff --git a/gegl/operation/gegl-operation-context.h b/gegl/operation/gegl-operation-context.h
index 55f21d0..b52cdd9 100644
--- a/gegl/operation/gegl-operation-context.h
+++ b/gegl/operation/gegl-operation-context.h
@@ -66,6 +66,8 @@ void            gegl_operation_context_take_object     (GeglOperationContext *co
 void            gegl_operation_context_set_property    (GeglOperationContext *self,
                                                         const gchar          *name,
                                                         const GValue         *value);
+GValue        * gegl_operation_context_get_value       (GeglOperationContext *self,
+                                                        const gchar          *property_name);
 void            gegl_operation_context_get_property    (GeglOperationContext *self,
                                                         const gchar          *name,
                                                         GValue               *value);
diff --git a/gegl/operation/gegl-operation-point-filter.c b/gegl/operation/gegl-operation-point-filter.c
index cd24632..c30adee 100644
--- a/gegl/operation/gegl-operation-point-filter.c
+++ b/gegl/operation/gegl-operation-point-filter.c
@@ -104,19 +104,13 @@ gboolean gegl_can_passthrough (GeglOperation       *operation,
   if (!input || 
       GEGL_IS_CACHE (input))
     return FALSE;
+  if (g_object_get_data (G_OBJECT (input), "no in-place"))
+    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 TRUE;
   return FALSE;
 }
 
@@ -155,4 +149,3 @@ static gboolean gegl_operation_point_filter_op_process
     g_object_unref (input);
   return success;
 }
-
diff --git a/gegl/process/gegl-eval-visitor.c b/gegl/process/gegl-eval-visitor.c
index 8c3cb87..cfe1182 100644
--- a/gegl/process/gegl-eval-visitor.c
+++ b/gegl/process/gegl-eval-visitor.c
@@ -90,6 +90,22 @@ gegl_eval_visitor_visit_pad (GeglVisitor *self,
           time      = gegl_ticks () - time;
 
           gegl_instrument ("process", gegl_node_get_operation (node), time);
+
+          if (gegl_pad_get_num_connections (pad) > 1)
+            {
+              /* Mark buffers that have been consumed by different parts of the
+               * graph so that in-place processing can be avoided on them.
+               */
+              GValue *value;
+              GeglBuffer *buffer;
+              value = gegl_operation_context_get_value (context, gegl_pad_get_name (pad));
+              if (value)
+                {
+                  buffer = g_value_get_object (value);
+                  if (buffer)
+                    g_object_set_data (G_OBJECT (buffer), "no in-place", (void*)0xf);
+                }
+            }
         }
     }
   else if (gegl_pad_is_input (pad))
diff --git a/operations/affine/affine.c b/operations/affine/affine.c
index 6bed8c0..bf11c20 100644
--- a/operations/affine/affine.c
+++ b/operations/affine/affine.c
@@ -764,6 +764,12 @@ gegl_affine_process (GeglOperation        *operation,
                                                     of source) */
                          NULL);
 
+      /* If the input buffer should not be in-place processed the
+       * shifted sub-buffer shold not either.
+       */
+      if (g_object_get_data (G_OBJECT (input), "no in-place"))
+        g_object_set_data (G_OBJECT (output), "no in-place", (void*)0xf);
+
       gegl_operation_context_take_object (context, "output", G_OBJECT (output));
 
       if (input != NULL)
diff --git a/operations/core/crop.c b/operations/core/crop.c
index 6a22651..9efb59a 100644
--- a/operations/core/crop.c
+++ b/operations/core/crop.c
@@ -137,7 +137,11 @@ gegl_crop_process (GeglOperation        *operation,
       GeglBuffer *output;
 
       output = gegl_buffer_create_sub_buffer (input, &extent);
+
+      if (g_object_get_data (G_OBJECT (input), "no in-place"))
+        g_object_set_data (G_OBJECT (output), "no in-place", (void*)0xf);
       gegl_operation_context_take_object (context, "output", G_OBJECT (output));
+
       g_object_unref (input);
       success = TRUE;
     }



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