[gegl] buffer: add gegl_buffer_{freeze,thaw}_changed()



commit 413b8bd1a5654ad0fef7f6400e342c810e5bbfdd
Author: Ell <ell_se yahoo com>
Date:   Sat Jan 12 02:29:52 2019 -0500

    buffer: add gegl_buffer_{freeze,thaw}_changed()
    
    Add gegl_buffer_{freeze,thaw}_changed() functions, which block/
    unblock the emission of the buffer's "changed" signal.  While the
    signal is blocked, changes to the buffer are accumulated, and a
    corresponding "changed" signal is emitted once it's unblocked.

 gegl/buffer/gegl-buffer.c | 57 ++++++++++++++++++++++++++++++++++++++++-------
 gegl/buffer/gegl-buffer.h | 22 ++++++++++++++++++
 2 files changed, 71 insertions(+), 8 deletions(-)
---
diff --git a/gegl/buffer/gegl-buffer.c b/gegl/buffer/gegl-buffer.c
index ad09c972d..eaf8b0435 100644
--- a/gegl/buffer/gegl-buffer.c
+++ b/gegl/buffer/gegl-buffer.c
@@ -1178,16 +1178,29 @@ gegl_buffer_emit_changed_signal (GeglBuffer          *buffer,
                                  const GeglRectangle *rect)
 {
   if (buffer->changed_signal_connections)
-  {
-    GeglRectangle copy;
+    {
+      GeglRectangle copy;
 
-    if (rect == NULL)
-      copy = *gegl_buffer_get_extent (buffer);
-    else
-      copy = *rect;
+      if (rect == NULL)
+        copy = *gegl_buffer_get_extent (buffer);
+      else
+        copy = *rect;
 
-    g_signal_emit (buffer, gegl_buffer_signals[CHANGED], 0, &copy, NULL);
-  }
+      if (buffer->changed_signal_freeze_count == 0)
+        {
+          g_signal_emit (buffer, gegl_buffer_signals[CHANGED], 0, &copy, NULL);
+        }
+      else
+        {
+          g_rec_mutex_lock (&buffer->tile_storage->mutex);
+
+          gegl_rectangle_bounding_box (&buffer->changed_signal_accumulator,
+                                       &buffer->changed_signal_accumulator,
+                                       &copy);
+
+          g_rec_mutex_unlock (&buffer->tile_storage->mutex);
+        }
+    }
 }
 
 glong gegl_buffer_signal_connect (GeglBuffer *buffer,
@@ -1199,6 +1212,34 @@ glong gegl_buffer_signal_connect (GeglBuffer *buffer,
   return g_signal_connect(buffer, detailed_signal, c_handler, data);
 }
 
+void
+gegl_buffer_freeze_changed (GeglBuffer *buffer)
+{
+  g_return_if_fail (GEGL_IS_BUFFER (buffer));
+
+  if (buffer->changed_signal_freeze_count++ == 0)
+    {
+      buffer->changed_signal_accumulator.x      = 0;
+      buffer->changed_signal_accumulator.y      = 0;
+      buffer->changed_signal_accumulator.width  = 0;
+      buffer->changed_signal_accumulator.height = 0;
+    }
+}
+
+void
+gegl_buffer_thaw_changed (GeglBuffer *buffer)
+{
+  g_return_if_fail (GEGL_IS_BUFFER (buffer));
+  g_return_if_fail (buffer->changed_signal_freeze_count > 0);
+
+  if (--buffer->changed_signal_freeze_count == 0 &&
+      ! gegl_rectangle_is_empty (&buffer->changed_signal_accumulator))
+    {
+      gegl_buffer_emit_changed_signal (buffer,
+                                       &buffer->changed_signal_accumulator);
+    }
+}
+
 GeglTile *
 gegl_buffer_get_tile (GeglBuffer *buffer,
                       gint        x,
diff --git a/gegl/buffer/gegl-buffer.h b/gegl/buffer/gegl-buffer.h
index 88fd069e3..d280fc083 100644
--- a/gegl/buffer/gegl-buffer.h
+++ b/gegl/buffer/gegl-buffer.h
@@ -718,6 +718,28 @@ glong gegl_buffer_signal_connect (GeglBuffer *buffer,
                                   GCallback   c_handler,
                                   gpointer    data);
 
+/**
+ * gegl_buffer_freeze_changed:
+ * @buffer: a GeglBuffer
+ *
+ * Blocks emission of the "changed" signal for @buffer.
+ *
+ * While the signal is blocked, changes to @buffer are accumulated, and will
+ * be emitted once the signal is unblocked, using gegl_buffer_thaw_changed().
+ */
+void gegl_buffer_freeze_changed (GeglBuffer *buffer);
+
+/**
+ * gegl_buffer_thaw_changed:
+ * @buffer: a GeglBuffer
+ *
+ * Unblocks emission of the "changed" signal for @buffer.
+ *
+ * Once all calls to gegl_buffer_freeze_changed() are matched by corresponding
+ * calls to gegl_buffer_freeze_changed(), all accumulated changes are emitted.
+ */
+void gegl_buffer_thaw_changed (GeglBuffer *buffer);
+
 
 /**
  * gegl_buffer_flush_ext:


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