[gegl] sampler: clamp computed cache area after computation



commit 113c959afc73bb8ee42a02c8a0d8768c274e6f38
Author: Øyvind Kolås <pippin gimp org>
Date:   Tue Jun 17 08:53:57 2014 +0200

    sampler: clamp computed cache area after computation
    
    nohalo/lohalo have context rects which are 64px wide, the padding added to get
    a better idea of sampling direction could overflow the 64x64 size of the cache
    buf; clamping after computing the rect fixes this. Also plugs a leak of mipmap
    copies.

 gegl/buffer/gegl-sampler.c            |   17 +++++++++------
 operations/common/stress.c            |    2 +-
 operations/transform/transform-core.c |   36 ++++++++++++++++++++------------
 perf/test-rotate.c                    |    2 +-
 4 files changed, 34 insertions(+), 23 deletions(-)
---
diff --git a/gegl/buffer/gegl-sampler.c b/gegl/buffer/gegl-sampler.c
index 224f520..d1629ee 100644
--- a/gegl/buffer/gegl-sampler.c
+++ b/gegl/buffer/gegl-sampler.c
@@ -124,7 +124,7 @@ gegl_sampler_init (GeglSampler *sampler)
 
   sampler->level[0].sampler_buffer =
     g_malloc0 (GEGL_SAMPLER_MAXIMUM_WIDTH *
-               GEGL_SAMPLER_MAXIMUM_HEIGHT * 16);
+               GEGL_SAMPLER_MAXIMUM_HEIGHT * GEGL_SAMPLER_BPP);
 }
 
 void
