From a9768b035f2c47be0908520474073cc68d225d8a Mon Sep 17 00:00:00 2001
From: marha <marha@users.sourceforge.net>
Date: Tue, 19 Jan 2010 23:10:44 +0000
Subject: Updated to:   libX11-1.3.3   pixman-0.17.4

---
 pixman/COPYING                          |   1 +
 pixman/Makefile.am                      |   2 +-
 pixman/Makefile.in                      |   2 +-
 pixman/configure                        |  26 +-
 pixman/configure.ac                     |   4 +-
 pixman/pixman/pixman-arm-neon-asm.S     | 494 ++++++++++++++++++++++++++++++--
 pixman/pixman/pixman-arm-neon-asm.h     | 153 ++++++++--
 pixman/pixman/pixman-arm-neon.c         | 388 ++++++++++++++++++-------
 pixman/pixman/pixman-arm-simd.c         |  83 +++---
 pixman/pixman/pixman-bits-image.c       |  11 +-
 pixman/pixman/pixman-conical-gradient.c |   2 +-
 pixman/pixman/pixman-image.c            |   3 +
 pixman/pixman/pixman-mmx.c              |  78 +++--
 pixman/pixman/pixman-private.h          |   4 -
 pixman/pixman/pixman-region.c           |  43 ++-
 pixman/pixman/pixman-sse2.c             |   4 +-
 pixman/pixman/pixman-utils.c            |  43 ++-
 pixman/pixman/pixman-version.h          |   4 +-
 pixman/pixman/solaris-hwcap.mapfile     |  36 +--
 pixman/test/Makefile.am                 |  21 +-
 pixman/test/Makefile.in                 | 178 +++++++++---
 pixman/test/alphamap.c                  |  49 ++++
 pixman/test/blitters-test.c             |  59 ++--
 pixman/test/fetch-test.c                | 102 ++++---
 pixman/test/utils.c                     |  14 +
 pixman/test/utils.h                     |   4 +
 26 files changed, 1399 insertions(+), 409 deletions(-)
 create mode 100644 pixman/test/alphamap.c

(limited to 'pixman')

diff --git a/pixman/COPYING b/pixman/COPYING
index 286158f2e..b0571e6a6 100644
--- a/pixman/COPYING
+++ b/pixman/COPYING
@@ -18,6 +18,7 @@ Copyright 2008 Rodrigo Kumpera
 Copyright 2008 André Tupinambá
 Copyright 2008 Mozilla Corporation
 Copyright 2008 Frederic Plourde
+Copyright 2009 Sun Microsystems, Inc.
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
diff --git a/pixman/Makefile.am b/pixman/Makefile.am
index 63b08c1fb..9fd3a375a 100644
--- a/pixman/Makefile.am
+++ b/pixman/Makefile.am
@@ -77,7 +77,7 @@ ensure-prev:
 		false;									\
 	fi
 
-release-check: ensure-prev release-verify-newer release-remove-old distcheck
+release-check: ensure-prev release-verify-newer release-remove-old check distcheck
 
 release-tag:
 	git tag -u $(GPGKEY) -m "$(PACKAGE) $(VERSION) release" $(PACKAGE)-$(VERSION)
diff --git a/pixman/Makefile.in b/pixman/Makefile.in
index 8017fe87d..35109d3b0 100644
--- a/pixman/Makefile.in
+++ b/pixman/Makefile.in
@@ -756,7 +756,7 @@ ensure-prev:
 		false;									\
 	fi
 
-release-check: ensure-prev release-verify-newer release-remove-old distcheck
+release-check: ensure-prev release-verify-newer release-remove-old check distcheck
 
 release-tag:
 	git tag -u $(GPGKEY) -m "$(PACKAGE) $(VERSION) release" $(PACKAGE)-$(VERSION)
diff --git a/pixman/configure b/pixman/configure
index eb6e6c67b..38551e427 100644
--- a/pixman/configure
+++ b/pixman/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.63 for pixman 0.17.2.
+# Generated by GNU Autoconf 2.63 for pixman 0.17.4.
 #
 # Report bugs to <"sandmann@daimi.au.dk">.
 #
@@ -750,8 +750,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
 # Identity of this package.
 PACKAGE_NAME='pixman'
 PACKAGE_TARNAME='pixman'
-PACKAGE_VERSION='0.17.2'
-PACKAGE_STRING='pixman 0.17.2'
+PACKAGE_VERSION='0.17.4'
+PACKAGE_STRING='pixman 0.17.4'
 PACKAGE_BUGREPORT='"sandmann@daimi.au.dk"'
 
 # Factoring default headers for most tests.
