[gegl] buffer: remove [un]block_changed_signal(); add ITERATOR_NO_NOTIFY



commit fe9eb724693e13c5a600c249dceb56c47a184162
Author: Ell <ell_se yahoo com>
Date:   Wed Feb 21 09:17:52 2018 -0500

    buffer: remove [un]block_changed_signal(); add ITERATOR_NO_NOTIFY
    
    Partially revert last commit by removing
    gegl_buffer_{block,unblock}_changed_signal(), and its usage in
    gegl-buffer-access.c -- it isn't thread safe.  While the functions
    themselves can be made thread safe, their usage is problematic,
    since it can cause one thread to block signal emission in another
    thread, if no locking is used.
    
    Instead, add an internal GEGL_ITERATOR_NO_NOTIFY access mode flag,
    which prevents the iterator from emitting a "changed" signal, and
    use it in gegl_buffer_{copy,clear}2().

 gegl/buffer/gegl-buffer-access.c           |   21 +++++----------------
 gegl/buffer/gegl-buffer-iterator-private.h |    5 +++++
 gegl/buffer/gegl-buffer-iterator.c         |    9 +++++----
 gegl/buffer/gegl-buffer-private.h          |    8 ++------
 gegl/buffer/gegl-buffer.c                  |   17 +----------------
 5 files changed, 18 insertions(+), 42 deletions(-)
---
diff --git a/gegl/buffer/gegl-buffer-access.c b/gegl/buffer/gegl-buffer-access.c
index f31b593..ad4530e 100644
--- a/gegl/buffer/gegl-buffer-access.c
+++ b/gegl/buffer/gegl-buffer-access.c
@@ -36,6 +36,7 @@
 #include "gegl-sampler.h"
 #include "gegl-tile-backend.h"
 #include "gegl-buffer-iterator.h"
+#include "gegl-buffer-iterator-private.h"
 #include "gegl-buffer-cl-cache.h"
 #include "gegl-config.h"
 
@@ -2219,7 +2220,8 @@ gegl_buffer_copy2 (GeglBuffer          *src,
     dest_rect_r.height = src_rect->height;
 
     i = gegl_buffer_iterator_new (dst, &dest_rect_r, 0, dst->soft_format,
-                                  GEGL_ACCESS_WRITE, repeat_mode);
+                                  GEGL_ACCESS_WRITE | GEGL_ITERATOR_NO_NOTIFY,
+                                  repeat_mode);
     while (gegl_buffer_iterator_next (i))
       {
         GeglRectangle src_rect = i->roi[0];
@@ -2251,8 +2253,6 @@ gegl_buffer_copy (GeglBuffer          *src,
       dst_rect = src_rect;
     }
 
-  gegl_buffer_block_changed_signal (dst);
-
   if (src->soft_format == dst->soft_format &&
       src_rect->width >= src->tile_width &&
       src_rect->height >= src->tile_height &&
@@ -2401,8 +2401,6 @@ gegl_buffer_copy (GeglBuffer          *src,
       gegl_buffer_copy2 (src, src_rect, repeat_mode, dst, dst_rect);
     }
 
-  gegl_buffer_unblock_changed_signal (dst);
-
   gegl_buffer_emit_changed_signal (dst, dst_rect);
 }
 
@@ -2432,7 +2430,8 @@ gegl_buffer_clear2 (GeglBuffer          *dst,
    * that fully voided tiles are dropped.
    */
   i = gegl_buffer_iterator_new (dst, dst_rect, 0, dst->soft_format,
-                                GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE);
+                                GEGL_ACCESS_WRITE | GEGL_ITERATOR_NO_NOTIFY,
+                                GEGL_ABYSS_NONE);
   while (gegl_buffer_iterator_next (i))
     {
       memset (((guchar*)(i->data[0])), 0, i->length * pxsize);
@@ -2450,8 +2449,6 @@ gegl_buffer_clear (GeglBuffer          *dst,
       dst_rect = gegl_buffer_get_extent (dst);
     }
 
-  gegl_buffer_block_changed_signal (dst);
-
 #if 1
   /* cow for clearing is currently broken */
   if (!g_object_get_data (G_OBJECT (dst), "is-linear"))
@@ -2551,8 +2548,6 @@ gegl_buffer_clear (GeglBuffer          *dst,
       gegl_buffer_clear2 (dst, dst_rect);
     }
 
-  gegl_buffer_unblock_changed_signal (dst);
-
   gegl_buffer_emit_changed_signal (dst, dst_rect);
 }
 
@@ -2682,8 +2677,6 @@ gegl_buffer_set_color (GeglBuffer          *dst,
 
   bpp = babl_format_get_bytes_per_pixel (dst->soft_format);
 
-  gegl_buffer_block_changed_signal (dst);
-
   /* FIXME: this can be even further optimized by special casing it so
    * that fully filled tiles are shared.
    */
@@ -2693,10 +2686,6 @@ gegl_buffer_set_color (GeglBuffer          *dst,
     {
       gegl_memset_pattern (i->data[0], pixel, bpp, i->length);
     }
-
-  gegl_buffer_unblock_changed_signal (dst);
-
-  gegl_buffer_emit_changed_signal (dst, dst_rect);
 }
 
 GeglBuffer *
diff --git a/gegl/buffer/gegl-buffer-iterator-private.h b/gegl/buffer/gegl-buffer-iterator-private.h
index fd84246..9d83ea6 100644
--- a/gegl/buffer/gegl-buffer-iterator-private.h
+++ b/gegl/buffer/gegl-buffer-iterator-private.h
@@ -19,4 +19,9 @@
 #ifndef __GEGL_BUFFER_ITERATOR_PRIVATE_H__
 #define __GEGL_BUFFER_ITERATOR_PRIVATE_H__
 
+G_STATIC_ASSERT (GEGL_BUFFER_READWRITE == 0x3);
+
+#define GEGL_ITERATOR_INCOMPATIBLE (1 << 2)
+#define GEGL_ITERATOR_NO_NOTIFY    (1 << 3)
+
 #endif
diff --git a/gegl/buffer/gegl-buffer-iterator.c b/gegl/buffer/gegl-buffer-iterator.c
index 1183f26..7411726 100644
--- a/gegl/buffer/gegl-buffer-iterator.c
+++ b/gegl/buffer/gegl-buffer-iterator.c
@@ -33,8 +33,6 @@
 #include "gegl-buffer-cl-cache.h"
 #include "gegl-config.h"
 
-#define GEGL_ITERATOR_INCOMPATIBLE (1 << 2)
-
 typedef enum {
   GeglIteratorState_Start,
   GeglIteratorState_InTile,
@@ -553,8 +551,11 @@ _gegl_buffer_iterator_stop (GeglBufferIterator *iter)
 
           gegl_buffer_unlock (sub->buffer);
 
-          if (sub->access_mode & GEGL_ACCESS_WRITE)
-            gegl_buffer_emit_changed_signal (sub->buffer, &sub->full_rect);
+          if ((sub->access_mode & GEGL_ACCESS_WRITE) &&
+              ! (sub->access_mode & GEGL_ITERATOR_NO_NOTIFY))
+            {
+              gegl_buffer_emit_changed_signal (sub->buffer, &sub->full_rect);
+            }
         }
     }
 
diff --git a/gegl/buffer/gegl-buffer-private.h b/gegl/buffer/gegl-buffer-private.h
index 5662cb6..9df62bf 100644
--- a/gegl/buffer/gegl-buffer-private.h
+++ b/gegl/buffer/gegl-buffer-private.h
@@ -74,8 +74,6 @@ struct _GeglBuffer
 
   gint              changed_signal_connections; /* to avoid firing changed signals
                                                    with no listeners */
-  gint              changed_signal_block_count; /* temporarily block changed
-                                                   signal */
 
   GeglTileBackend  *backend;
 };
