[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

pixman: Changes to 'upstream-experimental'



 TODO                           |  137 ++-
 pixman/Makefile.am             |   25 
 pixman/pixman-compose.c        | 1611 +++++++++++++++++++----------------------
 pixman/pixman-compute-region.c |    4 
 pixman/pixman-edge-imp.h       |   43 -
 pixman/pixman-edge.c           |  372 ++-------
 pixman/pixman-image.c          |  146 +++
 pixman/pixman-mmx.c            |  244 ++++--
 pixman/pixman-mmx.h            |   15 
 pixman/pixman-pict.c           |  415 +++++++++-
 pixman/pixman-private.h        |  263 ++++--
 pixman/pixman-region.c         |   95 ++
 pixman/pixman-timer.c          |   59 +
 pixman/pixman-utils.c          |  314 +++++++
 pixman/pixman.h                |    5 
 test/gradient-test.c           |    1 
 16 files changed, 2329 insertions(+), 1420 deletions(-)

New commits:
commit 0c80a0cd84f30616563cef5910df9deb4f8ed687
Author: Alan Coopersmith <alanc@sun.com>
Date:   Mon Jul 16 15:06:23 2007 -0400

    Build fixes for Solaris.

diff --git a/pixman/pixman-edge.c b/pixman/pixman-edge.c
index 335a25f..191752f 100644
--- a/pixman/pixman-edge.c
+++ b/pixman/pixman-edge.c
@@ -321,13 +321,9 @@ pixman_rasterize_edges (pixman_image_t *image,
 			pixman_fixed_t	b)
 {
     if (image->common.read_func	|| image->common.write_func)
-    {
-	return pixman_rasterize_edges_accessors (image, l, r, t, b);
-    }
+	pixman_rasterize_edges_accessors (image, l, r, t, b);
     else
-    {
-	return pixman_rasterize_edges_no_accessors (image, l, r, t, b);
-    }
+	pixman_rasterize_edges_no_accessors (image, l, r, t, b);
 }
 
 #endif

commit 0f392d81748ab1338d294de96e28c43270f24180
Author: Jinghua Luo <sunmoon1997@gmail.com>
Date:   Tue Jul 10 14:47:28 2007 +0800

    Fix bug in rasterizeEdges() where the stride should be signed.

diff --git a/pixman/pixman-edge.c b/pixman/pixman-edge.c
index 1b28550..335a25f 100644
--- a/pixman/pixman-edge.c
+++ b/pixman/pixman-edge.c
@@ -128,7 +128,7 @@ fbRasterizeEdges8 (pixman_image_t       *image,
     int fill_start = -1, fill_end = -1;
     int fill_size = 0;
     uint32_t *buf = (image)->bits.bits;		
-    uint32_t stride = (image)->bits.rowstride;	
+    int32_t stride = (image)->bits.rowstride;	
     uint32_t width = (image)->bits.width;
     
     line = buf + pixman_fixed_to_int (y) * stride;

commit bbef73192e558695933d7f05befaa8c18550bb63
Author: Søren Sandmann <sandmann@redhat.com>
Date:   Mon Jul 2 12:18:42 2007 -0400

    Port Vlad's fixes for integer overflows with malloc().

diff --git a/TODO b/TODO
index 92beb0b..6649c69 100644
--- a/TODO
+++ b/TODO
@@ -1,8 +1,15 @@
+  - Go through things marked FIXME
+
+  - Add calls to prepare and finish access where necessary.  grep for
+    ACCESS_MEM, and make sure they are correctly wrapped in prepare
+    and finish.
+
+  - restore READ/WRITE in the fbcompose combiners since they sometimes
+    store directly to destination drawables.
+
   - It probably makes sense to move the more strange X region API
     into pixman as well, but guarded with PIXMAN_XORG_COMPATIBILITY
 
-  - Go through things marked FIXME
-
   - Reinstate the FbBits typedef? At the moment we don't
     even have the FbBits type; we just use uint32_t everywhere.
 
@@ -14,33 +21,78 @@
         this, I suggest just using 32-bit datatypes by setting
         IC_SHIFT to 5 for all machines.
 
-- Consider whether calling regions region16 is really such a great idea
+  - Consider whether calling regions region16 is really such a great
+    idea Vlad wants 32 bit regions for Cairo. This will break X server
+    ABI, but should otherwise be mostly harmless, though a
+    pixman_region_get_boxes16() may be useful.
 
-- Run cairo test suite; fix bugs
-	- one bug in source-scale-clip
+  - Make source clipping optional.
+      - done: source clipping happens through an indirection.
+	still needs to make the indirection settable. (And call it
+        from X)
 
- - Remove the warning suppression in the ACCESS_MEM macro and fix the
-    warnings that are real
+  - Consider optimizing the 8/16 bit solid fills in pixman-util.c by
+    storing more than one value at a time.
 
-- Add calls to prepare and finish access where necessary. 
-  grep for ACCESS_MEM, and make sure they are correctly wrapped in
-  prepare and finish
+  - Add an image cache to prevent excessive malloc/free. Note that pixman
+    needs to be thread safe when used from cairo.
 
-- Make source clipping optional.
-       - done: source clipping happens through an indirection.
-         still needs to make the indirection settable.
+  - Review the pixman_format_code_t enum to make sure it will support
+    future formats. Some formats we will probably need:
 
-- make the wrapper functions global instead of image specific
-	- this won't work since pixman is linked to both fb and wfb
+    	   ARGB/ABGR with 16/32/64 bit integer/floating channels
+	   YUV2,
+	   YV12
+
+    Also we may need the ability to distinguish between PICT_c8 and
+    PICT_x4c4. (This could be done by interpreting the A channel as
+    the depth for TYPE_COLOR and TYPE_GRAY formats).
+
+    A possibility may be to reserve the two top bits and make them
+    encode "number of places to shift the channel widths given" Since
+    these bits are 00 at the moment everything will continue to work,
+    but these additional widths will be allowed:
+
+    	     All even widths between 18-32
+	     All multiples of four widths between 33 and 64
+	     All multiples of eight between 64 and 128
 
-- restore READ/WRITE in the fbcompose combiners since they sometimes
-  store directly to destination drawables.
+    This means things like r21g22b21 won't work - is that worth
+    worrying about? I don't think so. And of course the bpp field
+    can't handle a depth of over 256, so > 64 bit channels arent'
+    really all that useful.
+
+    We could reserve one extra bit to indicate floating point, but
+    we may also just add 
+
+       	   PIXMAN_TYPE_ARGB_FLOAT
+	   PIXMAN_TYPE_BGRA_FLOAT
+	   PIXMAN_TYPE_A_FLOAT
+    
+    image types. With five bits we can support up to 32 different
+    format types, which should be enough for everybody, even if we
+    decide to support all the various video formats here:
+
+    	        http://www.fourcc.org/yuv.php
+
+    It may make sense to have a PIXMAN_TYPE_YUV, and then use the
+    channel bits to specify the exact subtype.
+
+    What about color spaces such a linear vs. srGB etc.?
 
-- Consider optimizing the 8/16 bit solid fills in pixman-util.c by
-  storing more than one value at a time.
 
 done:
 
+- Run cairo test suite; fix bugs
+	- one bug in source-scale-clip
+
+ - Remove the warning suppression in the ACCESS_MEM macro and fix the
+    warnings that are real
+	- irrelevant now.
+
+- make the wrapper functions global instead of image specific
+	- this won't work since pixman is linked to both fb and wfb
+
 - Add non-mmx solid fill
 
 - Make sure the endian-ness macros are defined correctly.
diff --git a/pixman/pixman-compose.c b/pixman/pixman-compose.c
index e336e04..e7f80f8 100644
--- a/pixman/pixman-compose.c
+++ b/pixman/pixman-compose.c
@@ -4074,7 +4074,7 @@ static void fbFetchExternalAlpha(bits_image_t * pict, int x, int y, int width, u
 	return;
     }
     if (width > SCANLINE_BUFFER_LENGTH)
-        alpha_buffer = (uint32_t *) malloc(width*sizeof(uint32_t));
+        alpha_buffer = (uint32_t *) pixman_malloc_ab (width, sizeof(uint32_t));
     
     fbFetchTransformed(pict, x, y, width, buffer, mask, maskBits);
     fbFetchTransformed((bits_image_t *)pict->common.alpha_map, x - pict->common.alpha_origin.x,
diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index f22d2c0..ca186a3 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -44,7 +44,7 @@ init_gradient (gradient_t     *gradient,
 
     init_source_image (&gradient->common);
 
-    gradient->stops = malloc (n_stops * sizeof (pixman_gradient_stop_t));
+    gradient->stops = pixman_malloc_ab (n_stops, sizeof (pixman_gradient_stop_t));
     if (!gradient->stops)
 	return FALSE;
 
@@ -443,7 +443,7 @@ pixman_image_set_filter (pixman_image_t       *image,
     new_params = NULL;
     if (params)
     {
-	new_params = malloc (n_params * sizeof (pixman_fixed_t));
+	new_params = pixman_malloc_ab (n_params, sizeof (pixman_fixed_t));
 	if (!new_params)
 	    return FALSE;
 
diff --git a/pixman/pixman-pict.c b/pixman/pixman-pict.c
index cad11dd..b8b7b76 100644
--- a/pixman/pixman-pict.c
+++ b/pixman/pixman-pict.c
@@ -1359,7 +1359,7 @@ pixman_image_composite_rect  (pixman_op_t                   op,
     
     if (width > SCANLINE_BUFFER_LENGTH)
     {
-	scanline_buffer = (uint32_t *)malloc (width * 3 * sizeof (uint32_t));
+	scanline_buffer = (uint32_t *)pixman_malloc_abc (width, 3, sizeof (uint32_t));
 
 	if (!scanline_buffer)
 	    return;
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index 9b89dee..89abf8f 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -44,6 +44,9 @@
 #define FB_MASK     (FB_UNIT - 1)
 #define FB_ALLONES  ((uint32_t) -1)
     
+/* Memory allocation helpers */
+void *pixman_malloc_ab (unsigned int n, unsigned int b);
+void *pixman_malloc_abc (unsigned int a, unsigned int b, unsigned int c);
 
 #if DEBUG
 
diff --git a/pixman/pixman-region.c b/pixman/pixman-region.c
index 08ce2e2..ffd92d6 100644
--- a/pixman/pixman-region.c
+++ b/pixman/pixman-region.c
@@ -69,7 +69,6 @@ typedef struct pixman_region16_point {
 #define PIXREGION_BOX(reg,i) (&PIXREGION_BOXPTR(reg)[i])
 #define PIXREGION_TOP(reg) PIXREGION_BOX(reg, (reg)->data->numRects)
 #define PIXREGION_END(reg) PIXREGION_BOX(reg, (reg)->data->numRects - 1)
-#define PIXREGION_SZOF(n) (sizeof(pixman_region16_data_t) + ((n) * sizeof(pixman_box16_t)))
 
 
 #undef assert
@@ -186,7 +185,29 @@ pixman_break (pixman_region16_t *pReg);
         ((r1)->y1 <= (r2)->y1) && \
         ((r1)->y2 >= (r2)->y2) )
 
-#define allocData(n) malloc(PIXREGION_SZOF(n))
+static size_t
+PIXREGION_SZOF(size_t n)
+{
+    size_t size = n * sizeof(pixman_box16_t);
+    if (n > UINT32_MAX / sizeof(pixman_box16_t))
+        return 0;
+
+    if (sizeof(pixman_region16_data_t) > UINT32_MAX - size)
+        return 0;
+
+    return size + sizeof(pixman_region16_data_t);
+}
+
+static void *
+allocData(size_t n)
+{
+    size_t sz = PIXREGION_SZOF(n);
+    if (!sz)
+	return NULL;
+
+    return malloc(sz);
+}
+
 #define freeData(reg) if ((reg)->data && (reg)->data->size) free((reg)->data)
 
 #define RECTALLOC_BAIL(pReg,n,bail) \
@@ -219,17 +240,21 @@ if (!(pReg)->data || (((pReg)->data->numRects + (n)) > (pReg)->data->size)) \
     assert(pReg->data->numRects<=pReg->data->size);			\
 }
 
-#define DOWNSIZE(reg,numRects)						 \
-if (((numRects) < ((reg)->data->size >> 1)) && ((reg)->data->size > 50)) \
-{									 \
-    pixman_region16_data_t * NewData;							 \
-    NewData = (pixman_region16_data_t *)realloc((reg)->data, PIXREGION_SZOF(numRects));	 \
-    if (NewData)							 \
-    {									 \
-	NewData->size = (numRects);					 \
-	(reg)->data = NewData;						 \
-    }									 \
-}
+#define DOWNSIZE(reg,numRects)						\
+    if (((numRects) < ((reg)->data->size >> 1)) && ((reg)->data->size > 50)) \
+    {									\
+	pixman_region16_data_t * NewData;				\
+	size_t data_size = PIXREGION_SZOF(numRects);			\
+	if (!data_size)							\
+	    NewData = NULL;						\
+	else								\
+	    NewData = (pixman_region16_data_t *)realloc((reg)->data, data_size); \
+	if (NewData)							\
+	{								\
+	    NewData->size = (numRects);					\
+	    (reg)->data = NewData;					\
+	}								\
+    }
 
 pixman_bool_t
 pixman_region_equal(reg1, reg2)
@@ -365,6 +390,7 @@ pixman_rect_alloc (pixman_region16_t * region, int n)
     }
     else
     {
+	size_t data_size;
 	if (n == 1)
 	{
 	    n = region->data->numRects;
@@ -372,7 +398,11 @@ pixman_rect_alloc (pixman_region16_t * region, int n)
 		n = 250;
 	}
 	n += region->data->numRects;
-	data = (pixman_region16_data_t *)realloc(region->data, PIXREGION_SZOF(n));
+	data_size = PIXREGION_SZOF(n);
+	if (!data_size)
+	    data = NULL;
+	else
+	    data = (pixman_region16_data_t *)realloc(region->data, PIXREGION_SZOF(n));
 	if (!data)
 	    return pixman_break (region);
 	region->data = data;
@@ -1466,7 +1496,7 @@ pixman_region_validate(pixman_region16_t * badreg,
 
     /* Set up the first region to be the first rectangle in badreg */
     /* Note that step 2 code will never overflow the ri[0].reg rects array */
-    ri = (RegionInfo *) malloc(4 * sizeof(RegionInfo));
+    ri = (RegionInfo *) pixman_malloc_ab (4, sizeof(RegionInfo));
     if (!ri)
 	return pixman_break (badreg);
     sizeRI = 4;
@@ -1528,9 +1558,15 @@ pixman_region_validate(pixman_region16_t * badreg,
 	/* Uh-oh.  No regions were appropriate.  Create a new one. */
 	if (sizeRI == numRI)
 	{
+	    size_t data_size;
+	    
 	    /* Oops, allocate space for new region information */
 	    sizeRI <<= 1;
-	    rit = (RegionInfo *) realloc(ri, sizeRI * sizeof(RegionInfo));
+
+            data_size = sizeRI * sizeof(RegionInfo);
+            if (data_size / sizeRI != sizeof(RegionInfo))
+                goto bail;
+            rit = (RegionInfo *) realloc(ri, data_size);
 	    if (!rit)
 		goto bail;
 	    ri = rit;
diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c
index aadb6e7..cdf115d 100644
--- a/pixman/pixman-utils.c
+++ b/pixman/pixman-utils.c
@@ -22,6 +22,7 @@
  */
 
 #include <config.h>
+#include <stdlib.h>
 #include "pixman.h"
 #include "pixman-private.h"
 #include "pixman-mmx.h"
@@ -366,3 +367,26 @@ pixman_line_fixed_edge_init (pixman_edge_t *e,
 		    bot->x + x_off_fixed,
 		    bot->y + y_off_fixed);
 }
+
+void *
+pixman_malloc_ab(unsigned int a,
+		 unsigned int b)
+{
+    if (a >= INT32_MAX / b)
+	return NULL;
+
+    return malloc (a * b);
+}
+
+void *
+pixman_malloc_abc (unsigned int a,
+		   unsigned int b,
+		   unsigned int c)
+{
+    if (a >= INT32_MAX / b)
+	return NULL;
+    else if (a * b >= INT32_MAX / c)
+	return NULL;
+    else
+	return malloc (a * b * c);
+}
diff --git a/pixman/pixman.h b/pixman/pixman.h
index cd64c8d..bd6045f 100644
--- a/pixman/pixman.h
+++ b/pixman/pixman.h
@@ -363,7 +363,7 @@ struct pixman_indexed
 				 PIXMAN_FORMAT_B(f))
 
 #define PIXMAN_TYPE_OTHER	0
-#define PIXMAN_TYPE_A	1
+#define PIXMAN_TYPE_A		1
 #define PIXMAN_TYPE_ARGB	2
 #define PIXMAN_TYPE_ABGR	3
 #define PIXMAN_TYPE_COLOR	4

commit 2e61f30e4c8d0e01e175495e13a5f132521ad6f2
Author: Søren Sandmann <sandmann@redhat.com>
Date:   Fri Jun 22 13:37:46 2007 -0400

    Revert "Add a cache of images to reduce malloc/free time"
    
    Revert the image cache since it isn't thread safe.
    
    This reverts commit deb09d769ae4fc55cde595c170f417692284b3e8.

diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index 3cc6b8d..f22d2c0 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -69,37 +69,10 @@ color_to_uint32 (const pixman_color_t *color)
 	(color->blue >> 8);
 }
 
-static pixman_image_t *image_cache;
-
-static pixman_image_t *
-new_image (void)
-{
-    pixman_image_t *image;
-
-    if (image_cache)
-    {
-	image = image_cache;
-	image_cache = image->next;
-    }
-    else
-    {
-	image = malloc (sizeof (pixman_image_t));
-    }
-
-    return image;
-}
-
-static void
-delete_image (pixman_image_t *image)
-{
-    image->next = image_cache;
-    image_cache = image;
-}
-
 static pixman_image_t *
 allocate_image (void)
 {
-    pixman_image_t *image = new_image();
+    pixman_image_t *image = malloc (sizeof (pixman_image_t));
     
     if (image)
     {
@@ -172,7 +145,7 @@ pixman_image_unref (pixman_image_t *image)
 	if (image->type == BITS && image->bits.free_me)
 	    free (image->bits.free_me);
 	
-	delete_image (image);
+	free (image);
     }
 }
 
diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h
index d10d7ad..9b89dee 100644
--- a/pixman/pixman-private.h
+++ b/pixman/pixman-private.h
@@ -260,7 +260,6 @@ union pixman_image
     conical_gradient_t		conical;
     radial_gradient_t		radial;
     solid_fill_t		solid;
-    pixman_image_t             *next;	/* Used in the image cache */
 };
 
 #define LOG2_BITMAP_PAD 5

commit 64e3146c5ddfad415663fa5f87f7b9ff327a8c56
Author: Søren Sandmann Pedersen <sandmann@redhat.com>
Date:   Fri Jun 22 00:58:05 2007 -0400

    Don't treat void as a value. Bug 11322, Alan Coopersmith.

diff --git a/pixman/pixman-compose.c b/pixman/pixman-compose.c
index 24402da..e336e04 100644
--- a/pixman/pixman-compose.c
+++ b/pixman/pixman-compose.c
@@ -4459,11 +4459,11 @@ pixman_composite_rect_general (const FbComposeData *data,
 	data->dest->common.read_func			||
 	data->dest->common.write_func)
     {
-	return pixman_composite_rect_general_accessors (data, scanline_buffer);
+	pixman_composite_rect_general_accessors (data, scanline_buffer);
     }
     else
     {
-	return pixman_composite_rect_general_no_accessors (data, scanline_buffer);
+	pixman_composite_rect_general_no_accessors (data, scanline_buffer);
     }
 }
 

commit 8216ba1cbd27c5428970b8d393722d0f4343efed
Author: Vladimir Vukicevic <vladimir@pobox.com>
Date:   Wed Jun 20 15:13:30 2007 -0400

    Add pixman_region_init_rects()

diff --git a/pixman/pixman-region.c b/pixman/pixman-region.c
index 7a0f9da..08ce2e2 100644
--- a/pixman/pixman-region.c
+++ b/pixman/pixman-region.c
@@ -2468,3 +2468,30 @@ pixman_region_selfcheck (reg)
     }
 }
 
+pixman_bool_t
+pixman_region_init_rects (pixman_region16_t *region,
+			  pixman_box16_t *boxes, int count)
+{
+    int overlap;
+
+    if (count == 1) {
+       pixman_region_init_rect(region,
+                               boxes[0].x1,
+                               boxes[0].y1,
+                               boxes[0].x2 - boxes[0].x1,
+                               boxes[0].y2 - boxes[0].y1);
+       return TRUE;
+    }
+
+    pixman_region_init(region);
+    if (!pixman_rect_alloc(region, count))
+	return FALSE;
+
+    /* Copy in the rects */
+    memcpy (PIXREGION_RECTS(region), boxes, sizeof(pixman_box16_t) * count);
+    region->data->numRects = count;
+
+    /* Validate */
+    region->extents.x1 = region->extents.x2 = 0;
+    return pixman_region_validate (region, &overlap);
+}
diff --git a/pixman/pixman.h b/pixman/pixman.h
index 0014cef..cd64c8d 100644
--- a/pixman/pixman.h
+++ b/pixman/pixman.h
@@ -288,7 +288,8 @@ pixman_bool_t		pixman_region_equal (pixman_region16_t *region1,
 					     pixman_region16_t *region2);
 pixman_bool_t		pixman_region_selfcheck (pixman_region16_t *region);
 void			pixman_region_reset(pixman_region16_t *region, pixman_box16_t *box);
-
+pixman_bool_t		pixman_region_init_rects (pixman_region16_t *region,
+						  pixman_box16_t *boxes, int count);
 
 /* Copy / Fill */
 pixman_bool_t pixman_blt (uint32_t *src_bits,

commit f1194a8bc0599e3ecceb785795ad8283a7c04dc0
Author: Søren Sandmann Pedersen <sandmann@redhat.com>
Date:   Wed Jun 20 12:12:43 2007 -0400

    Fix typo

diff --git a/pixman/pixman-pict.c b/pixman/pixman-pict.c
index dafed13..cad11dd 100644
--- a/pixman/pixman-pict.c
+++ b/pixman/pixman-pict.c
@@ -1993,7 +1993,7 @@ pixman_image_composite (pixman_op_t      op,
 		func = fbCompositeIn_8x8mmx;	    
 	    else
 #endif
-		func = fbCompositeIn_8x8;
+		func = fbCompositeSrcIn_8x8;
 	}
 	else if (srcRepeat && pMask && !pMask->common.component_alpha &&
 		 (pSrc->bits.format == PIXMAN_a8r8g8b8 ||

commit 3dbb2a56bd1918595091006c6e0de5260d43af09
Author: Alex Larsson <alexl@redhat.com>
Date:   Wed Jun 20 12:01:12 2007 -0400

    Add non-mmx fast paths for In_8x8 and In_nx8x8. Bug 4191, patch by
    Alex Larsson.

diff --git a/pixman/pixman-pict.c b/pixman/pixman-pict.c
index 8886c0c..dafed13 100644
--- a/pixman/pixman-pict.c
+++ b/pixman/pixman-pict.c
@@ -149,6 +149,135 @@ fbCompositeOver_x888x8x8888 (pixman_op_t      op,
     fbFinishAccess (pDst->pDrawable);
 }
 
+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,
@@ -1855,13 +1984,16 @@ pixman_image_composite (pixman_op_t      op,
 	}
 	break;
     case PIXMAN_OP_IN:
-#ifdef USE_MMX
 	if (pSrc->bits.format == PIXMAN_a8 &&
 	    pDst->bits.format == PIXMAN_a8 &&
 	    !pMask)
-	{
+	{	
+#ifdef USE_MMX
 	    if (pixman_have_mmx())
-		func = fbCompositeIn_8x8mmx;
+		func = fbCompositeIn_8x8mmx;	    
+	    else
+#endif
+		func = fbCompositeIn_8x8;
 	}
 	else if (srcRepeat && pMask && !pMask->common.component_alpha &&
 		 (pSrc->bits.format == PIXMAN_a8r8g8b8 ||
@@ -1869,15 +2001,14 @@ pixman_image_composite (pixman_op_t      op,
 		 (pMask->bits.format == PIXMAN_a8)        &&
 		 pDst->bits.format == PIXMAN_a8)
 	{
+#ifdef USE_MMX
 	    if (pixman_have_mmx())
-	    {
-		srcRepeat = FALSE;
 		func = fbCompositeIn_nx8x8mmx;
-	    }
-	}
-#else
-	func = NULL;
+	    else
 #endif
+		func = fbCompositeSolidMaskIn_nx8x8;
+	    srcRepeat = FALSE;
+	}
        break;
     default:
 	break;

commit 658acaad4e73ac705f705f947a42a2cd0979042c
Author: Søren Sandmann Pedersen <sandmann@redhat.com>
Date:   Wed Jun 20 11:36:22 2007 -0400

    Add fbCompositeSrc_8888xx888(); comment out
    fbCompositeOver_x888x8x8888{mmx} since they are not actually faster
    than the generic code.

diff --git a/pixman/pixman-pict.c b/pixman/pixman-pict.c
index 57bd7d6..8886c0c 100644
--- a/pixman/pixman-pict.c
+++ b/pixman/pixman-pict.c
@@ -1048,6 +1048,40 @@ fbCompositeSolidFill (pixman_op_t op,
 }
 
 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;
+    }
+    
+    fbFinishAccess(pSrc->pDrawable);
+    fbFinishAccess(pDst->pDrawable);
+}
+
+static void
 pixman_walk_composite_region (pixman_op_t op,
 			      pixman_image_t * pSrc,
 			      pixman_image_t * pMask,
@@ -1509,6 +1543,10 @@ pixman_image_composite (pixman_op_t      op,
 		}
 		else
 		{
+#if 0
+		    /* FIXME: This code is commented out since it's apparently not
+		     * actually faster than the generic code.
+		     */
 		    if (pMask->bits.format == PIXMAN_a8)
 		    {
 			if ((pSrc->bits.format == PIXMAN_x8r8g8b8 &&
@@ -1526,6 +1564,7 @@ pixman_image_composite (pixman_op_t      op,
 				func = fbCompositeOver_x888x8x8888;
 			}
 		    }
+#endif
 		}
 	    }
 	}
@@ -1804,6 +1843,15 @@ pixman_image_composite (pixman_op_t      op,
 #endif
 			;
 	    }
+	    else if (((pSrc->bits.format == PIXMAN_a8r8g8b8 ||
+		       pSrc->bits.format == PIXMAN_x8r8g8b8) &&
+		      pDst->bits.format == PIXMAN_x8r8g8b8)	||
+		     ((pSrc->bits.format == PIXMAN_a8b8g8r8 ||
+		       pSrc->bits.format == PIXMAN_x8b8g8r8) &&
+		      pDst->bits.format == PIXMAN_x8b8g8r8))
+	    {
+		func = fbCompositeSrc_8888xx888;
+	    }
 	}
 	break;
     case PIXMAN_OP_IN:

commit 440ed1da1c7ac600865c615cf257173cac2af214
Author: Søren Sandmann Pedersen <sandmann@redhat.com>
Date:   Tue Jun 19 14:41:04 2007 -0400

    Optimize pixman_fill_rectangles() in a few more cases

diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c
index bd50705..3cc6b8d 100644
--- a/pixman/pixman-image.c
+++ b/pixman/pixman-image.c
@@ -591,6 +591,47 @@ pixman_image_get_depth (pixman_image_t *image)
 }
 
 pixman_bool_t
+color_to_pixel (pixman_color_t *color,
+		uint32_t       *pixel,
+		pixman_format_code_t format)
+{
+    uint32_t c = color_to_uint32 (color);
+
+    if (!(format == PIXMAN_a8r8g8b8	||
+	  format == PIXMAN_x8r8g8b8	||
+	  format == PIXMAN_a8b8g8r8	||
+	  format == PIXMAN_x8b8g8r8	||
+	  format == PIXMAN_r5g6b5	||
+	  format == PIXMAN_b5g6r5	||
+	  format == PIXMAN_a8))
+    {
+	return FALSE;
+    }
+    
+    if (PIXMAN_FORMAT_TYPE (format) == PIXMAN_TYPE_ABGR)
+    {
+	c = ((c & 0xff000000) >>  0) |
+	    ((c & 0x00ff0000) >> 16) |
+	    ((c & 0x0000ff00) >>  0) |
+	    ((c & 0x000000ff) << 16);
+    }
+
+    if (format == PIXMAN_a8)
+	c = c >> 24;
+    else if (format == PIXMAN_r5g6b5 ||
+	     format == PIXMAN_b5g6r5)
+	c = cvt8888to0565 (c);
+
+#if 0
+    printf ("color: %x %x %x %x\n", color->alpha, color->red, color->green, color->blue);
+    printf ("pixel: %x\n", c);
+#endif
+    
+    *pixel = c;
+    return TRUE;
+}
+
+pixman_bool_t
 pixman_image_fill_rectangles (pixman_op_t		    op,
 			      pixman_image_t		   *dest,
 			      pixman_color_t		   *color,
@@ -619,6 +660,36 @@ pixman_image_fill_rectangles (pixman_op_t		    op,
 	op = PIXMAN_OP_SRC;
     }
 
+    if (op == PIXMAN_OP_SRC)
+    {
+	uint32_t pixel;
+	
+	if (color_to_pixel (color, &pixel, dest->bits.format))
+	{
+	    for (i = 0; i < n_rects; ++i)
+	    {
+		pixman_region16_t fill_region;
+		int n_boxes, j;
+		pixman_box16_t *boxes;
+		
+		pixman_region_init_rect (&fill_region, rects[i].x, rects[i].y, rects[i].width, rects[i].height);
+		pixman_region_intersect (&fill_region, &fill_region, &dest->common.clip_region);
+
+		boxes = pixman_region_rectangles (&fill_region, &n_boxes);
+		for (j = 0; j < n_boxes; ++j)
+		{
+		    const pixman_box16_t *box = &(boxes[j]);
+		    pixman_fill (dest->bits.bits, dest->bits.rowstride, PIXMAN_FORMAT_BPP (dest->bits.format),
+				 box->x1, box->y1, box->x2 - box->x1, box->y2 - box->y1,
+				 pixel);
+		}
+
+		pixman_region_fini (&fill_region);
+	    }
+	    return TRUE;
+	}
+    }
+    
     solid = pixman_image_create_solid_fill (color);
     if (!solid)
 	return FALSE;
diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c
index b15b818..aadb6e7 100644
--- a/pixman/pixman-utils.c
+++ b/pixman/pixman-utils.c
@@ -162,6 +162,11 @@ pixman_fill (uint32_t *bits,
 	     int height,
 	     uint32_t xor)
 {
+#if 0
+    printf ("filling: %d %d %d %d (stride: %d, bpp: %d)   pixel: %x\n",
+	    x, y, width, height, stride, bpp, xor);
+#endif
+    
 #ifdef USE_MMX
     if (!pixman_have_mmx() || !pixman_fill_mmx (bits, stride, bpp, x, y, width, height, xor))
 #endif

commit deb09d769ae4fc55cde595c170f417692284b3e8
Author: Søren Sandmann Pedersen <sandmann@redhat.com>
Date:   Tue Jun 19 12:41:21 2007 -0400

    Add a cache of images to reduce malloc/free time



Reply to: