[gegl] buffer: fix performance regression due to last commit



commit a66f509888802e53456e612b89ad35ec8341342a
Author: Ell <ell_se yahoo com>
Date:   Sat Mar 3 05:40:26 2018 -0500

    buffer: fix performance regression due to last commit
    
    The tests added in the last commit slightly worsened the
    performance of sampler box filtering, even in the common case where
    they aren't necessary.
    
    Modify the code to minimize the tests and gain back the lost
    performance.  While this may technically involve UB in some cases,
    it should be fine in practice.

 gegl/buffer/gegl-sampler.h |   55 ++++++++++++++++++++-----------------------
 1 files changed, 26 insertions(+), 29 deletions(-)
---
diff --git a/gegl/buffer/gegl-sampler.h b/gegl/buffer/gegl-sampler.h
index e482a7f..f0d1185 100644
--- a/gegl/buffer/gegl-sampler.h
+++ b/gegl/buffer/gegl-sampler.h
@@ -239,42 +239,39 @@ _gegl_sampler_box_get (GeglSampler*    restrict  self,
                               MAX (0.0, scale->coeff[1][0] + scale->coeff[1][1]));
       const gdouble w = x2 - x1;
       const gdouble h = y2 - y1;
-      const gdouble ixf = floor (absolute_x - w / 2.0);
-      const gdouble iyf = floor (absolute_y - h / 2.0);
-      const gdouble xxf = ceil  (absolute_x + w / 2.0);
-      const gdouble yyf = ceil  (absolute_y + h / 2.0);
-      const gint ix = CLAMP (ixf, -(G_MAXINT / 2), +(G_MAXINT / 2));
-      const gint iy = CLAMP (iyf, -(G_MAXINT / 2), +(G_MAXINT / 2));
-      const gint xx = CLAMP (xxf, -(G_MAXINT / 2), +(G_MAXINT / 2));
-      const gint yy = CLAMP (yyf, -(G_MAXINT / 2), +(G_MAXINT / 2));
+      const gint ix = floor (absolute_x - w / 2.0);
+      const gint iy = floor (absolute_y - h / 2.0);
+      const gint xx = ceil  (absolute_x + w / 2.0);
+      const gint yy = ceil  (absolute_y + h / 2.0);
       int u, v;
       int count = 0;
-      int hskip = (xx - ix) / n_samples;
-      int vskip = (yy - iy) / n_samples;
+      int hskip = xx - ix;
+      int vskip = yy - iy;
 
-      if (hskip <= 0)
-        hskip = 1;
-      if (vskip <= 0)
-        vskip = 1;
-
-      for (v = iy; v < yy; v += vskip)
+      if (hskip > 0 && vskip > 0)
         {
-          for (u = ix; u < xx; u += hskip)
+          hskip /= n_samples;
+          vskip /= n_samples;
+
+          hskip += ! hskip;
+          vskip += ! vskip;
+
+          for (v = iy; v < yy; v += vskip)
             {
-              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);
-              for (c = 0; c < 4; c++)
-                result[c] += input[c];
-              count ++;
+              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);
+                  for (c = 0; c < 4; c++)
+                    result[c] += input[c];
+                  count ++;
+                }
             }
-        }
 
-      if (count)
-        {
           result[0] /= count;
           result[1] /= count;
           result[2] /= count;


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