pixman: Branch 'master' - 12 commits

Søren Sandmann Pedersen sandmann at kemper.freedesktop.org
Sat Jun 13 07:26:14 PDT 2009


 TODO                           |    2 
 pixman/pixman-bits-image.c     |  112 +++++++++++++++++++-------
 pixman/pixman-compute-region.c |  108 ++++++++++++++-----------
 pixman/pixman-fast-path.c      |    2 
 pixman/pixman-general.c        |   51 -----------
 pixman/pixman-image.c          |  121 +++++++++++++---------------
 pixman/pixman-private.h        |   37 ++++----
 pixman/pixman-utils.c          |  175 +++++++++++++++++++++++++++--------------
 pixman/pixman.h                |    5 +
 9 files changed, 348 insertions(+), 265 deletions(-)

New commits:
commit 68ec1244cdd4aa2703739a19c7c3917231b7b889
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Sat Jun 13 09:32:59 2009 -0400

    Add API to set a function to be called when the image is destroyed.

diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index 9b4b73d..e95cff2 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -113,6 +113,8 @@ _pixman_image_allocate (void)
 	common->write_func = NULL;
 	common->classify = NULL;
 	common->client_clip = FALSE;
+	common->destroy_func = NULL;
+	common->destroy_data = NULL;
     }
 
     return image;
@@ -191,6 +193,9 @@ pixman_image_unref (pixman_image_t *image)
 
     if (common->ref_count == 0)
     {
+	if (image->common.destroy_func)
+	    image->common.destroy_func (image, image->common.destroy_data);
+	
 	pixman_region32_fini (&common->clip_region);
 
 	if (common->transform)
@@ -228,6 +233,16 @@ pixman_image_unref (pixman_image_t *image)
     return FALSE;
 }
 
+PIXMAN_EXPORT void
+pixman_image_set_destroy_function (pixman_image_t *image,
+				   pixman_image_destroy_func_t func,
+				   void *data)
+{
+    image->common.destroy_func = func;
+    image->common.destroy_data = data;
+}
+			       
+
 /* Constructors */
 
 void
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index ae51447..4a5de59 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -316,6 +316,9 @@ struct image_common
     property_changed_func_t	property_changed;
     scanFetchProc		get_scanline_32;
     scanFetchProc		get_scanline_64;
+
+    pixman_image_destroy_func_t destroy_func;
+    void *			destroy_data;
 };
 
 struct source_image
diff --git a/pixman/pixman.h b/pixman/pixman.h
index 29c054a..a954d2c 100644
--- a/pixman/pixman.h
+++ b/pixman/pixman.h
@@ -597,6 +597,8 @@ typedef struct pixman_gradient_stop	pixman_gradient_stop_t;
 typedef uint32_t (* pixman_read_memory_func_t) (const void *src, int size);
 typedef void     (* pixman_write_memory_func_t) (void *dst, uint32_t value, int size);
 
