[gegl] buffer: do some thread safety conditionally



commit c49e9c57641a5c9842ec24561e5f136dfdd87c29
Author: Øyvind Kolås <pippin gimp org>
Date:   Tue Jun 24 07:32:50 2014 +0200

    buffer: do some thread safety conditionally
    
    Some use of mutexes is a performance impact we want to minimize in the
    non-threaded case.

 gegl/buffer/gegl-buffer-access.c   |   26 +++++++++++++++++++-------
 gegl/buffer/gegl-buffer-iterator.c |   21 +++++++++++++++++----
 gegl/buffer/gegl-sampler-nearest.c |   23 ++++++++++++++++++++---
 gegl/gegl-config.h                 |    2 ++
 gegl/gegl-init.c                   |    7 +++++++
 5 files changed, 65 insertions(+), 14 deletions(-)
---
diff --git a/gegl/buffer/gegl-buffer-access.c b/gegl/buffer/gegl-buffer-access.c
index aa0367a..3f723ba 100644
--- a/gegl/buffer/gegl-buffer-access.c
+++ b/gegl/buffer/gegl-buffer-access.c
@@ -37,6 +37,7 @@
 #include "gegl-tile-backend.h"
 #include "gegl-buffer-iterator.h"
 #include "gegl-buffer-cl-cache.h"