@@ -260,10 +260,6 @@ GeglRectangle _gegl_sampler_compute_rectangle (GeglSampler *sampler,
          perhaps working better on small local non-linear access patterns
        */
 
-      if (rectangle.width >= GEGL_SAMPLER_MAXIMUM_WIDTH)
-        rectangle.width = GEGL_SAMPLER_MAXIMUM_WIDTH;
-      if (rectangle.height >= GEGL_SAMPLER_MAXIMUM_HEIGHT)
-        rectangle.height = GEGL_SAMPLER_MAXIMUM_HEIGHT;
 
 
       /* align rectangle corner we've likely entered with sampled pixel
@@ -293,6 +289,11 @@ GeglRectangle _gegl_sampler_compute_rectangle (GeglSampler *sampler,
                         - (rectangle.height - level->context_rect.y)/4;
     }
 
+  if (rectangle.width >= GEGL_SAMPLER_MAXIMUM_WIDTH)
+    rectangle.width = GEGL_SAMPLER_MAXIMUM_WIDTH;
+  if (rectangle.height >= GEGL_SAMPLER_MAXIMUM_HEIGHT)
+    rectangle.height = GEGL_SAMPLER_MAXIMUM_HEIGHT;
+
   g_assert (level->context_rect.width  <= rectangle.width);
   g_assert (level->context_rect.height <= rectangle.height);
 
@@ -321,6 +322,7 @@ gegl_sampler_get_from_mipmap (GeglSampler    *sampler,
   g_assert (level->context_rect.width  <= maximum_width);
   g_assert (level->context_rect.height <= maximum_height);
 
+
   if ((level->sampler_buffer == NULL)
    || (x + level->context_rect.x < level->sampler_rectangle.x)
    || (y + level->context_rect.y < level->sampler_rectangle.y)
@@ -335,9 +337,10 @@ gegl_sampler_get_from_mipmap (GeglSampler    *sampler,
        */
       level->sampler_rectangle = _gegl_sampler_compute_rectangle (sampler, x, y, 
                                                                   level_no);
+      if (!level->sampler_buffer)
+        level->sampler_buffer =
+          g_malloc0 (GEGL_SAMPLER_ROWSTRIDE * GEGL_SAMPLER_MAXIMUM_HEIGHT);
 
-      level->sampler_buffer =
-        g_malloc0 (GEGL_SAMPLER_ROWSTRIDE * GEGL_SAMPLER_MAXIMUM_HEIGHT);
 
       gegl_buffer_get (sampler->buffer,
                        &level->sampler_rectangle,
diff --git a/operations/common/stress.c b/operations/common/stress.c
index 7be3cae..9a03eff 100644
--- a/operations/common/stress.c
+++ b/operations/common/stress.c
@@ -180,7 +180,7 @@ static const gchar *composition =
     "<node operation='gegl:stress'>"
     "  <params>"
     "    <param name='radius'>200</param>"
-    "    <param name='iterations'>90</param>"
+    "    <param name='iterations'>30</param>"
     "  </params>"
     "</node>"
     "<node operation='gegl:load'>"
diff --git a/operations/transform/transform-core.c b/operations/transform/transform-core.c
index 30f5cbe..ae1cd32 100644
--- a/operations/transform/transform-core.c
+++ b/operations/transform/transform-core.c
@@ -701,6 +701,7 @@ transform_affine (GeglBuffer  *dest,
                   gint         level)
 {
   const Babl  *format = babl_format ("RaGaBaA float");
+  GeglSamplerGetFun sampler_get_fun = gegl_sampler_get_fun (sampler);
   GeglMatrix3  inverse;
   GeglMatrix2  inverse_jacobian;
   gint         dest_pixels;
@@ -810,18 +811,26 @@ transform_affine (GeglBuffer  *dest,
      * irrespective of orientation ("left-hand" VS "right-hand")
      * issues.
      */
-    const gint flip_x =
+
+#if 0
+    const gint flip_x = 
       inverse.coeff [0][0] + inverse.coeff [1][0] < (gdouble) 0.
       ?
       (gint) 1
       :
       (gint) 0;
-    const gint flip_y =
+    const gint flip_y = 
       inverse.coeff [0][1] + inverse.coeff [1][1] < (gdouble) 0.
       ?
       (gint) 1
       :
       (gint) 0;
+#else
+    /* XXX: not doing the flipping tricks is faster with the adaptive
+     *      sampler cache that has been added */
+    const gint flip_x = 0;
+    const gint flip_y = 0;
+#endif
 
     /*
      * Hoist most of what can out of the while loop:
@@ -866,12 +875,11 @@ transform_affine (GeglBuffer  *dest,
 
           gint x = roi->width;
           do {
-            gegl_sampler_get (sampler,
-                              u_float,
-                              v_float,
-                              &inverse_jacobian,
-                              dest_ptr,
-                              GEGL_ABYSS_NONE);
+            sampler_get_fun (sampler,
+                             u_float, v_float,
+                             &inverse_jacobian,
+                             dest_ptr,
+                             GEGL_ABYSS_NONE);
             dest_ptr += (gint) 4 - (gint) 8 * flip_x;
 
             u_float += inverse_jacobian.coeff [0][0];
@@ -895,6 +903,7 @@ transform_generic (GeglBuffer  *dest,
                    gint         level)
 {
   const Babl          *format = babl_format ("RaGaBaA float");
+  GeglSamplerGetFun sampler_get_fun = gegl_sampler_get_fun (sampler);
   GeglBufferIterator  *i;
   const GeglRectangle *dest_extent;
   GeglMatrix3          inverse;
@@ -1030,12 +1039,11 @@ transform_generic (GeglBuffer  *dest,
           inverse_jacobian.coeff [1][1] =
             (inverse.coeff [1][1] - inverse.coeff [2][1] * v) * w_recip;
 
-          gegl_sampler_get (sampler,
-                            u,
-                            v,
-                            &inverse_jacobian,
-                            dest_ptr,
-                            GEGL_ABYSS_NONE);
+          sampler_get_fun (sampler,
+                           u, v,
+                           &inverse_jacobian,
+                           dest_ptr,
+                           GEGL_ABYSS_NONE);
 
           dest_ptr += flip_x * (gint) 4;
           u_float += flip_x * inverse.coeff [0][0];
diff --git a/perf/test-rotate.c b/perf/test-rotate.c
index 628f911..9e70a1e 100644
--- a/perf/test-rotate.c
+++ b/perf/test-rotate.c
@@ -26,7 +26,7 @@ main (gint    argc,
 
   gegl = gegl_node_new ();
   source = gegl_node_new_child (gegl, "operation", "gegl:buffer-source", "buffer", buffer, NULL);
-  rotate = gegl_node_new_child (gegl, "operation", "gegl:rotate", "degrees", 4.0, "sampler", 
GEGL_SAMPLER_NEAREST, NULL);
+  rotate = gegl_node_new_child (gegl, "operation", "gegl:rotate", "degrees", 4.0, "sampler", 
GEGL_SAMPLER_NOHALO, NULL);
   sink = gegl_node_new_child (gegl, "operation", "gegl:buffer-sink", "buffer", &buffer2, NULL);
 
   gegl_node_link_many (source, rotate, sink, NULL);


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