[gimp/gimp-2-10] app: use GimpChunkIterator in gimp_gegl_apply_cached_operation()



commit 50dc4571cbb8a30ac8b9d576fc8c167a92ef6dad
Author: Ell <ell_se yahoo com>
Date:   Sat Jan 12 03:41:00 2019 -0500

    app: use GimpChunkIterator in gimp_gegl_apply_cached_operation()
    
    In gimp_gegl_apply_cached_operation(), replace the use of
    GeglProcessor with GimpChunkIterator, so that we use the same
    chunking logic as for rendering projections.  This has the
    advantage of better chunk alignment to the tile grid and dynamic
    chunk sizing, which improve performance.
    
    Use chunking even when there's no progress indication, since it
    generally results in better cache locality.
    
    (cherry picked from commit 4110f7b7b186a609d9ca9882cf1f8a1e12b4169e)

 app/gegl/gimp-gegl-apply-operation.c | 133 ++++++++++++++---------------------
 1 file changed, 54 insertions(+), 79 deletions(-)
---
diff --git a/app/gegl/gimp-gegl-apply-operation.c b/app/gegl/gimp-gegl-apply-operation.c
index ded1f43441..40b8cd7447 100644
--- a/app/gegl/gimp-gegl-apply-operation.c
+++ b/app/gegl/gimp-gegl-apply-operation.c
@@ -30,6 +30,7 @@
 
 #include "core/gimp-transform-utils.h"
 #include "core/gimp-utils.h"
+#include "core/gimpchunkiterator.h"
 #include "core/gimpprogress.h"
 
 #include "gimp-gegl-apply-operation.h"
@@ -77,15 +78,17 @@ gimp_gegl_apply_cached_operation (GeglBuffer          *src_buffer,
                                   gint                 n_valid_rects,
                                   gboolean             cancellable)
 {
-  GeglNode      *gegl;
-  GeglNode      *effect;
-  GeglNode      *dest_node;
-  GeglNode      *operation_src_node = NULL;
-  GeglRectangle  rect = { 0, };
-  GeglProcessor *processor          = NULL;
-  gboolean       progress_started   = FALSE;
-  gdouble        value;
-  gboolean       cancel             = FALSE;
+  GeglNode          *gegl;
+  GeglNode          *effect;
+  GeglNode          *dest_node;
+  GeglNode          *operation_src_node = NULL;
+  GimpChunkIterator *iter;
+  cairo_region_t    *region;
+  GeglRectangle      rect = { 0, };
+  gboolean           progress_started   = FALSE;
+  gboolean           cancel             = FALSE;
+  gint               all_pixels;
+  gint               done_pixels;
 
   g_return_val_if_fail (src_buffer == NULL || GEGL_IS_BUFFER (src_buffer), FALSE);
   g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), FALSE);