+typedef void     (* pixman_image_destroy_func_t) (pixman_image_t *image, void *data);
+
 struct pixman_gradient_stop {
     pixman_fixed_t x;
     pixman_color_t color;
@@ -748,6 +750,9 @@ pixman_image_t *pixman_image_create_bits             (pixman_format_code_t
 pixman_image_t *pixman_image_ref                     (pixman_image_t               *image);
 pixman_bool_t   pixman_image_unref                   (pixman_image_t               *image);
 
+void		pixman_image_set_destroy_function    (pixman_image_t		   *image,
+						      pixman_image_destroy_func_t   function,
+						      void			   *data);
 
 /* Set properties */
 pixman_bool_t   pixman_image_set_clip_region         (pixman_image_t               *image,
commit ebc39ed35a9f79ac9bb329bfc7dc27f290f6e1b0
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Wed Jun 10 08:52:31 2009 -0400

    Work around X server bug.
    
    X servers prior to
    
    	ebfd6688d1927288155221e7a78fbca9f9293952
    
    relied on pixman not clipping to destination geometry whenever an
    explicit clip region was set. Since only X servers set
    source_clipping, we can just trigger off of that.

diff --git a/TODO b/TODO
index 6abeb0b..52d7377 100644
--- a/TODO
+++ b/TODO
@@ -14,6 +14,8 @@
         the required precision by simply adding offset_x/y to the
         relevant rendering API?
 
+      - Get rid of workaround for X server bug.
+
       - pixman_image_set_indexed() should copy its argument, and X
         should be ported over to use a pixman_image as the
         representation of a Picture, rather than creating one on each
diff --git a/pixman/pixman-compute-region.c b/pixman/pixman-compute-region.c
index 70ffa3f..72fd9e8 100644
--- a/pixman/pixman-compute-region.c
+++ b/pixman/pixman-compute-region.c
@@ -136,8 +136,17 @@ pixman_compute_composite_region32 (pixman_region32_t *	pRegion,
 
     pRegion->extents.x1 = MAX (pRegion->extents.x1, 0);
     pRegion->extents.y1 = MAX (pRegion->extents.y1, 0);
-    pRegion->extents.x2 = MIN (pRegion->extents.x2, pDst->bits.width);
-    pRegion->extents.y2 = MIN (pRegion->extents.y2, pDst->bits.height);
+    
+    /* Some X servers rely on an old bug, where pixman would just believe the
+     * set clip_region and not clip against the destination geometry. So, 
+     * since only X servers set "source clip", we only clip against destination
+     * geometry when that is set.
+     */
+    if (!pDst->common.clip_sources)
+    {
+	pRegion->extents.x2 = MIN (pRegion->extents.x2, pDst->bits.width);
+	pRegion->extents.y2 = MIN (pRegion->extents.y2, pDst->bits.height);
+    }
     
     pRegion->data = 0;
     
commit 08eb065c568de5c0cb67b7b02ccb17bf72d5059c
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Wed Jun 3 05:21:29 2009 -0400

    Move region computation closer to the region walking.
    
    Computing the composite is region is a bit expensive, so only compute
    it if we are likely to actually walk it.

diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c
index 7fa89fa..c13bc3b 100644
--- a/pixman/pixman-utils.c
+++ b/pixman/pixman-utils.c
@@ -758,19 +758,7 @@ _pixman_run_fast_path (const FastPathInfo *paths,
     pixman_composite_func_t func = NULL;
     pixman_bool_t src_repeat = src->common.repeat == PIXMAN_REPEAT_NORMAL;
     pixman_bool_t mask_repeat = mask && mask->common.repeat == PIXMAN_REPEAT_NORMAL;
-    pixman_region32_t region;
     pixman_bool_t result;
-    pixman_box32_t extents;
-
-    pixman_region32_init (&region);
-
-    if (!pixman_compute_composite_region32 (
-	    &region, src, mask, dest, src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
-    {
-	result = TRUE;
-
-	goto out;
-    }
 
     if ((src->type == BITS || pixman_image_can_get_solid (src)) &&
 	(!mask || mask->type == BITS)
@@ -791,16 +779,6 @@ _pixman_run_fast_path (const FastPathInfo *paths,
 	const FastPathInfo *info;	
 	pixman_bool_t pixbuf;
 
-	extents = *pixman_region32_extents (&region);
-	
-	if (!image_covers (src, &extents)		||
-	    (mask && !image_covers (mask, &extents)))
-	{
-	    result = FALSE;
-	    
-	    goto out;
-	}
-    
 	pixbuf =
 	    src && src->type == BITS		&&
 	    mask && mask->type == BITS		&&
@@ -842,25 +820,36 @@ _pixman_run_fast_path (const FastPathInfo *paths,
 	}
     }
     
+    result = FALSE;
+    
     if (func)
     {
-	walk_region_internal (imp, op,
-			      src, mask, dest,
-			      src_x, src_y, mask_x, mask_y,
-			      dest_x, dest_y,
-			      width, height,
-			      src_repeat, mask_repeat,
-			      &region,
-			      func);
+	pixman_region32_t region;
+	pixman_region32_init (&region);
+
+	if (pixman_compute_composite_region32 (
+		&region, src, mask, dest, src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
+	{
+	    pixman_box32_t *extents = pixman_region32_extents (&region);
 	
-	result = TRUE;
-    }
-    else
-    {
-	result = FALSE;
+	    if (image_covers (src, extents)		   &&
+		(!mask || image_covers (mask, extents)))
+	    {
+		walk_region_internal (imp, op,
+				      src, mask, dest,
+				      src_x, src_y, mask_x, mask_y,
+				      dest_x, dest_y,
+				      width, height,
+				      src_repeat, mask_repeat,
+				      &region,
+				      func);
+	    
+		result = TRUE;
+	    }
+	}
+	    
+	pixman_region32_fini (&region);
     }
     
-out:
-    pixman_region32_fini (&region);
     return result;
 }
commit 78ca4eea6467dbb6b9da1198b9526750a0a8dca3
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Tue Jun 2 23:17:34 2009 -0400

    Simplify clipping rule
    
    The new rule is:
    
    - Output is clipped to the destination clip region.
    
    - If a source image has the clip_sources property set, then there
      is an additional step, after repeating and transforming, but before
      compositing, where pixels that are not in the source clip are
      rejected. Rejected means no compositing takes place (not that the
      pixel is treated as 0). By default source clipping is turned off;
      when they are turned on, only client-set clips are honored.
    
    The old rules were unclear and inconsistently implemented.

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index a654b46..c991422 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -186,27 +186,6 @@ bits_image_fetch_alpha_pixels (bits_image_t *image, uint32_t *buffer, int n_pixe
 static void
 bits_image_fetch_pixels_src_clip (bits_image_t *image, uint32_t *buffer, int n_pixels)
 {
-    if (image->common.src_clip != &(image->common.full_region) &&
-	!pixman_region32_equal (image->common.src_clip, &(image->common.full_region)))
-    {
-	int32_t *coords = (int32_t *)buffer;
-	int i;
-
-	for (i = 0; i < n_pixels; ++i)
-	{
-	    int32_t x = coords[0];
-	    int32_t y = coords[1];
-
-	    if (!pixman_region32_contains_point (image->common.src_clip, x, y, NULL))
-	    {
-		coords[0] = 0xffffffff;
-		coords[1] = 0xffffffff;
-	    }
-
-	    coords += 2;
-	}
-    }
-
     bits_image_fetch_alpha_pixels (image, buffer, n_pixels);
 }
 
@@ -663,7 +642,7 @@ bits_image_fetch_untransformed_repeat_none (bits_image_t *image, pixman_bool_t w
 					    uint32_t *buffer)
 {
     uint32_t w;
-    
+
     if (y < 0 || y >= image->height)
     {
 	memset (buffer, 0, width * sizeof (uint32_t));
@@ -690,11 +669,11 @@ bits_image_fetch_untransformed_repeat_none (bits_image_t *image, pixman_bool_t w
 	else
 	    image->fetch_scanline_raw_32 (image, x, y, w, buffer);
 	
+	width -= w;
 	buffer += w;
 	x += w;
-	width -= w;
     }
-    
+
     memset (buffer, 0, width * (wide? 8 : 4));
 }
 
@@ -889,10 +868,6 @@ pixman_image_create_bits (pixman_format_code_t  format,
 									*/
     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);
diff --git a/pixman/pixman-compute-region.c b/pixman/pixman-compute-region.c
index 31eaee8..70ffa3f 100644
--- a/pixman/pixman-compute-region.c
+++ b/pixman/pixman-compute-region.c
@@ -79,43 +79,15 @@ miClipPictureSrc (pixman_region32_t *	pRegion,
 		  int		dx,
 		  int		dy)
 {
-    /* XXX what to do with clipping from transformed pictures? */
-    if (pPicture->common.transform || pPicture->type != BITS)
+    /* Source clips are ignored, unless they are explicitly turned on
+     * and the clip in question was set by an X client
+     */
+    if (!pPicture->common.clip_sources || !pPicture->common.client_clip)
 	return TRUE;
 
-    if (pPicture->common.repeat)
-    {
-	/* If the clip region was set by a client, then it should be intersected
-	 * with the composite region since it's interpreted as happening
-	 * after the repeat algorithm.
-	 *
-	 * If the clip region was not set by a client, then it was imposed by
-	 * boundaries of the pixmap, or by sibling or child windows, which means
-	 * it should in theory be repeated along. FIXME: we ignore that case.
-	 * It is only relevant for windows that are (a) clipped by siblings/children
-	 * and (b) used as source. However this case is not useful anyway due
-	 * to lack of GraphicsExpose events.
-	 */
-	if (pPicture->common.has_client_clip)
-	{
-	    pixman_region32_translate (pRegion, dx, dy);
-	    
-	    if (!pixman_region32_intersect (pRegion, pRegion, 
-					    pPicture->common.src_clip))
-		return FALSE;
-	    
-	    pixman_region32_translate ( pRegion, -dx, -dy);
-	}
-	    
-	return TRUE;
-    }
-    else
-    {
-	return miClipPictureReg (pRegion,
-				 pPicture->common.src_clip,
-				 dx,
-				 dy);
-    }
+    return miClipPictureReg (pRegion,
+			     &pPicture->common.clip_region,
+			     dx, dy);
 }
 
 /*
@@ -123,6 +95,22 @@ miClipPictureSrc (pixman_region32_t *	pRegion,
  * an allocation failure, but rendering ignores those anyways.
  */
 
+static void
+print_region (pixman_region32_t *region, const char *header)
+{
+    int n_boxes;
+    pixman_box32_t *boxes = pixman_region32_rectangles (region, &n_boxes);
+    int i;
+
+    printf ("%s\n", header);
+    for (i = 0; i < n_boxes; ++i)
+    {
+	pixman_box32_t *box = &(boxes[i]);
+
+	printf ("   %d %d %d %d\n", box->x1, box->y1, box->x2, box->y2);
+    }
+}
+
 pixman_bool_t
 pixman_compute_composite_region32 (pixman_region32_t *	pRegion,
 				   pixman_image_t *	pSrc,
@@ -145,7 +133,14 @@ pixman_compute_composite_region32 (pixman_region32_t *	pRegion,
     pRegion->extents.y1 = yDst;
     v = yDst + height;
     pRegion->extents.y2 = BOUND(v);
+
+    pRegion->extents.x1 = MAX (pRegion->extents.x1, 0);
+    pRegion->extents.y1 = MAX (pRegion->extents.y1, 0);
+    pRegion->extents.x2 = MIN (pRegion->extents.x2, pDst->bits.width);
+    pRegion->extents.y2 = MIN (pRegion->extents.y2, pDst->bits.height);
+    
     pRegion->data = 0;
+    
     /* Check for empty operation */
     if (pRegion->extents.x1 >= pRegion->extents.x2 ||
 	pRegion->extents.y1 >= pRegion->extents.y2)
@@ -153,13 +148,17 @@ pixman_compute_composite_region32 (pixman_region32_t *	pRegion,
 	pixman_region32_init (pRegion);
 	return FALSE;
     }
-    /* clip against dst */
-    if (!miClipPictureReg (pRegion, &pDst->common.clip_region, 0, 0))
+    
+    if (pDst->common.have_clip_region)
     {
-	pixman_region32_fini (pRegion);
-	return FALSE;
+	if (!miClipPictureReg (pRegion, &pDst->common.clip_region, 0, 0))
+	{
+	    pixman_region32_fini (pRegion);
+	    return FALSE;
+	}
     }
-    if (pDst->common.alpha_map)
+    
+    if (pDst->common.alpha_map && pDst->common.alpha_map->common.have_clip_region)
     {
 	if (!miClipPictureReg (pRegion, &pDst->common.alpha_map->common.clip_region,
 			       -pDst->common.alpha_origin.x,
@@ -169,13 +168,17 @@ pixman_compute_composite_region32 (pixman_region32_t *	pRegion,
 	    return FALSE;
 	}
     }
+    
     /* clip against src */
-    if (!miClipPictureSrc (pRegion, pSrc, xDst - xSrc, yDst - ySrc))
+    if (pSrc->common.have_clip_region)
     {
-	pixman_region32_fini (pRegion);
-	return FALSE;
+	if (!miClipPictureSrc (pRegion, pSrc, xDst - xSrc, yDst - ySrc))
+	{
+	    pixman_region32_fini (pRegion);
+	    return FALSE;
+	}
     }
-    if (pSrc->common.alpha_map)
+    if (pSrc->common.alpha_map && pSrc->common.alpha_map->common.have_clip_region)
     {
 	if (!miClipPictureSrc (pRegion, (pixman_image_t *)pSrc->common.alpha_map,
 			       xDst - (xSrc - pSrc->common.alpha_origin.x),
@@ -186,14 +189,14 @@ pixman_compute_composite_region32 (pixman_region32_t *	pRegion,
 	}
     }
     /* clip against mask */
-    if (pMask)
+    if (pMask && pMask->common.have_clip_region)
     {
 	if (!miClipPictureSrc (pRegion, pMask, xDst - xMask, yDst - yMask))
 	{
 	    pixman_region32_fini (pRegion);
 	    return FALSE;
 	}	
-	if (pMask->common.alpha_map)
+	if (pMask->common.alpha_map && pMask->common.alpha_map->common.have_clip_region)
 	{
 	    if (!miClipPictureSrc (pRegion, (pixman_image_t *)pMask->common.alpha_map,
 				   xDst - (xMask - pMask->common.alpha_origin.x),
@@ -204,6 +207,10 @@ pixman_compute_composite_region32 (pixman_region32_t *	pRegion,
 	    }
 	}
     }
+
+#if 0
+    print_region (pRegion, "composite region");
+#endif
     
     return TRUE;
 }
diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c
index 33bc0d1..7aee95e 100644
--- a/pixman/pixman-fast-path.c
+++ b/pixman/pixman-fast-path.c
@@ -1190,7 +1190,6 @@ fast_path_composite (pixman_implementation_t *imp,
         && (src->common.filter == PIXMAN_FILTER_NEAREST)
         && PIXMAN_FORMAT_BPP(dest->bits.format) == 32
         && src->bits.format == dest->bits.format
-        && src->common.src_clip == &(src->common.full_region)
         && !src->common.read_func && !src->common.write_func
         && !dest->common.read_func && !dest->common.write_func)
     {
diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index c9fad13..bdb6550 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -29,7 +29,6 @@
 #include <stdlib.h>
 #include <string.h>
 #include <math.h>
-#include <assert.h>
 #include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index b930c9f..9b4b73d 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -97,10 +97,10 @@ _pixman_image_allocate (void)
     {
 	image_common_t *common = &image->common;
 
-	pixman_region32_init (&common->full_region);
 	pixman_region32_init (&common->clip_region);
-	common->src_clip = &common->full_region;
-	common->has_client_clip = FALSE;
+
+	common->have_clip_region = FALSE;
+	common->clip_sources = FALSE;
 	common->transform = NULL;
 	common->repeat = PIXMAN_REPEAT_NONE;
 	common->filter = PIXMAN_FILTER_NEAREST;
@@ -112,6 +112,7 @@ _pixman_image_allocate (void)
 	common->read_func = NULL;
 	common->write_func = NULL;
 	common->classify = NULL;
+	common->client_clip = FALSE;
     }
 
     return image;
@@ -191,7 +192,6 @@ pixman_image_unref (pixman_image_t *image)
     if (common->ref_count == 0)
     {
 	pixman_region32_fini (&common->clip_region);
-	pixman_region32_fini (&common->full_region);
 
 	if (common->transform)
 	    free (common->transform);
@@ -233,17 +233,7 @@ pixman_image_unref (pixman_image_t *image)
 void
 _pixman_image_reset_clip_region (pixman_image_t *image)
 {
-    pixman_region32_fini (&image->common.clip_region);
-
-    if (image->type == BITS)
-    {
-	pixman_region32_init_rect (&image->common.clip_region, 0, 0,
-				   image->bits.width, image->bits.height);
-    }
-    else
-    {
-	pixman_region32_init (&image->common.clip_region);
-    }
+    image->common.have_clip_region = FALSE;
 }
 
 PIXMAN_EXPORT pixman_bool_t
@@ -255,7 +245,8 @@ pixman_image_set_clip_region32 (pixman_image_t *image,
 
     if (region)
     {
-	result = pixman_region32_copy (&common->clip_region, region);
+	if ((result = pixman_region32_copy (&common->clip_region, region)))
+	    image->common.have_clip_region = TRUE;
     }
     else
     {
@@ -279,7 +270,8 @@ pixman_image_set_clip_region (pixman_image_t    *image,
 
     if (region)
     {
-	result = pixman_region32_copy_from_region16 (&common->clip_region, region);
+	if ((result = pixman_region32_copy_from_region16 (&common->clip_region, region)))
+	    image->common.have_clip_region = TRUE;
     }
     else
     {
@@ -293,15 +285,11 @@ pixman_image_set_clip_region (pixman_image_t    *image,
     return result;
 }
 
-/* Sets whether the clip region includes a clip region set by the client
- */
 PIXMAN_EXPORT void
 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);
+    image->common.client_clip = client_clip;
 }
 
 PIXMAN_EXPORT pixman_bool_t
@@ -393,16 +381,9 @@ pixman_image_set_filter (pixman_image_t       *image,
 
 PIXMAN_EXPORT void
 pixman_image_set_source_clipping (pixman_image_t  *image,
-				  pixman_bool_t    source_clipping)
+				  pixman_bool_t    clip_sources)
 {
-    image_common_t *common = &image->common;
-
-    if (source_clipping)
-	common->src_clip = &common->clip_region;
-    else
-	common->src_clip = &common->full_region;
-
-    image_property_changed (image);
+    image->common.clip_sources = clip_sources;
 }
 
 /* Unlike all the other property setters, this function does not
@@ -617,11 +598,14 @@ pixman_image_fill_rectangles (pixman_op_t		    op,
 		pixman_box32_t *boxes;
 
 		pixman_region32_init_rect (&fill_region, rects[i].x, rects[i].y, rects[i].width, rects[i].height);
-		if (!pixman_region32_intersect (&fill_region,
-						&fill_region,
-						&dest->common.clip_region))
-		    return FALSE;
 
+		if (dest->common.have_clip_region)
+		{
+		    if (!pixman_region32_intersect (&fill_region,
+						    &fill_region,
+						    &dest->common.clip_region))
+			return FALSE;
+		}
 
 		boxes = pixman_region32_rectangles (&fill_region, &n_boxes);
 		for (j = 0; j < n_boxes; ++j)
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 70b4dbc..ae51447 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -296,10 +296,12 @@ struct image_common
 {
     image_type_t		type;
     int32_t			ref_count;
-    pixman_region32_t		full_region;
     pixman_region32_t		clip_region;
-    pixman_region32_t	       *src_clip;
-    pixman_bool_t               has_client_clip;
+    pixman_bool_t		have_clip_region;	/* FALSE if there is no clip */
+    pixman_bool_t		client_clip;	/* Whether the source clip was set by a client */
+    pixman_bool_t		clip_sources;		/* Whether the clip applies when
+							 * the image is used as a source
+							 */
     pixman_transform_t	       *transform;
     pixman_repeat_t		repeat;
     pixman_filter_t		filter;
diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c
index 5023f3b..7fa89fa 100644
--- a/pixman/pixman-utils.c
+++ b/pixman/pixman-utils.c
@@ -565,6 +565,7 @@ walk_region_internal (pixman_implementation_t *imp,
 	    x_src = pbox->x1 - xDst + xSrc;
 	    x_msk = pbox->x1 - xDst + xMask;
 	    x_dst = pbox->x1;
+	    
 	    if (maskRepeat)
 	    {
 		y_msk = MOD (y_msk, pMask->bits.height);
@@ -629,7 +630,7 @@ _pixman_walk_composite_region (pixman_implementation_t *imp,
     pixman_region32_t region;
     
     pixman_region32_init (&region);
-    
+
     if (pixman_compute_composite_region32 (
 	    &region, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height))
     {
commit b9683cb2ae519707e06a0b9302f8a373d336da12
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Wed Jun 3 00:25:54 2009 -0400

    Fix pixman_image_is_opaque()
    
    - Don't claim that non-repeating bits images are opaque.
    
    - Don't claim that conical gradients are opaque ever.

diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index c8295f8..b930c9f 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -692,57 +692,51 @@ pixman_image_can_get_solid (pixman_image_t *image)
 }
 
 pixman_bool_t
-pixman_image_is_opaque(pixman_image_t *image)
+pixman_image_is_opaque (pixman_image_t *image)
 {
-    int i = 0;
-    int gradientNumberOfColors = 0;
+    int i;
 
-    if(image->common.alpha_map)
+    if (image->common.alpha_map)
         return FALSE;
 
-    switch(image->type)
+    switch (image->type)
     {
     case BITS:
-        if(PIXMAN_FORMAT_A(image->bits.format))
+	if (image->common.repeat == PIXMAN_REPEAT_NONE)
+	    return FALSE;
+	
+        if (PIXMAN_FORMAT_A (image->bits.format))
             return FALSE;
         break;
 
     case LINEAR:
-    case CONICAL:
     case RADIAL:
-        gradientNumberOfColors = image->gradient.n_stops;
-        i=0;
-        while(i<gradientNumberOfColors)
-        {
-            if(image->gradient.stops[i].color.alpha != 0xffff)
+	if (image->common.repeat == PIXMAN_REPEAT_NONE)
+	    return FALSE;
+	
+	for (i = 0; i < image->gradient.n_stops; ++i)
+	{
+            if (image->gradient.stops[i].color.alpha != 0xffff)
                 return FALSE;
-            i++;
         }
         break;
 
+    case CONICAL:
+	/* Conical gradients always have a transparent border */
+	return FALSE;
+	break;
+	
     case SOLID:
-         if(Alpha(image->solid.color) != 0xff)
+         if (Alpha (image->solid.color) != 0xff)
             return FALSE;
         break;
     }
 
-    /* Convolution filters can introduce translucency if the sum of the weights
-       is lower than 1. */
+    /* Convolution filters can introduce translucency if the sum of the
+     * weights is lower than 1.
+     */
     if (image->common.filter == PIXMAN_FILTER_CONVOLUTION)
          return FALSE;
 
-    if (image->common.repeat == PIXMAN_REPEAT_NONE)
-    {
-        if (image->common.filter != PIXMAN_FILTER_NEAREST)
-            return FALSE;
-
-        if (image->common.transform)
-            return FALSE;
-
-	/* Gradients do not necessarily cover the entire compositing area */
-	if (image->type == LINEAR || image->type == CONICAL || image->type == RADIAL)
-	    return FALSE;
-    }
-
      return TRUE;
 }
commit 7aeed3fc08b3359a3e4e6178f569dbb28ffdad08
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Tue Jun 2 22:57:23 2009 -0400

    Only call fast paths when the images cover the composite region

diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c
index c85adef..5023f3b 100644
--- a/pixman/pixman-utils.c
+++ b/pixman/pixman-utils.c
@@ -722,6 +722,22 @@ get_fast_path (const FastPathInfo *fast_paths,
     return NULL;
 }
 
+static inline pixman_bool_t
+image_covers (pixman_image_t *image, pixman_box32_t *extents)
+{
+    if (image->common.type == BITS && image->common.repeat == PIXMAN_REPEAT_NONE)
+    {
+	if (extents->x1 < 0 || extents->y1 < 0 ||
+	    extents->x2 >= image->bits.width ||
+	    extents->y2 >= image->bits.height)
+	{
+	    return FALSE;
+	}
+    }
+
+    return TRUE;
+}
+
 pixman_bool_t
 _pixman_run_fast_path (const FastPathInfo *paths,
 		       pixman_implementation_t *imp,
@@ -741,15 +757,28 @@ _pixman_run_fast_path (const FastPathInfo *paths,
     pixman_composite_func_t func = NULL;
     pixman_bool_t src_repeat = src->common.repeat == PIXMAN_REPEAT_NORMAL;
     pixman_bool_t mask_repeat = mask && mask->common.repeat == PIXMAN_REPEAT_NORMAL;
-    
+    pixman_region32_t region;
+    pixman_bool_t result;
+    pixman_box32_t extents;
+
+    pixman_region32_init (&region);
+
+    if (!pixman_compute_composite_region32 (
+	    &region, src, mask, dest, src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
+    {
+	result = TRUE;
+
+	goto out;
+    }
+
     if ((src->type == BITS || pixman_image_can_get_solid (src)) &&
 	(!mask || mask->type == BITS)
-        && !src->common.transform && !(mask && mask->common.transform)
-        && !(mask && mask->common.alpha_map) && !src->common.alpha_map && !dest->common.alpha_map
-        && (src->common.filter != PIXMAN_FILTER_CONVOLUTION)
-        && (src->common.repeat != PIXMAN_REPEAT_PAD)
-        && (src->common.repeat != PIXMAN_REPEAT_REFLECT)
-        && (!mask || (mask->common.filter != PIXMAN_FILTER_CONVOLUTION &&
+	&& !src->common.transform && !(mask && mask->common.transform)
+	&& !(mask && mask->common.alpha_map) && !src->common.alpha_map && !dest->common.alpha_map
+	&& (src->common.filter != PIXMAN_FILTER_CONVOLUTION)
+	&& (src->common.repeat != PIXMAN_REPEAT_PAD)
+	&& (src->common.repeat != PIXMAN_REPEAT_REFLECT)
+	&& (!mask || (mask->common.filter != PIXMAN_FILTER_CONVOLUTION &&
 		      mask->common.repeat != PIXMAN_REPEAT_PAD &&
 		      mask->common.repeat != PIXMAN_REPEAT_REFLECT))
 	&& !src->common.read_func && !src->common.write_func
@@ -761,6 +790,16 @@ _pixman_run_fast_path (const FastPathInfo *paths,
 	const FastPathInfo *info;	
 	pixman_bool_t pixbuf;
 
+	extents = *pixman_region32_extents (&region);
+	
+	if (!image_covers (src, &extents)		||
+	    (mask && !image_covers (mask, &extents)))
+	{
+	    result = FALSE;
+	    
+	    goto out;
+	}
+    
 	pixbuf =
 	    src && src->type == BITS		&&
 	    mask && mask->type == BITS		&&
@@ -771,17 +810,17 @@ _pixman_run_fast_path (const FastPathInfo *paths,
 	    !mask_repeat;
 	
 	info = get_fast_path (paths, op, src, mask, dest, pixbuf);
-
+	
 	if (info)
 	{
 	    func = info->func;
-		
+	    
 	    if (info->src_format == PIXMAN_solid)
 		src_repeat = FALSE;
-
+	    
 	    if (info->mask_format == PIXMAN_solid || info->flags & NEED_SOLID_MASK)
 		mask_repeat = FALSE;
-
+	    
 	    if ((src_repeat			&&
 		 src->bits.width == 1		&&
 		 src->bits.height == 1)	||
@@ -801,30 +840,26 @@ _pixman_run_fast_path (const FastPathInfo *paths,
 	    }
 	}
     }
-
+    
     if (func)
     {
-	pixman_region32_t region;
-	
-	pixman_region32_init (&region);
-	
-	if (pixman_compute_composite_region32 (
-		&region, src, mask, dest, src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
-	{
-	    walk_region_internal (imp, op,
-				  src, mask, dest,
-				  src_x, src_y, mask_x, mask_y,
-				  dest_x, dest_y,
-				  width, height,
-				  src_repeat, mask_repeat,
-				  &region,
-				  func);
-	}
-
-	pixman_region32_fini (&region);
+	walk_region_internal (imp, op,
+			      src, mask, dest,
+			      src_x, src_y, mask_x, mask_y,
+			      dest_x, dest_y,
+			      width, height,
+			      src_repeat, mask_repeat,
+			      &region,
+			      func);
 	
-	return TRUE;
+	result = TRUE;
+    }
+    else
+    {
+	result = FALSE;
     }
     
-    return FALSE;
+out:
+    pixman_region32_fini (&region);
+    return result;
 }
commit e67c7eedf203f4424bdfac7982d2bc7c6e1748d2
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Tue Jun 2 22:17:00 2009 -0400

    Pass the region to walk_region_internal()

diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c
index 332d881..c85adef 100644
--- a/pixman/pixman-utils.c
+++ b/pixman/pixman-utils.c
@@ -543,23 +543,13 @@ walk_region_internal (pixman_implementation_t *imp,
 		      uint16_t height,
 		      pixman_bool_t srcRepeat,
 		      pixman_bool_t maskRepeat,
+		      pixman_region32_t *region,
 		      pixman_composite_func_t compositeRect)
 {
-    int		    n;
+    int n;
     const pixman_box32_t *pbox;
-    int		    w, h, w_this, h_this;
-    int		    x_msk, y_msk, x_src, y_src, x_dst, y_dst;
-    pixman_region32_t reg;
-    pixman_region32_t *region;
-
-    pixman_region32_init (&reg);
-    if (!pixman_compute_composite_region32 (&reg, pSrc, pMask, pDst,
-					    xSrc, ySrc, xMask, yMask, xDst, yDst, width, height))
-    {
-	return;
-    }
-
-    region = &reg;
+    int w, h, w_this, h_this;
+    int x_msk, y_msk, x_src, y_src, x_dst, y_dst;
 
     pbox = pixman_region32_rectangles (region, &n);
     while (n--)
@@ -618,7 +608,6 @@ walk_region_internal (pixman_implementation_t *imp,
 	}
 	pbox++;
     }
-    pixman_region32_fini (&reg);
 }
 
 void
@@ -637,11 +626,22 @@ _pixman_walk_composite_region (pixman_implementation_t *imp,
 			       uint16_t height,
 			       pixman_composite_func_t compositeRect)
 {
-    walk_region_internal (imp, op,
-			  pSrc, pMask, pDst,
-			  xSrc, ySrc, xMask, yMask, xDst, yDst,
-			  width, height, FALSE, FALSE,
-			  compositeRect);
+    pixman_region32_t region;
+    
+    pixman_region32_init (&region);
+    
+    if (pixman_compute_composite_region32 (
+	    &region, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height))
+    {
+	walk_region_internal (imp, op,
+			      pSrc, pMask, pDst,
+			      xSrc, ySrc, xMask, yMask, xDst, yDst,
+			      width, height, FALSE, FALSE,
+			      &region,
+			      compositeRect);
+    }
+
+    pixman_region32_fini (&region);
 }
 
     
@@ -680,7 +680,7 @@ get_fast_path (const FastPathInfo *fast_paths,
 	if (info->op != op)
 	    continue;
 
-	if ((info->src_format == PIXMAN_solid && pixman_image_can_get_solid (pSrc))		||
+	if ((info->src_format == PIXMAN_solid && pixman_image_can_get_solid (pSrc)) ||
 	    (pSrc->type == BITS && info->src_format == pSrc->bits.format))
 	{
 	    valid_src = TRUE;
@@ -689,7 +689,7 @@ get_fast_path (const FastPathInfo *fast_paths,
 	if (!valid_src)
 	    continue;
 
-	if ((info->mask_format == PIXMAN_null && !pMask)			||
+	if ((info->mask_format == PIXMAN_null && !pMask) ||
 	    (pMask && pMask->type == BITS && info->mask_format == pMask->bits.format))
 	{
 	    valid_mask = TRUE;
@@ -804,13 +804,25 @@ _pixman_run_fast_path (const FastPathInfo *paths,
 
     if (func)
     {
-	walk_region_internal (imp, op,
-			      src, mask, dest,
-			      src_x, src_y, mask_x, mask_y,
-			      dest_x, dest_y,
-			      width, height,
-			      src_repeat, mask_repeat,
-			      func);
+	pixman_region32_t region;
+	
+	pixman_region32_init (&region);
+	
+	if (pixman_compute_composite_region32 (
+		&region, src, mask, dest, src_x, src_y, mask_x, mask_y, dest_x, dest_y, width, height))
+	{
+	    walk_region_internal (imp, op,
+				  src, mask, dest,
+				  src_x, src_y, mask_x, mask_y,
+				  dest_x, dest_y,
+				  width, height,
+				  src_repeat, mask_repeat,
+				  &region,
+				  func);
+	}
+
+	pixman_region32_fini (&region);
+	
 	return TRUE;
     }
     
commit 85a2f55e6b55833cb4092c6e9e58497fbd9e7167
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Tue Jun 2 22:08:02 2009 -0400

    Remove srcRepeat and maskRepeat arguments from _pixman_walk_composite_region()

diff --git a/pixman/pixman-fast-path.c b/pixman/pixman-fast-path.c
index 65a291f..33bc0d1 100644
--- a/pixman/pixman-fast-path.c
+++ b/pixman/pixman-fast-path.c
@@ -1207,7 +1207,6 @@ fast_path_composite (pixman_implementation_t *imp,
 					   mask_x, mask_y,
 					   dest_x, dest_y,
 					   width, height,
-					   FALSE, FALSE, 
 					   fbCompositeSrcScaleNearest);
 	    return;
 	}
diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index 4039144..c9fad13 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -261,7 +261,7 @@ general_composite (pixman_implementation_t *	imp,
 {
     _pixman_walk_composite_region (imp, op, src, mask, dest, src_x, src_y,
 				   mask_x, mask_y, dest_x, dest_y, width, height,
-				   FALSE, FALSE, general_composite_rect);
+				   general_composite_rect);
 }
 
 static pixman_bool_t
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 896dfac..70b4dbc 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -884,20 +884,18 @@ typedef pixman_bool_t (* pixman_fill_func_t) (pixman_implementation_t *imp,
 
 void
 _pixman_walk_composite_region (pixman_implementation_t *imp,
-			      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,
-			      pixman_bool_t srcRepeat,
-			      pixman_bool_t maskRepeat,
+			       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,
 			       pixman_composite_func_t compositeRect);
 
 void _pixman_setup_combiner_functions_32 (pixman_implementation_t *imp);
diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c
index 5f218eb..332d881 100644
--- a/pixman/pixman-utils.c
+++ b/pixman/pixman-utils.c
@@ -635,15 +635,12 @@ _pixman_walk_composite_region (pixman_implementation_t *imp,
 			       int16_t yDst,
 			       uint16_t width,
 			       uint16_t height,
-			       pixman_bool_t srcRepeat,
-			       pixman_bool_t maskRepeat,
 			       pixman_composite_func_t compositeRect)
 {
     walk_region_internal (imp, op,
 			  pSrc, pMask, pDst,
 			  xSrc, ySrc, xMask, yMask, xDst, yDst,
-			  width, height,
-			  srcRepeat, maskRepeat,
+			  width, height, FALSE, FALSE,
 			  compositeRect);
 }
 
@@ -807,13 +804,13 @@ _pixman_run_fast_path (const FastPathInfo *paths,
 
     if (func)
     {
-	_pixman_walk_composite_region (imp, op,
-				       src, mask, dest,
-				       src_x, src_y, mask_x, mask_y,
-				       dest_x, dest_y,
-				       width, height,
-				       src_repeat, mask_repeat,
-				       func);
+	walk_region_internal (imp, op,
+			      src, mask, dest,
+			      src_x, src_y, mask_x, mask_y,
+			      dest_x, dest_y,
+			      width, height,
+			      src_repeat, mask_repeat,
+			      func);
 	return TRUE;
     }
     
commit dc0a9dd65ab2622646d1220adf3e5ea70dcae951
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Tue Jun 2 22:04:47 2009 -0400

    Remove all the srcRepeat/srcTransform stuff from the general implementation.

diff --git a/pixman/pixman-general.c b/pixman/pixman-general.c
index be512d5..4039144 100644
--- a/pixman/pixman-general.c
+++ b/pixman/pixman-general.c
@@ -259,57 +259,9 @@ general_composite (pixman_implementation_t *	imp,
 		   int32_t			width,
 		   int32_t			height)
 {
-    pixman_bool_t srcRepeat = src->type == BITS && src->common.repeat == PIXMAN_REPEAT_NORMAL;
-    pixman_bool_t maskRepeat = FALSE;
-    pixman_bool_t srcTransform = src->common.transform != NULL;
-    pixman_bool_t maskTransform = FALSE;
-    
-    if (srcRepeat && srcTransform &&
-	src->bits.width == 1 &&
-	src->bits.height == 1)
-    {
-	srcTransform = FALSE;
-    }
-    
-    if (mask && mask->type == BITS)
-    {
-	maskRepeat = mask->common.repeat == PIXMAN_REPEAT_NORMAL;
-	
-	maskTransform = mask->common.transform != 0;
-	if (mask->common.filter == PIXMAN_FILTER_CONVOLUTION)
-	    maskTransform = TRUE;
-	
-	if (maskRepeat && maskTransform &&
-	    mask->bits.width == 1 &&
-	    mask->bits.height == 1)
-	{
-	    maskTransform = FALSE;
-	}
-    }
-    
-    /* CompositeGeneral optimizes 1x1 repeating images itself */
-    if (src->type == BITS &&
-	src->bits.width == 1 && src->bits.height == 1)
-    {
-	srcRepeat = FALSE;
-    }
-    
-    if (mask && mask->type == BITS &&
-	mask->bits.width == 1 && mask->bits.height == 1)
-    {
-	maskRepeat = FALSE;
-    }
-    
-    /* if we are transforming, repeats are handled in fbFetchTransformed */
-    if (srcTransform)
-	srcRepeat = FALSE;
-    
-    if (maskTransform)
-	maskRepeat = FALSE;
-    
     _pixman_walk_composite_region (imp, op, src, mask, dest, src_x, src_y,
 				   mask_x, mask_y, dest_x, dest_y, width, height,
-				   srcRepeat, maskRepeat, general_composite_rect);
+				   FALSE, FALSE, general_composite_rect);
 }
 
 static pixman_bool_t
commit f885caad4a709d7d2c4f0bf63d735080bcca3c24
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Tue Jun 2 22:02:52 2009 -0400

    Make _pixman_walk_composite_region() a wrapper around an internal function

diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c
index 8139947..5f218eb 100644
--- a/pixman/pixman-utils.c
+++ b/pixman/pixman-utils.c
@@ -527,23 +527,23 @@ pixman_format_supported_source (pixman_format_code_t format)
     }
 }
 
-void
-_pixman_walk_composite_region (pixman_implementation_t *imp,
-			      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,
-			      pixman_bool_t srcRepeat,
-			      pixman_bool_t maskRepeat,
-			      pixman_composite_func_t compositeRect)
+static void
+walk_region_internal (pixman_implementation_t *imp,
+		      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,
+		      pixman_bool_t srcRepeat,
+		      pixman_bool_t maskRepeat,
+		      pixman_composite_func_t compositeRect)
 {
     int		    n;
     const pixman_box32_t *pbox;
@@ -621,6 +621,33 @@ _pixman_walk_composite_region (pixman_implementation_t *imp,
     pixman_region32_fini (&reg);
 }
 
+void
+_pixman_walk_composite_region (pixman_implementation_t *imp,
+			       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,
+			       pixman_bool_t srcRepeat,
+			       pixman_bool_t maskRepeat,
+			       pixman_composite_func_t compositeRect)
+{
+    walk_region_internal (imp, op,
+			  pSrc, pMask, pDst,
+			  xSrc, ySrc, xMask, yMask, xDst, yDst,
+			  width, height,
+			  srcRepeat, maskRepeat,
+			  compositeRect);
+}
+
+    
 static pixman_bool_t
 mask_is_solid (pixman_image_t *mask)
 {
@@ -650,8 +677,8 @@ get_fast_path (const FastPathInfo *fast_paths,
 
     for (info = fast_paths; info->op != PIXMAN_OP_NONE; info++)
     {
-	pixman_bool_t valid_src		= FALSE;
-	pixman_bool_t valid_mask	= FALSE;
+	pixman_bool_t valid_src = FALSE;
+	pixman_bool_t valid_mask = FALSE;
 
 	if (info->op != op)
 	    continue;
commit d5768884a1576e7ad4a9d1e24063d214babb7157
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Tue Jun 2 21:31:58 2009 -0400

    Handle repeat_none/normal for 64 bit fetchers

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index bbdfa89..a654b46 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -658,77 +658,98 @@ bits_image_fetch_solid_64 (bits_image_t * image,
 }
 
 static void
-bits_image_fetch_untransformed_32 (bits_image_t * image,
-				   int x, int y, int width,
-				   uint32_t *buffer, uint32_t *mask, uint32_t maskBits)
+bits_image_fetch_untransformed_repeat_none (bits_image_t *image, pixman_bool_t wide,
+					    int x, int y, int width,
+					    uint32_t *buffer)
 {
-    if (image->common.repeat == PIXMAN_REPEAT_NONE)
+    uint32_t w;
+    
+    if (y < 0 || y >= image->height)
     {
-	if (y < 0 || y >= image->height)
-	{
-	    memset (buffer, 0, width * sizeof (uint32_t));
-	}
-	else
-	{
-	    uint32_t w;
-
-	    if (x < 0)
-	    {
-		w = MIN (width, -x);
-		
-		memset (buffer, 0, w * sizeof (uint32_t));
-		
-		width -= w;
-		buffer += w;
-		x += w;
-	    }
-
-	    if (x < image->width)
-	    {
-		w = MIN (width, image->width - x);
-		image->fetch_scanline_raw_32 (image, x, y, w, buffer);
+	memset (buffer, 0, width * sizeof (uint32_t));
+	return;
+    }
 
-		buffer += w;
-		x += w;
-		width -= w;
-	    }
-	    
-	    memset (buffer, 0, width * sizeof (uint32_t));
-	}
+    if (x < 0)
+    {
+	w = MIN (width, -x);
+	
+	memset (buffer, 0, w * (wide? 8 : 4));
+	
+	width -= w;
+	buffer += w;
+	x += w;
     }
-    else if (image->common.repeat == PIXMAN_REPEAT_NORMAL)
+    
+    if (x < image->width)
     {
-	uint32_t w;
+	w = MIN (width, image->width - x);
 	
-	while (y < 0)
-	    y += image->height;
-	while (y >= image->height)
-	    y -= image->height;
-
-	while (width)
-	{
-	    while (x < 0)
-		x += image->width;
-	    while (x >= image->width)
-		x -= image->width;
-
-	    w = MIN (width, image->width - x);
-	    
+	if (wide)
+	    image->fetch_scanline_raw_64 (image, x, y, w, (uint64_t *)buffer);
+	else
 	    image->fetch_scanline_raw_32 (image, x, y, w, buffer);
+	
+	buffer += w;
+	x += w;
+	width -= w;
+    }
+    
+    memset (buffer, 0, width * (wide? 8 : 4));
+}
 
-	    buffer += w;
-	    x += w;
-	    width -= w;
-	}
+static void
+bits_image_fetch_untransformed_repeat_normal (bits_image_t *image, pixman_bool_t wide,
+					      int x, int y, int width,
+					      uint32_t *buffer)
+{
+    uint32_t w;
+    
+    while (y < 0)
+	y += image->height;
+    while (y >= image->height)
+	y -= image->height;
+    
+    while (width)
+    {
+	while (x < 0)
+	    x += image->width;
+	while (x >= image->width)
+	    x -= image->width;
+	
+	w = MIN (width, image->width - x);
+	
+	if (wide)
+	    image->fetch_scanline_raw_64 (image, x, y, w, (uint64_t *)buffer);
+	else
+	    image->fetch_scanline_raw_32 (image, x, y, w, buffer);
+	
+	buffer += w;
+	x += w;
+	width -= w;
     }
 }
 
 static void
+bits_image_fetch_untransformed_32 (bits_image_t * image,
+				   int x, int y, int width,
+				   uint32_t *buffer, uint32_t *mask, uint32_t maskBits)
+{
+    if (image->common.repeat == PIXMAN_REPEAT_NONE)
+	bits_image_fetch_untransformed_repeat_none (image, FALSE, x, y, width, buffer);
+    else
+	bits_image_fetch_untransformed_repeat_normal (image, FALSE, x, y, width, buffer);
+}
+
+static void
 bits_image_fetch_untransformed_64 (bits_image_t * image,
 				   int x, int y, int width,
 				   uint64_t *buffer, void *unused, uint32_t unused2)
 {
-    image->fetch_scanline_raw_64 (image, x, y, width, buffer);
+    if (image->common.repeat == PIXMAN_REPEAT_NONE)
+	bits_image_fetch_untransformed_repeat_none (image, FALSE, x, y, width, (uint32_t *)buffer);
+    else
+	bits_image_fetch_untransformed_repeat_normal (image, FALSE, x, y, width, (uint32_t *)buffer);
 }
 
 static void
commit c9ea4a9722bc3c2223e8c8d72aa1b23598db489e
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date:   Tue Jun 2 21:20:42 2009 -0400

    Make the untransformed path handle REPEAT_NONE and REPEAT_NORMAL

diff --git a/pixman/pixman-bits-image.c b/pixman/pixman-bits-image.c
index e9f12d0..bbdfa89 100644
--- a/pixman/pixman-bits-image.c
+++ b/pixman/pixman-bits-image.c
@@ -662,7 +662,65 @@ bits_image_fetch_untransformed_32 (bits_image_t * image,
 				   int x, int y, int width,
 				   uint32_t *buffer, uint32_t *mask, uint32_t maskBits)
 {
-    image->fetch_scanline_raw_32 (image, x, y, width, buffer);
+    if (image->common.repeat == PIXMAN_REPEAT_NONE)
+    {
+	if (y < 0 || y >= image->height)
+	{
+	    memset (buffer, 0, width * sizeof (uint32_t));
+	}
+	else
+	{
+	    uint32_t w;
+
+	    if (x < 0)
+	    {
+		w = MIN (width, -x);
+		
+		memset (buffer, 0, w * sizeof (uint32_t));
+		
+		width -= w;
+		buffer += w;
+		x += w;
+	    }
+
+	    if (x < image->width)
+	    {
+		w = MIN (width, image->width - x);
+		image->fetch_scanline_raw_32 (image, x, y, w, buffer);
+
+		buffer += w;
+		x += w;
+		width -= w;
+	    }
+	    
+	    memset (buffer, 0, width * sizeof (uint32_t));
+	}
+    }
+    else if (image->common.repeat == PIXMAN_REPEAT_NORMAL)
+    {
+	uint32_t w;
+	
+	while (y < 0)
+	    y += image->height;
+	while (y >= image->height)
+	    y -= image->height;
+
+	while (width)
+	{
+	    while (x < 0)
+		x += image->width;
+	    while (x >= image->width)
+		x -= image->width;
+
+	    w = MIN (width, image->width - x);
+	    
+	    image->fetch_scanline_raw_32 (image, x, y, w, buffer);
+
+	    buffer += w;
+	    x += w;
+	    width -= w;
+	}
+    }
 }
 
 static void
@@ -694,8 +752,8 @@ bits_image_property_changed (pixman_image_t *image)
     }
     else if (!bits->common.transform &&
 	     bits->common.filter != PIXMAN_FILTER_CONVOLUTION &&
-	     bits->common.repeat != PIXMAN_REPEAT_PAD &&
-	     bits->common.repeat != PIXMAN_REPEAT_REFLECT)
+	     (bits->common.repeat == PIXMAN_REPEAT_NONE ||
+	      bits->common.repeat == PIXMAN_REPEAT_NORMAL))
     {
 	image->common.get_scanline_64 = (scanFetchProc)bits_image_fetch_untransformed_64;
 	image->common.get_scanline_32 = (scanFetchProc)bits_image_fetch_untransformed_32;


More information about the xorg-commit mailing list