+#include "gegl-config.h"
 
 static void gegl_buffer_iterate_read_fringed (GeglBuffer          *buffer,
                                               const GeglRectangle *roi,
@@ -334,6 +335,7 @@ gegl_buffer_iterate_write (GeglBuffer          *buffer,
   gint abyss_x_total  = buffer_abyss_x + buffer->abyss.width;
   gint abyss_y_total  = buffer_abyss_y + buffer->abyss.height;
   gint factor         = 1<<level;
+  gboolean threaded   = gegl_config()->threads > 1;
   const Babl *fish;
 
   /* roi specified, override buffers extent */
@@ -393,10 +395,19 @@ gegl_buffer_iterate_write (GeglBuffer          *buffer,
           index_x = gegl_tile_indice (tiledx, tile_width);
           index_y = gegl_tile_indice (tiledy, tile_height);
 
-          g_mutex_lock (&mutexes[(index_x&15) * 16 + (index_y&15)]);
-          tile = gegl_tile_source_get_tile ((GeglTileSource *) (buffer),
-                                            index_x, index_y, level);
-          g_mutex_unlock (&mutexes[(index_x&15) * 16 + (index_y&15)]);
+          if (threaded)
+            {
+              g_mutex_lock (&mutexes[(index_x&15) * 16 + (index_y&15)]);
+              tile = gegl_tile_source_get_tile ((GeglTileSource *) (buffer),
+                                                index_x, index_y, level);
+              g_mutex_unlock (&mutexes[(index_x&15) * 16 + (index_y&15)]);
+            }
+          else
+            {
+              tile = gegl_tile_source_get_tile ((GeglTileSource *) (buffer),
+                                                index_x, index_y, level);
+            }
+
 
           lskip = (buffer_abyss_x) - (buffer_x + bufx);
           /* gap between left side of tile, and abyss */
@@ -1319,7 +1330,8 @@ gegl_buffer_set (GeglBuffer          *buffer,
   if (format == NULL)
     format = buffer->soft_format;
 
-  if (rect && (rect->width == 1 && rect->height == 1))
+  if (rect && (rect->width == 1 && rect->height == 1) &&
+    gegl_config()->threads == 1)
       _gegl_buffer_set_pixel (buffer, rect->x, rect->y, format, src,
                               GEGL_BUFFER_SET_FLAG_LOCK|GEGL_BUFFER_SET_FLAG_NOTIFY);
   else
@@ -1377,7 +1389,7 @@ _gegl_buffer_get_unlocked (GeglBuffer          *buffer,
 
   if (format == NULL)
     format = buffer->soft_format;
-
+/*
   if (scale == 1.0 &&
       rect &&
       rect->width == 1 &&
@@ -1386,7 +1398,7 @@ _gegl_buffer_get_unlocked (GeglBuffer          *buffer,
       gegl_buffer_get_pixel (buffer, rect->x, rect->y, format, dest_buf, repeat_mode);
       return;
     }
-
+*/
   if (gegl_cl_is_accelerated ())
     {
       gegl_buffer_cl_cache_flush (buffer, rect);
diff --git a/gegl/buffer/gegl-buffer-iterator.c b/gegl/buffer/gegl-buffer-iterator.c
index e0a8360..a8bfe50 100644
--- a/gegl/buffer/gegl-buffer-iterator.c
+++ b/gegl/buffer/gegl-buffer-iterator.c
@@ -32,6 +32,7 @@
 #include "gegl-buffer-iterator-private.h"
 #include "gegl-buffer-private.h"
 #include "gegl-buffer-cl-cache.h"
+#include "gegl-config.h"
 
 #define GEGL_ITERATOR_INCOMPATIBLE (1 << 2)
 
@@ -79,6 +80,7 @@ struct _GeglBufferIteratorPriv
   SubIterState      sub_iter[GEGL_BUFFER_MAX_ITERATORS];
 };
 
+static gboolean threaded = TRUE;
 
 GeglBufferIterator *
 gegl_buffer_iterator_empty_new (void)
@@ -88,6 +90,9 @@ gegl_buffer_iterator_empty_new (void)
 
   iter->priv->num_buffers = 0;
   iter->priv->state       = GeglIteratorState_Start;
+
+  threaded = gegl_config()->threads > 1;
+
   return iter;
 }
 
@@ -314,10 +319,18 @@ get_tile (GeglBufferIterator *iter,
       int tile_x = gegl_tile_indice (iter->roi[index].x + shift_x, tile_width);
       int tile_y = gegl_tile_indice (iter->roi[index].y + shift_y, tile_height);
 
-      g_mutex_lock (&mutexes[(ABS(tile_x) % 16) * 16 + (ABS(tile_y)%16)]);
-      sub->current_tile = gegl_tile_source_get_tile ((GeglTileSource *)(buf),
-                                                     tile_x, tile_y, 0);
-      g_mutex_unlock (&mutexes[(ABS(tile_x) % 16) * 16 + (ABS(tile_y)%16)]);
+      if (threaded)
+        {
+          g_mutex_lock (&mutexes[(ABS(tile_x) % 16) * 16 + (ABS(tile_y)%16)]);
+          sub->current_tile = gegl_tile_source_get_tile ((GeglTileSource *)(buf),
+                                                         tile_x, tile_y, 0);
+          g_mutex_unlock (&mutexes[(ABS(tile_x) % 16) * 16 + (ABS(tile_y)%16)]);
+        }
+      else
+        {
+          sub->current_tile = gegl_tile_source_get_tile ((GeglTileSource *)(buf),
+                                                         tile_x, tile_y, 0);
+        }
 
       if (sub->flags & GEGL_BUFFER_WRITE)
         gegl_tile_lock (sub->current_tile);
diff --git a/gegl/buffer/gegl-sampler-nearest.c b/gegl/buffer/gegl-sampler-nearest.c
index 8d9be5f..4461a83 100644
--- a/gegl/buffer/gegl-sampler-nearest.c
+++ b/gegl/buffer/gegl-sampler-nearest.c
@@ -26,7 +26,7 @@
 #include "gegl-buffer-private.h"
 #include "gegl-tile-storage.h"
 #include "gegl-tile-backend.h"
-
+#include "gegl-config.h"
 #include "gegl-sampler-nearest.h"
 
 enum
@@ -180,6 +180,20 @@ gegl_sampler_nearest_get_same_format  (      GeglSampler*    restrict  sampler,
 }
 
 static void
+gegl_sampler_nearest_get_threaded (      GeglSampler*    restrict  sampler,
+                          const gdouble                   absolute_x,
+                          const gdouble                   absolute_y,
+                                GeglMatrix2              *scale,
+                                void*           restrict  output,
+                                GeglAbyssPolicy           repeat_mode)
+{
+  GeglRectangle rect = {(gint) floorf ((double) absolute_x),
+                        (gint) floorf ((double) absolute_y),1,1};
+  gegl_buffer_get (sampler->buffer, &rect, 1.0, sampler->format, output, GEGL_AUTO_ROWSTRIDE, repeat_mode);
+  return;
+}
+
+static void
 gegl_sampler_nearest_get (      GeglSampler*    restrict  sampler,
                           const gdouble                   absolute_x,
                           const gdouble                   absolute_y,
@@ -194,8 +208,8 @@ gegl_sampler_nearest_get (      GeglSampler*    restrict  sampler,
 #else
   const gfloat* restrict in_bptr =
     gegl_sampler_get_ptr (sampler,
-                          (gint) floor ((double) absolute_x),
-                          (gint) floor ((double) absolute_y),
+                          (gint) floorf ((double) absolute_x),
+                          (gint) floorf ((double) absolute_y),
                           repeat_mode);
   babl_process (sampler->fish, in_bptr, output, 1);
 #endif
@@ -209,6 +223,9 @@ gegl_sampler_nearest_prepare (GeglSampler* restrict sampler)
     return;
   GEGL_SAMPLER_NEAREST (sampler)->buffer_bpp = babl_format_get_bytes_per_pixel (sampler->buffer->format);
 
+  if (gegl_config()->threads > 1)
+    sampler->get = gegl_sampler_nearest_get_threaded;
+
 #if 0 // maybe re-enable; when certain result is correct
   if (sampler->format == sampler->buffer->soft_format)
     {
diff --git a/gegl/gegl-config.h b/gegl/gegl-config.h
index 607c883..f5330d0 100644
--- a/gegl/gegl-config.h
+++ b/gegl/gegl-config.h
@@ -52,6 +52,8 @@ struct _GeglConfigClass
   GObjectClass parent_class;
 };
 
+gint gegl_config_threads (void);
+
 G_END_DECLS
 
 #endif
diff --git a/gegl/gegl-init.c b/gegl/gegl-init.c
index 91baf04..ff8ac8e 100644
--- a/gegl/gegl-init.c
+++ b/gegl/gegl-init.c
@@ -399,6 +399,13 @@ GeglConfig *gegl_config (void)
   return config;
 }
 
+gint gegl_config_threads (void)
+{
+  if (!config)
+    config = gegl_config ();
+  return config->threads;
+}
+
 static void swap_clean (void)
 {
   const gchar  *swap_dir = gegl_swap_dir ();


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