[gegl] buffer: in gegl_buffer_set(), avoid fetching/copying whole tiles



commit 8a6bbcc38120f59d5931f361d3594dec5ae22b85
Author: Ell <ell_se yahoo com>
Date:   Tue Jan 1 14:37:06 2019 -0500

    buffer: in gegl_buffer_set(), avoid fetching/copying whole tiles
    
    In gegl_buffer_iterate_write(), use gegl_tile_handler_get_tile() to
    fetch written-to tiles, instead of gegl_buffer_get_tile(), and
    don't preserve tile data when the entire tile is being written to.
    This avoids unnecessarily fetching the tile from storage, or
    copying its data during uncloning.

 gegl/buffer/gegl-buffer-access.c | 21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)
---
diff --git a/gegl/buffer/gegl-buffer-access.c b/gegl/buffer/gegl-buffer-access.c
index eb4c6e97f..b1f54ea52 100644
--- a/gegl/buffer/gegl-buffer-access.c
+++ b/gegl/buffer/gegl-buffer-access.c
@@ -426,6 +426,7 @@ gegl_buffer_iterate_write (GeglBuffer          *buffer,
           gint      lskip, rskip, pixels, row;
           guchar   *bp, *tile_base, *tp;
           GeglTile *tile;
+          gboolean  whole_tile;
 
           bp = buf + bufy * buf_stride + bufx * bpx_size;
 
@@ -437,8 +438,6 @@ gegl_buffer_iterate_write (GeglBuffer          *buffer,
           index_x = gegl_tile_indice (tiledx, tile_width);
           index_y = gegl_tile_indice (tiledy, tile_height);
 
-          tile = gegl_buffer_get_tile (buffer, index_x, index_y, level);
-
           lskip = (buffer_abyss_x) - (buffer_x + bufx);
           /* gap between left side of tile, and abyss */
           rskip = (buffer_x + bufx + pixels) - abyss_x_total;
@@ -453,6 +452,21 @@ gegl_buffer_iterate_write (GeglBuffer          *buffer,
           if (rskip > pixels)
             rskip = pixels;
 
+          pixels -= lskip;
+          pixels -= rskip;
+
+          whole_tile = pixels == tile_width && bufy >= buffer_abyss_y &&
+                       MIN (MIN (height - bufy, tile_height - offsety),
+                            abyss_y_total - bufy) == tile_height;
+
+          g_rec_mutex_lock (&buffer->tile_storage->mutex);
+
+          tile = gegl_tile_handler_get_tile ((GeglTileHandler *) buffer,
+                                             index_x, index_y, level,
+                                             ! whole_tile);
+
+          g_rec_mutex_unlock (&buffer->tile_storage->mutex);
+
           if (!tile)
             {
               g_warning ("didn't get tile, trying to continue");
@@ -465,9 +479,6 @@ gegl_buffer_iterate_write (GeglBuffer          *buffer,
           tile_base = gegl_tile_get_data (tile);
           tp        = ((guchar *) tile_base) + (offsety * tile_width + offsetx) * px_size;
 
-          pixels -= lskip;
-          pixels -= rskip;
-
           if (fish)
             {
               int skip = 0, rows = MIN(height - bufy, tile_height - offsety);


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