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 <[EMAIL PROTECTED]>
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 <[EMAIL PROTECTED]>
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 <[EMAIL PROTECTED]>
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 <[EMAIL PROTECTED]>
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 <[EMAIL PROTECTED]>
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 <[EMAIL PROTECTED]>
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 <[EMAIL PROTECTED]>
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 <[EMAIL PROTECTED]>
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 <[EMAIL PROTECTED]>
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 <[EMAIL PROTECTED]>
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 <[EMAIL PROTECTED]>
Date:   Tue Jun 19 12:41:21 2007 -0400

    Add a cache of images to reduce malloc/free time


-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]

Reply via email to