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]