[Pixman] [PATCH/RFC] Use pixman_fixed_16_16_t type in _pixman_gradient_walker_{reset/pixel}

Siarhei Siamashka siarhei.siamashka at gmail.com
Fri Feb 19 03:31:24 PST 2010


From: Siarhei Siamashka <siarhei.siamashka at nokia.com>

This argument is explicitly cast to 'int' or 'int32_t' anyway when it
gets processed, except for 'if (pos < stops[n].x)' construct.

And at least the value coming from radial gradients processing code is
expected to be in [0.0, 1.0], which should fit into pixman_fixed_16_16_t
data type nicely.

This change provides a noticeable performance improvement for processing
radial gradients on ARM, where fast double -> int64_t conversion is not
supported by hardware. It can be measured by cairo-perf-trace, using
traces 'swfdec-youtube' or 'firefox-talos-svg'.

Benchmark from ARM Cortex-A8 @720MHz

before:

[ # ]  backend                         test   min(s) median(s) stddev. count
[  0]    image               swfdec-youtube   49.002   49.060   0.08%    6/6

after:

[ # ]  backend                         test   min(s) median(s) stddev. count
[  0]    image               swfdec-youtube   39.078   39.156   0.11%    6/6
---
 pixman/pixman-gradient-walker.c |    4 ++--
 pixman/pixman-private.h         |    4 ++--
 pixman/pixman-radial-gradient.c |   14 +++++++-------
 3 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/pixman/pixman-gradient-walker.c b/pixman/pixman-gradient-walker.c
index dd666b4..49693e1 100644
--- a/pixman/pixman-gradient-walker.c
+++ b/pixman/pixman-gradient-walker.c
@@ -49,7 +49,7 @@ _pixman_gradient_walker_init (pixman_gradient_walker_t *walker,
 
 void
 _pixman_gradient_walker_reset (pixman_gradient_walker_t *walker,
-                               pixman_fixed_32_32_t      pos)
+                               pixman_fixed_16_16_t      pos)
 {
     int32_t x, left_x, right_x;
     pixman_color_t          *left_c, *right_c;
@@ -222,7 +222,7 @@ _pixman_gradient_walker_reset (pixman_gradient_walker_t *walker,
 /* the following assumes that PIXMAN_GRADIENT_WALKER_NEED_RESET(w,x) is FALSE */
 uint32_t
 _pixman_gradient_walker_pixel (pixman_gradient_walker_t *walker,
-                               pixman_fixed_32_32_t      x)
+                               pixman_fixed_16_16_t      x)
 {
     int dist, idist;
     uint32_t t1, t2, a, color;
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index c99b101..fd2f133 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -332,11 +332,11 @@ _pixman_gradient_walker_init (pixman_gradient_walker_t *walker,
 
 void
 _pixman_gradient_walker_reset (pixman_gradient_walker_t *walker,
-                               pixman_fixed_32_32_t      pos);
+                               pixman_fixed_16_16_t      pos);
 
 uint32_t
 _pixman_gradient_walker_pixel (pixman_gradient_walker_t *walker,
-                               pixman_fixed_32_32_t      x);
+                               pixman_fixed_16_16_t      x);
 
 /*
  * Edges
diff --git a/pixman/pixman-radial-gradient.c b/pixman/pixman-radial-gradient.c
index 022157b..3802bb2 100644
--- a/pixman/pixman-radial-gradient.c
+++ b/pixman/pixman-radial-gradient.c
@@ -240,14 +240,14 @@ radial_gradient_get_scanline_32 (pixman_image_t *image,
 	{
 	    if (!mask || *mask++ & mask_bits)
 	    {
-		pixman_fixed_48_16_t t;
+		pixman_fixed_16_16_t t;
 		double det = B * B + A4 * (pdx * pdx + pdy * pdy - r1sq);
 		if (det <= 0.)
-		    t = (pixman_fixed_48_16_t) (B * invA);
+		    t = (pixman_fixed_16_16_t) (B * invA);
 		else if (invert)
-		    t = (pixman_fixed_48_16_t) ((B + sqrt (det)) * invA);
+		    t = (pixman_fixed_16_16_t) ((B + sqrt (det)) * invA);
 		else
-		    t = (pixman_fixed_48_16_t) ((B - sqrt (det)) * invA);
+		    t = (pixman_fixed_16_16_t) ((B - sqrt (det)) * invA);
 
 		*buffer = _pixman_gradient_walker_pixel (&walker, t);
 	    }
@@ -271,7 +271,7 @@ radial_gradient_get_scanline_32 (pixman_image_t *image,
 		double c1x = radial->c1.x / 65536.0;
 		double c1y = radial->c1.y / 65536.0;
 		double r1  = radial->c1.radius / 65536.0;
-		pixman_fixed_48_16_t t;
+		pixman_fixed_16_16_t t;
 		double x, y;
 
 		if (rz != 0)
@@ -297,9 +297,9 @@ radial_gradient_get_scanline_32 (pixman_image_t *image,
 		    det = 0.0;
 
 		if (radial->A * radial->dr < 0)
-		    t = (pixman_fixed_48_16_t) ((-B - sqrt (det)) / (2.0 * radial->A) * 65536);
+		    t = (pixman_fixed_16_16_t) ((-B - sqrt (det)) / (2.0 * radial->A) * 65536);
 		else
-		    t = (pixman_fixed_48_16_t) ((-B + sqrt (det)) / (2.0 * radial->A) * 65536);
+		    t = (pixman_fixed_16_16_t) ((-B + sqrt (det)) / (2.0 * radial->A) * 65536);
 
 		*buffer = _pixman_gradient_walker_pixel (&walker, t);
 	    }
-- 
1.6.4.4



More information about the Pixman mailing list