pixman: Branch 'master' - 29 commits

Søren Sandmann Pedersen sandmann at kemper.freedesktop.org
Tue May 19 08:06:09 PDT 2009


 pixman/Makefile.am               |   55 -
 pixman/pixman-arm-neon.c         |   24 
 pixman/pixman-arm-neon.h         |    2 
 pixman/pixman-arm-simd.c         |   21 
 pixman/pixman-arm-simd.h         |    2 
 pixman/pixman-bits-image.c       |  217 ++++
 pixman/pixman-compose.c          |   14 
 pixman/pixman-conical-gradient.c |  157 +++
 pixman/pixman-cpu.c              |  498 ++++++++++
 pixman/pixman-fast-path.c        | 1056 +++++++++++++++++++++
 pixman/pixman-gradient-walker.c  |  232 ++++
 pixman/pixman-image.c            |  507 ++--------
 pixman/pixman-linear-gradient.c  |  261 +++++
 pixman/pixman-mmx.c              |  121 +-
 pixman/pixman-mmx.h              |  234 ----
 pixman/pixman-pict.c             | 1939 ---------------------------------------
 pixman/pixman-private.h          |  118 +-
 pixman/pixman-radial-gradient.c  |  326 ++++++
 pixman/pixman-solid-fill.c       |   85 +
 pixman/pixman-source.c           |  709 --------------
 pixman/pixman-sse2.c             |  119 +-
 pixman/pixman-sse2.h             |  283 -----
 pixman/pixman-transformed.c      |   63 -
 pixman/pixman-vmx.c              |    7 
 pixman/pixman-vmx.h              |    2 
 pixman/refactor                  |  196 +++
 test/gradient-test.c             |    5 
 27 files changed, 3537 insertions(+), 3716 deletions(-)

New commits:
commit 14cd45dc4a63296a549bcc53453ca40beed67f51
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Wed May 13 05:53:40 2009 -0400

    Make SSE2 fast paths static and remove them from the header file

diff --git a/pixman/pixman-sse2.c b/pixman/pixman-sse2.c
index 240d079..af458dc 100644
--- a/pixman/pixman-sse2.c
+++ b/pixman/pixman-sse2.c
@@ -2537,7 +2537,7 @@ fbComposeSetupSSE2(void)
  * fbCompositeSolid_nx8888
  */
 
-void
+static void
 fbCompositeSolid_nx8888sse2 (pixman_op_t op,
 			    pixman_image_t * pSrc,
 			    pixman_image_t * pMask,
@@ -2623,7 +2623,7 @@ fbCompositeSolid_nx8888sse2 (pixman_op_t op,
 /* -------------------------------------------------------------------------------------------------
  * fbCompositeSolid_nx0565
  */
-void
+static void
 fbCompositeSolid_nx0565sse2 (pixman_op_t op,
 			    pixman_image_t * pSrc,
 			    pixman_image_t * pMask,
@@ -2712,7 +2712,7 @@ fbCompositeSolid_nx0565sse2 (pixman_op_t op,
  * fbCompositeSolidMask_nx8888x8888C
  */
 
-void
+static void
 fbCompositeSolidMask_nx8888x8888Csse2 (pixman_op_t op,
 				      pixman_image_t * pSrc,
 				      pixman_image_t * pMask,
@@ -2846,7 +2846,7 @@ fbCompositeSolidMask_nx8888x8888Csse2 (pixman_op_t op,
  * fbCompositeSrc_8888x8x8888
  */
 
-void
+static void
 fbCompositeSrc_8888x8x8888sse2 (pixman_op_t op,
 			       pixman_image_t * pSrc,
 			       pixman_image_t * pMask,
@@ -2958,7 +2958,7 @@ fbCompositeSrc_8888x8x8888sse2 (pixman_op_t op,
 /* -------------------------------------------------------------------------------------------------
  * fbCompositeSrc_x888xnx8888
  */
-void
+static void
 fbCompositeSrc_x888xnx8888sse2 (pixman_op_t op,
 			       pixman_image_t * pSrc,
 			       pixman_image_t * pMask,
@@ -3070,7 +3070,7 @@ fbCompositeSrc_x888xnx8888sse2 (pixman_op_t op,
 /* -------------------------------------------------------------------------------------------------
  * fbCompositeSrc_8888x8888
  */
-void
+static void
 fbCompositeSrc_8888x8888sse2 (pixman_op_t op,
 			     pixman_image_t * pSrc,
 			     pixman_image_t * pMask,
@@ -3118,7 +3118,7 @@ fbCompositeSrc_8888x0565pixel (uint32_t src, uint16_t dst)
                                                    expand565_16_1x64 (dst))));
 }
 
-void
+static void
 fbCompositeSrc_8888x0565sse2 (pixman_op_t op,
 			     pixman_image_t * pSrc,
 			     pixman_image_t * pMask,
@@ -3231,7 +3231,7 @@ fbCompositeSrc_8888x0565sse2 (pixman_op_t op,
  * fbCompositeSolidMask_nx8x8888
  */
 
-void
+static void
 fbCompositeSolidMask_nx8x8888sse2 (pixman_op_t op,
 				  pixman_image_t * pSrc,
 				  pixman_image_t * pMask,
@@ -3508,7 +3508,7 @@ pixmanFillsse2 (uint32_t *bits,
     return TRUE;
 }
 
-void
+static void
 fbCompositeSolidMaskSrc_nx8x8888sse2 (pixman_op_t op,
 				     pixman_image_t * pSrc,
 				     pixman_image_t * pMask,
@@ -3643,7 +3643,7 @@ fbCompositeSolidMaskSrc_nx8x8888sse2 (pixman_op_t op,
  * fbCompositeSolidMask_nx8x0565
  */
 
-void
+static void
 fbCompositeSolidMask_nx8x0565sse2 (pixman_op_t op,
 				  pixman_image_t * pSrc,
 				  pixman_image_t * pMask,
@@ -3792,7 +3792,7 @@ fbCompositeSolidMask_nx8x0565sse2 (pixman_op_t op,
  * fbCompositeSrc_8888RevNPx0565
  */
 
-void
+static void
 fbCompositeSrc_8888RevNPx0565sse2 (pixman_op_t op,
 				  pixman_image_t * pSrc,
 				  pixman_image_t * pMask,
@@ -3925,7 +3925,7 @@ fbCompositeSrc_8888RevNPx0565sse2 (pixman_op_t op,
  * fbCompositeSrc_8888RevNPx8888
  */
 
-void
+static void
 fbCompositeSrc_8888RevNPx8888sse2 (pixman_op_t op,
 				  pixman_image_t * pSrc,
 				  pixman_image_t * pMask,
@@ -4038,7 +4038,7 @@ fbCompositeSrc_8888RevNPx8888sse2 (pixman_op_t op,
  * fbCompositeSolidMask_nx8888x0565C
  */
 
-void
+static void
 fbCompositeSolidMask_nx8888x0565Csse2 (pixman_op_t op,
 				      pixman_image_t * pSrc,
 				      pixman_image_t * pMask,
@@ -4186,7 +4186,7 @@ fbCompositeSolidMask_nx8888x0565Csse2 (pixman_op_t op,
  * fbCompositeIn_nx8x8
  */
 
-void
+static void
 fbCompositeIn_nx8x8sse2 (pixman_op_t op,
 			pixman_image_t * pSrc,
 			pixman_image_t * pMask,
@@ -4288,7 +4288,7 @@ fbCompositeIn_nx8x8sse2 (pixman_op_t op,
  * fbCompositeIn_8x8
  */
 
-void
+static void
 fbCompositeIn_8x8sse2 (pixman_op_t op,
 		      pixman_image_t * pSrc,
 		      pixman_image_t * pMask,
@@ -4377,7 +4377,7 @@ fbCompositeIn_8x8sse2 (pixman_op_t op,
  * fbCompositeSrcAdd_8888x8x8
  */
 
-void
+static void
 fbCompositeSrcAdd_8888x8x8sse2 (pixman_op_t op,
 			       pixman_image_t * pSrc,
 			       pixman_image_t * pMask,
@@ -4482,7 +4482,7 @@ fbCompositeSrcAdd_8888x8x8sse2 (pixman_op_t op,
  * fbCompositeSrcAdd_8000x8000
  */
 
-void
+static void
 fbCompositeSrcAdd_8000x8000sse2 (pixman_op_t op,
 				pixman_image_t * pSrc,
 				pixman_image_t * pMask,
@@ -4548,7 +4548,7 @@ fbCompositeSrcAdd_8000x8000sse2 (pixman_op_t op,
 /* -------------------------------------------------------------------------------------------------
  * fbCompositeSrcAdd_8888x8888
  */
-void
+static void
 fbCompositeSrcAdd_8888x8888sse2 (pixman_op_t 	op,
 				pixman_image_t *	pSrc,
 				pixman_image_t *	pMask,
@@ -4725,7 +4725,7 @@ pixmanBltsse2 (uint32_t *src_bits,
     return TRUE;
 }
 
-void
+static void
 fbCompositeCopyAreasse2 (pixman_op_t       op,
 			pixman_image_t *	pSrc,
 			pixman_image_t *	pMask,
diff --git a/pixman/pixman-sse2.h b/pixman/pixman-sse2.h
index 783fcdf..417e31d 100644
--- a/pixman/pixman-sse2.h
+++ b/pixman/pixman-sse2.h
@@ -74,287 +74,6 @@ pixmanBltsse2 (uint32_t *src_bits,
 		int dst_x, int dst_y,
 		int width, int height);
 
-void
-fbCompositeSolid_nx8888sse2 (pixman_op_t op,
-			    pixman_image_t * pSrc,
-			    pixman_image_t * pMask,
-			    pixman_image_t * pDst,
-			    int16_t	xSrc,
-			    int16_t	ySrc,
-			    int16_t	xMask,
-			    int16_t	yMask,
-			    int16_t	xDst,
-			    int16_t	yDst,
-			    uint16_t	width,
-			    uint16_t	height);
-
-void
-fbCompositeSolid_nx0565sse2 (pixman_op_t op,
-			    pixman_image_t * pSrc,
-			    pixman_image_t * pMask,
-			    pixman_image_t * pDst,
-			    int16_t	xSrc,
-			    int16_t	ySrc,
-			    int16_t	xMask,
-			    int16_t	yMask,
-			    int16_t	xDst,
-			    int16_t	yDst,
-			    uint16_t	width,
-			    uint16_t	height);
-
-void
-fbCompositeSolidMask_nx8888x8888Csse2 (pixman_op_t op,
-				      pixman_image_t * pSrc,
-				      pixman_image_t * pMask,
-				      pixman_image_t * pDst,
-				      int16_t	xSrc,
-				      int16_t	ySrc,
-				      int16_t	xMask,
-				      int16_t	yMask,
-				      int16_t	xDst,
-				      int16_t	yDst,
-				      uint16_t	width,
-				      uint16_t	height);
-
-void
-fbCompositeSrc_8888x8x8888sse2 (pixman_op_t op,
-			       pixman_image_t * pSrc,
-			       pixman_image_t * pMask,
-			       pixman_image_t * pDst,
-			       int16_t	xSrc,
-			       int16_t	ySrc,
-			       int16_t      xMask,
-			       int16_t      yMask,
-			       int16_t      xDst,
-			       int16_t      yDst,
-			       uint16_t     width,
-			       uint16_t     height);
-
-void
-fbCompositeSrc_x888xnx8888sse2 (pixman_op_t op,
-			       pixman_image_t * pSrc,
-			       pixman_image_t * pMask,
-			       pixman_image_t * pDst,
-			       int16_t	xSrc,
-			       int16_t	ySrc,
-			       int16_t      xMask,
-			       int16_t      yMask,
-			       int16_t      xDst,
-			       int16_t      yDst,
-			       uint16_t     width,
-			       uint16_t     height);
-
-void
-fbCompositeSrc_8888x8888sse2 (pixman_op_t op,
-                 pixman_image_t * pSrc,
-                 pixman_image_t * pMask,
-                 pixman_image_t * pDst,
-                 int16_t    xSrc,
-                 int16_t    ySrc,
-                 int16_t      xMask,
-                 int16_t      yMask,
-                 int16_t      xDst,
-                 int16_t      yDst,
-                 uint16_t     width,
-                 uint16_t     height);
-
-void
-fbCompositeSrc_8888x0565sse2 (pixman_op_t op,
-                 pixman_image_t * pSrc,
-                 pixman_image_t * pMask,
-                 pixman_image_t * pDst,
-                 int16_t      xSrc,
-                 int16_t      ySrc,
-                 int16_t      xMask,
-                 int16_t      yMask,
-                 int16_t      xDst,
-                 int16_t      yDst,
-                 uint16_t     width,
-                 uint16_t     height);
-
-void
-fbCompositeSolidMask_nx8x8888sse2 (pixman_op_t op,
-				  pixman_image_t * pSrc,
-				  pixman_image_t * pMask,
-				  pixman_image_t * pDst,
-				  int16_t      xSrc,
-				  int16_t      ySrc,
-				  int16_t      xMask,
-				  int16_t      yMask,
-				  int16_t      xDst,
-				  int16_t      yDst,
-				  uint16_t     width,
-				  uint16_t     height);
-
-void
-fbCompositeSolidMaskSrc_nx8x8888sse2 (pixman_op_t op,
-				     pixman_image_t * pSrc,
-				     pixman_image_t * pMask,
-				     pixman_image_t * pDst,
-				     int16_t      xSrc,
-				     int16_t      ySrc,
-				     int16_t      xMask,
-				     int16_t      yMask,
-				     int16_t      xDst,
-				     int16_t      yDst,
-				     uint16_t     width,
-				     uint16_t     height);
-
-void
-fbCompositeSolidMask_nx8x0565sse2 (pixman_op_t op,
-				  pixman_image_t * pSrc,
-				  pixman_image_t * pMask,
-				  pixman_image_t * pDst,
-				  int16_t      xSrc,
-				  int16_t      ySrc,
-				  int16_t      xMask,
-				  int16_t      yMask,
-				  int16_t      xDst,
-				  int16_t      yDst,
-				  uint16_t     width,
-				  uint16_t     height);
-
-void
-fbCompositeSrc_8888RevNPx0565sse2 (pixman_op_t op,
-				  pixman_image_t * pSrc,
-				  pixman_image_t * pMask,
-				  pixman_image_t * pDst,
-				  int16_t      xSrc,
-				  int16_t      ySrc,
-				  int16_t      xMask,
-				  int16_t      yMask,
-				  int16_t      xDst,
-				  int16_t      yDst,
-				  uint16_t     width,
-				  uint16_t     height);
-
-void
-fbCompositeSrc_8888RevNPx8888sse2 (pixman_op_t op,
-				  pixman_image_t * pSrc,
-				  pixman_image_t * pMask,
-				  pixman_image_t * pDst,
-				  int16_t      xSrc,
-				  int16_t      ySrc,
-				  int16_t      xMask,
-				  int16_t      yMask,
-				  int16_t      xDst,
-				  int16_t      yDst,
-				  uint16_t     width,
-				  uint16_t     height);
-
-void
-fbCompositeSolidMask_nx8888x0565Csse2 (pixman_op_t op,
-				      pixman_image_t * pSrc,
-				      pixman_image_t * pMask,
-				      pixman_image_t * pDst,
-				      int16_t      xSrc,
-				      int16_t      ySrc,
-				      int16_t      xMask,
-				      int16_t      yMask,
-				      int16_t      xDst,
-				      int16_t      yDst,
-				      uint16_t     width,
-				      uint16_t     height);
-
-void
-fbCompositeIn_nx8x8sse2 (pixman_op_t op,
-			pixman_image_t * pSrc,
-			pixman_image_t * pMask,
-			pixman_image_t * pDst,
-			int16_t      xSrc,
-			int16_t      ySrc,
-			int16_t      xMask,
-			int16_t      yMask,
-			int16_t      xDst,
-			int16_t      yDst,
-			uint16_t     width,
-			uint16_t     height);
-
-void
-fbCompositeIn_8x8sse2 (pixman_op_t op,
-		      pixman_image_t * pSrc,
-		      pixman_image_t * pMask,
-		      pixman_image_t * pDst,
-		      int16_t      xSrc,
-		      int16_t      ySrc,
-		      int16_t      xMask,
-		      int16_t      yMask,
-		      int16_t      xDst,
-		      int16_t      yDst,
-		      uint16_t     width,
-		      uint16_t     height);
-
-void
-fbCompositeSrcAdd_8888x8x8sse2 (pixman_op_t op,
-			       pixman_image_t * pSrc,
-			       pixman_image_t * pMask,
-			       pixman_image_t * pDst,
-			       int16_t      xSrc,
-			       int16_t      ySrc,
-			       int16_t      xMask,
-			       int16_t      yMask,
-			       int16_t      xDst,
-			       int16_t      yDst,
-			       uint16_t     width,
-			       uint16_t     height);
-
-
-void
-fbCompositeSrcAdd_8000x8000sse2 (pixman_op_t op,
-                pixman_image_t * pSrc,
-                pixman_image_t * pMask,
-                pixman_image_t * pDst,
-                int16_t      xSrc,
-                int16_t      ySrc,
-                int16_t      xMask,
-                int16_t      yMask,
-                int16_t      xDst,
-                int16_t      yDst,
-                uint16_t     width,
-                uint16_t     height);
-
-void
-fbCompositeSrcAdd_8888x8888sse2 (pixman_op_t    op,
-                pixman_image_t *    pSrc,
-                pixman_image_t *    pMask,
-                pixman_image_t *     pDst,
-                int16_t      xSrc,
-                int16_t      ySrc,
-                int16_t      xMask,
-                int16_t      yMask,
-                int16_t      xDst,
-                int16_t      yDst,
-                uint16_t     width,
-                uint16_t     height);
-
-void
-fbCompositeCopyAreasse2 (pixman_op_t       op,
-			pixman_image_t *	pSrc,
-			pixman_image_t *	pMask,
-			pixman_image_t *	pDst,
-			int16_t		xSrc,
-			int16_t		ySrc,
-			int16_t		xMask,
-			int16_t		yMask,
-			int16_t		xDst,
-			int16_t		yDst,
-			uint16_t		width,
-			uint16_t		height);
-
-void
-fbCompositeOver_x888x8x8888sse2 (pixman_op_t      op,
-				pixman_image_t * pSrc,
-				pixman_image_t * pMask,
-				pixman_image_t * pDst,
-				int16_t      xSrc,
-				int16_t      ySrc,
-				int16_t      xMask,
-				int16_t      yMask,
-				int16_t      xDst,
-				int16_t      yDst,
-				uint16_t     width,
-				uint16_t     height);
-
 #endif /* USE_SSE2 */
 
 #endif /* _PIXMAN_SSE_H_ */
commit 0f1a212bf24490cbf80d6135bac17c5122d18cd2
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Wed May 13 05:49:13 2009 -0400

    Make MMX fast paths static and remove them from the header file

diff --git a/pixman/pixman-mmx.c b/pixman/pixman-mmx.c
index c9f6276..f8577db 100644
--- a/pixman/pixman-mmx.c
+++ b/pixman/pixman-mmx.c
@@ -936,7 +936,7 @@ fbComposeSetupMMX(void)
 
 /* ------------------ MMX code paths called from fbpict.c ----------------------- */
 
-void
+static void
 fbCompositeSolid_nx8888mmx (pixman_op_t op,
 			    pixman_image_t * pSrc,
 			    pixman_image_t * pMask,
@@ -1014,7 +1014,7 @@ fbCompositeSolid_nx8888mmx (pixman_op_t op,
     _mm_empty();
 }
 
-void
+static void
 fbCompositeSolid_nx0565mmx (pixman_op_t op,
 			    pixman_image_t * pSrc,
 			    pixman_image_t * pMask,
@@ -1099,7 +1099,7 @@ fbCompositeSolid_nx0565mmx (pixman_op_t op,
     _mm_empty();
 }
 
-void
+static void
 fbCompositeSolidMask_nx8888x8888Cmmx (pixman_op_t op,
 				      pixman_image_t * pSrc,
 				      pixman_image_t * pMask,
@@ -1202,7 +1202,7 @@ fbCompositeSolidMask_nx8888x8888Cmmx (pixman_op_t op,
     _mm_empty();
 }
 
-void
+static void
 fbCompositeSrc_8888x8x8888mmx (pixman_op_t op,
 			       pixman_image_t * pSrc,
 			       pixman_image_t * pMask,
@@ -1286,7 +1286,7 @@ fbCompositeSrc_8888x8x8888mmx (pixman_op_t op,
     _mm_empty();
 }
 
-void
+static void
 fbCompositeSrc_x888xnx8888mmx (pixman_op_t op,
 			       pixman_image_t * pSrc,
 			       pixman_image_t * pMask,
@@ -1420,7 +1420,7 @@ fbCompositeSrc_x888xnx8888mmx (pixman_op_t op,
     _mm_empty();
 }
 
-void
+static void
 fbCompositeSrc_8888x8888mmx (pixman_op_t op,
 			     pixman_image_t * pSrc,
 			     pixman_image_t * pMask,
@@ -1472,7 +1472,7 @@ fbCompositeSrc_8888x8888mmx (pixman_op_t op,
     _mm_empty();
 }
 
-void
+static void
 fbCompositeSrc_8888x0565mmx (pixman_op_t op,
 			     pixman_image_t * pSrc,
 			     pixman_image_t * pMask,
@@ -1573,7 +1573,7 @@ fbCompositeSrc_8888x0565mmx (pixman_op_t op,
     _mm_empty();
 }
 
-void
+static void
 fbCompositeSolidMask_nx8x8888mmx (pixman_op_t op,
 				  pixman_image_t * pSrc,
 				  pixman_image_t * pMask,
@@ -1844,7 +1844,7 @@ pixman_fill_mmx (uint32_t *bits,
     return TRUE;
 }
 
-void
+static void
 fbCompositeSolidMaskSrc_nx8x8888mmx (pixman_op_t op,
 				     pixman_image_t * pSrc,
 				     pixman_image_t * pMask,
@@ -1975,7 +1975,7 @@ fbCompositeSolidMaskSrc_nx8x8888mmx (pixman_op_t op,
     _mm_empty();
 }
 
-void
+static void
 fbCompositeSolidMask_nx8x0565mmx (pixman_op_t op,
 				  pixman_image_t * pSrc,
 				  pixman_image_t * pMask,
@@ -2107,7 +2107,7 @@ fbCompositeSolidMask_nx8x0565mmx (pixman_op_t op,
     _mm_empty();
 }
 
-void
+static void
 fbCompositeSrc_8888RevNPx0565mmx (pixman_op_t op,
 				  pixman_image_t * pSrc,
 				  pixman_image_t * pMask,
@@ -2228,7 +2228,7 @@ fbCompositeSrc_8888RevNPx0565mmx (pixman_op_t op,
 
 /* "8888RevNP" is GdkPixbuf's format: ABGR, non premultiplied */
 
-void
+static void
 fbCompositeSrc_8888RevNPx8888mmx (pixman_op_t op,
 				  pixman_image_t * pSrc,
 				  pixman_image_t * pMask,
@@ -2327,7 +2327,7 @@ fbCompositeSrc_8888RevNPx8888mmx (pixman_op_t op,
     _mm_empty();
 }
 
-void
+static void
 fbCompositeSolidMask_nx8888x0565Cmmx (pixman_op_t op,
 				      pixman_image_t * pSrc,
 				      pixman_image_t * pMask,
@@ -2434,7 +2434,7 @@ fbCompositeSolidMask_nx8888x0565Cmmx (pixman_op_t op,
     _mm_empty ();
 }
 
-void
+static void
 fbCompositeIn_nx8x8mmx (pixman_op_t op,
 			pixman_image_t * pSrc,
 			pixman_image_t * pMask,
@@ -2518,7 +2518,7 @@ fbCompositeIn_nx8x8mmx (pixman_op_t op,
     _mm_empty();
 }
 
-void
+static void
 fbCompositeIn_8x8mmx (pixman_op_t op,
 		      pixman_image_t * pSrc,
 		      pixman_image_t * pMask,
@@ -2582,7 +2582,7 @@ fbCompositeIn_8x8mmx (pixman_op_t op,
     _mm_empty ();
 }
 
-void
+static void
 fbCompositeSrcAdd_8888x8x8mmx (pixman_op_t op,
 			       pixman_image_t * pSrc,
 			       pixman_image_t * pMask,
@@ -2660,7 +2660,7 @@ fbCompositeSrcAdd_8888x8x8mmx (pixman_op_t op,
     _mm_empty();
 }
 
-void
+static void
 fbCompositeSrcAdd_8000x8000mmx (pixman_op_t op,
 				pixman_image_t * pSrc,
 				pixman_image_t * pMask,
@@ -2732,7 +2732,7 @@ fbCompositeSrcAdd_8000x8000mmx (pixman_op_t op,
     _mm_empty();
 }
 
-void
+static void
 fbCompositeSrcAdd_8888x8888mmx (pixman_op_t 	op,
 				pixman_image_t *	pSrc,
 				pixman_image_t *	pMask,
@@ -2953,7 +2953,7 @@ fbCompositeCopyAreammx (pixman_op_t       op,
 		    xSrc, ySrc, xDst, yDst, width, height);
 }
 
-void
+static void
 fbCompositeOver_x888x8x8888mmx (pixman_op_t      op,
 				pixman_image_t * pSrc,
 				pixman_image_t * pMask,
diff --git a/pixman/pixman-mmx.h b/pixman/pixman-mmx.h
index de4c46a..f17816f 100644
--- a/pixman/pixman-mmx.h
+++ b/pixman/pixman-mmx.h
@@ -72,225 +72,6 @@ pixman_fill_mmx (uint32_t *bits,
 		 uint32_t xor);
 
 void fbComposeSetupMMX(void);
-
-void fbCompositeSolidMask_nx8888x0565Cmmx (pixman_op_t      op,
-					   pixman_image_t * pSrc,
-					   pixman_image_t * pMask,
-					   pixman_image_t * pDst,
-					   int16_t      xSrc,
-					   int16_t      ySrc,
-					   int16_t      xMask,
-					   int16_t      yMask,
-					   int16_t      xDst,
-					   int16_t      yDst,
-					   uint16_t     width,
-					   uint16_t     height);
-void fbCompositeSrcAdd_8888x8888mmx (pixman_op_t	op,
-				     pixman_image_t *	pSrc,
-				     pixman_image_t *	pMask,
-				     pixman_image_t *	pDst,
-				     int16_t	xSrc,
-				     int16_t      ySrc,
-				     int16_t      xMask,
-				     int16_t      yMask,
-				     int16_t      xDst,
-				     int16_t      yDst,
-				     uint16_t     width,
-				     uint16_t     height);
-void fbCompositeSrc_8888x8888mmx (pixman_op_t		op,
-				  pixman_image_t *	pSrc,
-				  pixman_image_t *	pMask,
-				  pixman_image_t *	pDst,
-				  int16_t		xSrc,
-				  int16_t		ySrc,
-				  int16_t		xMask,
-				  int16_t		yMask,
-				  int16_t		xDst,
-				  int16_t		yDst,
-				  uint16_t	width,
-				  uint16_t	height);
-void
-fbCompositeSolidMaskSrc_nx8x8888mmx (pixman_op_t      op,
-				     pixman_image_t * pSrc,
-				     pixman_image_t * pMask,
-				     pixman_image_t * pDst,
-				     int16_t      xSrc,
-				     int16_t      ySrc,
-				     int16_t      xMask,
-				     int16_t      yMask,
-				     int16_t      xDst,
-				     int16_t      yDst,
-				     uint16_t     width,
-				     uint16_t     height);
-void
-fbCompositeSrc_x888xnx8888mmx (pixman_op_t	op,
-			       pixman_image_t * pSrc,
-			       pixman_image_t * pMask,
-			       pixman_image_t * pDst,
-			       int16_t	xSrc,
-			       int16_t	ySrc,
-			       int16_t      xMask,
-			       int16_t      yMask,
-			       int16_t      xDst,
-			       int16_t      yDst,
-			       uint16_t     width,
-			       uint16_t     height);
-void fbCompositeSolidMask_nx8888x8888Cmmx (pixman_op_t	op,
-					   pixman_image_t *	pSrc,
-					   pixman_image_t *	pMask,
-					   pixman_image_t *	pDst,
-					   int16_t	xSrc,
-					   int16_t	ySrc,
-					   int16_t	xMask,
-					   int16_t	yMask,
-					   int16_t	xDst,
-					   int16_t	yDst,
-					   uint16_t	width,
-					   uint16_t	height);
-void fbCompositeSolidMask_nx8x8888mmx (pixman_op_t      op,
-				       pixman_image_t * pSrc,
-				       pixman_image_t * pMask,
-				       pixman_image_t * pDst,
-				       int16_t      xSrc,
-				       int16_t      ySrc,
-				       int16_t      xMask,
-				       int16_t      yMask,
-				       int16_t      xDst,
-				       int16_t      yDst,
-				       uint16_t     width,
-				       uint16_t     height);
-void fbCompositeIn_nx8x8mmx (pixman_op_t	op,
-			pixman_image_t * pSrc,
-			pixman_image_t * pMask,
-			pixman_image_t * pDst,
-			int16_t      xSrc,
-			int16_t      ySrc,
-			int16_t      xMask,
-			int16_t      yMask,
-			int16_t      xDst,
-			int16_t      yDst,
-			uint16_t     width,
-			uint16_t     height);
-void fbCompositeIn_8x8mmx (pixman_op_t	op,
-		      pixman_image_t * pSrc,
-		      pixman_image_t * pMask,
-		      pixman_image_t * pDst,
-		      int16_t      xSrc,
-		      int16_t      ySrc,
-		      int16_t      xMask,
-		      int16_t      yMask,
-		      int16_t      xDst,
-		      int16_t      yDst,
-		      uint16_t     width,
-		      uint16_t     height);
-void fbCompositeSrcAdd_8888x8x8mmx (pixman_op_t   op,
-			       pixman_image_t * pSrc,
-			       pixman_image_t * pMask,
-			       pixman_image_t * pDst,
-			       int16_t      xSrc,
-			       int16_t      ySrc,
-			       int16_t      xMask,
-			       int16_t      yMask,
-			       int16_t      xDst,
-			       int16_t      yDst,
-			       uint16_t     width,
-			       uint16_t     height);
-void fbCompositeSrcAdd_8000x8000mmx (pixman_op_t	op,
-				     pixman_image_t * pSrc,
-				     pixman_image_t * pMask,
-				     pixman_image_t * pDst,
-				     int16_t      xSrc,
-				     int16_t      ySrc,
-				     int16_t      xMask,
-				     int16_t      yMask,
-				     int16_t      xDst,
-				     int16_t      yDst,
-				     uint16_t     width,
-				     uint16_t     height);
-void fbCompositeSrc_8888RevNPx8888mmx (pixman_op_t      op,
-				       pixman_image_t * pSrc,
-				       pixman_image_t * pMask,
-				       pixman_image_t * pDst,
-				       int16_t      xSrc,
-				       int16_t      ySrc,
-				       int16_t      xMask,
-				       int16_t      yMask,
-				       int16_t      xDst,
-				       int16_t      yDst,
-				       uint16_t     width,
-				       uint16_t     height);
-void fbCompositeSrc_8888x0565mmx (pixman_op_t      op,
-				  pixman_image_t * pSrc,
-				  pixman_image_t * pMask,
-				  pixman_image_t * pDst,
-				  int16_t      xSrc,
-				  int16_t      ySrc,
-				  int16_t      xMask,
-				  int16_t      yMask,
-				  int16_t      xDst,
-				  int16_t      yDst,
-				  uint16_t     width,
-				  uint16_t     height);
-void fbCompositeSrc_8888RevNPx0565mmx (pixman_op_t      op,
-				       pixman_image_t * pSrc,
-				       pixman_image_t * pMask,
-				       pixman_image_t * pDst,
-				       int16_t      xSrc,
-				       int16_t      ySrc,
-				       int16_t      xMask,
-				       int16_t      yMask,
-				       int16_t      xDst,
-				       int16_t      yDst,
-				       uint16_t     width,
-				       uint16_t     height);
-void fbCompositeSolid_nx8888mmx (pixman_op_t		op,
-				 pixman_image_t *	pSrc,
-				 pixman_image_t *	pMask,
-				 pixman_image_t *	pDst,
-				 int16_t		xSrc,
-				 int16_t		ySrc,
-				 int16_t		xMask,
-				 int16_t		yMask,
-				 int16_t		xDst,
-				 int16_t		yDst,
-				 uint16_t		width,
-				 uint16_t		height);
-void fbCompositeSolid_nx0565mmx (pixman_op_t		op,
-				 pixman_image_t *	pSrc,
-				 pixman_image_t *	pMask,
-				 pixman_image_t *	pDst,
-				 int16_t		xSrc,
-				 int16_t		ySrc,
-				 int16_t		xMask,
-				 int16_t		yMask,
-				 int16_t		xDst,
-				 int16_t		yDst,
-				 uint16_t		width,
-				 uint16_t		height);
-void fbCompositeSolidMask_nx8x0565mmx (pixman_op_t      op,
-				       pixman_image_t * pSrc,
-				       pixman_image_t * pMask,
-				       pixman_image_t * pDst,
-				       int16_t      xSrc,
-				       int16_t      ySrc,
-				       int16_t      xMask,
-				       int16_t      yMask,
-				       int16_t      xDst,
-				       int16_t      yDst,
-				       uint16_t     width,
-				       uint16_t     height);
-void fbCompositeSrc_8888x8x8888mmx (pixman_op_t	op,
-				    pixman_image_t *  pSrc,
-				    pixman_image_t *  pMask,
-				    pixman_image_t *  pDst,
-				    int16_t	xSrc,
-				    int16_t	ySrc,
-				    int16_t       xMask,
-				    int16_t       yMask,
-				    int16_t       xDst,
-				    int16_t       yDst,
-				    uint16_t      width,
-				    uint16_t      height);
 void fbCompositeCopyAreammx (pixman_op_t	op,
 			     pixman_image_t *	pSrc,
 			     pixman_image_t *	pMask,
@@ -303,19 +84,6 @@ void fbCompositeCopyAreammx (pixman_op_t	op,
 			     int16_t      yDst,
 			     uint16_t     width,
 			     uint16_t     height);
-void
-fbCompositeOver_x888x8x8888mmx (pixman_op_t      op,
-				pixman_image_t * pSrc,
-				pixman_image_t * pMask,
-				pixman_image_t * pDst,
-				int16_t      xSrc,
-				int16_t      ySrc,
-				int16_t      xMask,
-				int16_t      yMask,
-				int16_t      xDst,
-				int16_t      yDst,
-				uint16_t     width,
-				uint16_t     height);
 
 #endif /* USE_MMX */
 
commit 87f18154c1198752f2217241c568c28a103e69f6
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Tue May 5 09:07:32 2009 -0400

    Notes on component alpha

diff --git a/pixman/refactor b/pixman/refactor
index 9c05f20..52fceab 100644
--- a/pixman/refactor
+++ b/pixman/refactor
@@ -295,12 +295,6 @@ Possibly interesting additions:
 	  compositing, the whole thing ends up being equivalent to the
 	  output kernel from above.
 
-	- Glyph polygons
-
-	  If glyphs could be given as polygons, they could be
-	  positioned and rasterized more accurately. The glyph
-	  structure would need subpixel positioning though.
-
 	- Color space conversion
 
 	  The complete model here is that each surface has a color
@@ -316,6 +310,17 @@ Possibly interesting additions:
 	  with color spaces? Presumably dithering should happen in linear
 	  intensity space).
 
+	- Floating point surfaces, 16, 32 and possibly 64 bit per
+	  channel.
+
+	Maybe crack:
+
+	- Glyph polygons
+
+	  If glyphs could be given as polygons, they could be
+	  positioned and rasterized more accurately. The glyph
+	  structure would need subpixel positioning though.
+
 	- Luminance vs. coverage for the alpha channel
 
 	  Whether the alpha channel should be interpreted as luminance
@@ -324,8 +329,20 @@ Possibly interesting additions:
 	  also be considered whether it should be possible to have 
 	  both channels in the same drawable.
 
-	- Floating point surfaces, 16, 32 and possibly 64 bit per
-	  channel.
+	- Alternative for component alpha
+
+	  - Set component-alpha on the output image.
+
+	    - This means each of the components are sampled
+	      independently and composited in the corresponding
+	      channel only.
+
+	  - Have 3 x oversampled mask
+
+	  - Scale it down by 3 horizontally, with [ 1/3, 1/3, 1/3 ]
+            resampling filter. 
+
+	    Is this equivalent to just using a component alpha mask?
 
 	Incompatible changes:
 
commit ac2299693f76be9c0d19a015096497d26aaf2c7d
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Tue May 5 08:49:49 2009 -0400

    Note about glyphs polygons

diff --git a/pixman/refactor b/pixman/refactor
index 7a7290e..9c05f20 100644
--- a/pixman/refactor
+++ b/pixman/refactor
@@ -295,6 +295,12 @@ Possibly interesting additions:
 	  compositing, the whole thing ends up being equivalent to the
 	  output kernel from above.
 
+	- Glyph polygons
+
+	  If glyphs could be given as polygons, they could be
+	  positioned and rasterized more accurately. The glyph
+	  structure would need subpixel positioning though.
+
 	- Color space conversion
 
 	  The complete model here is that each surface has a color
commit c093ee8a415602d78b53dbe936ca743ed816d393
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Tue May 5 07:31:52 2009 -0400

    Notes on output kernels

diff --git a/pixman/refactor b/pixman/refactor
index f7ac86d..7a7290e 100644
--- a/pixman/refactor
+++ b/pixman/refactor
@@ -276,6 +276,25 @@ Possibly interesting additions:
 	  will need to deal with the fact that the resampling kernel
 	  will not necessarily be pixel aligned.
 
+	  "Output kernels"
+
+	  One could imagine doing the resampling after compositing,
+	  ie., for each destination pixel sample each source image 16
+	  times, then composite those subpixels individually, then
+	  finally apply a kernel.
+
+	  However, this is effectively the same as full screen
+	  antialiasing, which is a simpler way to think about it. So
+	  resampling kernels may make sense for individual images, but
+	  not as a post-compositing step.
+	  
+	  Fullscreen AA is inefficient without chained compositing
+	  though. Consider an (image scaled up to oversample size IN
+	  some polygon) scaled down to screen size. With the current
+	  implementation, there will be a huge temporary. With chained
+	  compositing, the whole thing ends up being equivalent to the
+	  output kernel from above.
+
 	- Color space conversion
 
 	  The complete model here is that each surface has a color
commit 90ae09f2e4826d21ebab21c6538cfa7fe1e0b90b
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Tue May 5 03:10:44 2009 -0400

    Further notes on the rendering pipeline

diff --git a/pixman/refactor b/pixman/refactor
index 91cbf5a..f7ac86d 100644
--- a/pixman/refactor
+++ b/pixman/refactor
@@ -198,21 +198,28 @@ Rendering pipeline:
 Drawable:
 	0. if (picture has alpha map)
 		0.1. Position alpha map according to the alpha_x/alpha_y
-	        0.2. Replace the alpha channel of source with the one
-		     from the alpha map. Outside the geometry of the alpha
-		     map no replacement takes place.
-		(FIXME: should this be "... the alpha channel is 0"?)
+	        0.2. Where the two drawables intersect, the alpha channel
+		     Replace the alpha channel of source with the one
+		     from the alpha map. Replacement only takes place
+		     in the intersection of the two drawables' geometries.
 	1. Repeat the drawable according to the repeat attribute
 	2. Reconstruct a continuous image according to the filter
 	3. Transform according to the transform attribute
 	4. Position image such that src_x, src_y is over dst_x, dst_y
-	5. Clip. If a pixel is not in the source clip, then no
-	   compositing takes place at that pixel. (Ie., it's not
+	5. Sample once per destination pixel 
+	6. Clip. If a pixel is not within the source clip, then no
+	   compositing takes place at that pixel. (Ie., it's *not*
 	   treated as 0).
-	6. Sample once per destination pixel 
 
-	Note that the top left sample in a drawable has coordinates
-	(0.5, 0.5).
+	Sampling a drawable: 
+
+	- If the channel does not have an alpha channel, the pixels in it
+	  are treated as opaque.
+
+	Note on reconstruction:
+
+	- The top left pixel has coordinates (0.5, 0.5) and pixels are
+	  spaced 1 apart.
 
 Gradient:
 	1. Unless gradient type is conical, repeat the underlying (0, 1)
@@ -220,24 +227,24 @@ Gradient:
 	2. Integrate the gradient across the plane according to type.
 	3. Transform according to transform attribute
 	4. Position gradient 
-	5. Clip
-	6. Sample once per destination pixel.
+	5. Sample once per destination pixel.
+ 	6. Clip
 
 Solid Fill:
 	1. Repeat has no effect
 	2. Image is already continuous and defined for the entire plane
 	3. Transform has no effect
 	4. Positioning has no effect
-	5. Clip
-	6. Sample once per destination pixel.
+	5. Sample once per destination pixel.
+	6. Clip
 
 Polygon:
 	1. Repeat has no effect
 	2. Image is already continuous and defined on the whole plane
 	3. Transform according to transform attribute
 	4. Position image
-	5. Clip
-	6. Supersample 15x17 per destination pixel.
+	5. Supersample 15x17 per destination pixel.
+	6. Clip
 
 Possibly interesting additions:
 	- More general transformations, such as warping, or general
@@ -261,22 +268,45 @@ Possibly interesting additions:
 
 	  (Note that the difference between a reconstruction and a
 	  resampling filter is mainly where in the pipeline they
-	  occur. High quality resampling should use correctly oriented
-	  kernel so it should happen after transformation. 
+	  occur. High quality resampling should use a correctly
+	  oriented kernel so it should happen after transformation.
 
 	  An implementation can transform the resampling kernel and
 	  convolve it with the reconstruction if it so desires, but it
 	  will need to deal with the fact that the resampling kernel
 	  will not necessarily be pixel aligned.
 
+	- Color space conversion
+
+	  The complete model here is that each surface has a color
+	  space associated with it and that the compositing operation
+	  also has one associated with it. Note also that gradients
+	  should have associcated colorspaces.
+
 	- Dithering
 
 	  If people dither something that is already dithered, it will
-	  look terrible, but don't do that, then.
+	  look terrible, but don't do that, then. (Dithering happens
+	  after resampling if at all - what is the relationship
+	  with color spaces? Presumably dithering should happen in linear
+	  intensity space).
+
+	- Luminance vs. coverage for the alpha channel
+
+	  Whether the alpha channel should be interpreted as luminance
+          modulation or as coverage (intensity modulation). This is a
+          bit of a departure from the rendering model though. It could
+	  also be considered whether it should be possible to have 
+	  both channels in the same drawable.
+
+	- Floating point surfaces, 16, 32 and possibly 64 bit per
+	  channel.
+
+	Incompatible changes:
 
-	- Whether the alpha channel should be interpreted as luminance
-          modulation or as coverage (intensity modulation).  This is a
-          bit of a departure from the rendering model though.
+	- Gradients could be specified with premultiplied colors. (You
+	  can use a mask to get things like gradients from solid red to
+	  transparent red.
 
 Refactoring pixman
 
commit fa274ffc6180fc0d57f11bf7b691fe95f344c5d9
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Tue May 5 01:58:48 2009 -0400

    Some roadmap notes

diff --git a/pixman/refactor b/pixman/refactor
index 93e7533..91cbf5a 100644
--- a/pixman/refactor
+++ b/pixman/refactor
@@ -1,5 +1,40 @@
 Roadmap
 
+- Move all the fetchers etc. into pixman-image to make pixman-compose.c
+  less intimidating.
+
+  DONE
+
+- Make combiners for unified alpha take a mask argument. That way
+  we won't need two separate paths for unified vs component in the
+  general compositing code.
+
+  DONE, except that the Altivec code needs to be updated. Luca is
+  looking into that.
+
+- Delete separate 'unified alpha' path
+ 
+  DONE
+
+- Split images into their own files
+
+  DONE
+
+- Split the gradient walker code out into its own file
+
+  DONE
+
+- Add scanline getters per image
+
+  DONE
+
+- Generic 64 bit fetcher 
+
+  DONE
+
+- Split fast path tables into their respective architecture dependent
+  files.
+
 See "Render Algorithm" below for rationale
 
 Images will eventually have these virtual functions:
commit ba1dcec76ae1033b0cbb3048c3d82450922a02cc
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Mon May 4 17:39:19 2009 -0400

    Describe alpha map in the pipeline

diff --git a/pixman/refactor b/pixman/refactor
index 4cc18d0..93e7533 100644
--- a/pixman/refactor
+++ b/pixman/refactor
@@ -18,7 +18,7 @@ Images will eventually have these virtual functions:
 
 1.
 
-Initially we will jsut have get_scanline() and get_scanline_wide();
+Initially we will just have get_scanline() and get_scanline_wide();
 these will be based on the ones in pixman-compose. Hopefully this will
 reduce the complexity in pixman_composite_rect_general().
 
@@ -161,12 +161,19 @@ will just call expand, except for 10 bit formats.
 Rendering pipeline:
 
 Drawable:
+	0. if (picture has alpha map)
+		0.1. Position alpha map according to the alpha_x/alpha_y
+	        0.2. Replace the alpha channel of source with the one
+		     from the alpha map. Outside the geometry of the alpha
+		     map no replacement takes place.
+		(FIXME: should this be "... the alpha channel is 0"?)
 	1. Repeat the drawable according to the repeat attribute
 	2. Reconstruct a continuous image according to the filter
 	3. Transform according to the transform attribute
 	4. Position image such that src_x, src_y is over dst_x, dst_y
-	5. If a pixel is not in the source clip, then no compositing
-	   takes place there.
+	5. Clip. If a pixel is not in the source clip, then no
+	   compositing takes place at that pixel. (Ie., it's not
+	   treated as 0).
 	6. Sample once per destination pixel 
 
 	Note that the top left sample in a drawable has coordinates
commit 3fdefd683b5cbaaa4a93f1737197954f1df8bc57
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Sun May 3 22:46:34 2009 -0400

    Notes on the rendering pipeline

diff --git a/pixman/refactor b/pixman/refactor
index c887539..4cc18d0 100644
--- a/pixman/refactor
+++ b/pixman/refactor
@@ -37,8 +37,6 @@ reinit() call.  Call this whenever a property of the image changes.
 Split the get_scanline() call into smaller functions that are
 initialized by the reinit() call.
 
-
-
 The Render Algorithm:
 	(first repeat, then filter, then transform, then clip)
 
@@ -160,6 +158,84 @@ There will also be wide fetchers for both pixels and lines. The line
 fetcher will just call the wide pixel fetcher. The wide pixel fetcher
 will just call expand, except for 10 bit formats.
 
+Rendering pipeline:
+
+Drawable:
+	1. Repeat the drawable according to the repeat attribute
+	2. Reconstruct a continuous image according to the filter
+	3. Transform according to the transform attribute
+	4. Position image such that src_x, src_y is over dst_x, dst_y
+	5. If a pixel is not in the source clip, then no compositing
+	   takes place there.
+	6. Sample once per destination pixel 
+
+	Note that the top left sample in a drawable has coordinates
+	(0.5, 0.5).
+
+Gradient:
+	1. Unless gradient type is conical, repeat the underlying (0, 1)
+		gradient according to the repeat attribute
+	2. Integrate the gradient across the plane according to type.
+	3. Transform according to transform attribute
+	4. Position gradient 
+	5. Clip
+	6. Sample once per destination pixel.
+
+Solid Fill:
+	1. Repeat has no effect
+	2. Image is already continuous and defined for the entire plane
+	3. Transform has no effect
+	4. Positioning has no effect
+	5. Clip
+	6. Sample once per destination pixel.
+
+Polygon:
+	1. Repeat has no effect
+	2. Image is already continuous and defined on the whole plane
+	3. Transform according to transform attribute
+	4. Position image
+	5. Clip
+	6. Supersample 15x17 per destination pixel.
+
+Possibly interesting additions:
+	- More general transformations, such as warping, or general
+	  shading.
+
+	- Shader image where a function is called to generate the
+          pixel (ie., uploading assembly code).
+
+	- Resampling kernels
+
+	  In principle the polygon image uses a 15x17 box filter for
+	  resampling. If we allow general resampling filters, then we
+	  get all the various antialiasing types for free. 
+
+	  Bilinear downsampling looks terrible and could be much 
+	  improved by a resampling filter. NEAREST reconstruction
+	  combined with a box resampling filter is what GdkPixbuf
+	  does, I believe.
+
+	  Useful for high frequency gradients as well.
+
+	  (Note that the difference between a reconstruction and a
+	  resampling filter is mainly where in the pipeline they
+	  occur. High quality resampling should use correctly oriented
+	  kernel so it should happen after transformation. 
+
+	  An implementation can transform the resampling kernel and
+	  convolve it with the reconstruction if it so desires, but it
+	  will need to deal with the fact that the resampling kernel
+	  will not necessarily be pixel aligned.
+
+	- Dithering
+
+	  If people dither something that is already dithered, it will
+	  look terrible, but don't do that, then.
+
+	- Whether the alpha channel should be interpreted as luminance
+          modulation or as coverage (intensity modulation).  This is a
+          bit of a departure from the rendering model though.
+
 Refactoring pixman
 
 The pixman code is not particularly nice to put it mildly. Among the
commit e07a4c6e8c1571f762c6f583204f16e3aca42882
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Sun May 3 21:07:06 2009 -0400

    Move C fast paths to their own file pixman-fast-path.c

diff --git a/pixman/Makefile.am b/pixman/Makefile.am
index ea5ec67..b55daa0 100644
--- a/pixman/Makefile.am
+++ b/pixman/Makefile.am
@@ -2,36 +2,37 @@ lib_LTLIBRARIES = libpixman-1.la
 libpixman_1_la_LDFLAGS = -version-info $(LT_VERSION_INFO) -no-undefined
 libpixman_1_la_LIBADD = @DEP_LIBS@ -lm
 libpixman_1_la_CFLAGS = -DPIXMAN_DISABLE_DEPRECATED
-libpixman_1_la_SOURCES =		\
-	pixman.h			\
-	pixman-access.c			\
-	pixman-access-accessors.c	\
-	pixman-cpu.c			\
-	pixman-gradient-walker.c	\
-	pixman-region16.c		\
-	pixman-region32.c		\
-	pixman-private.h		\
-	pixman-image.c			\
-	pixman-combine32.c		\
-	pixman-combine32.h		\
-	pixman-combine64.c		\
-	pixman-combine64.h		\
-	pixman-compose.c		\
-	pixman-pict.c			\
-	pixman-solid-fill.c		\
-	pixman-conical-gradient.c	\
-	pixman-linear-gradient.c	\
-	pixman-radial-gradient.c	\
-	pixman-bits-image.c		\
-	pixman-transformed.c		\
-	pixman-transformed-accessors.c	\
-	pixman-utils.c			\
-	pixman-edge.c			\
-	pixman-edge-accessors.c		\
-	pixman-edge-imp.h		\
-	pixman-trap.c			\
-	pixman-compute-region.c		\
-	pixman-timer.c			\
+libpixman_1_la_SOURCES =			\
+	pixman.h				\
+	pixman-access.c				\
+	pixman-access-accessors.c		\
+	pixman-cpu.c				\
+	pixman-gradient-walker.c		\
+	pixman-region16.c			\
+	pixman-region32.c			\
+	pixman-private.h			\
+	pixman-image.c				\
+	pixman-combine32.c			\
+	pixman-combine32.h			\
+	pixman-combine64.c			\
+	pixman-combine64.h			\
+	pixman-compose.c			\
+	pixman-pict.c				\
+	pixman-fast-path.c			\
+	pixman-solid-fill.c			\
+	pixman-conical-gradient.c		\
+	pixman-linear-gradient.c		\
+	pixman-radial-gradient.c		\
+	pixman-bits-image.c			\
+	pixman-transformed.c			\
+	pixman-transformed-accessors.c		\
+	pixman-utils.c				\
+	pixman-edge.c				\
+	pixman-edge-accessors.c			\
+	pixman-edge-imp.h			\
+	pixman-trap.c				\
+	pixman-compute-region.c			\
+	pixman-timer.c				\
 	pixman-matrix.c
 
 libpixmanincludedir = $(includedir)/pixman-1/
diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c
new file mode 100644
index 0000000..f7f6f19
--- /dev/null
+++ b/pixman/pixman-fast-path.c
@@ -0,0 +1,1056 @@
+/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */
+/*
+ * Copyright © 2000 SuSE, Inc.
+ * Copyright © 2007 Red Hat, Inc.
+ *
+ * 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ *
+ * Author:  Keith Packard, SuSE, Inc.
+ */
+
+#include <config.h>
+#include <string.h>
+#include "pixman-private.h"
+#include "pixman-combine32.h"
+#define FbFullMask(n)   ((n) == 32 ? (uint32_t)-1 : ((((uint32_t) 1) << n) - 1))
+
+#undef READ
+#undef WRITE
+#define READ(img,x) (*(x))
+#define WRITE(img,ptr,v) ((*(ptr)) = (v))
+
+static force_inline uint32_t
+fbOver (uint32_t src, uint32_t dest)
+{
+    // dest = (dest * (255 - alpha)) / 255 + src
+    uint32_t a = ~src >> 24; // 255 - alpha == 255 + (~alpha + 1) == ~alpha
+    FbByteMulAdd(dest, a, src);
+
+    return dest;
+}
+
+static uint32_t
+fbOver24 (uint32_t x, uint32_t y)
+{
+    uint16_t  a = ~x >> 24;
+    uint16_t  t;
+    uint32_t  m,n,o;
+
+    m = FbOverU(x,y,0,a,t);
+    n = FbOverU(x,y,8,a,t);
+    o = FbOverU(x,y,16,a,t);
+    return m|n|o;
+}
+
+static uint32_t
+fbIn (uint32_t x, uint8_t y)
+{
+    uint16_t  a = y;
+    uint16_t  t;
+    uint32_t  m,n,o,p;
+
+    m = FbInU(x,0,a,t);
+    n = FbInU(x,8,a,t);
+    o = FbInU(x,16,a,t);
+    p = FbInU(x,24,a,t);
+    return m|n|o|p;
+}
+
+/*
+ * Naming convention:
+ *
+ *  opSRCxMASKxDST
+ */
+
+static void
+fbCompositeOver_x888x8x8888 (pixman_op_t      op,
+			     pixman_image_t * pSrc,
+			     pixman_image_t * pMask,
+			     pixman_image_t * pDst,
+			     int16_t      xSrc,
+			     int16_t      ySrc,
+			     int16_t      xMask,
+			     int16_t      yMask,
+			     int16_t      xDst,
+			     int16_t      yDst,
+			     uint16_t     width,
+			     uint16_t     height)
+{
+    uint32_t	*src, *srcLine;
+    uint32_t    *dst, *dstLine;
+    uint8_t	*mask, *maskLine;
+    int		 srcStride, maskStride, dstStride;
+    uint8_t m;
+    uint32_t s, d;
+    uint16_t w;
+
+    fbComposeGetStart (pDst, xDst, yDst, uint32_t, dstStride, dstLine, 1);
+    fbComposeGetStart (pMask, xMask, yMask, uint8_t, maskStride, maskLine, 1);
+    fbComposeGetStart (pSrc, xSrc, ySrc, uint32_t, srcStride, srcLine, 1);
+
+    while (height--)
+    {
+	src = srcLine;
+	srcLine += srcStride;
+	dst = dstLine;
+	dstLine += dstStride;
+	mask = maskLine;
+	maskLine += maskStride;
+
+	w = width;
+	while (w--)
+	{
+	    m = READ(pMask, mask++);
+	    if (m)
+	    {
+		s = READ(pSrc, src) | 0xff000000;
+
+		if (m == 0xff)
+		    WRITE(pDst, dst, s);
+		else
+		{
+		    d = fbIn (s, m);
+		    WRITE(pDst, dst, fbOver (d, READ(pDst, dst)));
+		}
+	    }
+	    src++;
+	    dst++;
+	}
+    }
+}
+
+static void
+fbCompositeSolidMaskIn_nx8x8 (pixman_op_t      op,
+			      pixman_image_t    *iSrc,
+			      pixman_image_t    *iMask,
+			      pixman_image_t    *iDst,
+			      int16_t      xSrc,
+			      int16_t      ySrc,
+			      int16_t      xMask,
+			      int16_t      yMask,
+			      int16_t      xDst,
+			      int16_t      yDst,
+			      uint16_t     width,
+			      uint16_t     height)
+{
+    uint32_t	src, srca;
+    uint8_t	*dstLine, *dst, dstMask;
+    uint8_t	*maskLine, *mask, m;
+    int	dstStride, maskStride;
+    uint16_t	w;
+    uint16_t    t;
+
+    fbComposeGetSolid(iSrc, src, iDst->bits.format);
+
+    dstMask = FbFullMask (PIXMAN_FORMAT_DEPTH (iDst->bits.format));
+    srca = src >> 24;
+
+    fbComposeGetStart (iDst, xDst, yDst, uint8_t, dstStride, dstLine, 1);
+    fbComposeGetStart (iMask, xMask, yMask, uint8_t, maskStride, maskLine, 1);
+
+    if (srca == 0xff) {
+	while (height--)
+	{
+	    dst = dstLine;
+	    dstLine += dstStride;
+	    mask = maskLine;
+	    maskLine += maskStride;
+	    w = width;
+
+	    while (w--)
+	    {
+		m = *mask++;
+		if (m == 0)
+		{
+		    *dst = 0;
+		}
+		else if (m != 0xff)
+		{
+		    *dst = FbIntMult(m, *dst, t);
+		}
+		dst++;
+	    }
+	}
+    }
+    else
+    {
+	while (height--)
+	{
+	    dst = dstLine;
+	    dstLine += dstStride;
+	    mask = maskLine;
+	    maskLine += maskStride;
+	    w = width;
+
+	    while (w--)
+	    {
+		m = *mask++;
+		m = FbIntMult(m, srca, t);
+		if (m == 0)
+		{
+		    *dst = 0;
+		}
+		else if (m != 0xff)
+		{
+		    *dst = FbIntMult(m, *dst, t);
+		}
+		dst++;
+	    }
+	}
+    }
+}
+
+
+static void
+fbCompositeSrcIn_8x8 (pixman_op_t      op,
+		      pixman_image_t  *iSrc,
+		      pixman_image_t  *iMask,
+		      pixman_image_t  *iDst,
+		      int16_t          xSrc,
+		      int16_t          ySrc,
+		      int16_t          xMask,
+		      int16_t          yMask,
+		      int16_t          xDst,
+		      int16_t          yDst,
+		      uint16_t         width,
+		      uint16_t         height)
+{
+    uint8_t	*dstLine, *dst;
+    uint8_t	*srcLine, *src;
+    int	dstStride, srcStride;
+    uint16_t	w;
+    uint8_t	s;
+    uint16_t	t;
+
+    fbComposeGetStart (iSrc, xSrc, ySrc, uint8_t, srcStride, srcLine, 1);
+    fbComposeGetStart (iDst, xDst, yDst, uint8_t, dstStride, dstLine, 1);
+
+    while (height--)
+    {
+	dst = dstLine;
+	dstLine += dstStride;
+	src = srcLine;
+	srcLine += srcStride;
+	w = width;
+
+	while (w--)
+	{
+	    s = *src++;
+	    if (s == 0)
+	    {
+		*dst = 0;
+	    }
+	    else if (s != 0xff)
+	    {
+		*dst = FbIntMult(s, *dst, t);
+	    }
+	    dst++;
+	}
+    }
+}
+
+static void
+fbCompositeSolidMask_nx8x8888 (pixman_op_t      op,
+			       pixman_image_t * pSrc,
+			       pixman_image_t * pMask,
+			       pixman_image_t * pDst,
+			       int16_t      xSrc,
+			       int16_t      ySrc,
+			       int16_t      xMask,
+			       int16_t      yMask,
+			       int16_t      xDst,
+			       int16_t      yDst,
+			       uint16_t     width,
+			       uint16_t     height)
+{
+    uint32_t	 src, srca;
+    uint32_t	*dstLine, *dst, d, dstMask;
+    uint8_t	*maskLine, *mask, m;
+    int		 dstStride, maskStride;
+    uint16_t	 w;
+
+    fbComposeGetSolid(pSrc, src, pDst->bits.format);
+
+    dstMask = FbFullMask (PIXMAN_FORMAT_DEPTH (pDst->bits.format));
+    srca = src >> 24;
+    if (src == 0)
+	return;
+
+    fbComposeGetStart (pDst, xDst, yDst, uint32_t, dstStride, dstLine, 1);
+    fbComposeGetStart (pMask, xMask, yMask, uint8_t, maskStride, maskLine, 1);
+
+    while (height--)
+    {
+	dst = dstLine;
+	dstLine += dstStride;
+	mask = maskLine;
+	maskLine += maskStride;
+	w = width;
+
+	while (w--)
+	{
+	    m = READ(pMask, mask++);
+	    if (m == 0xff)
+	    {
+		if (srca == 0xff)
+		    WRITE(pDst, dst, src & dstMask);
+		else
+		    WRITE(pDst, dst, fbOver (src, READ(pDst, dst)) & dstMask);
+	    }
+	    else if (m)
+	    {
+		d = fbIn (src, m);
+		WRITE(pDst, dst, fbOver (d, READ(pDst, dst)) & dstMask);
+	    }
+	    dst++;
+	}
+    }
+}
+
+static void
+fbCompositeSolidMask_nx8888x8888C (pixman_op_t op,
+				   pixman_image_t * pSrc,
+				   pixman_image_t * pMask,
+				   pixman_image_t * pDst,
+				   int16_t      xSrc,
+				   int16_t      ySrc,
+				   int16_t      xMask,
+				   int16_t      yMask,
+				   int16_t      xDst,
+				   int16_t      yDst,
+				   uint16_t     width,
+				   uint16_t     height)
+{
+    uint32_t	src, srca;
+    uint32_t	*dstLine, *dst, d, dstMask;
+    uint32_t	*maskLine, *mask, ma;
+    int	dstStride, maskStride;
+    uint16_t	w;
+    uint32_t	m, n, o, p;
+
+    fbComposeGetSolid(pSrc, src, pDst->bits.format);
+
+    dstMask = FbFullMask (PIXMAN_FORMAT_DEPTH (pDst->bits.format));
+    srca = src >> 24;
+    if (src == 0)
+	return;
+
+    fbComposeGetStart (pDst, xDst, yDst, uint32_t, dstStride, dstLine, 1);
+    fbComposeGetStart (pMask, xMask, yMask, uint32_t, maskStride, maskLine, 1);
+
+    while (height--)
+    {
+	dst = dstLine;
+	dstLine += dstStride;
+	mask = maskLine;
+	maskLine += maskStride;
+	w = width;
+
+	while (w--)
+	{
+	    ma = READ(pMask, mask++);
+	    if (ma == 0xffffffff)
+	    {
+		if (srca == 0xff)
+		    WRITE(pDst, dst, src & dstMask);
+		else
+		    WRITE(pDst, dst, fbOver (src, READ(pDst, dst)) & dstMask);
+	    }
+	    else if (ma)
+	    {
+		d = READ(pDst, dst);
+#define FbInOverC(src,srca,msk,dst,i,result) { \
+    uint16_t  __a = FbGet8(msk,i); \
+    uint32_t  __t, __ta; \
+    uint32_t  __i; \
+    __t = FbIntMult (FbGet8(src,i), __a,__i); \
+    __ta = (uint8_t) ~FbIntMult (srca, __a,__i); \
+    __t = __t + FbIntMult(FbGet8(dst,i),__ta,__i); \
+    __t = (uint32_t) (uint8_t) (__t | (-(__t >> 8))); \
+    result = __t << (i); \
+}
+		FbInOverC (src, srca, ma, d, 0, m);
+		FbInOverC (src, srca, ma, d, 8, n);
+		FbInOverC (src, srca, ma, d, 16, o);
+		FbInOverC (src, srca, ma, d, 24, p);
+		WRITE(pDst, dst, m|n|o|p);
+	    }
+	    dst++;
+	}
+    }
+}
+
+static void
+fbCompositeSolidMask_nx8x0888 (pixman_op_t op,
+			       pixman_image_t * pSrc,
+			       pixman_image_t * pMask,
+			       pixman_image_t * pDst,
+			       int16_t      xSrc,
+			       int16_t      ySrc,
+			       int16_t      xMask,
+			       int16_t      yMask,
+			       int16_t      xDst,
+			       int16_t      yDst,
+			       uint16_t     width,
+			       uint16_t     height)
+{
+    uint32_t	src, srca;
+    uint8_t	*dstLine, *dst;
+    uint32_t	d;
+    uint8_t	*maskLine, *mask, m;
+    int	dstStride, maskStride;
+    uint16_t	w;
+
+    fbComposeGetSolid(pSrc, src, pDst->bits.format);
+
+    srca = src >> 24;
+    if (src == 0)
+	return;
+
+    fbComposeGetStart (pDst, xDst, yDst, uint8_t, dstStride, dstLine, 3);
+    fbComposeGetStart (pMask, xMask, yMask, uint8_t, maskStride, maskLine, 1);
+
+    while (height--)
+    {
+	dst = dstLine;
+	dstLine += dstStride;
+	mask = maskLine;
+	maskLine += maskStride;
+	w = width;
+
+	while (w--)
+	{
+	    m = READ(pMask, mask++);
+	    if (m == 0xff)
+	    {
+		if (srca == 0xff)
+		    d = src;
+		else
+		{
+		    d = Fetch24(pDst, dst);
+		    d = fbOver24 (src, d);
+		}
+		Store24(pDst, dst,d);
+	    }
+	    else if (m)
+	    {
+		d = fbOver24 (fbIn(src,m), Fetch24(pDst, dst));
+		Store24(pDst, dst, d);
+	    }
+	    dst += 3;
+	}
+    }
+}
+
+static void
+fbCompositeSolidMask_nx8x0565 (pixman_op_t op,
+				  pixman_image_t * pSrc,
+				  pixman_image_t * pMask,
+				  pixman_image_t * pDst,
+				  int16_t      xSrc,
+				  int16_t      ySrc,
+				  int16_t      xMask,
+				  int16_t      yMask,
+				  int16_t      xDst,
+				  int16_t      yDst,
+				  uint16_t     width,
+				  uint16_t     height)
+{
+    uint32_t	src, srca;
+    uint16_t	*dstLine, *dst;
+    uint32_t	d;
+    uint8_t	*maskLine, *mask, m;
+    int	dstStride, maskStride;
+    uint16_t	w;
+
+    fbComposeGetSolid(pSrc, src, pDst->bits.format);
+
+    srca = src >> 24;
+    if (src == 0)
+	return;
+
+    fbComposeGetStart (pDst, xDst, yDst, uint16_t, dstStride, dstLine, 1);
+    fbComposeGetStart (pMask, xMask, yMask, uint8_t, maskStride, maskLine, 1);
+
+    while (height--)
+    {
+	dst = dstLine;
+	dstLine += dstStride;
+	mask = maskLine;
+	maskLine += maskStride;
+	w = width;
+
+	while (w--)
+	{
+	    m = READ(pMask, mask++);
+	    if (m == 0xff)
+	    {
+		if (srca == 0xff)
+		    d = src;
+		else
+		{
+		    d = READ(pDst, dst);
+		    d = fbOver24 (src, cvt0565to0888(d));
+		}
+		WRITE(pDst, dst, cvt8888to0565(d));
+	    }
+	    else if (m)
+	    {
+		d = READ(pDst, dst);
+		d = fbOver24 (fbIn(src,m), cvt0565to0888(d));
+		WRITE(pDst, dst, cvt8888to0565(d));
+	    }
+	    dst++;
+	}
+    }
+}
+
+static void
+fbCompositeSolidMask_nx8888x0565C (pixman_op_t op,
+				   pixman_image_t * pSrc,
+				   pixman_image_t * pMask,
+				   pixman_image_t * pDst,
+				   int16_t      xSrc,
+				   int16_t      ySrc,
+				   int16_t      xMask,
+				   int16_t      yMask,
+				   int16_t      xDst,
+				   int16_t      yDst,
+				   uint16_t     width,
+				   uint16_t     height)
+{
+    uint32_t	src, srca;
+    uint16_t	src16;
+    uint16_t	*dstLine, *dst;
+    uint32_t	d;
+    uint32_t	*maskLine, *mask, ma;
+    int	dstStride, maskStride;
+    uint16_t	w;
+    uint32_t	m, n, o;
+
+    fbComposeGetSolid(pSrc, src, pDst->bits.format);
+
+    srca = src >> 24;
+    if (src == 0)
+	return;
+
+    src16 = cvt8888to0565(src);
+
+    fbComposeGetStart (pDst, xDst, yDst, uint16_t, dstStride, dstLine, 1);
+    fbComposeGetStart (pMask, xMask, yMask, uint32_t, maskStride, maskLine, 1);
+
+    while (height--)
+    {
+	dst = dstLine;
+	dstLine += dstStride;
+	mask = maskLine;
+	maskLine += maskStride;
+	w = width;
+
+	while (w--)
+	{
+	    ma = READ(pMask, mask++);
+	    if (ma == 0xffffffff)
+	    {
+		if (srca == 0xff)
+		{
+		    WRITE(pDst, dst, src16);
+		}
+		else
+		{
+		    d = READ(pDst, dst);
+		    d = fbOver24 (src, cvt0565to0888(d));
+		    WRITE(pDst, dst, cvt8888to0565(d));
+		}
+	    }
+	    else if (ma)
+	    {
+		d = READ(pDst, dst);
+		d = cvt0565to0888(d);
+		FbInOverC (src, srca, ma, d, 0, m);
+		FbInOverC (src, srca, ma, d, 8, n);
+		FbInOverC (src, srca, ma, d, 16, o);
+		d = m|n|o;
+		WRITE(pDst, dst, cvt8888to0565(d));
+	    }
+	    dst++;
+	}
+    }
+}
+
+static void
+fbCompositeSrc_8888x8888 (pixman_op_t op,
+			 pixman_image_t * pSrc,
+			 pixman_image_t * pMask,
+			 pixman_image_t * pDst,
+			 int16_t      xSrc,
+			 int16_t      ySrc,
+			 int16_t      xMask,
+			 int16_t      yMask,
+			 int16_t      xDst,
+			 int16_t      yDst,
+			 uint16_t     width,
+			 uint16_t     height)
+{
+    uint32_t	*dstLine, *dst, dstMask;
+    uint32_t	*srcLine, *src, s;
+    int	dstStride, srcStride;
+    uint8_t	a;
+    uint16_t	w;
+
+    fbComposeGetStart (pDst, xDst, yDst, uint32_t, dstStride, dstLine, 1);
+    fbComposeGetStart (pSrc, xSrc, ySrc, uint32_t, srcStride, srcLine, 1);
+
+    dstMask = FbFullMask (PIXMAN_FORMAT_DEPTH (pDst->bits.format));
+
+    while (height--)
+    {
+	dst = dstLine;
+	dstLine += dstStride;
+	src = srcLine;
+	srcLine += srcStride;
+	w = width;
+
+	while (w--)
+	{
+	    s = READ(pSrc, src++);
+	    a = s >> 24;
+	    if (a == 0xff)
+		WRITE(pDst, dst, s & dstMask);
+	    else if (s)
+		WRITE(pDst, dst, fbOver (s, READ(pDst, dst)) & dstMask);
+	    dst++;
+	}
+    }
+}
+
+static void
+fbCompositeSrc_8888x0888 (pixman_op_t op,
+			 pixman_image_t * pSrc,
+			 pixman_image_t * pMask,
+			 pixman_image_t * pDst,
+			 int16_t      xSrc,
+			 int16_t      ySrc,
+			 int16_t      xMask,
+			 int16_t      yMask,
+			 int16_t      xDst,
+			 int16_t      yDst,
+			 uint16_t     width,
+			 uint16_t     height)
+{
+    uint8_t	*dstLine, *dst;
+    uint32_t	d;
+    uint32_t	*srcLine, *src, s;
+    uint8_t	a;
+    int	dstStride, srcStride;
+    uint16_t	w;
+
+    fbComposeGetStart (pDst, xDst, yDst, uint8_t, dstStride, dstLine, 3);
+    fbComposeGetStart (pSrc, xSrc, ySrc, uint32_t, srcStride, srcLine, 1);
+
+    while (height--)
+    {
+	dst = dstLine;
+	dstLine += dstStride;
+	src = srcLine;
+	srcLine += srcStride;
+	w = width;
+
+	while (w--)
+	{
+	    s = READ(pSrc, src++);
+	    a = s >> 24;
+	    if (a)
+	    {
+		if (a == 0xff)
+		    d = s;
+		else
+		    d = fbOver24 (s, Fetch24(pDst, dst));
+		Store24(pDst, dst, d);
+	    }
+	    dst += 3;
+	}
+    }
+}
+
+static void
+fbCompositeSrc_8888x0565 (pixman_op_t op,
+			 pixman_image_t * pSrc,
+			 pixman_image_t * pMask,
+			 pixman_image_t * pDst,
+			 int16_t      xSrc,
+			 int16_t      ySrc,
+			 int16_t      xMask,
+			 int16_t      yMask,
+			 int16_t      xDst,
+			 int16_t      yDst,
+			 uint16_t     width,
+			 uint16_t     height)
+{
+    uint16_t	*dstLine, *dst;
+    uint32_t	d;
+    uint32_t	*srcLine, *src, s;
+    uint8_t	a;
+    int	dstStride, srcStride;
+    uint16_t	w;
+
+    fbComposeGetStart (pSrc, xSrc, ySrc, uint32_t, srcStride, srcLine, 1);
+    fbComposeGetStart (pDst, xDst, yDst, uint16_t, dstStride, dstLine, 1);
+
+    while (height--)
+    {
+	dst = dstLine;
+	dstLine += dstStride;
+	src = srcLine;
+	srcLine += srcStride;
+	w = width;
+
+	while (w--)
+	{
+	    s = READ(pSrc, src++);
+	    a = s >> 24;
+	    if (s)
+	    {
+		if (a == 0xff)
+		    d = s;
+		else
+		{
+		    d = READ(pDst, dst);
+		    d = fbOver24 (s, cvt0565to0888(d));
+		}
+		WRITE(pDst, dst, cvt8888to0565(d));
+	    }
+	    dst++;
+	}
+    }
+}
+
+static void
+fbCompositeSrc_x888x0565 (pixman_op_t op,
+                          pixman_image_t * pSrc,
+                          pixman_image_t * pMask,
+                          pixman_image_t * pDst,
+                          int16_t      xSrc,
+                          int16_t      ySrc,
+                          int16_t      xMask,
+                          int16_t      yMask,
+                          int16_t      xDst,
+                          int16_t      yDst,
+                          uint16_t     width,
+                          uint16_t     height)
+{
+    uint16_t	*dstLine, *dst;
+    uint32_t	*srcLine, *src, s;
+    int	dstStride, srcStride;
+    uint16_t	w;
+
+    fbComposeGetStart (pSrc, xSrc, ySrc, uint32_t, srcStride, srcLine, 1);
+    fbComposeGetStart (pDst, xDst, yDst, uint16_t, dstStride, dstLine, 1);
+
+    while (height--)
+    {
+	dst = dstLine;
+	dstLine += dstStride;
+	src = srcLine;
+	srcLine += srcStride;
+	w = width;
+
+	while (w--)
+	{
+	    s = READ(pSrc, src++);
+	    WRITE(pDst, dst, cvt8888to0565(s));
+	    dst++;
+	}
+    }
+}
+
+static void
+fbCompositeSrcAdd_8000x8000 (pixman_op_t	op,
+			     pixman_image_t * pSrc,
+			     pixman_image_t * pMask,
+			     pixman_image_t * pDst,
+			     int16_t      xSrc,
+			     int16_t      ySrc,
+			     int16_t      xMask,
+			     int16_t      yMask,
+			     int16_t      xDst,
+			     int16_t      yDst,
+			     uint16_t     width,
+			     uint16_t     height)
+{
+    uint8_t	*dstLine, *dst;
+    uint8_t	*srcLine, *src;
+    int	dstStride, srcStride;
+    uint16_t	w;
+    uint8_t	s, d;
+    uint16_t	t;
+
+    fbComposeGetStart (pSrc, xSrc, ySrc, uint8_t, srcStride, srcLine, 1);
+    fbComposeGetStart (pDst, xDst, yDst, uint8_t, dstStride, dstLine, 1);
+
+    while (height--)
+    {
+	dst = dstLine;
+	dstLine += dstStride;
+	src = srcLine;
+	srcLine += srcStride;
+	w = width;
+
+	while (w--)
+	{
+	    s = READ(pSrc, src++);
+	    if (s)
+	    {
+		if (s != 0xff)
+		{
+		    d = READ(pDst, dst);
+		    t = d + s;
+		    s = t | (0 - (t >> 8));
+		}
+		WRITE(pDst, dst, s);
+	    }
+	    dst++;
+	}
+    }
+}
+
+static void
+fbCompositeSrcAdd_8888x8888 (pixman_op_t	op,
+			     pixman_image_t * pSrc,
+			     pixman_image_t * pMask,
+			     pixman_image_t * pDst,
+			     int16_t      xSrc,
+			     int16_t      ySrc,
+			     int16_t      xMask,
+			     int16_t      yMask,
+			     int16_t      xDst,
+			     int16_t      yDst,
+			     uint16_t     width,
+			     uint16_t     height)
+{
+    uint32_t	*dstLine, *dst;
+    uint32_t	*srcLine, *src;
+    int	dstStride, srcStride;
+    uint16_t	w;
+    uint32_t	s, d;
+    uint16_t	t;
+    uint32_t	m,n,o,p;
+
+    fbComposeGetStart (pSrc, xSrc, ySrc, uint32_t, srcStride, srcLine, 1);
+    fbComposeGetStart (pDst, xDst, yDst, uint32_t, dstStride, dstLine, 1);
+
+    while (height--)
+    {
+	dst = dstLine;
+	dstLine += dstStride;
+	src = srcLine;
+	srcLine += srcStride;
+	w = width;
+
+	while (w--)
+	{
+	    s = READ(pSrc, src++);
+	    if (s)
+	    {
+		if (s != 0xffffffff)
+		{
+		    d = READ(pDst, dst);
+		    if (d)
+		    {
+			m = FbAdd(s,d,0,t);
+			n = FbAdd(s,d,8,t);
+			o = FbAdd(s,d,16,t);
+			p = FbAdd(s,d,24,t);
+			s = m|n|o|p;
+		    }
+		}
+		WRITE(pDst, dst, s);
+	    }
+	    dst++;
+	}
+    }
+}
+
+static void
+fbCompositeSrcAdd_8888x8x8 (pixman_op_t op,
+			    pixman_image_t * pSrc,
+			    pixman_image_t * pMask,
+			    pixman_image_t * pDst,
+			    int16_t      xSrc,
+			    int16_t      ySrc,
+			    int16_t      xMask,
+			    int16_t      yMask,
+			    int16_t      xDst,
+			    int16_t      yDst,
+			    uint16_t     width,
+			    uint16_t     height)
+{
+    uint8_t	*dstLine, *dst;
+    uint8_t	*maskLine, *mask;
+    int	dstStride, maskStride;
+    uint16_t	w;
+    uint32_t	src;
+    uint8_t	sa;
+
+    fbComposeGetStart (pDst, xDst, yDst, uint8_t, dstStride, dstLine, 1);
+    fbComposeGetStart (pMask, xMask, yMask, uint8_t, maskStride, maskLine, 1);
+    fbComposeGetSolid (pSrc, src, pDst->bits.format);
+    sa = (src >> 24);
+
+    while (height--)
+    {
+	dst = dstLine;
+	dstLine += dstStride;
+	mask = maskLine;
+	maskLine += maskStride;
+	w = width;
+
+	while (w--)
+	{
+	    uint16_t	tmp;
+	    uint16_t	a;
+	    uint32_t	m, d;
+	    uint32_t	r;
+
+	    a = READ(pMask, mask++);
+	    d = READ(pDst, dst);
+
+	    m = FbInU (sa, 0, a, tmp);
+	    r = FbAdd (m, d, 0, tmp);
+
+	    WRITE(pDst, dst++, r);
+	}
+    }
+}
+
+/*
+ * Simple bitblt
+ */
+
+static void
+fbCompositeSolidFill (pixman_op_t op,
+		      pixman_image_t * pSrc,
+		      pixman_image_t * pMask,
+		      pixman_image_t * pDst,
+		      int16_t      xSrc,
+		      int16_t      ySrc,
+		      int16_t      xMask,
+		      int16_t      yMask,
+		      int16_t      xDst,
+		      int16_t      yDst,
+		      uint16_t     width,
+		      uint16_t     height)
+{
+    uint32_t	src;
+
+    fbComposeGetSolid(pSrc, src, pDst->bits.format);
+
+    if (pDst->bits.format == PIXMAN_a8)
+	src = src >> 24;
+    else if (pDst->bits.format == PIXMAN_r5g6b5 ||
+	     pDst->bits.format == PIXMAN_b5g6r5)
+	src = cvt8888to0565 (src);
+
+    pixman_fill (pDst->bits.bits, pDst->bits.rowstride,
+		 PIXMAN_FORMAT_BPP (pDst->bits.format),
+		 xDst, yDst,
+		 width, height,
+		 src);
+}
+
+static void
+fbCompositeSrc_8888xx888 (pixman_op_t op,
+			  pixman_image_t * pSrc,
+			  pixman_image_t * pMask,
+			  pixman_image_t * pDst,
+			  int16_t      xSrc,
+			  int16_t      ySrc,
+			  int16_t      xMask,
+			  int16_t      yMask,
+			  int16_t      xDst,
+			  int16_t      yDst,
+			  uint16_t     width,
+			  uint16_t     height)
+{
+    uint32_t	*dst;
+    uint32_t    *src;
+    int		 dstStride, srcStride;
+    uint32_t	 n_bytes = width * sizeof (uint32_t);
+
+    fbComposeGetStart (pSrc, xSrc, ySrc, uint32_t, srcStride, src, 1);
+    fbComposeGetStart (pDst, xDst, yDst, uint32_t, dstStride, dst, 1);
+
+    while (height--)
+    {
+	memcpy (dst, src, n_bytes);
+
+	dst += dstStride;
+	src += srcStride;
+    }
+}
+
+static const FastPathInfo c_fast_path_array[] =
+{
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_r5g6b5,   fbCompositeSolidMask_nx8x0565, 0 },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_b5g6r5,   fbCompositeSolidMask_nx8x0565, 0 },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_r8g8b8,   fbCompositeSolidMask_nx8x0888, 0 },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_b8g8r8,   fbCompositeSolidMask_nx8x0888, 0 },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_a8r8g8b8, fbCompositeSolidMask_nx8x8888, 0 },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_x8r8g8b8, fbCompositeSolidMask_nx8x8888, 0 },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_a8b8g8r8, fbCompositeSolidMask_nx8x8888, 0 },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_x8b8g8r8, fbCompositeSolidMask_nx8x8888, 0 },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8r8g8b8, PIXMAN_a8r8g8b8, fbCompositeSolidMask_nx8888x8888C, NEED_COMPONENT_ALPHA },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8r8g8b8, PIXMAN_x8r8g8b8, fbCompositeSolidMask_nx8888x8888C, NEED_COMPONENT_ALPHA },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8r8g8b8, PIXMAN_r5g6b5,   fbCompositeSolidMask_nx8888x0565C, NEED_COMPONENT_ALPHA },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8b8g8r8, PIXMAN_a8b8g8r8, fbCompositeSolidMask_nx8888x8888C, NEED_COMPONENT_ALPHA },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8b8g8r8, PIXMAN_x8b8g8r8, fbCompositeSolidMask_nx8888x8888C, NEED_COMPONENT_ALPHA },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8b8g8r8, PIXMAN_b5g6r5,   fbCompositeSolidMask_nx8888x0565C, NEED_COMPONENT_ALPHA },
+    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8,	PIXMAN_x8r8g8b8, fbCompositeOver_x888x8x8888,       0 },
+    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8,	PIXMAN_a8r8g8b8, fbCompositeOver_x888x8x8888,       0 },
+    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8,	PIXMAN_x8b8g8r8, fbCompositeOver_x888x8x8888,       0 },
+    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8,	PIXMAN_a8b8g8r8, fbCompositeOver_x888x8x8888,       0 },
+    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null,     PIXMAN_a8r8g8b8, fbCompositeSrc_8888x8888,	   0 },
+    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null,	PIXMAN_x8r8g8b8, fbCompositeSrc_8888x8888,	   0 },
+    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null,	PIXMAN_r5g6b5,	 fbCompositeSrc_8888x0565,	   0 },
+    { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null,	PIXMAN_a8b8g8r8, fbCompositeSrc_8888x8888,	   0 },
+    { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null,	PIXMAN_x8b8g8r8, fbCompositeSrc_8888x8888,	   0 },
+    { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null,     PIXMAN_b5g6r5,   fbCompositeSrc_8888x0565,	   0 },
+    { PIXMAN_OP_ADD, PIXMAN_a8r8g8b8,  PIXMAN_null,	PIXMAN_a8r8g8b8, fbCompositeSrcAdd_8888x8888,   0 },
+    { PIXMAN_OP_ADD, PIXMAN_a8b8g8r8,  PIXMAN_null,	PIXMAN_a8b8g8r8, fbCompositeSrcAdd_8888x8888,   0 },
+    { PIXMAN_OP_ADD, PIXMAN_a8,        PIXMAN_null,     PIXMAN_a8,       fbCompositeSrcAdd_8000x8000,   0 },
+    { PIXMAN_OP_ADD, PIXMAN_solid,     PIXMAN_a8,       PIXMAN_a8,       fbCompositeSrcAdd_8888x8x8,    0 },
+    { PIXMAN_OP_SRC, PIXMAN_solid,     PIXMAN_null,     PIXMAN_a8r8g8b8, fbCompositeSolidFill, 0 },
+    { PIXMAN_OP_SRC, PIXMAN_solid,     PIXMAN_null,     PIXMAN_x8r8g8b8, fbCompositeSolidFill, 0 },
+    { PIXMAN_OP_SRC, PIXMAN_solid,     PIXMAN_null,     PIXMAN_a8b8g8r8, fbCompositeSolidFill, 0 },
+    { PIXMAN_OP_SRC, PIXMAN_solid,     PIXMAN_null,     PIXMAN_x8b8g8r8, fbCompositeSolidFill, 0 },
+    { PIXMAN_OP_SRC, PIXMAN_solid,     PIXMAN_null,     PIXMAN_a8,       fbCompositeSolidFill, 0 },
+    { PIXMAN_OP_SRC, PIXMAN_solid,     PIXMAN_null,     PIXMAN_r5g6b5,   fbCompositeSolidFill, 0 },
+    { PIXMAN_OP_SRC, PIXMAN_a8r8g8b8,  PIXMAN_null,     PIXMAN_x8r8g8b8, fbCompositeSrc_8888xx888, 0 },
+    { PIXMAN_OP_SRC, PIXMAN_x8r8g8b8,  PIXMAN_null,     PIXMAN_x8r8g8b8, fbCompositeSrc_8888xx888, 0 },
+    { PIXMAN_OP_SRC, PIXMAN_a8b8g8r8,  PIXMAN_null,     PIXMAN_x8b8g8r8, fbCompositeSrc_8888xx888, 0 },
+    { PIXMAN_OP_SRC, PIXMAN_x8b8g8r8,  PIXMAN_null,     PIXMAN_x8b8g8r8, fbCompositeSrc_8888xx888, 0 },
+    { PIXMAN_OP_SRC, PIXMAN_a8r8g8b8,  PIXMAN_null,     PIXMAN_r5g6b5,   fbCompositeSrc_x888x0565, 0 },
+    { PIXMAN_OP_SRC, PIXMAN_x8r8g8b8,  PIXMAN_null,     PIXMAN_r5g6b5,   fbCompositeSrc_x888x0565, 0 },
+    { PIXMAN_OP_SRC, PIXMAN_a8b8g8r8,  PIXMAN_null,     PIXMAN_b5g6r5,   fbCompositeSrc_x888x0565, 0 },
+    { PIXMAN_OP_SRC, PIXMAN_x8b8g8r8,  PIXMAN_null,     PIXMAN_b5g6r5,   fbCompositeSrc_x888x0565, 0 },
+    { PIXMAN_OP_IN,  PIXMAN_a8,        PIXMAN_null,     PIXMAN_a8,       fbCompositeSrcIn_8x8,   0 },
+    { PIXMAN_OP_IN,  PIXMAN_solid,     PIXMAN_a8,	PIXMAN_a8,	 fbCompositeSolidMaskIn_nx8x8, 0 },
+    { PIXMAN_OP_NONE },
+};
+
+const FastPathInfo *const c_fast_paths = c_fast_path_array;
diff --git a/pixman/pixman-pict.c b/pixman/pixman-pict.c
index 2298fdd..b22785b 100644
--- a/pixman/pixman-pict.c
+++ b/pixman/pixman-pict.c
@@ -38,1105 +38,6 @@
 #include "pixman-arm-neon.h"
 #include "pixman-combine32.h"
 
-#define FbFullMask(n)   ((n) == 32 ? (uint32_t)-1 : ((((uint32_t) 1) << n) - 1))
-
-#undef READ
-#undef WRITE
-#define READ(img,x) (*(x))
-#define WRITE(img,ptr,v) ((*(ptr)) = (v))
-
-static force_inline uint32_t
-fbOver (uint32_t src, uint32_t dest)
-{
-    // dest = (dest * (255 - alpha)) / 255 + src
-    uint32_t a = ~src >> 24; // 255 - alpha == 255 + (~alpha + 1) == ~alpha
-    FbByteMulAdd(dest, a, src);
-
-    return dest;
-}
-
-static uint32_t
-fbOver24 (uint32_t x, uint32_t y)
-{
-    uint16_t  a = ~x >> 24;
-    uint16_t  t;
-    uint32_t  m,n,o;
-
-    m = FbOverU(x,y,0,a,t);
-    n = FbOverU(x,y,8,a,t);
-    o = FbOverU(x,y,16,a,t);
-    return m|n|o;
-}
-
-static uint32_t
-fbIn (uint32_t x, uint8_t y)
-{
-    uint16_t  a = y;
-    uint16_t  t;
-    uint32_t  m,n,o,p;
-
-    m = FbInU(x,0,a,t);
-    n = FbInU(x,8,a,t);
-    o = FbInU(x,16,a,t);
-    p = FbInU(x,24,a,t);
-    return m|n|o|p;
-}
-
-/*
- * Naming convention:
- *
- *  opSRCxMASKxDST
- */
-
-static void
-fbCompositeOver_x888x8x8888 (pixman_op_t      op,
-			     pixman_image_t * pSrc,
-			     pixman_image_t * pMask,
-			     pixman_image_t * pDst,
-			     int16_t      xSrc,
-			     int16_t      ySrc,
-			     int16_t      xMask,
-			     int16_t      yMask,
-			     int16_t      xDst,
-			     int16_t      yDst,
-			     uint16_t     width,
-			     uint16_t     height)
-{
-    uint32_t	*src, *srcLine;
-    uint32_t    *dst, *dstLine;
-    uint8_t	*mask, *maskLine;
-    int		 srcStride, maskStride, dstStride;
-    uint8_t m;
-    uint32_t s, d;
-    uint16_t w;
-
-    fbComposeGetStart (pDst, xDst, yDst, uint32_t, dstStride, dstLine, 1);
-    fbComposeGetStart (pMask, xMask, yMask, uint8_t, maskStride, maskLine, 1);
-    fbComposeGetStart (pSrc, xSrc, ySrc, uint32_t, srcStride, srcLine, 1);
-
-    while (height--)
-    {
-	src = srcLine;
-	srcLine += srcStride;
-	dst = dstLine;
-	dstLine += dstStride;
-	mask = maskLine;
-	maskLine += maskStride;
-
-	w = width;
-	while (w--)
-	{
-	    m = READ(pMask, mask++);
-	    if (m)
-	    {
-		s = READ(pSrc, src) | 0xff000000;
-
-		if (m == 0xff)
-		    WRITE(pDst, dst, s);
-		else
-		{
-		    d = fbIn (s, m);
-		    WRITE(pDst, dst, fbOver (d, READ(pDst, dst)));
-		}
-	    }
-	    src++;
-	    dst++;
-	}
-    }
-}
-
-static void
-fbCompositeSolidMaskIn_nx8x8 (pixman_op_t      op,
-			      pixman_image_t    *iSrc,
-			      pixman_image_t    *iMask,
-			      pixman_image_t    *iDst,
-			      int16_t      xSrc,
-			      int16_t      ySrc,
-			      int16_t      xMask,
-			      int16_t      yMask,
-			      int16_t      xDst,
-			      int16_t      yDst,
-			      uint16_t     width,
-			      uint16_t     height)
-{
-    uint32_t	src, srca;
-    uint8_t	*dstLine, *dst, dstMask;
-    uint8_t	*maskLine, *mask, m;
-    int	dstStride, maskStride;
-    uint16_t	w;
-    uint16_t    t;
-
-    fbComposeGetSolid(iSrc, src, iDst->bits.format);
-
-    dstMask = FbFullMask (PIXMAN_FORMAT_DEPTH (iDst->bits.format));
-    srca = src >> 24;
-
-    fbComposeGetStart (iDst, xDst, yDst, uint8_t, dstStride, dstLine, 1);
-    fbComposeGetStart (iMask, xMask, yMask, uint8_t, maskStride, maskLine, 1);
-
-    if (srca == 0xff) {
-	while (height--)
-	{
-	    dst = dstLine;
-	    dstLine += dstStride;
-	    mask = maskLine;
-	    maskLine += maskStride;
-	    w = width;
-
-	    while (w--)
-	    {
-		m = *mask++;
-		if (m == 0)
-		{
-		    *dst = 0;
-		}
-		else if (m != 0xff)
-		{
-		    *dst = FbIntMult(m, *dst, t);
-		}
-		dst++;
-	    }
-	}
-    }
-    else
-    {
-	while (height--)
-	{
-	    dst = dstLine;
-	    dstLine += dstStride;
-	    mask = maskLine;
-	    maskLine += maskStride;
-	    w = width;
-
-	    while (w--)
-	    {
-		m = *mask++;
-		m = FbIntMult(m, srca, t);
-		if (m == 0)
-		{
-		    *dst = 0;
-		}
-		else if (m != 0xff)
-		{
-		    *dst = FbIntMult(m, *dst, t);
-		}
-		dst++;
-	    }
-	}
-    }
-}
-
-
-static void
-fbCompositeSrcIn_8x8 (pixman_op_t      op,
-		      pixman_image_t  *iSrc,
-		      pixman_image_t  *iMask,
-		      pixman_image_t  *iDst,
-		      int16_t          xSrc,
-		      int16_t          ySrc,
-		      int16_t          xMask,
-		      int16_t          yMask,
-		      int16_t          xDst,
-		      int16_t          yDst,
-		      uint16_t         width,
-		      uint16_t         height)
-{
-    uint8_t	*dstLine, *dst;
-    uint8_t	*srcLine, *src;
-    int	dstStride, srcStride;
-    uint16_t	w;
-    uint8_t	s;
-    uint16_t	t;
-
-    fbComposeGetStart (iSrc, xSrc, ySrc, uint8_t, srcStride, srcLine, 1);
-    fbComposeGetStart (iDst, xDst, yDst, uint8_t, dstStride, dstLine, 1);
-
-    while (height--)
-    {
-	dst = dstLine;
-	dstLine += dstStride;
-	src = srcLine;
-	srcLine += srcStride;
-	w = width;
-
-	while (w--)
-	{
-	    s = *src++;
-	    if (s == 0)
-	    {
-		*dst = 0;
-	    }
-	    else if (s != 0xff)
-	    {
-		*dst = FbIntMult(s, *dst, t);
-	    }
-	    dst++;
-	}
-    }
-}
-
-void
-fbCompositeSolidMask_nx8x8888 (pixman_op_t      op,
-			       pixman_image_t * pSrc,
-			       pixman_image_t * pMask,
-			       pixman_image_t * pDst,
-			       int16_t      xSrc,
-			       int16_t      ySrc,
-			       int16_t      xMask,
-			       int16_t      yMask,
-			       int16_t      xDst,
-			       int16_t      yDst,
-			       uint16_t     width,
-			       uint16_t     height)
-{
-    uint32_t	 src, srca;
-    uint32_t	*dstLine, *dst, d, dstMask;
-    uint8_t	*maskLine, *mask, m;
-    int		 dstStride, maskStride;
-    uint16_t	 w;
-
-    fbComposeGetSolid(pSrc, src, pDst->bits.format);
-
-    dstMask = FbFullMask (PIXMAN_FORMAT_DEPTH (pDst->bits.format));
-    srca = src >> 24;
-    if (src == 0)
-	return;
-
-    fbComposeGetStart (pDst, xDst, yDst, uint32_t, dstStride, dstLine, 1);
-    fbComposeGetStart (pMask, xMask, yMask, uint8_t, maskStride, maskLine, 1);
-
-    while (height--)
-    {
-	dst = dstLine;
-	dstLine += dstStride;
-	mask = maskLine;
-	maskLine += maskStride;
-	w = width;
-
-	while (w--)
-	{
-	    m = READ(pMask, mask++);
-	    if (m == 0xff)
-	    {
-		if (srca == 0xff)
-		    WRITE(pDst, dst, src & dstMask);
-		else
-		    WRITE(pDst, dst, fbOver (src, READ(pDst, dst)) & dstMask);
-	    }
-	    else if (m)
-	    {
-		d = fbIn (src, m);
-		WRITE(pDst, dst, fbOver (d, READ(pDst, dst)) & dstMask);
-	    }
-	    dst++;
-	}
-    }
-}
-
-void
-fbCompositeSolidMask_nx8888x8888C (pixman_op_t op,
-				   pixman_image_t * pSrc,
-				   pixman_image_t * pMask,
-				   pixman_image_t * pDst,
-				   int16_t      xSrc,
-				   int16_t      ySrc,
-				   int16_t      xMask,
-				   int16_t      yMask,
-				   int16_t      xDst,
-				   int16_t      yDst,
-				   uint16_t     width,
-				   uint16_t     height)
-{
-    uint32_t	src, srca;
-    uint32_t	*dstLine, *dst, d, dstMask;
-    uint32_t	*maskLine, *mask, ma;
-    int	dstStride, maskStride;
-    uint16_t	w;
-    uint32_t	m, n, o, p;
-
-    fbComposeGetSolid(pSrc, src, pDst->bits.format);
-
-    dstMask = FbFullMask (PIXMAN_FORMAT_DEPTH (pDst->bits.format));
-    srca = src >> 24;
-    if (src == 0)
-	return;
-
-    fbComposeGetStart (pDst, xDst, yDst, uint32_t, dstStride, dstLine, 1);
-    fbComposeGetStart (pMask, xMask, yMask, uint32_t, maskStride, maskLine, 1);
-
-    while (height--)
-    {
-	dst = dstLine;
-	dstLine += dstStride;
-	mask = maskLine;
-	maskLine += maskStride;
-	w = width;
-
-	while (w--)
-	{
-	    ma = READ(pMask, mask++);
-	    if (ma == 0xffffffff)
-	    {
-		if (srca == 0xff)
-		    WRITE(pDst, dst, src & dstMask);
-		else
-		    WRITE(pDst, dst, fbOver (src, READ(pDst, dst)) & dstMask);
-	    }
-	    else if (ma)
-	    {
-		d = READ(pDst, dst);
-#define FbInOverC(src,srca,msk,dst,i,result) { \
-    uint16_t  __a = FbGet8(msk,i); \
-    uint32_t  __t, __ta; \
-    uint32_t  __i; \
-    __t = FbIntMult (FbGet8(src,i), __a,__i); \
-    __ta = (uint8_t) ~FbIntMult (srca, __a,__i); \
-    __t = __t + FbIntMult(FbGet8(dst,i),__ta,__i); \
-    __t = (uint32_t) (uint8_t) (__t | (-(__t >> 8))); \
-    result = __t << (i); \
-}
-		FbInOverC (src, srca, ma, d, 0, m);
-		FbInOverC (src, srca, ma, d, 8, n);
-		FbInOverC (src, srca, ma, d, 16, o);
-		FbInOverC (src, srca, ma, d, 24, p);
-		WRITE(pDst, dst, m|n|o|p);
-	    }
-	    dst++;
-	}
-    }
-}
-
-void
-fbCompositeSolidMask_nx8x0888 (pixman_op_t op,
-			       pixman_image_t * pSrc,
-			       pixman_image_t * pMask,
-			       pixman_image_t * pDst,
-			       int16_t      xSrc,
-			       int16_t      ySrc,
-			       int16_t      xMask,
-			       int16_t      yMask,
-			       int16_t      xDst,
-			       int16_t      yDst,
-			       uint16_t     width,
-			       uint16_t     height)
-{
-    uint32_t	src, srca;
-    uint8_t	*dstLine, *dst;
-    uint32_t	d;
-    uint8_t	*maskLine, *mask, m;
-    int	dstStride, maskStride;
-    uint16_t	w;
-
-    fbComposeGetSolid(pSrc, src, pDst->bits.format);
-
-    srca = src >> 24;
-    if (src == 0)
-	return;
-
-    fbComposeGetStart (pDst, xDst, yDst, uint8_t, dstStride, dstLine, 3);
-    fbComposeGetStart (pMask, xMask, yMask, uint8_t, maskStride, maskLine, 1);
-
-    while (height--)
-    {
-	dst = dstLine;
-	dstLine += dstStride;
-	mask = maskLine;
-	maskLine += maskStride;
-	w = width;
-
-	while (w--)
-	{
-	    m = READ(pMask, mask++);
-	    if (m == 0xff)
-	    {
-		if (srca == 0xff)
-		    d = src;
-		else
-		{
-		    d = Fetch24(pDst, dst);
-		    d = fbOver24 (src, d);
-		}
-		Store24(pDst, dst,d);
-	    }
-	    else if (m)
-	    {
-		d = fbOver24 (fbIn(src,m), Fetch24(pDst, dst));
-		Store24(pDst, dst, d);
-	    }
-	    dst += 3;
-	}
-    }
-}
-
-void
-fbCompositeSolidMask_nx8x0565 (pixman_op_t op,
-				  pixman_image_t * pSrc,
-				  pixman_image_t * pMask,
-				  pixman_image_t * pDst,
-				  int16_t      xSrc,
-				  int16_t      ySrc,
-				  int16_t      xMask,
-				  int16_t      yMask,
-				  int16_t      xDst,
-				  int16_t      yDst,
-				  uint16_t     width,
-				  uint16_t     height)
-{
-    uint32_t	src, srca;
-    uint16_t	*dstLine, *dst;
-    uint32_t	d;
-    uint8_t	*maskLine, *mask, m;
-    int	dstStride, maskStride;
-    uint16_t	w;
-
-    fbComposeGetSolid(pSrc, src, pDst->bits.format);
-
-    srca = src >> 24;
-    if (src == 0)
-	return;
-
-    fbComposeGetStart (pDst, xDst, yDst, uint16_t, dstStride, dstLine, 1);
-    fbComposeGetStart (pMask, xMask, yMask, uint8_t, maskStride, maskLine, 1);
-
-    while (height--)
-    {
-	dst = dstLine;
-	dstLine += dstStride;
-	mask = maskLine;
-	maskLine += maskStride;
-	w = width;
-
-	while (w--)
-	{
-	    m = READ(pMask, mask++);
-	    if (m == 0xff)
-	    {
-		if (srca == 0xff)
-		    d = src;
-		else
-		{
-		    d = READ(pDst, dst);
-		    d = fbOver24 (src, cvt0565to0888(d));
-		}
-		WRITE(pDst, dst, cvt8888to0565(d));
-	    }
-	    else if (m)
-	    {
-		d = READ(pDst, dst);
-		d = fbOver24 (fbIn(src,m), cvt0565to0888(d));
-		WRITE(pDst, dst, cvt8888to0565(d));
-	    }
-	    dst++;
-	}
-    }
-}
-
-void
-fbCompositeSolidMask_nx8888x0565C (pixman_op_t op,
-				   pixman_image_t * pSrc,
-				   pixman_image_t * pMask,
-				   pixman_image_t * pDst,
-				   int16_t      xSrc,
-				   int16_t      ySrc,
-				   int16_t      xMask,
-				   int16_t      yMask,
-				   int16_t      xDst,
-				   int16_t      yDst,
-				   uint16_t     width,
-				   uint16_t     height)
-{
-    uint32_t	src, srca;
-    uint16_t	src16;
-    uint16_t	*dstLine, *dst;
-    uint32_t	d;
-    uint32_t	*maskLine, *mask, ma;
-    int	dstStride, maskStride;
-    uint16_t	w;
-    uint32_t	m, n, o;
-
-    fbComposeGetSolid(pSrc, src, pDst->bits.format);
-
-    srca = src >> 24;
-    if (src == 0)
-	return;
-
-    src16 = cvt8888to0565(src);
-
-    fbComposeGetStart (pDst, xDst, yDst, uint16_t, dstStride, dstLine, 1);
-    fbComposeGetStart (pMask, xMask, yMask, uint32_t, maskStride, maskLine, 1);
-
-    while (height--)
-    {
-	dst = dstLine;
-	dstLine += dstStride;
-	mask = maskLine;
-	maskLine += maskStride;
-	w = width;
-
-	while (w--)
-	{
-	    ma = READ(pMask, mask++);
-	    if (ma == 0xffffffff)
-	    {
-		if (srca == 0xff)
-		{
-		    WRITE(pDst, dst, src16);
-		}
-		else
-		{
-		    d = READ(pDst, dst);
-		    d = fbOver24 (src, cvt0565to0888(d));
-		    WRITE(pDst, dst, cvt8888to0565(d));
-		}
-	    }
-	    else if (ma)
-	    {
-		d = READ(pDst, dst);
-		d = cvt0565to0888(d);
-		FbInOverC (src, srca, ma, d, 0, m);
-		FbInOverC (src, srca, ma, d, 8, n);
-		FbInOverC (src, srca, ma, d, 16, o);
-		d = m|n|o;
-		WRITE(pDst, dst, cvt8888to0565(d));
-	    }
-	    dst++;
-	}
-    }
-}
-
-void
-fbCompositeSrc_8888x8888 (pixman_op_t op,
-			 pixman_image_t * pSrc,
-			 pixman_image_t * pMask,
-			 pixman_image_t * pDst,
-			 int16_t      xSrc,
-			 int16_t      ySrc,
-			 int16_t      xMask,
-			 int16_t      yMask,
-			 int16_t      xDst,
-			 int16_t      yDst,
-			 uint16_t     width,
-			 uint16_t     height)
-{
-    uint32_t	*dstLine, *dst, dstMask;
-    uint32_t	*srcLine, *src, s;
-    int	dstStride, srcStride;
-    uint8_t	a;
-    uint16_t	w;
-
-    fbComposeGetStart (pDst, xDst, yDst, uint32_t, dstStride, dstLine, 1);
-    fbComposeGetStart (pSrc, xSrc, ySrc, uint32_t, srcStride, srcLine, 1);
-
-    dstMask = FbFullMask (PIXMAN_FORMAT_DEPTH (pDst->bits.format));
-
-    while (height--)
-    {
-	dst = dstLine;
-	dstLine += dstStride;
-	src = srcLine;
-	srcLine += srcStride;
-	w = width;
-
-	while (w--)
-	{
-	    s = READ(pSrc, src++);
-	    a = s >> 24;
-	    if (a == 0xff)
-		WRITE(pDst, dst, s & dstMask);
-	    else if (s)
-		WRITE(pDst, dst, fbOver (s, READ(pDst, dst)) & dstMask);
-	    dst++;
-	}
-    }
-}
-
-void
-fbCompositeSrc_8888x0888 (pixman_op_t op,
-			 pixman_image_t * pSrc,
-			 pixman_image_t * pMask,
-			 pixman_image_t * pDst,
-			 int16_t      xSrc,
-			 int16_t      ySrc,
-			 int16_t      xMask,
-			 int16_t      yMask,
-			 int16_t      xDst,
-			 int16_t      yDst,
-			 uint16_t     width,
-			 uint16_t     height)
-{
-    uint8_t	*dstLine, *dst;
-    uint32_t	d;
-    uint32_t	*srcLine, *src, s;
-    uint8_t	a;
-    int	dstStride, srcStride;
-    uint16_t	w;
-
-    fbComposeGetStart (pDst, xDst, yDst, uint8_t, dstStride, dstLine, 3);
-    fbComposeGetStart (pSrc, xSrc, ySrc, uint32_t, srcStride, srcLine, 1);
-
-    while (height--)
-    {
-	dst = dstLine;
-	dstLine += dstStride;
-	src = srcLine;
-	srcLine += srcStride;
-	w = width;
-
-	while (w--)
-	{
-	    s = READ(pSrc, src++);
-	    a = s >> 24;
-	    if (a)
-	    {
-		if (a == 0xff)
-		    d = s;
-		else
-		    d = fbOver24 (s, Fetch24(pDst, dst));
-		Store24(pDst, dst, d);
-	    }
-	    dst += 3;
-	}
-    }
-}
-
-void
-fbCompositeSrc_8888x0565 (pixman_op_t op,
-			 pixman_image_t * pSrc,
-			 pixman_image_t * pMask,
-			 pixman_image_t * pDst,
-			 int16_t      xSrc,
-			 int16_t      ySrc,
-			 int16_t      xMask,
-			 int16_t      yMask,
-			 int16_t      xDst,
-			 int16_t      yDst,
-			 uint16_t     width,
-			 uint16_t     height)
-{
-    uint16_t	*dstLine, *dst;
-    uint32_t	d;
-    uint32_t	*srcLine, *src, s;
-    uint8_t	a;
-    int	dstStride, srcStride;
-    uint16_t	w;
-
-    fbComposeGetStart (pSrc, xSrc, ySrc, uint32_t, srcStride, srcLine, 1);
-    fbComposeGetStart (pDst, xDst, yDst, uint16_t, dstStride, dstLine, 1);
-
-    while (height--)
-    {
-	dst = dstLine;
-	dstLine += dstStride;
-	src = srcLine;
-	srcLine += srcStride;
-	w = width;
-
-	while (w--)
-	{
-	    s = READ(pSrc, src++);
-	    a = s >> 24;
-	    if (s)
-	    {
-		if (a == 0xff)
-		    d = s;
-		else
-		{
-		    d = READ(pDst, dst);
-		    d = fbOver24 (s, cvt0565to0888(d));
-		}
-		WRITE(pDst, dst, cvt8888to0565(d));
-	    }
-	    dst++;
-	}
-    }
-}
-
-
-void
-fbCompositeSrc_x888x0565 (pixman_op_t op,
-                          pixman_image_t * pSrc,
-                          pixman_image_t * pMask,
-                          pixman_image_t * pDst,
-                          int16_t      xSrc,
-                          int16_t      ySrc,
-                          int16_t      xMask,
-                          int16_t      yMask,
-                          int16_t      xDst,
-                          int16_t      yDst,
-                          uint16_t     width,
-                          uint16_t     height)
-{
-    uint16_t	*dstLine, *dst;
-    uint32_t	*srcLine, *src, s;
-    int	dstStride, srcStride;
-    uint16_t	w;
-
-    fbComposeGetStart (pSrc, xSrc, ySrc, uint32_t, srcStride, srcLine, 1);
-    fbComposeGetStart (pDst, xDst, yDst, uint16_t, dstStride, dstLine, 1);
-
-    while (height--)
-    {
-	dst = dstLine;
-	dstLine += dstStride;
-	src = srcLine;
-	srcLine += srcStride;
-	w = width;
-
-	while (w--)
-	{
-	    s = READ(pSrc, src++);
-	    WRITE(pDst, dst, cvt8888to0565(s));
-	    dst++;
-	}
-    }
-}
-
-void
-fbCompositeSrcAdd_8000x8000 (pixman_op_t	op,
-			     pixman_image_t * pSrc,
-			     pixman_image_t * pMask,
-			     pixman_image_t * pDst,
-			     int16_t      xSrc,
-			     int16_t      ySrc,
-			     int16_t      xMask,
-			     int16_t      yMask,
-			     int16_t      xDst,
-			     int16_t      yDst,
-			     uint16_t     width,
-			     uint16_t     height)
-{
-    uint8_t	*dstLine, *dst;
-    uint8_t	*srcLine, *src;
-    int	dstStride, srcStride;
-    uint16_t	w;
-    uint8_t	s, d;
-    uint16_t	t;
-
-    fbComposeGetStart (pSrc, xSrc, ySrc, uint8_t, srcStride, srcLine, 1);
-    fbComposeGetStart (pDst, xDst, yDst, uint8_t, dstStride, dstLine, 1);
-
-    while (height--)
-    {
-	dst = dstLine;
-	dstLine += dstStride;
-	src = srcLine;
-	srcLine += srcStride;
-	w = width;
-
-	while (w--)
-	{
-	    s = READ(pSrc, src++);
-	    if (s)
-	    {
-		if (s != 0xff)
-		{
-		    d = READ(pDst, dst);
-		    t = d + s;
-		    s = t | (0 - (t >> 8));
-		}
-		WRITE(pDst, dst, s);
-	    }
-	    dst++;
-	}
-    }
-}
-
-void
-fbCompositeSrcAdd_8888x8888 (pixman_op_t	op,
-			     pixman_image_t * pSrc,
-			     pixman_image_t * pMask,
-			     pixman_image_t * pDst,
-			     int16_t      xSrc,
-			     int16_t      ySrc,
-			     int16_t      xMask,
-			     int16_t      yMask,
-			     int16_t      xDst,
-			     int16_t      yDst,
-			     uint16_t     width,
-			     uint16_t     height)
-{
-    uint32_t	*dstLine, *dst;
-    uint32_t	*srcLine, *src;
-    int	dstStride, srcStride;
-    uint16_t	w;
-    uint32_t	s, d;
-    uint16_t	t;
-    uint32_t	m,n,o,p;
-
-    fbComposeGetStart (pSrc, xSrc, ySrc, uint32_t, srcStride, srcLine, 1);
-    fbComposeGetStart (pDst, xDst, yDst, uint32_t, dstStride, dstLine, 1);
-
-    while (height--)
-    {
-	dst = dstLine;
-	dstLine += dstStride;
-	src = srcLine;
-	srcLine += srcStride;
-	w = width;
-
-	while (w--)
-	{
-	    s = READ(pSrc, src++);
-	    if (s)
-	    {
-		if (s != 0xffffffff)
-		{
-		    d = READ(pDst, dst);
-		    if (d)
-		    {
-			m = FbAdd(s,d,0,t);
-			n = FbAdd(s,d,8,t);
-			o = FbAdd(s,d,16,t);
-			p = FbAdd(s,d,24,t);
-			s = m|n|o|p;
-		    }
-		}
-		WRITE(pDst, dst, s);
-	    }
-	    dst++;
-	}
-    }
-}
-
-static void
-fbCompositeSrcAdd_8888x8x8 (pixman_op_t op,
-			    pixman_image_t * pSrc,
-			    pixman_image_t * pMask,
-			    pixman_image_t * pDst,
-			    int16_t      xSrc,
-			    int16_t      ySrc,
-			    int16_t      xMask,
-			    int16_t      yMask,
-			    int16_t      xDst,
-			    int16_t      yDst,
-			    uint16_t     width,
-			    uint16_t     height)
-{
-    uint8_t	*dstLine, *dst;
-    uint8_t	*maskLine, *mask;
-    int	dstStride, maskStride;
-    uint16_t	w;
-    uint32_t	src;
-    uint8_t	sa;
-
-    fbComposeGetStart (pDst, xDst, yDst, uint8_t, dstStride, dstLine, 1);
-    fbComposeGetStart (pMask, xMask, yMask, uint8_t, maskStride, maskLine, 1);
-    fbComposeGetSolid (pSrc, src, pDst->bits.format);
-    sa = (src >> 24);
-
-    while (height--)
-    {
-	dst = dstLine;
-	dstLine += dstStride;
-	mask = maskLine;
-	maskLine += maskStride;
-	w = width;
-
-	while (w--)
-	{
-	    uint16_t	tmp;
-	    uint16_t	a;
-	    uint32_t	m, d;
-	    uint32_t	r;
-
-	    a = READ(pMask, mask++);
-	    d = READ(pDst, dst);
-
-	    m = FbInU (sa, 0, a, tmp);
-	    r = FbAdd (m, d, 0, tmp);
-
-	    WRITE(pDst, dst++, r);
-	}
-    }
-}
-
-void
-fbCompositeSrcAdd_1000x1000 (pixman_op_t	op,
-			     pixman_image_t * pSrc,
-			     pixman_image_t * pMask,
-			     pixman_image_t * pDst,
-			     int16_t      xSrc,
-			     int16_t      ySrc,
-			     int16_t      xMask,
-			     int16_t      yMask,
-			     int16_t      xDst,
-			     int16_t      yDst,
-			     uint16_t     width,
-			     uint16_t     height)
-{
-    /* FIXME */
-#if 0
-
-    uint32_t	*dstBits, *srcBits;
-    int	dstStride, srcStride;
-    int		dstBpp, srcBpp;
-    int		dstXoff, dstYoff;
-    int		srcXoff, srcYoff;
-
-    fbGetDrawable(pSrc->pDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff);
-
-    fbGetDrawable(pDst->pDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff);
-
-    fbBlt (srcBits + srcStride * (ySrc + srcYoff),
-	   srcStride,
-	   xSrc + srcXoff,
-
-	   dstBits + dstStride * (yDst + dstYoff),
-	   dstStride,
-	   xDst + dstXoff,
-
-	   width,
-	   height,
-
-	   GXor,
-	   FB_ALLONES,
-	   srcBpp,
-
-	   FALSE,
-	   FALSE);
-
-#endif
-}
-
-void
-fbCompositeSolidMask_nx1xn (pixman_op_t op,
-			    pixman_image_t * pSrc,
-			    pixman_image_t * pMask,
-			    pixman_image_t * pDst,
-			    int16_t      xSrc,
-			    int16_t      ySrc,
-			    int16_t      xMask,
-			    int16_t      yMask,
-			    int16_t      xDst,
-			    int16_t      yDst,
-			    uint16_t     width,
-			    uint16_t     height)
-{
-    /* FIXME */
-#if 0
-    uint32_t	*dstBits;
-    uint32_t	*maskBits;
-    int	dstStride, maskStride;
-    int		dstBpp, maskBpp;
-    int		dstXoff, dstYoff;
-    int		maskXoff, maskYoff;
-    uint32_t	src;
-
-    fbComposeGetSolid(pSrc, src, pDst->bits.format);
-    fbGetStipDrawable (pMask->pDrawable, maskBits, maskStride, maskBpp, maskXoff, maskYoff);
-    fbGetDrawable (pDst->pDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff);
-
-    switch (dstBpp) {
-    case 32:
-	break;
-    case 24:
-	break;
-    case 16:
-	src = cvt8888to0565(src);
-	break;
-    }
-
-    src = fbReplicatePixel (src, dstBpp);
-
-    fbBltOne (maskBits + maskStride * (yMask + maskYoff),
-	      maskStride,
-	      xMask + maskXoff,
-
-	      dstBits + dstStride * (yDst + dstYoff),
-	      dstStride,
-	      (xDst + dstXoff) * dstBpp,
-	      dstBpp,
-
-	      width * dstBpp,
-	      height,
-
-	      0x0,
-	      src,
-	      FB_ALLONES,
-	      0x0);
-
-#endif
-}
-
-/*
- * Simple bitblt
- */
-
-static void
-pixman_image_composite_rect  (pixman_op_t                   op,
-			      pixman_image_t               *src,
-			      pixman_image_t               *mask,
-			      pixman_image_t               *dest,
-			      int16_t                       src_x,
-			      int16_t                       src_y,
-			      int16_t                       mask_x,
-			      int16_t                       mask_y,
-			      int16_t                       dest_x,
-			      int16_t                       dest_y,
-			      uint16_t                      width,
-			      uint16_t                      height);
-static void
-fbCompositeSolidFill (pixman_op_t op,
-		      pixman_image_t * pSrc,
-		      pixman_image_t * pMask,
-		      pixman_image_t * pDst,
-		      int16_t      xSrc,
-		      int16_t      ySrc,
-		      int16_t      xMask,
-		      int16_t      yMask,
-		      int16_t      xDst,
-		      int16_t      yDst,
-		      uint16_t     width,
-		      uint16_t     height)
-{
-    uint32_t	src;
-
-    fbComposeGetSolid(pSrc, src, pDst->bits.format);
-
-    if (pDst->bits.format == PIXMAN_a8)
-	src = src >> 24;
-    else if (pDst->bits.format == PIXMAN_r5g6b5 ||
-	     pDst->bits.format == PIXMAN_b5g6r5)
-	src = cvt8888to0565 (src);
-
-    pixman_fill (pDst->bits.bits, pDst->bits.rowstride,
-		 PIXMAN_FORMAT_BPP (pDst->bits.format),
-		 xDst, yDst,
-		 width, height,
-		 src);
-}
-
-static void
-fbCompositeSrc_8888xx888 (pixman_op_t op,
-			  pixman_image_t * pSrc,
-			  pixman_image_t * pMask,
-			  pixman_image_t * pDst,
-			  int16_t      xSrc,
-			  int16_t      ySrc,
-			  int16_t      xMask,
-			  int16_t      yMask,
-			  int16_t      xDst,
-			  int16_t      yDst,
-			  uint16_t     width,
-			  uint16_t     height)
-{
-    uint32_t	*dst;
-    uint32_t    *src;
-    int		 dstStride, srcStride;
-    uint32_t	 n_bytes = width * sizeof (uint32_t);
-
-    fbComposeGetStart (pSrc, xSrc, ySrc, uint32_t, srcStride, src, 1);
-    fbComposeGetStart (pDst, xDst, yDst, uint32_t, dstStride, dst, 1);
-
-    while (height--)
-    {
-	memcpy (dst, src, n_bytes);
-
-	dst += dstStride;
-	src += srcStride;
-    }
-}
-
 static void
 fbCompositeSrcScaleNearest (pixman_op_t     op,
 			    pixman_image_t *pSrc,
@@ -1360,82 +261,6 @@ pixman_image_composite_rect  (pixman_op_t                   op,
     pixman_composite_rect_general (&compose_data);
 }
 
-static const FastPathInfo c_fast_paths[] =
-{
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_r5g6b5,   fbCompositeSolidMask_nx8x0565, 0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_b5g6r5,   fbCompositeSolidMask_nx8x0565, 0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_r8g8b8,   fbCompositeSolidMask_nx8x0888, 0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_b8g8r8,   fbCompositeSolidMask_nx8x0888, 0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_a8r8g8b8, fbCompositeSolidMask_nx8x8888, 0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_x8r8g8b8, fbCompositeSolidMask_nx8x8888, 0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_a8b8g8r8, fbCompositeSolidMask_nx8x8888, 0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_x8b8g8r8, fbCompositeSolidMask_nx8x8888, 0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8r8g8b8, PIXMAN_a8r8g8b8, fbCompositeSolidMask_nx8888x8888C, NEED_COMPONENT_ALPHA },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8r8g8b8, PIXMAN_x8r8g8b8, fbCompositeSolidMask_nx8888x8888C, NEED_COMPONENT_ALPHA },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8r8g8b8, PIXMAN_r5g6b5,   fbCompositeSolidMask_nx8888x0565C, NEED_COMPONENT_ALPHA },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8b8g8r8, PIXMAN_a8b8g8r8, fbCompositeSolidMask_nx8888x8888C, NEED_COMPONENT_ALPHA },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8b8g8r8, PIXMAN_x8b8g8r8, fbCompositeSolidMask_nx8888x8888C, NEED_COMPONENT_ALPHA },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8b8g8r8, PIXMAN_b5g6r5,   fbCompositeSolidMask_nx8888x0565C, NEED_COMPONENT_ALPHA },
-#if 0
-    /* FIXME: This code is commented out since it's apparently not actually faster than the generic code */
-    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8,	PIXMAN_x8r8g8b8, fbCompositeOver_x888x8x8888,       0 },
-    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8,	PIXMAN_a8r8g8b8, fbCompositeOver_x888x8x8888,       0 },
-    { PIXMAN_OP_OVER, PIXMAN_x8b8r8g8, PIXMAN_a8,	PIXMAN_x8b8g8r8, fbCompositeOver_x888x8x8888,       0 },
-    { PIXMAN_OP_OVER, PIXMAN_x8b8r8g8, PIXMAN_a8,	PIXMAN_a8r8g8b8, fbCompositeOver_x888x8x8888,       0 },
-#endif
-    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null,     PIXMAN_a8r8g8b8, fbCompositeSrc_8888x8888,	   0 },
-    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null,	PIXMAN_x8r8g8b8, fbCompositeSrc_8888x8888,	   0 },
-    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null,	PIXMAN_r5g6b5,	 fbCompositeSrc_8888x0565,	   0 },
-    { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null,	PIXMAN_a8b8g8r8, fbCompositeSrc_8888x8888,	   0 },
-    { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null,	PIXMAN_x8b8g8r8, fbCompositeSrc_8888x8888,	   0 },
-    { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null,     PIXMAN_b5g6r5,   fbCompositeSrc_8888x0565,	   0 },
-#if 0
-    /* FIXME */
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a1,	PIXMAN_r5g6b5,   fbCompositeSolidMask_nx1xn,	   0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a1,	PIXMAN_b5g6r5,   fbCompositeSolidMask_nx1xn,	   0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a1,	PIXMAN_r8g8b8,   fbCompositeSolidMask_nx1xn,	   0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a1,	PIXMAN_b8g8r8,   fbCompositeSolidMask_nx1xn,	   0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a1,	PIXMAN_a8r8g8b8, fbCompositeSolidMask_nx1xn,	   0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a1,	PIXMAN_a8b8g8r8, fbCompositeSolidMask_nx1xn,	   0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a1,	PIXMAN_x8r8g8b8, fbCompositeSolidMask_nx1xn,	   0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a1,	PIXMAN_x8b8g8r8, fbCompositeSolidMask_nx1xn,	   0 },
-#endif
-    { PIXMAN_OP_ADD, PIXMAN_a8r8g8b8,  PIXMAN_null,	PIXMAN_a8r8g8b8, fbCompositeSrcAdd_8888x8888,   0 },
-    { PIXMAN_OP_ADD, PIXMAN_a8b8g8r8,  PIXMAN_null,	PIXMAN_a8b8g8r8, fbCompositeSrcAdd_8888x8888,   0 },
-    { PIXMAN_OP_ADD, PIXMAN_a8,        PIXMAN_null,     PIXMAN_a8,       fbCompositeSrcAdd_8000x8000,   0 },
-#if 0
-    /* FIXME */
-    { PIXMAN_OP_ADD, PIXMAN_a1,        PIXMAN_null,     PIXMAN_a1,       fbCompositeSrcAdd_1000x1000,   0 },
-#endif
-    { PIXMAN_OP_ADD, PIXMAN_solid,     PIXMAN_a8,       PIXMAN_a8,       fbCompositeSrcAdd_8888x8x8,    0 },
-    { PIXMAN_OP_SRC, PIXMAN_solid,     PIXMAN_null,     PIXMAN_a8r8g8b8, fbCompositeSolidFill, 0 },
-    { PIXMAN_OP_SRC, PIXMAN_solid,     PIXMAN_null,     PIXMAN_x8r8g8b8, fbCompositeSolidFill, 0 },
-    { PIXMAN_OP_SRC, PIXMAN_solid,     PIXMAN_null,     PIXMAN_a8b8g8r8, fbCompositeSolidFill, 0 },
-    { PIXMAN_OP_SRC, PIXMAN_solid,     PIXMAN_null,     PIXMAN_x8b8g8r8, fbCompositeSolidFill, 0 },
-    { PIXMAN_OP_SRC, PIXMAN_solid,     PIXMAN_null,     PIXMAN_a8,       fbCompositeSolidFill, 0 },
-    { PIXMAN_OP_SRC, PIXMAN_solid,     PIXMAN_null,     PIXMAN_r5g6b5,   fbCompositeSolidFill, 0 },
-    { PIXMAN_OP_SRC, PIXMAN_a8r8g8b8,  PIXMAN_null,     PIXMAN_x8r8g8b8, fbCompositeSrc_8888xx888, 0 },
-    { PIXMAN_OP_SRC, PIXMAN_x8r8g8b8,  PIXMAN_null,     PIXMAN_x8r8g8b8, fbCompositeSrc_8888xx888, 0 },
-    { PIXMAN_OP_SRC, PIXMAN_a8b8g8r8,  PIXMAN_null,     PIXMAN_x8b8g8r8, fbCompositeSrc_8888xx888, 0 },
-    { PIXMAN_OP_SRC, PIXMAN_x8b8g8r8,  PIXMAN_null,     PIXMAN_x8b8g8r8, fbCompositeSrc_8888xx888, 0 },
-#if 0
-    /* FIXME */
-    { PIXMAN_OP_SRC, PIXMAN_a8r8g8b8,  PIXMAN_null,	PIXMAN_a8r8g8b8, fbCompositeSrcSrc_nxn, 0 },
-    { PIXMAN_OP_SRC, PIXMAN_a8b8g8r8,  PIXMAN_null,	PIXMAN_a8b8g8r8, fbCompositeSrcSrc_nxn, 0 },
-    { PIXMAN_OP_SRC, PIXMAN_x8r8g8b8,  PIXMAN_null,	PIXMAN_x8r8g8b8, fbCompositeSrcSrc_nxn, 0 },
-    { PIXMAN_OP_SRC, PIXMAN_x8b8g8r8,  PIXMAN_null,	PIXMAN_x8b8g8r8, fbCompositeSrcSrc_nxn, 0 },
-    { PIXMAN_OP_SRC, PIXMAN_r5g6b5,    PIXMAN_null,     PIXMAN_r5g6b5,   fbCompositeSrcSrc_nxn, 0 },
-    { PIXMAN_OP_SRC, PIXMAN_b5g6r5,    PIXMAN_null,     PIXMAN_b5g6r5,   fbCompositeSrcSrc_nxn, 0 },
-#endif
-    { PIXMAN_OP_SRC, PIXMAN_a8r8g8b8,  PIXMAN_null,     PIXMAN_r5g6b5,   fbCompositeSrc_x888x0565, 0 },
-    { PIXMAN_OP_SRC, PIXMAN_x8r8g8b8,  PIXMAN_null,     PIXMAN_r5g6b5,   fbCompositeSrc_x888x0565, 0 },
-    { PIXMAN_OP_SRC, PIXMAN_a8b8g8r8,  PIXMAN_null,     PIXMAN_b5g6r5,   fbCompositeSrc_x888x0565, 0 },
-    { PIXMAN_OP_SRC, PIXMAN_x8b8g8r8,  PIXMAN_null,     PIXMAN_b5g6r5,   fbCompositeSrc_x888x0565, 0 },
-    { PIXMAN_OP_IN,  PIXMAN_a8,        PIXMAN_null,     PIXMAN_a8,       fbCompositeSrcIn_8x8,   0 },
-    { PIXMAN_OP_IN,  PIXMAN_solid,     PIXMAN_a8,	PIXMAN_a8,	 fbCompositeSolidMaskIn_nx8x8, 0 },
-    { PIXMAN_OP_NONE },
-};
-
 static pixman_bool_t
 mask_is_solid (pixman_image_t *mask)
 {
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 805b5ce..927a1c4 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -175,6 +175,8 @@ typedef struct
     uint32_t			flags;
 } FastPathInfo;
 
+extern const FastPathInfo *const c_fast_paths;
+
 /* FIXME - the types and structures below should be give proper names
  */
 
commit e42fae9e8364f5f0791f9fce749ab18b33acf598
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Sun May 3 21:05:45 2009 -0400

    Move the arch specific fast path tables into their arch files

diff --git a/pixman/pixman-arm-neon.c b/pixman/pixman-arm-neon.c
index 51f7d55..633f05e 100644
--- a/pixman/pixman-arm-neon.c
+++ b/pixman/pixman-arm-neon.c
@@ -1376,3 +1376,27 @@ fbCompositeSrcAdd_8888x8x8neon (pixman_op_t op,
     }
 }
 
+static const FastPathInfo arm_neon_fast_path_array[] = 
+{
+    { PIXMAN_OP_ADD,  PIXMAN_solid,    PIXMAN_a8,       PIXMAN_a8,       fbCompositeSrcAdd_8888x8x8neon,        0 },
+    { PIXMAN_OP_ADD,  PIXMAN_a8,       PIXMAN_null,     PIXMAN_a8,       fbCompositeSrcAdd_8000x8000neon,       0 },
+    { PIXMAN_OP_SRC,  PIXMAN_a8r8g8b8, PIXMAN_null,     PIXMAN_r5g6b5,   fbCompositeSrc_x888x0565neon,          0 },
+    { PIXMAN_OP_SRC,  PIXMAN_x8r8g8b8, PIXMAN_null,     PIXMAN_r5g6b5,   fbCompositeSrc_x888x0565neon,          0 },
+    { PIXMAN_OP_SRC,  PIXMAN_a8b8g8r8, PIXMAN_null,     PIXMAN_b5g6r5,   fbCompositeSrc_x888x0565neon,          0 },
+    { PIXMAN_OP_SRC,  PIXMAN_x8b8g8r8, PIXMAN_null,     PIXMAN_b5g6r5,   fbCompositeSrc_x888x0565neon,          0 },
+    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null,     PIXMAN_a8r8g8b8, fbCompositeSrc_8888x8888neon,          0 },
+    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null,     PIXMAN_x8r8g8b8, fbCompositeSrc_8888x8888neon,          0 },
+    { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null,     PIXMAN_a8b8g8r8, fbCompositeSrc_8888x8888neon,          0 },
+    { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null,     PIXMAN_x8b8g8r8, fbCompositeSrc_8888x8888neon,          0 },
+    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_a8,       PIXMAN_a8r8g8b8, fbCompositeSrc_8888x8x8888neon,        NEED_SOLID_MASK },
+    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_a8,       PIXMAN_x8r8g8b8, fbCompositeSrc_8888x8x8888neon,        NEED_SOLID_MASK },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_r5g6b5,   fbCompositeSolidMask_nx8x0565neon,     0 },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_b5g6r5,   fbCompositeSolidMask_nx8x0565neon,     0 },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_a8r8g8b8, fbCompositeSolidMask_nx8x8888neon,     0 },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_x8r8g8b8, fbCompositeSolidMask_nx8x8888neon,     0 },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_a8b8g8r8, fbCompositeSolidMask_nx8x8888neon,     0 },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_x8b8g8r8, fbCompositeSolidMask_nx8x8888neon,     0 },
+    { PIXMAN_OP_NONE },
+};
+
+const FastPathInfo *const arm_neon_fast_paths = arm_neon_fast_path_array;
diff --git a/pixman/pixman-arm-neon.h b/pixman/pixman-arm-neon.h
index acfe8a4..f43af65 100644
--- a/pixman/pixman-arm-neon.h
+++ b/pixman/pixman-arm-neon.h
@@ -36,6 +36,8 @@ pixman_bool_t pixman_have_arm_neon(void);
 
 #ifdef USE_ARM_NEON
 
+extern const FastPathInfo *const arm_fast_paths;
+
 void
 fbCompositeSrcAdd_8000x8000neon (pixman_op_t op,
                         pixman_image_t * pSrc,
diff --git a/pixman/pixman-arm-simd.c b/pixman/pixman-arm-simd.c
index ceef1a8..8a6b58c 100644
--- a/pixman/pixman-arm-simd.c
+++ b/pixman/pixman-arm-simd.c
@@ -407,3 +407,24 @@ fbCompositeSolidMask_nx8x8888arm (pixman_op_t      op,
 			);
     }
 }
+
+static const FastPathInfo arm_simd_fast_path_array[] =
+{
+    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null,     PIXMAN_a8r8g8b8, fbCompositeSrc_8888x8888arm,      0 },
+    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null,	PIXMAN_x8r8g8b8, fbCompositeSrc_8888x8888arm,	   0 },
+    { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null,	PIXMAN_a8b8g8r8, fbCompositeSrc_8888x8888arm,	   0 },
+    { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null,	PIXMAN_x8b8g8r8, fbCompositeSrc_8888x8888arm,	   0 },
+    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_a8,       PIXMAN_a8r8g8b8, fbCompositeSrc_8888x8x8888arm,    NEED_SOLID_MASK },
+    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_a8,       PIXMAN_x8r8g8b8, fbCompositeSrc_8888x8x8888arm,	   NEED_SOLID_MASK },
+
+    { PIXMAN_OP_ADD, PIXMAN_a8,        PIXMAN_null,     PIXMAN_a8,       fbCompositeSrcAdd_8000x8000arm,   0 },
+
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_a8r8g8b8, fbCompositeSolidMask_nx8x8888arm,     0 },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_x8r8g8b8, fbCompositeSolidMask_nx8x8888arm,     0 },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_a8b8g8r8, fbCompositeSolidMask_nx8x8888arm,     0 },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_x8b8g8r8, fbCompositeSolidMask_nx8x8888arm,     0 },
+
+    { PIXMAN_OP_NONE },
+};
+
+const FastPathInfo *const arm_simd_fast_paths;
diff --git a/pixman/pixman-arm-simd.h b/pixman/pixman-arm-simd.h
index fae7b94..cc7a035 100644
--- a/pixman/pixman-arm-simd.h
+++ b/pixman/pixman-arm-simd.h
@@ -36,6 +36,8 @@ pixman_bool_t pixman_have_arm_simd(void);
 
 #ifdef USE_ARM_SIMD
 
+extern const FastPathInfo *const arm_simd_fast_paths;
+
 void
 fbCompositeSrcAdd_8000x8000arm (pixman_op_t op,
 				pixman_image_t * pSrc,
diff --git a/pixman/pixman-mmx.c b/pixman/pixman-mmx.c
index 1c9b538..c9f6276 100644
--- a/pixman/pixman-mmx.c
+++ b/pixman/pixman-mmx.c
@@ -39,11 +39,6 @@
 
 #include "pixman-mmx.h"
 
-#undef READ
-#undef WRITE
-#define READ(img,x) *(x)
-#define WRITE(img,ptr,v) (*(ptr) = (v));
-
 #define noVERBOSE
 
 #ifdef VERBOSE
@@ -3022,6 +3017,82 @@ fbCompositeOver_x888x8x8888mmx (pixman_op_t      op,
     _mm_empty();
 }
 
-
+static const FastPathInfo mmx_fast_path_array[] =
+{
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_r5g6b5,   fbCompositeSolidMask_nx8x0565mmx,     0 },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_b5g6r5,   fbCompositeSolidMask_nx8x0565mmx,     0 },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_a8r8g8b8, fbCompositeSolidMask_nx8x8888mmx,     0 },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_x8r8g8b8, fbCompositeSolidMask_nx8x8888mmx,     0 },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_a8b8g8r8, fbCompositeSolidMask_nx8x8888mmx,     0 },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_x8b8g8r8, fbCompositeSolidMask_nx8x8888mmx,     0 },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8r8g8b8, PIXMAN_a8r8g8b8, fbCompositeSolidMask_nx8888x8888Cmmx, NEED_COMPONENT_ALPHA },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8r8g8b8, PIXMAN_x8r8g8b8, fbCompositeSolidMask_nx8888x8888Cmmx, NEED_COMPONENT_ALPHA },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8r8g8b8, PIXMAN_r5g6b5,   fbCompositeSolidMask_nx8888x0565Cmmx, NEED_COMPONENT_ALPHA },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8b8g8r8, PIXMAN_a8b8g8r8, fbCompositeSolidMask_nx8888x8888Cmmx, NEED_COMPONENT_ALPHA },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8b8g8r8, PIXMAN_x8b8g8r8, fbCompositeSolidMask_nx8888x8888Cmmx, NEED_COMPONENT_ALPHA },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8b8g8r8, PIXMAN_b5g6r5,   fbCompositeSolidMask_nx8888x0565Cmmx, NEED_COMPONENT_ALPHA },
+    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8r8g8b8, PIXMAN_a8r8g8b8, fbCompositeSrc_8888RevNPx8888mmx, NEED_PIXBUF },
+    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8b8g8r8, PIXMAN_a8r8g8b8, fbCompositeSrc_8888RevNPx8888mmx, NEED_PIXBUF },
+    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8r8g8b8, PIXMAN_x8r8g8b8, fbCompositeSrc_8888RevNPx8888mmx, NEED_PIXBUF },
+    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8b8g8r8, PIXMAN_x8r8g8b8, fbCompositeSrc_8888RevNPx8888mmx, NEED_PIXBUF },
+    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8r8g8b8, PIXMAN_r5g6b5,   fbCompositeSrc_8888RevNPx0565mmx, NEED_PIXBUF },
+    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8b8g8r8, PIXMAN_r5g6b5,   fbCompositeSrc_8888RevNPx0565mmx, NEED_PIXBUF },
+    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8r8g8b8, PIXMAN_a8b8g8r8, fbCompositeSrc_8888RevNPx8888mmx, NEED_PIXBUF },
+    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8b8g8r8, PIXMAN_a8b8g8r8, fbCompositeSrc_8888RevNPx8888mmx, NEED_PIXBUF },
+    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8r8g8b8, PIXMAN_x8b8g8r8, fbCompositeSrc_8888RevNPx8888mmx, NEED_PIXBUF },
+    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8b8g8r8, PIXMAN_x8b8g8r8, fbCompositeSrc_8888RevNPx8888mmx, NEED_PIXBUF },
+    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8r8g8b8, PIXMAN_b5g6r5,   fbCompositeSrc_8888RevNPx0565mmx, NEED_PIXBUF },
+    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8b8g8r8, PIXMAN_b5g6r5,   fbCompositeSrc_8888RevNPx0565mmx, NEED_PIXBUF },
+    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8,       PIXMAN_a8r8g8b8, fbCompositeSrc_x888xnx8888mmx,    NEED_SOLID_MASK },
+    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8,       PIXMAN_x8r8g8b8, fbCompositeSrc_x888xnx8888mmx,	   NEED_SOLID_MASK },
+    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8,	PIXMAN_a8b8g8r8, fbCompositeSrc_x888xnx8888mmx,	   NEED_SOLID_MASK },
+    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8,	PIXMAN_x8b8g8r8, fbCompositeSrc_x888xnx8888mmx,	   NEED_SOLID_MASK },
+    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_a8,       PIXMAN_a8r8g8b8, fbCompositeSrc_8888x8x8888mmx,    NEED_SOLID_MASK },
+    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_a8,       PIXMAN_x8r8g8b8, fbCompositeSrc_8888x8x8888mmx,	   NEED_SOLID_MASK },
+    { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_a8,	PIXMAN_a8b8g8r8, fbCompositeSrc_8888x8x8888mmx,	   NEED_SOLID_MASK },
+    { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_a8,	PIXMAN_x8b8g8r8, fbCompositeSrc_8888x8x8888mmx,	   NEED_SOLID_MASK },
+#if 0
+    /* FIXME: This code is commented out since it's apparently not actually faster than the generic code. */
+    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8,	PIXMAN_x8r8g8b8, fbCompositeOver_x888x8x8888mmx,   0 },
+    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8,	PIXMAN_a8r8g8b8, fbCompositeOver_x888x8x8888mmx,   0 },
+    { PIXMAN_OP_OVER, PIXMAN_x8b8r8g8, PIXMAN_a8,	PIXMAN_x8b8g8r8, fbCompositeOver_x888x8x8888mmx,   0 },
+    { PIXMAN_OP_OVER, PIXMAN_x8b8r8g8, PIXMAN_a8,	PIXMAN_a8r8g8b8, fbCompositeOver_x888x8x8888mmx,   0 },
+#endif
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_null,	PIXMAN_a8r8g8b8, fbCompositeSolid_nx8888mmx,       0 },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_null,     PIXMAN_x8r8g8b8, fbCompositeSolid_nx8888mmx,	   0 },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_null,     PIXMAN_r5g6b5,   fbCompositeSolid_nx0565mmx,	   0 },
+    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_null,     PIXMAN_x8r8g8b8, fbCompositeCopyAreammx,	   0 },
+    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_null,     PIXMAN_x8b8g8r8, fbCompositeCopyAreammx,	   0 },
+    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null,     PIXMAN_a8r8g8b8, fbCompositeSrc_8888x8888mmx,	   0 },
+    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null,	PIXMAN_x8r8g8b8, fbCompositeSrc_8888x8888mmx,	   0 },
+    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null,	PIXMAN_r5g6b5,	 fbCompositeSrc_8888x0565mmx,	   0 },
+    { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null,	PIXMAN_a8b8g8r8, fbCompositeSrc_8888x8888mmx,	   0 },
+    { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null,	PIXMAN_x8b8g8r8, fbCompositeSrc_8888x8888mmx,	   0 },
+    { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null,     PIXMAN_b5g6r5,   fbCompositeSrc_8888x0565mmx,	   0 },
+
+    { PIXMAN_OP_ADD, PIXMAN_a8r8g8b8,  PIXMAN_null,	PIXMAN_a8r8g8b8, fbCompositeSrcAdd_8888x8888mmx,   0 },
+    { PIXMAN_OP_ADD, PIXMAN_a8b8g8r8,  PIXMAN_null,	PIXMAN_a8b8g8r8, fbCompositeSrcAdd_8888x8888mmx,   0 },
+    { PIXMAN_OP_ADD, PIXMAN_a8,        PIXMAN_null,     PIXMAN_a8,       fbCompositeSrcAdd_8000x8000mmx,   0 },
+    { PIXMAN_OP_ADD, PIXMAN_solid,     PIXMAN_a8,       PIXMAN_a8,       fbCompositeSrcAdd_8888x8x8mmx,    0 },
+
+    { PIXMAN_OP_SRC, PIXMAN_solid,     PIXMAN_a8,       PIXMAN_a8r8g8b8, fbCompositeSolidMaskSrc_nx8x8888mmx, 0 },
+    { PIXMAN_OP_SRC, PIXMAN_solid,     PIXMAN_a8,       PIXMAN_x8r8g8b8, fbCompositeSolidMaskSrc_nx8x8888mmx, 0 },
+    { PIXMAN_OP_SRC, PIXMAN_solid,     PIXMAN_a8,       PIXMAN_a8b8g8r8, fbCompositeSolidMaskSrc_nx8x8888mmx, 0 },
+    { PIXMAN_OP_SRC, PIXMAN_solid,     PIXMAN_a8,       PIXMAN_x8b8g8r8, fbCompositeSolidMaskSrc_nx8x8888mmx, 0 },
+    { PIXMAN_OP_SRC, PIXMAN_a8r8g8b8,  PIXMAN_null,	PIXMAN_a8r8g8b8, fbCompositeCopyAreammx, 0 },
+    { PIXMAN_OP_SRC, PIXMAN_a8b8g8r8,  PIXMAN_null,	PIXMAN_a8b8g8r8, fbCompositeCopyAreammx, 0 },
+    { PIXMAN_OP_SRC, PIXMAN_a8r8g8b8,  PIXMAN_null,	PIXMAN_x8r8g8b8, fbCompositeCopyAreammx, 0 },
+    { PIXMAN_OP_SRC, PIXMAN_a8b8g8r8,  PIXMAN_null,	PIXMAN_x8b8g8r8, fbCompositeCopyAreammx, 0 },
+    { PIXMAN_OP_SRC, PIXMAN_x8r8g8b8,  PIXMAN_null,	PIXMAN_x8r8g8b8, fbCompositeCopyAreammx, 0 },
+    { PIXMAN_OP_SRC, PIXMAN_x8b8g8r8,  PIXMAN_null,	PIXMAN_x8b8g8r8, fbCompositeCopyAreammx, 0 },
+    { PIXMAN_OP_SRC, PIXMAN_r5g6b5,    PIXMAN_null,     PIXMAN_r5g6b5,   fbCompositeCopyAreammx, 0 },
+    { PIXMAN_OP_SRC, PIXMAN_b5g6r5,    PIXMAN_null,     PIXMAN_b5g6r5,   fbCompositeCopyAreammx, 0 },    
+
+    { PIXMAN_OP_IN,  PIXMAN_a8,        PIXMAN_null,     PIXMAN_a8,       fbCompositeIn_8x8mmx,   0 },
+    { PIXMAN_OP_IN,  PIXMAN_solid,     PIXMAN_a8,	PIXMAN_a8,	 fbCompositeIn_nx8x8mmx, 0 },
+
+    { PIXMAN_OP_NONE },
+};
+const FastPathInfo *const mmx_fast_paths = mmx_fast_path_array;
 
 #endif /* USE_MMX */
diff --git a/pixman/pixman-mmx.h b/pixman/pixman-mmx.h
index 611e1ad..de4c46a 100644
--- a/pixman/pixman-mmx.h
+++ b/pixman/pixman-mmx.h
@@ -49,6 +49,8 @@ pixman_bool_t pixman_have_mmx(void);
 
 #ifdef USE_MMX
 
+extern const FastPathInfo *const mmx_fast_paths;
+
 pixman_bool_t 
 pixman_blt_mmx (uint32_t *src_bits,
 		uint32_t *dst_bits,
diff --git a/pixman/pixman-pict.c b/pixman/pixman-pict.c
index 0016528..2298fdd 100644
--- a/pixman/pixman-pict.c
+++ b/pixman/pixman-pict.c
@@ -45,11 +45,6 @@
 #define READ(img,x) (*(x))
 #define WRITE(img,ptr,v) ((*(ptr)) = (v))
 
-typedef void (* CompositeFunc) (pixman_op_t,
-				pixman_image_t *, pixman_image_t *, pixman_image_t *,
-				int16_t, int16_t, int16_t, int16_t, int16_t, int16_t,
-				uint16_t, uint16_t);
-
 static force_inline uint32_t
 fbOver (uint32_t src, uint32_t dest)
 {
@@ -1064,76 +1059,10 @@ fbCompositeSolidMask_nx1xn (pixman_op_t op,
 }
 
 /*
- * Apply a constant alpha value in an over computation
- */
-static void
-fbCompositeSrcSrc_nxn  (pixman_op_t	   op,
-			pixman_image_t * pSrc,
-			pixman_image_t * pMask,
-			pixman_image_t * pDst,
-			int16_t      xSrc,
-			int16_t      ySrc,
-			int16_t      xMask,
-			int16_t      yMask,
-			int16_t      xDst,
-			int16_t      yDst,
-			uint16_t     width,
-			uint16_t     height);
-
-/*
  * Simple bitblt
  */
 
 static void
-fbCompositeSrcSrc_nxn  (pixman_op_t	   op,
-			pixman_image_t * pSrc,
-			pixman_image_t * pMask,
-			pixman_image_t * pDst,
-			int16_t      xSrc,
-			int16_t      ySrc,
-			int16_t      xMask,
-			int16_t      yMask,
-			int16_t      xDst,
-			int16_t      yDst,
-			uint16_t     width,
-			uint16_t     height)
-{
-    /* FIXME */
-#if 0
-    uint32_t	*dst;
-    uint32_t	*src;
-    int	dstStride, srcStride;
-    int		srcXoff, srcYoff;
-    int		dstXoff, dstYoff;
-    int		srcBpp;
-    int		dstBpp;
-    pixman_bool_t	reverse = FALSE;
-    pixman_bool_t	upsidedown = FALSE;
-
-    fbGetDrawable(pSrc->pDrawable,src,srcStride,srcBpp,srcXoff,srcYoff);
-    fbGetDrawable(pDst->pDrawable,dst,dstStride,dstBpp,dstXoff,dstYoff);
-
-    fbBlt (src + (ySrc + srcYoff) * srcStride,
-	   srcStride,
-	   (xSrc + srcXoff) * srcBpp,
-
-	   dst + (yDst + dstYoff) * dstStride,
-	   dstStride,
-	   (xDst + dstXoff) * dstBpp,
-
-	   (width) * dstBpp,
-	   (height),
-
-	   GXcopy,
-	   FB_ALLONES,
-	   dstBpp,
-
-	   reverse,
-	   upsidedown);
-#endif
-}
-
-static void
 pixman_image_composite_rect  (pixman_op_t                   op,
 			      pixman_image_t               *src,
 			      pixman_image_t               *mask,
@@ -1431,236 +1360,6 @@ pixman_image_composite_rect  (pixman_op_t                   op,
     pixman_composite_rect_general (&compose_data);
 }
 
-/* These "formats" both have depth 0, so they
- * will never clash with any real ones
- */
-#define PIXMAN_null		PIXMAN_FORMAT(0,0,0,0,0,0)
-#define PIXMAN_solid		PIXMAN_FORMAT(0,1,0,0,0,0)
-
-#define NEED_COMPONENT_ALPHA		(1 << 0)
-#define NEED_PIXBUF			(1 << 1)
-#define NEED_SOLID_MASK		        (1 << 2)
-
-typedef struct
-{
-    pixman_op_t			op;
-    pixman_format_code_t	src_format;
-    pixman_format_code_t	mask_format;
-    pixman_format_code_t	dest_format;
-    CompositeFunc		func;
-    uint32_t			flags;
-} FastPathInfo;
-
-#ifdef USE_MMX
-static const FastPathInfo mmx_fast_paths[] =
-{
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_r5g6b5,   fbCompositeSolidMask_nx8x0565mmx,     0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_b5g6r5,   fbCompositeSolidMask_nx8x0565mmx,     0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_a8r8g8b8, fbCompositeSolidMask_nx8x8888mmx,     0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_x8r8g8b8, fbCompositeSolidMask_nx8x8888mmx,     0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_a8b8g8r8, fbCompositeSolidMask_nx8x8888mmx,     0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_x8b8g8r8, fbCompositeSolidMask_nx8x8888mmx,     0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8r8g8b8, PIXMAN_a8r8g8b8, fbCompositeSolidMask_nx8888x8888Cmmx, NEED_COMPONENT_ALPHA },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8r8g8b8, PIXMAN_x8r8g8b8, fbCompositeSolidMask_nx8888x8888Cmmx, NEED_COMPONENT_ALPHA },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8r8g8b8, PIXMAN_r5g6b5,   fbCompositeSolidMask_nx8888x0565Cmmx, NEED_COMPONENT_ALPHA },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8b8g8r8, PIXMAN_a8b8g8r8, fbCompositeSolidMask_nx8888x8888Cmmx, NEED_COMPONENT_ALPHA },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8b8g8r8, PIXMAN_x8b8g8r8, fbCompositeSolidMask_nx8888x8888Cmmx, NEED_COMPONENT_ALPHA },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8b8g8r8, PIXMAN_b5g6r5,   fbCompositeSolidMask_nx8888x0565Cmmx, NEED_COMPONENT_ALPHA },
-    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8r8g8b8, PIXMAN_a8r8g8b8, fbCompositeSrc_8888RevNPx8888mmx, NEED_PIXBUF },
-    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8b8g8r8, PIXMAN_a8r8g8b8, fbCompositeSrc_8888RevNPx8888mmx, NEED_PIXBUF },
-    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8r8g8b8, PIXMAN_x8r8g8b8, fbCompositeSrc_8888RevNPx8888mmx, NEED_PIXBUF },
-    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8b8g8r8, PIXMAN_x8r8g8b8, fbCompositeSrc_8888RevNPx8888mmx, NEED_PIXBUF },
-    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8r8g8b8, PIXMAN_r5g6b5,   fbCompositeSrc_8888RevNPx0565mmx, NEED_PIXBUF },
-    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8b8g8r8, PIXMAN_r5g6b5,   fbCompositeSrc_8888RevNPx0565mmx, NEED_PIXBUF },
-    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8r8g8b8, PIXMAN_a8b8g8r8, fbCompositeSrc_8888RevNPx8888mmx, NEED_PIXBUF },
-    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8b8g8r8, PIXMAN_a8b8g8r8, fbCompositeSrc_8888RevNPx8888mmx, NEED_PIXBUF },
-    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8r8g8b8, PIXMAN_x8b8g8r8, fbCompositeSrc_8888RevNPx8888mmx, NEED_PIXBUF },
-    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8b8g8r8, PIXMAN_x8b8g8r8, fbCompositeSrc_8888RevNPx8888mmx, NEED_PIXBUF },
-    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8r8g8b8, PIXMAN_b5g6r5,   fbCompositeSrc_8888RevNPx0565mmx, NEED_PIXBUF },
-    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8b8g8r8, PIXMAN_b5g6r5,   fbCompositeSrc_8888RevNPx0565mmx, NEED_PIXBUF },
-    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8,       PIXMAN_a8r8g8b8, fbCompositeSrc_x888xnx8888mmx,    NEED_SOLID_MASK },
-    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8,       PIXMAN_x8r8g8b8, fbCompositeSrc_x888xnx8888mmx,	   NEED_SOLID_MASK },
-    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8,	PIXMAN_a8b8g8r8, fbCompositeSrc_x888xnx8888mmx,	   NEED_SOLID_MASK },
-    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8,	PIXMAN_x8b8g8r8, fbCompositeSrc_x888xnx8888mmx,	   NEED_SOLID_MASK },
-    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_a8,       PIXMAN_a8r8g8b8, fbCompositeSrc_8888x8x8888mmx,    NEED_SOLID_MASK },
-    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_a8,       PIXMAN_x8r8g8b8, fbCompositeSrc_8888x8x8888mmx,	   NEED_SOLID_MASK },
-    { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_a8,	PIXMAN_a8b8g8r8, fbCompositeSrc_8888x8x8888mmx,	   NEED_SOLID_MASK },
-    { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_a8,	PIXMAN_x8b8g8r8, fbCompositeSrc_8888x8x8888mmx,	   NEED_SOLID_MASK },
-#if 0
-    /* FIXME: This code is commented out since it's apparently not actually faster than the generic code. */
-    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8,	PIXMAN_x8r8g8b8, fbCompositeOver_x888x8x8888mmx,   0 },
-    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8,	PIXMAN_a8r8g8b8, fbCompositeOver_x888x8x8888mmx,   0 },
-    { PIXMAN_OP_OVER, PIXMAN_x8b8r8g8, PIXMAN_a8,	PIXMAN_x8b8g8r8, fbCompositeOver_x888x8x8888mmx,   0 },
-    { PIXMAN_OP_OVER, PIXMAN_x8b8r8g8, PIXMAN_a8,	PIXMAN_a8r8g8b8, fbCompositeOver_x888x8x8888mmx,   0 },
-#endif
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_null,	PIXMAN_a8r8g8b8, fbCompositeSolid_nx8888mmx,        0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_null,     PIXMAN_x8r8g8b8, fbCompositeSolid_nx8888mmx,	   0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_null,     PIXMAN_r5g6b5,   fbCompositeSolid_nx0565mmx,	   0 },
-    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_null,     PIXMAN_x8r8g8b8, fbCompositeCopyAreammx,	   0 },
-    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_null,     PIXMAN_x8b8g8r8, fbCompositeCopyAreammx,	   0 },
-    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null,     PIXMAN_a8r8g8b8, fbCompositeSrc_8888x8888mmx,	   0 },
-    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null,	PIXMAN_x8r8g8b8, fbCompositeSrc_8888x8888mmx,	   0 },
-    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null,	PIXMAN_r5g6b5,	 fbCompositeSrc_8888x0565mmx,	   0 },
-    { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null,	PIXMAN_a8b8g8r8, fbCompositeSrc_8888x8888mmx,	   0 },
-    { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null,	PIXMAN_x8b8g8r8, fbCompositeSrc_8888x8888mmx,	   0 },
-    { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null,     PIXMAN_b5g6r5,   fbCompositeSrc_8888x0565mmx,	   0 },
-
-    { PIXMAN_OP_ADD, PIXMAN_a8r8g8b8,  PIXMAN_null,	PIXMAN_a8r8g8b8, fbCompositeSrcAdd_8888x8888mmx,   0 },
-    { PIXMAN_OP_ADD, PIXMAN_a8b8g8r8,  PIXMAN_null,	PIXMAN_a8b8g8r8, fbCompositeSrcAdd_8888x8888mmx,   0 },
-    { PIXMAN_OP_ADD, PIXMAN_a8,        PIXMAN_null,     PIXMAN_a8,       fbCompositeSrcAdd_8000x8000mmx,   0 },
-    { PIXMAN_OP_ADD, PIXMAN_solid,     PIXMAN_a8,       PIXMAN_a8,       fbCompositeSrcAdd_8888x8x8mmx,    0 },
-    { PIXMAN_OP_SRC, PIXMAN_solid,     PIXMAN_a8,       PIXMAN_a8r8g8b8, fbCompositeSolidMaskSrc_nx8x8888mmx, 0 },
-    { PIXMAN_OP_SRC, PIXMAN_solid,     PIXMAN_a8,       PIXMAN_x8r8g8b8, fbCompositeSolidMaskSrc_nx8x8888mmx, 0 },
-    { PIXMAN_OP_SRC, PIXMAN_solid,     PIXMAN_a8,       PIXMAN_a8b8g8r8, fbCompositeSolidMaskSrc_nx8x8888mmx, 0 },
-    { PIXMAN_OP_SRC, PIXMAN_solid,     PIXMAN_a8,       PIXMAN_x8b8g8r8, fbCompositeSolidMaskSrc_nx8x8888mmx, 0 },
-
-    { PIXMAN_OP_SRC, PIXMAN_a8r8g8b8,  PIXMAN_null,	PIXMAN_a8r8g8b8, fbCompositeCopyAreammx, 0 },
-    { PIXMAN_OP_SRC, PIXMAN_a8b8g8r8,  PIXMAN_null,	PIXMAN_a8b8g8r8, fbCompositeCopyAreammx, 0 },
-    { PIXMAN_OP_SRC, PIXMAN_a8r8g8b8,  PIXMAN_null,	PIXMAN_x8r8g8b8, fbCompositeCopyAreammx, 0 },
-    { PIXMAN_OP_SRC, PIXMAN_a8b8g8r8,  PIXMAN_null,	PIXMAN_x8b8g8r8, fbCompositeCopyAreammx, 0 },
-    { PIXMAN_OP_SRC, PIXMAN_x8r8g8b8,  PIXMAN_null,	PIXMAN_x8r8g8b8, fbCompositeCopyAreammx, 0 },
-    { PIXMAN_OP_SRC, PIXMAN_x8b8g8r8,  PIXMAN_null,	PIXMAN_x8b8g8r8, fbCompositeCopyAreammx, 0 },
-    { PIXMAN_OP_SRC, PIXMAN_r5g6b5,    PIXMAN_null,     PIXMAN_r5g6b5,   fbCompositeCopyAreammx, 0 },
-    { PIXMAN_OP_SRC, PIXMAN_b5g6r5,    PIXMAN_null,     PIXMAN_b5g6r5,   fbCompositeCopyAreammx, 0 },    
-    { PIXMAN_OP_IN,  PIXMAN_a8,        PIXMAN_null,     PIXMAN_a8,       fbCompositeIn_8x8mmx,   0 },
-    { PIXMAN_OP_IN,  PIXMAN_solid,     PIXMAN_a8,	PIXMAN_a8,	 fbCompositeIn_nx8x8mmx, 0 },
-    { PIXMAN_OP_NONE },
-};
-#endif
-
-#ifdef USE_SSE2
-static const FastPathInfo sse2_fast_paths[] =
-{
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_r5g6b5,   fbCompositeSolidMask_nx8x0565sse2,     0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_b5g6r5,   fbCompositeSolidMask_nx8x0565sse2,     0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_null,     PIXMAN_a8r8g8b8, fbCompositeSolid_nx8888sse2,           0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_null,     PIXMAN_x8r8g8b8, fbCompositeSolid_nx8888sse2,           0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_null,     PIXMAN_r5g6b5,   fbCompositeSolid_nx0565sse2,           0 },
-    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null,     PIXMAN_a8r8g8b8, fbCompositeSrc_8888x8888sse2,          0 },
-    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null,     PIXMAN_x8r8g8b8, fbCompositeSrc_8888x8888sse2,          0 },
-    { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null,     PIXMAN_a8b8g8r8, fbCompositeSrc_8888x8888sse2,          0 },
-    { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null,     PIXMAN_x8b8g8r8, fbCompositeSrc_8888x8888sse2,          0 },
-    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null,     PIXMAN_r5g6b5,   fbCompositeSrc_8888x0565sse2,          0 },
-    { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null,     PIXMAN_b5g6r5,   fbCompositeSrc_8888x0565sse2,          0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_a8r8g8b8, fbCompositeSolidMask_nx8x8888sse2,     0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_x8r8g8b8, fbCompositeSolidMask_nx8x8888sse2,     0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_a8b8g8r8, fbCompositeSolidMask_nx8x8888sse2,     0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_x8b8g8r8, fbCompositeSolidMask_nx8x8888sse2,     0 },
-#if 0
-    /* FIXME: This code are buggy in MMX version, now the bug was translated to SSE2 version */
-    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8,       PIXMAN_x8r8g8b8, fbCompositeOver_x888x8x8888sse2,       0 },
-    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8,       PIXMAN_a8r8g8b8, fbCompositeOver_x888x8x8888sse2,       0 },
-    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8,       PIXMAN_x8b8g8r8, fbCompositeOver_x888x8x8888sse2,       0 },
-    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8,       PIXMAN_a8r8g8b8, fbCompositeOver_x888x8x8888sse2,       0 },
-#endif
-    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8,       PIXMAN_a8r8g8b8, fbCompositeSrc_x888xnx8888sse2,        NEED_SOLID_MASK },
-    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8,       PIXMAN_x8r8g8b8, fbCompositeSrc_x888xnx8888sse2,        NEED_SOLID_MASK },
-    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8,       PIXMAN_a8b8g8r8, fbCompositeSrc_x888xnx8888sse2,        NEED_SOLID_MASK },
-    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8,       PIXMAN_x8b8g8r8, fbCompositeSrc_x888xnx8888sse2,        NEED_SOLID_MASK },
-    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_a8,       PIXMAN_a8r8g8b8, fbCompositeSrc_8888x8x8888sse2,        NEED_SOLID_MASK },
-    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_a8,       PIXMAN_x8r8g8b8, fbCompositeSrc_8888x8x8888sse2,        NEED_SOLID_MASK },
-    { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_a8,       PIXMAN_a8b8g8r8, fbCompositeSrc_8888x8x8888sse2,        NEED_SOLID_MASK },
-    { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_a8,       PIXMAN_x8b8g8r8, fbCompositeSrc_8888x8x8888sse2,        NEED_SOLID_MASK },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8r8g8b8, PIXMAN_a8r8g8b8, fbCompositeSolidMask_nx8888x8888Csse2, NEED_COMPONENT_ALPHA },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8r8g8b8, PIXMAN_x8r8g8b8, fbCompositeSolidMask_nx8888x8888Csse2, NEED_COMPONENT_ALPHA },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8b8g8r8, PIXMAN_a8b8g8r8, fbCompositeSolidMask_nx8888x8888Csse2, NEED_COMPONENT_ALPHA },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8b8g8r8, PIXMAN_x8b8g8r8, fbCompositeSolidMask_nx8888x8888Csse2, NEED_COMPONENT_ALPHA },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8r8g8b8, PIXMAN_r5g6b5,   fbCompositeSolidMask_nx8888x0565Csse2, NEED_COMPONENT_ALPHA },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8b8g8r8, PIXMAN_b5g6r5,   fbCompositeSolidMask_nx8888x0565Csse2, NEED_COMPONENT_ALPHA },
-    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8r8g8b8, PIXMAN_a8r8g8b8, fbCompositeSrc_8888RevNPx8888sse2,     NEED_PIXBUF },
-    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8b8g8r8, PIXMAN_a8r8g8b8, fbCompositeSrc_8888RevNPx8888sse2,     NEED_PIXBUF },
-    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8r8g8b8, PIXMAN_x8r8g8b8, fbCompositeSrc_8888RevNPx8888sse2,     NEED_PIXBUF },
-    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8b8g8r8, PIXMAN_x8r8g8b8, fbCompositeSrc_8888RevNPx8888sse2,     NEED_PIXBUF },
-    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8r8g8b8, PIXMAN_a8b8g8r8, fbCompositeSrc_8888RevNPx8888sse2,     NEED_PIXBUF },
-    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8b8g8r8, PIXMAN_a8b8g8r8, fbCompositeSrc_8888RevNPx8888sse2,     NEED_PIXBUF },
-    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8r8g8b8, PIXMAN_x8b8g8r8, fbCompositeSrc_8888RevNPx8888sse2,     NEED_PIXBUF },
-    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8b8g8r8, PIXMAN_x8b8g8r8, fbCompositeSrc_8888RevNPx8888sse2,     NEED_PIXBUF },
-    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8r8g8b8, PIXMAN_r5g6b5,   fbCompositeSrc_8888RevNPx0565sse2,     NEED_PIXBUF },
-    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8b8g8r8, PIXMAN_r5g6b5,   fbCompositeSrc_8888RevNPx0565sse2,     NEED_PIXBUF },
-    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8r8g8b8, PIXMAN_b5g6r5,   fbCompositeSrc_8888RevNPx0565sse2,     NEED_PIXBUF },
-    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8b8g8r8, PIXMAN_b5g6r5,   fbCompositeSrc_8888RevNPx0565sse2,     NEED_PIXBUF },
-    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_null,     PIXMAN_x8r8g8b8, fbCompositeCopyAreasse2,               0 },
-    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_null,     PIXMAN_x8b8g8r8, fbCompositeCopyAreasse2,               0 },
-
-    { PIXMAN_OP_ADD,  PIXMAN_a8,       PIXMAN_null,     PIXMAN_a8,       fbCompositeSrcAdd_8000x8000sse2,       0 },
-    { PIXMAN_OP_ADD,  PIXMAN_a8r8g8b8, PIXMAN_null,     PIXMAN_a8r8g8b8, fbCompositeSrcAdd_8888x8888sse2,       0 },
-    { PIXMAN_OP_ADD,  PIXMAN_a8b8g8r8, PIXMAN_null,     PIXMAN_a8b8g8r8, fbCompositeSrcAdd_8888x8888sse2,       0 },
-    { PIXMAN_OP_ADD,  PIXMAN_solid,    PIXMAN_a8,       PIXMAN_a8,       fbCompositeSrcAdd_8888x8x8sse2,        0 },
-
-    { PIXMAN_OP_SRC, PIXMAN_solid,     PIXMAN_a8,       PIXMAN_a8r8g8b8, fbCompositeSolidMaskSrc_nx8x8888sse2,  0 },
-    { PIXMAN_OP_SRC, PIXMAN_solid,     PIXMAN_a8,       PIXMAN_x8r8g8b8, fbCompositeSolidMaskSrc_nx8x8888sse2,  0 },
-    { PIXMAN_OP_SRC, PIXMAN_solid,     PIXMAN_a8,       PIXMAN_a8b8g8r8, fbCompositeSolidMaskSrc_nx8x8888sse2,  0 },
-    { PIXMAN_OP_SRC, PIXMAN_solid,     PIXMAN_a8,       PIXMAN_x8b8g8r8, fbCompositeSolidMaskSrc_nx8x8888sse2,  0 },
-
-    { PIXMAN_OP_SRC, PIXMAN_a8r8g8b8,  PIXMAN_null,     PIXMAN_a8r8g8b8, fbCompositeCopyAreasse2,               0 },
-    { PIXMAN_OP_SRC, PIXMAN_a8b8g8r8,  PIXMAN_null,     PIXMAN_a8b8g8r8, fbCompositeCopyAreasse2,               0 },
-    { PIXMAN_OP_SRC, PIXMAN_a8r8g8b8,  PIXMAN_null,     PIXMAN_x8r8g8b8, fbCompositeCopyAreasse2,		0 },
-    { PIXMAN_OP_SRC, PIXMAN_a8b8g8r8,  PIXMAN_null,	PIXMAN_x8b8g8r8, fbCompositeCopyAreasse2,		0 },
-    { PIXMAN_OP_SRC, PIXMAN_x8r8g8b8,  PIXMAN_null,     PIXMAN_x8r8g8b8, fbCompositeCopyAreasse2,               0 },
-    { PIXMAN_OP_SRC, PIXMAN_x8b8g8r8,  PIXMAN_null,     PIXMAN_x8b8g8r8, fbCompositeCopyAreasse2,               0 },
-    { PIXMAN_OP_SRC, PIXMAN_r5g6b5,    PIXMAN_null,     PIXMAN_r5g6b5,   fbCompositeCopyAreasse2,               0 },
-    { PIXMAN_OP_SRC, PIXMAN_b5g6r5,    PIXMAN_null,     PIXMAN_b5g6r5,   fbCompositeCopyAreasse2,               0 },
-
-    { PIXMAN_OP_IN,  PIXMAN_a8,        PIXMAN_null,     PIXMAN_a8,       fbCompositeIn_8x8sse2,                 0 },
-    { PIXMAN_OP_IN,  PIXMAN_solid,     PIXMAN_a8,       PIXMAN_a8,       fbCompositeIn_nx8x8sse2,               0 },
-
-    { PIXMAN_OP_NONE },
-};
-#endif
-
-#ifdef USE_VMX
-static const FastPathInfo vmx_fast_paths[] =
-{
-    { PIXMAN_OP_NONE },
-};
-#endif
-
-#ifdef USE_ARM_NEON
-static const FastPathInfo arm_neon_fast_paths[] =
-{
-    { PIXMAN_OP_ADD,  PIXMAN_solid,    PIXMAN_a8,       PIXMAN_a8,       fbCompositeSrcAdd_8888x8x8neon,        0 },
-    { PIXMAN_OP_ADD,  PIXMAN_a8,       PIXMAN_null,     PIXMAN_a8,       fbCompositeSrcAdd_8000x8000neon,       0 },
-    { PIXMAN_OP_SRC,  PIXMAN_a8r8g8b8, PIXMAN_null,     PIXMAN_r5g6b5,   fbCompositeSrc_x888x0565neon,          0 },
-    { PIXMAN_OP_SRC,  PIXMAN_x8r8g8b8, PIXMAN_null,     PIXMAN_r5g6b5,   fbCompositeSrc_x888x0565neon,          0 },
-    { PIXMAN_OP_SRC,  PIXMAN_a8b8g8r8, PIXMAN_null,     PIXMAN_b5g6r5,   fbCompositeSrc_x888x0565neon,          0 },
-    { PIXMAN_OP_SRC,  PIXMAN_x8b8g8r8, PIXMAN_null,     PIXMAN_b5g6r5,   fbCompositeSrc_x888x0565neon,          0 },
-    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null,     PIXMAN_a8r8g8b8, fbCompositeSrc_8888x8888neon,          0 },
-    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null,     PIXMAN_x8r8g8b8, fbCompositeSrc_8888x8888neon,          0 },
-    { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null,     PIXMAN_a8b8g8r8, fbCompositeSrc_8888x8888neon,          0 },
-    { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null,     PIXMAN_x8b8g8r8, fbCompositeSrc_8888x8888neon,          0 },
-    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_a8,       PIXMAN_a8r8g8b8, fbCompositeSrc_8888x8x8888neon,        NEED_SOLID_MASK },
-    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_a8,       PIXMAN_x8r8g8b8, fbCompositeSrc_8888x8x8888neon,        NEED_SOLID_MASK },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_r5g6b5,   fbCompositeSolidMask_nx8x0565neon,     0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_b5g6r5,   fbCompositeSolidMask_nx8x0565neon,     0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_a8r8g8b8, fbCompositeSolidMask_nx8x8888neon,     0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_x8r8g8b8, fbCompositeSolidMask_nx8x8888neon,     0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_a8b8g8r8, fbCompositeSolidMask_nx8x8888neon,     0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_x8b8g8r8, fbCompositeSolidMask_nx8x8888neon,     0 },
-    { PIXMAN_OP_NONE },
-};
-#endif
-
-#ifdef USE_ARM_SIMD
-static const FastPathInfo arm_simd_fast_paths[] =
-{
-    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null,     PIXMAN_a8r8g8b8, fbCompositeSrc_8888x8888arm,      0 },
-    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null,	PIXMAN_x8r8g8b8, fbCompositeSrc_8888x8888arm,	   0 },
-    { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null,	PIXMAN_a8b8g8r8, fbCompositeSrc_8888x8888arm,	   0 },
-    { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null,	PIXMAN_x8b8g8r8, fbCompositeSrc_8888x8888arm,	   0 },
-    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_a8,       PIXMAN_a8r8g8b8, fbCompositeSrc_8888x8x8888arm,    NEED_SOLID_MASK },
-    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_a8,       PIXMAN_x8r8g8b8, fbCompositeSrc_8888x8x8888arm,	   NEED_SOLID_MASK },
-
-    { PIXMAN_OP_ADD, PIXMAN_a8,        PIXMAN_null,     PIXMAN_a8,       fbCompositeSrcAdd_8000x8000arm,   0 },
-
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_a8r8g8b8, fbCompositeSolidMask_nx8x8888arm,     0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_x8r8g8b8, fbCompositeSolidMask_nx8x8888arm,     0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_a8b8g8r8, fbCompositeSolidMask_nx8x8888arm,     0 },
-    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_x8b8g8r8, fbCompositeSolidMask_nx8x8888arm,     0 },
-
-    { PIXMAN_OP_NONE },
-};
-#endif
-
 static const FastPathInfo c_fast_paths[] =
 {
     { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_r5g6b5,   fbCompositeSolidMask_nx8x0565, 0 },
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 6f9575a..805b5ce 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -149,6 +149,32 @@ typedef struct bits_image bits_image_t;
 typedef struct circle circle_t;
 typedef struct point point_t;
 
+typedef void (* CompositeFunc) (pixman_op_t,
+				pixman_image_t *, pixman_image_t *, pixman_image_t *,
+				int16_t, int16_t, int16_t, int16_t, int16_t, int16_t,
+				uint16_t, uint16_t);
+
+
+/* These "formats" both have depth 0, so they
+ * will never clash with any real ones
+ */
+#define PIXMAN_null		PIXMAN_FORMAT(0,0,0,0,0,0)
+#define PIXMAN_solid		PIXMAN_FORMAT(0,1,0,0,0,0)
+
+#define NEED_COMPONENT_ALPHA		(1 << 0)
+#define NEED_PIXBUF			(1 << 1)
+#define NEED_SOLID_MASK		        (1 << 2)
+
+typedef struct
+{
+    pixman_op_t			op;
+    pixman_format_code_t	src_format;
+    pixman_format_code_t	mask_format;
+    pixman_format_code_t	dest_format;
+    CompositeFunc		func;
+    uint32_t			flags;
+} FastPathInfo;
+
 /* FIXME - the types and structures below should be give proper names
  */
 
diff --git a/pixman/pixman-sse2.c b/pixman/pixman-sse2.c
index 995c714..240d079 100644
--- a/pixman/pixman-sse2.c
+++ b/pixman/pixman-sse2.c
@@ -4889,6 +4889,85 @@ fbCompositeOver_x888x8x8888sse2 (pixman_op_t      op,
 
     _mm_empty();
 }
-#endif /* #if 0 */
+#endif
+
+static const FastPathInfo sse2_fast_path_array[] =
+{
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_r5g6b5,   fbCompositeSolidMask_nx8x0565sse2,     0 },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_b5g6r5,   fbCompositeSolidMask_nx8x0565sse2,     0 },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_null,     PIXMAN_a8r8g8b8, fbCompositeSolid_nx8888sse2,           0 },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_null,     PIXMAN_x8r8g8b8, fbCompositeSolid_nx8888sse2,           0 },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_null,     PIXMAN_r5g6b5,   fbCompositeSolid_nx0565sse2,           0 },
+    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null,     PIXMAN_a8r8g8b8, fbCompositeSrc_8888x8888sse2,          0 },
+    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null,     PIXMAN_x8r8g8b8, fbCompositeSrc_8888x8888sse2,          0 },
+    { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null,     PIXMAN_a8b8g8r8, fbCompositeSrc_8888x8888sse2,          0 },
+    { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null,     PIXMAN_x8b8g8r8, fbCompositeSrc_8888x8888sse2,          0 },
+    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_null,     PIXMAN_r5g6b5,   fbCompositeSrc_8888x0565sse2,          0 },
+    { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_null,     PIXMAN_b5g6r5,   fbCompositeSrc_8888x0565sse2,          0 },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_a8r8g8b8, fbCompositeSolidMask_nx8x8888sse2,     0 },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_x8r8g8b8, fbCompositeSolidMask_nx8x8888sse2,     0 },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_a8b8g8r8, fbCompositeSolidMask_nx8x8888sse2,     0 },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8,       PIXMAN_x8b8g8r8, fbCompositeSolidMask_nx8x8888sse2,     0 },
+#if 0
+    /* FIXME: This code are buggy in MMX version, now the bug was translated to SSE2 version */
+    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8,       PIXMAN_x8r8g8b8, fbCompositeOver_x888x8x8888sse2,       0 },
+    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8,       PIXMAN_a8r8g8b8, fbCompositeOver_x888x8x8888sse2,       0 },
+    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8,       PIXMAN_x8b8g8r8, fbCompositeOver_x888x8x8888sse2,       0 },
+    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8,       PIXMAN_a8r8g8b8, fbCompositeOver_x888x8x8888sse2,       0 },
+#endif
+    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8,       PIXMAN_a8r8g8b8, fbCompositeSrc_x888xnx8888sse2,        NEED_SOLID_MASK },
+    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8,       PIXMAN_x8r8g8b8, fbCompositeSrc_x888xnx8888sse2,        NEED_SOLID_MASK },
+    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8,       PIXMAN_a8b8g8r8, fbCompositeSrc_x888xnx8888sse2,        NEED_SOLID_MASK },
+    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8,       PIXMAN_x8b8g8r8, fbCompositeSrc_x888xnx8888sse2,        NEED_SOLID_MASK },
+    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_a8,       PIXMAN_a8r8g8b8, fbCompositeSrc_8888x8x8888sse2,        NEED_SOLID_MASK },
+    { PIXMAN_OP_OVER, PIXMAN_a8r8g8b8, PIXMAN_a8,       PIXMAN_x8r8g8b8, fbCompositeSrc_8888x8x8888sse2,        NEED_SOLID_MASK },
+    { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_a8,       PIXMAN_a8b8g8r8, fbCompositeSrc_8888x8x8888sse2,        NEED_SOLID_MASK },
+    { PIXMAN_OP_OVER, PIXMAN_a8b8g8r8, PIXMAN_a8,       PIXMAN_x8b8g8r8, fbCompositeSrc_8888x8x8888sse2,        NEED_SOLID_MASK },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8r8g8b8, PIXMAN_a8r8g8b8, fbCompositeSolidMask_nx8888x8888Csse2, NEED_COMPONENT_ALPHA },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8r8g8b8, PIXMAN_x8r8g8b8, fbCompositeSolidMask_nx8888x8888Csse2, NEED_COMPONENT_ALPHA },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8b8g8r8, PIXMAN_a8b8g8r8, fbCompositeSolidMask_nx8888x8888Csse2, NEED_COMPONENT_ALPHA },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8b8g8r8, PIXMAN_x8b8g8r8, fbCompositeSolidMask_nx8888x8888Csse2, NEED_COMPONENT_ALPHA },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8r8g8b8, PIXMAN_r5g6b5,   fbCompositeSolidMask_nx8888x0565Csse2, NEED_COMPONENT_ALPHA },
+    { PIXMAN_OP_OVER, PIXMAN_solid,    PIXMAN_a8b8g8r8, PIXMAN_b5g6r5,   fbCompositeSolidMask_nx8888x0565Csse2, NEED_COMPONENT_ALPHA },
+    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8r8g8b8, PIXMAN_a8r8g8b8, fbCompositeSrc_8888RevNPx8888sse2,     NEED_PIXBUF },
+    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8b8g8r8, PIXMAN_a8r8g8b8, fbCompositeSrc_8888RevNPx8888sse2,     NEED_PIXBUF },
+    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8r8g8b8, PIXMAN_x8r8g8b8, fbCompositeSrc_8888RevNPx8888sse2,     NEED_PIXBUF },
+    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8b8g8r8, PIXMAN_x8r8g8b8, fbCompositeSrc_8888RevNPx8888sse2,     NEED_PIXBUF },
+    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8r8g8b8, PIXMAN_a8b8g8r8, fbCompositeSrc_8888RevNPx8888sse2,     NEED_PIXBUF },
+    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8b8g8r8, PIXMAN_a8b8g8r8, fbCompositeSrc_8888RevNPx8888sse2,     NEED_PIXBUF },
+    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8r8g8b8, PIXMAN_x8b8g8r8, fbCompositeSrc_8888RevNPx8888sse2,     NEED_PIXBUF },
+    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8b8g8r8, PIXMAN_x8b8g8r8, fbCompositeSrc_8888RevNPx8888sse2,     NEED_PIXBUF },
+    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8r8g8b8, PIXMAN_r5g6b5,   fbCompositeSrc_8888RevNPx0565sse2,     NEED_PIXBUF },
+    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_a8b8g8r8, PIXMAN_r5g6b5,   fbCompositeSrc_8888RevNPx0565sse2,     NEED_PIXBUF },
+    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8r8g8b8, PIXMAN_b5g6r5,   fbCompositeSrc_8888RevNPx0565sse2,     NEED_PIXBUF },
+    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_a8b8g8r8, PIXMAN_b5g6r5,   fbCompositeSrc_8888RevNPx0565sse2,     NEED_PIXBUF },
+    { PIXMAN_OP_OVER, PIXMAN_x8r8g8b8, PIXMAN_null,     PIXMAN_x8r8g8b8, fbCompositeCopyAreasse2,               0 },
+    { PIXMAN_OP_OVER, PIXMAN_x8b8g8r8, PIXMAN_null,     PIXMAN_x8b8g8r8, fbCompositeCopyAreasse2,               0 },
+
+    { PIXMAN_OP_ADD,  PIXMAN_a8,       PIXMAN_null,     PIXMAN_a8,       fbCompositeSrcAdd_8000x8000sse2,       0 },
+    { PIXMAN_OP_ADD,  PIXMAN_a8r8g8b8, PIXMAN_null,     PIXMAN_a8r8g8b8, fbCompositeSrcAdd_8888x8888sse2,       0 },
+    { PIXMAN_OP_ADD,  PIXMAN_a8b8g8r8, PIXMAN_null,     PIXMAN_a8b8g8r8, fbCompositeSrcAdd_8888x8888sse2,       0 },
+    { PIXMAN_OP_ADD,  PIXMAN_solid,    PIXMAN_a8,       PIXMAN_a8,       fbCompositeSrcAdd_8888x8x8sse2,        0 },
+
+    { PIXMAN_OP_SRC, PIXMAN_solid,     PIXMAN_a8,       PIXMAN_a8r8g8b8, fbCompositeSolidMaskSrc_nx8x8888sse2,  0 },
+    { PIXMAN_OP_SRC, PIXMAN_solid,     PIXMAN_a8,       PIXMAN_x8r8g8b8, fbCompositeSolidMaskSrc_nx8x8888sse2,  0 },
+    { PIXMAN_OP_SRC, PIXMAN_solid,     PIXMAN_a8,       PIXMAN_a8b8g8r8, fbCompositeSolidMaskSrc_nx8x8888sse2,  0 },
+    { PIXMAN_OP_SRC, PIXMAN_solid,     PIXMAN_a8,       PIXMAN_x8b8g8r8, fbCompositeSolidMaskSrc_nx8x8888sse2,  0 },
+    { PIXMAN_OP_SRC, PIXMAN_a8r8g8b8,  PIXMAN_null,     PIXMAN_a8r8g8b8, fbCompositeCopyAreasse2,               0 },
+    { PIXMAN_OP_SRC, PIXMAN_a8b8g8r8,  PIXMAN_null,     PIXMAN_a8b8g8r8, fbCompositeCopyAreasse2,               0 },
+    { PIXMAN_OP_SRC, PIXMAN_a8r8g8b8,  PIXMAN_null,     PIXMAN_x8r8g8b8, fbCompositeCopyAreasse2,		0 },
+    { PIXMAN_OP_SRC, PIXMAN_a8b8g8r8,  PIXMAN_null,	PIXMAN_x8b8g8r8, fbCompositeCopyAreasse2,		0 },
+    { PIXMAN_OP_SRC, PIXMAN_x8r8g8b8,  PIXMAN_null,     PIXMAN_x8r8g8b8, fbCompositeCopyAreasse2,               0 },
+    { PIXMAN_OP_SRC, PIXMAN_x8b8g8r8,  PIXMAN_null,     PIXMAN_x8b8g8r8, fbCompositeCopyAreasse2,               0 },
+    { PIXMAN_OP_SRC, PIXMAN_r5g6b5,    PIXMAN_null,     PIXMAN_r5g6b5,   fbCompositeCopyAreasse2,               0 },
+    { PIXMAN_OP_SRC, PIXMAN_b5g6r5,    PIXMAN_null,     PIXMAN_b5g6r5,   fbCompositeCopyAreasse2,               0 },
+
+    { PIXMAN_OP_IN,  PIXMAN_a8,        PIXMAN_null,     PIXMAN_a8,       fbCompositeIn_8x8sse2,                 0 },
+    { PIXMAN_OP_IN,  PIXMAN_solid,     PIXMAN_a8,       PIXMAN_a8,       fbCompositeIn_nx8x8sse2,               0 },
+
+    { PIXMAN_OP_NONE },
+};
+
+const FastPathInfo *const sse2_fast_paths = sse2_fast_path_array;
 
 #endif /* USE_SSE2 */
diff --git a/pixman/pixman-sse2.h b/pixman/pixman-sse2.h
index 2bcbf97..783fcdf 100644
--- a/pixman/pixman-sse2.h
+++ b/pixman/pixman-sse2.h
@@ -49,6 +49,8 @@ pixman_bool_t pixman_have_sse2(void);
 
 #ifdef USE_SSE2
 
+extern const FastPathInfo *const sse2_fast_paths;
+
 void fbComposeSetupSSE2(void);
 
 pixman_bool_t
diff --git a/pixman/pixman-vmx.c b/pixman/pixman-vmx.c
index 6478b90..adcd967 100644
--- a/pixman/pixman-vmx.c
+++ b/pixman/pixman-vmx.c
@@ -1031,3 +1031,10 @@ void fbComposeSetupVMX (void)
         pixman_composeFunctions.combineC[PIXMAN_OP_ADD] = vmxCombineAddC;
     }
 }
+
+static const FastPathInfo vmx_fast_path_array[] =
+{
+    { PIXMAN_OP_NONE },
+};
+
+const FastPathInfo *const vmx_fast_paths = vmx_fast_path_array;
diff --git a/pixman/pixman-vmx.h b/pixman/pixman-vmx.h
index 70cb53a..2672004 100644
--- a/pixman/pixman-vmx.h
+++ b/pixman/pixman-vmx.h
@@ -37,6 +37,8 @@ pixman_bool_t pixman_have_vmx(void);
 
 #ifdef USE_VMX
 
+extern const FastPathInfo *const vmx_fast_paths = vmx_fast_path_array;
+
 #define AVV(x...) {x}
 
 void fbComposeSetupVMX (void);
commit 93900a591c530a310542dfcca7e41d3391dc3565
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Sun May 3 19:12:02 2009 -0400

    Move CPU detection code to its own file

diff --git a/pixman/Makefile.am b/pixman/Makefile.am
index 07452f1..ea5ec67 100644
--- a/pixman/Makefile.am
+++ b/pixman/Makefile.am
@@ -6,6 +6,7 @@ libpixman_1_la_SOURCES =		\
 	pixman.h			\
 	pixman-access.c			\
 	pixman-access-accessors.c	\
+	pixman-cpu.c			\
 	pixman-gradient-walker.c	\
 	pixman-region16.c		\
 	pixman-region32.c		\
diff --git a/pixman/pixman-cpu.c b/pixman/pixman-cpu.c
new file mode 100644
index 0000000..dc68b31
--- /dev/null
+++ b/pixman/pixman-cpu.c
@@ -0,0 +1,498 @@
+/*
+ * Copyright © 2000 SuSE, Inc.
+ * Copyright © 2007 Red Hat, Inc.
+ *
+ * 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#if defined(USE_ARM_SIMD) && defined(_MSC_VER)
+/* Needed for EXCEPTION_ILLEGAL_INSTRUCTION */
+#include <windows.h>
+#endif
+
+#include "pixman-private.h"
+
+#ifdef USE_VMX
+
+/* The CPU detection code needs to be in a file not compiled with
+ * "-maltivec -mabi=altivec", as gcc would try to save vector register
+ * across function calls causing SIGILL on cpus without Altivec/vmx.
+ */
+static pixman_bool_t initialized = FALSE;
+static volatile pixman_bool_t have_vmx = TRUE;
+
+#ifdef __APPLE__
+#include <sys/sysctl.h>
+
+pixman_bool_t
+pixman_have_vmx (void)
+{
+    if(!initialized) {
+        size_t length = sizeof(have_vmx);
+        int error =
+            sysctlbyname("hw.optional.altivec", &have_vmx, &length, NULL, 0);
+        if(error) have_vmx = FALSE;
+        initialized = TRUE;
+    }
+    return have_vmx;
+}
+
+#elif defined (__linux__)
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <linux/auxvec.h>
+#include <asm/cputable.h>
+
+pixman_bool_t
+pixman_have_vmx (void)
+{
+    if (!initialized) {
+	char fname[64];
+	unsigned long buf[64];
+	ssize_t count = 0;
+	pid_t pid;
+	int fd, i;
+
+	pid = getpid();
+	snprintf(fname, sizeof(fname)-1, "/proc/%d/auxv", pid);
+
+	fd = open(fname, O_RDONLY);
+	if (fd >= 0) {
+	    for (i = 0; i <= (count / sizeof(unsigned long)); i += 2) {
+		/* Read more if buf is empty... */
+		if (i == (count / sizeof(unsigned long))) {
+		    count = read(fd, buf, sizeof(buf));
+		    if (count <= 0)
+			break;
+		    i = 0;
+		}
+
+		if (buf[i] == AT_HWCAP) {
+		    have_vmx = !!(buf[i+1] & PPC_FEATURE_HAS_ALTIVEC);
+		    initialized = TRUE;
+		    break;
+		} else if (buf[i] == AT_NULL) {
+		    break;
+		}
+	    }
+	    close(fd);
+	}
+    }
+    if (!initialized) {
+	/* Something went wrong. Assume 'no' rather than playing
+	   fragile tricks with catching SIGILL. */
+	have_vmx = FALSE;
+	initialized = TRUE;
+    }
+
+    return have_vmx;
+}
+#else /* !__APPLE__ && !__linux__ */
+#include <signal.h>
+#include <setjmp.h>
+
+static jmp_buf jump_env;
+
+static void vmx_test(int sig, siginfo_t *si, void *unused) {
+    longjmp (jump_env, 1);
+}
+
+pixman_bool_t pixman_have_vmx (void) {
+    struct sigaction sa, osa;
+    int jmp_result;
+    if (!initialized) {
+        sa.sa_flags = SA_SIGINFO;
+        sigemptyset(&sa.sa_mask);
+        sa.sa_sigaction = vmx_test;
+        sigaction(SIGILL, &sa, &osa);
+	jmp_result = setjmp (jump_env);
+	if (jmp_result == 0) {
+	    asm volatile ( "vor 0, 0, 0" );
+	}
+        sigaction(SIGILL, &osa, NULL);
+	have_vmx = (jmp_result == 0);
+        initialized = TRUE;
+    }
+    return have_vmx;
+}
+#endif /* __APPLE__ */
+#endif /* USE_VMX */
+
+#if defined(USE_ARM_SIMD) || defined(USE_ARM_NEON)
+
+#if defined(_MSC_VER)
+
+#if defined(USE_ARM_SIMD)
+extern int pixman_msvc_try_arm_simd_op();
+
+pixman_bool_t
+pixman_have_arm_simd (void)
+{
+    static pixman_bool_t initialized = FALSE;
+    static pixman_bool_t have_arm_simd = FALSE;
+
+    if (!initialized) {
+        __try {
+            pixman_msvc_try_arm_simd_op();
+            have_arm_simd = TRUE;
+        } __except(GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION) {
+            have_arm_simd = FALSE;
+        }
+	initialized = TRUE;
+    }
+
+    return have_arm_simd;
+}
+#endif /* USE_ARM_SIMD */
+
+#if defined(USE_ARM_NEON)
+extern int pixman_msvc_try_arm_neon_op();
+
+pixman_bool_t
+pixman_have_arm_neon (void)
+{
+    static pixman_bool_t initialized = FALSE;
+    static pixman_bool_t have_arm_neon = FALSE;
+
+    if (!initialized) {
+        __try {
+            pixman_msvc_try_arm_neon_op();
+            have_arm_neon = TRUE;
+        } __except(GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION) {
+            have_arm_neon = FALSE;
+        }
+	initialized = TRUE;
+    }
+
+    return have_arm_neon;
+}
+#endif /* USE_ARM_NEON */
+
+#else /* linux ELF */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <string.h>
+#include <elf.h>
+
+static pixman_bool_t arm_has_v7 = FALSE;
+static pixman_bool_t arm_has_v6 = FALSE;
+static pixman_bool_t arm_has_vfp = FALSE;
+static pixman_bool_t arm_has_neon = FALSE;
+static pixman_bool_t arm_has_iwmmxt = FALSE;
+static pixman_bool_t arm_tests_initialized = FALSE;
+
+static void
+pixman_arm_read_auxv() {
+    int fd;
+    Elf32_auxv_t aux;
+
+    fd = open("/proc/self/auxv", O_RDONLY);
+    if (fd >= 0) {
+        while (read(fd, &aux, sizeof(Elf32_auxv_t)) == sizeof(Elf32_auxv_t)) {
+            if (aux.a_type == AT_HWCAP) {
+		uint32_t hwcap = aux.a_un.a_val;
+		if (getenv("ARM_FORCE_HWCAP"))
+		    hwcap = strtoul(getenv("ARM_FORCE_HWCAP"), NULL, 0);
+		// hardcode these values to avoid depending on specific versions
+		// of the hwcap header, e.g. HWCAP_NEON
+		arm_has_vfp = (hwcap & 64) != 0;
+		arm_has_iwmmxt = (hwcap & 512) != 0;
+		// this flag is only present on kernel 2.6.29
+		arm_has_neon = (hwcap & 4096) != 0;
+            } else if (aux.a_type == AT_PLATFORM) {
+		const char *plat = (const char*) aux.a_un.a_val;
+		if (getenv("ARM_FORCE_PLATFORM"))
+		    plat = getenv("ARM_FORCE_PLATFORM");
+		if (strncmp(plat, "v7l", 3) == 0) {
+		    arm_has_v7 = TRUE;
+		    arm_has_v6 = TRUE;
+		} else if (strncmp(plat, "v6l", 3) == 0) {
+		    arm_has_v6 = TRUE;
+		}
+            }
+        }
+        close (fd);
+
+	// if we don't have 2.6.29, we have to do this hack; set
+	// the env var to trust HWCAP.
+	if (!getenv("ARM_TRUST_HWCAP") && arm_has_v7)
+	    arm_has_neon = TRUE;
+    }
+
+    arm_tests_initialized = TRUE;
+}
+
+#if defined(USE_ARM_SIMD)
+pixman_bool_t
+pixman_have_arm_simd (void)
+{
+    if (!arm_tests_initialized)
+	pixman_arm_read_auxv();
+
+    return arm_has_v6;
+}
+#endif /* USE_ARM_SIMD */
+
+#if defined(USE_ARM_NEON)
+pixman_bool_t
+pixman_have_arm_neon (void)
+{
+    if (!arm_tests_initialized)
+	pixman_arm_read_auxv();
+
+    return arm_has_neon;
+}
+#endif /* USE_ARM_NEON */
+
+#endif /* linux */
+
+#endif /* USE_ARM_SIMD || USE_ARM_NEON */
+
+#ifdef USE_MMX
+/* The CPU detection code needs to be in a file not compiled with
+ * "-mmmx -msse", as gcc would generate CMOV instructions otherwise
+ * that would lead to SIGILL instructions on old CPUs that don't have
+ * it.
+ */
+#if !defined(__amd64__) && !defined(__x86_64__)
+
+#ifdef HAVE_GETISAX
+#include <sys/auxv.h>
+#endif
+
+enum CPUFeatures {
+    NoFeatures = 0,
+    MMX = 0x1,
+    MMX_Extensions = 0x2,
+    SSE = 0x6,
+    SSE2 = 0x8,
+    CMOV = 0x10
+};
+
+static unsigned int detectCPUFeatures(void) {
+    unsigned int features = 0;
+    unsigned int result = 0;
+
+#ifdef HAVE_GETISAX
+    if (getisax(&result, 1)) {
+        if (result & AV_386_CMOV)
+            features |= CMOV;
+        if (result & AV_386_MMX)
+            features |= MMX;
+        if (result & AV_386_AMD_MMX)
+            features |= MMX_Extensions;
+        if (result & AV_386_SSE)
+            features |= SSE;
+        if (result & AV_386_SSE2)
+            features |= SSE2;
+    }
+#else
+    char vendor[13];
+#ifdef _MSC_VER
+    int vendor0 = 0, vendor1, vendor2;
+#endif
+    vendor[0] = 0;
+    vendor[12] = 0;
+
+#ifdef __GNUC__
+    /* see p. 118 of amd64 instruction set manual Vol3 */
+    /* We need to be careful about the handling of %ebx and
+     * %esp here. We can't declare either one as clobbered
+     * since they are special registers (%ebx is the "PIC
+     * register" holding an offset to global data, %esp the
+     * stack pointer), so we need to make sure they have their
+     * original values when we access the output operands.
+     */
+    __asm__ (
+	"pushf\n"
+	"pop %%eax\n"
+	"mov %%eax, %%ecx\n"
+	"xor $0x00200000, %%eax\n"
+	"push %%eax\n"
+	"popf\n"
+	"pushf\n"
+	"pop %%eax\n"
+	"mov $0x0, %%edx\n"
+	"xor %%ecx, %%eax\n"
+	"jz 1f\n"
+	
+	"mov $0x00000000, %%eax\n"
+	"push %%ebx\n"
+	"cpuid\n"
+	"mov %%ebx, %%eax\n"
+	"pop %%ebx\n"
+	"mov %%eax, %1\n"
+	"mov %%edx, %2\n"
+	"mov %%ecx, %3\n"
+	"mov $0x00000001, %%eax\n"
+	"push %%ebx\n"
+	"cpuid\n"
+	"pop %%ebx\n"
+	"1:\n"
+	"mov %%edx, %0\n"
+	: "=r" (result),
+	  "=m" (vendor[0]),
+	  "=m" (vendor[4]),
+	  "=m" (vendor[8])
+	:
+	: "%eax", "%ecx", "%edx"
+        );
+    
+#elif defined (_MSC_VER)
+
+    _asm {
+      pushfd
+      pop eax
+      mov ecx, eax
+      xor eax, 00200000h
+      push eax
+      popfd
+      pushfd
+      pop eax
+      mov edx, 0
+      xor eax, ecx
+      jz nocpuid
+
+      mov eax, 0
+      push ebx
+      cpuid
+      mov eax, ebx
+      pop ebx
+      mov vendor0, eax
+      mov vendor1, edx
+      mov vendor2, ecx
+      mov eax, 1
+      push ebx
+      cpuid
+      pop ebx
+    nocpuid:
+      mov result, edx
+    }
+    memmove (vendor+0, &vendor0, 4);
+    memmove (vendor+4, &vendor1, 4);
+    memmove (vendor+8, &vendor2, 4);
+
+#else
+#   error unsupported compiler
+#endif
+
+    features = 0;
+    if (result) {
+        /* result now contains the standard feature bits */
+        if (result & (1 << 15))
+            features |= CMOV;
+        if (result & (1 << 23))
+            features |= MMX;
+        if (result & (1 << 25))
+            features |= SSE;
+        if (result & (1 << 26))
+            features |= SSE2;
+        if ((features & MMX) && !(features & SSE) &&
+            (strcmp(vendor, "AuthenticAMD") == 0 ||
+             strcmp(vendor, "Geode by NSC") == 0)) {
+            /* check for AMD MMX extensions */
+#ifdef __GNUC__
+            __asm__(
+		"	push %%ebx\n"
+		"	mov $0x80000000, %%eax\n"
+		"	cpuid\n"
+		"	xor %%edx, %%edx\n"
+		"	cmp $0x1, %%eax\n"
+		"	jge 2f\n"
+		"	mov $0x80000001, %%eax\n"
+		"	cpuid\n"
+		"2:\n"
+		"	pop %%ebx\n"
+		"	mov %%edx, %0\n"
+		: "=r" (result)
+		:
+		: "%eax", "%ecx", "%edx"
+                );
+#elif defined _MSC_VER
+            _asm {
+              push ebx
+              mov eax, 80000000h
+              cpuid
+              xor edx, edx
+              cmp eax, 1
+              jge notamd
+              mov eax, 80000001h
+              cpuid
+            notamd:
+              pop ebx
+              mov result, edx
+            }
+#endif
+            if (result & (1<<22))
+                features |= MMX_Extensions;
+        }
+    }
+#endif /* HAVE_GETISAX */
+
+    return features;
+}
+
+pixman_bool_t
+pixman_have_mmx (void)
+{
+    static pixman_bool_t initialized = FALSE;
+    static pixman_bool_t mmx_present;
+
+    if (!initialized)
+    {
+        unsigned int features = detectCPUFeatures();
+	mmx_present = (features & (MMX|MMX_Extensions)) == (MMX|MMX_Extensions);
+        initialized = TRUE;
+    }
+
+    return mmx_present;
+}
+
+#ifdef USE_SSE2
+pixman_bool_t
+pixman_have_sse2 (void)
+{
+    static pixman_bool_t initialized = FALSE;
+    static pixman_bool_t sse2_present;
+
+    if (!initialized)
+    {
+        unsigned int features = detectCPUFeatures();
+        sse2_present = (features & (MMX|MMX_Extensions|SSE|SSE2)) == (MMX|MMX_Extensions|SSE|SSE2);
+        initialized = TRUE;
+    }
+
+    return sse2_present;
+}
+#endif
+
+#endif /* __amd64__ */
+#endif
diff --git a/pixman/pixman-pict.c b/pixman/pixman-pict.c
index 1b23045..0016528 100644
--- a/pixman/pixman-pict.c
+++ b/pixman/pixman-pict.c
@@ -38,11 +38,6 @@
 #include "pixman-arm-neon.h"
 #include "pixman-combine32.h"
 
-#if defined(USE_ARM_SIMD) && defined(_MSC_VER)
-/* Needed for EXCEPTION_ILLEGAL_INSTRUCTION */
-#include <windows.h>
-#endif
-
 #define FbFullMask(n)   ((n) == 32 ? (uint32_t)-1 : ((((uint32_t) 1) << n) - 1))
 
 #undef READ
@@ -2121,461 +2116,3 @@ pixman_image_composite (pixman_op_t      op,
 }
 
 
-#ifdef USE_VMX
-/* The CPU detection code needs to be in a file not compiled with
- * "-maltivec -mabi=altivec", as gcc would try to save vector register
- * across function calls causing SIGILL on cpus without Altivec/vmx.
- */
-static pixman_bool_t initialized = FALSE;
-static volatile pixman_bool_t have_vmx = TRUE;
-
-#ifdef __APPLE__
-#include <sys/sysctl.h>
-
-pixman_bool_t pixman_have_vmx (void) {
-    if(!initialized) {
-        size_t length = sizeof(have_vmx);
-        int error =
-            sysctlbyname("hw.optional.altivec", &have_vmx, &length, NULL, 0);
-        if(error) have_vmx = FALSE;
-        initialized = TRUE;
-    }
-    return have_vmx;
-}
-
-#elif defined (__linux__)
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <linux/auxvec.h>
-#include <asm/cputable.h>
-
-pixman_bool_t pixman_have_vmx (void)
-{
-    if (!initialized) {
-	char fname[64];
-	unsigned long buf[64];
-	ssize_t count = 0;
-	pid_t pid;
-	int fd, i;
-
-	pid = getpid();
-	snprintf(fname, sizeof(fname)-1, "/proc/%d/auxv", pid);
-
-	fd = open(fname, O_RDONLY);
-	if (fd >= 0) {
-	    for (i = 0; i <= (count / sizeof(unsigned long)); i += 2) {
-		/* Read more if buf is empty... */
-		if (i == (count / sizeof(unsigned long))) {
-		    count = read(fd, buf, sizeof(buf));
-		    if (count <= 0)
-			break;
-		    i = 0;
-		}
-
-		if (buf[i] == AT_HWCAP) {
-		    have_vmx = !!(buf[i+1] & PPC_FEATURE_HAS_ALTIVEC);
-		    initialized = TRUE;
-		    break;
-		} else if (buf[i] == AT_NULL) {
-		    break;
-		}
-	    }
-	    close(fd);
-	}
-    }
-    if (!initialized) {
-	/* Something went wrong. Assume 'no' rather than playing
-	   fragile tricks with catching SIGILL. */
-	have_vmx = FALSE;
-	initialized = TRUE;
-    }
-
-    return have_vmx;
-}
-#else /* !__APPLE__ && !__linux__ */
-#include <signal.h>
-#include <setjmp.h>
-
-static jmp_buf jump_env;
-
-static void vmx_test(int sig, siginfo_t *si, void *unused) {
-    longjmp (jump_env, 1);
-}
-
-pixman_bool_t pixman_have_vmx (void) {
-    struct sigaction sa, osa;
-    int jmp_result;
-    if (!initialized) {
-        sa.sa_flags = SA_SIGINFO;
-        sigemptyset(&sa.sa_mask);
-        sa.sa_sigaction = vmx_test;
-        sigaction(SIGILL, &sa, &osa);
-	jmp_result = setjmp (jump_env);
-	if (jmp_result == 0) {
-	    asm volatile ( "vor 0, 0, 0" );
-	}
-        sigaction(SIGILL, &osa, NULL);
-	have_vmx = (jmp_result == 0);
-        initialized = TRUE;
-    }
-    return have_vmx;
-}
-#endif /* __APPLE__ */
-#endif /* USE_VMX */
-
-#if defined(USE_ARM_SIMD) || defined(USE_ARM_NEON)
-
-#if defined(_MSC_VER)
-
-#if defined(USE_ARM_SIMD)
-extern int pixman_msvc_try_arm_simd_op();
-
-pixman_bool_t
-pixman_have_arm_simd (void)
-{
-    static pixman_bool_t initialized = FALSE;
-    static pixman_bool_t have_arm_simd = FALSE;
-
-    if (!initialized) {
-        __try {
-            pixman_msvc_try_arm_simd_op();
-            have_arm_simd = TRUE;
-        } __except(GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION) {
-            have_arm_simd = FALSE;
-        }
-	initialized = TRUE;
-    }
-
-    return have_arm_simd;
-}
-#endif /* USE_ARM_SIMD */
-
-#if defined(USE_ARM_NEON)
-extern int pixman_msvc_try_arm_neon_op();
-
-pixman_bool_t
-pixman_have_arm_neon (void)
-{
-    static pixman_bool_t initialized = FALSE;
-    static pixman_bool_t have_arm_neon = FALSE;
-
-    if (!initialized) {
-        __try {
-            pixman_msvc_try_arm_neon_op();
-            have_arm_neon = TRUE;
-        } __except(GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION) {
-            have_arm_neon = FALSE;
-        }
-	initialized = TRUE;
-    }
-
-    return have_arm_neon;
-}
-#endif /* USE_ARM_NEON */
-
-#else /* linux ELF */
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <fcntl.h>
-#include <string.h>
-#include <elf.h>
-
-static pixman_bool_t arm_has_v7 = FALSE;
-static pixman_bool_t arm_has_v6 = FALSE;
-static pixman_bool_t arm_has_vfp = FALSE;
-static pixman_bool_t arm_has_neon = FALSE;
-static pixman_bool_t arm_has_iwmmxt = FALSE;
-static pixman_bool_t arm_tests_initialized = FALSE;
-
-static void
-pixman_arm_read_auxv() {
-    int fd;
-    Elf32_auxv_t aux;
-
-    fd = open("/proc/self/auxv", O_RDONLY);
-    if (fd >= 0) {
-        while (read(fd, &aux, sizeof(Elf32_auxv_t)) == sizeof(Elf32_auxv_t)) {
-            if (aux.a_type == AT_HWCAP) {
-		uint32_t hwcap = aux.a_un.a_val;
-		if (getenv("ARM_FORCE_HWCAP"))
-		    hwcap = strtoul(getenv("ARM_FORCE_HWCAP"), NULL, 0);
-		// hardcode these values to avoid depending on specific versions
-		// of the hwcap header, e.g. HWCAP_NEON
-		arm_has_vfp = (hwcap & 64) != 0;
-		arm_has_iwmmxt = (hwcap & 512) != 0;
-		// this flag is only present on kernel 2.6.29
-		arm_has_neon = (hwcap & 4096) != 0;
-            } else if (aux.a_type == AT_PLATFORM) {
-		const char *plat = (const char*) aux.a_un.a_val;
-		if (getenv("ARM_FORCE_PLATFORM"))
-		    plat = getenv("ARM_FORCE_PLATFORM");
-		if (strncmp(plat, "v7l", 3) == 0) {
-		    arm_has_v7 = TRUE;
-		    arm_has_v6 = TRUE;
-		} else if (strncmp(plat, "v6l", 3) == 0) {
-		    arm_has_v6 = TRUE;
-		}
-            }
-        }
-        close (fd);
-
-	// if we don't have 2.6.29, we have to do this hack; set
-	// the env var to trust HWCAP.
-	if (!getenv("ARM_TRUST_HWCAP") && arm_has_v7)
-	    arm_has_neon = TRUE;
-    }
-
-    arm_tests_initialized = TRUE;
-}
-
-#if defined(USE_ARM_SIMD)
-pixman_bool_t
-pixman_have_arm_simd (void)
-{
-    if (!arm_tests_initialized)
-	pixman_arm_read_auxv();
-
-    return arm_has_v6;
-}
-#endif /* USE_ARM_SIMD */
-
-#if defined(USE_ARM_NEON)
-pixman_bool_t
-pixman_have_arm_neon (void)
-{
-    if (!arm_tests_initialized)
-	pixman_arm_read_auxv();
-
-    return arm_has_neon;
-}
-#endif /* USE_ARM_NEON */
-
-#endif /* linux */
-
-#endif /* USE_ARM_SIMD || USE_ARM_NEON */
-
-#ifdef USE_MMX
-/* The CPU detection code needs to be in a file not compiled with
- * "-mmmx -msse", as gcc would generate CMOV instructions otherwise
- * that would lead to SIGILL instructions on old CPUs that don't have
- * it.
- */
-#if !defined(__amd64__) && !defined(__x86_64__)
-
-#ifdef HAVE_GETISAX
-#include <sys/auxv.h>
-#endif
-
-enum CPUFeatures {
-    NoFeatures = 0,
-    MMX = 0x1,
-    MMX_Extensions = 0x2,
-    SSE = 0x6,
-    SSE2 = 0x8,
-    CMOV = 0x10
-};
-
-static unsigned int detectCPUFeatures(void) {
-    unsigned int features = 0;
-    unsigned int result = 0;
-
-#ifdef HAVE_GETISAX
-    if (getisax(&result, 1)) {
-        if (result & AV_386_CMOV)
-            features |= CMOV;
-        if (result & AV_386_MMX)
-            features |= MMX;
-        if (result & AV_386_AMD_MMX)
-            features |= MMX_Extensions;
-        if (result & AV_386_SSE)
-            features |= SSE;
-        if (result & AV_386_SSE2)
-            features |= SSE2;
-    }
-#else
-    char vendor[13];
-#ifdef _MSC_VER
-    int vendor0 = 0, vendor1, vendor2;
-#endif
-    vendor[0] = 0;
-    vendor[12] = 0;
-
-#ifdef __GNUC__
-    /* see p. 118 of amd64 instruction set manual Vol3 */
-    /* We need to be careful about the handling of %ebx and
-     * %esp here. We can't declare either one as clobbered
-     * since they are special registers (%ebx is the "PIC
-     * register" holding an offset to global data, %esp the
-     * stack pointer), so we need to make sure they have their
-     * original values when we access the output operands.
-     */
-    __asm__ ("pushf\n"
-             "pop %%eax\n"
-             "mov %%eax, %%ecx\n"
-             "xor $0x00200000, %%eax\n"
-             "push %%eax\n"
-             "popf\n"
-             "pushf\n"
-             "pop %%eax\n"
-             "mov $0x0, %%edx\n"
-             "xor %%ecx, %%eax\n"
-             "jz 1f\n"
-
-             "mov $0x00000000, %%eax\n"
-	     "push %%ebx\n"
-             "cpuid\n"
-             "mov %%ebx, %%eax\n"
-	     "pop %%ebx\n"
-	     "mov %%eax, %1\n"
-             "mov %%edx, %2\n"
-             "mov %%ecx, %3\n"
-             "mov $0x00000001, %%eax\n"
-	     "push %%ebx\n"
-             "cpuid\n"
-	     "pop %%ebx\n"
-             "1:\n"
-             "mov %%edx, %0\n"
-             : "=r" (result),
-               "=m" (vendor[0]),
-               "=m" (vendor[4]),
-               "=m" (vendor[8])
-             :
-             : "%eax", "%ecx", "%edx"
-        );
-
-#elif defined (_MSC_VER)
-
-    _asm {
-      pushfd
-      pop eax
-      mov ecx, eax
-      xor eax, 00200000h
-      push eax
-      popfd
-      pushfd
-      pop eax
-      mov edx, 0
-      xor eax, ecx
-      jz nocpuid
-
-      mov eax, 0
-      push ebx
-      cpuid
-      mov eax, ebx
-      pop ebx
-      mov vendor0, eax
-      mov vendor1, edx
-      mov vendor2, ecx
-      mov eax, 1
-      push ebx
-      cpuid
-      pop ebx
-    nocpuid:
-      mov result, edx
-    }
-    memmove (vendor+0, &vendor0, 4);
-    memmove (vendor+4, &vendor1, 4);
-    memmove (vendor+8, &vendor2, 4);
-
-#else
-#   error unsupported compiler
-#endif
-
-    features = 0;
-    if (result) {
-        /* result now contains the standard feature bits */
-        if (result & (1 << 15))
-            features |= CMOV;
-        if (result & (1 << 23))
-            features |= MMX;
-        if (result & (1 << 25))
-            features |= SSE;
-        if (result & (1 << 26))
-            features |= SSE2;
-        if ((features & MMX) && !(features & SSE) &&
-            (strcmp(vendor, "AuthenticAMD") == 0 ||
-             strcmp(vendor, "Geode by NSC") == 0)) {
-            /* check for AMD MMX extensions */
-#ifdef __GNUC__
-            __asm__("push %%ebx\n"
-                    "mov $0x80000000, %%eax\n"
-                    "cpuid\n"
-                    "xor %%edx, %%edx\n"
-                    "cmp $0x1, %%eax\n"
-                    "jge 2f\n"
-                    "mov $0x80000001, %%eax\n"
-                    "cpuid\n"
-                    "2:\n"
-                    "pop %%ebx\n"
-                    "mov %%edx, %0\n"
-                    : "=r" (result)
-                    :
-                    : "%eax", "%ecx", "%edx"
-                );
-#elif defined _MSC_VER
-            _asm {
-              push ebx
-              mov eax, 80000000h
-              cpuid
-              xor edx, edx
-              cmp eax, 1
-              jge notamd
-              mov eax, 80000001h
-              cpuid
-            notamd:
-              pop ebx
-              mov result, edx
-            }
-#endif
-            if (result & (1<<22))
-                features |= MMX_Extensions;
-        }
-    }
-#endif /* HAVE_GETISAX */
-
-    return features;
-}
-
-pixman_bool_t
-pixman_have_mmx (void)
-{
-    static pixman_bool_t initialized = FALSE;
-    static pixman_bool_t mmx_present;
-
-    if (!initialized)
-    {
-        unsigned int features = detectCPUFeatures();
-	mmx_present = (features & (MMX|MMX_Extensions)) == (MMX|MMX_Extensions);
-        initialized = TRUE;
-    }
-
-    return mmx_present;
-}
-
-#ifdef USE_SSE2
-pixman_bool_t
-pixman_have_sse2 (void)
-{
-    static pixman_bool_t initialized = FALSE;
-    static pixman_bool_t sse2_present;
-
-    if (!initialized)
-    {
-        unsigned int features = detectCPUFeatures();
-        sse2_present = (features & (MMX|MMX_Extensions|SSE|SSE2)) == (MMX|MMX_Extensions|SSE|SSE2);
-        initialized = TRUE;
-    }
-
-    return sse2_present;
-}
-#endif
-
-#endif /* __amd64__ */
-#endif
commit e6e6f6350230cc2e10e7dfe0ebd89ec4b587b660
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Sun May 3 01:18:49 2009 -0400

    Move conical gradient code to pixman-conical-gradient.c and delete pixman-source.c

diff --git a/pixman/Makefile.am b/pixman/Makefile.am
index ed5fca9..07452f1 100644
--- a/pixman/Makefile.am
+++ b/pixman/Makefile.am
@@ -17,7 +17,6 @@ libpixman_1_la_SOURCES =		\
 	pixman-combine64.h		\
 	pixman-compose.c		\
 	pixman-pict.c			\
-	pixman-source.c			\
 	pixman-solid-fill.c		\
 	pixman-conical-gradient.c	\
 	pixman-linear-gradient.c	\
diff --git a/pixman/pixman-conical-gradient.c b/pixman/pixman-conical-gradient.c
index 974fd7c..023256a 100644
--- a/pixman/pixman-conical-gradient.c
+++ b/pixman/pixman-conical-gradient.c
@@ -1,33 +1,127 @@
 /*
  * Copyright © 2000 SuSE, Inc.
  * Copyright © 2007 Red Hat, Inc.
+ * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
+ *             2005 Lars Knoll & Zack Rusin, Trolltech
  *
  * 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 SuSE not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission.  SuSE makes no representations about the
- * suitability of this software for any purpose.  It is provided "as is"
- * without express or implied warranty.
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
  *
- * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
- * 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 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.
  */
-
 #include <config.h>
 #include <stdlib.h>
+#include <math.h>
 #include "pixman-private.h"
 
 static void
+conical_gradient_get_scanline_32 (pixman_image_t *image, int x, int y, int width,
+				  uint32_t *buffer, uint32_t *mask, uint32_t maskBits)
+{
+    source_image_t *source = (source_image_t *)image;
+    gradient_t *gradient = (gradient_t *)source;
+    conical_gradient_t *conical = (conical_gradient_t *)image;
+    uint32_t       *end = buffer + width;
+    GradientWalker  walker;
+    pixman_bool_t affine = TRUE;
+    double cx = 1.;
+    double cy = 0.;
+    double cz = 0.;
+    double rx = x + 0.5;
+    double ry = y + 0.5;
+    double rz = 1.;
+    double a = conical->angle/(180.*65536);
+
+    _pixman_gradient_walker_init (&walker, gradient, source->common.repeat);
+    
+    if (source->common.transform) {
+	pixman_vector_t v;
+	/* reference point is the center of the pixel */
+	v.vector[0] = pixman_int_to_fixed(x) + pixman_fixed_1/2;
+	v.vector[1] = pixman_int_to_fixed(y) + pixman_fixed_1/2;
+	v.vector[2] = pixman_fixed_1;
+	if (!pixman_transform_point_3d (source->common.transform, &v))
+	    return;
+	
+	cx = source->common.transform->matrix[0][0]/65536.;
+	cy = source->common.transform->matrix[1][0]/65536.;
+	cz = source->common.transform->matrix[2][0]/65536.;
+	rx = v.vector[0]/65536.;
+	ry = v.vector[1]/65536.;
+	rz = v.vector[2]/65536.;
+	affine = source->common.transform->matrix[2][0] == 0 && v.vector[2] == pixman_fixed_1;
+    }
+    
+    if (affine) {
+	rx -= conical->center.x/65536.;
+	ry -= conical->center.y/65536.;
+	
+	while (buffer < end) {
+	    double angle;
+	    
+	    if (!mask || *mask++ & maskBits)
+	    {
+		pixman_fixed_48_16_t   t;
+		
+		angle = atan2(ry, rx) + a;
+		t     = (pixman_fixed_48_16_t) (angle * (65536. / (2*M_PI)));
+		
+		*(buffer) = _pixman_gradient_walker_pixel (&walker, t);
+	    }
+	    
+	    ++buffer;
+	    rx += cx;
+	    ry += cy;
+	}
+    } else {
+	while (buffer < end) {
+	    double x, y;
+	    double angle;
+	    
+	    if (!mask || *mask++ & maskBits)
+	    {
+		pixman_fixed_48_16_t  t;
+		
+		if (rz != 0) {
+		    x = rx/rz;
+		    y = ry/rz;
+		} else {
+		    x = y = 0.;
+		}
+		x -= conical->center.x/65536.;
+		y -= conical->center.y/65536.;
+		angle = atan2(y, x) + a;
+		t     = (pixman_fixed_48_16_t) (angle * (65536. / (2*M_PI)));
+		
+		*(buffer) = _pixman_gradient_walker_pixel (&walker, t);
+	    }
+	    
+	    ++buffer;
+	    rx += cx;
+	    ry += cy;
+	    rz += cz;
+	}
+    }
+}
+
+static void
 conical_gradient_property_changed (pixman_image_t *image)
 {
-    image->common.get_scanline_32 = (scanFetchProc)pixmanFetchGradient;
+    image->common.get_scanline_32 = (scanFetchProc)conical_gradient_get_scanline_32;
     image->common.get_scanline_64 = (scanFetchProc)_pixman_image_get_scanline_64_generic;
 }
 
@@ -39,24 +133,24 @@ pixman_image_create_conical_gradient (pixman_point_fixed_t         *center,
 {
     pixman_image_t *image = _pixman_image_allocate();
     conical_gradient_t *conical;
-
+    
     if (!image)
 	return NULL;
-
+    
     conical = &image->conical;
-
+    
     if (!_pixman_init_gradient (&conical->common, stops, n_stops))
     {
 	free (image);
 	return NULL;
     }
-
+    
     image->type = CONICAL;
     conical->center = *center;
     conical->angle = angle;
-
+    
     image->common.property_changed = conical_gradient_property_changed;
-
+    
     conical_gradient_property_changed (image);
     
     return image;
diff --git a/pixman/pixman-source.c b/pixman/pixman-source.c
deleted file mode 100644
index dfdb183..0000000
--- a/pixman/pixman-source.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- *
- * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
- *             2005 Lars Knoll & Zack Rusin, Trolltech
- *
- * 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 Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission.  Keith Packard makes no
- * representations about the suitability of this software for any purpose.  It
- * is provided "as is" without express or implied warranty.
- *
- * 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.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdlib.h>
-#include <math.h>
-
-#include "pixman-private.h"
-
-void
-pixmanFetchGradient(gradient_t *gradient, int x, int y, int width,
-		    uint32_t *buffer, uint32_t *mask, uint32_t maskBits)
-{
-    GradientWalker  walker;
-    uint32_t       *end = buffer + width;
-    source_image_t *pict;
-
-    pict = (source_image_t *)gradient;
-
-    _pixman_gradient_walker_init (&walker, gradient, pict->common.repeat);
-
-    if (pict->common.type == LINEAR) {
-	assert (0);
-    } else {
-        if (pict->common.type == RADIAL) {
-	    assert (0);
-        } else /* SourcePictTypeConical */ {
-	    /* radial or conical */
-	    pixman_bool_t affine = TRUE;
-	    double cx = 1.;
-	    double cy = 0.;
-	    double cz = 0.;
-	    double rx = x + 0.5;
-	    double ry = y + 0.5;
-	    double rz = 1.;
-	    
-	    if (pict->common.transform) {
-		pixman_vector_t v;
-		/* reference point is the center of the pixel */
-		v.vector[0] = pixman_int_to_fixed(x) + pixman_fixed_1/2;
-		v.vector[1] = pixman_int_to_fixed(y) + pixman_fixed_1/2;
-		v.vector[2] = pixman_fixed_1;
-		if (!pixman_transform_point_3d (pict->common.transform, &v))
-		    return;
-		
-		cx = pict->common.transform->matrix[0][0]/65536.;
-		cy = pict->common.transform->matrix[1][0]/65536.;
-		cz = pict->common.transform->matrix[2][0]/65536.;
-		rx = v.vector[0]/65536.;
-		ry = v.vector[1]/65536.;
-		rz = v.vector[2]/65536.;
-		affine = pict->common.transform->matrix[2][0] == 0 && v.vector[2] == pixman_fixed_1;
-	    }
-	    
-	    conical_gradient_t *conical = (conical_gradient_t *)pict;
-            double a = conical->angle/(180.*65536);
-            if (affine) {
-                rx -= conical->center.x/65536.;
-                ry -= conical->center.y/65536.;
-
-                while (buffer < end) {
-		    double angle;
-
-                    if (!mask || *mask++ & maskBits)
-		    {
-                        pixman_fixed_48_16_t   t;
-
-                        angle = atan2(ry, rx) + a;
-			t     = (pixman_fixed_48_16_t) (angle * (65536. / (2*M_PI)));
-
-			*(buffer) = _pixman_gradient_walker_pixel (&walker, t);
-		    }
-
-                    ++buffer;
-                    rx += cx;
-                    ry += cy;
-                }
-            } else {
-                while (buffer < end) {
-                    double x, y;
-                    double angle;
-
-                    if (!mask || *mask++ & maskBits)
-                    {
-			pixman_fixed_48_16_t  t;
-
-			if (rz != 0) {
-			    x = rx/rz;
-			    y = ry/rz;
-			} else {
-			    x = y = 0.;
-			}
-			x -= conical->center.x/65536.;
-			y -= conical->center.y/65536.;
-			angle = atan2(y, x) + a;
-			t     = (pixman_fixed_48_16_t) (angle * (65536. / (2*M_PI)));
-
-			*(buffer) = _pixman_gradient_walker_pixel (&walker, t);
-		    }
-
-                    ++buffer;
-                    rx += cx;
-                    ry += cy;
-                    rz += cz;
-                }
-            }
-        }
-    }
-}
commit 47abb3c7659a4eb1214c358796965f92f98fc901
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Sun May 3 01:08:54 2009 -0400

    Move the radial gradient code form pixman-source.c into pixman-radial-gradient.c

diff --git a/pixman/pixman-radial-gradient.c b/pixman/pixman-radial-gradient.c
index 19853e3..4a45430 100644
--- a/pixman/pixman-radial-gradient.c
+++ b/pixman/pixman-radial-gradient.c
@@ -1,41 +1,279 @@
 /*
+ *
+ * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
  * Copyright © 2000 SuSE, Inc.
+ *             2005 Lars Knoll & Zack Rusin, Trolltech
  * Copyright © 2007 Red Hat, Inc.
  *
+ *
  * 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 SuSE not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission.  SuSE makes no representations about the
- * suitability of this software for any purpose.  It is provided "as is"
- * without express or implied warranty.
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
  *
- * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
- * 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 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.
  */
 
 #include <config.h>
 #include <stdlib.h>
+#include <math.h>
 #include "pixman-private.h"
 
 static void
-radial_gradient_property_changed (pixman_image_t *image)
+radial_gradient_get_scanline_32 (pixman_image_t *image, int x, int y, int width,
+				 uint32_t *buffer, uint32_t *mask, uint32_t maskBits)
 {
-    image->common.get_scanline_32 = (scanFetchProc)pixmanFetchGradient;
-    image->common.get_scanline_64 = (scanFetchProc)_pixman_image_get_scanline_64_generic;
+    /*
+     * In the radial gradient problem we are given two circles (c₁,r₁) and
+     * (câ‚‚,râ‚‚) that define the gradient itself. Then, for any point p, we
+     * must compute the value(s) of t within [0.0, 1.0] representing the
+     * circle(s) that would color the point.
+     *
+     * There are potentially two values of t since the point p can be
+     * colored by both sides of the circle, (which happens whenever one
+     * circle is not entirely contained within the other).
+     *
+     * If we solve for a value of t that is outside of [0.0, 1.0] then we
+     * use the extend mode (NONE, REPEAT, REFLECT, or PAD) to map to a
+     * value within [0.0, 1.0].
+     *
+     * Here is an illustration of the problem:
+     *
+     *              pâ‚‚
+     *           p  •
+     *           •   ╲
+     *        ·       ╲r₂
+     *  p₁ ·           ╲
+     *  •              θ╲
+     *   ╲             ╌╌•
+     *    ╲r₁        ·   c₂
+     *    θ╲    ·
+     *    ╌╌•
+     *      c₁
+     *
+     * Given (c₁,r₁), (c₂,r₂) and p, we must find an angle θ such that two
+     * points p₁ and p₂ on the two circles are collinear with p. Then, the
+     * desired value of t is the ratio of the length of p₁p to the length
+     * of p₁p₂.
+     *
+     * So, we have six unknown values: (p₁x, p₁y), (p₂x, p₂y), θ and t.
+     * We can also write six equations that constrain the problem:
+     *
+     * Point p₁ is a distance r₁ from c₁ at an angle of θ:
+     *
+     *	1. p₁x = c₁x + r₁·cos θ
+     *	2. p₁y = c₁y + r₁·sin θ
+     *
+     * Point p₂ is a distance r₂ from c₂ at an angle of θ:
+     *
+     *	3. p₂x = c₂x + r2·cos θ
+     *	4. p₂y = c₂y + r2·sin θ
+     *
+     * Point p lies at a fraction t along the line segment p₁p₂:
+     *
+     *	5. px = t·p₂x + (1-t)·p₁x
+     *	6. py = t·p₂y + (1-t)·p₁y
+     *
+     * To solve, first subtitute 1-4 into 5 and 6:
+     *
+     * px = t·(c₂x + r₂·cos θ) + (1-t)·(c₁x + r₁·cos θ)
+     * py = t·(c₂y + r₂·sin θ) + (1-t)·(c₁y + r₁·sin θ)
+     *
+     * Then solve each for cos θ and sin θ expressed as a function of t:
+     *
+     * cos θ = (-(c₂x - c₁x)·t + (px - c₁x)) / ((r₂-r₁)·t + r₁)
+     * sin θ = (-(c₂y - c₁y)·t + (py - c₁y)) / ((r₂-r₁)·t + r₁)
+     *
+     * To simplify this a bit, we define new variables for several of the
+     * common terms as shown below:
+     *
+     *              pâ‚‚
+     *           p  •
+     *           •   ╲
+     *        ·  ┆    ╲r₂
+     *  p₁ ·     ┆     ╲
+     *  •     pdy┆      ╲
+     *   ╲       ┆       •c₂
+     *    ╲r₁    ┆   ·   ┆
+     *     ╲    ·┆       ┆cdy
+     *      •╌╌╌╌┴╌╌╌╌╌╌╌┘
+     *    c₁  pdx   cdx
+     *
+     * cdx = (c₂x - c₁x)
+     * cdy = (c₂y - c₁y)
+     *  dr =  r₂-r₁
+     * pdx =  px - c₁x
+     * pdy =  py - c₁y
+     *
+     * Note that cdx, cdy, and dr do not depend on point p at all, so can
+     * be pre-computed for the entire gradient. The simplifed equations
+     * are now:
+     *
+     * cos θ = (-cdx·t + pdx) / (dr·t + r₁)
+     * sin θ = (-cdy·t + pdy) / (dr·t + r₁)
+     *
+     * Finally, to get a single function of t and eliminate the last
+     * unknown θ, we use the identity sin²θ + cos²θ = 1. First, square
+     * each equation, (we knew a quadratic was coming since it must be
+     * possible to obtain two solutions in some cases):
+     *
+     * cos²θ = (cdx²t² - 2·cdx·pdx·t + pdx²) / (dr²·t² + 2·r₁·dr·t + r₁²)
+     * sin²θ = (cdy²t² - 2·cdy·pdy·t + pdy²) / (dr²·t² + 2·r₁·dr·t + r₁²)
+     *
+     * Then add both together, set the result equal to 1, and express as a
+     * standard quadratic equation in t of the form At² + Bt + C = 0
+     *
+     * (cdx² + cdy² - dr²)·t² - 2·(cdx·pdx + cdy·pdy + r₁·dr)·t + (pdx² + pdy² - r₁²) = 0
+     *
+     * In other words:
+     *
+     * A = cdx² + cdy² - dr²
+     * B = -2·(pdx·cdx + pdy·cdy + r₁·dr)
+     * C = pdx² + pdy² - r₁²
+     *
+     * And again, notice that A does not depend on p, so can be
+     * precomputed. From here we just use the quadratic formula to solve
+     * for t:
+     *
+     * t = (-2·B ± ⎷(B² - 4·A·C)) / 2·A
+     */
+
+    gradient_t *gradient = (gradient_t *)image;
+    source_image_t *source = (source_image_t *)image;
+    radial_gradient_t *radial = (radial_gradient_t *)image;
+    uint32_t       *end = buffer + width;
+    GradientWalker  walker;
+    pixman_bool_t affine = TRUE;
+    double cx = 1.;
+    double cy = 0.;
+    double cz = 0.;
+    double rx = x + 0.5;
+    double ry = y + 0.5;
+    double rz = 1.;
+    
+    _pixman_gradient_walker_init (&walker, gradient, source->common.repeat);
+    
+    if (source->common.transform) {
+	pixman_vector_t v;
+	/* reference point is the center of the pixel */
+	v.vector[0] = pixman_int_to_fixed(x) + pixman_fixed_1/2;
+	v.vector[1] = pixman_int_to_fixed(y) + pixman_fixed_1/2;
+	v.vector[2] = pixman_fixed_1;
+	if (!pixman_transform_point_3d (source->common.transform, &v))
+	    return;
+	
+	cx = source->common.transform->matrix[0][0]/65536.;
+	cy = source->common.transform->matrix[1][0]/65536.;
+	cz = source->common.transform->matrix[2][0]/65536.;
+	rx = v.vector[0]/65536.;
+	ry = v.vector[1]/65536.;
+	rz = v.vector[2]/65536.;
+	affine = source->common.transform->matrix[2][0] == 0 && v.vector[2] == pixman_fixed_1;
+    }
+    
+    if (affine) {
+	while (buffer < end) {
+	    if (!mask || *mask++ & maskBits)
+	    {
+		double pdx, pdy;
+		double B, C;
+		double det;
+		double c1x = radial->c1.x / 65536.0;
+		double c1y = radial->c1.y / 65536.0;
+		double r1  = radial->c1.radius / 65536.0;
+		pixman_fixed_48_16_t t;
+		
+		pdx = rx - c1x;
+		pdy = ry - c1y;
+		
+		B = -2 * (  pdx * radial->cdx
+			    + pdy * radial->cdy
+			    + r1 * radial->dr);
+		C = (pdx * pdx + pdy * pdy - r1 * r1);
+		
+		det = (B * B) - (4 * radial->A * C);
+		if (det < 0.0)
+		    det = 0.0;
+		
+		if (radial->A < 0)
+		    t = (pixman_fixed_48_16_t) ((- B - sqrt(det)) / (2.0 * radial->A) * 65536);
+		else
+		    t = (pixman_fixed_48_16_t) ((- B + sqrt(det)) / (2.0 * radial->A) * 65536);
+		
+		*(buffer) = _pixman_gradient_walker_pixel (&walker, t);
+	    }
+	    ++buffer;
+	    
+	    rx += cx;
+	    ry += cy;
+	}
+    } else {
+	/* projective */
+	while (buffer < end) {
+	    if (!mask || *mask++ & maskBits)
+	    {
+		double pdx, pdy;
+		double B, C;
+		double det;
+		double c1x = radial->c1.x / 65536.0;
+		double c1y = radial->c1.y / 65536.0;
+		double r1  = radial->c1.radius / 65536.0;
+		pixman_fixed_48_16_t t;
+		double x, y;
+		
+		if (rz != 0) {
+		    x = rx/rz;
+		    y = ry/rz;
+		} else {
+		    x = y = 0.;
+		}
+		
+		pdx = x - c1x;
+		pdy = y - c1y;
+		
+		B = -2 * (  pdx * radial->cdx
+			    + pdy * radial->cdy
+			    + r1 * radial->dr);
+		C = (pdx * pdx + pdy * pdy - r1 * r1);
+		
+		det = (B * B) - (4 * radial->A * C);
+		if (det < 0.0)
+		    det = 0.0;
+		
+		if (radial->A < 0)
+		    t = (pixman_fixed_48_16_t) ((- B - sqrt(det)) / (2.0 * radial->A) * 65536);
+		else
+		    t = (pixman_fixed_48_16_t) ((- B + sqrt(det)) / (2.0 * radial->A) * 65536);
+		
+		*(buffer) = _pixman_gradient_walker_pixel (&walker, t);
+	    }
+	    ++buffer;
+	    
+	    rx += cx;
+	    ry += cy;
+	    rz += cz;
+	}
+    }
+    
 }
 
 static void
-radial_gradient_get_scanline_32 (pixman_image_t *image, int x, int y, int width,
-				 uint32_t *buffer, uint32_t *mask, uint32_t maskBits)
+radial_gradient_property_changed (pixman_image_t *image)
 {
-    
+    image->common.get_scanline_32 = (scanFetchProc)radial_gradient_get_scanline_32;
+    image->common.get_scanline_64 = (scanFetchProc)_pixman_image_get_scanline_64_generic;
 }
 
 PIXMAN_EXPORT pixman_image_t *
@@ -48,24 +286,24 @@ pixman_image_create_radial_gradient (pixman_point_fixed_t         *inner,
 {
     pixman_image_t *image;
     radial_gradient_t *radial;
-
+    
     return_val_if_fail (n_stops >= 2, NULL);
-
+    
     image = _pixman_image_allocate();
-
+    
     if (!image)
 	return NULL;
-
+    
     radial = &image->radial;
-
+    
     if (!_pixman_init_gradient (&radial->common, stops, n_stops))
     {
 	free (image);
 	return NULL;
     }
-
+    
     image->type = RADIAL;
-
+    
     radial->c1.x = inner->x;
     radial->c1.y = inner->y;
     radial->c1.radius = inner_radius;
@@ -78,9 +316,9 @@ pixman_image_create_radial_gradient (pixman_point_fixed_t         *inner,
     radial->A = (radial->cdx * radial->cdx
 		 + radial->cdy * radial->cdy
 		 - radial->dr  * radial->dr);
-
+    
     image->common.property_changed = radial_gradient_property_changed;
-
+    
     radial_gradient_property_changed (image);
     
     return image;
diff --git a/pixman/pixman-source.c b/pixman/pixman-source.c
index d3dce87..dfdb183 100644
--- a/pixman/pixman-source.c
+++ b/pixman/pixman-source.c
@@ -47,232 +47,8 @@ pixmanFetchGradient(gradient_t *gradient, int x, int y, int width,
     if (pict->common.type == LINEAR) {
 	assert (0);
     } else {
-/*
- * In the radial gradient problem we are given two circles (c₁,r₁) and
- * (câ‚‚,râ‚‚) that define the gradient itself. Then, for any point p, we
- * must compute the value(s) of t within [0.0, 1.0] representing the
- * circle(s) that would color the point.
- *
- * There are potentially two values of t since the point p can be
- * colored by both sides of the circle, (which happens whenever one
- * circle is not entirely contained within the other).
- *
- * If we solve for a value of t that is outside of [0.0, 1.0] then we
- * use the extend mode (NONE, REPEAT, REFLECT, or PAD) to map to a
- * value within [0.0, 1.0].
- *
- * Here is an illustration of the problem:
- *
- *              pâ‚‚
- *           p  •
- *           •   ╲
- *        ·       ╲r₂
- *  p₁ ·           ╲
- *  •              θ╲
- *   ╲             ╌╌•
- *    ╲r₁        ·   c₂
- *    θ╲    ·
- *    ╌╌•
- *      c₁
- *
- * Given (c₁,r₁), (c₂,r₂) and p, we must find an angle θ such that two
- * points p₁ and p₂ on the two circles are collinear with p. Then, the
- * desired value of t is the ratio of the length of p₁p to the length
- * of p₁p₂.
- *
- * So, we have six unknown values: (p₁x, p₁y), (p₂x, p₂y), θ and t.
- * We can also write six equations that constrain the problem:
- *
- * Point p₁ is a distance r₁ from c₁ at an angle of θ:
- *
- *	1. p₁x = c₁x + r₁·cos θ
- *	2. p₁y = c₁y + r₁·sin θ
- *
- * Point p₂ is a distance r₂ from c₂ at an angle of θ:
- *
- *	3. p₂x = c₂x + r2·cos θ
- *	4. p₂y = c₂y + r2·sin θ
- *
- * Point p lies at a fraction t along the line segment p₁p₂:
- *
- *	5. px = t·p₂x + (1-t)·p₁x
- *	6. py = t·p₂y + (1-t)·p₁y
- *
- * To solve, first subtitute 1-4 into 5 and 6:
- *
- * px = t·(c₂x + r₂·cos θ) + (1-t)·(c₁x + r₁·cos θ)
- * py = t·(c₂y + r₂·sin θ) + (1-t)·(c₁y + r₁·sin θ)
- *
- * Then solve each for cos θ and sin θ expressed as a function of t:
- *
- * cos θ = (-(c₂x - c₁x)·t + (px - c₁x)) / ((r₂-r₁)·t + r₁)
- * sin θ = (-(c₂y - c₁y)·t + (py - c₁y)) / ((r₂-r₁)·t + r₁)
- *
- * To simplify this a bit, we define new variables for several of the
- * common terms as shown below:
- *
- *              pâ‚‚
- *           p  •
- *           •   ╲
- *        ·  ┆    ╲r₂
- *  p₁ ·     ┆     ╲
- *  •     pdy┆      ╲
- *   ╲       ┆       •c₂
- *    ╲r₁    ┆   ·   ┆
- *     ╲    ·┆       ┆cdy
- *      •╌╌╌╌┴╌╌╌╌╌╌╌┘
- *    c₁  pdx   cdx
- *
- * cdx = (c₂x - c₁x)
- * cdy = (c₂y - c₁y)
- *  dr =  r₂-r₁
- * pdx =  px - c₁x
- * pdy =  py - c₁y
- *
- * Note that cdx, cdy, and dr do not depend on point p at all, so can
- * be pre-computed for the entire gradient. The simplifed equations
- * are now:
- *
- * cos θ = (-cdx·t + pdx) / (dr·t + r₁)
- * sin θ = (-cdy·t + pdy) / (dr·t + r₁)
- *
- * Finally, to get a single function of t and eliminate the last
- * unknown θ, we use the identity sin²θ + cos²θ = 1. First, square
- * each equation, (we knew a quadratic was coming since it must be
- * possible to obtain two solutions in some cases):
- *
- * cos²θ = (cdx²t² - 2·cdx·pdx·t + pdx²) / (dr²·t² + 2·r₁·dr·t + r₁²)
- * sin²θ = (cdy²t² - 2·cdy·pdy·t + pdy²) / (dr²·t² + 2·r₁·dr·t + r₁²)
- *
- * Then add both together, set the result equal to 1, and express as a
- * standard quadratic equation in t of the form At² + Bt + C = 0
- *
- * (cdx² + cdy² - dr²)·t² - 2·(cdx·pdx + cdy·pdy + r₁·dr)·t + (pdx² + pdy² - r₁²) = 0
- *
- * In other words:
- *
- * A = cdx² + cdy² - dr²
- * B = -2·(pdx·cdx + pdy·cdy + r₁·dr)
- * C = pdx² + pdy² - r₁²
- *
- * And again, notice that A does not depend on p, so can be
- * precomputed. From here we just use the quadratic formula to solve
- * for t:
- *
- * t = (-2·B ± ⎷(B² - 4·A·C)) / 2·A
- */
         if (pict->common.type == RADIAL) {
-	    /* radial or conical */
-	    pixman_bool_t affine = TRUE;
-	    double cx = 1.;
-	    double cy = 0.;
-	    double cz = 0.;
-	    double rx = x + 0.5;
-	    double ry = y + 0.5;
-	    double rz = 1.;
-	    
-	    if (pict->common.transform) {
-		pixman_vector_t v;
-		/* reference point is the center of the pixel */
-		v.vector[0] = pixman_int_to_fixed(x) + pixman_fixed_1/2;
-		v.vector[1] = pixman_int_to_fixed(y) + pixman_fixed_1/2;
-		v.vector[2] = pixman_fixed_1;
-		if (!pixman_transform_point_3d (pict->common.transform, &v))
-		    return;
-		
-		cx = pict->common.transform->matrix[0][0]/65536.;
-		cy = pict->common.transform->matrix[1][0]/65536.;
-		cz = pict->common.transform->matrix[2][0]/65536.;
-		rx = v.vector[0]/65536.;
-		ry = v.vector[1]/65536.;
-		rz = v.vector[2]/65536.;
-		affine = pict->common.transform->matrix[2][0] == 0 && v.vector[2] == pixman_fixed_1;
-	    }
-	    
-	    radial_gradient_t *radial = (radial_gradient_t *)pict;
-            if (affine) {
-                while (buffer < end) {
-		    if (!mask || *mask++ & maskBits)
-		    {
-			double pdx, pdy;
-			double B, C;
-			double det;
-			double c1x = radial->c1.x / 65536.0;
-			double c1y = radial->c1.y / 65536.0;
-			double r1  = radial->c1.radius / 65536.0;
-                        pixman_fixed_48_16_t t;
-
-			pdx = rx - c1x;
-			pdy = ry - c1y;
-
-			B = -2 * (  pdx * radial->cdx
-				    + pdy * radial->cdy
-				    + r1 * radial->dr);
-			C = (pdx * pdx + pdy * pdy - r1 * r1);
-
-                        det = (B * B) - (4 * radial->A * C);
-			if (det < 0.0)
-			    det = 0.0;
-
-			if (radial->A < 0)
-			    t = (pixman_fixed_48_16_t) ((- B - sqrt(det)) / (2.0 * radial->A) * 65536);
-			else
-			    t = (pixman_fixed_48_16_t) ((- B + sqrt(det)) / (2.0 * radial->A) * 65536);
-
-			*(buffer) = _pixman_gradient_walker_pixel (&walker, t);
-		    }
-		    ++buffer;
-
-                    rx += cx;
-                    ry += cy;
-                }
-            } else {
-		/* projective */
-                while (buffer < end) {
-		    if (!mask || *mask++ & maskBits)
-		    {
-			double pdx, pdy;
-			double B, C;
-			double det;
-			double c1x = radial->c1.x / 65536.0;
-			double c1y = radial->c1.y / 65536.0;
-			double r1  = radial->c1.radius / 65536.0;
-                        pixman_fixed_48_16_t t;
-			double x, y;
-
-			if (rz != 0) {
-			    x = rx/rz;
-			    y = ry/rz;
-			} else {
-			    x = y = 0.;
-			}
-
-			pdx = x - c1x;
-			pdy = y - c1y;
-
-			B = -2 * (  pdx * radial->cdx
-				    + pdy * radial->cdy
-				    + r1 * radial->dr);
-			C = (pdx * pdx + pdy * pdy - r1 * r1);
-
-                        det = (B * B) - (4 * radial->A * C);
-			if (det < 0.0)
-			    det = 0.0;
-
-			if (radial->A < 0)
-			    t = (pixman_fixed_48_16_t) ((- B - sqrt(det)) / (2.0 * radial->A) * 65536);
-			else
-			    t = (pixman_fixed_48_16_t) ((- B + sqrt(det)) / (2.0 * radial->A) * 65536);
-
-			*(buffer) = _pixman_gradient_walker_pixel (&walker, t);
-		    }
-		    ++buffer;
-
-                    rx += cx;
-                    ry += cy;
-		    rz += cz;
-                }
-            }
+	    assert (0);
         } else /* SourcePictTypeConical */ {
 	    /* radial or conical */
 	    pixman_bool_t affine = TRUE;
commit a10b0e7e136116cea95d6717f119d92599491f27
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Sun May 3 00:59:36 2009 -0400

    Duplicate some code that was shared between radial and conical gradients.
    
    It is going to live in separate files.

diff --git a/pixman/pixman-radial-gradient.c b/pixman/pixman-radial-gradient.c
index 40c76ce..19853e3 100644
--- a/pixman/pixman-radial-gradient.c
+++ b/pixman/pixman-radial-gradient.c
@@ -31,6 +31,13 @@ radial_gradient_property_changed (pixman_image_t *image)
     image->common.get_scanline_64 = (scanFetchProc)_pixman_image_get_scanline_64_generic;
 }
 
+static void
+radial_gradient_get_scanline_32 (pixman_image_t *image, int x, int y, int width,
+				 uint32_t *buffer, uint32_t *mask, uint32_t maskBits)
+{
+    
+}
+
 PIXMAN_EXPORT pixman_image_t *
 pixman_image_create_radial_gradient (pixman_point_fixed_t         *inner,
 				     pixman_point_fixed_t         *outer,
diff --git a/pixman/pixman-source.c b/pixman/pixman-source.c
index fbb0a77..d3dce87 100644
--- a/pixman/pixman-source.c
+++ b/pixman/pixman-source.c
@@ -47,7 +47,6 @@ pixmanFetchGradient(gradient_t *gradient, int x, int y, int width,
     if (pict->common.type == LINEAR) {
 	assert (0);
     } else {
-
 /*
  * In the radial gradient problem we are given two circles (c₁,r₁) and
  * (câ‚‚,râ‚‚) that define the gradient itself. Then, for any point p, we
@@ -162,34 +161,34 @@ pixmanFetchGradient(gradient_t *gradient, int x, int y, int width,
  *
  * t = (-2·B ± ⎷(B² - 4·A·C)) / 2·A
  */
-        /* radial or conical */
-        pixman_bool_t affine = TRUE;
-        double cx = 1.;
-        double cy = 0.;
-        double cz = 0.;
-	double rx = x + 0.5;
-	double ry = y + 0.5;
-        double rz = 1.;
-
-        if (pict->common.transform) {
-            pixman_vector_t v;
-            /* reference point is the center of the pixel */
-            v.vector[0] = pixman_int_to_fixed(x) + pixman_fixed_1/2;
-            v.vector[1] = pixman_int_to_fixed(y) + pixman_fixed_1/2;
-            v.vector[2] = pixman_fixed_1;
-            if (!pixman_transform_point_3d (pict->common.transform, &v))
-                return;
-
-            cx = pict->common.transform->matrix[0][0]/65536.;
-            cy = pict->common.transform->matrix[1][0]/65536.;
-            cz = pict->common.transform->matrix[2][0]/65536.;
-            rx = v.vector[0]/65536.;
-            ry = v.vector[1]/65536.;
-            rz = v.vector[2]/65536.;
-            affine = pict->common.transform->matrix[2][0] == 0 && v.vector[2] == pixman_fixed_1;
-        }
-
         if (pict->common.type == RADIAL) {
+	    /* radial or conical */
+	    pixman_bool_t affine = TRUE;
+	    double cx = 1.;
+	    double cy = 0.;
+	    double cz = 0.;
+	    double rx = x + 0.5;
+	    double ry = y + 0.5;
+	    double rz = 1.;
+	    
+	    if (pict->common.transform) {
+		pixman_vector_t v;
+		/* reference point is the center of the pixel */
+		v.vector[0] = pixman_int_to_fixed(x) + pixman_fixed_1/2;
+		v.vector[1] = pixman_int_to_fixed(y) + pixman_fixed_1/2;
+		v.vector[2] = pixman_fixed_1;
+		if (!pixman_transform_point_3d (pict->common.transform, &v))
+		    return;
+		
+		cx = pict->common.transform->matrix[0][0]/65536.;
+		cy = pict->common.transform->matrix[1][0]/65536.;
+		cz = pict->common.transform->matrix[2][0]/65536.;
+		rx = v.vector[0]/65536.;
+		ry = v.vector[1]/65536.;
+		rz = v.vector[2]/65536.;
+		affine = pict->common.transform->matrix[2][0] == 0 && v.vector[2] == pixman_fixed_1;
+	    }
+	    
 	    radial_gradient_t *radial = (radial_gradient_t *)pict;
             if (affine) {
                 while (buffer < end) {
@@ -275,6 +274,33 @@ pixmanFetchGradient(gradient_t *gradient, int x, int y, int width,
                 }
             }
         } else /* SourcePictTypeConical */ {
+	    /* radial or conical */
+	    pixman_bool_t affine = TRUE;
+	    double cx = 1.;
+	    double cy = 0.;
+	    double cz = 0.;
+	    double rx = x + 0.5;
+	    double ry = y + 0.5;
+	    double rz = 1.;
+	    
+	    if (pict->common.transform) {
+		pixman_vector_t v;
+		/* reference point is the center of the pixel */
+		v.vector[0] = pixman_int_to_fixed(x) + pixman_fixed_1/2;
+		v.vector[1] = pixman_int_to_fixed(y) + pixman_fixed_1/2;
+		v.vector[2] = pixman_fixed_1;
+		if (!pixman_transform_point_3d (pict->common.transform, &v))
+		    return;
+		
+		cx = pict->common.transform->matrix[0][0]/65536.;
+		cy = pict->common.transform->matrix[1][0]/65536.;
+		cz = pict->common.transform->matrix[2][0]/65536.;
+		rx = v.vector[0]/65536.;
+		ry = v.vector[1]/65536.;
+		rz = v.vector[2]/65536.;
+		affine = pict->common.transform->matrix[2][0] == 0 && v.vector[2] == pixman_fixed_1;
+	    }
+	    
 	    conical_gradient_t *conical = (conical_gradient_t *)pict;
             double a = conical->angle/(180.*65536);
             if (affine) {
commit 9a867fa231e37d945f1dc3d18cb17359b24dbde3
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Sun May 3 00:56:16 2009 -0400

    Move the linear gradient code from pixman-source.c into pixman-linear-gradient.c

diff --git a/pixman/pixman-linear-gradient.c b/pixman/pixman-linear-gradient.c
index b18c2cf..ea29750 100644
--- a/pixman/pixman-linear-gradient.c
+++ b/pixman/pixman-linear-gradient.c
@@ -1,23 +1,27 @@
 /*
  * Copyright © 2000 SuSE, Inc.
  * Copyright © 2007 Red Hat, Inc.
+ * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
+ *             2005 Lars Knoll & Zack Rusin, Trolltech
  *
  * 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 SuSE not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission.  SuSE makes no representations about the
- * suitability of this software for any purpose.  It is provided "as is"
- * without express or implied warranty.
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
  *
- * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
- * 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 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.
  */
 
 #include <config.h>
@@ -79,14 +83,143 @@ linear_gradient_classify (pixman_image_t *image,
 	image->source.class = SOURCE_IMAGE_CLASS_HORIZONTAL;
     else if (factors[1] == factors[0])
 	image->source.class = SOURCE_IMAGE_CLASS_VERTICAL;
-
+    
     return image->source.class;
 }
 
 static void
+linear_gradient_get_scanline_32 (pixman_image_t *image, int x, int y, int width,
+				 uint32_t *buffer, uint32_t *mask, uint32_t maskBits)
+{
+    pixman_vector_t v, unit;
+    pixman_fixed_32_32_t l;
+    pixman_fixed_48_16_t dx, dy, a, b, off;
+    gradient_t *gradient = (gradient_t *)image;
+    source_image_t *source = (source_image_t *)image;
+    linear_gradient_t *linear = (linear_gradient_t *)image;
+    uint32_t       *end = buffer + width;
+    GradientWalker  walker;
+    
+    _pixman_gradient_walker_init (&walker, gradient, source->common.repeat);
+    
+    /* reference point is the center of the pixel */
+    v.vector[0] = pixman_int_to_fixed(x) + pixman_fixed_1/2;
+    v.vector[1] = pixman_int_to_fixed(y) + pixman_fixed_1/2;
+    v.vector[2] = pixman_fixed_1;
+    if (source->common.transform) {
+	if (!pixman_transform_point_3d (source->common.transform, &v))
+	    return;
+	unit.vector[0] = source->common.transform->matrix[0][0];
+	unit.vector[1] = source->common.transform->matrix[1][0];
+	unit.vector[2] = source->common.transform->matrix[2][0];
+    } else {
+	unit.vector[0] = pixman_fixed_1;
+	unit.vector[1] = 0;
+	unit.vector[2] = 0;
+    }
+    
+    dx = linear->p2.x - linear->p1.x;
+    dy = linear->p2.y - linear->p1.y;
+    l = dx*dx + dy*dy;
+    if (l != 0) {
+	a = (dx << 32) / l;
+	b = (dy << 32) / l;
+	off = (-a*linear->p1.x - b*linear->p1.y)>>16;
+    }
+    if (l == 0  || (unit.vector[2] == 0 && v.vector[2] == pixman_fixed_1)) {
+	pixman_fixed_48_16_t inc, t;
+	/* affine transformation only */
+	if (l == 0) {
+	    t = 0;
+	    inc = 0;
+	} else {
+	    t = ((a*v.vector[0] + b*v.vector[1]) >> 16) + off;
+	    inc = (a * unit.vector[0] + b * unit.vector[1]) >> 16;
+	}
+	
+	if (source->class == SOURCE_IMAGE_CLASS_VERTICAL)
+	{
+	    register uint32_t color;
+	    
+	    color = _pixman_gradient_walker_pixel( &walker, t );
+	    while (buffer < end)
+		*(buffer++) = color;
+	}
+	else
+	{
+	    if (!mask) {
+		while (buffer < end)
+		{
+		    *(buffer) = _pixman_gradient_walker_pixel (&walker, t);
+		    buffer += 1;
+		    t      += inc;
+		}
+	    } else {
+		while (buffer < end) {
+		    if (*mask++ & maskBits)
+		    {
+			*(buffer) = _pixman_gradient_walker_pixel (&walker, t);
+		    }
+		    buffer += 1;
+		    t      += inc;
+		}
+	    }
+	}
+    }
+    else /* projective transformation */
+    {
+	pixman_fixed_48_16_t t;
+	
+	if (source->class == SOURCE_IMAGE_CLASS_VERTICAL)
+	{
+	    register uint32_t color;
+	    
+	    if (v.vector[2] == 0)
+	    {
+		t = 0;
+	    }
+	    else
+	    {
+		pixman_fixed_48_16_t x, y;
+		
+		x = ((pixman_fixed_48_16_t) v.vector[0] << 16) / v.vector[2];
+		y = ((pixman_fixed_48_16_t) v.vector[1] << 16) / v.vector[2];
+		t = ((a * x + b * y) >> 16) + off;
+	    }
+	    
+	    color = _pixman_gradient_walker_pixel( &walker, t );
+	    while (buffer < end)
+		*(buffer++) = color;
+	}
+	else
+	{
+	    while (buffer < end)
+	    {
+		if (!mask || *mask++ & maskBits)
+		{
+		    if (v.vector[2] == 0) {
+			t = 0;
+		    } else {
+			pixman_fixed_48_16_t x, y;
+			x = ((pixman_fixed_48_16_t)v.vector[0] << 16) / v.vector[2];
+			y = ((pixman_fixed_48_16_t)v.vector[1] << 16) / v.vector[2];
+			t = ((a*x + b*y) >> 16) + off;
+		    }
+		    *(buffer) = _pixman_gradient_walker_pixel (&walker, t);
+		}
+		++buffer;
+		v.vector[0] += unit.vector[0];
+		v.vector[1] += unit.vector[1];
+		v.vector[2] += unit.vector[2];
+	    }
+	}
+    }
+}
+
+static void
 linear_gradient_property_changed (pixman_image_t *image)
 {
-    image->common.get_scanline_32 = (scanFetchProc)pixmanFetchGradient;
+    image->common.get_scanline_32 = (scanFetchProc)linear_gradient_get_scanline_32;
     image->common.get_scanline_64 = (scanFetchProc)_pixman_image_get_scanline_64_generic;
 }
 
@@ -121,7 +254,7 @@ pixman_image_create_linear_gradient (pixman_point_fixed_t         *p1,
     image->source.class = SOURCE_IMAGE_CLASS_UNKNOWN;
     image->common.classify = linear_gradient_classify;
     image->common.property_changed = linear_gradient_property_changed;
-
+    
     linear_gradient_property_changed (image);
     
     return image;
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index a983da8..6f9575a 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -7,6 +7,7 @@
 
 #include "pixman.h"
 #include <time.h>
+#include <assert.h>
 
 #ifndef FALSE
 #define FALSE 0
diff --git a/pixman/pixman-source.c b/pixman/pixman-source.c
index ba0ba67..fbb0a77 100644
--- a/pixman/pixman-source.c
+++ b/pixman/pixman-source.c
@@ -45,123 +45,7 @@ pixmanFetchGradient(gradient_t *gradient, int x, int y, int width,
     _pixman_gradient_walker_init (&walker, gradient, pict->common.repeat);
 
     if (pict->common.type == LINEAR) {
-	pixman_vector_t v, unit;
-	pixman_fixed_32_32_t l;
-	pixman_fixed_48_16_t dx, dy, a, b, off;
-	linear_gradient_t *linear = (linear_gradient_t *)pict;
-
-        /* reference point is the center of the pixel */
-        v.vector[0] = pixman_int_to_fixed(x) + pixman_fixed_1/2;
-        v.vector[1] = pixman_int_to_fixed(y) + pixman_fixed_1/2;
-        v.vector[2] = pixman_fixed_1;
-        if (pict->common.transform) {
-            if (!pixman_transform_point_3d (pict->common.transform, &v))
-                return;
-            unit.vector[0] = pict->common.transform->matrix[0][0];
-            unit.vector[1] = pict->common.transform->matrix[1][0];
-            unit.vector[2] = pict->common.transform->matrix[2][0];
-        } else {
-            unit.vector[0] = pixman_fixed_1;
-            unit.vector[1] = 0;
-            unit.vector[2] = 0;
-        }
-
-        dx = linear->p2.x - linear->p1.x;
-        dy = linear->p2.y - linear->p1.y;
-        l = dx*dx + dy*dy;
-        if (l != 0) {
-            a = (dx << 32) / l;
-            b = (dy << 32) / l;
-            off = (-a*linear->p1.x - b*linear->p1.y)>>16;
-        }
-        if (l == 0  || (unit.vector[2] == 0 && v.vector[2] == pixman_fixed_1)) {
-            pixman_fixed_48_16_t inc, t;
-            /* affine transformation only */
-            if (l == 0) {
-                t = 0;
-                inc = 0;
-            } else {
-                t = ((a*v.vector[0] + b*v.vector[1]) >> 16) + off;
-                inc = (a * unit.vector[0] + b * unit.vector[1]) >> 16;
-            }
-
-	    if (pict->class == SOURCE_IMAGE_CLASS_VERTICAL)
-	    {
-		register uint32_t color;
-
-		color = _pixman_gradient_walker_pixel( &walker, t );
-		while (buffer < end)
-		    *(buffer++) = color;
-	    }
-	    else
-	    {
-                if (!mask) {
-                    while (buffer < end)
-                    {
-			*(buffer) = _pixman_gradient_walker_pixel (&walker, t);
-                        buffer += 1;
-                        t      += inc;
-                    }
-                } else {
-                    while (buffer < end) {
-                        if (*mask++ & maskBits)
-                        {
-			    *(buffer) = _pixman_gradient_walker_pixel (&walker, t);
-                        }
-                        buffer += 1;
-                        t      += inc;
-                    }
-                }
-	    }
-	}
-	else /* projective transformation */
-	{
-	    pixman_fixed_48_16_t t;
-
-	    if (pict->class == SOURCE_IMAGE_CLASS_VERTICAL)
-	    {
-		register uint32_t color;
-
-		if (v.vector[2] == 0)
-		{
-		    t = 0;
-		}
-		else
-		{
-		    pixman_fixed_48_16_t x, y;
-
-		    x = ((pixman_fixed_48_16_t) v.vector[0] << 16) / v.vector[2];
-		    y = ((pixman_fixed_48_16_t) v.vector[1] << 16) / v.vector[2];
-		    t = ((a * x + b * y) >> 16) + off;
-		}
-
- 		color = _pixman_gradient_walker_pixel( &walker, t );
-		while (buffer < end)
-		    *(buffer++) = color;
-	    }
-	    else
-	    {
-		while (buffer < end)
-		{
-		    if (!mask || *mask++ & maskBits)
-		    {
-			if (v.vector[2] == 0) {
-			    t = 0;
-			} else {
-			    pixman_fixed_48_16_t x, y;
-			    x = ((pixman_fixed_48_16_t)v.vector[0] << 16) / v.vector[2];
-			    y = ((pixman_fixed_48_16_t)v.vector[1] << 16) / v.vector[2];
-			    t = ((a*x + b*y) >> 16) + off;
-			}
-			*(buffer) = _pixman_gradient_walker_pixel (&walker, t);
-		    }
-		    ++buffer;
-		    v.vector[0] += unit.vector[0];
-		    v.vector[1] += unit.vector[1];
-		    v.vector[2] += unit.vector[2];
-		}
-            }
-        }
+	assert (0);
     } else {
 
 /*
commit ade664ced3b9ac64120424f0fc80dc0deef69b00
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Sun May 3 00:46:30 2009 -0400

    Rename pixmanFetchSourcePict to pixmanFetchGradient
    
    Move the solid fill parts into pixman-solid-fill.c

diff --git a/pixman/pixman-conical-gradient.c b/pixman/pixman-conical-gradient.c
index d5c4e23..974fd7c 100644
--- a/pixman/pixman-conical-gradient.c
+++ b/pixman/pixman-conical-gradient.c
@@ -27,7 +27,7 @@
 static void
 conical_gradient_property_changed (pixman_image_t *image)
 {
-    image->common.get_scanline_32 = (scanFetchProc)pixmanFetchSourcePict;
+    image->common.get_scanline_32 = (scanFetchProc)pixmanFetchGradient;
     image->common.get_scanline_64 = (scanFetchProc)_pixman_image_get_scanline_64_generic;
 }
 
diff --git a/pixman/pixman-linear-gradient.c b/pixman/pixman-linear-gradient.c
index c6c662a..b18c2cf 100644
--- a/pixman/pixman-linear-gradient.c
+++ b/pixman/pixman-linear-gradient.c
@@ -86,7 +86,7 @@ linear_gradient_classify (pixman_image_t *image,
 static void
 linear_gradient_property_changed (pixman_image_t *image)
 {
-    image->common.get_scanline_32 = (scanFetchProc)pixmanFetchSourcePict;
+    image->common.get_scanline_32 = (scanFetchProc)pixmanFetchGradient;
     image->common.get_scanline_64 = (scanFetchProc)_pixman_image_get_scanline_64_generic;
 }
 
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index ff1bfa6..a983da8 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -220,7 +220,7 @@ storeProc64 pixman_storeProcForPicture64_accessors (bits_image_t *);
 void pixman_expand(uint64_t *dst, const uint32_t *src, pixman_format_code_t, int width);
 void pixman_contract(uint32_t *dst, const uint64_t *src, int width);
 
-void pixmanFetchSourcePict(source_image_t *, int x, int y, int width,
+void pixmanFetchGradient (gradient_t *, int x, int y, int width,
                            uint32_t *buffer, uint32_t *mask, uint32_t maskBits);
 void _pixman_image_get_scanline_64_generic (pixman_image_t * pict, int x, int y, int width,
 					    uint64_t *buffer, uint64_t *mask, uint32_t maskBits);
diff --git a/pixman/pixman-radial-gradient.c b/pixman/pixman-radial-gradient.c
index e05299c..40c76ce 100644
--- a/pixman/pixman-radial-gradient.c
+++ b/pixman/pixman-radial-gradient.c
@@ -27,7 +27,7 @@
 static void
 radial_gradient_property_changed (pixman_image_t *image)
 {
-    image->common.get_scanline_32 = (scanFetchProc)pixmanFetchSourcePict;
+    image->common.get_scanline_32 = (scanFetchProc)pixmanFetchGradient;
     image->common.get_scanline_64 = (scanFetchProc)_pixman_image_get_scanline_64_generic;
 }
 
diff --git a/pixman/pixman-solid-fill.c b/pixman/pixman-solid-fill.c
index af383b5..1805600 100644
--- a/pixman/pixman-solid-fill.c
+++ b/pixman/pixman-solid-fill.c
@@ -24,6 +24,19 @@
 #include <config.h>
 #include "pixman-private.h"
 
+static void
+solid_fill_get_scanline_32 (pixman_image_t *image, int x, int y, int width,
+			    uint32_t *buffer, uint32_t *mask, uint32_t maskBits)
+{
+    uint32_t *end = buffer + width;
+    register uint32_t color = ((solid_fill_t *)image)->color;
+    
+    while (buffer < end)
+	*(buffer++) = color;
+    
+    return;
+}
+
 static source_pict_class_t
 solid_fill_classify (pixman_image_t *image,
 		     int	     x,
@@ -37,7 +50,7 @@ solid_fill_classify (pixman_image_t *image,
 static void
 solid_fill_property_changed (pixman_image_t *image)
 {
-    image->common.get_scanline_32 = (scanFetchProc)pixmanFetchSourcePict;
+    image->common.get_scanline_32 = (scanFetchProc)solid_fill_get_scanline_32;
     image->common.get_scanline_64 = (scanFetchProc)_pixman_image_get_scanline_64_generic;
 }
 
diff --git a/pixman/pixman-source.c b/pixman/pixman-source.c
index 0b2569e..ba0ba67 100644
--- a/pixman/pixman-source.c
+++ b/pixman/pixman-source.c
@@ -32,27 +32,15 @@
 
 #include "pixman-private.h"
 
-void pixmanFetchSourcePict(source_image_t * pict, int x, int y, int width,
-                           uint32_t *buffer, uint32_t *mask, uint32_t maskBits)
+void
+pixmanFetchGradient(gradient_t *gradient, int x, int y, int width,
+		    uint32_t *buffer, uint32_t *mask, uint32_t maskBits)
 {
-#if 0
-    SourcePictPtr   pGradient = pict->pSourcePict;
-#endif
     GradientWalker  walker;
     uint32_t       *end = buffer + width;
-    gradient_t	    *gradient;
-
-    if (pict->common.type == SOLID)
-    {
-	register uint32_t color = ((solid_fill_t *)pict)->color;
-
-	while (buffer < end)
-	    *(buffer++) = color;
-
-	return;
-    }
+    source_image_t *pict;
 
-    gradient = (gradient_t *)pict;
+    pict = (source_image_t *)gradient;
 
     _pixman_gradient_walker_init (&walker, gradient, pict->common.repeat);
 
commit 8267d8d38f794c51e09f440c470f1c23c59e11aa
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Sat May 2 23:26:30 2009 -0400

    Add a generic 64 bit fetcher and use it for gradients and transformed images

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 1437406..2dcf34b 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -90,7 +90,7 @@ bits_image_property_changed (pixman_image_t *image)
     if (bits->common.alpha_map)
     {
 	image->common.get_scanline_64 =
-	    (scanFetchProc)READ_ACCESS(fbFetchExternalAlpha64);
+	    (scanFetchProc)_pixman_image_get_scanline_64_generic;
 	image->common.get_scanline_32 =
 	    (scanFetchProc)READ_ACCESS(fbFetchExternalAlpha);
     }
@@ -112,7 +112,7 @@ bits_image_property_changed (pixman_image_t *image)
     else
     {
 	image->common.get_scanline_64 =
-	    (scanFetchProc)READ_ACCESS(fbFetchTransformed64);
+	    (scanFetchProc)_pixman_image_get_scanline_64_generic;
 	image->common.get_scanline_32 =
 	    (scanFetchProc)READ_ACCESS(fbFetchTransformed);
     }
diff --git a/pixman/pixman-compose.c b/pixman/pixman-compose.c
index d13d87c..23bfe5d 100644
--- a/pixman/pixman-compose.c
+++ b/pixman/pixman-compose.c
@@ -216,7 +216,7 @@ pixman_composite_rect_general (const FbComposeData *data)
     const int Bpp = wide ? 8 : 4;
     uint8_t *scanline_buffer = stack_scanline_buffer;
     uint8_t *src_buffer, *mask_buffer, *dest_buffer;
-
+    
     if (data->width * Bpp > SCANLINE_BUFFER_LENGTH)
     {
 	scanline_buffer = pixman_malloc_abc (data->width, 3, Bpp);
diff --git a/pixman/pixman-conical-gradient.c b/pixman/pixman-conical-gradient.c
index cd8d36c..d5c4e23 100644
--- a/pixman/pixman-conical-gradient.c
+++ b/pixman/pixman-conical-gradient.c
@@ -27,8 +27,8 @@
 static void
 conical_gradient_property_changed (pixman_image_t *image)
 {
-    image->common.get_scanline_64 = (scanFetchProc)pixmanFetchSourcePict64;
     image->common.get_scanline_32 = (scanFetchProc)pixmanFetchSourcePict;
+    image->common.get_scanline_64 = (scanFetchProc)_pixman_image_get_scanline_64_generic;
 }
 
 PIXMAN_EXPORT pixman_image_t *
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index 0553a5a..9d62f4a 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -56,6 +56,38 @@ _pixman_init_gradient (gradient_t     *gradient,
     return TRUE;
 }
 
+/*
+ * By default, just evaluate the image at 32bpp and expand.  Individual image
+ * types can plug in a better scanline getter if they want to. For example
+ * we  could produce smoother gradients by evaluating them at higher color depth, but
+ * that's a project for the future.
+ */
+void
+_pixman_image_get_scanline_64_generic (pixman_image_t * pict, int x, int y, int width,
+				       uint64_t *buffer, uint64_t *mask, uint32_t maskBits)
+{
+    uint32_t *mask8 = NULL;
+
+    // Contract the mask image, if one exists, so that the 32-bit fetch function
+    // can use it.
+    if (mask) {
+        mask8 = pixman_malloc_ab(width, sizeof(uint32_t));
+	if (!mask8)
+	    return;
+	
+        pixman_contract(mask8, mask, width);
+    }
+
+    // Fetch the source image into the first half of buffer.
+    _pixman_image_get_scanline_32 (pict, x, y, width, (uint32_t*)buffer, mask8,
+				   maskBits);
+
+    // Expand from 32bpp to 64bpp in place.
+    pixman_expand(buffer, (uint32_t*)buffer, PIXMAN_a8r8g8b8, width);
+
+    free(mask8);
+}
+
 pixman_image_t *
 _pixman_image_allocate (void)
 {
diff --git a/pixman/pixman-linear-gradient.c b/pixman/pixman-linear-gradient.c
index 46217a0..c6c662a 100644
--- a/pixman/pixman-linear-gradient.c
+++ b/pixman/pixman-linear-gradient.c
@@ -86,8 +86,8 @@ linear_gradient_classify (pixman_image_t *image,
 static void
 linear_gradient_property_changed (pixman_image_t *image)
 {
-    image->common.get_scanline_64 = (scanFetchProc)pixmanFetchSourcePict64;
     image->common.get_scanline_32 = (scanFetchProc)pixmanFetchSourcePict;
+    image->common.get_scanline_64 = (scanFetchProc)_pixman_image_get_scanline_64_generic;
 }
 
 PIXMAN_EXPORT pixman_image_t *
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index fedbbb3..ff1bfa6 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -222,9 +222,8 @@ void pixman_contract(uint32_t *dst, const uint64_t *src, int width);
 
 void pixmanFetchSourcePict(source_image_t *, int x, int y, int width,
                            uint32_t *buffer, uint32_t *mask, uint32_t maskBits);
-void pixmanFetchSourcePict64(source_image_t *, int x, int y, int width,
-                             uint64_t *buffer, uint64_t *mask, uint32_t maskBits);
-
+void _pixman_image_get_scanline_64_generic (pixman_image_t * pict, int x, int y, int width,
+					    uint64_t *buffer, uint64_t *mask, uint32_t maskBits);
 void fbFetchTransformed(bits_image_t *, int x, int y, int width,
                         uint32_t *buffer, uint32_t *mask, uint32_t maskBits);
 void fbStoreExternalAlpha(bits_image_t *, int x, int y, int width,
@@ -241,21 +240,11 @@ void fbFetchExternalAlpha_accessors(bits_image_t *, int x, int y, int width,
                                     uint32_t *buffer, uint32_t *mask,
                                     uint32_t maskBits);
 
-void fbFetchTransformed64(bits_image_t *, int x, int y, int width,
-                          uint64_t *buffer, uint64_t *mask, uint32_t maskBits);
 void fbStoreExternalAlpha64(bits_image_t *, int x, int y, int width,
                             uint64_t *buffer);
-void fbFetchExternalAlpha64(bits_image_t *, int x, int y, int width,
-                            uint64_t *buffer, uint64_t *mask, uint32_t maskBits);
 
-void fbFetchTransformed64_accessors(bits_image_t *, int x, int y, int width,
-                                    uint64_t *buffer, uint64_t *mask,
-                                    uint32_t maskBits);
 void fbStoreExternalAlpha64_accessors(bits_image_t *, int x, int y, int width,
                                       uint64_t *buffer);
-void fbFetchExternalAlpha64_accessors(bits_image_t *, int x, int y, int width,
-                                      uint64_t *buffer, uint64_t *mask,
-                                      uint32_t maskBits);
 
 /* end */
 
diff --git a/pixman/pixman-radial-gradient.c b/pixman/pixman-radial-gradient.c
index 62f8f27..e05299c 100644
--- a/pixman/pixman-radial-gradient.c
+++ b/pixman/pixman-radial-gradient.c
@@ -27,8 +27,8 @@
 static void
 radial_gradient_property_changed (pixman_image_t *image)
 {
-    image->common.get_scanline_64 = (scanFetchProc)pixmanFetchSourcePict64;
     image->common.get_scanline_32 = (scanFetchProc)pixmanFetchSourcePict;
+    image->common.get_scanline_64 = (scanFetchProc)_pixman_image_get_scanline_64_generic;
 }
 
 PIXMAN_EXPORT pixman_image_t *
diff --git a/pixman/pixman-solid-fill.c b/pixman/pixman-solid-fill.c
index b6e8ebb..af383b5 100644
--- a/pixman/pixman-solid-fill.c
+++ b/pixman/pixman-solid-fill.c
@@ -37,8 +37,8 @@ solid_fill_classify (pixman_image_t *image,
 static void
 solid_fill_property_changed (pixman_image_t *image)
 {
-    image->common.get_scanline_64 = (scanFetchProc)pixmanFetchSourcePict64;
     image->common.get_scanline_32 = (scanFetchProc)pixmanFetchSourcePict;
+    image->common.get_scanline_64 = (scanFetchProc)_pixman_image_get_scanline_64_generic;
 }
 
 static uint32_t
diff --git a/pixman/pixman-source.c b/pixman/pixman-source.c
index c405f49..0b2569e 100644
--- a/pixman/pixman-source.c
+++ b/pixman/pixman-source.c
@@ -458,30 +458,3 @@ void pixmanFetchSourcePict(source_image_t * pict, int x, int y, int width,
         }
     }
 }
-
-/*
- * For now, just evaluate the source picture at 32bpp and expand.  We could
- * produce smoother gradients by evaluating them at higher color depth, but
- * that's a project for the future.
- */
-void pixmanFetchSourcePict64(source_image_t * pict, int x, int y, int width,
-                             uint64_t *buffer, uint64_t *mask, uint32_t maskBits)
-{
-    uint32_t *mask8 = NULL;
-
-    // Contract the mask image, if one exists, so that the 32-bit fetch function
-    // can use it.
-    if (mask) {
-        mask8 = pixman_malloc_ab(width, sizeof(uint32_t));
-        pixman_contract(mask8, mask, width);
-    }
-
-    // Fetch the source image into the first half of buffer.
-    pixmanFetchSourcePict(pict, x, y, width, (uint32_t*)buffer, mask8,
-                          maskBits);
-
-    // Expand from 32bpp to 64bpp in place.
-    pixman_expand(buffer, (uint32_t*)buffer, PIXMAN_a8r8g8b8, width);
-
-    free(mask8);
-}
diff --git a/pixman/pixman-transformed.c b/pixman/pixman-transformed.c
index 6d695c5..997d24e 100644
--- a/pixman/pixman-transformed.c
+++ b/pixman/pixman-transformed.c
@@ -472,30 +472,6 @@ ACCESS(fbFetchTransformed)(bits_image_t * pict, int x, int y, int width,
     }
 }
 
-void
-ACCESS(fbFetchTransformed64)(bits_image_t * pict, int x, int y, int width,
-                             uint64_t *buffer, uint64_t *mask, uint32_t maskBits)
-{
-    // TODO: Don't lose precision for wide pictures!
-    uint32_t *mask8 = NULL;
-
-    // Contract the mask image, if one exists, so that the 32-bit fetch function
-    // can use it.
-    if (mask) {
-        mask8 = pixman_malloc_ab(width, sizeof(uint32_t));
-        pixman_contract(mask8, mask, width);
-    }
-
-    // Fetch the image into the first half of buffer.
-    ACCESS(fbFetchTransformed)(pict, x, y, width, (uint32_t*)buffer, mask8,
-                               maskBits);
-
-    // Expand from 32bpp to 64bpp in place.
-    pixman_expand(buffer, (uint32_t*)buffer, PIXMAN_a8r8g8b8, width);
-
-    free(mask8);
-}
-
 #define SCANLINE_BUFFER_LENGTH 2048
 
 void
@@ -534,45 +510,6 @@ ACCESS(fbFetchExternalAlpha)(bits_image_t * pict, int x, int y, int width,
 }
 
 void
-ACCESS(fbFetchExternalAlpha64)(bits_image_t * pict, int x, int y, int width,
-                               uint64_t *buffer, uint64_t *mask,
-                               uint32_t maskBits)
-{
-    int i;
-    uint64_t _alpha_buffer[SCANLINE_BUFFER_LENGTH];
-    uint64_t *alpha_buffer = _alpha_buffer;
-    uint64_t maskBits64;
-
-    if (!pict->common.alpha_map) {
-        ACCESS(fbFetchTransformed64) (pict, x, y, width, buffer, mask, maskBits);
-	return;
-    }
-    if (width > SCANLINE_BUFFER_LENGTH)
-        alpha_buffer = (uint64_t *) pixman_malloc_ab (width, sizeof(uint64_t));
-
-    ACCESS(fbFetchTransformed64)(pict, x, y, width, buffer, mask, maskBits);
-    ACCESS(fbFetchTransformed64)((bits_image_t *)pict->common.alpha_map, x - pict->common.alpha_origin.x,
-                                 y - pict->common.alpha_origin.y, width,
-                                 alpha_buffer, mask, maskBits);
-
-    pixman_expand(&maskBits64, &maskBits, PIXMAN_a8r8g8b8, 1);
-
-    for (i = 0; i < width; ++i) {
-        if (!mask || mask[i] & maskBits64)
-	{
-	    int64_t a = alpha_buffer[i]>>48;
-	    *(buffer + i) = (a << 48)
-		| (div_65535(Red64(*(buffer + i)) * a) << 32)
-		| (div_65535(Green64(*(buffer + i)) * a) << 16)
-		| (div_65535(Blue64(*(buffer + i)) * a));
-	}
-    }
-
-    if (alpha_buffer != _alpha_buffer)
-        free(alpha_buffer);
-}
-
-void
 ACCESS(fbStoreExternalAlpha)(bits_image_t * pict, int x, int y, int width,
                              uint32_t *buffer)
 {
commit ecaaef2f505fb61b383b194236b68ee59d52ecda
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Sat May 2 23:08:59 2009 -0400

    Move the gradient walker code to its own file

diff --git a/pixman/Makefile.am b/pixman/Makefile.am
index cca662e..ed5fca9 100644
--- a/pixman/Makefile.am
+++ b/pixman/Makefile.am
@@ -6,6 +6,7 @@ libpixman_1_la_SOURCES =		\
 	pixman.h			\
 	pixman-access.c			\
 	pixman-access-accessors.c	\
+	pixman-gradient-walker.c	\
 	pixman-region16.c		\
 	pixman-region32.c		\
 	pixman-private.h		\
diff --git a/pixman/pixman-gradient-walker.c b/pixman/pixman-gradient-walker.c
new file mode 100644
index 0000000..6a47a8e
--- /dev/null
+++ b/pixman/pixman-gradient-walker.c
@@ -0,0 +1,232 @@
+/*
+ *
+ * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
+ *             2005 Lars Knoll & Zack Rusin, Trolltech
+ *
+ * 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * 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.
+ */
+
+#include <config.h>
+#include "pixman-private.h"
+
+void
+_pixman_gradient_walker_init (GradientWalker  *walker,
+			      gradient_t      *gradient,
+			      unsigned int     spread)
+{
+    walker->num_stops = gradient->n_stops;
+    walker->stops     = gradient->stops;
+    walker->left_x    = 0;
+    walker->right_x   = 0x10000;
+    walker->stepper   = 0;
+    walker->left_ag   = 0;
+    walker->left_rb   = 0;
+    walker->right_ag  = 0;
+    walker->right_rb  = 0;
+    walker->spread    = spread;
+    
+    walker->need_reset = TRUE;
+}
+
+void
+_pixman_gradient_walker_reset (GradientWalker       *walker,
+			       pixman_fixed_32_32_t  pos)
+{
+    int32_t                  x, left_x, right_x;
+    pixman_color_t          *left_c, *right_c;
+    int                      n, count = walker->num_stops;
+    pixman_gradient_stop_t *      stops = walker->stops;
+    
+    static const pixman_color_t   transparent_black = { 0, 0, 0, 0 };
+    
+    switch (walker->spread)
+    {
+    case PIXMAN_REPEAT_NORMAL:
+	x = (int32_t)pos & 0xFFFF;
+	for (n = 0; n < count; n++)
+	    if (x < stops[n].x)
+		break;
+	if (n == 0) {
+	    left_x =  stops[count-1].x - 0x10000;
+	    left_c = &stops[count-1].color;
+	} else {
+	    left_x =  stops[n-1].x;
+	    left_c = &stops[n-1].color;
+	}
+	
+	if (n == count) {
+	    right_x =  stops[0].x + 0x10000;
+	    right_c = &stops[0].color;
+	} else {
+	    right_x =  stops[n].x;
+	    right_c = &stops[n].color;
+	}
+	left_x  += (pos - x);
+	right_x += (pos - x);
+	break;
+	
+    case PIXMAN_REPEAT_PAD:
+	for (n = 0; n < count; n++)
+	    if (pos < stops[n].x)
+		break;
+	
+	if (n == 0) {
+	    left_x =  INT32_MIN;
+	    left_c = &stops[0].color;
+	} else {
+	    left_x =  stops[n-1].x;
+	    left_c = &stops[n-1].color;
+	}
+	
+	if (n == count) {
+	    right_x =  INT32_MAX;
+	    right_c = &stops[n-1].color;
+	} else {
+	    right_x =  stops[n].x;
+	    right_c = &stops[n].color;
+	}
+	break;
+	
+    case PIXMAN_REPEAT_REFLECT:
+	x = (int32_t)pos & 0xFFFF;
+	if ((int32_t)pos & 0x10000)
+	    x = 0x10000 - x;
+	for (n = 0; n < count; n++)
+	    if (x < stops[n].x)
+		break;
+	
+	if (n == 0) {
+	    left_x =  -stops[0].x;
+	    left_c = &stops[0].color;
+	} else {
+	    left_x =  stops[n-1].x;
+	    left_c = &stops[n-1].color;
+	}
+	
+	if (n == count) {
+	    right_x = 0x20000 - stops[n-1].x;
+	    right_c = &stops[n-1].color;
+	} else {
+	    right_x =  stops[n].x;
+	    right_c = &stops[n].color;
+	}
+	
+	if ((int32_t)pos & 0x10000) {
+	    pixman_color_t  *tmp_c;
+	    int32_t          tmp_x;
+	    
+	    tmp_x   = 0x10000 - right_x;
+	    right_x = 0x10000 - left_x;
+	    left_x  = tmp_x;
+	    
+	    tmp_c   = right_c;
+	    right_c = left_c;
+	    left_c  = tmp_c;
+	    
+	    x = 0x10000 - x;
+	}
+	left_x  += (pos - x);
+	right_x += (pos - x);
+	break;
+	
+    default:  /* RepeatNone */
+	for (n = 0; n < count; n++)
+	    if (pos < stops[n].x)
+		break;
+	
+	if (n == 0)
+	{
+	    left_x  =  INT32_MIN;
+	    right_x =  stops[0].x;
+	    left_c  = right_c = (pixman_color_t*) &transparent_black;
+	}
+	else if (n == count)
+	{
+	    left_x  = stops[n-1].x;
+	    right_x = INT32_MAX;
+	    left_c  = right_c = (pixman_color_t*) &transparent_black;
+	}
+	else
+	{
+	    left_x  =  stops[n-1].x;
+	    right_x =  stops[n].x;
+	    left_c  = &stops[n-1].color;
+	    right_c = &stops[n].color;
+	}
+    }
+    
+    walker->left_x   = left_x;
+    walker->right_x  = right_x;
+    walker->left_ag  = ((left_c->alpha >> 8) << 16)   | (left_c->green >> 8);
+    walker->left_rb  = ((left_c->red & 0xff00) << 8)  | (left_c->blue >> 8);
+    walker->right_ag = ((right_c->alpha >> 8) << 16)  | (right_c->green >> 8);
+    walker->right_rb = ((right_c->red & 0xff00) << 8) | (right_c->blue >> 8);
+    
+    if ( walker->left_x == walker->right_x                ||
+	 ( walker->left_ag == walker->right_ag &&
+	   walker->left_rb == walker->right_rb )   )
+    {
+	walker->stepper = 0;
+    }
+    else
+    {
+	int32_t width = right_x - left_x;
+	walker->stepper = ((1 << 24) + width/2)/width;
+    }
+    
+    walker->need_reset = FALSE;
+}
+
+#define  PIXMAN_GRADIENT_WALKER_NEED_RESET(w,x)				\
+    ( (w)->need_reset || (x) < (w)->left_x || (x) >= (w)->right_x)
+
+
+/* the following assumes that PIXMAN_GRADIENT_WALKER_NEED_RESET(w,x) is FALSE */
+uint32_t
+_pixman_gradient_walker_pixel (GradientWalker  *walker,
+			       pixman_fixed_32_32_t     x)
+{
+    int  dist, idist;
+    uint32_t  t1, t2, a, color;
+    
+    if (PIXMAN_GRADIENT_WALKER_NEED_RESET (walker, x))
+        _pixman_gradient_walker_reset (walker, x);
+    
+    dist  = ((int)(x - walker->left_x)*walker->stepper) >> 16;
+    idist = 256 - dist;
+    
+    /* combined INTERPOLATE and premultiply */
+    t1 = walker->left_rb*idist + walker->right_rb*dist;
+    t1 = (t1 >> 8) & 0xff00ff;
+    
+    t2  = walker->left_ag*idist + walker->right_ag*dist;
+    t2 &= 0xff00ff00;
+    
+    color = t2 & 0xff000000;
+    a     = t2 >> 24;
+    
+    t1  = t1*a + 0x800080;
+    t1  = (t1 + ((t1 >> 8) & 0xff00ff)) >> 8;
+    
+    t2  = (t2 >> 8)*a + 0x800080;
+    t2  = (t2 + ((t2 >> 8) & 0xff00ff));
+    
+    return (color | (t1 & 0xff00ff) | (t2 & 0xff00));
+}
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 9baab65..fedbbb3 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -428,6 +428,39 @@ union pixman_image
     solid_fill_t		solid;
 };
 
+/* Gradient walker
+ */
+typedef struct
+{
+    uint32_t        left_ag;
+    uint32_t        left_rb;
+    uint32_t        right_ag;
+    uint32_t        right_rb;
+    int32_t       left_x;
+    int32_t       right_x;
+    int32_t       stepper;
+
+    pixman_gradient_stop_t	*stops;
+    int                      num_stops;
+    unsigned int             spread;
+
+    int		  need_reset;
+} GradientWalker;
+
+void
+_pixman_gradient_walker_init (GradientWalker  *walker,
+			      gradient_t      *gradient,
+			      unsigned int     spread);
+
+void
+_pixman_gradient_walker_reset (GradientWalker       *walker,
+			       pixman_fixed_32_32_t  pos);
+
+uint32_t
+_pixman_gradient_walker_pixel (GradientWalker       *walker,
+			       pixman_fixed_32_32_t  x);
+
+
 
 #define LOG2_BITMAP_PAD 5
 #define FB_STIP_SHIFT	LOG2_BITMAP_PAD
diff --git a/pixman/pixman-source.c b/pixman/pixman-source.c
index 6a640fa..c405f49 100644
--- a/pixman/pixman-source.c
+++ b/pixman/pixman-source.c
@@ -32,228 +32,6 @@
 
 #include "pixman-private.h"
 
-typedef struct
-{
-    uint32_t        left_ag;
-    uint32_t        left_rb;
-    uint32_t        right_ag;
-    uint32_t        right_rb;
-    int32_t       left_x;
-    int32_t       right_x;
-    int32_t       stepper;
-
-    pixman_gradient_stop_t	*stops;
-    int                      num_stops;
-    unsigned int             spread;
-
-    int		  need_reset;
-} GradientWalker;
-
-static void
-_gradient_walker_init (GradientWalker  *walker,
-		       gradient_t      *gradient,
-		       unsigned int     spread)
-{
-    walker->num_stops = gradient->n_stops;
-    walker->stops     = gradient->stops;
-    walker->left_x    = 0;
-    walker->right_x   = 0x10000;
-    walker->stepper   = 0;
-    walker->left_ag   = 0;
-    walker->left_rb   = 0;
-    walker->right_ag  = 0;
-    walker->right_rb  = 0;
-    walker->spread    = spread;
-
-    walker->need_reset = TRUE;
-}
-
-static void
-_gradient_walker_reset (GradientWalker  *walker,
-                        pixman_fixed_32_32_t     pos)
-{
-    int32_t                  x, left_x, right_x;
-    pixman_color_t          *left_c, *right_c;
-    int                      n, count = walker->num_stops;
-    pixman_gradient_stop_t *      stops = walker->stops;
-
-    static const pixman_color_t   transparent_black = { 0, 0, 0, 0 };
-
-    switch (walker->spread)
-    {
-    case PIXMAN_REPEAT_NORMAL:
-	x = (int32_t)pos & 0xFFFF;
-	for (n = 0; n < count; n++)
-	    if (x < stops[n].x)
-		break;
-	if (n == 0) {
-	    left_x =  stops[count-1].x - 0x10000;
-	    left_c = &stops[count-1].color;
-	} else {
-	    left_x =  stops[n-1].x;
-	    left_c = &stops[n-1].color;
-	}
-
-	if (n == count) {
-	    right_x =  stops[0].x + 0x10000;
-	    right_c = &stops[0].color;
-	} else {
-	    right_x =  stops[n].x;
-	    right_c = &stops[n].color;
-	}
-	left_x  += (pos - x);
-	right_x += (pos - x);
-	break;
-
-    case PIXMAN_REPEAT_PAD:
-	for (n = 0; n < count; n++)
-	    if (pos < stops[n].x)
-		break;
-
-	if (n == 0) {
-	    left_x =  INT32_MIN;
-	    left_c = &stops[0].color;
-	} else {
-	    left_x =  stops[n-1].x;
-	    left_c = &stops[n-1].color;
-	}
-
-	if (n == count) {
-	    right_x =  INT32_MAX;
-	    right_c = &stops[n-1].color;
-	} else {
-	    right_x =  stops[n].x;
-	    right_c = &stops[n].color;
-	}
-	break;
-
-    case PIXMAN_REPEAT_REFLECT:
-	x = (int32_t)pos & 0xFFFF;
-	if ((int32_t)pos & 0x10000)
-	    x = 0x10000 - x;
-	for (n = 0; n < count; n++)
-	    if (x < stops[n].x)
-		break;
-
-	if (n == 0) {
-	    left_x =  -stops[0].x;
-	    left_c = &stops[0].color;
-	} else {
-	    left_x =  stops[n-1].x;
-	    left_c = &stops[n-1].color;
-	}
-
-	if (n == count) {
-	    right_x = 0x20000 - stops[n-1].x;
-	    right_c = &stops[n-1].color;
-	} else {
-	    right_x =  stops[n].x;
-	    right_c = &stops[n].color;
-	}
-
-	if ((int32_t)pos & 0x10000) {
-	    pixman_color_t  *tmp_c;
-	    int32_t          tmp_x;
-
-	    tmp_x   = 0x10000 - right_x;
-	    right_x = 0x10000 - left_x;
-	    left_x  = tmp_x;
-
-	    tmp_c   = right_c;
-	    right_c = left_c;
-	    left_c  = tmp_c;
-
-	    x = 0x10000 - x;
-	}
-	left_x  += (pos - x);
-	right_x += (pos - x);
-	break;
-
-    default:  /* RepeatNone */
-	for (n = 0; n < count; n++)
-	    if (pos < stops[n].x)
-		break;
-
-	if (n == 0)
-	{
-	    left_x  =  INT32_MIN;
-	    right_x =  stops[0].x;
-	    left_c  = right_c = (pixman_color_t*) &transparent_black;
-	}
-	else if (n == count)
-	{
-	    left_x  = stops[n-1].x;
-	    right_x = INT32_MAX;
-	    left_c  = right_c = (pixman_color_t*) &transparent_black;
-	}
-	else
-	{
-	    left_x  =  stops[n-1].x;
-	    right_x =  stops[n].x;
-	    left_c  = &stops[n-1].color;
-	    right_c = &stops[n].color;
-	}
-    }
-
-    walker->left_x   = left_x;
-    walker->right_x  = right_x;
-    walker->left_ag  = ((left_c->alpha >> 8) << 16)   | (left_c->green >> 8);
-    walker->left_rb  = ((left_c->red & 0xff00) << 8)  | (left_c->blue >> 8);
-    walker->right_ag = ((right_c->alpha >> 8) << 16)  | (right_c->green >> 8);
-    walker->right_rb = ((right_c->red & 0xff00) << 8) | (right_c->blue >> 8);
-
-    if ( walker->left_x == walker->right_x                ||
-	 ( walker->left_ag == walker->right_ag &&
-	   walker->left_rb == walker->right_rb )   )
-    {
-	walker->stepper = 0;
-    }
-    else
-    {
-	int32_t width = right_x - left_x;
-	walker->stepper = ((1 << 24) + width/2)/width;
-    }
-
-    walker->need_reset = FALSE;
-}
-
-#define  GRADIENT_WALKER_NEED_RESET(w,x)				\
-    ( (w)->need_reset || (x) < (w)->left_x || (x) >= (w)->right_x)
-
-
-/* the following assumes that GRADIENT_WALKER_NEED_RESET(w,x) is FALSE */
-static uint32_t
-_gradient_walker_pixel (GradientWalker  *walker,
-                        pixman_fixed_32_32_t     x)
-{
-    int  dist, idist;
-    uint32_t  t1, t2, a, color;
-
-    if (GRADIENT_WALKER_NEED_RESET (walker, x))
-        _gradient_walker_reset (walker, x);
-
-    dist  = ((int)(x - walker->left_x)*walker->stepper) >> 16;
-    idist = 256 - dist;
-
-    /* combined INTERPOLATE and premultiply */
-    t1 = walker->left_rb*idist + walker->right_rb*dist;
-    t1 = (t1 >> 8) & 0xff00ff;
-
-    t2  = walker->left_ag*idist + walker->right_ag*dist;
-    t2 &= 0xff00ff00;
-
-    color = t2 & 0xff000000;
-    a     = t2 >> 24;
-
-    t1  = t1*a + 0x800080;
-    t1  = (t1 + ((t1 >> 8) & 0xff00ff)) >> 8;
-
-    t2  = (t2 >> 8)*a + 0x800080;
-    t2  = (t2 + ((t2 >> 8) & 0xff00ff));
-
-    return (color | (t1 & 0xff00ff) | (t2 & 0xff00));
-}
-
 void pixmanFetchSourcePict(source_image_t * pict, int x, int y, int width,
                            uint32_t *buffer, uint32_t *mask, uint32_t maskBits)
 {
@@ -276,7 +54,7 @@ void pixmanFetchSourcePict(source_image_t * pict, int x, int y, int width,
 
     gradient = (gradient_t *)pict;
 
-    _gradient_walker_init (&walker, gradient, pict->common.repeat);
+    _pixman_gradient_walker_init (&walker, gradient, pict->common.repeat);
 
     if (pict->common.type == LINEAR) {
 	pixman_vector_t v, unit;
@@ -323,7 +101,7 @@ void pixmanFetchSourcePict(source_image_t * pict, int x, int y, int width,
 	    {
 		register uint32_t color;
 
-		color = _gradient_walker_pixel( &walker, t );
+		color = _pixman_gradient_walker_pixel( &walker, t );
 		while (buffer < end)
 		    *(buffer++) = color;
 	    }
@@ -332,7 +110,7 @@ void pixmanFetchSourcePict(source_image_t * pict, int x, int y, int width,
                 if (!mask) {
                     while (buffer < end)
                     {
-			*(buffer) = _gradient_walker_pixel (&walker, t);
+			*(buffer) = _pixman_gradient_walker_pixel (&walker, t);
                         buffer += 1;
                         t      += inc;
                     }
@@ -340,7 +118,7 @@ void pixmanFetchSourcePict(source_image_t * pict, int x, int y, int width,
                     while (buffer < end) {
                         if (*mask++ & maskBits)
                         {
-			    *(buffer) = _gradient_walker_pixel (&walker, t);
+			    *(buffer) = _pixman_gradient_walker_pixel (&walker, t);
                         }
                         buffer += 1;
                         t      += inc;
@@ -369,7 +147,7 @@ void pixmanFetchSourcePict(source_image_t * pict, int x, int y, int width,
 		    t = ((a * x + b * y) >> 16) + off;
 		}
 
- 		color = _gradient_walker_pixel( &walker, t );
+ 		color = _pixman_gradient_walker_pixel( &walker, t );
 		while (buffer < end)
 		    *(buffer++) = color;
 	    }
@@ -387,7 +165,7 @@ void pixmanFetchSourcePict(source_image_t * pict, int x, int y, int width,
 			    y = ((pixman_fixed_48_16_t)v.vector[1] << 16) / v.vector[2];
 			    t = ((a*x + b*y) >> 16) + off;
 			}
-			*(buffer) = _gradient_walker_pixel (&walker, t);
+			*(buffer) = _pixman_gradient_walker_pixel (&walker, t);
 		    }
 		    ++buffer;
 		    v.vector[0] += unit.vector[0];
@@ -570,7 +348,7 @@ void pixmanFetchSourcePict(source_image_t * pict, int x, int y, int width,
 			else
 			    t = (pixman_fixed_48_16_t) ((- B + sqrt(det)) / (2.0 * radial->A) * 65536);
 
-			*(buffer) = _gradient_walker_pixel (&walker, t);
+			*(buffer) = _pixman_gradient_walker_pixel (&walker, t);
 		    }
 		    ++buffer;
 
@@ -615,7 +393,7 @@ void pixmanFetchSourcePict(source_image_t * pict, int x, int y, int width,
 			else
 			    t = (pixman_fixed_48_16_t) ((- B + sqrt(det)) / (2.0 * radial->A) * 65536);
 
-			*(buffer) = _gradient_walker_pixel (&walker, t);
+			*(buffer) = _pixman_gradient_walker_pixel (&walker, t);
 		    }
 		    ++buffer;
 
@@ -641,7 +419,7 @@ void pixmanFetchSourcePict(source_image_t * pict, int x, int y, int width,
                         angle = atan2(ry, rx) + a;
 			t     = (pixman_fixed_48_16_t) (angle * (65536. / (2*M_PI)));
 
-			*(buffer) = _gradient_walker_pixel (&walker, t);
+			*(buffer) = _pixman_gradient_walker_pixel (&walker, t);
 		    }
 
                     ++buffer;
@@ -668,7 +446,7 @@ void pixmanFetchSourcePict(source_image_t * pict, int x, int y, int width,
 			angle = atan2(y, x) + a;
 			t     = (pixman_fixed_48_16_t) (angle * (65536. / (2*M_PI)));
 
-			*(buffer) = _gradient_walker_pixel (&walker, t);
+			*(buffer) = _pixman_gradient_walker_pixel (&walker, t);
 		    }
 
                     ++buffer;
diff --git a/test/gradient-test.c b/test/gradient-test.c
index c3a0d1c..2593ee3 100644
--- a/test/gradient-test.c
+++ b/test/gradient-test.c
@@ -54,9 +54,8 @@ main (int argc, char **argv)
     r_inner = 0;
     r_outer = pixman_double_to_fixed (50.0);
     
-    src_img = pixman_image_create_radial_gradient (&c_inner, &c_outer,
-						   r_inner, r_outer,
-						   stops, 2);
+    src_img = pixman_image_create_conical_gradient (&c_inner, r_inner,
+						    stops, 2);
 #if 0
     src_img = pixman_image_create_conical_gradient (&c_inner, r_inner,
 						    stops, 2);
commit 51d972ecd885b05165a09d19fb3491ecb3ce813a
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Sat May 2 22:55:56 2009 -0400

    Replace pixman_image_get_fetchers() with pixman_image_get_scanline_{32,64}

diff --git a/pixman/pixman-compose.c b/pixman/pixman-compose.c
index be922a7..d13d87c 100644
--- a/pixman/pixman-compose.c
+++ b/pixman/pixman-compose.c
@@ -63,18 +63,24 @@ pixman_composite_rect_general_internal (const FbComposeData *data,
     
     if (data->op == PIXMAN_OP_CLEAR)
         fetchSrc = NULL;
+    else if (wide)
+	fetchSrc = _pixman_image_get_scanline_64;
     else
-	fetchSrc = _pixman_image_get_fetcher (data->src, wide);
+	fetchSrc = _pixman_image_get_scanline_32;
 
     if (!data->mask || data->op == PIXMAN_OP_CLEAR)
 	fetchMask = NULL;
+    else if (wide)
+	fetchMask = _pixman_image_get_scanline_64;
     else
-	fetchMask = _pixman_image_get_fetcher (data->mask, wide);
+	fetchMask = _pixman_image_get_scanline_32;
 
     if (data->op == PIXMAN_OP_CLEAR || data->op == PIXMAN_OP_SRC)
 	fetchDest = NULL;
+    else if (wide)
+	fetchDest = _pixman_image_get_scanline_64;
     else
-	fetchDest = _pixman_image_get_fetcher (data->dest, wide);
+	fetchDest = _pixman_image_get_scanline_32;
 
     store = _pixman_image_get_storer (data->dest, wide);
 
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index dd21718..0553a5a 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -98,6 +98,24 @@ _pixman_image_classify (pixman_image_t *image,
 	return SOURCE_IMAGE_CLASS_UNKNOWN;
 }
 
+void
+_pixman_image_get_scanline_32 (pixman_image_t *image, int x, int y, int width,
+			       uint32_t *buffer, uint32_t *mask, uint32_t mask_bits)
+{
+    image->common.get_scanline_32 (image, x, y, width, buffer, mask, mask_bits);
+}
+
+void
+_pixman_image_get_scanline_64 (pixman_image_t *image, int x, int y, int width,
+			       uint32_t *buffer, uint32_t *unused, uint32_t unused2)
+{
+    image->common.get_scanline_64 (image, x, y, width, buffer, unused, unused2);
+}
+
+/* Even thought the type of buffer is uint32_t *, the function actually expects
+ * a uint64_t *buffer.
+ */
+
 scanFetchProc
 _pixman_image_get_fetcher (pixman_image_t *image,
 			   int             wide)
@@ -111,8 +129,6 @@ _pixman_image_get_fetcher (pixman_image_t *image,
 	return image->common.get_scanline_32;
 }
 
-
-
 #define WRITE_ACCESS(f) ((image->common.write_func)? f##_accessors : f)
 
 static void
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 0881a7c..9baab65 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -287,9 +287,16 @@ source_pict_class_t _pixman_image_classify (pixman_image_t *image,
 					    int             width,
 					    int             height);
 
-scanFetchProc
-_pixman_image_get_fetcher (pixman_image_t *image,
-			   int             wide);
+void
+_pixman_image_get_scanline_32 (pixman_image_t *image, int x, int y, int width,
+			       uint32_t *buffer, uint32_t *mask, uint32_t mask_bits);
+
+/* Even thought the type of buffer is uint32_t *, the function actually expects
+ * a uint64_t *buffer.
+ */
+void
+_pixman_image_get_scanline_64 (pixman_image_t *image, int x, int y, int width,
+			       uint32_t *buffer, uint32_t *unused, uint32_t unused2);
 
 scanStoreProc
 _pixman_image_get_storer (pixman_image_t *image,
commit b7f113200e285c003b9225de83d8fe83492717ee
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Sat May 2 22:46:20 2009 -0400

    Set up scanline getters for bits images

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 9b0f224..1437406 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -24,10 +24,98 @@
 #include <stdlib.h>
 #include "pixman-private.h"
 
+
+#define READ_ACCESS(f) ((image->common.read_func)? f##_accessors : f)
+
+static void
+fbFetchSolid(bits_image_t * image,
+	     int x, int y, int width,
+	     uint32_t *buffer,
+	     uint32_t *mask, uint32_t maskBits)
+{
+    uint32_t color;
+    uint32_t *end;
+    fetchPixelProc32 fetch =
+	READ_ACCESS(pixman_fetchPixelProcForPicture32)(image);
+    
+    color = fetch(image, 0, 0);
+    
+    end = buffer + width;
+    while (buffer < end)
+	*(buffer++) = color;
+}
+
+static void
+fbFetchSolid64(bits_image_t * image,
+	       int x, int y, int width,
+	       uint64_t *buffer, void *unused, uint32_t unused2)
+{
+    uint64_t color;
+    uint64_t *end;
+    fetchPixelProc64 fetch =
+	READ_ACCESS(pixman_fetchPixelProcForPicture64)(image);
+    
+    color = fetch(image, 0, 0);
+    
+    end = buffer + width;
+    while (buffer < end)
+	*(buffer++) = color;
+}
+
+static void
+fbFetch(bits_image_t * image,
+	int x, int y, int width,
+	uint32_t *buffer, uint32_t *mask, uint32_t maskBits)
+{
+    fetchProc32 fetch = READ_ACCESS(pixman_fetchProcForPicture32)(image);
+    
+    fetch(image, x, y, width, buffer);
+}
+
+static void
+fbFetch64(bits_image_t * image,
+	  int x, int y, int width,
+	  uint64_t *buffer, void *unused, uint32_t unused2)
+{
+    fetchProc64 fetch = READ_ACCESS(pixman_fetchProcForPicture64)(image);
+    
+    fetch(image, x, y, width, buffer);
+}
+
 static void
 bits_image_property_changed (pixman_image_t *image)
 {
+    bits_image_t *bits = (bits_image_t *)image;
     
+    if (bits->common.alpha_map)
+    {
+	image->common.get_scanline_64 =
+	    (scanFetchProc)READ_ACCESS(fbFetchExternalAlpha64);
+	image->common.get_scanline_32 =
+	    (scanFetchProc)READ_ACCESS(fbFetchExternalAlpha);
+    }
+    else if ((bits->common.repeat != PIXMAN_REPEAT_NONE) &&
+	     bits->width == 1 &&
+	     bits->height == 1)
+    {
+	image->common.get_scanline_64 = (scanFetchProc)fbFetchSolid64;
+	image->common.get_scanline_32 = (scanFetchProc)fbFetchSolid;
+    }
+    else if (!bits->common.transform &&
+	     bits->common.filter != PIXMAN_FILTER_CONVOLUTION &&
+	     bits->common.repeat != PIXMAN_REPEAT_PAD &&
+	     bits->common.repeat != PIXMAN_REPEAT_REFLECT)
+    {
+	image->common.get_scanline_64 = (scanFetchProc)fbFetch64;
+	image->common.get_scanline_32 = (scanFetchProc)fbFetch;
+    }
+    else
+    {
+	image->common.get_scanline_64 =
+	    (scanFetchProc)READ_ACCESS(fbFetchTransformed64);
+	image->common.get_scanline_32 =
+	    (scanFetchProc)READ_ACCESS(fbFetchTransformed);
+    }
 }
 
 static uint32_t *
@@ -39,37 +127,37 @@ create_bits (pixman_format_code_t format,
     int stride;
     int buf_size;
     int bpp;
-
+    
     /* what follows is a long-winded way, avoiding any possibility of integer
      * overflows, of saying:
      * stride = ((width * bpp + FB_MASK) >> FB_SHIFT) * sizeof (uint32_t);
      */
-
+    
     bpp = PIXMAN_FORMAT_BPP (format);
     if (pixman_multiply_overflows_int (width, bpp))
 	return NULL;
-
+    
     stride = width * bpp;
     if (pixman_addition_overflows_int (stride, FB_MASK))
 	return NULL;
-
+    
     stride += FB_MASK;
     stride >>= FB_SHIFT;
-
+    
 #if FB_SHIFT < 2
     if (pixman_multiply_overflows_int (stride, sizeof (uint32_t)))
 	return NULL;
 #endif
     stride *= sizeof (uint32_t);
-
+    
     if (pixman_multiply_overflows_int (height, stride))
 	return NULL;
-
+    
     buf_size = height * stride;
-
+    
     if (rowstride_bytes)
 	*rowstride_bytes = stride;
-
+    
     return calloc (buf_size, 1);
 }
 
@@ -82,21 +170,21 @@ pixman_image_create_bits (pixman_format_code_t  format,
 {
     pixman_image_t *image;
     uint32_t *free_me = NULL;
-
+    
     /* must be a whole number of uint32_t's
      */
     return_val_if_fail (bits == NULL ||
 			(rowstride_bytes % sizeof (uint32_t)) == 0, NULL);
-
+    
     if (!bits && width && height)
     {
 	free_me = bits = create_bits (format, width, height, &rowstride_bytes);
 	if (!bits)
 	    return NULL;
     }
-
+    
     image = _pixman_image_allocate();
-
+    
     if (!image) {
 	if (free_me)
 	    free (free_me);
@@ -109,21 +197,21 @@ pixman_image_create_bits (pixman_format_code_t  format,
     image->bits.height = height;
     image->bits.bits = bits;
     image->bits.free_me = free_me;
-
+    
     image->bits.rowstride = rowstride_bytes / (int) sizeof (uint32_t); /* we store it in number
-								  * of uint32_t's
-								  */
+									* of uint32_t's
+									*/
     image->bits.indexed = NULL;
-
+    
     pixman_region32_fini (&image->common.full_region);
     pixman_region32_init_rect (&image->common.full_region, 0, 0,
 			       image->bits.width, image->bits.height);
-
+    
     image->common.property_changed = bits_image_property_changed;
     
     bits_image_property_changed (image);
     
     _pixman_image_reset_clip_region (image);
-
+    
     return image;
 }
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index 859cb0d..dd21718 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -98,91 +98,10 @@ _pixman_image_classify (pixman_image_t *image,
 	return SOURCE_IMAGE_CLASS_UNKNOWN;
 }
 
-#define READ_ACCESS(f) ((image->common.read_func)? f##_accessors : f)
-
-static void fbFetchSolid(bits_image_t * image, int x, int y, int width, uint32_t *buffer, uint32_t *mask, uint32_t maskBits)
-{
-    uint32_t color;
-    uint32_t *end;
-    fetchPixelProc32 fetch = READ_ACCESS(pixman_fetchPixelProcForPicture32)(image);
-
-    color = fetch(image, 0, 0);
-
-    end = buffer + width;
-    while (buffer < end)
-	*(buffer++) = color;
-}
-
-static void fbFetchSolid64(bits_image_t * image, int x, int y, int width, uint64_t *buffer, void *unused, uint32_t unused2)
-{
-    uint64_t color;
-    uint64_t *end;
-    fetchPixelProc64 fetch = READ_ACCESS(pixman_fetchPixelProcForPicture64)(image);
-
-    color = fetch(image, 0, 0);
-
-    end = buffer + width;
-    while (buffer < end)
-	*(buffer++) = color;
-}
-
-static void fbFetch(bits_image_t * image, int x, int y, int width, uint32_t *buffer, uint32_t *mask, uint32_t maskBits)
-{
-    fetchProc32 fetch = READ_ACCESS(pixman_fetchProcForPicture32)(image);
-
-    fetch(image, x, y, width, buffer);
-}
-
-static void fbFetch64(bits_image_t * image, int x, int y, int width, uint64_t *buffer, void *unused, uint32_t unused2)
-{
-    fetchProc64 fetch = READ_ACCESS(pixman_fetchProcForPicture64)(image);
-
-    fetch(image, x, y, width, buffer);
-}
-
-static void
-set_fetchers (pixman_image_t *image)
-{
-    if (!IS_SOURCE_IMAGE (image))
-    {
-	bits_image_t *bits = (bits_image_t *)image;
-	
-	if (bits->common.alpha_map)
-	{
-	    image->common.get_scanline_64 =
-		(scanFetchProc)READ_ACCESS(fbFetchExternalAlpha64);
-	    image->common.get_scanline_32 =
-		(scanFetchProc)READ_ACCESS(fbFetchExternalAlpha);
-	}
-	else if ((bits->common.repeat != PIXMAN_REPEAT_NONE) &&
-		 bits->width == 1 &&
-		 bits->height == 1)
-	{
-	    image->common.get_scanline_64 = (scanFetchProc)fbFetchSolid64;
-	    image->common.get_scanline_32 = (scanFetchProc)fbFetchSolid;
-	}
-	else if (!bits->common.transform &&
-		 bits->common.filter != PIXMAN_FILTER_CONVOLUTION &&
-		 bits->common.repeat != PIXMAN_REPEAT_PAD &&
-		 bits->common.repeat != PIXMAN_REPEAT_REFLECT)
-	{
-	    image->common.get_scanline_64 = (scanFetchProc)fbFetch64;
-	    image->common.get_scanline_32 = (scanFetchProc)fbFetch;
-	}
-	else
-	{
-	    image->common.get_scanline_64 = (scanFetchProc)READ_ACCESS(fbFetchTransformed64);
-	    image->common.get_scanline_32 = (scanFetchProc)READ_ACCESS(fbFetchTransformed);
-	}
-    }
-}
-
 scanFetchProc
 _pixman_image_get_fetcher (pixman_image_t *image,
 			   int             wide)
 {
-    set_fetchers (image);
-
     assert (image->common.get_scanline_64);
     assert (image->common.get_scanline_32);
     
commit b496d566dcc3e277f9ed9a8e93dbb3963a6d14e6
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Sat May 2 22:42:59 2009 -0400

    Set up scanline getters for source pictures

diff --git a/pixman/pixman-conical-gradient.c b/pixman/pixman-conical-gradient.c
index 7f8853c..cd8d36c 100644
--- a/pixman/pixman-conical-gradient.c
+++ b/pixman/pixman-conical-gradient.c
@@ -27,7 +27,8 @@
 static void
 conical_gradient_property_changed (pixman_image_t *image)
 {
-    
+    image->common.get_scanline_64 = (scanFetchProc)pixmanFetchSourcePict64;
+    image->common.get_scanline_32 = (scanFetchProc)pixmanFetchSourcePict;
 }
 
 PIXMAN_EXPORT pixman_image_t *
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index d0bf102..859cb0d 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -27,6 +27,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
+#include <assert.h>
 
 #include "pixman-private.h"
 
@@ -142,15 +143,10 @@ static void fbFetch64(bits_image_t * image, int x, int y, int width, uint64_t *b
 static void
 set_fetchers (pixman_image_t *image)
 {
-    if (IS_SOURCE_IMAGE (image))
-    {
-	image->common.get_scanline_64 = (scanFetchProc)pixmanFetchSourcePict64;
-	image->common.get_scanline_32 = (scanFetchProc)pixmanFetchSourcePict;
-    }
-    else
+    if (!IS_SOURCE_IMAGE (image))
     {
 	bits_image_t *bits = (bits_image_t *)image;
-
+	
 	if (bits->common.alpha_map)
 	{
 	    image->common.get_scanline_64 =
@@ -186,6 +182,10 @@ _pixman_image_get_fetcher (pixman_image_t *image,
 			   int             wide)
 {
     set_fetchers (image);
+
+    assert (image->common.get_scanline_64);
+    assert (image->common.get_scanline_32);
+    
     if (wide)
 	return image->common.get_scanline_64;
     else
diff --git a/pixman/pixman-linear-gradient.c b/pixman/pixman-linear-gradient.c
index 2a8605c..46217a0 100644
--- a/pixman/pixman-linear-gradient.c
+++ b/pixman/pixman-linear-gradient.c
@@ -86,7 +86,8 @@ linear_gradient_classify (pixman_image_t *image,
 static void
 linear_gradient_property_changed (pixman_image_t *image)
 {
-    
+    image->common.get_scanline_64 = (scanFetchProc)pixmanFetchSourcePict64;
+    image->common.get_scanline_32 = (scanFetchProc)pixmanFetchSourcePict;
 }
 
 PIXMAN_EXPORT pixman_image_t *
diff --git a/pixman/pixman-radial-gradient.c b/pixman/pixman-radial-gradient.c
index ca52c11..62f8f27 100644
--- a/pixman/pixman-radial-gradient.c
+++ b/pixman/pixman-radial-gradient.c
@@ -27,7 +27,8 @@
 static void
 radial_gradient_property_changed (pixman_image_t *image)
 {
-    
+    image->common.get_scanline_64 = (scanFetchProc)pixmanFetchSourcePict64;
+    image->common.get_scanline_32 = (scanFetchProc)pixmanFetchSourcePict;
 }
 
 PIXMAN_EXPORT pixman_image_t *
diff --git a/pixman/pixman-solid-fill.c b/pixman/pixman-solid-fill.c
index 2663012..b6e8ebb 100644
--- a/pixman/pixman-solid-fill.c
+++ b/pixman/pixman-solid-fill.c
@@ -37,7 +37,8 @@ solid_fill_classify (pixman_image_t *image,
 static void
 solid_fill_property_changed (pixman_image_t *image)
 {
-    
+    image->common.get_scanline_64 = (scanFetchProc)pixmanFetchSourcePict64;
+    image->common.get_scanline_32 = (scanFetchProc)pixmanFetchSourcePict;
 }
 
 static uint32_t
commit c62f2a14f433a07c5333cfefeed934214507d63a
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Sat May 2 22:26:23 2009 -0400

    Store get_scanline() functions in the image struct

diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index 42362eb..d0bf102 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -139,16 +139,13 @@ static void fbFetch64(bits_image_t * image, int x, int y, int width, uint64_t *b
     fetch(image, x, y, width, buffer);
 }
 
-scanFetchProc
-_pixman_image_get_fetcher (pixman_image_t *image,
-			   int             wide)
+static void
+set_fetchers (pixman_image_t *image)
 {
     if (IS_SOURCE_IMAGE (image))
     {
-	if (wide)
-	    return (scanFetchProc)pixmanFetchSourcePict64;
-	else
-	    return (scanFetchProc)pixmanFetchSourcePict;
+	image->common.get_scanline_64 = (scanFetchProc)pixmanFetchSourcePict64;
+	image->common.get_scanline_32 = (scanFetchProc)pixmanFetchSourcePict;
     }
     else
     {
@@ -156,38 +153,45 @@ _pixman_image_get_fetcher (pixman_image_t *image,
 
 	if (bits->common.alpha_map)
 	{
-	    if (wide)
-		return (scanFetchProc)READ_ACCESS(fbFetchExternalAlpha64);
-	    else
-		return (scanFetchProc)READ_ACCESS(fbFetchExternalAlpha);
+	    image->common.get_scanline_64 =
+		(scanFetchProc)READ_ACCESS(fbFetchExternalAlpha64);
+	    image->common.get_scanline_32 =
+		(scanFetchProc)READ_ACCESS(fbFetchExternalAlpha);
 	}
 	else if ((bits->common.repeat != PIXMAN_REPEAT_NONE) &&
 		 bits->width == 1 &&
 		 bits->height == 1)
 	{
-	    if (wide)
-		return (scanFetchProc)fbFetchSolid64;
-	    else
-		return (scanFetchProc)fbFetchSolid;
+	    image->common.get_scanline_64 = (scanFetchProc)fbFetchSolid64;
+	    image->common.get_scanline_32 = (scanFetchProc)fbFetchSolid;
 	}
-	else if (!bits->common.transform && bits->common.filter != PIXMAN_FILTER_CONVOLUTION
-                && bits->common.repeat != PIXMAN_REPEAT_PAD && bits->common.repeat != PIXMAN_REPEAT_REFLECT)
+	else if (!bits->common.transform &&
+		 bits->common.filter != PIXMAN_FILTER_CONVOLUTION &&
+		 bits->common.repeat != PIXMAN_REPEAT_PAD &&
+		 bits->common.repeat != PIXMAN_REPEAT_REFLECT)
 	{
-	    if (wide)
-		return (scanFetchProc)fbFetch64;
-	    else
-		return (scanFetchProc)fbFetch;
+	    image->common.get_scanline_64 = (scanFetchProc)fbFetch64;
+	    image->common.get_scanline_32 = (scanFetchProc)fbFetch;
 	}
 	else
 	{
-	    if (wide)
-		return (scanFetchProc)READ_ACCESS(fbFetchTransformed64);
-	    else
-		return (scanFetchProc)READ_ACCESS(fbFetchTransformed);
+	    image->common.get_scanline_64 = (scanFetchProc)READ_ACCESS(fbFetchTransformed64);
+	    image->common.get_scanline_32 = (scanFetchProc)READ_ACCESS(fbFetchTransformed);
 	}
     }
 }
 
+scanFetchProc
+_pixman_image_get_fetcher (pixman_image_t *image,
+			   int             wide)
+{
+    set_fetchers (image);
+    if (wide)
+	return image->common.get_scanline_64;
+    else
+	return image->common.get_scanline_32;
+}
+
 
 
 #define WRITE_ACCESS(f) ((image->common.write_func)? f##_accessors : f)
@@ -243,6 +247,8 @@ _pixman_image_get_storer (pixman_image_t *image,
 static void
 image_property_changed (pixman_image_t *image)
 {
+    
+    
     image->common.property_changed (image);
 }
 
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 9a9ec59..0881a7c 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -337,6 +337,8 @@ struct image_common
     pixman_write_memory_func_t	write_func;
     classify_func_t		classify;
     property_changed_func_t	property_changed;
+    scanFetchProc		get_scanline_32;
+    scanFetchProc		get_scanline_64;
 };
 
 struct source_image
commit 0b497b33fe8bdfc404ed377f3b7525b4e5c11ad5
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Sat May 2 22:00:25 2009 -0400

    Add stubs for property_changed virtual functions

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index 7df159f..9b0f224 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -24,6 +24,12 @@
 #include <stdlib.h>
 #include "pixman-private.h"
 
+static void
+bits_image_property_changed (pixman_image_t *image)
+{
+    
+}
+
 static uint32_t *
 create_bits (pixman_format_code_t format,
 	     int		  width,
@@ -113,6 +119,11 @@ pixman_image_create_bits (pixman_format_code_t  format,
     pixman_region32_init_rect (&image->common.full_region, 0, 0,
 			       image->bits.width, image->bits.height);
 
+    image->common.property_changed = bits_image_property_changed;
+    
+    bits_image_property_changed (image);
+    
     _pixman_image_reset_clip_region (image);
+
     return image;
 }
diff --git a/pixman/pixman-conical-gradient.c b/pixman/pixman-conical-gradient.c
index 0b041f0..7f8853c 100644
--- a/pixman/pixman-conical-gradient.c
+++ b/pixman/pixman-conical-gradient.c
@@ -24,11 +24,17 @@
 #include <stdlib.h>
 #include "pixman-private.h"
 
+static void
+conical_gradient_property_changed (pixman_image_t *image)
+{
+    
+}
+
 PIXMAN_EXPORT pixman_image_t *
-pixman_image_create_conical_gradient (pixman_point_fixed_t *center,
-				      pixman_fixed_t angle,
+pixman_image_create_conical_gradient (pixman_point_fixed_t         *center,
+				      pixman_fixed_t                angle,
 				      const pixman_gradient_stop_t *stops,
-				      int n_stops)
+				      int                           n_stops)
 {
     pixman_image_t *image = _pixman_image_allocate();
     conical_gradient_t *conical;
@@ -48,5 +54,9 @@ pixman_image_create_conical_gradient (pixman_point_fixed_t *center,
     conical->center = *center;
     conical->angle = angle;
 
+    image->common.property_changed = conical_gradient_property_changed;
+
+    conical_gradient_property_changed (image);
+    
     return image;
 }
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index 1ee7529..42362eb 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -240,6 +240,12 @@ _pixman_image_get_storer (pixman_image_t *image,
     }
 }
 
+static void
+image_property_changed (pixman_image_t *image)
+{
+    image->common.property_changed (image);
+}
+
 /* Ref Counting */
 PIXMAN_EXPORT pixman_image_t *
 pixman_image_ref (pixman_image_t *image)
@@ -320,17 +326,22 @@ pixman_image_set_clip_region32 (pixman_image_t *image,
 				pixman_region32_t *region)
 {
     image_common_t *common = (image_common_t *)image;
+    pixman_bool_t result;
 
     if (region)
     {
-	return pixman_region32_copy (&common->clip_region, region);
+	result = pixman_region32_copy (&common->clip_region, region);
     }
     else
     {
 	_pixman_image_reset_clip_region (image);
 
-	return TRUE;
+	result = TRUE;
     }
+
+    image_property_changed (image);
+
+    return result;
 }
 
 
@@ -339,17 +350,22 @@ pixman_image_set_clip_region (pixman_image_t    *image,
 			      pixman_region16_t *region)
 {
     image_common_t *common = (image_common_t *)image;
+    pixman_bool_t result;
 
     if (region)
     {
-	return pixman_region32_copy_from_region16 (&common->clip_region, region);
+	result = pixman_region32_copy_from_region16 (&common->clip_region, region);
     }
     else
     {
 	_pixman_image_reset_clip_region (image);
 
-	return TRUE;
+	result = TRUE;
     }
+
+    image_property_changed (image);
+
+    return result;
 }
 
 /* Sets whether the clip region includes a clip region set by the client
@@ -359,6 +375,8 @@ pixman_image_set_has_client_clip (pixman_image_t *image,
 				  pixman_bool_t	  client_clip)
 {
     image->common.has_client_clip = client_clip;
+
+    image_property_changed (image);
 }
 
 PIXMAN_EXPORT pixman_bool_t
@@ -374,6 +392,7 @@ pixman_image_set_transform (pixman_image_t           *image,
     };
 
     image_common_t *common = (image_common_t *)image;
+    pixman_bool_t result;
 
     if (common->transform == transform)
 	return TRUE;
@@ -382,16 +401,24 @@ pixman_image_set_transform (pixman_image_t           *image,
     {
 	free(common->transform);
 	common->transform = NULL;
-	return TRUE;
+	result = TRUE;
+	goto out;
     }
 
     if (common->transform == NULL)
 	common->transform = malloc (sizeof (pixman_transform_t));
+
     if (common->transform == NULL)
-	return FALSE;
+    {
+	result = FALSE;
+	goto out;
+    }
 
     memcpy(common->transform, transform, sizeof(pixman_transform_t));
 
+out:
+    image_property_changed (image);
+    
     return TRUE;
 }
 
@@ -400,6 +427,8 @@ pixman_image_set_repeat (pixman_image_t  *image,
 			 pixman_repeat_t  repeat)
 {
     image->common.repeat = repeat;
+
+    image_property_changed (image);
 }
 
 PIXMAN_EXPORT pixman_bool_t
@@ -432,6 +461,8 @@ pixman_image_set_filter (pixman_image_t       *image,
 
     common->filter_params = new_params;
     common->n_filter_params = n_params;
+
+    image_property_changed (image);
     return TRUE;
 }
 
@@ -445,6 +476,8 @@ pixman_image_set_source_clipping (pixman_image_t  *image,
 	common->src_clip = &common->clip_region;
     else
 	common->src_clip = &common->full_region;
+
+    image_property_changed (image);
 }
 
 /* Unlike all the other property setters, this function does not
@@ -458,6 +491,8 @@ pixman_image_set_indexed (pixman_image_t	 *image,
     bits_image_t *bits = (bits_image_t *)image;
 
     bits->indexed = indexed;
+
+    image_property_changed (image);
 }
 
 PIXMAN_EXPORT void
@@ -483,6 +518,8 @@ pixman_image_set_alpha_map (pixman_image_t *image,
 
     common->alpha_origin.x = x;
     common->alpha_origin.y = y;
+
+    image_property_changed (image);
 }
 
 PIXMAN_EXPORT void
@@ -490,6 +527,8 @@ pixman_image_set_component_alpha   (pixman_image_t       *image,
 				    pixman_bool_t         component_alpha)
 {
     image->common.component_alpha = component_alpha;
+
+    image_property_changed (image);
 }
 
 
@@ -502,6 +541,8 @@ pixman_image_set_accessors (pixman_image_t             *image,
 
     image->common.read_func = read_func;
     image->common.write_func = write_func;
+
+    image_property_changed (image);
 }
 
 PIXMAN_EXPORT uint32_t *
diff --git a/pixman/pixman-linear-gradient.c b/pixman/pixman-linear-gradient.c
index 04bd796..2a8605c 100644
--- a/pixman/pixman-linear-gradient.c
+++ b/pixman/pixman-linear-gradient.c
@@ -83,6 +83,12 @@ linear_gradient_classify (pixman_image_t *image,
     return image->source.class;
 }
 
+static void
+linear_gradient_property_changed (pixman_image_t *image)
+{
+    
+}
+
 PIXMAN_EXPORT pixman_image_t *
 pixman_image_create_linear_gradient (pixman_point_fixed_t         *p1,
 				     pixman_point_fixed_t         *p2,
@@ -113,6 +119,9 @@ pixman_image_create_linear_gradient (pixman_point_fixed_t         *p1,
     image->type = LINEAR;
     image->source.class = SOURCE_IMAGE_CLASS_UNKNOWN;
     image->common.classify = linear_gradient_classify;
+    image->common.property_changed = linear_gradient_property_changed;
+
+    linear_gradient_property_changed (image);
     
     return image;
 }
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 1bde4b9..9a9ec59 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -277,12 +277,6 @@ typedef enum
     SOURCE_IMAGE_CLASS_VERTICAL,
 } source_pict_class_t;
 
-typedef source_pict_class_t (* classify_func_t) (pixman_image_t *image,
-						 int             x,
-						 int             y,
-						 int             width,
-						 int             height);
-
 typedef void (*scanStoreProc)(pixman_image_t *, int, int, int, uint32_t *);
 typedef void (*scanFetchProc)(pixman_image_t *, int, int, int, uint32_t *,
 			      uint32_t *, uint32_t);
@@ -316,6 +310,13 @@ struct point
     int16_t x, y;
 };
 
+typedef source_pict_class_t (* classify_func_t) (pixman_image_t *image,
+						 int             x,
+						 int             y,
+						 int             width,
+						 int             height);
+typedef void (* property_changed_func_t)        (pixman_image_t *image);
+
 struct image_common
 {
     image_type_t		type;
@@ -335,6 +336,7 @@ struct image_common
     pixman_read_memory_func_t	read_func;
     pixman_write_memory_func_t	write_func;
     classify_func_t		classify;
+    property_changed_func_t	property_changed;
 };
 
 struct source_image
diff --git a/pixman/pixman-radial-gradient.c b/pixman/pixman-radial-gradient.c
index b1e617d..ca52c11 100644
--- a/pixman/pixman-radial-gradient.c
+++ b/pixman/pixman-radial-gradient.c
@@ -24,6 +24,12 @@
 #include <stdlib.h>
 #include "pixman-private.h"
 
+static void
+radial_gradient_property_changed (pixman_image_t *image)
+{
+    
+}
+
 PIXMAN_EXPORT pixman_image_t *
 pixman_image_create_radial_gradient (pixman_point_fixed_t         *inner,
 				     pixman_point_fixed_t         *outer,
@@ -65,6 +71,10 @@ pixman_image_create_radial_gradient (pixman_point_fixed_t         *inner,
 		 + radial->cdy * radial->cdy
 		 - radial->dr  * radial->dr);
 
+    image->common.property_changed = radial_gradient_property_changed;
+
+    radial_gradient_property_changed (image);
+    
     return image;
 }
 
diff --git a/pixman/pixman-solid-fill.c b/pixman/pixman-solid-fill.c
index af32d5a..2663012 100644
--- a/pixman/pixman-solid-fill.c
+++ b/pixman/pixman-solid-fill.c
@@ -34,6 +34,12 @@ solid_fill_classify (pixman_image_t *image,
     return (image->source.class = SOURCE_IMAGE_CLASS_HORIZONTAL);
 }
 
+static void
+solid_fill_property_changed (pixman_image_t *image)
+{
+    
+}
+
 static uint32_t
 color_to_uint32 (const pixman_color_t *color)
 {
@@ -52,11 +58,14 @@ pixman_image_create_solid_fill (pixman_color_t *color)
     if (!img)
 	return NULL;
 
-    img->source.class = SOURCE_IMAGE_CLASS_UNKNOWN;
-    img->common.classify = solid_fill_classify;
-    
     img->type = SOLID;
     img->solid.color = color_to_uint32 (color);
 
+    img->source.class = SOURCE_IMAGE_CLASS_UNKNOWN;
+    img->common.classify = solid_fill_classify;
+    img->common.property_changed = solid_fill_property_changed;
+
+    solid_fill_property_changed (img);
+    
     return img;
 }
commit 7bb615f6baf39e3d7c31a8ce521c0ff0b5172d7e
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Sat May 2 21:14:36 2009 -0400

    Split pixel images into pixman-bits-image.c

diff --git a/pixman/Makefile.am b/pixman/Makefile.am
index 4a0cba0..cca662e 100644
--- a/pixman/Makefile.am
+++ b/pixman/Makefile.am
@@ -21,6 +21,7 @@ libpixman_1_la_SOURCES =		\
 	pixman-conical-gradient.c	\
 	pixman-linear-gradient.c	\
 	pixman-radial-gradient.c	\
+	pixman-bits-image.c		\
 	pixman-transformed.c		\
 	pixman-transformed-accessors.c	\
 	pixman-utils.c			\
diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
new file mode 100644
index 0000000..7df159f
--- /dev/null
+++ b/pixman/pixman-bits-image.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright © 2000 SuSE, Inc.
+ * Copyright © 2007 Red Hat, Inc.
+ *
+ * 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include "pixman-private.h"
+
+static uint32_t *
+create_bits (pixman_format_code_t format,
+	     int		  width,
+	     int		  height,
+	     int		 *rowstride_bytes)
+{
+    int stride;
+    int buf_size;
+    int bpp;
+
+    /* what follows is a long-winded way, avoiding any possibility of integer
+     * overflows, of saying:
+     * stride = ((width * bpp + FB_MASK) >> FB_SHIFT) * sizeof (uint32_t);
+     */
+
+    bpp = PIXMAN_FORMAT_BPP (format);
+    if (pixman_multiply_overflows_int (width, bpp))
+	return NULL;
+
+    stride = width * bpp;
+    if (pixman_addition_overflows_int (stride, FB_MASK))
+	return NULL;
+
+    stride += FB_MASK;
+    stride >>= FB_SHIFT;
+
+#if FB_SHIFT < 2
+    if (pixman_multiply_overflows_int (stride, sizeof (uint32_t)))
+	return NULL;
+#endif
+    stride *= sizeof (uint32_t);
+
+    if (pixman_multiply_overflows_int (height, stride))
+	return NULL;
+
+    buf_size = height * stride;
+
+    if (rowstride_bytes)
+	*rowstride_bytes = stride;
+
+    return calloc (buf_size, 1);
+}
+
+PIXMAN_EXPORT pixman_image_t *
+pixman_image_create_bits (pixman_format_code_t  format,
+			  int                   width,
+			  int                   height,
+			  uint32_t	       *bits,
+			  int			rowstride_bytes)
+{
+    pixman_image_t *image;
+    uint32_t *free_me = NULL;
+
+    /* must be a whole number of uint32_t's
+     */
+    return_val_if_fail (bits == NULL ||
+			(rowstride_bytes % sizeof (uint32_t)) == 0, NULL);
+
+    if (!bits && width && height)
+    {
+	free_me = bits = create_bits (format, width, height, &rowstride_bytes);
+	if (!bits)
+	    return NULL;
+    }
+
+    image = _pixman_image_allocate();
+
+    if (!image) {
+	if (free_me)
+	    free (free_me);
+	return NULL;
+    }
+    
+    image->type = BITS;
+    image->bits.format = format;
+    image->bits.width = width;
+    image->bits.height = height;
+    image->bits.bits = bits;
+    image->bits.free_me = free_me;
+
+    image->bits.rowstride = rowstride_bytes / (int) sizeof (uint32_t); /* we store it in number
+								  * of uint32_t's
+								  */
+    image->bits.indexed = NULL;
+
+    pixman_region32_fini (&image->common.full_region);
+    pixman_region32_init_rect (&image->common.full_region, 0, 0,
+			       image->bits.width, image->bits.height);
+
+    _pixman_image_reset_clip_region (image);
+    return image;
+}
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index 970ca53..1ee7529 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -299,51 +299,8 @@ pixman_image_unref (pixman_image_t *image)
 
 /* Constructors */
 
-static uint32_t *
-create_bits (pixman_format_code_t format,
-	     int		  width,
-	     int		  height,
-	     int		 *rowstride_bytes)
-{
-    int stride;
-    int buf_size;
-    int bpp;
-
-    /* what follows is a long-winded way, avoiding any possibility of integer
-     * overflows, of saying:
-     * stride = ((width * bpp + FB_MASK) >> FB_SHIFT) * sizeof (uint32_t);
-     */
-
-    bpp = PIXMAN_FORMAT_BPP (format);
-    if (pixman_multiply_overflows_int (width, bpp))
-	return NULL;
-
-    stride = width * bpp;
-    if (pixman_addition_overflows_int (stride, FB_MASK))
-	return NULL;
-
-    stride += FB_MASK;
-    stride >>= FB_SHIFT;
-
-#if FB_SHIFT < 2
-    if (pixman_multiply_overflows_int (stride, sizeof (uint32_t)))
-	return NULL;
-#endif
-    stride *= sizeof (uint32_t);
-
-    if (pixman_multiply_overflows_int (height, stride))
-	return NULL;
-
-    buf_size = height * stride;
-
-    if (rowstride_bytes)
-	*rowstride_bytes = stride;
-
-    return calloc (buf_size, 1);
-}
-
-static void
-reset_clip_region (pixman_image_t *image)
+void
+_pixman_image_reset_clip_region (pixman_image_t *image)
 {
     pixman_region32_fini (&image->common.clip_region);
 
@@ -358,56 +315,6 @@ reset_clip_region (pixman_image_t *image)
     }
 }
 
-PIXMAN_EXPORT pixman_image_t *
-pixman_image_create_bits (pixman_format_code_t  format,
-			  int                   width,
-			  int                   height,
-			  uint32_t	       *bits,
-			  int			rowstride_bytes)
-{
-    pixman_image_t *image;
-    uint32_t *free_me = NULL;
-
-    /* must be a whole number of uint32_t's
-     */
-    return_val_if_fail (bits == NULL ||
-			(rowstride_bytes % sizeof (uint32_t)) == 0, NULL);
-
-    if (!bits && width && height)
-    {
-	free_me = bits = create_bits (format, width, height, &rowstride_bytes);
-	if (!bits)
-	    return NULL;
-    }
-
-    image = _pixman_image_allocate();
-
-    if (!image) {
-	if (free_me)
-	    free (free_me);
-	return NULL;
-    }
-    
-    image->type = BITS;
-    image->bits.format = format;
-    image->bits.width = width;
-    image->bits.height = height;
-    image->bits.bits = bits;
-    image->bits.free_me = free_me;
-
-    image->bits.rowstride = rowstride_bytes / (int) sizeof (uint32_t); /* we store it in number
-								  * of uint32_t's
-								  */
-    image->bits.indexed = NULL;
-
-    pixman_region32_fini (&image->common.full_region);
-    pixman_region32_init_rect (&image->common.full_region, 0, 0,
-			       image->bits.width, image->bits.height);
-
-    reset_clip_region (image);
-    return image;
-}
-
 PIXMAN_EXPORT pixman_bool_t
 pixman_image_set_clip_region32 (pixman_image_t *image,
 				pixman_region32_t *region)
@@ -420,7 +327,7 @@ pixman_image_set_clip_region32 (pixman_image_t *image,
     }
     else
     {
-	reset_clip_region (image);
+	_pixman_image_reset_clip_region (image);
 
 	return TRUE;
     }
@@ -439,7 +346,7 @@ pixman_image_set_clip_region (pixman_image_t    *image,
     }
     else
     {
-	reset_clip_region (image);
+	_pixman_image_reset_clip_region (image);
 
 	return TRUE;
     }
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index be120ff..1bde4b9 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -308,6 +308,9 @@ pixman_bool_t
 _pixman_init_gradient (gradient_t     *gradient,
 		       const pixman_gradient_stop_t *stops,
 		       int	       n_stops);
+void
+_pixman_image_reset_clip_region (pixman_image_t *image);
+
 struct point
 {
     int16_t x, y;
commit 53bae97c7e7bf9b20ddfd400fd0bd11d03431d39
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Sat May 2 21:08:12 2009 -0400

    Split conical gradient images into pixman-conical-gradient.c

diff --git a/pixman/Makefile.am b/pixman/Makefile.am
index cad1f39..4a0cba0 100644
--- a/pixman/Makefile.am
+++ b/pixman/Makefile.am
@@ -18,6 +18,7 @@ libpixman_1_la_SOURCES =		\
 	pixman-pict.c			\
 	pixman-source.c			\
 	pixman-solid-fill.c		\
+	pixman-conical-gradient.c	\
 	pixman-linear-gradient.c	\
 	pixman-radial-gradient.c	\
 	pixman-transformed.c		\
diff --git a/pixman/pixman-conical-gradient.c b/pixman/pixman-conical-gradient.c
new file mode 100644
index 0000000..0b041f0
--- /dev/null
+++ b/pixman/pixman-conical-gradient.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright © 2000 SuSE, Inc.
+ * Copyright © 2007 Red Hat, Inc.
+ *
+ * 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include "pixman-private.h"
+
+PIXMAN_EXPORT pixman_image_t *
+pixman_image_create_conical_gradient (pixman_point_fixed_t *center,
+				      pixman_fixed_t angle,
+				      const pixman_gradient_stop_t *stops,
+				      int n_stops)
+{
+    pixman_image_t *image = _pixman_image_allocate();
+    conical_gradient_t *conical;
+
+    if (!image)
+	return NULL;
+
+    conical = &image->conical;
+
+    if (!_pixman_init_gradient (&conical->common, stops, n_stops))
+    {
+	free (image);
+	return NULL;
+    }
+
+    image->type = CONICAL;
+    conical->center = *center;
+    conical->angle = angle;
+
+    return image;
+}
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index ce087f3..970ca53 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -299,33 +299,6 @@ pixman_image_unref (pixman_image_t *image)
 
 /* Constructors */
 
-PIXMAN_EXPORT pixman_image_t *
-pixman_image_create_conical_gradient (pixman_point_fixed_t *center,
-				      pixman_fixed_t angle,
-				      const pixman_gradient_stop_t *stops,
-				      int n_stops)
-{
-    pixman_image_t *image = _pixman_image_allocate();
-    conical_gradient_t *conical;
-
-    if (!image)
-	return NULL;
-
-    conical = &image->conical;
-
-    if (!_pixman_init_gradient (&conical->common, stops, n_stops))
-    {
-	free (image);
-	return NULL;
-    }
-
-    image->type = CONICAL;
-    conical->center = *center;
-    conical->angle = angle;
-
-    return image;
-}
-
 static uint32_t *
 create_bits (pixman_format_code_t format,
 	     int		  width,
commit c43c3628935722f489d5e5359413dbb17d4c4a44
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Sat May 2 21:06:23 2009 -0400

    Split radial gradient images into pixman-radial-gradient.c

diff --git a/pixman/Makefile.am b/pixman/Makefile.am
index c4d27cb..cad1f39 100644
--- a/pixman/Makefile.am
+++ b/pixman/Makefile.am
@@ -19,6 +19,7 @@ libpixman_1_la_SOURCES =		\
 	pixman-source.c			\
 	pixman-solid-fill.c		\
 	pixman-linear-gradient.c	\
+	pixman-radial-gradient.c	\
 	pixman-transformed.c		\
 	pixman-transformed-accessors.c	\
 	pixman-utils.c			\
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index 99388ed..ce087f3 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -300,50 +300,6 @@ pixman_image_unref (pixman_image_t *image)
 /* Constructors */
 
 PIXMAN_EXPORT pixman_image_t *
-pixman_image_create_radial_gradient (pixman_point_fixed_t         *inner,
-				     pixman_point_fixed_t         *outer,
-				     pixman_fixed_t                inner_radius,
-				     pixman_fixed_t                outer_radius,
-				     const pixman_gradient_stop_t *stops,
-				     int                           n_stops)
-{
-    pixman_image_t *image;
-    radial_gradient_t *radial;
-
-    return_val_if_fail (n_stops >= 2, NULL);
-
-    image = _pixman_image_allocate();
-
-    if (!image)
-	return NULL;
-
-    radial = &image->radial;
-
-    if (!_pixman_init_gradient (&radial->common, stops, n_stops))
-    {
-	free (image);
-	return NULL;
-    }
-
-    image->type = RADIAL;
-
-    radial->c1.x = inner->x;
-    radial->c1.y = inner->y;
-    radial->c1.radius = inner_radius;
-    radial->c2.x = outer->x;
-    radial->c2.y = outer->y;
-    radial->c2.radius = outer_radius;
-    radial->cdx = pixman_fixed_to_double (radial->c2.x - radial->c1.x);
-    radial->cdy = pixman_fixed_to_double (radial->c2.y - radial->c1.y);
-    radial->dr = pixman_fixed_to_double (radial->c2.radius - radial->c1.radius);
-    radial->A = (radial->cdx * radial->cdx
-		 + radial->cdy * radial->cdy
-		 - radial->dr  * radial->dr);
-
-    return image;
-}
-
-PIXMAN_EXPORT pixman_image_t *
 pixman_image_create_conical_gradient (pixman_point_fixed_t *center,
 				      pixman_fixed_t angle,
 				      const pixman_gradient_stop_t *stops,
diff --git a/pixman/pixman-radial-gradient.c b/pixman/pixman-radial-gradient.c
new file mode 100644
index 0000000..b1e617d
--- /dev/null
+++ b/pixman/pixman-radial-gradient.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright © 2000 SuSE, Inc.
+ * Copyright © 2007 Red Hat, Inc.
+ *
+ * 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include "pixman-private.h"
+
+PIXMAN_EXPORT pixman_image_t *
+pixman_image_create_radial_gradient (pixman_point_fixed_t         *inner,
+				     pixman_point_fixed_t         *outer,
+				     pixman_fixed_t                inner_radius,
+				     pixman_fixed_t                outer_radius,
+				     const pixman_gradient_stop_t *stops,
+				     int                           n_stops)
+{
+    pixman_image_t *image;
+    radial_gradient_t *radial;
+
+    return_val_if_fail (n_stops >= 2, NULL);
+
+    image = _pixman_image_allocate();
+
+    if (!image)
+	return NULL;
+
+    radial = &image->radial;
+
+    if (!_pixman_init_gradient (&radial->common, stops, n_stops))
+    {
+	free (image);
+	return NULL;
+    }
+
+    image->type = RADIAL;
+
+    radial->c1.x = inner->x;
+    radial->c1.y = inner->y;
+    radial->c1.radius = inner_radius;
+    radial->c2.x = outer->x;
+    radial->c2.y = outer->y;
+    radial->c2.radius = outer_radius;
+    radial->cdx = pixman_fixed_to_double (radial->c2.x - radial->c1.x);
+    radial->cdy = pixman_fixed_to_double (radial->c2.y - radial->c1.y);
+    radial->dr = pixman_fixed_to_double (radial->c2.radius - radial->c1.radius);
+    radial->A = (radial->cdx * radial->cdx
+		 + radial->cdy * radial->cdy
+		 - radial->dr  * radial->dr);
+
+    return image;
+}
+
commit 76418e388e1439f8e7f33eb777856c8eb475a2fc
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Sat May 2 20:54:17 2009 -0400

    Split linear gradient images into pixman-linear-gradient.c

diff --git a/pixman/Makefile.am b/pixman/Makefile.am
index 377b393..c4d27cb 100644
--- a/pixman/Makefile.am
+++ b/pixman/Makefile.am
@@ -18,6 +18,7 @@ libpixman_1_la_SOURCES =		\
 	pixman-pict.c			\
 	pixman-source.c			\
 	pixman-solid-fill.c		\
+	pixman-linear-gradient.c	\
 	pixman-transformed.c		\
 	pixman-transformed-accessors.c	\
 	pixman-utils.c			\
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index d09cd59..99388ed 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -32,86 +32,13 @@
 
 #define Alpha(x) ((x) >> 24)
 
-static source_pict_class_t
-SourcePictureClassify (pixman_image_t *image,
-		       int	       x,
-		       int	       y,
-		       int	       width,
-		       int	       height)
-{
-    source_image_t *pict = &image->source;
-    
-    pict->class = SOURCE_IMAGE_CLASS_UNKNOWN;
-    
-    if (pict->common.type == LINEAR)
-    {
-	linear_gradient_t *linear = (linear_gradient_t *)pict;
-	pixman_vector_t   v;
-	pixman_fixed_32_32_t l;
-	pixman_fixed_48_16_t dx, dy, a, b, off;
-	pixman_fixed_48_16_t factors[4];
-	int	     i;
-
-	dx = linear->p2.x - linear->p1.x;
-	dy = linear->p2.y - linear->p1.y;
-	l = dx * dx + dy * dy;
-	if (l)
-	{
-	    a = (dx << 32) / l;
-	    b = (dy << 32) / l;
-	}
-	else
-	{
-	    a = b = 0;
-	}
-
-	off = (-a * linear->p1.x
-	       -b * linear->p1.y) >> 16;
-
-	for (i = 0; i < 3; i++)
-	{
-	    v.vector[0] = pixman_int_to_fixed ((i % 2) * (width  - 1) + x);
-	    v.vector[1] = pixman_int_to_fixed ((i / 2) * (height - 1) + y);
-	    v.vector[2] = pixman_fixed_1;
-
-	    if (pict->common.transform)
-	    {
-		if (!pixman_transform_point_3d (pict->common.transform, &v))
-		{
-		    pict->class = SOURCE_IMAGE_CLASS_UNKNOWN;
-		    goto out;
-		}
-	    }
-
-	    factors[i] = ((a * v.vector[0] + b * v.vector[1]) >> 16) + off;
-	}
-
-	if (factors[2] == factors[0])
-	    pict->class = SOURCE_IMAGE_CLASS_HORIZONTAL;
-	else if (factors[1] == factors[0])
-	    pict->class = SOURCE_IMAGE_CLASS_VERTICAL;
-    }
-
-out:
-    return pict->class;
-}
-
-static void
-init_source_image (source_image_t *image)
-{
-    image->class = SOURCE_IMAGE_CLASS_UNKNOWN;
-    image->common.classify = SourcePictureClassify;
-}
-
-static pixman_bool_t
-init_gradient (gradient_t     *gradient,
-	       const pixman_gradient_stop_t *stops,
-	       int	       n_stops)
+pixman_bool_t
+_pixman_init_gradient (gradient_t     *gradient,
+		       const pixman_gradient_stop_t *stops,
+		       int	       n_stops)
 {
     return_val_if_fail (n_stops > 0, FALSE);
 
-    init_source_image (&gradient->common);
-
     gradient->stops = pixman_malloc_ab (n_stops, sizeof (pixman_gradient_stop_t));
     if (!gradient->stops)
 	return FALSE;
@@ -123,6 +50,7 @@ init_gradient (gradient_t     *gradient,
     gradient->stop_range = 0xffff;
     gradient->color_table = NULL;
     gradient->color_table_size = 0;
+    gradient->common.class = SOURCE_IMAGE_CLASS_UNKNOWN;
 
     return TRUE;
 }
@@ -370,38 +298,6 @@ pixman_image_unref (pixman_image_t *image)
 }
 
 /* Constructors */
-PIXMAN_EXPORT pixman_image_t *
-pixman_image_create_linear_gradient (pixman_point_fixed_t         *p1,
-				     pixman_point_fixed_t         *p2,
-				     const pixman_gradient_stop_t *stops,
-				     int                           n_stops)
-{
-    pixman_image_t *image;
-    linear_gradient_t *linear;
-
-    return_val_if_fail (n_stops >= 2, NULL);
-
-    image = _pixman_image_allocate();
-
-    if (!image)
-	return NULL;
-
-    linear = &image->linear;
-
-    if (!init_gradient (&linear->common, stops, n_stops))
-    {
-	free (image);
-	return NULL;
-    }
-
-    linear->p1 = *p1;
-    linear->p2 = *p2;
-
-    image->type = LINEAR;
-
-    return image;
-}
-
 
 PIXMAN_EXPORT pixman_image_t *
 pixman_image_create_radial_gradient (pixman_point_fixed_t         *inner,
@@ -423,7 +319,7 @@ pixman_image_create_radial_gradient (pixman_point_fixed_t         *inner,
 
     radial = &image->radial;
 
-    if (!init_gradient (&radial->common, stops, n_stops))
+    if (!_pixman_init_gradient (&radial->common, stops, n_stops))
     {
 	free (image);
 	return NULL;
@@ -461,7 +357,7 @@ pixman_image_create_conical_gradient (pixman_point_fixed_t *center,
 
     conical = &image->conical;
 
-    if (!init_gradient (&conical->common, stops, n_stops))
+    if (!_pixman_init_gradient (&conical->common, stops, n_stops))
     {
 	free (image);
 	return NULL;
diff --git a/pixman/pixman-linear-gradient.c b/pixman/pixman-linear-gradient.c
new file mode 100644
index 0000000..04bd796
--- /dev/null
+++ b/pixman/pixman-linear-gradient.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright © 2000 SuSE, Inc.
+ * Copyright © 2007 Red Hat, Inc.
+ *
+ * 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include "pixman-private.h"
+
+static source_pict_class_t
+linear_gradient_classify (pixman_image_t *image,
+			  int	          x,
+			  int	          y,
+			  int	          width,
+			  int	          height)
+{
+    linear_gradient_t *linear = (linear_gradient_t *)image;
+    pixman_vector_t   v;
+    pixman_fixed_32_32_t l;
+    pixman_fixed_48_16_t dx, dy, a, b, off;
+    pixman_fixed_48_16_t factors[4];
+    int	     i;
+    
+    image->source.class = SOURCE_IMAGE_CLASS_UNKNOWN;
+    
+    dx = linear->p2.x - linear->p1.x;
+    dy = linear->p2.y - linear->p1.y;
+    l = dx * dx + dy * dy;
+    if (l)
+    {
+	a = (dx << 32) / l;
+	b = (dy << 32) / l;
+    }
+    else
+    {
+	a = b = 0;
+    }
+    
+    off = (-a * linear->p1.x
+	   -b * linear->p1.y) >> 16;
+    
+    for (i = 0; i < 3; i++)
+    {
+	v.vector[0] = pixman_int_to_fixed ((i % 2) * (width  - 1) + x);
+	v.vector[1] = pixman_int_to_fixed ((i / 2) * (height - 1) + y);
+	v.vector[2] = pixman_fixed_1;
+	
+	if (image->common.transform)
+	{
+	    if (!pixman_transform_point_3d (image->common.transform, &v))
+	    {
+		image->source.class = SOURCE_IMAGE_CLASS_UNKNOWN;
+		
+		return image->source.class;
+	    }
+	}
+	
+	factors[i] = ((a * v.vector[0] + b * v.vector[1]) >> 16) + off;
+    }
+    
+    if (factors[2] == factors[0])
+	image->source.class = SOURCE_IMAGE_CLASS_HORIZONTAL;
+    else if (factors[1] == factors[0])
+	image->source.class = SOURCE_IMAGE_CLASS_VERTICAL;
+
+    return image->source.class;
+}
+
+PIXMAN_EXPORT pixman_image_t *
+pixman_image_create_linear_gradient (pixman_point_fixed_t         *p1,
+				     pixman_point_fixed_t         *p2,
+				     const pixman_gradient_stop_t *stops,
+				     int                           n_stops)
+{
+    pixman_image_t *image;
+    linear_gradient_t *linear;
+    
+    return_val_if_fail (n_stops >= 2, NULL);
+    
+    image = _pixman_image_allocate();
+    
+    if (!image)
+	return NULL;
+    
+    linear = &image->linear;
+    
+    if (!_pixman_init_gradient (&linear->common, stops, n_stops))
+    {
+	free (image);
+	return NULL;
+    }
+    
+    linear->p1 = *p1;
+    linear->p2 = *p2;
+    
+    image->type = LINEAR;
+    image->source.class = SOURCE_IMAGE_CLASS_UNKNOWN;
+    image->common.classify = linear_gradient_classify;
+    
+    return image;
+}
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index faf9b20..be120ff 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -304,6 +304,10 @@ _pixman_image_get_storer (pixman_image_t *image,
 pixman_image_t *
 _pixman_image_allocate (void);
 
+pixman_bool_t
+_pixman_init_gradient (gradient_t     *gradient,
+		       const pixman_gradient_stop_t *stops,
+		       int	       n_stops);
 struct point
 {
     int16_t x, y;
commit 58de62bfada0d0ca945350fe3da38dee48aac7b4
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Sat May 2 20:40:16 2009 -0400

    Split solid fill images into pixman-solid-fill.c

diff --git a/pixman/Makefile.am b/pixman/Makefile.am
index 776d396..377b393 100644
--- a/pixman/Makefile.am
+++ b/pixman/Makefile.am
@@ -17,6 +17,7 @@ libpixman_1_la_SOURCES =		\
 	pixman-compose.c		\
 	pixman-pict.c			\
 	pixman-source.c			\
+	pixman-solid-fill.c		\
 	pixman-transformed.c		\
 	pixman-transformed-accessors.c	\
 	pixman-utils.c			\
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index 2030ddd..d09cd59 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -43,11 +43,7 @@ SourcePictureClassify (pixman_image_t *image,
     
     pict->class = SOURCE_IMAGE_CLASS_UNKNOWN;
     
-    if (pict->common.type == SOLID)
-    {
-	pict->class = SOURCE_IMAGE_CLASS_HORIZONTAL;
-    }
-    else if (pict->common.type == LINEAR)
+    if (pict->common.type == LINEAR)
     {
 	linear_gradient_t *linear = (linear_gradient_t *)pict;
 	pixman_vector_t   v;
@@ -131,18 +127,8 @@ init_gradient (gradient_t     *gradient,
     return TRUE;
 }
 
-static uint32_t
-color_to_uint32 (const pixman_color_t *color)
-{
-    return
-	(color->alpha >> 8 << 24) |
-	(color->red >> 8 << 16) |
-        (color->green & 0xff00) |
-	(color->blue >> 8);
-}
-
-static pixman_image_t *
-allocate_image (void)
+pixman_image_t *
+_pixman_image_allocate (void)
 {
     pixman_image_t *image = malloc (sizeof (pixman_image_t));
 
@@ -385,21 +371,6 @@ pixman_image_unref (pixman_image_t *image)
 
 /* Constructors */
 PIXMAN_EXPORT pixman_image_t *
-pixman_image_create_solid_fill (pixman_color_t *color)
-{
-    pixman_image_t *img = allocate_image();
-    if (!img)
-	return NULL;
-
-    init_source_image (&img->solid.common);
-
-    img->type = SOLID;
-    img->solid.color = color_to_uint32 (color);
-
-    return img;
-}
-
-PIXMAN_EXPORT pixman_image_t *
 pixman_image_create_linear_gradient (pixman_point_fixed_t         *p1,
 				     pixman_point_fixed_t         *p2,
 				     const pixman_gradient_stop_t *stops,
@@ -410,7 +381,7 @@ pixman_image_create_linear_gradient (pixman_point_fixed_t         *p1,
 
     return_val_if_fail (n_stops >= 2, NULL);
 
-    image = allocate_image();
+    image = _pixman_image_allocate();
 
     if (!image)
 	return NULL;
@@ -445,7 +416,7 @@ pixman_image_create_radial_gradient (pixman_point_fixed_t         *inner,
 
     return_val_if_fail (n_stops >= 2, NULL);
 
-    image = allocate_image();
+    image = _pixman_image_allocate();
 
     if (!image)
 	return NULL;
@@ -482,7 +453,7 @@ pixman_image_create_conical_gradient (pixman_point_fixed_t *center,
 				      const pixman_gradient_stop_t *stops,
 				      int n_stops)
 {
-    pixman_image_t *image = allocate_image();
+    pixman_image_t *image = _pixman_image_allocate();
     conical_gradient_t *conical;
 
     if (!image)
@@ -584,7 +555,7 @@ pixman_image_create_bits (pixman_format_code_t  format,
 	    return NULL;
     }
 
-    image = allocate_image();
+    image = _pixman_image_allocate();
 
     if (!image) {
 	if (free_me)
@@ -846,6 +817,16 @@ pixman_image_get_depth (pixman_image_t *image)
     return 0;
 }
 
+static uint32_t
+color_to_uint32 (const pixman_color_t *color)
+{
+    return
+	(color->alpha >> 8 << 24) |
+	(color->red >> 8 << 16) |
+        (color->green & 0xff00) |
+	(color->blue >> 8);
+}
+
 static pixman_bool_t
 color_to_pixel (pixman_color_t *color,
 		uint32_t       *pixel,
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 0ef2ef2..faf9b20 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -301,6 +301,9 @@ scanStoreProc
 _pixman_image_get_storer (pixman_image_t *image,
 			  int             wide);
 
+pixman_image_t *
+_pixman_image_allocate (void);
+
 struct point
 {
     int16_t x, y;
diff --git a/pixman/pixman-solid-fill.c b/pixman/pixman-solid-fill.c
new file mode 100644
index 0000000..af32d5a
--- /dev/null
+++ b/pixman/pixman-solid-fill.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright © 2000 SuSE, Inc.
+ * Copyright © 2007, 2009 Red Hat, Inc.
+ * Copyright © 2009 Soren Sandmann
+ *
+ * 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 SuSE not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  SuSE makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as is"
+ * without express or implied warranty.
+ *
+ * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
+ * 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.
+ */
+
+#include <config.h>
+#include "pixman-private.h"
+
+static source_pict_class_t
+solid_fill_classify (pixman_image_t *image,
+		     int	     x,
+		     int	     y,
+		     int	     width,
+		     int	     height)
+{
+    return (image->source.class = SOURCE_IMAGE_CLASS_HORIZONTAL);
+}
+
+static uint32_t
+color_to_uint32 (const pixman_color_t *color)
+{
+    return
+	(color->alpha >> 8 << 24) |
+	(color->red >> 8 << 16) |
+        (color->green & 0xff00) |
+	(color->blue >> 8);
+}
+
+PIXMAN_EXPORT pixman_image_t *
+pixman_image_create_solid_fill (pixman_color_t *color)
+{
+    pixman_image_t *img = _pixman_image_allocate();
+    
+    if (!img)
+	return NULL;
+
+    img->source.class = SOURCE_IMAGE_CLASS_UNKNOWN;
+    img->common.classify = solid_fill_classify;
+    
+    img->type = SOLID;
+    img->solid.color = color_to_uint32 (color);
+
+    return img;
+}


More information about the xorg-commit mailing list