[gegl] operation, graph: use uninitialized buffers for operation output



commit 6e9610e65cc9d36da57358a4720afbf122cd6e70
Author: Ell <ell_se yahoo com>
Date:   Wed May 6 11:58:06 2020 +0300

    operation, graph: use uninitialized buffers for operation output
    
    In gegl_operation_context_get_target(), return uninitialized
    buffers for operation output; likewise, in GeglNode, use an
    uninitialized buffer for the cache.  This avoids unnecessarily
    zero-initializaing output tiles when individual tiles are split
    across threads, or when not generating output on a per-tile basis
    (e.g., when generating output line-by-line).
    
    Note that since any operation can potentially be cached, and
    therefore have arbitrary data in its output buffer, operations
    should already overwrite the entire requested region when
    processing, and, conversely, consumers should only depend on the
    contents of the requested region.
    
    Allow reverting back to initialized output buffers by settings the
    GEGL_OPERATION_INIT_OUTPUT environment varaible to 1.

 gegl/graph/gegl-node.c                          |  9 +++--
 gegl/operation/gegl-operation-context-private.h |  2 +
 gegl/operation/gegl-operation-context.c         | 52 ++++++++++++++++++-------
 3 files changed, 47 insertions(+), 16 deletions(-)
---
diff --git a/gegl/graph/gegl-node.c b/gegl/graph/gegl-node.c
index b7c718fc8..9363ef955 100644
--- a/gegl/graph/gegl-node.c
+++ b/gegl/graph/gegl-node.c
@@ -43,6 +43,7 @@
 
 #include "operation/gegl-operation.h"
 #include "operation/gegl-operation-private.h"
+#include "operation/gegl-operation-context-private.h"
 #include "operation/gegl-operations.h"
 #include "operation/gegl-operation-meta.h"
 
@@ -2066,9 +2067,11 @@ gegl_node_get_cache (GeglNode *node)
     {
       GeglCache *cache;
 
-      cache = g_object_new (GEGL_TYPE_CACHE,
-                            "format", format,
-                            NULL);
+      cache = g_object_new (
+        GEGL_TYPE_CACHE,
+        "format",      format,
+        "initialized", gegl_operation_context_get_init_output (),
+        NULL);
 
       gegl_object_set_has_forked (G_OBJECT (cache));
       gegl_buffer_set_extent (GEGL_BUFFER (cache), &node->have_rect);
diff --git a/gegl/operation/gegl-operation-context-private.h b/gegl/operation/gegl-operation-context-private.h
index b624c4756..2401f4cb5 100644
--- a/gegl/operation/gegl-operation-context-private.h
+++ b/gegl/operation/gegl-operation-context-private.h
@@ -89,6 +89,8 @@ GeglRectangle  *gegl_operation_context_get_result_rect (GeglOperationContext *no
 void            gegl_operation_context_set_result_rect (GeglOperationContext *node,
                                                         const GeglRectangle  *rect);
 
+gboolean        gegl_operation_context_get_init_output (void);
+
 G_END_DECLS
 
 #endif /* __GEGL_OPERATION_CONTEXT_PRIVATE_H__ */
diff --git a/gegl/operation/gegl-operation-context.c b/gegl/operation/gegl-operation-context.c
index a70a5ee8b..939dcfe21 100644
--- a/gegl/operation/gegl-operation-context.c
+++ b/gegl/operation/gegl-operation-context.c
@@ -20,6 +20,7 @@
 
 #include "config.h"
 
+#include <stdlib.h>
 #include <string.h>
 #include <math.h>
 
@@ -302,7 +303,7 @@ GeglBuffer *
 gegl_operation_context_get_target (GeglOperationContext *context,
                                    const gchar          *padname)
 {
-  GeglBuffer          *output;
+  GeglBuffer          *output         = NULL;
   const GeglRectangle *result;
   const Babl          *format;
   GeglNode            *node;
@@ -350,24 +351,28 @@ gegl_operation_context_get_target (GeglOperationContext *context,
        * the current caching mechanism needs to be redesigned
        */
       if (gegl_rectangle_contains (gegl_buffer_get_extent (cache), result))
+        output = g_object_ref (cache);
+    }
+
+  if (! output)
+    {
+      if (linear_buffers)
         {
-          output = g_object_ref (cache);
+          output = gegl_buffer_linear_new (result, format);
         }
       else
         {
-          if (linear_buffers)
-            output = gegl_buffer_linear_new (result, format);
-          else
-            output = gegl_buffer_new (result, format);
+          output = g_object_new (
+            GEGL_TYPE_BUFFER,
+            "x",           result->x,
+            "y",           result->y,
+            "width",       result->width,
+            "height",      result->height,
+            "format",      format,
+            "initialized", gegl_operation_context_get_init_output (),
+            NULL);
         }
     }
-  else
-    {
-      if (linear_buffers)
-        output = gegl_buffer_linear_new (result, format);
-      else
-        output = gegl_buffer_new (result, format);
-    }
 
   gegl_operation_context_take_object (context, padname, G_OBJECT (output));
 
@@ -540,3 +545,24 @@ gegl_operation_context_dup_input_maybe_copy (GeglOperationContext *context,
 
   return result;
 }
+
+gboolean
+gegl_operation_context_get_init_output (void)
+{
+  static gint init_output = -1;
+
+  if (init_output < 0)
+    {
+      if (g_getenv ("GEGL_OPERATION_INIT_OUTPUT"))
+        {
+          init_output = atoi (g_getenv ("GEGL_OPERATION_INIT_OUTPUT")) ?
+            TRUE : FALSE;
+        }
+      else
+        {
+          init_output = FALSE;
+        }
+    }
+
+  return init_output;
+}


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