pixman: Branch 'master' - 4 commits
Søren Sandmann Pedersen
sandmann at kemper.freedesktop.org
Sat Jun 16 12:23:46 PDT 2007
TODO | 2
pixman/pixman-compose.c | 18 ----
pixman/pixman-image.c | 10 +-
pixman/pixman-mmx.c | 193 +++++++++++++++++++++++++++++++-----------------
pixman/pixman-mmx.h | 13 +++
pixman/pixman-pict.c | 47 +++++++++--
pixman/pixman-private.h | 73 ++++++++++--------
pixman/pixman-utils.c | 14 +--
8 files changed, 238 insertions(+), 132 deletions(-)
New commits:
diff-tree b5d07147fba7085d52966aa162db5d38164dfebf (from 5122f2b28bfbf08479cc88ff9ddfeb371f92264f)
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date: Sat Jun 16 15:13:04 2007 -0400
Make fbCompositeSrc_8888x8888mmx() check if the mask is 0
diff --git a/pixman/pixman-mmx.c b/pixman/pixman-mmx.c
index c738822..41c565b 100644
--- a/pixman/pixman-mmx.c
+++ b/pixman/pixman-mmx.c
@@ -1422,17 +1422,16 @@ fbCompositeSrc_8888x8888mmx (pixman_op_t
{
uint32_t *dstLine, *dst;
uint32_t *srcLine, *src;
+ uint32_t s;
int dstStride, srcStride;
+ uint8_t a;
uint16_t w;
- __m64 srca;
CHECKPOINT();
fbComposeGetStart (pDst, xDst, yDst, uint32_t, dstStride, dstLine, 1);
fbComposeGetStart (pSrc, xSrc, ySrc, uint32_t, srcStride, srcLine, 1);
- srca = MC (4x00ff);
-
while (height--)
{
dst = dstLine;
@@ -1441,47 +1440,21 @@ fbCompositeSrc_8888x8888mmx (pixman_op_t
srcLine += srcStride;
w = width;
- while (w && (unsigned long)dst & 7)
- {
- __m64 s = load8888 (*src);
- __m64 d = load8888 (*dst);
-
- *dst = store8888 (over (s, expand_alpha (s), d));
-
- w--;
- dst++;
- src++;
- }
-
- while (w >= 2)
- {
- __m64 vd = *(__m64 *)(dst + 0);
- __m64 vs = *(__m64 *)(src + 0);
- __m64 vs0 = expand8888 (vs, 0);
- __m64 vs1 = expand8888 (vs, 1);
-
- *(__m64 *)dst = (__m64)pack8888 (
- over (vs0, expand_alpha (vs0), expand8888 (vd, 0)),
- over (vs1, expand_alpha (vs1), expand8888 (vd, 1)));
-
- w -= 2;
- dst += 2;
- src += 2;
- }
-
- while (w)
+ while (w--)
{
- __m64 s = load8888 (*src);
- __m64 d = load8888 (*dst);
-
- *dst = store8888 (over (s, expand_alpha (s), d));
-
- w--;
+ s = *src++;
+ a = s >> 24;
+ if (a == 0xff)
+ *dst = s;
+ else if (a) {
+ __m64 ms, sa;
+ ms = load8888(s);
+ sa = expand_alpha(ms);
+ *dst = store8888(over(ms, sa, load8888(*dst)));
+ }
dst++;
- src++;
}
}
-
_mm_empty();
}
diff-tree 5122f2b28bfbf08479cc88ff9ddfeb371f92264f (from 8fc40c3b0076e99cc996bd27a2479db4c94cc77b)
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date: Sat Jun 16 14:56:25 2007 -0400
Unroll loop in fbComposite_x888x8x8888()
diff --git a/pixman/pixman-mmx.c b/pixman/pixman-mmx.c
index 9ec0429..c738822 100644
--- a/pixman/pixman-mmx.c
+++ b/pixman/pixman-mmx.c
@@ -1324,23 +1324,72 @@ fbCompositeSrc_x888x8x8888mmx (pixman_op
src++;
}
- while (w >= 2)
+ while (w >= 16)
{
+ __m64 vd0 = *(__m64 *)(dst + 0);
+ __m64 vd1 = *(__m64 *)(dst + 2);
+ __m64 vd2 = *(__m64 *)(dst + 4);
+ __m64 vd3 = *(__m64 *)(dst + 6);
+ __m64 vd4 = *(__m64 *)(dst + 8);
+ __m64 vd5 = *(__m64 *)(dst + 10);
+ __m64 vd6 = *(__m64 *)(dst + 12);
+ __m64 vd7 = *(__m64 *)(dst + 14);
+
+ __m64 vs0 = *(__m64 *)(src + 0);
+ __m64 vs1 = *(__m64 *)(src + 2);
+ __m64 vs2 = *(__m64 *)(src + 4);
+ __m64 vs3 = *(__m64 *)(src + 6);
+ __m64 vs4 = *(__m64 *)(src + 8);
+ __m64 vs5 = *(__m64 *)(src + 10);
+ __m64 vs6 = *(__m64 *)(src + 12);
+ __m64 vs7 = *(__m64 *)(src + 14);
- __m64 vd0 = *(__m64 *)(dst);
- __m64 vs0 = *(__m64 *)(src);
-
vd0 = pack8888 (
- in_over_full_src_alpha (expand8888 (vs0, 0), vmask, expand8888 (vd0, 0)),
- in_over_full_src_alpha (expand8888 (vs0, 1), vmask, expand8888 (vd0, 1)));
-
- *(__m64 *)(dst) = vd0;
-
- w -= 2;
- dst += 2;
- src += 2;
+ in_over (expand8888 (vs0, 0), srca, vmask, expand8888 (vd0, 0)),
+ in_over (expand8888 (vs0, 1), srca, vmask, expand8888 (vd0, 1)));
+
+ vd1 = pack8888 (
+ in_over (expand8888 (vs1, 0), srca, vmask, expand8888 (vd1, 0)),
+ in_over (expand8888 (vs1, 1), srca, vmask, expand8888 (vd1, 1)));
+
+ vd2 = pack8888 (
+ in_over (expand8888 (vs2, 0), srca, vmask, expand8888 (vd2, 0)),
+ in_over (expand8888 (vs2, 1), srca, vmask, expand8888 (vd2, 1)));
+
+ vd3 = pack8888 (
+ in_over (expand8888 (vs3, 0), srca, vmask, expand8888 (vd3, 0)),
+ in_over (expand8888 (vs3, 1), srca, vmask, expand8888 (vd3, 1)));
+
+ vd4 = pack8888 (
+ in_over (expand8888 (vs4, 0), srca, vmask, expand8888 (vd4, 0)),
+ in_over (expand8888 (vs4, 1), srca, vmask, expand8888 (vd4, 1)));
+
+ vd5 = pack8888 (
+ in_over (expand8888 (vs5, 0), srca, vmask, expand8888 (vd5, 0)),
+ in_over (expand8888 (vs5, 1), srca, vmask, expand8888 (vd5, 1)));
+
+ vd6 = pack8888 (
+ in_over (expand8888 (vs6, 0), srca, vmask, expand8888 (vd6, 0)),
+ in_over (expand8888 (vs6, 1), srca, vmask, expand8888 (vd6, 1)));
+
+ vd7 = pack8888 (
+ in_over (expand8888 (vs7, 0), srca, vmask, expand8888 (vd7, 0)),
+ in_over (expand8888 (vs7, 1), srca, vmask, expand8888 (vd7, 1)));
+
+ *(__m64 *)(dst + 0) = vd0;
+ *(__m64 *)(dst + 2) = vd1;
+ *(__m64 *)(dst + 4) = vd2;
+ *(__m64 *)(dst + 6) = vd3;
+ *(__m64 *)(dst + 8) = vd4;
+ *(__m64 *)(dst + 10) = vd5;
+ *(__m64 *)(dst + 12) = vd6;
+ *(__m64 *)(dst + 14) = vd7;
+
+ w -= 16;
+ dst += 16;
+ src += 16;
}
-
+
while (w)
{
__m64 s = load8888 (*src | 0xff000000);
diff-tree 8fc40c3b0076e99cc996bd27a2479db4c94cc77b (from 15e5cf16a9770da682addeaff5df8b1793cf4b73)
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date: Sat Jun 16 14:49:11 2007 -0400
Optimize 1x1 repeating images in the general case
Reinstate checks for empty masks in mmxCombineOverU() and mmxCombineMaskU()
diff --git a/pixman/pixman-mmx.c b/pixman/pixman-mmx.c
index bda9bf4..9ec0429 100644
--- a/pixman/pixman-mmx.c
+++ b/pixman/pixman-mmx.c
@@ -431,13 +431,19 @@ mmxCombineMaskU (uint32_t *src, const ui
{
const uint32_t *end = mask + width;
while (mask < end) {
- __m64 a = load8888(*mask);
- __m64 s = load8888(*src);
- a = expand_alpha(a);
- s = pix_multiply(s, a);
- *src = store8888(s);
- ++src;
- ++mask;
+ uint32_t mmask = *mask;
+ uint32_t maska = mmask >> 24;
+ if (maska == 0) {
+ *src = 0;
+ } else if (maska != 0xff) {
+ __m64 a = load8888(mmask);
+ __m64 s = load8888(*src);
+ a = expand_alpha(a);
+ s = pix_multiply(s, a);
+ *src = store8888(s);
+ }
+ ++src;
+ ++mask;
}
_mm_empty();
}
@@ -447,14 +453,20 @@ static FASTCALL void
mmxCombineOverU (uint32_t *dest, const uint32_t *src, int width)
{
const uint32_t *end = dest + width;
-
+
while (dest < end) {
- __m64 s, sa;
- s = load8888(*src);
- sa = expand_alpha(s);
- *dest = store8888(over(s, sa, load8888(*dest)));
- ++dest;
- ++src;
+ uint32_t ssrc = *src;
+ uint32_t a = ssrc >> 24;
+ if (a == 0xff) {
+ *dest = ssrc;
+ } else if (a) {
+ __m64 s, sa;
+ s = load8888(ssrc);
+ sa = expand_alpha(s);
+ *dest = store8888(over(s, sa, load8888(*dest)));
+ }
+ ++dest;
+ ++src;
}
_mm_empty();
}
diff --git a/pixman/pixman-pict.c b/pixman/pixman-pict.c
index 8b72ffb..f444713 100644
--- a/pixman/pixman-pict.c
+++ b/pixman/pixman-pict.c
@@ -1703,6 +1703,25 @@ pixman_image_composite (pixman_op_t
if (!func) {
func = pixman_image_composite_rect;
+
+ /* CompositeGeneral optimizes 1x1 repeating images itself */
+ if (pSrc->type == BITS)
+ {
+ srcRepeat =
+ pSrc->common.repeat == PIXMAN_REPEAT_NORMAL &&
+ !pSrc->common.transform &&
+ pSrc->bits.width != 1 &&
+ pSrc->bits.height != 1;
+ }
+
+ if (pMask && pMask->type == BITS)
+ {
+ maskRepeat =
+ pMask->common.repeat == PIXMAN_REPEAT_NORMAL &&
+ !pMask->common.transform &&
+ pMask->bits.width != 1 &&
+ pMask->bits.height != 1;
+ }
}
/* if we are transforming, we handle repeats in fbFetchTransformed */
diff-tree 15e5cf16a9770da682addeaff5df8b1793cf4b73 (from 10854b9d63afe6893ac15fb67714eb98b7a8eca6)
Author: Søren Sandmann Pedersen <sandmann at redhat.com>
Date: Sat Jun 16 12:55:59 2007 -0400
Add a few optimizations for solid fills
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
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
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_
{
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_
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
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_
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
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
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
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
break;
}
break;
- default:
- break;
}
}
else if (! srcRepeat)
@@ -1602,9 +1603,7 @@ pixman_image_composite (pixman_op_t
}
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
}
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 FbCompos
#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 FbCompos
(((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())
More information about the xorg-commit
mailing list