[gegl] buffer: use per-instance hot-tile for nearest samplers



commit 7404ac114c565238a04257cff48822872cf67bbc
Author: Ell <ell_se yahoo com>
Date:   Fri Dec 15 13:37:47 2017 -0500

    buffer: use per-instance hot-tile for nearest samplers
    
    In GeglSamplerNearest, use a per-instance hot-tile pointer, rather
    than using the tile-storage's common hot-tile pointer, so that
    sampling from the sampler's hot-tile doesn't require locking the
    tile storage.  This notably improves multithreaded performance of
    ops that use a nearest sampler with a more-or-less regular sampling
    pattern.

 gegl/buffer/gegl-sampler-nearest.c |   52 +++++++++++++++++++----------------
 gegl/buffer/gegl-sampler-nearest.h |    8 +++--
 2 files changed, 33 insertions(+), 27 deletions(-)
---
diff --git a/gegl/buffer/gegl-sampler-nearest.c b/gegl/buffer/gegl-sampler-nearest.c
index f610951..ccd0a94 100644
--- a/gegl/buffer/gegl-sampler-nearest.c
+++ b/gegl/buffer/gegl-sampler-nearest.c
@@ -36,6 +36,9 @@ enum
 };
 
 static void
+gegl_sampler_nearest_dispose (GObject *self);
+
+static void
 gegl_sampler_nearest_get (GeglSampler*    restrict self,
                           const gdouble            absolute_x,
                           const gdouble            absolute_y,
@@ -51,8 +54,11 @@ G_DEFINE_TYPE (GeglSamplerNearest, gegl_sampler_nearest, GEGL_TYPE_SAMPLER)
 static void
 gegl_sampler_nearest_class_init (GeglSamplerNearestClass *klass)
 {
+  GObjectClass     *object_class  = G_OBJECT_CLASS (klass);
   GeglSamplerClass *sampler_class = GEGL_SAMPLER_CLASS (klass);
 
+  object_class->dispose = gegl_sampler_nearest_dispose;
+
   sampler_class->get = gegl_sampler_nearest_get;
   sampler_class->prepare = gegl_sampler_nearest_prepare;
 }
@@ -72,6 +78,16 @@ gegl_sampler_nearest_init (GeglSamplerNearest *self)
   GEGL_SAMPLER (self)->interpolate_format = gegl_babl_rgbA_linear_float ();
 }
 
+static void
+gegl_sampler_nearest_dispose (GObject *object)
+{
+  GeglSamplerNearest *nearest_sampler = GEGL_SAMPLER_NEAREST (object);
+
+  g_clear_pointer (&nearest_sampler->hot_tile, gegl_tile_unref);
+
+  G_OBJECT_CLASS (gegl_sampler_nearest_parent_class)->dispose (object);
+}
+
 static void inline
 gegl_sampler_get_pixel (GeglSampler    *sampler,
                         gint            x,
@@ -131,8 +147,6 @@ gegl_sampler_get_pixel (GeglSampler    *sampler,
     }
 
   gegl_buffer_lock (sampler->buffer);
-  if (gegl_config_threads()>1)
-    g_rec_mutex_lock (&buffer->tile_storage->mutex);
 
   {
     gint tile_width  = buffer->tile_width;
@@ -142,17 +156,25 @@ gegl_sampler_get_pixel (GeglSampler    *sampler,
     gint indice_x    = gegl_tile_indice (tiledx, tile_width);
     gint indice_y    = gegl_tile_indice (tiledy, tile_height);
 
-    GeglTile *tile = buffer->tile_storage->hot_tile;
+    GeglTile *tile = nearest_sampler->hot_tile;
 
     if (!(tile &&
           tile->x == indice_x &&
           tile->y == indice_y))
       {
-        _gegl_buffer_drop_hot_tile (buffer);
+        if (gegl_config_threads()>1)
+          g_rec_mutex_lock (&buffer->tile_storage->mutex);
+
+        if (tile)
+          gegl_tile_unref (tile);
+
         tile = gegl_tile_source_get_tile ((GeglTileSource *) (buffer),
                                           indice_x, indice_y,
                                           0);
-        buffer->tile_storage->hot_tile = tile;
+        nearest_sampler->hot_tile = tile;
+
+        if (gegl_config_threads()>1)
+          g_rec_mutex_unlock (&buffer->tile_storage->mutex);
       }
 
     if (tile)
@@ -167,8 +189,7 @@ gegl_sampler_get_pixel (GeglSampler    *sampler,
         babl_process (sampler->fish, tp, buf, 1);
       }
   }
-  if (gegl_config_threads()>1)
-    g_rec_mutex_unlock (&buffer->tile_storage->mutex);
+
   gegl_buffer_unlock (sampler->buffer);
 }
 
@@ -187,20 +208,6 @@ gegl_sampler_nearest_get_same_format  (      GeglSampler*    restrict  sampler,
 #endif
 
 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,
@@ -230,9 +237,6 @@ 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/buffer/gegl-sampler-nearest.h b/gegl/buffer/gegl-sampler-nearest.h
index 2338ea9..c489f90 100644
--- a/gegl/buffer/gegl-sampler-nearest.h
+++ b/gegl/buffer/gegl-sampler-nearest.h
@@ -34,9 +34,11 @@ typedef struct _GeglSamplerNearestClass GeglSamplerNearestClass;
 
 struct _GeglSamplerNearest
 {
-  GeglSampler parent_instance;
-  gint        buffer_bpp;
-    /*< private >*/
+  GeglSampler  parent_instance;
+
+  /*< private >*/
+  gint         buffer_bpp;
+  GeglTile    *hot_tile;
 };
 
 struct _GeglSamplerNearestClass


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