[gegl] buffer: use a nearest sampler in sampler box-filter



commit 6c4235b3e2d5cb7be1b6fce2048b8e280abe9ad8
Author: Ell <ell_se yahoo com>
Date:   Sat Mar 3 12:32:31 2018 -0500

    buffer: use a nearest sampler in sampler box-filter
    
    Use a nearest-neighbor sampler to read buffer data in
    _gegl_sampler_box_get(), instead of using gegl_buffer_get(), which
    avoids using the buffer's shared hot tile (nearest-neighbor sampler
    instances maintain their own hot tile), and hence saves us a lock.

 gegl/buffer/gegl-sampler.c |    2 ++
 gegl/buffer/gegl-sampler.h |   31 ++++++++++++++++++++-----------
 2 files changed, 22 insertions(+), 11 deletions(-)
---
diff --git a/gegl/buffer/gegl-sampler.c b/gegl/buffer/gegl-sampler.c
index 56c14b2..71cae9d 100644
--- a/gegl/buffer/gegl-sampler.c
+++ b/gegl/buffer/gegl-sampler.c
@@ -242,6 +242,8 @@ dispose (GObject *gobject)
   /* This call handles unreffing the buffer and disconnecting signals */
   set_buffer (sampler, NULL);
 
+  g_clear_pointer (&sampler->nearest_sampler, g_object_unref);
+
   G_OBJECT_CLASS (gegl_sampler_parent_class)->dispose (gobject);
 }
 
diff --git a/gegl/buffer/gegl-sampler.h b/gegl/buffer/gegl-sampler.h
index f0d1185..b194f73 100644
--- a/gegl/buffer/gegl-sampler.h
+++ b/gegl/buffer/gegl-sampler.h
@@ -65,13 +65,15 @@ struct _GeglSampler
   GeglSamplerGetFun get;
 
   /*< private >*/
-  GeglBuffer    *buffer;
-  gint           lvel;
-  const Babl    *format;
-  const Babl    *interpolate_format;
-  const Babl    *fish;
-
-  GeglSamplerLevel level[GEGL_SAMPLER_MIPMAP_LEVELS];
+  GeglBuffer        *buffer;
+  gint               lvel;
+  const Babl        *format;
+  const Babl        *interpolate_format;
+  const Babl        *fish;
+  GeglSampler       *nearest_sampler;
+  GeglSamplerGetFun  nearest_sampler_get_fun;
+
+  GeglSamplerLevel   level[GEGL_SAMPLER_MIPMAP_LEVELS];
 };
 
 struct _GeglSamplerClass
@@ -256,16 +258,23 @@ _gegl_sampler_box_get (GeglSampler*    restrict  self,
           hskip += ! hskip;
           vskip += ! vskip;
 
+          if (! self->nearest_sampler)
+            {
+              self->nearest_sampler = gegl_buffer_sampler_new (self->buffer,
+                                                               self->format,
+                                                               GEGL_SAMPLER_NEAREST);
+              self->nearest_sampler_get_fun =
+                gegl_sampler_get_fun (self->nearest_sampler);
+            }
+
           for (v = iy; v < yy; v += vskip)
             {
               for (u = ix; u < xx; u += hskip)
                 {
                   int c;
                   gfloat input[4];
-                  GeglRectangle rect = {u, v, 1, 1};
-                  gegl_buffer_get (self->buffer, &rect, 1.0,
-                                   self->interpolate_format, input,
-                                   GEGL_AUTO_ROWSTRIDE, repeat_mode);
+                  self->nearest_sampler_get_fun (self->nearest_sampler,
+                                                 u, v, NULL, input, repeat_mode);
                   for (c = 0; c < 4; c++)
                     result[c] += input[c];
                   count ++;


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