pixman: Branch 'master'

Søren Sandmann Pedersen sandmann at kemper.freedesktop.org
Sun Jan 6 08:38:01 PST 2013


 pixman/pixman-general.c    |    8 ++++----
 pixman/pixman-noop.c       |   20 ++++++++++++++------
 pixman/pixman-private.h    |    3 ---
 pixman/pixman-solid-fill.c |   25 -------------------------
 4 files changed, 18 insertions(+), 38 deletions(-)

New commits:
commit 58526cfc7290a740f61e288f09fe721c4e6511bd
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Sun Aug 26 22:06:27 2012 -0400

    Handle solid images in the noop iterator
    
    The noop src iterator already has code to handle solid images, but
    that code never actually runs currently because it is not possible for
    an image to have both a format code of PIXMAN_solid and a flag of
    FAST_PATH_BITS_IMAGE.
    
    If these two were to be set at the same time, the
    fast_composite_tiled_repeat() fast path would trigger for solid images
    (because it triggers for PIXMAN_any formats, which includes
    PIXMAN_solid), but for solid images we can usually do better than that
    fast path.
    
    So this patch removes _pixman_solid_fill_iter_init() and instead
    handles such images (along with repeating 1x1 bits images without an
    alpha map) in pixman-noop.c.
    
    When a 1x1R image is involved in the general composite path, before
    this patch, it would hit this code in repeat() in pixman-inlines.h:
    
            while (*c >= size)
                *c -= size;
            while (*c < 0)
                *c += size;
    
    and those loops could run for a huge number of iteratons (proportional
    to the composite width). For such cases, the performance improvement
    is really big:
    
    ./test/lowlevel-blt-bench -n add_n_8888:
    
    Before:
    
        add_n_8888 =  L1:   3.86  L2:   3.78  M:  1.40 (  0.06%)  HT:  1.43  VT:  1.41  R:  1.41  RT:  1.38 (  19Kops/s)
    
    After:
    
        add_n_8888 =  L1:1236.86  L2:2468.49  M:1097.88 ( 49.04%)  HT:476.49  VT:429.05  R:417.04  RT:155.12 ( 817Kops/s)

diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index 0bf91e4..f175d77 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -42,9 +42,7 @@ general_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
 {
     pixman_image_t *image = iter->image;
 
-    if (image->type == SOLID)
-	_pixman_solid_fill_iter_init (image, iter);
-    else if (image->type == LINEAR)
+    if (image->type == LINEAR)
 	_pixman_linear_gradient_iter_init (image, iter);
     else if (image->type == RADIAL)
 	_pixman_radial_gradient_iter_init (image, iter);
@@ -52,7 +50,9 @@ general_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
 	_pixman_conical_gradient_iter_init (image, iter);
     else if (image->type == BITS)
 	_pixman_bits_image_src_iter_init (image, iter);
-    else
+    else if (image->type == SOLID)
+        _pixman_log_error (FUNC, "Solid image not handled by noop");
+    else         
 	_pixman_log_error (FUNC, "Pixman bug: unknown image type\n");
 
     return TRUE;
diff --git a/pixman/pixman-noop.c b/pixman/pixman-noop.c
index 850caa1..e39996d 100644
--- a/pixman/pixman-noop.c
+++ b/pixman/pixman-noop.c
@@ -77,25 +77,33 @@ noop_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
 	iter->get_scanline = _pixman_iter_get_scanline_noop;
     }
     else if (image->common.extended_format_code == PIXMAN_solid		&&
-	     ((iter->image_flags & (FAST_PATH_BITS_IMAGE | FAST_PATH_NO_ALPHA_MAP)) ==
-	      (FAST_PATH_BITS_IMAGE | FAST_PATH_NO_ALPHA_MAP)))
+	     (iter->image->type == SOLID ||
+	      (iter->image_flags & FAST_PATH_NO_ALPHA_MAP)))
     {
-	bits_image_t *bits = &image->bits;
-
 	if (iter->iter_flags & ITER_NARROW)
 	{
-	    uint32_t color = bits->fetch_pixel_32 (bits, 0, 0);
 	    uint32_t *buffer = iter->buffer;
 	    uint32_t *end = buffer + iter->width;
+	    uint32_t color;
+
+	    if (image->type == SOLID)
+		color = image->solid.color_32;
+	    else
+		color = image->bits.fetch_pixel_32 (&image->bits, 0, 0);
 
 	    while (buffer < end)
 		*(buffer++) = color;
 	}
 	else
 	{
-	    argb_t color = bits->fetch_pixel_float (bits, 0, 0);
 	    argb_t *buffer = (argb_t *)iter->buffer;
 	    argb_t *end = buffer + iter->width;
+	    argb_t color;
+
+	    if (image->type == SOLID)
+		color = image->solid.color_float;
+	    else
+		color = image->bits.fetch_pixel_float (&image->bits, 0, 0);
 
 	    while (buffer < end)
 		*(buffer++) = color;
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 765ce55..e5ab873 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -263,9 +263,6 @@ void
 _pixman_bits_image_dest_iter_init (pixman_image_t *image, pixman_iter_t *iter);
 
 void
-_pixman_solid_fill_iter_init (pixman_image_t *image, pixman_iter_t  *iter);
-
-void
 _pixman_linear_gradient_iter_init (pixman_image_t *image, pixman_iter_t  *iter);
 
 void
diff --git a/pixman/pixman-solid-fill.c b/pixman/pixman-solid-fill.c
index 60d56d5..5f9fef6 100644
--- a/pixman/pixman-solid-fill.c
+++ b/pixman/pixman-solid-fill.c
@@ -26,31 +26,6 @@
 #endif
 #include "pixman-private.h"
 
-void
-_pixman_solid_fill_iter_init (pixman_image_t *image, pixman_iter_t  *iter)
-{
-    if (iter->iter_flags & ITER_NARROW)
-    {
-	uint32_t *b = (uint32_t *)iter->buffer;
-	uint32_t *e = b + iter->width;
-	uint32_t color = iter->image->solid.color_32;
-
-	while (b < e)
-	    *(b++) = color;
-    }
-    else
-    {
-	argb_t *b = (argb_t *)iter->buffer;
-	argb_t *e = b + iter->width;
-	argb_t color = image->solid.color_float;
-
-	while (b < e)
-	    *(b++) = color;
-    }
-
-    iter->get_scanline = _pixman_iter_get_scanline_noop;
-}
-
 static uint32_t
 color_to_uint32 (const pixman_color_t *color)
 {


More information about the xorg-commit mailing list