[gegl] buffer: in gegl_buffer_copy(), avoid copying to/from abyss when using COW



commit 012afc1ca1a404d5c17d6015185d213cbf30b078
Author: Ell <ell_se yahoo com>
Date:   Mon Jul 29 22:55:17 2019 +0300

    buffer: in gegl_buffer_copy(), avoid copying to/from abyss when using COW
    
    In gegl_buffer_copy(), when copying whole tiles, avoid copying
    tiles that coincide with the source or destination abyss, so that
    we get the correct abyss behavior as with non-COW copy.  In
    particular, this avoids stale cached data in nodes whose bounding
    box has changed from leaving traces during processing, when the
    cache is being copied from.

 gegl/buffer/gegl-buffer-access.c | 27 +++++++++++++++++++++------
 1 file changed, 21 insertions(+), 6 deletions(-)
---
diff --git a/gegl/buffer/gegl-buffer-access.c b/gegl/buffer/gegl-buffer-access.c
index 6537de4d8..600b28925 100644
--- a/gegl/buffer/gegl-buffer-access.c
+++ b/gegl/buffer/gegl-buffer-access.c
@@ -2386,7 +2386,8 @@ gegl_buffer_copy (GeglBuffer          *src,
                   GeglBuffer          *dst,
                   const GeglRectangle *dst_rect)
 {
-  GeglRectangle dest_rect_r;
+  GeglRectangle real_src_rect;
+  GeglRectangle real_dst_rect;
 
   g_return_if_fail (GEGL_IS_BUFFER (src));
   g_return_if_fail (GEGL_IS_BUFFER (dst));
@@ -2404,10 +2405,19 @@ gegl_buffer_copy (GeglBuffer          *src,
       dst_rect = src_rect;
     }
 
-  dest_rect_r = *dst_rect;
-  dest_rect_r.width = src_rect->width;
-  dest_rect_r.height = src_rect->height;
-  dst_rect = &dest_rect_r;
+  real_dst_rect        = *dst_rect;
+  real_dst_rect.width  = src_rect->width;
+  real_dst_rect.height = src_rect->height;
+
+  if (! gegl_rectangle_intersect (&real_dst_rect, &real_dst_rect, &dst->abyss))
+    return;
+
+  real_src_rect    = real_dst_rect;
+  real_src_rect.x += src_rect->x - dst_rect->x;
+  real_src_rect.y += src_rect->y - dst_rect->y;
+
+  src_rect = &real_src_rect;
+  dst_rect = &real_dst_rect;
 
   if (! gegl_rectangle_intersect (NULL, src_rect, &src->abyss))
     {
@@ -2467,9 +2477,14 @@ gegl_buffer_copy (GeglBuffer          *src,
       gint tile_width  = dst->tile_width;
       gint tile_height = dst->tile_height;
 
-      GeglRectangle cow_rect = *dst_rect;
+      GeglRectangle cow_rect;
       gint          rem;
 
+      gegl_rectangle_intersect (&cow_rect, src_rect, &src->abyss);
+
+      cow_rect.x += dst_rect->x - src_rect->x;
+      cow_rect.y += dst_rect->y - src_rect->y;
+
       /* adjust origin to match the start of tile alignment */
       rem = (cow_rect.x + dst->shift_x) % tile_width;
       if (rem > 0)


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