@@ -117,9 +120,9 @@ gimp_gegl_apply_cached_operation (GeglBuffer          *src_buffer,
       GeglNode *src_node;
 
       /* dup() because reading and writing the same buffer doesn't
-       * work with area ops when using a processor. See bug #701875.
+       * work with area ops when working in chunks. See bug #701875.
        */
-      if (progress && (src_buffer == dest_buffer))
+      if (src_buffer == dest_buffer)
         src_buffer = gegl_buffer_dup (src_buffer);
       else
         g_object_ref (src_buffer);
@@ -175,8 +178,6 @@ gimp_gegl_apply_cached_operation (GeglBuffer          *src_buffer,
 
   if (progress)
     {
-      processor = gegl_node_new_processor (dest_node, &rect);
-
       if (gimp_progress_is_active (progress))
         {
           if (undo_desc)
@@ -197,18 +198,21 @@ gimp_gegl_apply_cached_operation (GeglBuffer          *src_buffer,
           progress_started = TRUE;
         }
     }
-
-  if (cache)
+  else
     {
-      cairo_region_t *region;
-      gint            all_pixels;
-      gint            done_pixels = 0;
-      gint            n_rects;
-      gint            i;
+      cancelable = FALSE;
+    }
+
+  gegl_buffer_freeze_changed (dest_buffer);
 
-      region = cairo_region_create_rectangle ((cairo_rectangle_int_t *) &rect);
+  all_pixels  = rect.width * rect.height;
+  done_pixels = 0;
 
-      all_pixels = rect.width * rect.height;
+  region = cairo_region_create_rectangle ((cairo_rectangle_int_t *) &rect);
+
+  if (cache)
+    {
+      gint i;
 
       for (i = 0; i < n_valid_rects; i++)
         {
@@ -230,77 +234,48 @@ gimp_gegl_apply_cached_operation (GeglBuffer          *src_buffer,
           done_pixels += valid_rect.width * valid_rect.height;
 
           if (progress)
-            gimp_progress_set_value (progress,
-                                     (gdouble) done_pixels /
-                                     (gdouble) all_pixels);
+            {
+              gimp_progress_set_value (progress,
+                                       (gdouble) done_pixels /
+                                       (gdouble) all_pixels);
+            }
         }
+    }
 
-      n_rects = cairo_region_num_rectangles (region);
+  iter = gimp_chunk_iterator_new (region);
 
-      for (i = 0; ! cancel && (i < n_rects); i++)
-        {
-          cairo_rectangle_int_t render_rect;
+  while (gimp_chunk_iterator_next (iter))
+    {
+      GeglRectangle render_rect;
 
-          cairo_region_get_rectangle (region, i, &render_rect);
+      if (cancelable)
+        {
+          while (! cancel && g_main_context_pending (NULL))
+            g_main_context_iteration (NULL, FALSE);
 
-          if (progress)
-            {
-              gint rect_pixels = render_rect.width * render_rect.height;
-
-#ifdef REUSE_PROCESSOR
-              gegl_processor_set_rectangle (processor,
-                                            (GeglRectangle *) &render_rect);
-#else
-              g_object_unref (processor);
-              processor = gegl_node_new_processor (dest_node,
-                                                   (GeglRectangle *) &render_rect);
-#endif
-
-              while (! cancel && gegl_processor_work (processor, &value))
-                {
-                  gimp_progress_set_value (progress,
-                                           ((gdouble) done_pixels +
-                                            value * rect_pixels) /
-                                           (gdouble) all_pixels);
-
-                  if (cancellable)
-                    while (! cancel && g_main_context_pending (NULL))
-                      g_main_context_iteration (NULL, FALSE);
-                }
-
-              done_pixels += rect_pixels;
-            }
-          else
-            {
-              gegl_node_blit (dest_node, 1.0, (GeglRectangle *) &render_rect,
-                              NULL, NULL, 0, GEGL_BLIT_DEFAULT);
-            }
+          if (cancel)
+            break;
         }
 
-      cairo_region_destroy (region);
-    }
-  else
-    {
-      if (progress)
+      while (gimp_chunk_iterator_get_rect (iter, &render_rect))
         {
-          while (! cancel && gegl_processor_work (processor, &value))
-            {
-              gimp_progress_set_value (progress, value);
+          gint rect_pixels = render_rect.width * render_rect.height;
 
-              if (cancellable)
-                while (! cancel && g_main_context_pending (NULL))
-                  g_main_context_iteration (NULL, FALSE);
-            }
+          gegl_node_blit (dest_node, 1.0, &render_rect, NULL, NULL, 0,
+                          GEGL_BLIT_DEFAULT);
+
+          done_pixels += rect_pixels;
         }
-      else
+
+      if (progress)
         {
-          gegl_node_blit (dest_node, 1.0, &rect,
-                          NULL, NULL, 0, GEGL_BLIT_DEFAULT);
+          gimp_progress_set_value (progress,
+                                   (gdouble) done_pixels /
+                                   (gdouble) all_pixels);
         }
     }
 
-  if (processor)
-    g_object_unref (processor);
+  gegl_buffer_thaw_changed (dest_buffer);
 
   g_object_unref (gegl);
 


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