pixman: Branch 'master' - 9 commits

Søren Sandmann Pedersen sandmann at kemper.freedesktop.org
Sat Sep 22 20:43:53 PDT 2012


 pixman/pixman-arm-neon.c       |   89 +++----------
 pixman/pixman-fast-path.c      |    8 -
 pixman/pixman-general.c        |   46 +-----
 pixman/pixman-glyph.c          |    4 
 pixman/pixman-implementation.c |  276 +++++++++++++++++++++++++++--------------
 pixman/pixman-mips-dspr2.c     |   89 +++----------
 pixman/pixman-mmx.c            |  119 +++++------------
 pixman/pixman-noop.c           |   14 +-
 pixman/pixman-private.h        |   36 ++---
 pixman/pixman-sse2.c           |  146 +++++++--------------
 pixman/pixman-utils.c          |  112 ----------------
 pixman/pixman.c                |    2 
 test/scaling-test.c            |   40 ++++-
 13 files changed, 388 insertions(+), 593 deletions(-)

New commits:
commit c4b69e706e63e01fbc70e0026c2079007c89de14
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Wed Sep 19 19:46:13 2012 -0400

    Fix bug in fast_composite_scaled_nearest()
    
    The fast_composite_scaled_nearest() function can be called when the
    format is x8b8g8r8. In that case pixels fetched in fetch_nearest()
    need to have their alpha channel set to 0xff.
    
    Fixes test suite failure in scaling-test.
    
    Reviewed-by: Matt Turner <mattst88 at gmail.com>

diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c
index 83c317f..86ed821 100644
--- a/pixman/pixman-fast-path.c
+++ b/pixman/pixman-fast-path.c
@@ -1458,7 +1458,7 @@ fetch_nearest (pixman_repeat_t src_repeat,
 {
     if (repeat (src_repeat, &x, src_width))
     {
-	if (format == PIXMAN_x8r8g8b8)
+	if (format == PIXMAN_x8r8g8b8 || format == PIXMAN_x8b8g8r8)
 	    return *(src + x) | 0xff000000;
 	else
 	    return *(src + x);
commit 35be7acb660228d4e350b5806c81e55606352e0d
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Wed Sep 19 19:26:49 2012 -0400

    Add PIXMAN_x8b8g8r8 and PIXMAN_a8b8g8r8 formats to scaling-test
    
    Update the CRC values based on what the general implementation
    reports. This reveals a bug in the fast implementation:
    
        % env PIXMAN_DISABLE="mmx sse2" ./test/scaling-test
        pixman: Disabled mmx implementation
        pixman: Disabled sse2 implementation
        scaling test failed! (checksum=AA722B06, expected 03A23E0C)
    
    vs.
    
        % env PIXMAN_DISABLE="mmx sse2 fast" ./test/scaling-test
        pixman: Disabled fast implementation
        pixman: Disabled mmx implementation
        pixman: Disabled sse2 implementation
        scaling test passed (checksum=03A23E0C)
    
    Reviewed-by: Matt Turner <mattst88 at gmail.com>

diff --git a/test/scaling-test.c b/test/scaling-test.c
index 44c4f3d..2736123 100644
--- a/test/scaling-test.c
+++ b/test/scaling-test.c
@@ -20,6 +20,31 @@
 /*
  * Composite operation with pseudorandom images
  */
+
+static pixman_format_code_t
+get_format (int bpp)
+{
+    if (bpp == 4)
+    {
+	switch (lcg_rand_n (4))
+	{
+	default:
+	case 0:
+	    return PIXMAN_a8r8g8b8;
+	case 1:
+	    return PIXMAN_x8r8g8b8;
+	case 2:
+	    return PIXMAN_a8b8g8r8;
+	case 3:
+	    return PIXMAN_x8b8g8r8;
+	}
+    }
+    else
+    {
+	return PIXMAN_r5g6b5;
+    }
+}
+
 uint32_t
 test_composite (int      testnum,
 		int      verbose)
@@ -124,11 +149,8 @@ test_composite (int      testnum,
     for (i = 0; i < dst_stride * dst_height; i++)
 	*((uint8_t *)dstbuf + i) = lcg_rand_n (256);
 
-    src_fmt = src_bpp == 4 ? (lcg_rand_n (2) == 0 ?
-                              PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8) : PIXMAN_r5g6b5;
-
-    dst_fmt = dst_bpp == 4 ? (lcg_rand_n (2) == 0 ?
-                              PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8) : PIXMAN_r5g6b5;
+    src_fmt = get_format (src_bpp);
+    dst_fmt = get_format (dst_bpp);
 
     src_img = pixman_image_create_bits (
         src_fmt, src_width, src_height, srcbuf, src_stride);
@@ -322,7 +344,7 @@ test_composite (int      testnum,
 	pixman_image_composite (op, src_img, mask_img, dst_img,
                             src_x, src_y, mask_x, mask_y, dst_x, dst_y, w, h);
 
-    if (dst_fmt == PIXMAN_x8r8g8b8)
+    if (dst_fmt == PIXMAN_x8r8g8b8 || dst_fmt == PIXMAN_x8b8g8r8)
     {
 	/* ignore unused part */
 	for (i = 0; i < dst_stride * dst_height / 4; i++)
@@ -358,11 +380,11 @@ test_composite (int      testnum,
 }
 
 #if BILINEAR_INTERPOLATION_BITS == 8
-#define CHECKSUM 0x80DF1CB2
+#define CHECKSUM 0x8D3A7539
 #elif BILINEAR_INTERPOLATION_BITS == 7
-#define CHECKSUM 0x2818D5FB
+#define CHECKSUM 0x03A23E0C
 #elif BILINEAR_INTERPOLATION_BITS == 4
-#define CHECKSUM 0x387540A5
+#define CHECKSUM 0xE96D1A5E
 #else
 #define CHECKSUM 0x00000000
 #endif
commit 9decb9a97975ae6bf25a42c0fd2eaa21b166c36d
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Sat Sep 15 19:10:56 2012 -0400

    implementation: Rename delegate to fallback
    
    At this point the chain of implementations has nothing to do with the
    delegation design pattern anymore, so rename the delegate pointer to
    'fallback'.

diff --git a/pixman/pixman-implementation.c b/pixman/pixman-implementation.c
index f371172..5dd0501 100644
--- a/pixman/pixman-implementation.c
+++ b/pixman/pixman-implementation.c
@@ -28,7 +28,7 @@
 #include "pixman-private.h"
 
 pixman_implementation_t *
-_pixman_implementation_create (pixman_implementation_t *delegate,
+_pixman_implementation_create (pixman_implementation_t *fallback,
 			       const pixman_fast_path_t *fast_paths)
 {
     pixman_implementation_t *imp;
@@ -41,11 +41,11 @@ _pixman_implementation_create (pixman_implementation_t *delegate,
 
 	memset (imp, 0, sizeof *imp);
 
-	imp->delegate = delegate;
+	imp->fallback = fallback;
 	imp->fast_paths = fast_paths;
 	
-	/* Make sure the whole delegate chain has the right toplevel */
-	for (d = imp; d != NULL; d = d->delegate)
+	/* Make sure the whole fallback chain has the right toplevel */
+	for (d = imp; d != NULL; d = d->fallback)
 	    d->toplevel = imp;
     }
 
@@ -109,7 +109,7 @@ _pixman_implementation_lookup_composite (pixman_implementation_t  *toplevel,
 	}
     }
 
-    for (imp = toplevel; imp != NULL; imp = imp->delegate)
+    for (imp = toplevel; imp != NULL; imp = imp->fallback)
     {
 	const pixman_fast_path_t *info = imp->fast_paths;
 
@@ -196,7 +196,7 @@ _pixman_implementation_lookup_combiner (pixman_implementation_t *imp,
 	if (f)
 	    return f;
 
-	imp = imp->delegate;
+	imp = imp->fallback;
     }
 
     return NULL;
@@ -227,7 +227,7 @@ _pixman_implementation_blt (pixman_implementation_t * imp,
 	    return TRUE;
 	}
 
-	imp = imp->delegate;
+	imp = imp->fallback;
     }
 
     return FALSE;
@@ -252,7 +252,7 @@ _pixman_implementation_fill (pixman_implementation_t *imp,
 	    return TRUE;
 	}
 
-	imp = imp->delegate;
+	imp = imp->fallback;
     }
 
     return FALSE;
@@ -284,7 +284,7 @@ _pixman_implementation_src_iter_init (pixman_implementation_t	*imp,
 	if (imp->src_iter_init && (*imp->src_iter_init) (imp, iter))
 	    return TRUE;
 
-	imp = imp->delegate;
+	imp = imp->fallback;
     }
 
     return FALSE;
@@ -316,7 +316,7 @@ _pixman_implementation_dest_iter_init (pixman_implementation_t	*imp,
 	if (imp->dest_iter_init && (*imp->dest_iter_init) (imp, iter))
 	    return TRUE;
 
-	imp = imp->delegate;
+	imp = imp->fallback;
     }
 
     return FALSE;
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index e671508..b9c8319 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -466,7 +466,7 @@ typedef struct
 struct pixman_implementation_t
 {
     pixman_implementation_t *	toplevel;
-    pixman_implementation_t *	delegate;
+    pixman_implementation_t *	fallback;
     const pixman_fast_path_t *	fast_paths;
 
     pixman_blt_func_t		blt;
@@ -486,7 +486,7 @@ _pixman_image_get_solid (pixman_implementation_t *imp,
                          pixman_format_code_t     format);
 
 pixman_implementation_t *
-_pixman_implementation_create (pixman_implementation_t *delegate,
+_pixman_implementation_create (pixman_implementation_t *fallback,
 			       const pixman_fast_path_t *fast_paths);
 
 pixman_bool_t
commit b96599ccf353e89f95aa106853fcf310203c5874
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Sat Sep 15 13:58:45 2012 -0400

    _pixman_implementation_create(): Initialize implementation with memset()
    
    All the function pointers are NULL by default now, so we can just zero
    the struct. Also write the function a little more compactly.

diff --git a/pixman/pixman-implementation.c b/pixman/pixman-implementation.c
index 1da9d82..f371172 100644
--- a/pixman/pixman-implementation.c
+++ b/pixman/pixman-implementation.c
@@ -31,35 +31,22 @@ pixman_implementation_t *
 _pixman_implementation_create (pixman_implementation_t *delegate,
 			       const pixman_fast_path_t *fast_paths)
 {
-    pixman_implementation_t *imp = malloc (sizeof (pixman_implementation_t));
-    pixman_implementation_t *d;
-    int i;
-
-    if (!imp)
-	return NULL;
+    pixman_implementation_t *imp;
 
     assert (fast_paths);
 
-    /* Make sure the whole delegate chain has the right toplevel */
-    imp->delegate = delegate;
-    for (d = imp; d != NULL; d = d->delegate)
-	d->toplevel = imp;
-
-    /* Fill out function pointers with ones that just delegate
-     */
-    imp->blt = NULL;
-    imp->fill = NULL;
-    imp->src_iter_init = NULL;
-    imp->dest_iter_init = NULL;
+    if ((imp = malloc (sizeof (pixman_implementation_t))))
+    {
+	pixman_implementation_t *d;
 
-    imp->fast_paths = fast_paths;
+	memset (imp, 0, sizeof *imp);
 
-    for (i = 0; i < PIXMAN_N_OPERATORS; ++i)
-    {
-	imp->combine_32[i] = NULL;
-	imp->combine_64[i] = NULL;
-	imp->combine_32_ca[i] = NULL;
-	imp->combine_64_ca[i] = NULL;
+	imp->delegate = delegate;
+	imp->fast_paths = fast_paths;
+	
+	/* Make sure the whole delegate chain has the right toplevel */
+	for (d = imp; d != NULL; d = d->delegate)
+	    d->toplevel = imp;
     }
 
     return imp;
commit 9539a18832c278ca0f6f572d8765932be6c9ad65
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Sat Sep 15 13:53:17 2012 -0400

    Rename _pixman_lookup_composite_function() to _pixman_implementation_lookup_composite()
    
    And move it into pixman-implementation.c which is where it belongs
    logically.

diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c
index d26f6e7..83c317f 100644
--- a/pixman/pixman-fast-path.c
+++ b/pixman/pixman-fast-path.c
@@ -1258,7 +1258,7 @@ fast_composite_tiled_repeat (pixman_implementation_t *imp,
 	mask_flags = FAST_PATH_IS_OPAQUE;
     }
 
-    if (_pixman_lookup_composite_function (
+    if (_pixman_implementation_lookup_composite (
 	    imp->toplevel, info->op,
 	    src_image->common.extended_format_code, src_flags,
 	    mask_format, mask_flags,
diff --git a/pixman/pixman-glyph.c b/pixman/pixman-glyph.c
index cbc3637..30a4099 100644
--- a/pixman/pixman-glyph.c
+++ b/pixman/pixman-glyph.c
@@ -464,7 +464,7 @@ pixman_composite_glyphs_no_mask (pixman_op_t            op,
 		    glyph_format = glyph_img->common.extended_format_code;
 		    glyph_flags = glyph_img->common.flags;
 		    
-		    _pixman_lookup_composite_function (
+		    _pixman_implementation_lookup_composite (
 			get_implementation(), op,
 			src->common.extended_format_code, src->common.flags,
 			glyph_format, glyph_flags | extra,
@@ -576,7 +576,7 @@ add_glyphs (pixman_glyph_cache_t *cache,
 		white_src = TRUE;
 	    }
 
-	    _pixman_lookup_composite_function (
+	    _pixman_implementation_lookup_composite (
 		get_implementation(), PIXMAN_OP_ADD,
 		src_format, info.src_flags,
 		mask_format, info.mask_flags,
diff --git a/pixman/pixman-implementation.c b/pixman/pixman-implementation.c
index 18da162..1da9d82 100644
--- a/pixman/pixman-implementation.c
+++ b/pixman/pixman-implementation.c
@@ -65,6 +65,118 @@ _pixman_implementation_create (pixman_implementation_t *delegate,
     return imp;
 }
 
+#define N_CACHED_FAST_PATHS 8
+
+typedef struct
+{
+    struct
+    {
+	pixman_implementation_t *	imp;
+	pixman_fast_path_t		fast_path;
+    } cache [N_CACHED_FAST_PATHS];
+} cache_t;
+
+PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache);
+
+pixman_bool_t
+_pixman_implementation_lookup_composite (pixman_implementation_t  *toplevel,
+					 pixman_op_t               op,
+					 pixman_format_code_t      src_format,
+					 uint32_t                  src_flags,
+					 pixman_format_code_t      mask_format,
+					 uint32_t                  mask_flags,
+					 pixman_format_code_t      dest_format,
+					 uint32_t                  dest_flags,
+					 pixman_implementation_t **out_imp,
+					 pixman_composite_func_t  *out_func)
+{
+    pixman_implementation_t *imp;
+    cache_t *cache;
+    int i;
+
+    /* Check cache for fast paths */
+    cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache);
+
+    for (i = 0; i < N_CACHED_FAST_PATHS; ++i)
+    {
+	const pixman_fast_path_t *info = &(cache->cache[i].fast_path);
+
+	/* Note that we check for equality here, not whether
+	 * the cached fast path matches. This is to prevent
+	 * us from selecting an overly general fast path
+	 * when a more specific one would work.
+	 */
+	if (info->op == op			&&
+	    info->src_format == src_format	&&
+	    info->mask_format == mask_format	&&
+	    info->dest_format == dest_format	&&
+	    info->src_flags == src_flags	&&
+	    info->mask_flags == mask_flags	&&
+	    info->dest_flags == dest_flags	&&
+	    info->func)
+	{
+	    *out_imp = cache->cache[i].imp;
+	    *out_func = cache->cache[i].fast_path.func;
+
+	    goto update_cache;
+	}
+    }
+
+    for (imp = toplevel; imp != NULL; imp = imp->delegate)
+    {
+	const pixman_fast_path_t *info = imp->fast_paths;
+
+	while (info->op != PIXMAN_OP_NONE)
+	{
+	    if ((info->op == op || info->op == PIXMAN_OP_any)		&&
+		/* Formats */
+		((info->src_format == src_format) ||
+		 (info->src_format == PIXMAN_any))			&&
+		((info->mask_format == mask_format) ||
+		 (info->mask_format == PIXMAN_any))			&&
+		((info->dest_format == dest_format) ||
+		 (info->dest_format == PIXMAN_any))			&&
+		/* Flags */
+		(info->src_flags & src_flags) == info->src_flags	&&
+		(info->mask_flags & mask_flags) == info->mask_flags	&&
+		(info->dest_flags & dest_flags) == info->dest_flags)
+	    {
+		*out_imp = imp;
+		*out_func = info->func;
+
+		/* Set i to the last spot in the cache so that the
+		 * move-to-front code below will work
+		 */
+		i = N_CACHED_FAST_PATHS - 1;
+
+		goto update_cache;
+	    }
+
+	    ++info;
+	}
+    }
+    return FALSE;
+
+update_cache:
+    if (i)
+    {
+	while (i--)
+	    cache->cache[i + 1] = cache->cache[i];
+
+	cache->cache[0].imp = *out_imp;
+	cache->cache[0].fast_path.op = op;
+	cache->cache[0].fast_path.src_format = src_format;
+	cache->cache[0].fast_path.src_flags = src_flags;
+	cache->cache[0].fast_path.mask_format = mask_format;
+	cache->cache[0].fast_path.mask_flags = mask_flags;
+	cache->cache[0].fast_path.dest_format = dest_format;
+	cache->cache[0].fast_path.dest_flags = dest_flags;
+	cache->cache[0].fast_path.func = *out_func;
+    }
+
+    return TRUE;
+}
+
 pixman_combine_32_func_t
 _pixman_implementation_lookup_combiner (pixman_implementation_t *imp,
 					pixman_op_t		 op,
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index fe5f7c6..e671508 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -489,6 +489,18 @@ pixman_implementation_t *
 _pixman_implementation_create (pixman_implementation_t *delegate,
 			       const pixman_fast_path_t *fast_paths);
 
+pixman_bool_t
+_pixman_implementation_lookup_composite (pixman_implementation_t  *toplevel,
+					 pixman_op_t               op,
+					 pixman_format_code_t      src_format,
+					 uint32_t                  src_flags,
+					 pixman_format_code_t      mask_format,
+					 uint32_t                  mask_flags,
+					 pixman_format_code_t      dest_format,
+					 uint32_t                  dest_flags,
+					 pixman_implementation_t **out_imp,
+					 pixman_composite_func_t  *out_func);
+
 pixman_combine_32_func_t
 _pixman_implementation_lookup_combiner (pixman_implementation_t *imp,
 					pixman_op_t		 op,
@@ -770,18 +782,6 @@ pixman_contract (uint32_t *      dst,
                  const uint64_t *src,
                  int             width);
 
-pixman_bool_t
-_pixman_lookup_composite_function (pixman_implementation_t     *toplevel,
-				   pixman_op_t			op,
-				   pixman_format_code_t		src_format,
-				   uint32_t			src_flags,
-				   pixman_format_code_t		mask_format,
-				   uint32_t			mask_flags,
-				   pixman_format_code_t		dest_format,
-				   uint32_t			dest_flags,
-				   pixman_implementation_t    **out_imp,
-				   pixman_composite_func_t     *out_func);
-
 /* Region Helpers */
 pixman_bool_t
 pixman_region32_copy_from_region16 (pixman_region32_t *dst,
diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c
index 93c061a..5633f8f 100644
--- a/pixman/pixman-utils.c
+++ b/pixman/pixman-utils.c
@@ -30,118 +30,6 @@
 
 #include "pixman-private.h"
 
-#define N_CACHED_FAST_PATHS 8
-
-typedef struct
-{
-    struct
-    {
-	pixman_implementation_t *	imp;
-	pixman_fast_path_t		fast_path;
-    } cache [N_CACHED_FAST_PATHS];
-} cache_t;
-
-PIXMAN_DEFINE_THREAD_LOCAL (cache_t, fast_path_cache);
-
-pixman_bool_t
-_pixman_lookup_composite_function (pixman_implementation_t     *toplevel,
-				   pixman_op_t			op,
-				   pixman_format_code_t		src_format,
-				   uint32_t			src_flags,
-				   pixman_format_code_t		mask_format,
-				   uint32_t			mask_flags,
-				   pixman_format_code_t		dest_format,
-				   uint32_t			dest_flags,
-				   pixman_implementation_t    **out_imp,
-				   pixman_composite_func_t     *out_func)
-{
-    pixman_implementation_t *imp;
-    cache_t *cache;
-    int i;
-
-    /* Check cache for fast paths */
-    cache = PIXMAN_GET_THREAD_LOCAL (fast_path_cache);
-
-    for (i = 0; i < N_CACHED_FAST_PATHS; ++i)
-    {
-	const pixman_fast_path_t *info = &(cache->cache[i].fast_path);
-
-	/* Note that we check for equality here, not whether
-	 * the cached fast path matches. This is to prevent
-	 * us from selecting an overly general fast path
-	 * when a more specific one would work.
-	 */
-	if (info->op == op			&&
-	    info->src_format == src_format	&&
-	    info->mask_format == mask_format	&&
-	    info->dest_format == dest_format	&&
-	    info->src_flags == src_flags	&&
-	    info->mask_flags == mask_flags	&&
-	    info->dest_flags == dest_flags	&&
-	    info->func)
-	{
-	    *out_imp = cache->cache[i].imp;
-	    *out_func = cache->cache[i].fast_path.func;
-
-	    goto update_cache;
-	}
-    }
-
-    for (imp = toplevel; imp != NULL; imp = imp->delegate)
-    {
-	const pixman_fast_path_t *info = imp->fast_paths;
-
-	while (info->op != PIXMAN_OP_NONE)
-	{
-	    if ((info->op == op || info->op == PIXMAN_OP_any)		&&
-		/* Formats */
-		((info->src_format == src_format) ||
-		 (info->src_format == PIXMAN_any))			&&
-		((info->mask_format == mask_format) ||
-		 (info->mask_format == PIXMAN_any))			&&
-		((info->dest_format == dest_format) ||
-		 (info->dest_format == PIXMAN_any))			&&
-		/* Flags */
-		(info->src_flags & src_flags) == info->src_flags	&&
-		(info->mask_flags & mask_flags) == info->mask_flags	&&
-		(info->dest_flags & dest_flags) == info->dest_flags)
-	    {
-		*out_imp = imp;
-		*out_func = info->func;
-
-		/* Set i to the last spot in the cache so that the
-		 * move-to-front code below will work
-		 */
-		i = N_CACHED_FAST_PATHS - 1;
-
-		goto update_cache;
-	    }
-
-	    ++info;
-	}
-    }
-    return FALSE;
-
-update_cache:
-    if (i)
-    {
-	while (i--)
-	    cache->cache[i + 1] = cache->cache[i];
-
-	cache->cache[0].imp = *out_imp;
-	cache->cache[0].fast_path.op = op;
-	cache->cache[0].fast_path.src_format = src_format;
-	cache->cache[0].fast_path.src_flags = src_flags;
-	cache->cache[0].fast_path.mask_format = mask_format;
-	cache->cache[0].fast_path.mask_flags = mask_flags;
-	cache->cache[0].fast_path.dest_format = dest_format;
-	cache->cache[0].fast_path.dest_flags = dest_flags;
-	cache->cache[0].fast_path.func = *out_func;
-    }
-
-    return TRUE;
-}
-
 pixman_bool_t
 _pixman_multiply_overflows_size (size_t a, size_t b)
 {
diff --git a/pixman/pixman.c b/pixman/pixman.c
index 994ef38..739cc79 100644
--- a/pixman/pixman.c
+++ b/pixman/pixman.c
@@ -669,7 +669,7 @@ pixman_image_composite32 (pixman_op_t      op,
      */
     op = optimize_operator (op, src_flags, mask_flags, dest_flags);
 
-    if (_pixman_lookup_composite_function (
+    if (_pixman_implementation_lookup_composite (
 	    get_implementation (), op,
 	    src_format, src_flags, mask_format, mask_flags, dest_format, dest_flags,
 	    &imp, &func))
commit ee6af72dadaf9eb049bfeb35dc9ff57c3902403a
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Sat Sep 15 13:20:52 2012 -0400

    Move delegation of src/dest iter init into pixman-implementation.c
    
    Instead of relying on each implementation to delegate when an iterator
    can't be initialized, change the type of iterator initializers to
    boolean and make pixman-implementation.c do the delegation whenever an
    iterator initializer returns FALSE.

diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index 6c6bda0..42a84a0 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -37,7 +37,7 @@
 #include <string.h>
 #include "pixman-private.h"
 
-static void
+static pixman_bool_t
 general_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
 {
     pixman_image_t *image = iter->image;
@@ -54,18 +54,24 @@ general_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
 	_pixman_bits_image_src_iter_init (image, iter);
     else
 	_pixman_log_error (FUNC, "Pixman bug: unknown image type\n");
+
+    return TRUE;
 }
 
-static void
+static pixman_bool_t
 general_dest_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
 {
     if (iter->image->type == BITS)
     {
 	_pixman_bits_image_dest_iter_init (iter->image, iter);
+
+	return TRUE;
     }
     else
     {
 	_pixman_log_error (FUNC, "Trying to write to a non-writable image");
+
+	return FALSE;
     }
 }
 
diff --git a/pixman/pixman-implementation.c b/pixman/pixman-implementation.c
index 5607f9d..18da162 100644
--- a/pixman/pixman-implementation.c
+++ b/pixman/pixman-implementation.c
@@ -27,20 +27,6 @@
 #include <stdlib.h>
 #include "pixman-private.h"
 
-static void
-delegate_src_iter_init (pixman_implementation_t *imp,
-			pixman_iter_t *	         iter)
-{
-    imp->delegate->src_iter_init (imp->delegate, iter);
-}
-
-static void
-delegate_dest_iter_init (pixman_implementation_t *imp,
-			 pixman_iter_t *	  iter)
-{
-    imp->delegate->dest_iter_init (imp->delegate, iter);
-}
-
 pixman_implementation_t *
 _pixman_implementation_create (pixman_implementation_t *delegate,
 			       const pixman_fast_path_t *fast_paths)
@@ -63,8 +49,8 @@ _pixman_implementation_create (pixman_implementation_t *delegate,
      */
     imp->blt = NULL;
     imp->fill = NULL;
-    imp->src_iter_init = delegate_src_iter_init;
-    imp->dest_iter_init = delegate_dest_iter_init;
+    imp->src_iter_init = NULL;
+    imp->dest_iter_init = NULL;
 
     imp->fast_paths = fast_paths;
 
@@ -173,7 +159,7 @@ _pixman_implementation_fill (pixman_implementation_t *imp,
     return FALSE;
 }
 
-void
+pixman_bool_t
 _pixman_implementation_src_iter_init (pixman_implementation_t	*imp,
 				      pixman_iter_t             *iter,
 				      pixman_image_t		*image,
@@ -194,10 +180,18 @@ _pixman_implementation_src_iter_init (pixman_implementation_t	*imp,
     iter->iter_flags = iter_flags;
     iter->image_flags = image_flags;
 
-    (*imp->src_iter_init) (imp, iter);
+    while (imp)
+    {
+	if (imp->src_iter_init && (*imp->src_iter_init) (imp, iter))
+	    return TRUE;
+
+	imp = imp->delegate;
+    }
+
+    return FALSE;
 }
 
-void
+pixman_bool_t
 _pixman_implementation_dest_iter_init (pixman_implementation_t	*imp,
 				       pixman_iter_t            *iter,
 				       pixman_image_t		*image,
@@ -218,7 +212,15 @@ _pixman_implementation_dest_iter_init (pixman_implementation_t	*imp,
     iter->iter_flags = iter_flags;
     iter->image_flags = image_flags;
 
-    (*imp->dest_iter_init) (imp, iter);
+    while (imp)
+    {
+	if (imp->dest_iter_init && (*imp->dest_iter_init) (imp, iter))
+	    return TRUE;
+
+	imp = imp->delegate;
+    }
+
+    return FALSE;
 }
 
 pixman_bool_t
diff --git a/pixman/pixman-mmx.c b/pixman/pixman-mmx.c
index a5a56f9..fccba9d 100644
--- a/pixman/pixman-mmx.c
+++ b/pixman/pixman-mmx.c
@@ -3915,7 +3915,7 @@ static const fetcher_info_t fetchers[] =
     { PIXMAN_null }
 };
 
-static void
+static pixman_bool_t
 mmx_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
 {
     pixman_image_t *image = iter->image;
@@ -3940,12 +3940,12 @@ mmx_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
 		iter->stride = s;
 
 		iter->get_scanline = f->get_scanline;
-		return;
+		return TRUE;
 	    }
 	}
     }
 
-    imp->delegate->src_iter_init (imp->delegate, iter);
+    return FALSE;
 }
 
 static const pixman_fast_path_t mmx_fast_paths[] =
diff --git a/pixman/pixman-noop.c b/pixman/pixman-noop.c
index 7b017e8..7b9759f 100644
--- a/pixman/pixman-noop.c
+++ b/pixman/pixman-noop.c
@@ -59,7 +59,7 @@ get_scanline_null (pixman_iter_t *iter, const uint32_t *mask)
     return NULL;
 }
 
-static void
+static pixman_bool_t
 noop_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
 {
     pixman_image_t *image = iter->image;
@@ -117,11 +117,13 @@ noop_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
     }
     else
     {
-	(* imp->delegate->src_iter_init) (imp->delegate, iter);
+	return FALSE;
     }
+
+    return TRUE;
 }
 
-static void
+static pixman_bool_t
 noop_dest_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
 {
     pixman_image_t *image = iter->image;
@@ -138,10 +140,12 @@ noop_dest_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
 
 	iter->get_scanline = _pixman_iter_get_scanline_noop;
 	iter->write_back = dest_write_back_direct;
+
+	return TRUE;
     }
     else
     {
-	(* imp->delegate->dest_iter_init) (imp->delegate, iter);
+	return FALSE;
     }
 }
 
@@ -156,7 +160,7 @@ _pixman_implementation_create_noop (pixman_implementation_t *fallback)
 {
     pixman_implementation_t *imp =
 	_pixman_implementation_create (fallback, noop_fast_paths);
-
+ 
     imp->src_iter_init = noop_src_iter_init;
     imp->dest_iter_init = noop_dest_iter_init;
 
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index dbfa829..fe5f7c6 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -445,8 +445,8 @@ typedef pixman_bool_t (*pixman_fill_func_t) (pixman_implementation_t *imp,
 					     int                      width,
 					     int                      height,
 					     uint32_t                 xor);
-typedef void (*pixman_iter_init_func_t) (pixman_implementation_t *imp,
-                                         pixman_iter_t           *iter);
+typedef pixman_bool_t (*pixman_iter_init_func_t) (pixman_implementation_t *imp,
+						  pixman_iter_t           *iter);
 
 void _pixman_setup_combiner_functions_32 (pixman_implementation_t *imp);
 void _pixman_setup_combiner_functions_64 (pixman_implementation_t *imp);
@@ -521,7 +521,7 @@ _pixman_implementation_fill (pixman_implementation_t *imp,
                              int                      height,
                              uint32_t                 xor);
 
-void
+pixman_bool_t
 _pixman_implementation_src_iter_init (pixman_implementation_t       *imp,
 				      pixman_iter_t                 *iter,
 				      pixman_image_t                *image,
@@ -533,7 +533,7 @@ _pixman_implementation_src_iter_init (pixman_implementation_t       *imp,
 				      iter_flags_t                   flags,
 				      uint32_t                       image_flags);
 
-void
+pixman_bool_t
 _pixman_implementation_dest_iter_init (pixman_implementation_t       *imp,
 				       pixman_iter_t                 *iter,
 				       pixman_image_t                *image,
diff --git a/pixman/pixman-sse2.c b/pixman/pixman-sse2.c
index 428db73..e273a95 100644
--- a/pixman/pixman-sse2.c
+++ b/pixman/pixman-sse2.c
@@ -6024,7 +6024,7 @@ static const fetcher_info_t fetchers[] =
     { PIXMAN_null }
 };
 
-static void
+static pixman_bool_t
 sse2_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
 {
     pixman_image_t *image = iter->image;
@@ -6049,12 +6049,12 @@ sse2_src_iter_init (pixman_implementation_t *imp, pixman_iter_t *iter)
 		iter->stride = s;
 
 		iter->get_scanline = f->get_scanline;
-		return;
+		return TRUE;
 	    }
 	}
     }
 
-    imp->delegate->src_iter_init (imp->delegate, iter);
+    return FALSE;
 }
 
 #if defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
commit c710d0fae2a9dc7d20913e5e39a1bb53f7c942db
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Sat Sep 15 13:08:51 2012 -0400

    Move fill delegation into pixman-implementation.c
    
    As in the blt commit, do the delegation in pixman-implementation.c
    whenever the implementation fill returns FALSE instead of relying on
    each implementation to do it by itself.
    
    With this change there is no longer any reason for the implementations
    to have one fill function that delegates and one that actually blits,
    so consolidate those in the NEON, DSPr2, SSE2, and MMX
    implementations.

diff --git a/pixman/pixman-arm-neon.c b/pixman/pixman-arm-neon.c
index f4cc0ba..60e9c78 100644
--- a/pixman/pixman-arm-neon.c
+++ b/pixman/pixman-arm-neon.c
@@ -183,14 +183,15 @@ pixman_composite_src_n_8888_asm_neon (int32_t   w,
                                       uint32_t  src);
 
 static pixman_bool_t
-pixman_fill_neon (uint32_t *bits,
-                  int       stride,
-                  int       bpp,
-                  int       x,
-                  int       y,
-                  int       width,
-                  int       height,
-                  uint32_t  _xor)
+arm_neon_fill (pixman_implementation_t *imp,
+               uint32_t *               bits,
+               int                      stride,
+               int                      bpp,
+               int                      x,
+               int                      y,
+               int                      width,
+               int                      height,
+	       uint32_t                 _xor)
 {
     /* stride is always multiple of 32bit units in pixman */
     uint32_t byte_stride = stride * sizeof(uint32_t);
@@ -423,24 +424,6 @@ static const pixman_fast_path_t arm_neon_fast_paths[] =
     { PIXMAN_OP_NONE },
 };
 
-static pixman_bool_t
-arm_neon_fill (pixman_implementation_t *imp,
-               uint32_t *               bits,
-               int                      stride,
-               int                      bpp,
-               int                      x,
-               int                      y,
-               int                      width,
-               int                      height,
-               uint32_t xor)
-{
-    if (pixman_fill_neon (bits, stride, bpp, x, y, width, height, xor))
-	return TRUE;
-
-    return _pixman_implementation_fill (
-	imp->delegate, bits, stride, bpp, x, y, width, height, xor);
-}
-
 #define BIND_COMBINE_U(name)                                             \
 void                                                                     \
 pixman_composite_scanline_##name##_mask_asm_neon (int32_t         w,     \
diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c
index 9778b0c..d26f6e7 100644
--- a/pixman/pixman-fast-path.c
+++ b/pixman/pixman-fast-path.c
@@ -2192,9 +2192,7 @@ fast_path_fill (pixman_implementation_t *imp,
 	break;
 
     default:
-	return _pixman_implementation_fill (
-	    imp->delegate, bits, stride, bpp, x, y, width, height, xor);
-	break;
+	return FALSE;
     }
 
     return TRUE;
diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index dcf9bfc..6c6bda0 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -200,20 +200,6 @@ static const pixman_fast_path_t general_fast_path[] =
     { PIXMAN_OP_NONE }
 };
 
-static pixman_bool_t
-general_fill (pixman_implementation_t *imp,
-              uint32_t *               bits,
-              int                      stride,
-              int                      bpp,
-              int                      x,
-              int                      y,
-              int                      width,
-              int                      height,
-              uint32_t xor)
-{
-    return FALSE;
-}
-
 pixman_implementation_t *
 _pixman_implementation_create_general (void)
 {
@@ -222,7 +208,6 @@ _pixman_implementation_create_general (void)
     _pixman_setup_combiner_functions_32 (imp);
     _pixman_setup_combiner_functions_64 (imp);
 
-    imp->fill = general_fill;
     imp->src_iter_init = general_src_iter_init;
     imp->dest_iter_init = general_dest_iter_init;
 
diff --git a/pixman/pixman-implementation.c b/pixman/pixman-implementation.c
index 8b07848..5607f9d 100644
--- a/pixman/pixman-implementation.c
+++ b/pixman/pixman-implementation.c
@@ -27,21 +27,6 @@
 #include <stdlib.h>
 #include "pixman-private.h"
 
-static pixman_bool_t
-delegate_fill (pixman_implementation_t *imp,
-               uint32_t *               bits,
-               int                      stride,
-               int                      bpp,
-               int                      x,
-               int                      y,
-               int                      width,
-               int                      height,
-               uint32_t                 xor)
-{
-    return _pixman_implementation_fill (
-	imp->delegate, bits, stride, bpp, x, y, width, height, xor);
-}
-
 static void
 delegate_src_iter_init (pixman_implementation_t *imp,
 			pixman_iter_t *	         iter)
@@ -77,7 +62,7 @@ _pixman_implementation_create (pixman_implementation_t *delegate,
     /* Fill out function pointers with ones that just delegate
      */
     imp->blt = NULL;
-    imp->fill = delegate_fill;
+    imp->fill = NULL;
     imp->src_iter_init = delegate_src_iter_init;
     imp->dest_iter_init = delegate_dest_iter_init;
 
@@ -174,7 +159,18 @@ _pixman_implementation_fill (pixman_implementation_t *imp,
                              int                      height,
                              uint32_t                 xor)
 {
-    return (*imp->fill) (imp, bits, stride, bpp, x, y, width, height, xor);
+    while (imp)
+    {
+	if (imp->fill &&
+	    ((*imp->fill) (imp, bits, stride, bpp, x, y, width, height, xor)))
+	{
+	    return TRUE;
+	}
+
+	imp = imp->delegate;
+    }
+
+    return FALSE;
 }
 
 void
diff --git a/pixman/pixman-mips-dspr2.c b/pixman/pixman-mips-dspr2.c
index 7c4ac60..1a9e610 100644
--- a/pixman/pixman-mips-dspr2.c
+++ b/pixman/pixman-mips-dspr2.c
@@ -85,14 +85,15 @@ PIXMAN_MIPS_BIND_SCALED_BILINEAR_SRC_A8_DST (SKIP_ZERO_SRC, 8888_8_8888, ADD,
                                              uint32_t, uint32_t)
 
 static pixman_bool_t
-pixman_fill_mips (uint32_t *bits,
-                  int       stride,
-                  int       bpp,
-                  int       x,
-                  int       y,
-                  int       width,
-                  int       height,
-                  uint32_t  _xor)
+mips_dspr2_fill (pixman_implementation_t *imp,
+                 uint32_t *               bits,
+                 int                      stride,
+                 int                      bpp,
+                 int                      x,
+                 int                      y,
+                 int                      width,
+                 int                      height,
+                 uint32_t                 _xor)
 {
     uint8_t *byte_line;
     uint32_t byte_width;
@@ -267,24 +268,6 @@ static const pixman_fast_path_t mips_dspr2_fast_paths[] =
     { PIXMAN_OP_NONE },
 };
 
-static pixman_bool_t
-mips_dspr2_fill (pixman_implementation_t *imp,
-                 uint32_t *               bits,
-                 int                      stride,
-                 int                      bpp,
-                 int                      x,
-                 int                      y,
-                 int                      width,
-                 int                      height,
-                 uint32_t xor)
-{
-    if (pixman_fill_mips (bits, stride, bpp, x, y, width, height, xor))
-        return TRUE;
-
-    return _pixman_implementation_fill (
-        imp->delegate, bits, stride, bpp, x, y, width, height, xor);
-}
-
 pixman_implementation_t *
 _pixman_implementation_create_mips_dspr2 (pixman_implementation_t *fallback)
 {
diff --git a/pixman/pixman-mmx.c b/pixman/pixman-mmx.c
index 7df4abb..a5a56f9 100644
--- a/pixman/pixman-mmx.c
+++ b/pixman/pixman-mmx.c
@@ -2055,15 +2055,16 @@ mmx_composite_over_n_8_8888 (pixman_implementation_t *imp,
     _mm_empty ();
 }
 
-pixman_bool_t
-pixman_fill_mmx (uint32_t *bits,
-                 int       stride,
-                 int       bpp,
-                 int       x,
-                 int       y,
-                 int       width,
-                 int       height,
-                 uint32_t xor)
+static pixman_bool_t
+mmx_fill (pixman_implementation_t *imp,
+          uint32_t *               bits,
+          int                      stride,
+          int                      bpp,
+          int                      x,
+          int                      y,
+          int                      width,
+          int                      height,
+          uint32_t		   xor)
 {
     uint64_t fill;
     __m64 vfill;
@@ -2281,9 +2282,9 @@ mmx_composite_src_n_8_8888 (pixman_implementation_t *imp,
     srca = src >> 24;
     if (src == 0)
     {
-	pixman_fill_mmx (dest_image->bits.bits, dest_image->bits.rowstride,
-			 PIXMAN_FORMAT_BPP (dest_image->bits.format),
-	                 dest_x, dest_y, width, height, 0);
+	mmx_fill (imp, dest_image->bits.bits, dest_image->bits.rowstride,
+		  PIXMAN_FORMAT_BPP (dest_image->bits.format),
+		  dest_x, dest_y, width, height, 0);
 	return;
     }
 
@@ -4043,26 +4044,6 @@ static const pixman_fast_path_t mmx_fast_paths[] =
     { PIXMAN_OP_NONE },
 };
 
-static pixman_bool_t
-mmx_fill (pixman_implementation_t *imp,
-          uint32_t *               bits,
-          int                      stride,
-          int                      bpp,
-          int                      x,
-          int                      y,
-          int                      width,
-          int                      height,
-          uint32_t xor)
-{
-    if (!pixman_fill_mmx (bits, stride, bpp, x, y, width, height, xor))
-    {
-	return _pixman_implementation_fill (
-	    imp->delegate, bits, stride, bpp, x, y, width, height, xor);
-    }
-
-    return TRUE;
-}
-
 pixman_implementation_t *
 _pixman_implementation_create_mmx (pixman_implementation_t *fallback)
 {
diff --git a/pixman/pixman-sse2.c b/pixman/pixman-sse2.c
index 42c0e99..428db73 100644
--- a/pixman/pixman-sse2.c
+++ b/pixman/pixman-sse2.c
@@ -3309,18 +3309,22 @@ sse2_composite_over_n_8_8888 (pixman_implementation_t *imp,
 
 }
 
+#if defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
+__attribute__((__force_align_arg_pointer__))
+#endif
 static pixman_bool_t
-pixman_fill_sse2 (uint32_t *bits,
-                  int       stride,
-                  int       bpp,
-                  int       x,
-                  int       y,
-                  int       width,
-                  int       height,
-                  uint32_t  data)
+sse2_fill (pixman_implementation_t *imp,
+           uint32_t *               bits,
+           int                      stride,
+           int                      bpp,
+           int                      x,
+           int                      y,
+           int                      width,
+           int                      height,
+           uint32_t		    xor)
 {
     uint32_t byte_width;
-    uint8_t         *byte_line;
+    uint8_t *byte_line;
 
     __m128i xmm_def;
 
@@ -3334,9 +3338,9 @@ pixman_fill_sse2 (uint32_t *bits,
 	byte_width = width;
 	stride *= 1;
 
-	b = data & 0xff;
+	b = xor & 0xff;
 	w = (b << 8) | b;
-	data = (w << 16) | w;
+	xor = (w << 16) | w;
     }
     else if (bpp == 16)
     {
@@ -3345,7 +3349,7 @@ pixman_fill_sse2 (uint32_t *bits,
 	byte_width = 2 * width;
 	stride *= 2;
 
-        data = (data & 0xffff) * 0x00010001;
+        xor = (xor & 0xffff) * 0x00010001;
     }
     else if (bpp == 32)
     {
@@ -3359,7 +3363,7 @@ pixman_fill_sse2 (uint32_t *bits,
 	return FALSE;
     }
 
-    xmm_def = create_mask_2x32_128 (data, data);
+    xmm_def = create_mask_2x32_128 (xor, xor);
 
     while (height--)
     {
@@ -3370,21 +3374,21 @@ pixman_fill_sse2 (uint32_t *bits,
 
 	if (w >= 1 && ((unsigned long)d & 1))
 	{
-	    *(uint8_t *)d = data;
+	    *(uint8_t *)d = xor;
 	    w -= 1;
 	    d += 1;
 	}
 
 	while (w >= 2 && ((unsigned long)d & 3))
 	{
-	    *(uint16_t *)d = data;
+	    *(uint16_t *)d = xor;
 	    w -= 2;
 	    d += 2;
 	}
 
 	while (w >= 4 && ((unsigned long)d & 15))
 	{
-	    *(uint32_t *)d = data;
+	    *(uint32_t *)d = xor;
 
 	    w -= 4;
 	    d += 4;
@@ -3435,7 +3439,7 @@ pixman_fill_sse2 (uint32_t *bits,
 
 	while (w >= 4)
 	{
-	    *(uint32_t *)d = data;
+	    *(uint32_t *)d = xor;
 
 	    w -= 4;
 	    d += 4;
@@ -3443,14 +3447,14 @@ pixman_fill_sse2 (uint32_t *bits,
 
 	if (w >= 2)
 	{
-	    *(uint16_t *)d = data;
+	    *(uint16_t *)d = xor;
 	    w -= 2;
 	    d += 2;
 	}
 
 	if (w >= 1)
 	{
-	    *(uint8_t *)d = data;
+	    *(uint8_t *)d = xor;
 	    w -= 1;
 	    d += 1;
 	}
@@ -3479,9 +3483,9 @@ sse2_composite_src_n_8_8888 (pixman_implementation_t *imp,
     srca = src >> 24;
     if (src == 0)
     {
-	pixman_fill_sse2 (dest_image->bits.bits, dest_image->bits.rowstride,
-	                  PIXMAN_FORMAT_BPP (dest_image->bits.format),
-	                  dest_x, dest_y, width, height, 0);
+	sse2_fill (imp, dest_image->bits.bits, dest_image->bits.rowstride,
+		   PIXMAN_FORMAT_BPP (dest_image->bits.format),
+		   dest_x, dest_y, width, height, 0);
 	return;
     }
 
@@ -5878,29 +5882,6 @@ static const pixman_fast_path_t sse2_fast_paths[] =
     { PIXMAN_OP_NONE },
 };
 
-#if defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
-__attribute__((__force_align_arg_pointer__))
-#endif
-static pixman_bool_t
-sse2_fill (pixman_implementation_t *imp,
-           uint32_t *               bits,
-           int                      stride,
-           int                      bpp,
-           int                      x,
-           int                      y,
-           int                      width,
-           int                      height,
-           uint32_t xor)
-{
-    if (!pixman_fill_sse2 (bits, stride, bpp, x, y, width, height, xor))
-    {
-	return _pixman_implementation_fill (
-	    imp->delegate, bits, stride, bpp, x, y, width, height, xor);
-    }
-
-    return TRUE;
-}
-
 static uint32_t *
 sse2_fetch_x8r8g8b8 (pixman_iter_t *iter, const uint32_t *mask)
 {
commit 534507ba3b00b9aaadc9f181c282b01e4e2fe415
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Sat Sep 15 13:03:10 2012 -0400

    Move blt delegation into pixman-implementation.c
    
    Rather than require each individual implementation to do the
    delegation for blt, just do it in pixman-implementation.c whenever the
    implementation blt returns FALSE.
    
    With this change, there is no longer any reason for the
    implementations to have one blt function that delegates and one that
    actually blits, so consolidate those in the NEON, DSPr2, SSE2, and MMX
    implementations.

diff --git a/pixman/pixman-arm-neon.c b/pixman/pixman-arm-neon.c
index ca139de..f4cc0ba 100644
--- a/pixman/pixman-arm-neon.c
+++ b/pixman/pixman-arm-neon.c
@@ -227,18 +227,19 @@ pixman_fill_neon (uint32_t *bits,
 }
 
 static pixman_bool_t
-pixman_blt_neon (uint32_t *src_bits,
-                 uint32_t *dst_bits,
-                 int       src_stride,
-                 int       dst_stride,
-                 int       src_bpp,
-                 int       dst_bpp,
-                 int       src_x,
-                 int       src_y,
-                 int       dest_x,
-                 int       dest_y,
-                 int       width,
-                 int       height)
+arm_neon_blt (pixman_implementation_t *imp,
+              uint32_t *               src_bits,
+              uint32_t *               dst_bits,
+              int                      src_stride,
+              int                      dst_stride,
+              int                      src_bpp,
+              int                      dst_bpp,
+              int                      src_x,
+              int                      src_y,
+              int                      dest_x,
+              int                      dest_y,
+              int                      width,
+              int                      height)
 {
     if (src_bpp != dst_bpp)
 	return FALSE;
@@ -423,35 +424,6 @@ static const pixman_fast_path_t arm_neon_fast_paths[] =
 };
 
 static pixman_bool_t
-arm_neon_blt (pixman_implementation_t *imp,
-              uint32_t *               src_bits,
-              uint32_t *               dst_bits,
-              int                      src_stride,
-              int                      dst_stride,
-              int                      src_bpp,
-              int                      dst_bpp,
-              int                      src_x,
-              int                      src_y,
-              int                      dest_x,
-              int                      dest_y,
-              int                      width,
-              int                      height)
-{
-    if (!pixman_blt_neon (
-            src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp,
-            src_x, src_y, dest_x, dest_y, width, height))
-
-    {
-	return _pixman_implementation_blt (
-	    imp->delegate,
-	    src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp,
-	    src_x, src_y, dest_x, dest_y, width, height);
-    }
-
-    return TRUE;
-}
-
-static pixman_bool_t
 arm_neon_fill (pixman_implementation_t *imp,
                uint32_t *               bits,
                int                      stride,
diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index d4b2daa..dcf9bfc 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -201,26 +201,6 @@ static const pixman_fast_path_t general_fast_path[] =
 };
 
 static pixman_bool_t
-general_blt (pixman_implementation_t *imp,
-             uint32_t *               src_bits,
-             uint32_t *               dst_bits,
-             int                      src_stride,
-             int                      dst_stride,
-             int                      src_bpp,
-             int                      dst_bpp,
-             int                      src_x,
-             int                      src_y,
-             int                      dest_x,
-             int                      dest_y,
-             int                      width,
-             int                      height)
-{
-    /* We can't blit unless we have sse2 or mmx */
-
-    return FALSE;
-}
-
-static pixman_bool_t
 general_fill (pixman_implementation_t *imp,
               uint32_t *               bits,
               int                      stride,
@@ -242,7 +222,6 @@ _pixman_implementation_create_general (void)
     _pixman_setup_combiner_functions_32 (imp);
     _pixman_setup_combiner_functions_64 (imp);
 
-    imp->blt = general_blt;
     imp->fill = general_fill;
     imp->src_iter_init = general_src_iter_init;
     imp->dest_iter_init = general_dest_iter_init;
diff --git a/pixman/pixman-implementation.c b/pixman/pixman-implementation.c
index d2573ab..8b07848 100644
--- a/pixman/pixman-implementation.c
+++ b/pixman/pixman-implementation.c
@@ -28,27 +28,6 @@
 #include "pixman-private.h"
 
 static pixman_bool_t
-delegate_blt (pixman_implementation_t * imp,
-              uint32_t *                src_bits,
-              uint32_t *                dst_bits,
-              int                       src_stride,
-              int                       dst_stride,
-              int                       src_bpp,
-              int                       dst_bpp,
-              int                       src_x,
-              int                       src_y,
-              int                       dest_x,
-              int                       dest_y,
-              int                       width,
-              int                       height)
-{
-    return _pixman_implementation_blt (
-	imp->delegate, src_bits, dst_bits, src_stride, dst_stride,
-	src_bpp, dst_bpp, src_x, src_y, dest_x, dest_y,
-	width, height);
-}
-
-static pixman_bool_t
 delegate_fill (pixman_implementation_t *imp,
                uint32_t *               bits,
                int                      stride,
@@ -97,7 +76,7 @@ _pixman_implementation_create (pixman_implementation_t *delegate,
 
     /* Fill out function pointers with ones that just delegate
      */
-    imp->blt = delegate_blt;
+    imp->blt = NULL;
     imp->fill = delegate_fill;
     imp->src_iter_init = delegate_src_iter_init;
     imp->dest_iter_init = delegate_dest_iter_init;
@@ -168,9 +147,20 @@ _pixman_implementation_blt (pixman_implementation_t * imp,
                             int                       width,
                             int                       height)
 {
-    return (*imp->blt) (imp, src_bits, dst_bits, src_stride, dst_stride,
-			src_bpp, dst_bpp, src_x, src_y, dest_x, dest_y,
-			width, height);
+    while (imp)
+    {
+	if (imp->blt &&
+	    (*imp->blt) (imp, src_bits, dst_bits, src_stride, dst_stride,
+			 src_bpp, dst_bpp, src_x, src_y, dest_x, dest_y,
+			 width, height))
+	{
+	    return TRUE;
+	}
+
+	imp = imp->delegate;
+    }
+
+    return FALSE;
 }
 
 pixman_bool_t
diff --git a/pixman/pixman-mips-dspr2.c b/pixman/pixman-mips-dspr2.c
index 63a0225..7c4ac60 100644
--- a/pixman/pixman-mips-dspr2.c
+++ b/pixman/pixman-mips-dspr2.c
@@ -130,18 +130,19 @@ pixman_fill_mips (uint32_t *bits,
 }
 
 static pixman_bool_t
-pixman_blt_mips (uint32_t *src_bits,
-                 uint32_t *dst_bits,
-                 int       src_stride,
-                 int       dst_stride,
-                 int       src_bpp,
-                 int       dst_bpp,
-                 int       src_x,
-                 int       src_y,
-                 int       dest_x,
-                 int       dest_y,
-                 int       width,
-                 int       height)
+mips_dspr2_blt (pixman_implementation_t *imp,
+                uint32_t *               src_bits,
+                uint32_t *               dst_bits,
+                int                      src_stride,
+                int                      dst_stride,
+                int                      src_bpp,
+                int                      dst_bpp,
+                int                      src_x,
+                int                      src_y,
+                int                      dest_x,
+                int                      dest_y,
+                int                      width,
+                int                      height)
 {
     if (src_bpp != dst_bpp)
         return FALSE;
@@ -267,35 +268,6 @@ static const pixman_fast_path_t mips_dspr2_fast_paths[] =
 };
 
 static pixman_bool_t
-mips_dspr2_blt (pixman_implementation_t *imp,
-                uint32_t *               src_bits,
-                uint32_t *               dst_bits,
-                int                      src_stride,
-                int                      dst_stride,
-                int                      src_bpp,
-                int                      dst_bpp,
-                int                      src_x,
-                int                      src_y,
-                int                      dest_x,
-                int                      dest_y,
-                int                      width,
-                int                      height)
-{
-    if (!pixman_blt_mips (
-            src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp,
-            src_x, src_y, dest_x, dest_y, width, height))
-
-    {
-        return _pixman_implementation_blt (
-            imp->delegate,
-            src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp,
-            src_x, src_y, dest_x, dest_y, width, height);
-    }
-
-    return TRUE;
-}
-
-static pixman_bool_t
 mips_dspr2_fill (pixman_implementation_t *imp,
                  uint32_t *               bits,
                  int                      stride,
diff --git a/pixman/pixman-mmx.c b/pixman/pixman-mmx.c
index b3a4c5f..7df4abb 100644
--- a/pixman/pixman-mmx.c
+++ b/pixman/pixman-mmx.c
@@ -3240,18 +3240,19 @@ mmx_composite_add_8888_8888 (pixman_implementation_t *imp,
 }
 
 static pixman_bool_t
-pixman_blt_mmx (uint32_t *src_bits,
-                uint32_t *dst_bits,
-                int       src_stride,
-                int       dst_stride,
-                int       src_bpp,
-                int       dst_bpp,
-                int       src_x,
-                int       src_y,
-                int       dest_x,
-                int       dest_y,
-                int       width,
-                int       height)
+mmx_blt (pixman_implementation_t *imp,
+         uint32_t *               src_bits,
+         uint32_t *               dst_bits,
+         int                      src_stride,
+         int                      dst_stride,
+         int                      src_bpp,
+         int                      dst_bpp,
+         int                      src_x,
+         int                      src_y,
+         int                      dest_x,
+         int                      dest_y,
+         int                      width,
+         int                      height)
 {
     uint8_t *   src_bytes;
     uint8_t *   dst_bytes;
@@ -3396,13 +3397,13 @@ mmx_composite_copy_area (pixman_implementation_t *imp,
 {
     PIXMAN_COMPOSITE_ARGS (info);
 
-    pixman_blt_mmx (src_image->bits.bits,
-                    dest_image->bits.bits,
-                    src_image->bits.rowstride,
-                    dest_image->bits.rowstride,
-                    PIXMAN_FORMAT_BPP (src_image->bits.format),
-                    PIXMAN_FORMAT_BPP (dest_image->bits.format),
-                    src_x, src_y, dest_x, dest_y, width, height);
+    mmx_blt (imp, src_image->bits.bits,
+	     dest_image->bits.bits,
+	     src_image->bits.rowstride,
+	     dest_image->bits.rowstride,
+	     PIXMAN_FORMAT_BPP (src_image->bits.format),
+	     PIXMAN_FORMAT_BPP (dest_image->bits.format),
+	     src_x, src_y, dest_x, dest_y, width, height);
 }
 
 static void
@@ -4043,35 +4044,6 @@ static const pixman_fast_path_t mmx_fast_paths[] =
 };
 
 static pixman_bool_t
-mmx_blt (pixman_implementation_t *imp,
-         uint32_t *               src_bits,
-         uint32_t *               dst_bits,
-         int                      src_stride,
-         int                      dst_stride,
-         int                      src_bpp,
-         int                      dst_bpp,
-         int                      src_x,
-         int                      src_y,
-         int                      dest_x,
-         int                      dest_y,
-         int                      width,
-         int                      height)
-{
-    if (!pixman_blt_mmx (
-            src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp,
-            src_x, src_y, dest_x, dest_y, width, height))
-
-    {
-	return _pixman_implementation_blt (
-	    imp->delegate,
-	    src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp,
-	    src_x, src_y, dest_x, dest_y, width, height);
-    }
-
-    return TRUE;
-}
-
-static pixman_bool_t
 mmx_fill (pixman_implementation_t *imp,
           uint32_t *               bits,
           int                      stride,
diff --git a/pixman/pixman-sse2.c b/pixman/pixman-sse2.c
index 665eead..42c0e99 100644
--- a/pixman/pixman-sse2.c
+++ b/pixman/pixman-sse2.c
@@ -4523,18 +4523,19 @@ sse2_composite_add_8888_8888 (pixman_implementation_t *imp,
 }
 
 static pixman_bool_t
-pixman_blt_sse2 (uint32_t *src_bits,
-                 uint32_t *dst_bits,
-                 int       src_stride,
-                 int       dst_stride,
-                 int       src_bpp,
-                 int       dst_bpp,
-                 int       src_x,
-                 int       src_y,
-                 int       dest_x,
-                 int       dest_y,
-                 int       width,
-                 int       height)
+sse2_blt (pixman_implementation_t *imp,
+          uint32_t *               src_bits,
+          uint32_t *               dst_bits,
+          int                      src_stride,
+          int                      dst_stride,
+          int                      src_bpp,
+          int                      dst_bpp,
+          int                      src_x,
+          int                      src_y,
+          int                      dest_x,
+          int                      dest_y,
+          int                      width,
+          int                      height)
 {
     uint8_t *   src_bytes;
     uint8_t *   dst_bytes;
@@ -4640,7 +4641,6 @@ pixman_blt_sse2 (uint32_t *src_bits,
 	}
     }
 
-
     return TRUE;
 }
 
@@ -4649,13 +4649,13 @@ sse2_composite_copy_area (pixman_implementation_t *imp,
                           pixman_composite_info_t *info)
 {
     PIXMAN_COMPOSITE_ARGS (info);
-    pixman_blt_sse2 (src_image->bits.bits,
-                     dest_image->bits.bits,
-                     src_image->bits.rowstride,
-                     dest_image->bits.rowstride,
-                     PIXMAN_FORMAT_BPP (src_image->bits.format),
-                     PIXMAN_FORMAT_BPP (dest_image->bits.format),
-                     src_x, src_y, dest_x, dest_y, width, height);
+    sse2_blt (imp, src_image->bits.bits,
+	      dest_image->bits.bits,
+	      src_image->bits.rowstride,
+	      dest_image->bits.rowstride,
+	      PIXMAN_FORMAT_BPP (src_image->bits.format),
+	      PIXMAN_FORMAT_BPP (dest_image->bits.format),
+	      src_x, src_y, dest_x, dest_y, width, height);
 }
 
 static void
@@ -5878,35 +5878,6 @@ static const pixman_fast_path_t sse2_fast_paths[] =
     { PIXMAN_OP_NONE },
 };
 
-static pixman_bool_t
-sse2_blt (pixman_implementation_t *imp,
-          uint32_t *               src_bits,
-          uint32_t *               dst_bits,
-          int                      src_stride,
-          int                      dst_stride,
-          int                      src_bpp,
-          int                      dst_bpp,
-          int                      src_x,
-          int                      src_y,
-          int                      dest_x,
-          int                      dest_y,
-          int                      width,
-          int                      height)
-{
-    if (!pixman_blt_sse2 (
-            src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp,
-            src_x, src_y, dest_x, dest_y, width, height))
-
-    {
-	return _pixman_implementation_blt (
-	    imp->delegate,
-	    src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp,
-	    src_x, src_y, dest_x, dest_y, width, height);
-    }
-
-    return TRUE;
-}
-
 #if defined(__GNUC__) && !defined(__x86_64__) && !defined(__amd64__)
 __attribute__((__force_align_arg_pointer__))
 #endif
commit 7ef4436abbdb898dc656ebb5832ed5d6fd764bba
Author: Søren Sandmann Pedersen <ssp at redhat.com>
Date:   Sat Sep 15 12:48:42 2012 -0400

    implementation: Write lookup_combiner() in a less convoluted way.
    
    Instead of initializing an array on the stack, just use a simple
    switch to select which set of combiners to look up in.

diff --git a/pixman/pixman-implementation.c b/pixman/pixman-implementation.c
index 77d0906..d2573ab 100644
--- a/pixman/pixman-implementation.c
+++ b/pixman/pixman-implementation.c
@@ -121,25 +121,36 @@ _pixman_implementation_lookup_combiner (pixman_implementation_t *imp,
 					pixman_bool_t		 component_alpha,
 					pixman_bool_t		 narrow)
 {
-    pixman_combine_32_func_t f;
-
-    do
+    while (imp)
     {
-	pixman_combine_32_func_t (*combiners[]) =
+	pixman_combine_32_func_t f = NULL;
+
+	switch ((narrow << 1) | component_alpha)
 	{
-	    (pixman_combine_32_func_t *)imp->combine_64,
-	    (pixman_combine_32_func_t *)imp->combine_64_ca,
-	    imp->combine_32,
-	    imp->combine_32_ca,
-	};
+	case 0: /* not narrow, not component alpha */
+	    f = (pixman_combine_32_func_t)imp->combine_64[op];
+	    break;
+	    
+	case 1: /* not narrow, component_alpha */
+	    f = (pixman_combine_32_func_t)imp->combine_64_ca[op];
+	    break;
+
+	case 2: /* narrow, not component alpha */
+	    f = imp->combine_32[op];
+	    break;
+
+	case 3: /* narrow, component_alpha */
+	    f = imp->combine_32_ca[op];
+	    break;
+	}
 
-	f = combiners[component_alpha | (narrow << 1)][op];
+	if (f)
+	    return f;
 
 	imp = imp->delegate;
     }
-    while (!f);
 
-    return f;
+    return NULL;
 }
 
 pixman_bool_t


More information about the xorg-commit mailing list