[gimp] app: use gimp_tile_handler_validate_validate() in gimp:buffer-source-validate



commit 83dd94ba6a12d39458943421a728dfbff020e18b
Author: Ell <ell_se yahoo com>
Date:   Wed Nov 28 13:19:08 2018 -0500

    app: use gimp_tile_handler_validate_validate() in gimp:buffer-source-validate
    
    Use gimp_tile_handler_validate_validate(), added in the commit
    before last, in gimp:buffer-source-validate, in order to pre-render
    the necessary region of the buffer, instead of performing the
    validation implicitly by iterating over the region.  This is both
    simpler, and, more importantly, allows us to render the entire
    region in a single chunk, instead of tile-by-tile, which can be
    considerably more efficient, especially with high thread counts.
    
    This essentially extends the dynamic sizing of rendered projection
    chunks to layer groups, which are rendered through
    gimp:buffer-source-validate, rather than just the main image
    projection.

 app/operations/gimpoperationbuffersourcevalidate.c | 103 +++++----------------
 1 file changed, 21 insertions(+), 82 deletions(-)
---
diff --git a/app/operations/gimpoperationbuffersourcevalidate.c 
b/app/operations/gimpoperationbuffersourcevalidate.c
index 40b16871e4..95d8a6b1d8 100644
--- a/app/operations/gimpoperationbuffersourcevalidate.c
+++ b/app/operations/gimpoperationbuffersourcevalidate.c
@@ -18,7 +18,6 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-#define GEGL_ITERATOR2_API
 #include "config.h"
 
 #include <cairo.h>
@@ -240,89 +239,29 @@ gimp_operation_buffer_source_validate_process (GeglOperation        *operation,
 
       if (validate_handler)
         {
-          gint n_threads;
-
-          g_object_get (gegl_config (),
-                        "threads", &n_threads,
+          gint          shift_x;
+          gint          shift_y;
+          gint          tile_width;
+          gint          tile_height;
+          GeglRectangle rect;
+
+          g_object_get (buffer_source_validate->buffer,
+                        "shift-x",     &shift_x,
+                        "shift-y",     &shift_y,
+                        "tile-width",  &tile_width,
+                        "tile-height", &tile_height,
                         NULL);
 
-          /* the main reason to validate the buffer during processing is to
-           * avoid threading issues.  skip validation if not using
-           * multithreading.
-           */
-          if (n_threads > 1)
-            {
-              gint                   shift_x;
-              gint                   shift_y;
-              gint                   tile_width;
-              gint                   tile_height;
-              cairo_rectangle_int_t  rect;
-              cairo_region_overlap_t overlap;
-
-              g_object_get (buffer_source_validate->buffer,
-                            "shift-x",     &shift_x,
-                            "shift-y",     &shift_y,
-                            "tile-width",  &tile_width,
-                            "tile-height", &tile_height,
-                            NULL);
-
-              /* align the rectangle to the tile grid */
-              rect.x      = (gint) floor ((gdouble) (result->x                  + shift_x) / tile_width)  * 
tile_width;
-              rect.y      = (gint) floor ((gdouble) (result->y                  + shift_y) / tile_height) * 
tile_height;
-              rect.width  = (gint) ceil  ((gdouble) (result->x + result->width  + shift_x) / tile_width)  * 
tile_width  - rect.x;
-              rect.height = (gint) ceil  ((gdouble) (result->y + result->height + shift_y) / tile_height) * 
tile_height - rect.y;
-
-              /* check if the rectangle interescts with the dirty region */
-              overlap = cairo_region_contains_rectangle (validate_handler->dirty_region,
-                                                         &rect);
-
-              if (overlap != CAIRO_REGION_OVERLAP_OUT)
-                {
-                  GeglBufferIterator *iter;
-
-                  /* if the rectangle is not entirely within the dirty
-                   * region ...
-                   */
-                  if (overlap == CAIRO_REGION_OVERLAP_PART)
-                    {
-                      cairo_region_t        *region;
-                      cairo_rectangle_int_t  intersection;
-
-                      /* ... intersect it with region and use the result's
-                       * bounds
-                       */
-                      region = cairo_region_copy (validate_handler->dirty_region);
-
-                      cairo_region_intersect_rectangle (region, &rect);
-                      cairo_region_get_extents (region, &intersection);
-
-                      cairo_region_destroy (region);
-
-                      /* realign the rectangle to the tile grid */
-                      rect.x      = (gint) floor ((gdouble) (intersection.x                      ) / 
tile_width)  * tile_width;
-                      rect.y      = (gint) floor ((gdouble) (intersection.y                      ) / 
tile_height) * tile_height;
-                      rect.width  = (gint) ceil  ((gdouble) (intersection.x + intersection.width ) / 
tile_width)  * tile_width  - rect.x;
-                      rect.height = (gint) ceil  ((gdouble) (intersection.y + intersection.height) / 
tile_height) * tile_height - rect.y;
-                    }
-
-                  rect.x -= shift_x;
-                  rect.y -= shift_y;
-
-                  /* iterate over the rectangle -- this implicitly causes
-                   * validation
-                   */
-                  iter = gegl_buffer_iterator_new (buffer,
-                                                   GEGL_RECTANGLE (rect.x,
-                                                                   rect.y,
-                                                                   rect.width,
-                                                                   rect.height),
-                                                   level, NULL,
-                                                   GEGL_BUFFER_READ,
-                                                   GEGL_ABYSS_NONE, 1);
-
-                  while (gegl_buffer_iterator_next (iter));
-                }
-            }
+          /* align the rectangle to the tile grid */
+          rect.x      = (gint) floor ((gdouble) (result->x                  + shift_x) / tile_width)  * 
tile_width;
+          rect.y      = (gint) floor ((gdouble) (result->y                  + shift_y) / tile_height) * 
tile_height;
+          rect.width  = (gint) ceil  ((gdouble) (result->x + result->width  + shift_x) / tile_width)  * 
tile_width  - rect.x;
+          rect.height = (gint) ceil  ((gdouble) (result->y + result->height + shift_y) / tile_height) * 
tile_height - rect.y;
+
+          gimp_tile_handler_validate_validate (validate_handler,
+                                               buffer_source_validate->buffer,
+                                               &rect,
+                                               TRUE);
         }
 
       gegl_operation_context_set_object (context, "output", G_OBJECT (buffer));


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