[gegl] operation: make in-place handling something ops can opt in/out of



commit 19eb15d1696c99594687e6cb72d61ba41e878e2d
Author: Øyvind Kolås <pippin gimp org>
Date:   Tue Jun 24 05:42:04 2014 +0200

    operation: make in-place handling something ops can opt in/out of
    
    Adding a flag to operation, that is used by the implementation/further
    subclass to declare that in-place processing should be done if possible. This
    also adds that capability to the base class of GIMPs layer modes.

 gegl/operation/gegl-operation-composer3.c       |   24 ++++++++-
 gegl/operation/gegl-operation-point-composer.c  |    9 ++-
 gegl/operation/gegl-operation-point-composer3.c |   68 +----------------------
 gegl/operation/gegl-operation-point-filter.c    |    5 +-
 gegl/operation/gegl-operation.h                 |    6 ++-
 5 files changed, 40 insertions(+), 72 deletions(-)
---
diff --git a/gegl/operation/gegl-operation-composer3.c b/gegl/operation/gegl-operation-composer3.c
index 339c813..7a52849 100644
--- a/gegl/operation/gegl-operation-composer3.c
+++ b/gegl/operation/gegl-operation-composer3.c
@@ -113,6 +113,7 @@ gegl_operation_composer3_process (GeglOperation        *operation,
                                   gint                  level)
 {
   GeglOperationComposer3Class *klass   = GEGL_OPERATION_COMPOSER3_GET_CLASS (operation);
+  GeglOperationClass          *op_class = GEGL_OPERATION_CLASS (klass);
   GeglBuffer                  *input;
   GeglBuffer                  *aux;
   GeglBuffer                  *aux2;
@@ -124,11 +125,32 @@ gegl_operation_composer3_process (GeglOperation        *operation,
       g_warning ("requested processing of %s pad on a composer", output_prop);
       return FALSE;
     }
+  output = gegl_operation_context_get_target (context, "output");
+
+  if (result->width == 0 || result->height == 0)
+    return TRUE;
+
+  if (result->width == 0 || result->height == 0)
+  {
+    output = gegl_operation_context_get_target (context, "output");
+    return TRUE;
+  }
 
   input = gegl_operation_context_get_source (context, "input");
+
+  if (op_class->want_in_place && 
+      gegl_can_do_inplace_processing (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");
+    }
+
   aux   = gegl_operation_context_get_source (context, "aux");
   aux2  = gegl_operation_context_get_source (context, "aux2");
-  output = gegl_operation_context_get_target (context, "output");
 
   /* A composer with a NULL aux, can still be valid, the
    * subclass has to handle it.
diff --git a/gegl/operation/gegl-operation-point-composer.c b/gegl/operation/gegl-operation-point-composer.c
index ec99365..8c52c08 100644
--- a/gegl/operation/gegl-operation-point-composer.c
+++ b/gegl/operation/gegl-operation-point-composer.c
@@ -66,6 +66,7 @@ gegl_operation_point_composer_class_init (GeglOperationPointComposerClass *klass
   operation_class->prepare = prepare;
   operation_class->no_cache = FALSE;
   operation_class->process = gegl_operation_composer_process2;
+  operation_class->want_in_place = TRUE;
 
   klass->process = NULL;
   klass->cl_process = NULL;
@@ -88,6 +89,7 @@ gegl_operation_composer_process2 (GeglOperation        *operation,
                                   gint                  level)
 {
   GeglOperationComposerClass *klass   = GEGL_OPERATION_COMPOSER_GET_CLASS (operation);
+  GeglOperationClass         *op_class = (void*)klass;
   GeglBuffer                 *input;
   GeglBuffer                 *aux;
   GeglBuffer                 *output;
@@ -102,13 +104,16 @@ gegl_operation_composer_process2 (GeglOperation        *operation,
   input = gegl_operation_context_get_source (context, "input");
   aux   = gegl_operation_context_get_source (context, "aux");
 
-  if (gegl_can_do_inplace_processing (operation, input, result))
+  if (op_class->want_in_place && 
+      gegl_can_do_inplace_processing (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");
+    {
+      output = gegl_operation_context_get_target (context, "output");
+    }
 
     {
       if (result->width == 0 || result->height == 0)
diff --git a/gegl/operation/gegl-operation-point-composer3.c b/gegl/operation/gegl-operation-point-composer3.c
index fc77236..fd0faa1 100644
--- a/gegl/operation/gegl-operation-point-composer3.c
+++ b/gegl/operation/gegl-operation-point-composer3.c
@@ -35,13 +35,6 @@ static gboolean gegl_operation_point_composer3_process
                                const GeglRectangle *result,
                                gint                 level);
 
-static gboolean
-gegl_operation_composer3_process2 (GeglOperation        *operation,
-                                   GeglOperationContext *context,
-                                   const gchar          *output_prop,
-                                   const GeglRectangle  *result,
-                                   gint                  level);
-
 G_DEFINE_TYPE (GeglOperationPointComposer3, gegl_operation_point_composer3, GEGL_TYPE_OPERATION_COMPOSER3)
 
 static void prepare (GeglOperation *operation)
@@ -63,7 +56,7 @@ gegl_operation_point_composer3_class_init (GeglOperationPointComposer3Class *kla
   composer_class->process = gegl_operation_point_composer3_process;
   operation_class->prepare = prepare;
   operation_class->no_cache =TRUE;
-  operation_class->process = gegl_operation_composer3_process2;
+  operation_class->want_in_place = TRUE;
 }
 
 static void
@@ -72,65 +65,6 @@ gegl_operation_point_composer3_init (GeglOperationPointComposer3 *self)
 
 }
 
-/* we replicate the process function from GeglOperationComposer3 to be
- * able to bail out earlier for some common processing time pitfalls
- */
-static gboolean
-gegl_operation_composer3_process2 (GeglOperation        *operation,
-                                   GeglOperationContext *context,
-                                   const gchar          *output_prop,
-                                   const GeglRectangle  *result,
-                                   gint                  level)
-{
-  GeglOperationComposer3Class *klass   = GEGL_OPERATION_COMPOSER3_GET_CLASS (operation);
-  GeglBuffer                  *input;
-  GeglBuffer                  *aux;
-  GeglBuffer                  *aux2;
-  GeglBuffer                  *output;
-  gboolean                     success = FALSE;
-
-  if (strcmp (output_prop, "output"))
-    {
-      g_warning ("requested processing of %s pad on a composer", output_prop);
-      return FALSE;
-    }
-
-  input = gegl_operation_context_get_source (context, "input");
-  aux   = gegl_operation_context_get_source (context, "aux");
-  aux2  = gegl_operation_context_get_source (context, "aux2");
-
-  /* we could be even faster by not alway writing to this buffer, that
-   * would potentially break other assumptions we want to make from the
-   * GEGL core so we avoid doing that
-   */
-  output = gegl_operation_context_get_target (context, "output");
-
-
-  if (input != NULL ||
-      aux != NULL ||
-      aux2 != NULL)
-    {
-      if (result->width == 0 || result->height == 0)
-        success = TRUE;
-      else
-        success = klass->process (operation, input, aux, aux2, output, result, level);
-
-      if (input)
-         g_object_unref (input);
-      if (aux)
-         g_object_unref (aux);
-      if (aux2)
-         g_object_unref (aux2);
-    }
-  else
-    {
-      g_warning ("%s received NULL input, aux, and aux2",
-                 gegl_node_get_operation (operation->node));
-    }
-
-  return success;
-}
-
 static gboolean
 gegl_operation_point_composer3_process (GeglOperation       *operation,
                                         GeglBuffer          *input,
diff --git a/gegl/operation/gegl-operation-point-filter.c b/gegl/operation/gegl-operation-point-filter.c
index 886f8f9..a30abbb 100644
--- a/gegl/operation/gegl-operation-point-filter.c
+++ b/gegl/operation/gegl-operation-point-filter.c
@@ -60,6 +60,7 @@ gegl_operation_point_filter_class_init (GeglOperationPointFilterClass *klass)
   operation_class->process = gegl_operation_point_filter_op_process;
   operation_class->prepare = prepare;
   operation_class->no_cache = TRUE;
+  operation_class->want_in_place = TRUE;
 
   klass->process = NULL;
   klass->cl_process = NULL;
@@ -198,13 +199,15 @@ static gboolean gegl_operation_point_filter_op_process
                                const GeglRectangle  *roi,
                                gint                  level)
 {
+  GeglOperationClass       *klass = GEGL_OPERATION_GET_CLASS (operation);
   GeglBuffer               *input;
   GeglBuffer               *output;
   gboolean                  success = FALSE;
 
   input = gegl_operation_context_get_source (context, "input");
 
-  if (gegl_can_do_inplace_processing (operation, input, roi))
+  if (klass->want_in_place && 
+      gegl_can_do_inplace_processing (operation, input, roi))
     {
       output = g_object_ref (input);
       gegl_operation_context_take_object (context, "output", G_OBJECT (output));
diff --git a/gegl/operation/gegl-operation.h b/gegl/operation/gegl-operation.h
index 45b582f..cd1cb59 100644
--- a/gegl/operation/gegl-operation.h
+++ b/gegl/operation/gegl-operation.h
@@ -78,7 +78,11 @@ struct _GeglOperationClass
 
   guint           no_cache      :1;  /* do not create a cache for this operation */
   guint           opencl_support:1;
-  guint64         bit_pad:62;
+  guint           want_in_place:1; /* if possible to use for in-place
+                                      processing, making output buffer =
+                                      input buffer.
+                                      */
+  guint64         bit_pad:61;
 
   /* attach this operation with a GeglNode, override this if you are creating a
    * GeglGraph, it is already defined for Filters/Sources/Composers.


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