From 15e5cf16a9770da682addeaff5df8b1793cf4b73 Mon Sep 17 00:00:00 2001 From: =?utf8?q?S=C3=B8ren=20Sandmann=20Pedersen?= Date: Sat, 16 Jun 2007 12:55:59 -0400 Subject: [PATCH] Add a few optimizations for solid fills --- TODO | 2 ++ pixman/pixman-compose.c | 18 ++---------- pixman/pixman-image.c | 10 +++++-- pixman/pixman-mmx.c | 25 +++++++++++++++++ pixman/pixman-mmx.h | 13 +++++++++ pixman/pixman-pict.c | 28 ++++++++++++------- pixman/pixman-private.h | 73 ++++++++++++++++++++++++++++--------------------- pixman/pixman-utils.c | 14 +++++----- 8 files changed, 118 insertions(+), 65 deletions(-) diff --git a/TODO b/TODO index 9423dd9..7bbb7d0 100644 --- a/TODO +++ b/TODO @@ -30,6 +30,8 @@ - done: source clipping happens through an indirection. still needs to make the indirection settable. +- Add non-mmx solid fill + done: - Make sure the endian-ness macros are defined correctly. diff --git a/pixman/pixman-compose.c b/pixman/pixman-compose.c index d761e8f..bff67f0 100644 --- a/pixman/pixman-compose.c +++ b/pixman/pixman-compose.c @@ -4328,6 +4328,9 @@ pixmanCompositeRect (const FbComposeData *data, uint32_t *scanline_buffer) if (IS_SOURCE_IMAGE (data->mask)) { fetchMask = (scanFetchProc)pixmanFetchSourcePict; + maskClass = SourcePictureClassify ((source_image_t *)data->mask, + data->xMask, data->yMask, + data->width, data->height); } else { @@ -4336,21 +4339,6 @@ pixmanCompositeRect (const FbComposeData *data, uint32_t *scanline_buffer) if (bits->common.alpha_map) { fetchMask = (scanFetchProc)fbFetchExternalAlpha; - /* FIXME: this looks highly suspicious. Why would we - * expect the mask to be a source picture here? In fact - * we _know_ it's not a source picture. - * - * That's why it's commented out. This will result in - * the classification of "unknown" which should be - * correct. - * - * It looks like it belongs in the IS_SOURCE_IMAGE() clause - */ -#if 0 - maskClass = SourcePictureClassify (data->mask, - data->xMask, data->yMask, - data->width, data->height); -#endif } else if (bits->common.repeat == PIXMAN_REPEAT_NORMAL && bits->width == 1 && bits->height == 1) diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c index 2211677..d54e438 100644 --- a/pixman/pixman-image.c +++ b/pixman/pixman-image.c @@ -572,10 +572,16 @@ pixman_image_fill_rectangles (pixman_op_t op, { pixman_image_t *solid = pixman_image_create_solid_fill (color); int i; - + if (!solid) return FALSE; + if (color->alpha == 0xffff) + { + if (op == PIXMAN_OP_OVER) + op = PIXMAN_OP_SRC; + } + for (i = 0; i < n_rects; ++i) { const pixman_rectangle16_t *rect = &(rects[i]); @@ -585,7 +591,7 @@ pixman_image_fill_rectangles (pixman_op_t op, rect->x, rect->y, rect->width, rect->height); } - + pixman_image_unref (solid); return TRUE; diff --git a/pixman/pixman-mmx.c b/pixman/pixman-mmx.c index ba2b873..bda9bf4 100644 --- a/pixman/pixman-mmx.c +++ b/pixman/pixman-mmx.c @@ -2850,6 +2850,31 @@ pixman_blt_mmx (uint32_t *src_bits, } void +fbCompositeSolidFillmmx (pixman_op_t op, + pixman_image_t * pSrc, + pixman_image_t * pMask, + pixman_image_t * pDst, + int16_t xSrc, + int16_t ySrc, + int16_t xMask, + int16_t yMask, + int16_t xDst, + int16_t yDst, + uint16_t width, + uint16_t height) +{ + uint32_t src; + + fbComposeGetSolid(pSrc, src, pDst->bits.format); + + pixman_fill_mmx (pDst->bits.bits, pDst->bits.rowstride, + PIXMAN_FORMAT_BPP (pDst->bits.format), + xDst, yDst, + width, height, + src); +} + +void fbCompositeCopyAreammx (pixman_op_t op, pixman_image_t * pSrc, pixman_image_t * pMask, diff --git a/pixman/pixman-mmx.h b/pixman/pixman-mmx.h index 4b9e823..6b86fdc 100644 --- a/pixman/pixman-mmx.h +++ b/pixman/pixman-mmx.h @@ -298,5 +298,18 @@ void fbCompositeCopyAreammx (pixman_op_t op, int16_t yDst, uint16_t width, uint16_t height); +void +fbCompositeSolidFillmmx (pixman_op_t op, + pixman_image_t * pSrc, + pixman_image_t * pMask, + pixman_image_t * pDst, + int16_t xSrc, + int16_t ySrc, + int16_t xMask, + int16_t yMask, + int16_t xDst, + int16_t yDst, + uint16_t width, + uint16_t height); #endif /* USE_MMX */ diff --git a/pixman/pixman-pict.c b/pixman/pixman-pict.c index 741ede6..8b72ffb 100644 --- a/pixman/pixman-pict.c +++ b/pixman/pixman-pict.c @@ -1037,6 +1037,9 @@ pixman_walk_composite_region (pixman_op_t op, static pixman_bool_t can_get_solid (pixman_image_t *image) { + if (image->type == SOLID) + return TRUE; + if (image->type != BITS || image->bits.width != 1 || image->bits.height != 1) @@ -1165,7 +1168,7 @@ pixman_image_composite (pixman_op_t op, maskTransform = FALSE; } - if (pSrc->type == BITS && (!pMask || pMask->type == BITS) + if ((pSrc->type == BITS || can_get_solid (pSrc)) && (!pMask || pMask->type == BITS) && !srcTransform && !maskTransform && !maskAlphaMap && !srcAlphaMap && !dstAlphaMap && (pSrc->common.filter != PIXMAN_FILTER_CONVOLUTION) @@ -1180,7 +1183,7 @@ pixman_image_composite (pixman_op_t op, if (can_get_solid(pSrc) && !maskRepeat) { - if (PIXMAN_FORMAT_COLOR(pSrc->bits.format)) { + if (pSrc->type == SOLID || PIXMAN_FORMAT_COLOR(pSrc->bits.format)) { switch (pMask->bits.format) { case PIXMAN_a8: switch (pDst->bits.format) { @@ -1405,8 +1408,8 @@ pixman_image_composite (pixman_op_t op, if (can_get_solid(pSrc)) { /* no mask and repeating source */ - switch (pSrc->bits.format) { - case PIXMAN_a8r8g8b8: + if (pSrc->type == SOLID || pSrc->bits.format == PIXMAN_a8r8g8b8) + { switch (pDst->bits.format) { case PIXMAN_a8r8g8b8: case PIXMAN_x8r8g8b8: @@ -1431,8 +1434,6 @@ pixman_image_composite (pixman_op_t op, break; } break; - default: - break; } } else if (! srcRepeat) @@ -1602,9 +1603,7 @@ pixman_image_composite (pixman_op_t op, } else { - if ((pSrc->bits.format == PIXMAN_a8r8g8b8 || - pSrc->bits.format == PIXMAN_a8b8g8r8) && - can_get_solid (pSrc) && + if (can_get_solid (pSrc) && pMask->bits.format == PIXMAN_a8 && pDst->bits.format == PIXMAN_a8) { @@ -1647,7 +1646,16 @@ pixman_image_composite (pixman_op_t op, } else { - if (pSrc->bits.format == pDst->bits.format) + if (can_get_solid (pSrc)) + { + if (PIXMAN_FORMAT_BPP (pDst->bits.format) == 16 || + PIXMAN_FORMAT_BPP (pDst->bits.format) == 32) + { + func = fbCompositeSolidFillmmx; + srcRepeat = FALSE; + } + } + else if (pSrc->bits.format == pDst->bits.format) { #ifdef USE_MMX if (pSrc->bits.bits != pDst->bits.bits && pixman_have_mmx() && diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h index db5597b..0dda1a6 100644 --- a/pixman/pixman-private.h +++ b/pixman/pixman-private.h @@ -179,7 +179,7 @@ struct image_common struct source_image { image_common_t common; - unsigned int class; /* FIXME: should be an enum */ + source_pict_class_t class; }; struct solid_fill @@ -643,32 +643,46 @@ void pixmanCompositeRect (const FbComposeData *data, #define fbFinishAccess(x) -#define fbComposeGetSolid(img, res, fmt) do { \ - uint32_t *bits__ = (img)->bits.bits; \ - pixman_format_code_t format__ = (img)->bits.format; \ - \ - switch (PIXMAN_FORMAT_BPP((img)->bits.format)) \ +#define fbComposeGetSolid(img, res, fmt) \ + do \ + { \ + pixman_format_code_t format__; \ + if (img->type == SOLID) \ { \ - case 32: \ - (res) = READ((uint32_t *)bits__); \ - break; \ - case 24: \ - (res) = Fetch24 ((uint8_t *) bits__); \ - break; \ - case 16: \ - (res) = READ((uint16_t *) bits__); \ - (res) = cvt0565to0888(res); \ - break; \ - case 8: \ - (res) = READ((uint8_t *) bits__); \ - (res) = (res) << 24; \ - break; \ - case 1: \ - (res) = READ((uint32_t *) bits__); \ - (res) = FbLeftStipBits((res),1) ? 0xff000000 : 0x00000000; \ - break; \ - default: \ - return; \ + format__ = PIXMAN_a8r8g8b8; \ + (res) = img->solid.color; \ + } \ + else \ + { \ + uint32_t *bits__ = (img)->bits.bits; \ + format__ = (img)->bits.format; \ + \ + switch (PIXMAN_FORMAT_BPP((img)->bits.format)) \ + { \ + case 32: \ + (res) = READ((uint32_t *)bits__); \ + break; \ + case 24: \ + (res) = Fetch24 ((uint8_t *) bits__); \ + break; \ + case 16: \ + (res) = READ((uint16_t *) bits__); \ + (res) = cvt0565to0888(res); \ + break; \ + case 8: \ + (res) = READ((uint8_t *) bits__); \ + (res) = (res) << 24; \ + break; \ + case 1: \ + (res) = READ((uint32_t *) bits__); \ + (res) = FbLeftStipBits((res),1) ? 0xff000000 : 0x00000000; \ + break; \ + default: \ + return; \ + } \ + /* manage missing src alpha */ \ + if (!PIXMAN_FORMAT_A((img)->bits.format)) \ + (res) |= 0xff000000; \ } \ /* If necessary, convert RGB <--> BGR. */ \ if (PIXMAN_FORMAT_TYPE (format__) != PIXMAN_FORMAT_TYPE(fmt)) \ @@ -678,11 +692,8 @@ void pixmanCompositeRect (const FbComposeData *data, (((res) & 0x0000ff00) >> 0) | \ (((res) & 0x000000ff) << 16)); \ } \ - /* manage missing src alpha */ \ - if (!PIXMAN_FORMAT_A((img)->bits.format)) \ - (res) |= 0xff000000; \ - } while (0) - + } \ + while (0) #define fbComposeGetStart(pict,x,y,type,out_stride,line,mul) do { \ uint32_t *__bits__; \ diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c index 4ac30aa..9d611e9 100644 --- a/pixman/pixman-utils.c +++ b/pixman/pixman-utils.c @@ -82,13 +82,13 @@ pixman_blt (uint32_t *src_bits, pixman_bool_t pixman_fill (uint32_t *bits, - int stride, - int bpp, - int x, - int y, - int width, - int height, - uint32_t xor) + int stride, + int bpp, + int x, + int y, + int width, + int height, + uint32_t xor) { #ifdef USE_MMX if (pixman_have_mmx()) -- 2.7.4