Speed up _pixman_image_get_solid() in common cases
authorSøren Sandmann Pedersen <ssp@redhat.com>
Tue, 3 May 2011 11:25:50 +0000 (07:25 -0400)
committerSøren Sandmann Pedersen <ssp@redhat.com>
Sat, 2 Jun 2012 12:19:38 +0000 (08:19 -0400)
Make _pixman_image_get_solid() faster by special-casing the common
cases where the image is SOLID or a repeating a8r8g8b8 image.

This optimization together with the previous one results in a small
but reproducable performance improvement on the xfce4-terminal-a1
cairo trace:

[ # ]  backend                         test   min(s) median(s) stddev. count
Before:
[  0]    image            xfce4-terminal-a1    1.221    1.239   1.21%  100/100
After:
[  0]    image            xfce4-terminal-a1    1.170    1.199   1.26%  100/100

Either optimization by itself is difficult to separate from noise.

pixman/pixman-image.c

index 6a965e4..8b634a7 100644 (file)
@@ -879,13 +879,34 @@ _pixman_image_get_solid (pixman_implementation_t *imp,
                          pixman_format_code_t     format)
 {
     uint32_t result;
-    pixman_iter_t iter;
 
-    _pixman_implementation_src_iter_init (
-       imp, &iter, image, 0, 0, 1, 1,
-       (uint8_t *)&result, ITER_NARROW, image->common.flags);
-
-    result = *iter.get_scanline (&iter, NULL);
+    if (image->type == SOLID)
+    {
+       result = image->solid.color_32;
+    }
+    else if (image->type == BITS)
+    {
+       if (image->bits.format == PIXMAN_a8r8g8b8)
+           result = image->bits.bits[0];
+       else if (image->bits.format == PIXMAN_x8r8g8b8)
+           result = image->bits.bits[0] | 0xff000000;
+       else if (image->bits.format == PIXMAN_a8)
+           result = (*(uint8_t *)image->bits.bits) << 24;
+       else
+           goto otherwise;
+    }
+    else
+    {
+       pixman_iter_t iter;
+
+    otherwise:
+       _pixman_implementation_src_iter_init (
+           imp, &iter, image, 0, 0, 1, 1,
+           (uint8_t *)&result,
+           ITER_NARROW, image->common.flags);
+       
+       result = *iter.get_scanline (&iter, NULL);
+    }
 
     /* If necessary, convert RGB <--> BGR. */
     if (PIXMAN_FORMAT_TYPE (format) != PIXMAN_TYPE_ARGB)