@@ -140,10 +138,8 @@ void              gegl_buffer_get_unlocked (GeglBuffer          *buffer,
 GeglBuffer *      gegl_buffer_new_ram     (const GeglRectangle *extent,
                                            const Babl          *format);
 
-void              gegl_buffer_emit_changed_signal    (GeglBuffer *buffer,
-                                                      const GeglRectangle *rect);
-void              gegl_buffer_block_changed_signal   (GeglBuffer *buffer);
-void              gegl_buffer_unblock_changed_signal (GeglBuffer *buffer);
+void              gegl_buffer_emit_changed_signal (GeglBuffer *buffer,
+                                                   const GeglRectangle *rect);
 
 /* the instance size of a GeglTile is a bit large, and should if possible be
  * trimmed down
diff --git a/gegl/buffer/gegl-buffer.c b/gegl/buffer/gegl-buffer.c
index cb84da3..a2480cf 100644
--- a/gegl/buffer/gegl-buffer.c
+++ b/gegl/buffer/gegl-buffer.c
@@ -1190,8 +1190,7 @@ void
 gegl_buffer_emit_changed_signal (GeglBuffer          *buffer,
                                  const GeglRectangle *rect)
 {
-  if (buffer->changed_signal_connections &&
-      buffer->changed_signal_block_count == 0)
+  if (buffer->changed_signal_connections)
   {
     GeglRectangle copy;
 
@@ -1204,20 +1203,6 @@ gegl_buffer_emit_changed_signal (GeglBuffer          *buffer,
   }
 }
 
-void
-gegl_buffer_block_changed_signal (GeglBuffer *buffer)
-{
-  buffer->changed_signal_block_count++;
-}
-
-void
-gegl_buffer_unblock_changed_signal (GeglBuffer *buffer)
-{
-  g_return_if_fail (buffer->changed_signal_block_count > 0);
-
-  buffer->changed_signal_block_count--;
-}
-
 glong gegl_buffer_signal_connect (GeglBuffer *buffer,
                                   const char *detailed_signal,
                                   GCallback   c_handler,


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