@@ -1525,7 +1525,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures pixman 0.17.2 to adapt to many kinds of systems.
+\`configure' configures pixman 0.17.4 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1595,7 +1595,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of pixman 0.17.2:";;
+     short | recursive ) echo "Configuration of pixman 0.17.4:";;
    esac
   cat <<\_ACEOF
 
@@ -1714,7 +1714,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-pixman configure 0.17.2
+pixman configure 0.17.4
 generated by GNU Autoconf 2.63
 
 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1728,7 +1728,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by pixman $as_me 0.17.2, which was
+It was created by pixman $as_me 0.17.4, which was
 generated by GNU Autoconf 2.63.  Invocation command line was
 
   $ $0 $@
@@ -2444,7 +2444,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='pixman'
- VERSION='0.17.2'
+ VERSION='0.17.4'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -21154,13 +21154,13 @@ fi
 
 
 
-LT_VERSION_INFO="17:2:17"
+LT_VERSION_INFO="17:4:17"
 
 PIXMAN_VERSION_MAJOR=0
 
 PIXMAN_VERSION_MINOR=17
 
-PIXMAN_VERSION_MICRO=2
+PIXMAN_VERSION_MICRO=4
 
 
 
@@ -21449,7 +21449,7 @@ cat >conftest.$ac_ext <<_ACEOF
 #include <xmmintrin.h>
 #include <emmintrin.h>
 int main () {
-    __m128i a, b, c;
+    __m128i a = _mm_set1_epi32 (0), b = _mm_set1_epi32 (0), c;
 	c = _mm_xor_si128 (a, b);
     return 0;
 }
@@ -22802,7 +22802,7 @@ exec 6>&1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by pixman $as_me 0.17.2, which was
+This file was extended by pixman $as_me 0.17.4, which was
 generated by GNU Autoconf 2.63.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -22865,7 +22865,7 @@ Report bugs to <bug-autoconf@gnu.org>."
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_version="\\
-pixman config.status 0.17.2
+pixman config.status 0.17.4
 configured by $0, generated by GNU Autoconf 2.63,
   with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
 
diff --git a/pixman/configure.ac b/pixman/configure.ac
index b8d4a59f7..2828648d8 100644
--- a/pixman/configure.ac
+++ b/pixman/configure.ac
@@ -54,7 +54,7 @@ AC_PREREQ([2.57])
 
 m4_define([pixman_major], 0)
 m4_define([pixman_minor], 17)
-m4_define([pixman_micro], 2)
+m4_define([pixman_micro], 4)
 
 m4_define([pixman_version],[pixman_major.pixman_minor.pixman_micro])
 
@@ -253,7 +253,7 @@ AC_COMPILE_IFELSE([
 #include <xmmintrin.h>
 #include <emmintrin.h>
 int main () {
-    __m128i a, b, c;
+    __m128i a = _mm_set1_epi32 (0), b = _mm_set1_epi32 (0), c;
 	c = _mm_xor_si128 (a, b);
     return 0;
 }], have_sse2_intrinsics=yes)
diff --git a/pixman/pixman/pixman-arm-neon-asm.S b/pixman/pixman/pixman-arm-neon-asm.S
index e8ccf77a9..298688442 100644
--- a/pixman/pixman/pixman-arm-neon-asm.S
+++ b/pixman/pixman/pixman-arm-neon-asm.S
@@ -1,24 +1,24 @@
 /*
  * Copyright © 2009 Nokia Corporation
  *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Nokia Corporation not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission.  Nokia Corporation makes no
- * representations about the suitability of this software for any purpose.
- * It is provided "as is" without express or implied warranty.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
  *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
- * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
  *
  * Author:  Siarhei Siamashka (siarhei.siamashka@nokia.com)
  */
@@ -41,6 +41,7 @@
 
     .text
     .fpu neon
+    .arch armv7a
     .altmacro
 
 #include "pixman-arm-neon-asm.h"
@@ -343,6 +344,75 @@ generate_composite_function \
 
 /******************************************************************************/
 
+.macro pixman_composite_over_n_0565_process_pixblock_head
+    /* convert 8 r5g6b5 pixel data from {d4, d5} to planar 8-bit format
+       and put data into d6 - red, d7 - green, d30 - blue */
+    vshrn.u16   d6, q2, #8
+    vshrn.u16   d7, q2, #3
+    vsli.u16    q2, q2, #5
+    vsri.u8     d6, d6, #5
+    vsri.u8     d7, d7, #6
+    vshrn.u16   d30, q2, #2
+    /* now do alpha blending, storing results in 8-bit planar format
+       into d16 - red, d19 - green, d18 - blue */
+    vmull.u8    q10, d3, d6
+    vmull.u8    q11, d3, d7
+    vmull.u8    q12, d3, d30
+    vrshr.u16   q13, q10, #8
+    vrshr.u16   q3, q11, #8
+    vrshr.u16   q15, q12, #8
+    vraddhn.u16 d20, q10, q13
+    vraddhn.u16 d23, q11, q3
+    vraddhn.u16 d22, q12, q15
+.endm
+
+.macro pixman_composite_over_n_0565_process_pixblock_tail
+    /* ... continue alpha blending */
+    vqadd.u8    d16, d2, d20
+    vqadd.u8    q9, q0, q11
+    /* convert the result to r5g6b5 and store it into {d28, d29} */
+    vshll.u8    q14, d16, #8
+    vshll.u8    q8, d19, #8
+    vshll.u8    q9, d18, #8
+    vsri.u16    q14, q8, #5
+    vsri.u16    q14, q9, #11
+.endm
+
+/* TODO: expand macros and do better instructions scheduling */
+.macro pixman_composite_over_n_0565_process_pixblock_tail_head
+    pixman_composite_over_n_0565_process_pixblock_tail
+    vld1.16     {d4, d5}, [DST_R, :128]!
+    vst1.16     {d28, d29}, [DST_W, :128]!
+    pixman_composite_over_n_0565_process_pixblock_head
+.endm
+
+.macro pixman_composite_over_n_0565_init
+    add         DUMMY, sp, #ARGS_STACK_OFFSET
+    vld1.32     {d3[0]}, [DUMMY]
+    vdup.8      d0, d3[0]
+    vdup.8      d1, d3[1]
+    vdup.8      d2, d3[2]
+    vdup.8      d3, d3[3]
+    vmvn.8      d3, d3      /* invert source alpha */
+.endm
+
+generate_composite_function \
+    pixman_composite_over_n_0565_asm_neon, 0, 0, 16, \
+    FLAG_DST_READWRITE, \
+    8, /* number of pixels, processed in a single block */ \
+    5, /* prefetch distance */ \
+    pixman_composite_over_n_0565_init, \
+    default_cleanup, \
+    pixman_composite_over_n_0565_process_pixblock_head, \
+    pixman_composite_over_n_0565_process_pixblock_tail, \
+    pixman_composite_over_n_0565_process_pixblock_tail_head, \
+    28, /* dst_w_basereg */ \
+    4,  /* dst_r_basereg */ \
+    0,  /* src_basereg   */ \
+    24  /* mask_basereg  */
+
+/******************************************************************************/
+
 .macro pixman_composite_src_8888_0565_process_pixblock_head
     vshll.u8    q8, d1, #8
     vshll.u8    q14, d2, #8
@@ -386,6 +456,41 @@ generate_composite_function \
 
 /******************************************************************************/
 
+.macro pixman_composite_src_0565_8888_process_pixblock_head
+    vshrn.u16   d30, q0, #8
+    vshrn.u16   d29, q0, #3
+    vsli.u16    q0, q0, #5
+    vmov.u8     d31, #255
+    vsri.u8     d30, d30, #5
+    vsri.u8     d29, d29, #6
+    vshrn.u16   d28, q0, #2
+.endm
+
+.macro pixman_composite_src_0565_8888_process_pixblock_tail
+.endm
+
+/* TODO: expand macros and do better instructions scheduling */
+.macro pixman_composite_src_0565_8888_process_pixblock_tail_head
+    pixman_composite_src_0565_8888_process_pixblock_tail
+    vst4.8     {d28, d29, d30, d31}, [DST_W, :128]!
+    vld1.16    {d0, d1}, [SRC]!
+    pixman_composite_src_0565_8888_process_pixblock_head
+    cache_preload 8, 8
+.endm
+
+generate_composite_function \
+    pixman_composite_src_0565_8888_asm_neon, 16, 0, 32, \
+    FLAG_DST_WRITEONLY | FLAG_DEINTERLEAVE_32BPP, \
+    8, /* number of pixels, processed in a single block */ \
+    10, /* prefetch distance */ \
+    default_init, \
+    default_cleanup, \
+    pixman_composite_src_0565_8888_process_pixblock_head, \
+    pixman_composite_src_0565_8888_process_pixblock_tail, \
+    pixman_composite_src_0565_8888_process_pixblock_tail_head
+
+/******************************************************************************/
+
 .macro pixman_composite_add_8000_8000_process_pixblock_head
     vqadd.u8    q14, q0, q2
     vqadd.u8    q15, q1, q3
@@ -426,6 +531,48 @@ generate_composite_function \
 
 /******************************************************************************/
 
+.macro pixman_composite_add_8888_8888_process_pixblock_tail_head
+    vld1.8      {d0, d1, d2, d3}, [SRC]!
+                                    PF add PF_X, PF_X, #8
+                                    PF tst PF_CTL, #0xF
+    vld1.8      {d4, d5, d6, d7}, [DST_R, :128]!
+                                    PF addne PF_X, PF_X, #8
+                                    PF subne PF_CTL, PF_CTL, #1
+        vst1.8      {d28, d29, d30, d31}, [DST_W, :128]!
+                                    PF cmp PF_X, ORIG_W
+                                    PF pld, [PF_SRC, PF_X, lsl #src_bpp_shift]
+                                    PF pld, [PF_DST, PF_X, lsl #dst_bpp_shift]
+                                    PF subge PF_X, PF_X, ORIG_W
+                                    PF subges PF_CTL, PF_CTL, #0x10
+    vqadd.u8    q14, q0, q2
+                                    PF ldrgeb DUMMY, [PF_SRC, SRC_STRIDE, lsl #src_bpp_shift]!
+                                    PF ldrgeb DUMMY, [PF_DST, DST_STRIDE, lsl #dst_bpp_shift]!
+    vqadd.u8    q15, q1, q3
+.endm
+
+generate_composite_function \
+    pixman_composite_add_8888_8888_asm_neon, 32, 0, 32, \
+    FLAG_DST_READWRITE, \
+    8, /* number of pixels, processed in a single block */ \
+    10, /* prefetch distance */ \
+    default_init, \
+    default_cleanup, \
+    pixman_composite_add_8000_8000_process_pixblock_head, \
+    pixman_composite_add_8000_8000_process_pixblock_tail, \
+    pixman_composite_add_8888_8888_process_pixblock_tail_head
+
+generate_composite_function_single_scanline \
+    pixman_composite_scanline_add_asm_neon, 32, 0, 32, \
+    FLAG_DST_READWRITE, \
+    8, /* number of pixels, processed in a single block */ \
+    default_init, \
+    default_cleanup, \
+    pixman_composite_add_8000_8000_process_pixblock_head, \
+    pixman_composite_add_8000_8000_process_pixblock_tail, \
+    pixman_composite_add_8888_8888_process_pixblock_tail_head
+
+/******************************************************************************/
+
 .macro pixman_composite_over_8888_8888_process_pixblock_head
     vmvn.8      d24, d3  /* get inverted alpha */
     /* do alpha blending */
@@ -491,6 +638,46 @@ generate_composite_function \
     pixman_composite_over_8888_8888_process_pixblock_tail, \
     pixman_composite_over_8888_8888_process_pixblock_tail_head
 
+generate_composite_function_single_scanline \
+    pixman_composite_scanline_over_asm_neon, 32, 0, 32, \
+    FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \
+    8, /* number of pixels, processed in a single block */ \
+    default_init, \
+    default_cleanup, \
+    pixman_composite_over_8888_8888_process_pixblock_head, \
+    pixman_composite_over_8888_8888_process_pixblock_tail, \
+    pixman_composite_over_8888_8888_process_pixblock_tail_head
+
+/******************************************************************************/
+
+/* TODO: expand macros and do better instructions scheduling */
+.macro pixman_composite_over_n_8888_process_pixblock_tail_head
+    pixman_composite_over_8888_8888_process_pixblock_tail
+    vld4.8      {d4, d5, d6, d7}, [DST_R, :128]!
+    vst4.8      {d28, d29, d30, d31}, [DST_W, :128]!
+    pixman_composite_over_8888_8888_process_pixblock_head
+.endm
+
+.macro pixman_composite_over_n_8888_init
+    add         DUMMY, sp, #ARGS_STACK_OFFSET
+    vld1.32     {d3[0]}, [DUMMY]
+    vdup.8      d0, d3[0]
+    vdup.8      d1, d3[1]
+    vdup.8      d2, d3[2]
+    vdup.8      d3, d3[3]
+.endm
+
+generate_composite_function \
+    pixman_composite_over_n_8888_asm_neon, 0, 0, 32, \
+    FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \
+    8, /* number of pixels, processed in a single block */ \
+    5, /* prefetch distance */ \
+    pixman_composite_over_n_8888_init, \
+    default_cleanup, \
+    pixman_composite_over_8888_8888_process_pixblock_head, \
+    pixman_composite_over_8888_8888_process_pixblock_tail, \
+    pixman_composite_over_n_8888_process_pixblock_tail_head
+
 /******************************************************************************/
 
 .macro pixman_composite_over_n_8_0565_process_pixblock_head
@@ -950,6 +1137,63 @@ generate_composite_function \
 
 /******************************************************************************/
 
+.macro pixman_composite_add_8888_8888_8888_process_pixblock_head
+    /* expecting source data in {d0, d1, d2, d3} */
+    /* destination data in {d4, d5, d6, d7} */
+    /* mask in {d24, d25, d26, d27} */
+    vmull.u8    q8, d27, d0
+    vmull.u8    q9, d27, d1
+    vmull.u8    q10, d27, d2
+    vmull.u8    q11, d27, d3
+    vrshr.u16   q0, q8, #8
+    vrshr.u16   q1, q9, #8
+    vrshr.u16   q12, q10, #8
+    vrshr.u16   q13, q11, #8
+    vraddhn.u16 d0, q0, q8
+    vraddhn.u16 d1, q1, q9
+    vraddhn.u16 d2, q12, q10
+    vraddhn.u16 d3, q13, q11
+    vqadd.u8    q14, q0, q2
+    vqadd.u8    q15, q1, q3
+.endm
+
+.macro pixman_composite_add_8888_8888_8888_process_pixblock_tail
+.endm
+
+/* TODO: expand macros and do better instructions scheduling */
+.macro pixman_composite_add_8888_8888_8888_process_pixblock_tail_head
+    pixman_composite_add_8888_8888_8888_process_pixblock_tail
+    vst4.8      {d28, d29, d30, d31}, [DST_W, :128]!
+    vld4.8      {d4, d5, d6, d7}, [DST_R, :128]!
+    vld4.8      {d24, d25, d26, d27}, [MASK]!
+    vld4.8      {d0, d1, d2, d3}, [SRC]!
+    cache_preload 8, 8
+    pixman_composite_add_8888_8888_8888_process_pixblock_head
+.endm
+
+generate_composite_function \
+    pixman_composite_add_8888_8888_8888_asm_neon, 32, 32, 32, \
+    FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \
+    8, /* number of pixels, processed in a single block */ \
+    10, /* prefetch distance */ \
+    default_init, \
+    default_cleanup, \
+    pixman_composite_add_8888_8888_8888_process_pixblock_head, \
+    pixman_composite_add_8888_8888_8888_process_pixblock_tail, \
+    pixman_composite_add_8888_8888_8888_process_pixblock_tail_head
+
+generate_composite_function_single_scanline \
+    pixman_composite_scanline_add_mask_asm_neon, 32, 32, 32, \
+    FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \
+    8, /* number of pixels, processed in a single block */ \
+    default_init, \
+    default_cleanup, \
+    pixman_composite_add_8888_8888_8888_process_pixblock_head, \
+    pixman_composite_add_8888_8888_8888_process_pixblock_tail, \
+    pixman_composite_add_8888_8888_8888_process_pixblock_tail_head
+
+/******************************************************************************/
+
 .macro pixman_composite_over_8888_n_8888_process_pixblock_head
     /* expecting source data in {d0, d1, d2, d3} */
     /* destination data in {d4, d5, d6, d7} */
@@ -1023,6 +1267,92 @@ generate_composite_function \
 
 /******************************************************************************/
 
+/* TODO: expand macros and do better instructions scheduling */
+.macro pixman_composite_over_8888_8888_8888_process_pixblock_tail_head
+    vld4.8     {d4, d5, d6, d7}, [DST_R, :128]!
+    pixman_composite_over_8888_n_8888_process_pixblock_tail
+    vld4.8     {d0, d1, d2, d3}, [SRC]!
+    cache_preload 8, 8
+    vld4.8     {d12, d13, d14, d15}, [MASK]!
+    pixman_composite_over_8888_n_8888_process_pixblock_head
+    vst4.8     {d28, d29, d30, d31}, [DST_W, :128]!
+.endm
+
+.macro pixman_composite_over_8888_8888_8888_init
+    vpush       {d8-d15}
+.endm
+
+.macro pixman_composite_over_8888_8888_8888_cleanup
+    vpop        {d8-d15}
+.endm
+
+generate_composite_function \
+    pixman_composite_over_8888_8888_8888_asm_neon, 32, 32, 32, \
+    FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \
+    8, /* number of pixels, processed in a single block */ \
+    5, /* prefetch distance */ \
+    pixman_composite_over_8888_8888_8888_init, \
+    pixman_composite_over_8888_8888_8888_cleanup, \
+    pixman_composite_over_8888_n_8888_process_pixblock_head, \
+    pixman_composite_over_8888_n_8888_process_pixblock_tail, \
+    pixman_composite_over_8888_8888_8888_process_pixblock_tail_head \
+    28, /* dst_w_basereg */ \
+    4,  /* dst_r_basereg */ \
+    0,  /* src_basereg   */ \
+    12  /* mask_basereg  */
+
+generate_composite_function_single_scanline \
+    pixman_composite_scanline_over_mask_asm_neon, 32, 32, 32, \
+    FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \
+    8, /* number of pixels, processed in a single block */ \
+    pixman_composite_over_8888_8888_8888_init, \
+    pixman_composite_over_8888_8888_8888_cleanup, \
+    pixman_composite_over_8888_n_8888_process_pixblock_head, \
+    pixman_composite_over_8888_n_8888_process_pixblock_tail, \
+    pixman_composite_over_8888_8888_8888_process_pixblock_tail_head \
+    28, /* dst_w_basereg */ \
+    4,  /* dst_r_basereg */ \
+    0,  /* src_basereg   */ \
+    12  /* mask_basereg  */
+
+/******************************************************************************/
+
+/* TODO: expand macros and do better instructions scheduling */
+.macro pixman_composite_over_8888_8_8888_process_pixblock_tail_head
+    vld4.8     {d4, d5, d6, d7}, [DST_R, :128]!
+    pixman_composite_over_8888_n_8888_process_pixblock_tail
+    vld4.8     {d0, d1, d2, d3}, [SRC]!
+    cache_preload 8, 8
+    vld1.8     {d15}, [MASK]!
+    pixman_composite_over_8888_n_8888_process_pixblock_head
+    vst4.8     {d28, d29, d30, d31}, [DST_W, :128]!
+.endm
+
+.macro pixman_composite_over_8888_8_8888_init
+    vpush       {d8-d15}
+.endm
+
+.macro pixman_composite_over_8888_8_8888_cleanup
+    vpop        {d8-d15}
+.endm
+
+generate_composite_function \
+    pixman_composite_over_8888_8_8888_asm_neon, 32, 8, 32, \
+    FLAG_DST_READWRITE | FLAG_DEINTERLEAVE_32BPP, \
+    8, /* number of pixels, processed in a single block */ \
+    5, /* prefetch distance */ \
+    pixman_composite_over_8888_8_8888_init, \
+    pixman_composite_over_8888_8_8888_cleanup, \
+    pixman_composite_over_8888_n_8888_process_pixblock_head, \
+    pixman_composite_over_8888_n_8888_process_pixblock_tail, \
+    pixman_composite_over_8888_8_8888_process_pixblock_tail_head \
+    28, /* dst_w_basereg */ \
+    4,  /* dst_r_basereg */ \
+    0,  /* src_basereg   */ \
+    15  /* mask_basereg  */
+
+/******************************************************************************/
+
 .macro pixman_composite_src_0888_0888_process_pixblock_head
 .endm
 
@@ -1049,3 +1379,133 @@ generate_composite_function \
     0, /* dst_r_basereg */ \
     0, /* src_basereg   */ \
     0  /* mask_basereg  */
+
+/******************************************************************************/
+
+.macro pixman_composite_src_0888_8888_rev_process_pixblock_head
+    vswp   d0, d2
+.endm
+
+.macro pixman_composite_src_0888_8888_rev_process_pixblock_tail
+.endm
+
+.macro pixman_composite_src_0888_8888_rev_process_pixblock_tail_head
+    vst4.8 {d0, d1, d2, d3}, [DST_W]!
+    vld3.8 {d0, d1, d2}, [SRC]!
+    vswp   d0, d2
+    cache_preload 8, 8
+.endm
+
+.macro pixman_composite_src_0888_8888_rev_init
+    veor   d3, d3, d3
+.endm
+
+generate_composite_function \
+    pixman_composite_src_0888_8888_rev_asm_neon, 24, 0, 32, \
+    FLAG_DST_WRITEONLY | FLAG_DEINTERLEAVE_32BPP, \
+    8, /* number of pixels, processed in a single block */ \
+    10, /* prefetch distance */ \
+    pixman_composite_src_0888_8888_rev_init, \
+    default_cleanup, \
+    pixman_composite_src_0888_8888_rev_process_pixblock_head, \
+    pixman_composite_src_0888_8888_rev_process_pixblock_tail, \
+    pixman_composite_src_0888_8888_rev_process_pixblock_tail_head, \
+    0, /* dst_w_basereg */ \
+    0, /* dst_r_basereg */ \
+    0, /* src_basereg   */ \
+    0  /* mask_basereg  */
+
+/******************************************************************************/
+
+.macro pixman_composite_src_0888_0565_rev_process_pixblock_head
+    vshll.u8    q8, d1, #8
+    vshll.u8    q9, d2, #8
+.endm
+
+.macro pixman_composite_src_0888_0565_rev_process_pixblock_tail
+    vshll.u8    q14, d0, #8
+    vsri.u16    q14, q8, #5
+    vsri.u16    q14, q9, #11
+.endm
+
+.macro pixman_composite_src_0888_0565_rev_process_pixblock_tail_head
+        vshll.u8    q14, d0, #8
+    vld3.8 {d0, d1, d2}, [SRC]!
+        vsri.u16    q14, q8, #5
+        vsri.u16    q14, q9, #11
+    vshll.u8    q8, d1, #8
+        vst1.16 {d28, d29}, [DST_W, :128]!
+    vshll.u8    q9, d2, #8
+.endm
+
+generate_composite_function \
+    pixman_composite_src_0888_0565_rev_asm_neon, 24, 0, 16, \
+    FLAG_DST_WRITEONLY, \
+    8, /* number of pixels, processed in a single block */ \
+    10, /* prefetch distance */ \
+    default_init, \
+    default_cleanup, \
+    pixman_composite_src_0888_0565_rev_process_pixblock_head, \
+    pixman_composite_src_0888_0565_rev_process_pixblock_tail, \
+    pixman_composite_src_0888_0565_rev_process_pixblock_tail_head, \
+    28, /* dst_w_basereg */ \
+    0, /* dst_r_basereg */ \
+    0, /* src_basereg   */ \
+    0  /* mask_basereg  */
+
+/******************************************************************************/
+
+.macro pixman_composite_src_pixbuf_8888_process_pixblock_head
+    vmull.u8    q8, d3, d0
+    vmull.u8    q9, d3, d1
+    vmull.u8    q10, d3, d2
+.endm
+
+.macro pixman_composite_src_pixbuf_8888_process_pixblock_tail
+    vrshr.u16   q11, q8, #8
+    vswp        d3, d31
+    vrshr.u16   q12, q9, #8
+    vrshr.u16   q13, q10, #8
+    vraddhn.u16 d30, q11, q8
+    vraddhn.u16 d29, q12, q9
+    vraddhn.u16 d28, q13, q10
+.endm
+
+.macro pixman_composite_src_pixbuf_8888_process_pixblock_tail_head
+        vrshr.u16   q11, q8, #8
+        vswp        d3, d31
+        vrshr.u16   q12, q9, #8
+        vrshr.u16   q13, q10, #8
+    vld4.8 {d0, d1, d2, d3}, [SRC]!
+        vraddhn.u16 d30, q11, q8
+                                    PF add PF_X, PF_X, #8
+                                    PF tst PF_CTL, #0xF
+                                    PF addne PF_X, PF_X, #8
+                                    PF subne PF_CTL, PF_CTL, #1
+        vraddhn.u16 d29, q12, q9
+        vraddhn.u16 d28, q13, q10
+    vmull.u8    q8, d3, d0
+    vmull.u8    q9, d3, d1
+    vmull.u8    q10, d3, d2
+        vst4.8 {d28, d29, d30, d31}, [DST_W, :128]!
+                                    PF cmp PF_X, ORIG_W
+                                    PF pld, [PF_SRC, PF_X, lsl #src_bpp_shift]
+                                    PF subge PF_X, PF_X, ORIG_W
+                                    PF subges PF_CTL, PF_CTL, #0x10
+                                    PF ldrgeb DUMMY, [PF_SRC, SRC_STRIDE, lsl #src_bpp_shift]!
+.endm
+
+generate_composite_function \
+    pixman_composite_src_pixbuf_8888_asm_neon, 32, 0, 32, \
+    FLAG_DST_WRITEONLY | FLAG_DEINTERLEAVE_32BPP, \
+    8, /* number of pixels, processed in a single block */ \
+    10, /* prefetch distance */ \
+    default_init, \
+    default_cleanup, \
+    pixman_composite_src_pixbuf_8888_process_pixblock_head, \
+    pixman_composite_src_pixbuf_8888_process_pixblock_tail, \
+    pixman_composite_src_pixbuf_8888_process_pixblock_tail_head, \
+    28, /* dst_w_basereg */ \
+    0, /* dst_r_basereg */ \
+    0, /* src_basereg   */ \
+    0  /* mask_basereg  */
diff --git a/pixman/pixman/pixman-arm-neon-asm.h b/pixman/pixman/pixman-arm-neon-asm.h
index e7be5cddf..56c3faebf 100644
--- a/pixman/pixman/pixman-arm-neon-asm.h
+++ b/pixman/pixman/pixman-arm-neon-asm.h
@@ -1,24 +1,24 @@
 /*
  * Copyright © 2009 Nokia Corporation
  *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Nokia Corporation not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission.  Nokia Corporation makes no
- * representations about the suitability of this software for any purpose.
- * It is provided "as is" without express or implied warranty.
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
  *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
- * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
  *
  * Author:  Siarhei Siamashka (siarhei.siamashka@nokia.com)
  */
@@ -780,6 +780,125 @@ fname:
     .endfunc
 .endm
 
+/*
+ * A simplified variant of function generation template for a single
+ * scanline processing (for implementing pixman combine functions)
+ */
+.macro generate_composite_function_single_scanline fname, \
+                                                   src_bpp_, \
+                                                   mask_bpp_, \
+                                                   dst_w_bpp_, \
+                                                   flags, \
+                                                   pixblock_size_, \
+                                                   init, \
+                                                   cleanup, \
+                                                   process_pixblock_head, \
+                                                   process_pixblock_tail, \
+                                                   process_pixblock_tail_head, \
+                                                   dst_w_basereg_ = 28, \
+                                                   dst_r_basereg_ = 4, \
+                                                   src_basereg_   = 0, \
+                                                   mask_basereg_  = 24
+
+    .func fname
+    .global fname
+    /* For ELF format also set function visibility to hidden */
+#ifdef __ELF__
+    .hidden fname
+    .type fname, %function
+#endif
+fname:
+    .set PREFETCH_TYPE_CURRENT, PREFETCH_TYPE_NONE
+/*
+ * Make some macro arguments globally visible and accessible
+ * from other macros
+ */
+    .set src_bpp, src_bpp_
+    .set mask_bpp, mask_bpp_
+    .set dst_w_bpp, dst_w_bpp_
+    .set pixblock_size, pixblock_size_
+    .set dst_w_basereg, dst_w_basereg_
+    .set dst_r_basereg, dst_r_basereg_
+    .set src_basereg, src_basereg_
+    .set mask_basereg, mask_basereg_
+/*
+ * Assign symbolic names to registers
+ */
+    W           .req        r0      /* width (is updated during processing) */
+    DST_W       .req        r1      /* destination buffer pointer for writes */
+    SRC         .req        r2      /* source buffer pointer */
+    DST_R       .req        ip      /* destination buffer pointer for reads */
+    MASK        .req        r3      /* mask pointer */
+
+.if (((flags) & FLAG_DST_READWRITE) != 0)
+    .set dst_r_bpp, dst_w_bpp
+.else
+    .set dst_r_bpp, 0
+.endif
+.if (((flags) & FLAG_DEINTERLEAVE_32BPP) != 0)
+    .set DEINTERLEAVE_32BPP_ENABLED, 1
+.else
+    .set DEINTERLEAVE_32BPP_ENABLED, 0
+.endif
+
+    init
+    mov         DST_R, DST_W
+
+    cmp         W, #pixblock_size
+    blt         8f
+
+    ensure_destination_ptr_alignment process_pixblock_head, \
+                                     process_pixblock_tail, \
+                                     process_pixblock_tail_head
+
+    subs        W, W, #pixblock_size
+    blt         7f
+
+    /* Implement "head (tail_head) ... (tail_head) tail" loop pattern */
+    pixld_a     pixblock_size, dst_r_bpp, \
+                (dst_r_basereg - pixblock_size * dst_r_bpp / 64), DST_R
+    pixld       pixblock_size, src_bpp, \
+                (src_basereg - pixblock_size * src_bpp / 64), SRC
+    pixld       pixblock_size, mask_bpp, \
+                (mask_basereg - pixblock_size * mask_bpp / 64), MASK
+    process_pixblock_head
+    subs        W, W, #pixblock_size
+    blt         2f
+1:
+    process_pixblock_tail_head
+    subs        W, W, #pixblock_size
+    bge         1b
+2:
+    process_pixblock_tail
+    pixst_a     pixblock_size, dst_w_bpp, \
+                (dst_w_basereg - pixblock_size * dst_w_bpp / 64), DST_W
+7:
+    /* Process the remaining trailing pixels in the scanline (dst aligned) */
+    process_trailing_pixels 0, 1, \
+                            process_pixblock_head, \
+                            process_pixblock_tail, \
+                            process_pixblock_tail_head
+
+    cleanup
+    bx         lr  /* exit */
+8:
+    /* Process the remaining trailing pixels in the scanline (dst unaligned) */
+    process_trailing_pixels 0, 0, \
+                            process_pixblock_head, \
+                            process_pixblock_tail, \
+                            process_pixblock_tail_head
+
+    cleanup
+    bx          lr  /* exit */
+
+    .unreq      SRC
+    .unreq      MASK
+    .unreq      DST_R
+    .unreq      DST_W
+    .unreq      W
+    .endfunc
+.endm
+
 .macro default_init
 .endm
 
diff --git a/pixman/pixman/pixman-arm-neon.c b/pixman/pixman/pixman-arm-neon.c
index 2ed8b4bdf..efeabebd5 100644
--- a/pixman/pixman/pixman-arm-neon.c
+++ b/pixman/pixman/pixman-arm-neon.c
@@ -35,27 +35,27 @@
 
 #define BIND_SRC_NULL_DST(name, src_type, src_cnt, dst_type, dst_cnt)   \
 void                                                                    \
-pixman_##name##_asm_neon (int32_t   w,                                  \
-                          int32_t   h,                                  \
-                          dst_type *dst,                                \
-                          int32_t   dst_stride,                         \
-                          src_type *src,                                \
-                          int32_t   src_stride);                        \
+pixman_composite_##name##_asm_neon (int32_t   w,                        \
+                                    int32_t   h,                        \
+                                    dst_type *dst,                      \
+                                    int32_t   dst_stride,               \
+                                    src_type *src,                      \
+                                    int32_t   src_stride);              \
                                                                         \
 static void                                                             \
-neon_##name (pixman_implementation_t *imp,                              \
-             pixman_op_t              op,                               \
-             pixman_image_t *         src_image,                        \
-             pixman_image_t *         mask_image,                       \
-             pixman_image_t *         dst_image,                        \
-             int32_t                  src_x,                            \
-             int32_t                  src_y,                            \
-             int32_t                  mask_x,                           \
-             int32_t                  mask_y,                           \
-             int32_t                  dest_x,                           \
-             int32_t                  dest_y,                           \
-             int32_t                  width,                            \
-             int32_t                  height)                           \
+neon_composite_##name (pixman_implementation_t *imp,                    \
+                       pixman_op_t              op,                     \
+                       pixman_image_t *         src_image,              \
+                       pixman_image_t *         mask_image,             \
+                       pixman_image_t *         dst_image,              \
+                       int32_t                  src_x,                  \
+                       int32_t                  src_y,                  \
+                       int32_t                  mask_x,                 \
+                       int32_t                  mask_y,                 \
+                       int32_t                  dest_x,                 \
+                       int32_t                  dest_y,                 \
+                       int32_t                  width,                  \
+                       int32_t                  height)                 \
 {                                                                       \
     dst_type *dst_line;                                                 \
     src_type *src_line;                                                 \
@@ -66,36 +66,76 @@ neon_##name (pixman_implementation_t *imp,                              \
     PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, dst_type,         \
                            dst_stride, dst_line, dst_cnt);              \
                                                                         \
-    pixman_##name##_asm_neon (width, height,                            \
-                              dst_line, dst_stride,                     \
-                              src_line, src_stride);                    \
+    pixman_composite_##name##_asm_neon (width, height,                  \
+                                        dst_line, dst_stride,           \
+                                        src_line, src_stride);          \
+}
+
+#define BIND_N_NULL_DST(name, dst_type, dst_cnt)                        \
+void                                                                    \
+pixman_composite_##name##_asm_neon (int32_t    w,                       \
+                                    int32_t    h,                       \
+                                    dst_type  *dst,                     \
+                                    int32_t    dst_stride,              \
+                                    uint32_t   src);                    \
+                                                                        \
+static void                                                             \
+neon_composite_##name (pixman_implementation_t *imp,                    \
+                       pixman_op_t              op,                     \
+                       pixman_image_t *         src_image,              \
+                       pixman_image_t *         mask_image,             \
+                       pixman_image_t *         dst_image,              \
+                       int32_t                  src_x,                  \
+                       int32_t                  src_y,                  \
+                       int32_t                  mask_x,                 \
+                       int32_t                  mask_y,                 \
+                       int32_t                  dest_x,                 \
+                       int32_t                  dest_y,                 \
+                       int32_t                  width,                  \
+                       int32_t                  height)                 \
+{                                                                       \
+    dst_type  *dst_line;                                                \
+    int32_t    dst_stride;                                              \
+    uint32_t   src;                                                     \
+                                                                        \
+    src = _pixman_image_get_solid (src_image, dst_image->bits.format);  \
+                                                                        \
+    if (src == 0)                                                       \
+	return;                                                         \
+                                                                        \
+    PIXMAN_IMAGE_GET_LINE (dst_image, dest_x, dest_y, dst_type,         \
+                           dst_stride, dst_line, dst_cnt);              \
+                                                                        \
+    pixman_composite_##name##_asm_neon (width, height,                  \
+                                        dst_line, dst_stride,           \
+                                        src);                           \
 }
 
 #define BIND_N_MASK_DST(name, mask_type, mask_cnt, dst_type, dst_cnt)   \
 void                                                                    \
-pixman_##name##_asm_neon (int32_t    w,                                 \
-                          int32_t    h,                                 \
-                          dst_type  *dst,                               \
-                          int32_t    dst_stride,                        \
-                          uint32_t   src,                               \
-                          int32_t    unused,                            \
-                          mask_type *mask,                              \
-                          int32_t    mask_stride);                      \
+pixman_composite_##name##_asm_neon (int32_t    w,                       \
+                                    int32_t    h,                       \
+                                    dst_type  *dst,                     \
+                                    int32_t    dst_stride,              \
+                                    uint32_t   src,                     \
+                                    int32_t    unused,                  \
+                                    mask_type *mask,                    \
+                                    int32_t    mask_stride);            \
                                                                         \
 static void                                                             \
-neon_##name (pixman_implementation_t *imp,                              \
-             pixman_op_t              op,                               \
-             pixman_image_t *         src_image,                        \
-             pixman_image_t *         mask_image,                       \
-             pixman_image_t *         dst_image,                        \
-             int32_t                  src_x,                            \
-             int32_t                  src_y,                            \
-             int32_t                  mask_x,                           \
-             int32_t                  mask_y,                           \
-             int32_t                  dest_x,                           \
-             int32_t                  dest_y,                           \
-             int32_t                  width,                            \
-             int32_t                  height)                           \
+neon_composite_##name (pixman_implementation_t *imp,                    \
+                       pixman_op_t              op,                     \
+                       pixman_image_t *         src_image,              \
+                       pixman_image_t *         mask_image,             \
+                       pixman_image_t *         dst_image,              \
+                       int32_t                  src_x,                  \
+                       int32_t                  src_y,                  \
+                       int32_t                  mask_x,                 \
+                       int32_t                  mask_y,                 \
+                       int32_t                  dest_x,                 \
+                       int32_t                  dest_y,                 \
+                       int32_t                  width,                  \
+                       int32_t                  height)                 \
 {                                                                       \
     dst_type  *dst_line;                                                \
     mask_type *mask_line;                                               \
@@ -112,36 +152,36 @@ neon_##name (pixman_implementation_t *imp,                              \
     PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, mask_type,       \
                            mask_stride, mask_line, mask_cnt);           \
                                                                         \
-    pixman_##name##_asm_neon (width, height,                            \
-                              dst_line, dst_stride,                     \
-                              src, 0,                                   \
-                              mask_line, mask_stride);                  \
+    pixman_composite_##name##_asm_neon (width, height,                  \
+                                        dst_line, dst_stride,           \
+                                        src, 0,                         \
+                                        mask_line, mask_stride);        \
 }
 
 #define BIND_SRC_N_DST(name, src_type, src_cnt, dst_type, dst_cnt)      \
 void                                                                    \
-pixman_##name##_asm_neon (int32_t    w,                                 \
-                          int32_t    h,                                 \
-                          dst_type  *dst,                               \
-                          int32_t    dst_stride,                        \
-                          src_type  *src,                               \
-                          int32_t    src_stride,                        \
-                          uint32_t   mask);                             \
+pixman_composite_##name##_asm_neon (int32_t    w,                       \
+                                    int32_t    h,                       \
+                                    dst_type  *dst,                     \
+                                    int32_t    dst_stride,              \
+                                    src_type  *src,                     \
+                                    int32_t    src_stride,              \
+                                    uint32_t   mask);                   \
                                                                         \
 static void                                                             \
-neon_##name (pixman_implementation_t *imp,                              \
-             pixman_op_t              op,                               \
-             pixman_image_t *         src_image,                        \
-             pixman_image_t *         mask_image,                       \
-             pixman_image_t *         dst_image,                        \
-             int32_t                  src_x,                            \
-             int32_t                  src_y,                            \
-             int32_t                  mask_x,                           \
-             int32_t                  mask_y,                           \
-             int32_t                  dest_x,                           \
-             int32_t                  dest_y,                           \
-             int32_t                  width,                            \
-             int32_t                  height)                           \
+neon_composite_##name (pixman_implementation_t *imp,                    \
+                       pixman_op_t              op,                     \
+                       pixman_image_t *         src_image,              \
+                       pixman_image_t *         mask_image,             \
+                       pixman_image_t *         dst_image,              \
+                       int32_t                  src_x,                  \
+                       int32_t                  src_y,                  \
+                       int32_t                  mask_x,                 \
+                       int32_t                  mask_y,                 \
+                       int32_t                  dest_x,                 \
+                       int32_t                  dest_y,                 \
+                       int32_t                  width,                  \
+                       int32_t                  height)                 \
 {                                                                       \
     dst_type  *dst_line;                                                \
     src_type  *src_line;                                                \
@@ -158,38 +198,38 @@ neon_##name (pixman_implementation_t *imp,                              \
     PIXMAN_IMAGE_GET_LINE (src_image, src_x, src_y, src_type,           \
                            src_stride, src_line, src_cnt);              \
                                                                         \
-    pixman_##name##_asm_neon (width, height,                            \
-                              dst_line, dst_stride,                     \
-                              src_line, src_stride,                     \
-                              mask);                                    \
+    pixman_composite_##name##_asm_neon (width, height,                  \
+                                        dst_line, dst_stride,           \
+                                        src_line, src_stride,           \
+                                        mask);                          \
 }
 
 #define BIND_SRC_MASK_DST(name, src_type, src_cnt, mask_type, mask_cnt, \
                           dst_type, dst_cnt)                            \
 void                                                                    \
-pixman_##name##_asm_neon (int32_t    w,                                 \
-                          int32_t    h,                                 \
-                          dst_type  *dst,                               \
-                          int32_t    dst_stride,                        \
-                          src_type  *src,                               \
-                          int32_t    src_stride,                        \
-                          mask_type *mask,                              \
-                          int32_t    mask_stride);                      \
+pixman_composite_##name##_asm_neon (int32_t    w,                       \
+                                    int32_t    h,                       \
+                                    dst_type  *dst,                     \
+                                    int32_t    dst_stride,              \
+                                    src_type  *src,                     \
+                                    int32_t    src_stride,              \
+                                    mask_type *mask,                    \
+                                    int32_t    mask_stride);            \
                                                                         \
 static void                                                             \
-neon_##name (pixman_implementation_t *imp,                              \
-             pixman_op_t              op,                               \
-             pixman_image_t *         src_image,                        \
-             pixman_image_t *         mask_image,                       \
-             pixman_image_t *         dst_image,                        \
-             int32_t                  src_x,                            \
-             int32_t                  src_y,                            \
-             int32_t                  mask_x,                           \
-             int32_t                  mask_y,                           \
-             int32_t                  dest_x,                           \
-             int32_t                  dest_y,                           \
-             int32_t                  width,                            \
-             int32_t                  height)                           \
+neon_composite_##name (pixman_implementation_t *imp,                    \
+                       pixman_op_t              op,                     \
+                       pixman_image_t *         src_image,              \
+                       pixman_image_t *         mask_image,             \
+                       pixman_image_t *         dst_image,              \
+                       int32_t                  src_x,                  \
+                       int32_t                  src_y,                  \
+                       int32_t                  mask_x,                 \
+                       int32_t                  mask_y,                 \
+                       int32_t                  dest_x,                 \
+                       int32_t                  dest_y,                 \
+                       int32_t                  width,                  \
+                       int32_t                  height)                 \
 {                                                                       \
     dst_type  *dst_line;                                                \
     src_type  *src_line;                                                \
@@ -203,29 +243,40 @@ neon_##name (pixman_implementation_t *imp,                              \
     PIXMAN_IMAGE_GET_LINE (mask_image, mask_x, mask_y, mask_type,       \
                            mask_stride, mask_line, mask_cnt);           \
                                                                         \
-    pixman_##name##_asm_neon (width, height,                            \
-                              dst_line, dst_stride,                     \
-                              src_line, src_stride,                     \
-                              mask_line, mask_stride);                  \
+    pixman_composite_##name##_asm_neon (width, height,                  \
+                                        dst_line, dst_stride,           \
+                                        src_line, src_stride,           \
+                                        mask_line, mask_stride);        \
 }
 
 
-BIND_SRC_NULL_DST(composite_src_8888_8888, uint32_t, 1, uint32_t, 1)
-BIND_SRC_NULL_DST(composite_src_0565_0565, uint16_t, 1, uint16_t, 1)
-BIND_SRC_NULL_DST(composite_src_0888_0888, uint8_t, 3, uint8_t, 3)
-BIND_SRC_NULL_DST(composite_src_8888_0565, uint32_t, 1, uint16_t, 1)
-BIND_SRC_NULL_DST(composite_add_8000_8000, uint8_t, 1, uint8_t, 1)
+BIND_SRC_NULL_DST(src_8888_8888, uint32_t, 1, uint32_t, 1)
+BIND_SRC_NULL_DST(src_0565_0565, uint16_t, 1, uint16_t, 1)
+BIND_SRC_NULL_DST(src_0888_0888, uint8_t, 3, uint8_t, 3)
+BIND_SRC_NULL_DST(src_8888_0565, uint32_t, 1, uint16_t, 1)
+BIND_SRC_NULL_DST(src_0565_8888, uint16_t, 1, uint32_t, 1)
+BIND_SRC_NULL_DST(src_0888_8888_rev, uint8_t, 3, uint32_t, 1)
+BIND_SRC_NULL_DST(src_0888_0565_rev, uint8_t, 3, uint16_t, 1)
+BIND_SRC_NULL_DST(src_pixbuf_8888, uint32_t, 1, uint32_t, 1)
+BIND_SRC_NULL_DST(add_8000_8000, uint8_t, 1, uint8_t, 1)
+BIND_SRC_NULL_DST(add_8888_8888, uint32_t, 1, uint32_t, 1)
 
-BIND_SRC_NULL_DST(composite_over_8888_0565, uint32_t, 1, uint16_t, 1)
-BIND_SRC_NULL_DST(composite_over_8888_8888, uint32_t, 1, uint32_t, 1)
+BIND_N_NULL_DST(over_n_0565, uint16_t, 1)
+BIND_N_NULL_DST(over_n_8888, uint32_t, 1)
 
-BIND_N_MASK_DST(composite_over_n_8_0565, uint8_t, 1, uint16_t, 1)
-BIND_N_MASK_DST(composite_over_n_8_8888, uint8_t, 1, uint32_t, 1)
-BIND_N_MASK_DST(composite_add_n_8_8, uint8_t, 1, uint8_t, 1)
+BIND_SRC_NULL_DST(over_8888_0565, uint32_t, 1, uint16_t, 1)
+BIND_SRC_NULL_DST(over_8888_8888, uint32_t, 1, uint32_t, 1)
 
-BIND_SRC_N_DST(composite_over_8888_n_8888, uint32_t, 1, uint32_t, 1)
+BIND_N_MASK_DST(over_n_8_0565, uint8_t, 1, uint16_t, 1)
+BIND_N_MASK_DST(over_n_8_8888, uint8_t, 1, uint32_t, 1)
+BIND_N_MASK_DST(add_n_8_8, uint8_t, 1, uint8_t, 1)
 
-BIND_SRC_MASK_DST(composite_add_8_8_8, uint8_t, 1, uint8_t, 1, uint8_t, 1)
+BIND_SRC_N_DST(over_8888_n_8888, uint32_t, 1, uint32_t, 1)
+
+BIND_SRC_MASK_DST(add_8_8_8, uint8_t, 1, uint8_t, 1, uint8_t, 1)
+BIND_SRC_MASK_DST(add_8888_8888_8888, uint32_t, 1, uint32_t, 1, uint32_t, 1)
+BIND_SRC_MASK_DST(over_8888_8_8888, uint32_t, 1, uint8_t, 1, uint32_t, 1)
+BIND_SRC_MASK_DST(over_8888_8888_8888, uint32_t, 1, uint32_t, 1, uint32_t, 1)
 
 void
 pixman_composite_src_n_8_asm_neon (int32_t   w,
@@ -292,6 +343,46 @@ 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       dst_x,
+                 int       dst_y,
+                 int       width,
+                 int       height)
+{
+    if (src_bpp != dst_bpp)
+	return FALSE;
+
+    switch (src_bpp)
+    {
+    case 16:
+	pixman_composite_src_0565_0565_asm_neon (
+		width, height,
+		(uint16_t *)(((char *) dst_bits) +
+		dst_y * dst_stride * 4 + dst_x * 2), dst_stride * 2,
+		(uint16_t *)(((char *) src_bits) +
+		src_y * src_stride * 4 + src_x * 2), src_stride * 2);
+	return TRUE;
+    case 32:
+	pixman_composite_src_8888_8888_asm_neon (
+		width, height,
+		(uint32_t *)(((char *) dst_bits) +
+		dst_y * dst_stride * 4 + dst_x * 4), dst_stride,
+		(uint32_t *)(((char *) src_bits) +
+		src_y * src_stride * 4 + src_x * 4), src_stride);
+	return TRUE;
+    default:
+	return FALSE;
+    }
+}
+
 static const pixman_fast_path_t arm_neon_fast_path_array[] =
 {
     { PIXMAN_OP_SRC,  PIXMAN_r5g6b5,   PIXMAN_null,     PIXMAN_r5g6b5,   neon_composite_src_0565_0565    },
@@ -300,19 +391,34 @@ static const pixman_fast_path_t arm_neon_fast_path_array[] =
     { PIXMAN_OP_SRC,  PIXMAN_x8r8g8b8, PIXMAN_null,     PIXMAN_r5g6b5,   neon_composite_src_8888_0565    },
     { PIXMAN_OP_SRC,  PIXMAN_a8b8g8r8, PIXMAN_null,     PIXMAN_b5g6r5,   neon_composite_src_8888_0565    },
     { PIXMAN_OP_SRC,  PIXMAN_x8b8g8r8, PIXMAN_null,     PIXMAN_b5g6r5,   neon_composite_src_8888_0565    },
+    { PIXMAN_OP_SRC,  PIXMAN_r5g6b5,   PIXMAN_null,     PIXMAN_a8r8g8b8, neon_composite_src_0565_8888    },
+    { PIXMAN_OP_SRC,  PIXMAN_r5g6b5,   PIXMAN_null,     PIXMAN_x8r8g8b8, neon_composite_src_0565_8888    },
+    { PIXMAN_OP_SRC,  PIXMAN_b5g6r5,   PIXMAN_null,     PIXMAN_a8b8g8r8, neon_composite_src_0565_8888    },
+    { PIXMAN_OP_SRC,  PIXMAN_b5g6r5,   PIXMAN_null,     PIXMAN_x8b8g8r8, neon_composite_src_0565_8888    },
     { PIXMAN_OP_SRC,  PIXMAN_a8r8g8b8, PIXMAN_null,     PIXMAN_x8r8g8b8, neon_composite_src_8888_8888    },
     { PIXMAN_OP_SRC,  PIXMAN_x8r8g8b8, PIXMAN_null,     PIXMAN_x8r8g8b8, neon_composite_src_8888_8888    },
     { PIXMAN_OP_SRC,  PIXMAN_a8b8g8r8, PIXMAN_null,     PIXMAN_x8b8g8r8, neon_composite_src_8888_8888    },
     { PIXMAN_OP_SRC,  PIXMAN_x8b8g8r8, PIXMAN_null,     PIXMAN_x8b8g8r8, neon_composite_src_8888_8888    },
     { PIXMAN_OP_SRC,  PIXMAN_r8g8b8,   PIXMAN_null,     PIXMAN_r8g8b8,   neon_composite_src_0888_0888    },
+    { PIXMAN_OP_SRC,  PIXMAN_b8g8r8,   PIXMAN_null,     PIXMAN_x8r8g8b8, neon_composite_src_0888_8888_rev },
+    { PIXMAN_OP_SRC,  PIXMAN_b8g8r8,   PIXMAN_null,     PIXMAN_r5g6b5,   neon_composite_src_0888_0565_rev },
+    { PIXMAN_OP_SRC,  PIXMAN_pixbuf,   PIXMAN_pixbuf,   PIXMAN_a8r8g8b8, neon_composite_src_pixbuf_8888  },
     { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_r5g6b5,   neon_composite_over_n_8_0565    },
     { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_b5g6r5,   neon_composite_over_n_8_0565    },
     { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_a8r8g8b8, neon_composite_over_n_8_8888    },
     { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_x8r8g8b8, neon_composite_over_n_8_8888    },
     { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_a8b8g8r8, neon_composite_over_n_8_8888    },
     { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_x8b8g8r8, neon_composite_over_n_8_8888    },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_null,     PIXMAN_r5g6b5,   neon_composite_over_n_0565      },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_null,     PIXMAN_a8r8g8b8, neon_composite_over_n_8888      },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_null,     PIXMAN_x8r8g8b8, neon_composite_over_n_8888      },
     { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_solid,    PIXMAN_a8r8g8b8, neon_composite_over_8888_n_8888 },
     { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_solid,    PIXMAN_x8r8g8b8, neon_composite_over_8888_n_8888 },
+    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_a8,       PIXMAN_a8r8g8b8, neon_composite_over_8888_8_8888 },
+    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_a8,       PIXMAN_x8r8g8b8, neon_composite_over_8888_8_8888 },
+    { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_a8,       PIXMAN_a8b8g8r8, neon_composite_over_8888_8_8888 },
+    { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_a8,       PIXMAN_x8b8g8r8, neon_composite_over_8888_8_8888 },
+    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_a8r8g8b8, PIXMAN_a8r8g8b8, neon_composite_over_8888_8888_8888 },
     { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null,     PIXMAN_r5g6b5,   neon_composite_over_8888_0565   },
     { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null,     PIXMAN_b5g6r5,   neon_composite_over_8888_0565   },
     { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null,     PIXMAN_a8r8g8b8, neon_composite_over_8888_8888   },
@@ -321,7 +427,10 @@ static const pixman_fast_path_t arm_neon_fast_path_array[] =
     { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null,     PIXMAN_x8b8g8r8, neon_composite_over_8888_8888   },
     { PIXMAN_OP_ADD,  PIXMAN_solid,    PIXMAN_a8,       PIXMAN_a8,       neon_composite_add_n_8_8        },
     { PIXMAN_OP_ADD,  PIXMAN_a8,       PIXMAN_a8,       PIXMAN_a8,       neon_composite_add_8_8_8        },
+    { PIXMAN_OP_ADD,  PIXMAN_a8r8g8b8, PIXMAN_a8r8g8b8, PIXMAN_a8r8g8b8, neon_composite_add_8888_8888_8888 },
     { PIXMAN_OP_ADD,  PIXMAN_a8,       PIXMAN_null,     PIXMAN_a8,       neon_composite_add_8000_8000    },
+    { PIXMAN_OP_ADD,  PIXMAN_a8r8g8b8, PIXMAN_null,     PIXMAN_a8r8g8b8, neon_composite_add_8888_8888    },
+    { PIXMAN_OP_ADD,  PIXMAN_a8b8g8r8, PIXMAN_null,     PIXMAN_a8b8g8r8, neon_composite_add_8888_8888    },
     { PIXMAN_OP_NONE },
 };
 
@@ -360,6 +469,35 @@ arm_neon_composite (pixman_implementation_t *imp,
                                       width, height);
 }
 
+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                      dst_x,
+              int                      dst_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, dst_x, dst_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, dst_x, dst_y, width, height);
+    }
+
+    return TRUE;
+}
+
 static pixman_bool_t
 arm_neon_fill (pixman_implementation_t *imp,
                uint32_t *               bits,
@@ -378,13 +516,47 @@ arm_neon_fill (pixman_implementation_t *imp,
 	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,     \
+                                                  const uint32_t *dst,   \
+                                                  const uint32_t *src,   \
+                                                  const uint32_t *mask); \
+                                                                         \
+void                                                                     \
+pixman_composite_scanline_##name##_asm_neon (int32_t         w,          \
+                                             const uint32_t *dst,        \
+                                             const uint32_t *src);       \
+                                                                         \
+static void                                                              \
+neon_combine_##name##_u (pixman_implementation_t *imp,                   \
+                         pixman_op_t              op,                    \
+                         uint32_t *               dest,                  \
+                         const uint32_t *         src,                   \
+                         const uint32_t *         mask,                  \
+                         int                      width)                 \
+{                                                                        \
+    if (mask)                                                            \
+	pixman_composite_scanline_##name##_mask_asm_neon (width, dest,   \
+	                                                  src, mask);    \
+    else                                                                 \
+	pixman_composite_scanline_##name##_asm_neon (width, dest, src);  \
+}
+
+BIND_COMBINE_U (over)
+BIND_COMBINE_U (add)
+
 pixman_implementation_t *
 _pixman_implementation_create_arm_neon (void)
 {
     pixman_implementation_t *general = _pixman_implementation_create_fast_path ();
     pixman_implementation_t *imp = _pixman_implementation_create (general);
 
+    imp->combine_32[PIXMAN_OP_OVER] = neon_combine_over_u;
+    imp->combine_32[PIXMAN_OP_ADD] = neon_combine_add_u;
+
     imp->composite = arm_neon_composite;
+    imp->blt = arm_neon_blt;
     imp->fill = arm_neon_fill;
 
     return imp;
diff --git a/pixman/pixman/pixman-arm-simd.c b/pixman/pixman/pixman-arm-simd.c
index 265c820b4..479524690 100644
--- a/pixman/pixman/pixman-arm-simd.c
+++ b/pixman/pixman/pixman-arm-simd.c
@@ -31,18 +31,18 @@
 
 static void
 arm_composite_add_8000_8000 (pixman_implementation_t * impl,
-    pixman_op_t               op,
-    pixman_image_t *          src_image,
-    pixman_image_t *          mask_image,
-    pixman_image_t *          dst_image,
-    int32_t                   src_x,
-    int32_t                   src_y,
-    int32_t                   mask_x,
-    int32_t                   mask_y,
-    int32_t                   dest_x,
-    int32_t                   dest_y,
-    int32_t                   width,
-    int32_t                   height)
+			     pixman_op_t               op,
+			     pixman_image_t *          src_image,
+			     pixman_image_t *          mask_image,
+			     pixman_image_t *          dst_image,
+			     int32_t                   src_x,
+			     int32_t                   src_y,
+			     int32_t                   mask_x,
+			     int32_t                   mask_y,
+			     int32_t                   dest_x,
+			     int32_t                   dest_y,
+			     int32_t                   width,
+			     int32_t                   height)
 {
     uint8_t     *dst_line, *dst;
     uint8_t     *src_line, *src;
@@ -103,18 +103,18 @@ arm_composite_add_8000_8000 (pixman_implementation_t * impl,
 
 static void
 arm_composite_over_8888_8888 (pixman_implementation_t * impl,
-    pixman_op_t               op,
-    pixman_image_t *          src_image,
-    pixman_image_t *          mask_image,
-    pixman_image_t *          dst_image,
-    int32_t                   src_x,
-    int32_t                   src_y,
-    int32_t                   mask_x,
-    int32_t                   mask_y,
-    int32_t                   dest_x,
-    int32_t                   dest_y,
-    int32_t                   width,
-    int32_t                   height)
+			      pixman_op_t               op,
+			      pixman_image_t *          src_image,
+			      pixman_image_t *          mask_image,
+			      pixman_image_t *          dst_image,
+			      int32_t                   src_x,
+			      int32_t                   src_y,
+			      int32_t                   mask_x,
+			      int32_t                   mask_y,
+			      int32_t                   dest_x,
+			      int32_t                   dest_y,
+			      int32_t                   width,
+			      int32_t                   height)
 {
     uint32_t    *dst_line, *dst;
     uint32_t    *src_line, *src;
@@ -188,27 +188,26 @@ arm_composite_over_8888_8888 (pixman_implementation_t * impl,
 	    "2:\n\t"
 	    : [w] "+r" (w), [dest] "+r" (dst), [src] "+r" (src)
 	    : [component_half] "r" (component_half), [upper_component_mask] "r" (upper_component_mask),
-	    [alpha_mask] "r" (alpha_mask)
+	      [alpha_mask] "r" (alpha_mask)
 	    : "r4", "r5", "r6", "r7", "r8", "cc", "memory"
 	    );
     }
 }
 
 static void
-arm_composite_over_8888_n_8888 (
-    pixman_implementation_t * impl,
-    pixman_op_t               op,
-    pixman_image_t *          src_image,
-    pixman_image_t *          mask_image,
-    pixman_image_t *          dst_image,
-    int32_t                   src_x,
-    int32_t                   src_y,
-    int32_t                   mask_x,
-    int32_t                   mask_y,
-    int32_t                   dest_x,
-    int32_t                   dest_y,
-    int32_t                   width,
-    int32_t                   height)
+arm_composite_over_8888_n_8888 (pixman_implementation_t * impl,
+				pixman_op_t               op,
+				pixman_image_t *          src_image,
+				pixman_image_t *          mask_image,
+				pixman_image_t *          dst_image,
+				int32_t                   src_x,
+				int32_t                   src_y,
+				int32_t                   mask_x,
+				int32_t                   mask_y,
+				int32_t                   dest_x,
+				int32_t                   dest_y,
+				int32_t                   width,
+				int32_t                   height)
 {
     uint32_t *dst_line, *dst;
     uint32_t *src_line, *src;
@@ -298,7 +297,7 @@ arm_composite_over_8888_n_8888 (
 	    "2:\n\t"
 	    : [w] "+r" (w), [dest] "+r" (dst), [src] "+r" (src)
 	    : [component_half] "r" (component_half), [mask_alpha] "r" (mask),
-	    [alpha_mask] "r" (alpha_mask)
+	      [alpha_mask] "r" (alpha_mask)
 	    : "r4", "r5", "r6", "r7", "r8", "r9", "cc", "memory"
 	    );
     }
@@ -384,7 +383,8 @@ arm_composite_over_n_8_8888 (pixman_implementation_t * impl,
 	    "uxtb16 r7, r4, ror #8\n\t"
 
 	    /* we could simplify this to use 'sub' if we were
-	    * willing to give up a register for alpha_mask */
+	     * willing to give up a register for alpha_mask
+	     */
 	    "mvn r8, r5\n\t"
 	    "mov r8, r8, lsr #24\n\t"
 
@@ -483,4 +483,3 @@ _pixman_implementation_create_arm_simd (void)
 
     return imp;
 }
-
diff --git a/pixman/pixman/pixman-bits-image.c b/pixman/pixman/pixman-bits-image.c
index 5a5a69057..23a379633 100644
--- a/pixman/pixman/pixman-bits-image.c
+++ b/pixman/pixman/pixman-bits-image.c
@@ -115,12 +115,13 @@ bits_image_fetch_pixel_alpha (bits_image_t *image, int x, int y)
     }
     else
     {
-	pixel_a = image->fetch_pixel_raw_32 (
+	pixel_a = image->common.alpha_map->fetch_pixel_raw_32 (
 	    image->common.alpha_map, x, y);
 	pixel_a = ALPHA_8 (pixel_a);
     }
 
-    UN8x4_MUL_UN8 (pixel, pixel_a);
+    pixel &= 0x00ffffff;
+    pixel |= (pixel_a << 24);
 
     return pixel;
 }
@@ -1043,6 +1044,12 @@ pixman_image_create_bits (pixman_format_code_t format,
     return_val_if_fail (bits == NULL ||
                         (rowstride_bytes % sizeof (uint32_t)) == 0, NULL);
 
+    if (PIXMAN_FORMAT_BPP (format) < PIXMAN_FORMAT_DEPTH (format))
+    {
+	fprintf (stderr, "Bad format passed to pixman_image_create_bits();\n");
+	return NULL;
+    }
+
     if (!bits && width && height)
     {
 	free_me = bits = create_bits (format, width, height, &rowstride_bytes);
diff --git a/pixman/pixman/pixman-conical-gradient.c b/pixman/pixman/pixman-conical-gradient.c
index d720db3d4..369a7a58f 100644
--- a/pixman/pixman/pixman-conical-gradient.c
+++ b/pixman/pixman/pixman-conical-gradient.c
@@ -49,7 +49,7 @@ conical_gradient_get_scanline_32 (pixman_image_t *image,
     double rx = x + 0.5;
     double ry = y + 0.5;
     double rz = 1.;
-    double a = conical->angle / (180. * 65536);
+    double a = (conical->angle * M_PI) / (180. * 65536);
 
     _pixman_gradient_walker_init (&walker, gradient, source->common.repeat);
 
diff --git a/pixman/pixman/pixman-image.c b/pixman/pixman/pixman-image.c
index e55ba2c15..1619165ab 100644
--- a/pixman/pixman/pixman-image.c
+++ b/pixman/pixman/pixman-image.c
@@ -245,6 +245,9 @@ _pixman_image_validate (pixman_image_t *image)
 	image->common.property_changed (image);
 	image->common.dirty = FALSE;
     }
+
+    if (image->common.alpha_map)
+	_pixman_image_validate (image->common.alpha_map);
 }
 
 PIXMAN_EXPORT pixman_bool_t
diff --git a/pixman/pixman/pixman-mmx.c b/pixman/pixman/pixman-mmx.c
index 819e3a0e3..b1591d967 100644
--- a/pixman/pixman/pixman-mmx.c
+++ b/pixman/pixman/pixman-mmx.c
@@ -485,7 +485,7 @@ mmx_combine_over_reverse_u (pixman_implementation_t *imp,
     {
 	__m64 d, da;
 	uint32_t s = combine (src, mask);
-	
+
 	d = load8888 (*dest);
 	da = expand_alpha (d);
 	*dest = store8888 (over (d, da, load8888 (s)));
@@ -511,12 +511,12 @@ mmx_combine_in_u (pixman_implementation_t *imp,
     while (dest < end)
     {
 	__m64 x, a;
-	
+
 	x = load8888 (combine (src, mask));
 	a = load8888 (*dest);
 	a = expand_alpha (a);
 	x = pix_multiply (x, a);
-	
+
 	*dest = store8888 (x);
 
 	++dest;
@@ -540,7 +540,7 @@ mmx_combine_in_reverse_u (pixman_implementation_t *imp,
     while (dest < end)
     {
 	__m64 x, a;
-	
+
 	x = load8888 (*dest);
 	a = load8888 (combine (src, mask));
 	a = expand_alpha (a);
@@ -568,7 +568,7 @@ mmx_combine_out_u (pixman_implementation_t *imp,
     while (dest < end)
     {
 	__m64 x, a;
-	
+
 	x = load8888 (combine (src, mask));
 	a = load8888 (*dest);
 	a = expand_alpha (a);
@@ -597,7 +597,7 @@ mmx_combine_out_reverse_u (pixman_implementation_t *imp,
     while (dest < end)
     {
 	__m64 x, a;
-	
+
 	x = load8888 (*dest);
 	a = load8888 (combine (src, mask));
 	a = expand_alpha (a);
@@ -627,7 +627,7 @@ mmx_combine_atop_u (pixman_implementation_t *imp,
     while (dest < end)
     {
 	__m64 s, da, d, sia;
-	
+
 	s = load8888 (combine (src, mask));
 	d = load8888 (*dest);
 	sia = expand_alpha (s);
@@ -659,7 +659,7 @@ mmx_combine_atop_reverse_u (pixman_implementation_t *imp,
     while (dest < end)
     {
 	__m64 s, dia, d, sa;
-	
+
 	s = load8888 (combine (src, mask));
 	d = load8888 (*dest);
 	sa = expand_alpha (s);
@@ -689,7 +689,7 @@ mmx_combine_xor_u (pixman_implementation_t *imp,
     while (dest < end)
     {
 	__m64 s, dia, d, sia;
-	
+
 	s = load8888 (combine (src, mask));
 	d = load8888 (*dest);
 	sia = expand_alpha (s);
@@ -720,7 +720,7 @@ mmx_combine_add_u (pixman_implementation_t *imp,
     while (dest < end)
     {
 	__m64 s, d;
-	
+
 	s = load8888 (combine (src, mask));
 	d = load8888 (*dest);
 	s = pix_add (s, d);
@@ -785,7 +785,7 @@ mmx_combine_src_ca (pixman_implementation_t *imp,
     {
 	__m64 a = load8888 (*mask);
 	__m64 s = load8888 (*src);
-	
+
 	s = pix_multiply (s, a);
 	*dest = store8888 (s);
 
@@ -864,7 +864,7 @@ mmx_combine_in_ca (pixman_implementation_t *imp,
 	__m64 s = load8888 (*src);
 	__m64 d = load8888 (*dest);
 	__m64 da = expand_alpha (d);
-	
+
 	s = pix_multiply (s, a);
 	s = pix_multiply (s, da);
 	*dest = store8888 (s);
@@ -892,7 +892,7 @@ mmx_combine_in_reverse_ca (pixman_implementation_t *imp,
 	__m64 s = load8888 (*src);
 	__m64 d = load8888 (*dest);
 	__m64 sa = expand_alpha (s);
-	
+
 	a = pix_multiply (a, sa);
 	d = pix_multiply (d, a);
 	*dest = store8888 (d);
@@ -920,7 +920,7 @@ mmx_combine_out_ca (pixman_implementation_t *imp,
 	__m64 s = load8888 (*src);
 	__m64 d = load8888 (*dest);
 	__m64 da = expand_alpha (d);
-	
+
 	da = negate (da);
 	s = pix_multiply (s, a);
 	s = pix_multiply (s, da);
@@ -1209,7 +1209,7 @@ mmx_composite_over_n_0565 (pixman_implementation_t *imp,
 	{
 	    uint64_t d = *dst;
 	    __m64 vdest = expand565 (M64 (d), 0);
-	    
+
 	    vdest = pack_565 (over (vsrc, vsrca, vdest), vdest, 0);
 	    *dst = UINT64 (vdest);
 
@@ -1240,7 +1240,7 @@ mmx_composite_over_n_0565 (pixman_implementation_t *imp,
 	{
 	    uint64_t d = *dst;
 	    __m64 vdest = expand565 (M64 (d), 0);
-	    
+
 	    vdest = pack_565 (over (vsrc, vsrca, vdest), vdest, 0);
 	    *dst = UINT64 (vdest);
 
@@ -1615,7 +1615,7 @@ mmx_composite_over_8888_8888 (pixman_implementation_t *imp,
 	{
 	    s = *src++;
 	    a = s >> 24;
-	    
+
 	    if (a == 0xff)
 	    {
 		*dst = s;
@@ -1627,7 +1627,7 @@ mmx_composite_over_8888_8888 (pixman_implementation_t *imp,
 		sa = expand_alpha (ms);
 		*dst = store8888 (over (ms, sa, load8888 (*dst)));
 	    }
-	    
+
 	    dst++;
 	}
     }
@@ -1795,7 +1795,7 @@ mmx_composite_over_n_8_8888 (pixman_implementation_t *imp,
 		__m64 vdest = in_over (vsrc, vsrca,
 				       expand_alpha_rev (M64 (m)),
 				       load8888 (*dst));
-		
+
 		*dst = store8888 (vdest);
 	    }
 
@@ -1809,7 +1809,7 @@ mmx_composite_over_n_8_8888 (pixman_implementation_t *imp,
 	while (w >= 2)
 	{
 	    uint64_t m0, m1;
-	    
+
 	    m0 = *mask;
 	    m1 = *(mask + 1);
 
@@ -1883,22 +1883,13 @@ pixman_fill_mmx (uint32_t *bits,
     if (bpp != 16 && bpp != 32 && bpp != 8)
 	return FALSE;
 
-    if (bpp == 16 && (xor >> 16 != (xor & 0xffff)))
-	return FALSE;
-
-    if (bpp == 8 &&
-        ((xor >> 16 != (xor & 0xffff)) ||
-         (xor >> 24 != (xor & 0x00ff) >> 16)))
-    {
-	return FALSE;
-    }
-
     if (bpp == 8)
     {
 	stride = stride * (int) sizeof (uint32_t) / 1;
 	byte_line = (uint8_t *)(((uint8_t *)bits) + stride * y + x);
 	byte_width = width;
 	stride *= 1;
+        xor = (xor & 0xff) * 0x01010101;
     }
     else if (bpp == 16)
     {
@@ -1906,6 +1897,7 @@ pixman_fill_mmx (uint32_t *bits,
 	byte_line = (uint8_t *)(((uint16_t *)bits) + stride * y + x);
 	byte_width = 2 * width;
 	stride *= 2;
+        xor = (xor & 0xffff) * 0x00010001;
     }
     else
     {
@@ -1928,7 +1920,7 @@ pixman_fill_mmx (uint32_t *bits,
         "movq		%7,	%5\n"
         "movq		%7,	%6\n"
 	: "=y" (v1), "=y" (v2), "=y" (v3),
-        "=y" (v4), "=y" (v5), "=y" (v6), "=y" (v7)
+	  "=y" (v4), "=y" (v5), "=y" (v6), "=y" (v7)
 	: "y" (vfill));
 #endif
 
@@ -1936,7 +1928,7 @@ pixman_fill_mmx (uint32_t *bits,
     {
 	int w;
 	uint8_t *d = byte_line;
-	
+
 	byte_line += stride;
 	w = byte_width;
 
@@ -1976,8 +1968,8 @@ pixman_fill_mmx (uint32_t *bits,
 	        "movq	%8,	56(%0)\n"
 		:
 		: "r" (d),
-	        "y" (vfill), "y" (v1), "y" (v2), "y" (v3),
-	        "y" (v4), "y" (v5), "y" (v6), "y" (v7)
+		  "y" (vfill), "y" (v1), "y" (v2), "y" (v3),
+		  "y" (v4), "y" (v5), "y" (v6), "y" (v7)
 		: "memory");
 #else
 	    *(__m64*) (d +  0) = vfill;
@@ -2080,7 +2072,7 @@ mmx_composite_src_n_8_8888 (pixman_implementation_t *imp,
 	    if (m)
 	    {
 		__m64 vdest = in (vsrc, expand_alpha_rev (M64 (m)));
-		
+
 		*dst = store8888 (vdest);
 	    }
 	    else
@@ -2136,7 +2128,7 @@ mmx_composite_src_n_8_8888 (pixman_implementation_t *imp,
 	    if (m)
 	    {
 		__m64 vdest = load8888 (*dst);
-		
+
 		vdest = in (vsrc, expand_alpha_rev (M64 (m)));
 		*dst = store8888 (vdest);
 	    }
@@ -2218,7 +2210,7 @@ mmx_composite_over_n_8_0565 (pixman_implementation_t *imp,
 		__m64 vd = M64 (d);
 		__m64 vdest = in_over (
 		    vsrc, vsrca, expand_alpha_rev (M64 (m)), expand565 (vd, 0));
-		
+
 		vd = pack_565 (vdest, _mm_setzero_si64 (), 0);
 		*dst = UINT64 (vd);
 	    }
@@ -3082,8 +3074,8 @@ pixman_blt_mmx (uint32_t *src_bits,
 		:
 		: "r" (d), "r" (s)
 		: "memory",
-	        "%mm0", "%mm1", "%mm2", "%mm3",
-	        "%mm4", "%mm5", "%mm6", "%mm7");
+		  "%mm0", "%mm1", "%mm2", "%mm3",
+		  "%mm4", "%mm5", "%mm6", "%mm7");
 #else
 	    __m64 v0 = *(__m64 *)(s + 0);
 	    __m64 v1 = *(__m64 *)(s + 8);
@@ -3346,9 +3338,9 @@ mmx_blt (pixman_implementation_t *imp,
 
     {
 	return _pixman_implementation_blt (
-	           imp->delegate,
-	           src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp,
-	           src_x, src_y, dst_x, dst_y, width, height);
+	    imp->delegate,
+	    src_bits, dst_bits, src_stride, dst_stride, src_bpp, dst_bpp,
+	    src_x, src_y, dst_x, dst_y, width, height);
     }
 
     return TRUE;
@@ -3368,7 +3360,7 @@ mmx_fill (pixman_implementation_t *imp,
     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);
+	    imp->delegate, bits, stride, bpp, x, y, width, height, xor);
     }
 
     return TRUE;
diff --git a/pixman/pixman/pixman-private.h b/pixman/pixman/pixman-private.h
index 5000f910d..c99f2a23c 100644
--- a/pixman/pixman/pixman-private.h
+++ b/pixman/pixman/pixman-private.h
@@ -254,10 +254,6 @@ _pixman_image_store_scanline_32 (bits_image_t *  image,
                                  int             y,
                                  int             width,
                                  const uint32_t *buffer);
-void
-_pixman_image_fetch_pixels (bits_image_t *image,
-                            uint32_t *    buffer,
-                            int           n_pixels);
 
 /* Even though the type of buffer is uint32_t *, the function
  * actually expects a uint64_t *buffer.
diff --git a/pixman/pixman/pixman-region.c b/pixman/pixman/pixman-region.c
index f88955f3b..8ce5deb77 100644
--- a/pixman/pixman/pixman-region.c
+++ b/pixman/pixman/pixman-region.c
@@ -66,9 +66,44 @@
 #define GOOD_RECT(rect) ((rect)->x1 < (rect)->x2 && (rect)->y1 < (rect)->y2)
 #define BAD_RECT(rect) ((rect)->x1 > (rect)->x2 || (rect)->y1 > (rect)->y2)
 
-#define noPIXMAN_REGION_LOG_FAILURES
+/* Turn on debugging depending on what type of release this is
+ */
 
-#if defined PIXMAN_REGION_LOG_FAILURES || defined PIXMAN_REGION_DEBUG
+#if ((PIXMAN_VERSION_MICRO % 2) == 1)
+/* Random git checkout.
+ * 
+ * Those are often used for performance work, so we don't turn on the
+ * full self-checking, but we do turn on the asserts.
+ */
+#    define   FATAL_BUGS
+#    define noSELF_CHECKS
+#elif ((PIXMAN_VERSION_MINOR % 2) == 0)
+/* Stable release.
+ *
+ * We don't want assertions because the X server should stay alive
+ * if possible. We also don't want self-checks for performance-reasons.
+ */
+#    define noFATAL_BUGS
+#    define noSELF_CHECKS
+#else
+/* Development snapshot.
+ *
+ * These are the things that get shipped in development distributions
+ * such as Rawhide. We want both self-checking and fatal assertions
+ * to catch as many bugs as possible.
+ */
+#    define FATAL_BUGS
+#    define SELF_CHECKS
+#endif
+
+#ifndef FATAL_BUGS
+#    undef assert
+#    undef abort
+#    define assert(expr)
+#    define abort()
+#endif
+
+#ifdef SELF_CHECKS
 
 static void
 log_region_error (const char *function, const char *message)
@@ -83,9 +118,7 @@ log_region_error (const char *function, const char *message)
 		 "Set a breakpoint on 'log_region_error' to debug\n\n",
                  function, message);
 
-#if defined PIXMAN_REGION_DEBUG
-        abort ();
-#endif
+        abort (); /* This is #defined away unless FATAL_BUGS is defined */
 
 	n_messages++;
     }
diff --git a/pixman/pixman/pixman-sse2.c b/pixman/pixman/pixman-sse2.c
index 78b0ad185..1f8aa6e38 100644
--- a/pixman/pixman/pixman-sse2.c
+++ b/pixman/pixman/pixman-sse2.c
@@ -3981,9 +3981,6 @@ pixman_fill_sse2 (uint32_t *bits,
 
     __m128i xmm_def;
 
-    if (bpp == 16 && (data >> 16 != (data & 0xffff)))
-	return FALSE;
-
     if (bpp != 16 && bpp != 32)
 	return FALSE;
 
@@ -3993,6 +3990,7 @@ pixman_fill_sse2 (uint32_t *bits,
 	byte_line = (uint8_t *)(((uint16_t *)bits) + stride * y + x);
 	byte_width = 2 * width;
 	stride *= 2;
+        data = (data & 0xffff) * 0x00010001;
     }
     else
     {
diff --git a/pixman/pixman/pixman-utils.c b/pixman/pixman/pixman-utils.c
index 6d03f3c07..a80a226fa 100644
--- a/pixman/pixman/pixman-utils.c
+++ b/pixman/pixman/pixman-utils.c
@@ -509,7 +509,7 @@ get_fast_path (const pixman_fast_path_t *fast_paths,
 	       int			 mask_x,
 	       int			 mask_y)
 {
-    pixman_format_code_t src_format, mask_format;
+    pixman_format_code_t src_format, mask_format, dest_format;
     const pixman_fast_path_t *info;
 
     /* Check for pixbufs */
@@ -528,6 +528,7 @@ get_fast_path (const pixman_fast_path_t *fast_paths,
     }
     else
     {
+	/* Source */
 	if (_pixman_image_is_solid (src_image))
 	{
 	    src_format = PIXMAN_solid;
@@ -540,7 +541,8 @@ get_fast_path (const pixman_fast_path_t *fast_paths,
 	{
 	    return NULL;
 	}
-	
+
+	/* Mask */
 	if (!mask_image)
 	{
 	    mask_format = PIXMAN_null;
@@ -577,21 +579,18 @@ get_fast_path (const pixman_fast_path_t *fast_paths,
 	    return NULL;
 	}
     }
+
+    dest_format = dst_image->bits.format;
     
-    for (info = fast_paths; info->op != PIXMAN_OP_NONE; info++)
+    for (info = fast_paths; info->op != PIXMAN_OP_NONE; ++info)
     {
-	if (info->op != op)
-	    continue;
-
-	if (info->src_format != src_format)
-	    continue;
-	if (info->mask_format != mask_format)
-	    continue;
-
-	if (info->dest_format != dst_image->bits.format)
-	    continue;
-
-	return info;
+	if (info->op == op			&&
+	    info->src_format == src_format	&&
+	    info->mask_format == mask_format	&&
+	    info->dest_format == dest_format)
+	{
+	    return info;
+	}
     }
 
     return NULL;
@@ -708,22 +707,20 @@ _pixman_run_fast_path (const pixman_fast_path_t *paths,
 		src_repeat = FALSE;
 
 	    if (info->mask_format == PIXMAN_solid)
-	    {
 		mask_repeat = FALSE;
-	    }
 
 	    if ((src_repeat                     &&
-	         src->bits.width == 1           &&
-	         src->bits.height == 1) ||
-	        (mask_repeat                    &&
-	         mask->bits.width == 1          &&
-	         mask->bits.height == 1))
+		 src->bits.width == 1           &&
+		 src->bits.height == 1)		||
+		(mask_repeat			&&
+		 mask->bits.width == 1		&&
+		 mask->bits.height == 1))
 	    {
 		/* If src or mask are repeating 1x1 images and src_repeat or
 		 * mask_repeat are still TRUE, it means the fast path we
 		 * selected does not actually handle repeating images.
 		 *
-		 * So rather than call the "fast path" with a zillion
+		 * So rather than calling the "fast path" with a zillion
 		 * 1x1 requests, we just fall back to the general code (which
 		 * does do something sensible with 1x1 repeating images).
 		 */
diff --git a/pixman/pixman/pixman-version.h b/pixman/pixman/pixman-version.h
index 6b93790e1..dbd175ca4 100644
--- a/pixman/pixman/pixman-version.h
+++ b/pixman/pixman/pixman-version.h
@@ -33,9 +33,9 @@
 
 #define PIXMAN_VERSION_MAJOR 0
 #define PIXMAN_VERSION_MINOR 17
-#define PIXMAN_VERSION_MICRO 2
+#define PIXMAN_VERSION_MICRO 4
 
-#define PIXMAN_VERSION_STRING "0.17.2"
+#define PIXMAN_VERSION_STRING "0.17.4"
 
 #define PIXMAN_VERSION_ENCODE(major, minor, micro) (	\
 	  ((major) * 10000)				\
diff --git a/pixman/pixman/solaris-hwcap.mapfile b/pixman/pixman/solaris-hwcap.mapfile
index 7f439a95a..3605ca79f 100644
--- a/pixman/pixman/solaris-hwcap.mapfile
+++ b/pixman/pixman/solaris-hwcap.mapfile
@@ -3,29 +3,23 @@
 # Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 #
 # Permission is hereby granted, free of charge, to any person obtaining a
-# copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, and/or sell copies of the Software, and to permit persons
-# to whom the Software is furnished to do so, provided that the above
-# copyright notice(s) and this permission notice appear in all copies of
-# the Software and that both the above copyright notice(s) and this
-# permission notice appear in supporting documentation.
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
 #
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
-# OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
-# HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
-# INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
-# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
-# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
-# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
 #
-# Except as contained in this notice, the name of a copyright holder
-# shall not be used in advertising or otherwise to promote the sale, use
-# or other dealings in this Software without prior written authorization
-# of the copyright holder.
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
 #
 ###############################################################################
 #
diff --git a/pixman/test/Makefile.am b/pixman/test/Makefile.am
index 89d32e96f..5f6ba13ac 100644
--- a/pixman/test/Makefile.am
+++ b/pixman/test/Makefile.am
@@ -3,13 +3,14 @@ INCLUDES = -I$(top_srcdir)/pixman -I$(top_builddir)/pixman
 
 TESTPROGRAMS =			\
 	region-test		\
-	scaling-test		\
-	blitters-test		\
-	composite		\
 	fetch-test		\
 	oob-test		\
 	window-test		\
-	trap-crasher
+	trap-crasher		\
+	alphamap		\
+	blitters-test		\
+	scaling-test		\
+	composite
 
 fetch_test_LDADD = $(TEST_LDADD)
 region_test_LDADD = $(TEST_LDADD)
@@ -24,6 +25,9 @@ blitters_test_SOURCES = blitters-test.c utils.c utils.h
 scaling_test_LDADD = $(TEST_LDADD)
 scaling_test_SOURCES = scaling-test.c utils.c utils.h
 
+alphamap_LDADD = $(TEST_LDADD)
+alphamap_SOURCES = alphamap.c utils.c utils.h
+
 # GTK using test programs
 
 if HAVE_GTK
@@ -31,7 +35,7 @@ if HAVE_GTK
 GTK_LDADD = $(TEST_LDADD) $(GTK_LIBS)
 GTK_UTILS = gtk-utils.c gtk-utils.h
 
-TESTPROGRAMS +=			\
+TESTPROGRAMS_GTK =		\
 	clip-test		\
 	clip-in			\
 	composite-test		\
@@ -39,7 +43,8 @@ TESTPROGRAMS +=			\
 	alpha-test		\
 	screen-test		\
 	convolution-test	\
-	trap-test
+	trap-test		\
+	alphamap
 
 INCLUDES += $(GTK_CFLAGS)
 
@@ -69,5 +74,7 @@ convolution_test_SOURCES = convolution-test.c $(GTK_UTILS)
 
 endif
 
-noinst_PROGRAMS = $(TESTPROGRAMS)
+noinst_PROGRAMS = $(TESTPROGRAMS) $(TESTPROGRAMS_GTK)
+
+TESTS = $(TESTPROGRAMS)
 
diff --git a/pixman/test/Makefile.in b/pixman/test/Makefile.in
index 4c19caf94..e7f0ab067 100644
--- a/pixman/test/Makefile.in
+++ b/pixman/test/Makefile.in
@@ -32,18 +32,9 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
-@HAVE_GTK_TRUE@am__append_1 = \
-@HAVE_GTK_TRUE@	clip-test		\
-@HAVE_GTK_TRUE@	clip-in			\
-@HAVE_GTK_TRUE@	composite-test		\
-@HAVE_GTK_TRUE@	gradient-test		\
-@HAVE_GTK_TRUE@	alpha-test		\
-@HAVE_GTK_TRUE@	screen-test		\
-@HAVE_GTK_TRUE@	convolution-test	\
-@HAVE_GTK_TRUE@	trap-test
-
-@HAVE_GTK_TRUE@am__append_2 = $(GTK_CFLAGS)
-noinst_PROGRAMS = $(am__EXEEXT_2)
+@HAVE_GTK_TRUE@am__append_1 = $(GTK_CFLAGS)
+noinst_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2)
+TESTS = $(am__EXEEXT_1)
 subdir = test
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -53,14 +44,15 @@ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
-@HAVE_GTK_TRUE@am__EXEEXT_1 = clip-test$(EXEEXT) clip-in$(EXEEXT) \
+am__EXEEXT_1 = region-test$(EXEEXT) fetch-test$(EXEEXT) \
+	oob-test$(EXEEXT) window-test$(EXEEXT) trap-crasher$(EXEEXT) \
+	alphamap$(EXEEXT) blitters-test$(EXEEXT) scaling-test$(EXEEXT) \
+	composite$(EXEEXT)
+@HAVE_GTK_TRUE@am__EXEEXT_2 = clip-test$(EXEEXT) clip-in$(EXEEXT) \
 @HAVE_GTK_TRUE@	composite-test$(EXEEXT) gradient-test$(EXEEXT) \
 @HAVE_GTK_TRUE@	alpha-test$(EXEEXT) screen-test$(EXEEXT) \
-@HAVE_GTK_TRUE@	convolution-test$(EXEEXT) trap-test$(EXEEXT)
-am__EXEEXT_2 = region-test$(EXEEXT) scaling-test$(EXEEXT) \
-	blitters-test$(EXEEXT) composite$(EXEEXT) fetch-test$(EXEEXT) \
-	oob-test$(EXEEXT) window-test$(EXEEXT) trap-crasher$(EXEEXT) \
-	$(am__EXEEXT_1)
+@HAVE_GTK_TRUE@	convolution-test$(EXEEXT) trap-test$(EXEEXT) \
+@HAVE_GTK_TRUE@	alphamap$(EXEEXT)
 PROGRAMS = $(noinst_PROGRAMS)
 am__alpha_test_SOURCES_DIST = alpha-test.c gtk-utils.c gtk-utils.h
 @HAVE_GTK_TRUE@am__objects_1 = gtk-utils.$(OBJEXT)
@@ -71,6 +63,9 @@ am__DEPENDENCIES_1 =
 @HAVE_GTK_TRUE@am__DEPENDENCIES_2 = $(TEST_LDADD) \
 @HAVE_GTK_TRUE@	$(am__DEPENDENCIES_1)
 @HAVE_GTK_TRUE@alpha_test_DEPENDENCIES = $(am__DEPENDENCIES_2)
+am_alphamap_OBJECTS = alphamap.$(OBJEXT) utils.$(OBJEXT)
+alphamap_OBJECTS = $(am_alphamap_OBJECTS)
+alphamap_DEPENDENCIES = $(TEST_LDADD)
 am_blitters_test_OBJECTS = blitters-test.$(OBJEXT) utils.$(OBJEXT)
 blitters_test_OBJECTS = $(am_blitters_test_OBJECTS)
 blitters_test_DEPENDENCIES = $(TEST_LDADD)
@@ -144,15 +139,17 @@ CCLD = $(CC)
 LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
 	--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
 	$(LDFLAGS) -o $@
-SOURCES = $(alpha_test_SOURCES) $(blitters_test_SOURCES) \
-	$(clip_in_SOURCES) $(clip_test_SOURCES) composite.c \
-	$(composite_test_SOURCES) $(convolution_test_SOURCES) \
-	fetch-test.c $(gradient_test_SOURCES) oob-test.c region-test.c \
+SOURCES = $(alpha_test_SOURCES) $(alphamap_SOURCES) \
+	$(blitters_test_SOURCES) $(clip_in_SOURCES) \
+	$(clip_test_SOURCES) composite.c $(composite_test_SOURCES) \
+	$(convolution_test_SOURCES) fetch-test.c \
+	$(gradient_test_SOURCES) oob-test.c region-test.c \
 	$(scaling_test_SOURCES) $(screen_test_SOURCES) trap-crasher.c \
 	$(trap_test_SOURCES) window-test.c
-DIST_SOURCES = $(am__alpha_test_SOURCES_DIST) $(blitters_test_SOURCES) \
-	$(am__clip_in_SOURCES_DIST) $(am__clip_test_SOURCES_DIST) \
-	composite.c $(am__composite_test_SOURCES_DIST) \
+DIST_SOURCES = $(am__alpha_test_SOURCES_DIST) $(alphamap_SOURCES) \
+	$(blitters_test_SOURCES) $(am__clip_in_SOURCES_DIST) \
+	$(am__clip_test_SOURCES_DIST) composite.c \
+	$(am__composite_test_SOURCES_DIST) \
 	$(am__convolution_test_SOURCES_DIST) fetch-test.c \
 	$(am__gradient_test_SOURCES_DIST) oob-test.c region-test.c \
 	$(scaling_test_SOURCES) $(am__screen_test_SOURCES_DIST) \
@@ -291,9 +288,18 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 TEST_LDADD = $(top_builddir)/pixman/libpixman-1.la
 INCLUDES = -I$(top_srcdir)/pixman -I$(top_builddir)/pixman \
-	$(am__append_2)
-TESTPROGRAMS = region-test scaling-test blitters-test composite \
-	fetch-test oob-test window-test trap-crasher $(am__append_1)
+	$(am__append_1)
+TESTPROGRAMS = \
+	region-test		\
+	fetch-test		\
+	oob-test		\
+	window-test		\
+	trap-crasher		\
+	alphamap		\
+	blitters-test		\
+	scaling-test		\
+	composite
+
 fetch_test_LDADD = $(TEST_LDADD)
 region_test_LDADD = $(TEST_LDADD)
 composite_LDADD = $(TEST_LDADD)
@@ -304,10 +310,23 @@ blitters_test_LDADD = $(TEST_LDADD)
 blitters_test_SOURCES = blitters-test.c utils.c utils.h
 scaling_test_LDADD = $(TEST_LDADD)
 scaling_test_SOURCES = scaling-test.c utils.c utils.h
+alphamap_LDADD = $(TEST_LDADD)
+alphamap_SOURCES = alphamap.c utils.c utils.h
 
 # GTK using test programs
 @HAVE_GTK_TRUE@GTK_LDADD = $(TEST_LDADD) $(GTK_LIBS)
 @HAVE_GTK_TRUE@GTK_UTILS = gtk-utils.c gtk-utils.h
+@HAVE_GTK_TRUE@TESTPROGRAMS_GTK = \
+@HAVE_GTK_TRUE@	clip-test		\
+@HAVE_GTK_TRUE@	clip-in			\
+@HAVE_GTK_TRUE@	composite-test		\
+@HAVE_GTK_TRUE@	gradient-test		\
+@HAVE_GTK_TRUE@	alpha-test		\
+@HAVE_GTK_TRUE@	screen-test		\
+@HAVE_GTK_TRUE@	convolution-test	\
+@HAVE_GTK_TRUE@	trap-test		\
+@HAVE_GTK_TRUE@	alphamap
+
 @HAVE_GTK_TRUE@gradient_test_LDADD = $(GTK_LDADD)
 @HAVE_GTK_TRUE@gradient_test_SOURCES = gradient-test.c $(GTK_UTILS)
 @HAVE_GTK_TRUE@alpha_test_LDADD = $(GTK_LDADD)
@@ -367,6 +386,9 @@ clean-noinstPROGRAMS:
 alpha-test$(EXEEXT): $(alpha_test_OBJECTS) $(alpha_test_DEPENDENCIES) 
 	@rm -f alpha-test$(EXEEXT)
 	$(LINK) $(alpha_test_OBJECTS) $(alpha_test_LDADD) $(LIBS)
+alphamap$(EXEEXT): $(alphamap_OBJECTS) $(alphamap_DEPENDENCIES) 
+	@rm -f alphamap$(EXEEXT)
+	$(LINK) $(alphamap_OBJECTS) $(alphamap_LDADD) $(LIBS)
 blitters-test$(EXEEXT): $(blitters_test_OBJECTS) $(blitters_test_DEPENDENCIES) 
 	@rm -f blitters-test$(EXEEXT)
 	$(LINK) $(blitters_test_OBJECTS) $(blitters_test_LDADD) $(LIBS)
@@ -420,6 +442,7 @@ distclean-compile:
 	-rm -f *.tab.c
 
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alpha-test.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alphamap.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blitters-test.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clip-in.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clip-test.Po@am__quote@
@@ -512,6 +535,79 @@ GTAGS:
 distclean-tags:
 	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
 
+check-TESTS: $(TESTS)
+	@failed=0; all=0; xfail=0; xpass=0; skip=0; ws='[	 ]'; \
+	srcdir=$(srcdir); export srcdir; \
+	list=' $(TESTS) '; \
+	if test -n "$$list"; then \
+	  for tst in $$list; do \
+	    if test -f ./$$tst; then dir=./; \
+	    elif test -f $$tst; then dir=; \
+	    else dir="$(srcdir)/"; fi; \
+	    if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
+	      all=`expr $$all + 1`; \
+	      case " $(XFAIL_TESTS) " in \
+	      *$$ws$$tst$$ws*) \
+		xpass=`expr $$xpass + 1`; \
+		failed=`expr $$failed + 1`; \
+		echo "XPASS: $$tst"; \
+	      ;; \
+	      *) \
+		echo "PASS: $$tst"; \
+	      ;; \
+	      esac; \
+	    elif test $$? -ne 77; then \
+	      all=`expr $$all + 1`; \
+	      case " $(XFAIL_TESTS) " in \
+	      *$$ws$$tst$$ws*) \
+		xfail=`expr $$xfail + 1`; \
+		echo "XFAIL: $$tst"; \
+	      ;; \
+	      *) \
+		failed=`expr $$failed + 1`; \
+		echo "FAIL: $$tst"; \
+	      ;; \
+	      esac; \
+	    else \
+	      skip=`expr $$skip + 1`; \
+	      echo "SKIP: $$tst"; \
+	    fi; \
+	  done; \
+	  if test "$$failed" -eq 0; then \
+	    if test "$$xfail" -eq 0; then \
+	      banner="All $$all tests passed"; \
+	    else \
+	      banner="All $$all tests behaved as expected ($$xfail expected failures)"; \
+	    fi; \
+	  else \
+	    if test "$$xpass" -eq 0; then \
+	      banner="$$failed of $$all tests failed"; \
+	    else \
+	      banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \
+	    fi; \
+	  fi; \
+	  dashes="$$banner"; \
+	  skipped=""; \
+	  if test "$$skip" -ne 0; then \
+	    skipped="($$skip tests were not run)"; \
+	    test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+	      dashes="$$skipped"; \
+	  fi; \
+	  report=""; \
+	  if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+	    report="Please report to $(PACKAGE_BUGREPORT)"; \
+	    test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+	      dashes="$$report"; \
+	  fi; \
+	  dashes=`echo "$$dashes" | sed s/./=/g`; \
+	  echo "$$dashes"; \
+	  echo "$$banner"; \
+	  test -z "$$skipped" || echo "$$skipped"; \
+	  test -z "$$report" || echo "$$report"; \
+	  echo "$$dashes"; \
+	  test "$$failed" -eq 0; \
+	else :; fi
+
 distdir: $(DISTFILES)
 	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
 	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
@@ -539,6 +635,7 @@ distdir: $(DISTFILES)
 	  fi; \
 	done
 check-am: all-am
+	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
 check: check-am
 all-am: Makefile $(PROGRAMS)
 installdirs:
@@ -627,18 +724,19 @@ uninstall-am:
 
 .MAKE: install-am install-strip
 
-.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
-	clean-libtool clean-noinstPROGRAMS ctags distclean \
-	distclean-compile distclean-generic distclean-libtool \
-	distclean-tags distdir dvi dvi-am html html-am info info-am \
-	install install-am install-data install-data-am install-dvi \
-	install-dvi-am install-exec install-exec-am install-html \
-	install-html-am install-info install-info-am install-man \
-	install-pdf install-pdf-am install-ps install-ps-am \
-	install-strip installcheck installcheck-am installdirs \
-	maintainer-clean maintainer-clean-generic mostlyclean \
-	mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
-	pdf pdf-am ps ps-am tags uninstall uninstall-am
+.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \
+	clean-generic clean-libtool clean-noinstPROGRAMS ctags \
+	distclean distclean-compile distclean-generic \
+	distclean-libtool distclean-tags distdir dvi dvi-am html \
+	html-am info info-am install install-am install-data \
+	install-data-am install-dvi install-dvi-am install-exec \
+	install-exec-am install-html install-html-am install-info \
+	install-info-am install-man install-pdf install-pdf-am \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-compile \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags uninstall uninstall-am
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/pixman/test/alphamap.c b/pixman/test/alphamap.c
new file mode 100644
index 000000000..e6a25efcb
--- /dev/null
+++ b/pixman/test/alphamap.c
@@ -0,0 +1,49 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "utils.h"
+
+#define WIDTH 400
+#define HEIGHT 200
+
+int
+main (int argc, char **argv)
+{
+    uint8_t *alpha = make_random_bytes (WIDTH * HEIGHT);
+    uint32_t *src = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * 4);
+    uint32_t *dest = (uint32_t *)make_random_bytes (WIDTH * HEIGHT * 4);
+    int i;
+
+    pixman_image_t *a = pixman_image_create_bits (PIXMAN_a8, WIDTH, HEIGHT, (uint32_t *)alpha, WIDTH);
+    pixman_image_t *d = pixman_image_create_bits (PIXMAN_a8r8g8b8, WIDTH, HEIGHT, dest, WIDTH * 4);
+
+    for (i = 0; i < 2; ++i)
+    {
+	pixman_format_code_t sformat = (i == 0)? PIXMAN_a8r8g8b8 : PIXMAN_a2r10g10b10;
+	pixman_image_t *s = pixman_image_create_bits (sformat, WIDTH, HEIGHT, src, WIDTH * 4);
+	int j, k;
+
+	pixman_image_set_alpha_map (s, a, 0, 0);
+
+	pixman_image_composite (PIXMAN_OP_SRC, s, NULL, d, 0, 0, 0, 0, 0, 0, WIDTH, HEIGHT);
+
+	for (j = 0; j < HEIGHT; ++j)
+	{
+	    for (k = 0; k < WIDTH; ++k)
+	    {
+		uint8_t ap = ((uint8_t *)alpha)[j * WIDTH + k];
+		uint32_t dap = (dest[j * WIDTH + k] >> 24);
+		uint32_t sap = (src[j * WIDTH + k] >> 24);
+
+		if (ap != dap)
+		{
+		    printf ("Wrong alpha value at (%d, %d). Should be %d; got %d (src was %d)\n", k, j, ap, dap, sap);
+		    return 1;
+		}
+	    }
+	}
+
+	pixman_image_unref (s);
+    }
+
+    return 0;
+}
diff --git a/pixman/test/blitters-test.c b/pixman/test/blitters-test.c
index ac816eba1..4664db63b 100644
--- a/pixman/test/blitters-test.c
+++ b/pixman/test/blitters-test.c
@@ -270,7 +270,7 @@ test_composite (uint32_t initcrc, int testnum, int verbose)
     int w, h;
     int op;
     pixman_format_code_t src_fmt, dst_fmt, mask_fmt;
-    uint32_t *dstbuf;
+    uint32_t *dstbuf, *srcbuf, *maskbuf;
     uint32_t crc32;
     int max_width, max_height, max_extra_stride;
 
@@ -308,12 +308,43 @@ test_composite (uint32_t initcrc, int testnum, int verbose)
     dst_img = create_random_image (img_fmt_list, max_width, max_height,
 				   max_extra_stride, &dst_fmt);
 
+    src_width = pixman_image_get_width (src_img);
+    src_height = pixman_image_get_height (src_img);
+    src_stride = pixman_image_get_stride (src_img);
+
+    dst_width = pixman_image_get_width (dst_img);
+    dst_height = pixman_image_get_height (dst_img);
+    dst_stride = pixman_image_get_stride (dst_img);
+
+    dstbuf = pixman_image_get_data (dst_img);
+    srcbuf = pixman_image_get_data (src_img);
+
+    src_x = lcg_rand_n (src_width);
+    src_y = lcg_rand_n (src_height);
+    dst_x = lcg_rand_n (dst_width);
+    dst_y = lcg_rand_n (dst_height);
+
     mask_img = NULL;
     mask_fmt = -1;
     mask_x = 0;
     mask_y = 0;
+    maskbuf = NULL;
 
-    if (lcg_rand_n (2))
+    if ((src_fmt == PIXMAN_x8r8g8b8 || src_fmt == PIXMAN_x8b8g8r8) &&
+	(lcg_rand_n (4) == 0))
+    {
+	/* PIXBUF */
+	mask_fmt = lcg_rand_n (2) ? PIXMAN_a8r8g8b8 : PIXMAN_a8b8g8r8;
+	mask_img = pixman_image_create_bits (mask_fmt,
+	                                     src_width,
+	                                     src_height,
+	                                     srcbuf,
+	                                     src_stride);
+	mask_x = src_x;
+	mask_y = src_y;
+	maskbuf = srcbuf;
+    }
+    else if (lcg_rand_n (2))
     {
 	if (lcg_rand_n (2))
 	{
@@ -335,20 +366,6 @@ test_composite (uint32_t initcrc, int testnum, int verbose)
 	mask_y = lcg_rand_n (pixman_image_get_height (mask_img));
     }
 
-    src_width = pixman_image_get_width (src_img);
-    src_height = pixman_image_get_height (src_img);
-    src_stride = pixman_image_get_stride (src_img);
-
-    dst_width = pixman_image_get_width (dst_img);
-    dst_height = pixman_image_get_height (dst_img);
-    dst_stride = pixman_image_get_stride (dst_img);
-
-    dstbuf = pixman_image_get_data (dst_img);
-
-    src_x = lcg_rand_n (src_width);
-    src_y = lcg_rand_n (src_height);
-    dst_x = lcg_rand_n (dst_width);
-    dst_y = lcg_rand_n (dst_height);
 
     w = lcg_rand_n (dst_width - dst_x + 1);
     h = lcg_rand_n (dst_height - dst_y + 1);
@@ -392,7 +409,13 @@ test_composite (uint32_t initcrc, int testnum, int verbose)
     crc32 = free_random_image (initcrc, dst_img, dst_fmt);
 
     if (mask_img)
-	free_random_image (initcrc, mask_img, -1);
+    {
+	if (srcbuf == maskbuf)
+	    pixman_image_unref(mask_img);
+	else
+	    free_random_image (initcrc, mask_img, -1);
+    }
+
 
     return crc32;
 }
@@ -440,7 +463,7 @@ main (int argc, char *argv[])
 	    /* Predefined value for running with all the fastpath functions
 	       disabled. It needs to be updated every time when changes are
 	       introduced to this program or behavior of pixman changes! */
-	    if (crc == 0x1911E2C3)
+	    if (crc == 0x20CBE02C)
 	    {
 		printf ("blitters test passed\n");
 	    }
diff --git a/pixman/test/fetch-test.c b/pixman/test/fetch-test.c
index 6306a4c42..c7b32ff3b 100644
--- a/pixman/test/fetch-test.c
+++ b/pixman/test/fetch-test.c
@@ -6,7 +6,8 @@
 
 #define SIZE 1024
 
-pixman_indexed_t mono_pallete = {
+static const pixman_indexed_t mono_palette =
+{
     .rgba = { 0x00000000, 0x00ffffff },
 };
 
@@ -20,14 +21,15 @@ typedef struct {
     pixman_indexed_t *indexed;
 } testcase_t;
 
-testcase_t testcases[] = {
+static const testcase_t testcases[] =
+{
     {
 	.format = PIXMAN_a8r8g8b8,
 	.width = 2, .height = 2,
 	.stride = 8,
-	.src = { 0x00112233, 0x44556677, 
+	.src = { 0x00112233, 0x44556677,
 	         0x8899aabb, 0xccddeeff },
-	.dst = { 0x00112233, 0x44556677, 
+	.dst = { 0x00112233, 0x44556677,
 	         0x8899aabb, 0xccddeeff },
 	.indexed = NULL,
     },
@@ -36,24 +38,33 @@ testcase_t testcases[] = {
 	.width = 8, .height = 2,
 	.stride = 4,
 #ifdef WORDS_BIGENDIAN
-	.src = { 0xaa000000,
-		 0x55000000 },
+	.src =
+	{
+	    0xaa000000,
+	    0x55000000
+	},
 #else
-	.src = { 0x00000055, 
-	         0x000000aa },
+	.src =
+	{
+	    0x00000055,
+	    0x000000aa
+	},
 #endif
-	.dst = { 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000,
-	         0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff },
-	.indexed = &mono_pallete,
+	.dst =
+	{
+	    0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000,
+	    0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff
+	},
+	.indexed = &mono_palette,
     },
 #if 0
     {
 	.format = PIXMAN_g8,
 	.width = 4, .height = 2,
 	.stride = 4,
-	.src = { 0x01234567, 
+	.src = { 0x01234567,
 	         0x89abcdef },
-	.dst = { 0x00010101, 0x00232323, 0x00454545, 0x00676767, 
+	.dst = { 0x00010101, 0x00232323, 0x00454545, 0x00676767,
 	         0x00898989, 0x00ababab, 0x00cdcdcd, 0x00efefef, },
     },
 #endif
@@ -63,28 +74,33 @@ testcase_t testcases[] = {
 	.width = 8, .height = 2,
 	.stride = 8,
 #ifdef WORDS_BIGENDIAN
-	.src = { 0x00ff00ff, 0x00ff00ff, 
-	         0xff00ff00, 0xff00ff00, 
-	         0x80ff8000, 
-		 0x800080ff
+	.src =
+	{
+	    0x00ff00ff, 0x00ff00ff,
+	    0xff00ff00, 0xff00ff00,
+	    0x80ff8000,
+	    0x800080ff
 	},
 #else
-	.src = { 0xff00ff00, 0xff00ff00, 
-	         0x00ff00ff, 0x00ff00ff, 
-	         0x0080ff80, 
-		 0xff800080
-	 },
+	.src =
+	{
+	    0xff00ff00, 0xff00ff00,
+	    0x00ff00ff, 0x00ff00ff,
+	    0x0080ff80,
+	    0xff800080
+	},
 #endif
-	.dst = { 
-		0xff000000, 0xffffffff, 0xffb80000, 0xffffe113,
-		0xff000000, 0xffffffff, 0xff0023ee, 0xff4affff,
-		0xffffffff, 0xff000000, 0xffffe113, 0xffb80000,
-		0xffffffff, 0xff000000, 0xff4affff, 0xff0023ee,
+	.dst =
+	{
+	    0xff000000, 0xffffffff, 0xffb80000, 0xffffe113,
+	    0xff000000, 0xffffffff, 0xff0023ee, 0xff4affff,
+	    0xffffffff, 0xff000000, 0xffffe113, 0xffb80000,
+	    0xffffffff, 0xff000000, 0xff4affff, 0xff0023ee,
 	},
     },
 };
 
-const int ntestcases = sizeof(testcases)/sizeof(testcases[0]);
+const int n_test_cases = sizeof(testcases)/sizeof(testcases[0]);
 
 
 static uint32_t
@@ -133,26 +149,29 @@ main (int argc, char **argv)
     int i, j, x, y;
     int ret = 0;
 
-    for (i = 0; i < ntestcases; ++i) {
-	for (j = 0; j < 2; ++j) {
+    for (i = 0; i < n_test_cases; ++i)
+    {
+	for (j = 0; j < 2; ++j)
+	{
 	    src_img = pixman_image_create_bits (testcases[i].format,
-						testcases[i].width, 
+						testcases[i].width,
 						testcases[i].height,
 						testcases[i].src,
 						testcases[i].stride);
 	    pixman_image_set_indexed(src_img, testcases[i].indexed);
 
 	    dst_img = pixman_image_create_bits (PIXMAN_a8r8g8b8,
-						testcases[i].width, 
+						testcases[i].width,
 						testcases[i].height,
 						dst,
 						testcases[i].width*4);
 
-	    if (j) {
+	    if (j)
+	    {
 		pixman_image_set_accessors (src_img, reader, writer);
 		pixman_image_set_accessors (dst_img, reader, writer);
 	    }
-	    
+
 	    pixman_image_composite (PIXMAN_OP_SRC, src_img, NULL, dst_img,
 				    0, 0, 0, 0, 0, 0, testcases[i].width, testcases[i].height);
 
@@ -160,18 +179,23 @@ main (int argc, char **argv)
 	    pixman_image_unref (dst_img);
 
 	    for (y = 0; y < testcases[i].height; ++y)
-		for (x = 0; x < testcases[i].width; ++x) {
-		    int offset = y*testcases[i].width + x;
-		    if (dst[offset] != testcases[i].dst[offset]) {
+	    {
+		for (x = 0; x < testcases[i].width; ++x)
+		{
+		    int offset = y * testcases[i].width + x;
+
+		    if (dst[offset] != testcases[i].dst[offset])
+		    {
 			printf ("test %i%c: pixel mismatch at (x=%d,y=%d): %08x expected, %08x obtained\n",
 			        i + 1, 'a' + j,
-			        x, y, 
+			        x, y,
 			        testcases[i].dst[offset], dst[offset]);
 			ret = 1;
 		    }
 		}
+	    }
 	}
     }
-    
+
     return ret;
 }
diff --git a/pixman/test/utils.c b/pixman/test/utils.c
index 1e42d89d8..58cd100e2 100644
--- a/pixman/test/utils.c
+++ b/pixman/test/utils.c
@@ -192,3 +192,17 @@ image_endian_swap (pixman_image_t *img, int bpp)
     }
 }
 
+uint8_t *
+make_random_bytes (int n_bytes)
+{
+    uint8_t *bytes = malloc (n_bytes);
+    int i;
+
+    if (!bytes)
+	return NULL;
+
+    for (i = 0; i < n_bytes; ++i)
+	bytes[i] = lcg_rand () & 0xff;
+
+    return bytes;
+}
diff --git a/pixman/test/utils.h b/pixman/test/utils.h
index 8fdb2ce4f..fb1ccec48 100644
--- a/pixman/test/utils.h
+++ b/pixman/test/utils.h
@@ -39,3 +39,7 @@ compute_crc32 (uint32_t    in_crc32,
  */
 void
 image_endian_swap (pixman_image_t *img, int bpp);
+
+/* Generate n_bytes random bytes in malloced memory */
+uint8_t *
+make_random_bytes (int n_bytes);
-- 
cgit v1.2.3