From 3dca89a677528845ccaee7ff6d355207c631ddd2 Mon Sep 17 00:00:00 2001 From: =?utf8?q?S=C3=B8ren=20Sandmann=20Pedersen?= Date: Mon, 11 Jun 2007 21:35:14 -0400 Subject: [PATCH] Add pixman_fill_mmx() function --- pixman/pixman-mmx.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++ pixman/pixman-mmx.h | 20 ++++++++ pixman/pixman-utils.c | 22 +++++++++ pixman/pixman.h | 9 +++- 4 files changed, 177 insertions(+), 1 deletion(-) diff --git a/pixman/pixman-mmx.c b/pixman/pixman-mmx.c index 3986cc8..84f440d 100644 --- a/pixman/pixman-mmx.c +++ b/pixman/pixman-mmx.c @@ -1640,6 +1640,133 @@ fbCompositeSolidMask_nx8x8888mmx (pixman_op_t op, _mm_empty(); } +pixman_bool_t +pixman_fill_mmx (uint32_t *bits, + int stride, + int bpp, + int x, + int y, + int width, + int height, + uint32_t xor) +{ + ullong fill; + __m64 vfill; + uint32_t byte_width; + uint8_t *byte_line; +#ifdef __GNUC__ + __m64 v1, v2, v3, v4, v5, v6, v7; +#endif + + if (bpp == 16 && (xor >> 16 != (xor & 0xffff))) + return FALSE; + + if (bpp != 16 && bpp != 32) + return FALSE; + + if (bpp == 16) + { + stride = stride * sizeof (uint32_t) / 2; + byte_line = (uint8_t *)(((uint16_t *)bits) + stride * y + x); + byte_width = 2 * width; + stride *= 2; + } + else + { + stride = stride * sizeof (uint32_t) / 4; + byte_line = (uint8_t *)(((uint32_t *)bits) + stride * y + x); + byte_width = 4 * width; + stride *= 4; + } + + fill = ((ullong)xor << 32) | xor; + vfill = (__m64)fill; + +#ifdef __GNUC__ + __asm__ ( + "movq %7, %0\n" + "movq %7, %1\n" + "movq %7, %2\n" + "movq %7, %3\n" + "movq %7, %4\n" + "movq %7, %5\n" + "movq %7, %6\n" + : "=y" (v1), "=y" (v2), "=y" (v3), + "=y" (v4), "=y" (v5), "=y" (v6), "=y" (v7) + : "y" (vfill)); +#endif + + while (height--) + { + int w; + uint8_t *d = byte_line; + byte_line += stride; + w = byte_width; + + while (w >= 2 && ((unsigned long)d & 3)) + { + *(uint16_t *)d = xor; + w -= 2; + d += 2; + } + + while (w >= 4 && ((unsigned long)d & 7)) + { + *(uint32_t *)d = xor; + + w -= 4; + d += 4; + } + + while (w >= 64) + { +#ifdef __GNUC__ + __asm__ ( + "movq %1, (%0)\n" + "movq %2, 8(%0)\n" + "movq %3, 16(%0)\n" + "movq %4, 24(%0)\n" + "movq %5, 32(%0)\n" + "movq %6, 40(%0)\n" + "movq %7, 48(%0)\n" + "movq %8, 56(%0)\n" + : + : "r" (d), + "y" (vfill), "y" (v1), "y" (v2), "y" (v3), + "y" (v4), "y" (v5), "y" (v6), "y" (v7) + : "memory"); +#else + *(__m64*) (d + 0) = vfill; + *(__m64*) (d + 8) = vfill; + *(__m64*) (d + 16) = vfill; + *(__m64*) (d + 24) = vfill; + *(__m64*) (d + 32) = vfill; + *(__m64*) (d + 40) = vfill; + *(__m64*) (d + 48) = vfill; + *(__m64*) (d + 56) = vfill; +#endif + w -= 64; + d += 64; + } + + while (w >= 4) + { + *(uint32_t *)d = xor; + + w -= 4; + d += 4; + } + if (w >= 2) + { + *(uint16_t *)d = xor; + w -= 2; + d += 2; + } + } + + _mm_empty(); + return TRUE; +} #if 0 /* FIXME */ diff --git a/pixman/pixman-mmx.h b/pixman/pixman-mmx.h index 9ea2ad7..be8af88 100644 --- a/pixman/pixman-mmx.h +++ b/pixman/pixman-mmx.h @@ -46,6 +46,26 @@ pixman_bool_t pixman_have_mmx(void); #ifdef USE_MMX +pixman_bool_t +pixman_blt_mmx (uint32_t *src_bits, + uint32_t *dst_bits, + int src_stride, + int dst_stride, + int src_bpp, + int dst_bpp, + int src_x, int src_y, + int dst_x, int dst_y, + int width, int height); +pixman_bool_t +pixman_fill_mmx (uint32_t *bits, + int stride, + int bpp, + int x, + int y, + int width, + int height, + uint32_t xor); + void fbComposeSetupMMX(void); void fbCompositeSolidMask_nx8888x0565Cmmx (pixman_op_t op, diff --git a/pixman/pixman-utils.c b/pixman/pixman-utils.c index ab6a1cd..4ac30aa 100644 --- a/pixman/pixman-utils.c +++ b/pixman/pixman-utils.c @@ -24,6 +24,7 @@ #include #include "pixman.h" #include "pixman-private.h" +#include "pixman-mmx.h" pixman_bool_t pixman_transform_point_3d (pixman_transform_t *transform, @@ -78,3 +79,24 @@ pixman_blt (uint32_t *src_bits, #endif return FALSE; } + +pixman_bool_t +pixman_fill (uint32_t *bits, + int stride, + int bpp, + int x, + int y, + int width, + int height, + uint32_t xor) +{ +#ifdef USE_MMX + if (pixman_have_mmx()) + { + return pixman_fill_mmx (bits, stride, bpp, x, y, width, height, xor); + } + else +#endif + return FALSE; +} + diff --git a/pixman/pixman.h b/pixman/pixman.h index 0421723..277fc0f 100644 --- a/pixman/pixman.h +++ b/pixman/pixman.h @@ -300,7 +300,14 @@ pixman_bool_t pixman_blt (uint32_t *src_bits, int src_x, int src_y, int dst_x, int dst_y, int width, int height); - +pixman_bool_t pixman_fill (uint32_t *bits, + int stride, + int bpp, + int x, + int y, + int width, + int height, + uint32_t xor); /* * Images */ -- 2.7.4