summaryrefslogtreecommitdiff
path: root/fb
diff options
context:
space:
mode:
Diffstat (limited to 'fb')
-rw-r--r--fb/fbcompose.c17
-rw-r--r--fb/fbcopy.c38
-rw-r--r--fb/fbmmx.c274
-rw-r--r--fb/fbmmx.h32
-rw-r--r--fb/fbpict.c28
5 files changed, 378 insertions, 11 deletions
diff --git a/fb/fbcompose.c b/fb/fbcompose.c
index 53872808f..a57e7729f 100644
--- a/fb/fbcompose.c
+++ b/fb/fbcompose.c
@@ -2693,7 +2693,6 @@ fbSet_transform (FbCompositeOperand *op, int x, int y)
op->u.transform.y = y - op->u.transform.top_y;
}
-
Bool
fbBuildCompositeOperand (PicturePtr pPict,
FbCompositeOperand op[4],
@@ -2710,7 +2709,6 @@ fbBuildCompositeOperand (PicturePtr pPict,
op->u.transform.top_y = pPict->pDrawable->y;
op->u.transform.left_x = pPict->pDrawable->x;
-
op->u.transform.start_x = x - op->u.transform.left_x;
op->u.transform.x = op->u.transform.start_x;
op->u.transform.y = y - op->u.transform.top_y;
@@ -2822,6 +2820,21 @@ fbCompositeGeneral (CARD8 op,
FbCombineFunc f;
int w;
+#if 0
+ ErrorF ("op: %d\n"
+ "src format: %lx\n"
+ "msk format %lx\n"
+ "dst format %lx\n"
+ "width: %d\n"
+ "height %d\n",
+ op,
+ pSrc? pSrc->format : 0,
+ pMask? pMask->format : 0,
+ pDst? pDst->format : 0,
+ width, height);
+ ErrorF ("PICT_x8r8g8b8: %lx\n", PICT_x8r8g8b8);
+#endif
+
if (!fbBuildCompositeOperand (pSrc, src, xSrc, ySrc, TRUE, TRUE))
return;
if (!fbBuildCompositeOperand (pDst, dst, xDst, yDst, FALSE, TRUE))
diff --git a/fb/fbcopy.c b/fb/fbcopy.c
index 940f11d73..9adccd71b 100644
--- a/fb/fbcopy.c
+++ b/fb/fbcopy.c
@@ -27,6 +27,7 @@
#ifdef IN_MODULE
#include "xf86_ansic.h"
#endif
+#include "fbmmx.h"
void
fbCopyNtoN (DrawablePtr pSrcDrawable,
@@ -54,28 +55,51 @@ fbCopyNtoN (DrawablePtr pSrcDrawable,
fbGetDrawable (pSrcDrawable, src, srcStride, srcBpp, srcXoff, srcYoff);
fbGetDrawable (pDstDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
-
+
while (nbox--)
{
+#ifdef USE_MMX
+ if (!reverse && !upsidedown && fbHaveMMX())
+ {
+ if (!fbCopyAreammx (pSrcDrawable,
+ pDstDrawable,
+
+ (pbox->x1 + dx + srcXoff),
+ (pbox->y1 + dy + srcYoff),
+
+ (pbox->x1 + dstXoff),
+ (pbox->y1 + dstYoff),
+
+ (pbox->x2 - pbox->x1),
+ (pbox->y2 - pbox->y1)))
+ goto fallback;
+ else
+ goto next;
+ }
+ fallback:
+#endif
fbBlt (src + (pbox->y1 + dy + srcYoff) * srcStride,
srcStride,
(pbox->x1 + dx + srcXoff) * srcBpp,
-
+
dst + (pbox->y1 + dstYoff) * dstStride,
dstStride,
(pbox->x1 + dstXoff) * dstBpp,
-
+
(pbox->x2 - pbox->x1) * dstBpp,
(pbox->y2 - pbox->y1),
-
+
alu,
pm,
dstBpp,
-
+
reverse,
upsidedown);
+#ifdef USE_MMX
+ next:
+#endif
pbox++;
- }
+ }
}
void
@@ -594,7 +618,7 @@ fbCopyArea (DrawablePtr pSrcDrawable,
int yOut)
{
fbCopyProc copy;
-
+
#ifdef FB_24_32BIT
if (pSrcDrawable->bitsPerPixel != pDstDrawable->bitsPerPixel)
copy = fb24_32CopyMtoN;
diff --git a/fb/fbmmx.c b/fb/fbmmx.c
index 76ee39bc1..39310cd0a 100644
--- a/fb/fbmmx.c
+++ b/fb/fbmmx.c
@@ -283,12 +283,13 @@ static __inline__ __m64
expand565 (__m64 pixel, int pos)
{
__m64 p = pixel;
+ __m64 t1, t2;
/* move pixel to low 16 bit and zero the rest */
p = shift (shift (p, (3 - pos) * 16), -48);
- __m64 t1 = shift (p, 36 - 11);
- __m64 t2 = shift (p, 16 - 5);
+ t1 = shift (p, 36 - 11);
+ t2 = shift (p, 16 - 5);
p = _mm_or_si64 (t1, p);
p = _mm_or_si64 (t2, p);
@@ -605,6 +606,132 @@ fbCompositeSolidMask_nx8888x8888Cmmx (CARD8 op,
}
void
+fbCompositeSrc_8888x8x8888mmx (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ CARD32 *dstLine, *dst;
+ CARD32 *srcLine, *src;
+ CARD8 *maskLine;
+ CARD32 mask;
+ __m64 vmask;
+ FbStride dstStride, srcStride, maskStride;
+ CARD16 w;
+ __m64 srca;
+
+ CHECKPOINT();
+
+ fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1);
+ fbComposeGetStart (pSrc, xSrc, ySrc, CARD32, srcStride, srcLine, 1);
+ fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);
+
+ mask = *maskLine << 24 | *maskLine << 16 | *maskLine << 8 | *maskLine;
+ vmask = load8888 (mask);
+ srca = MC(4x00ff);
+
+ while (height--)
+ {
+ dst = dstLine;
+ dstLine += dstStride;
+ src = srcLine;
+ srcLine += srcStride;
+ w = width;
+
+ while (w && (unsigned long)dst & 7)
+ {
+ __m64 s = load8888 (*src);
+ __m64 d = load8888 (*dst);
+
+ *dst = (ullong)pack8888 (in_over (s, srca, vmask, d), (__m64)_mm_setzero_si64());
+
+ w--;
+ dst++;
+ src++;
+ }
+
+ 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 *)(dst + 14);
+
+ vd0 = (__m64)pack8888 (
+ in_over (expand8888 (vs0, 0), srca, vmask, expand8888 (vd0, 0)),
+ in_over (expand8888 (vs0, 1), srca, vmask, expand8888 (vd0, 1)));
+
+ vd1 = (__m64)pack8888 (
+ in_over (expand8888 (vs1, 0), srca, vmask, expand8888 (vd1, 0)),
+ in_over (expand8888 (vs1, 1), srca, vmask, expand8888 (vd1, 1)));
+
+ vd2 = (__m64)pack8888 (
+ in_over (expand8888 (vs2, 0), srca, vmask, expand8888 (vd2, 0)),
+ in_over (expand8888 (vs2, 1), srca, vmask, expand8888 (vd2, 1)));
+
+ vd3 = (__m64)pack8888 (
+ in_over (expand8888 (vs3, 0), srca, vmask, expand8888 (vd3, 0)),
+ in_over (expand8888 (vs3, 1), srca, vmask, expand8888 (vd3, 1)));
+
+ vd4 = (__m64)pack8888 (
+ in_over (expand8888 (vs4, 0), srca, vmask, expand8888 (vd4, 0)),
+ in_over (expand8888 (vs4, 1), srca, vmask, expand8888 (vd4, 1)));
+
+ vd5 = (__m64)pack8888 (
+ in_over (expand8888 (vs5, 0), srca, vmask, expand8888 (vd5, 0)),
+ in_over (expand8888 (vs5, 1), srca, vmask, expand8888 (vd5, 1)));
+
+ vd6 = (__m64)pack8888 (
+ in_over (expand8888 (vs6, 0), srca, vmask, expand8888 (vd6, 0)),
+ in_over (expand8888 (vs6, 1), srca, vmask, expand8888 (vd6, 1)));
+
+ vd7 = (__m64)pack8888 (
+ in_over (expand8888 (vs7, 0), srca, vmask, expand8888 (vd7, 0)),
+ in_over (expand8888 (vs7, 1), srca, vmask, expand8888 (vd7, 1)));
+
+ w -= 16;
+ dst += 16;
+ src += 16;
+ }
+
+ while (w)
+ {
+ __m64 s = load8888 (*src);
+ __m64 d = load8888 (*dst);
+
+ *dst = (ullong)pack8888 (in_over (s, srca, vmask, d), (__m64)_mm_setzero_si64());
+
+ w--;
+ dst++;
+ src++;
+ }
+ }
+
+ _mm_empty();
+}
+
+void
fbCompositeSolidMask_nx8x8888mmx (CARD8 op,
PicturePtr pSrc,
PicturePtr pMask,
@@ -1412,6 +1539,149 @@ fbSolidFillmmx (DrawablePtr pDraw,
return TRUE;
}
+Bool
+fbCopyAreammx (DrawablePtr pSrc,
+ DrawablePtr pDst,
+ int src_x,
+ int src_y,
+ int dst_x,
+ int dst_y,
+ int width,
+ int height)
+{
+ FbBits * src_bits;
+ FbStride src_stride;
+ int src_bpp;
+ int src_xoff;
+ int src_yoff;
+
+ FbBits * dst_bits;
+ FbStride dst_stride;
+ int dst_bpp;
+ int dst_xoff;
+ int dst_yoff;
+
+ CARD8 * src_bytes;
+ CARD8 * dst_bytes;
+ int byte_width;
+
+ fbGetDrawable(pSrc, src_bits, src_stride, src_bpp, src_xoff, src_yoff);
+ fbGetDrawable(pDst, dst_bits, dst_stride, dst_bpp, dst_xoff, dst_yoff);
+
+ if (src_bpp != 16 && src_bpp != 32)
+ return FALSE;
+
+ if (dst_bpp != 16 && dst_bpp != 32)
+ return FALSE;
+
+ if (src_bpp != dst_bpp)
+ {
+ return FALSE;
+ }
+
+ if (src_bpp == 16)
+ {
+ src_stride = src_stride * sizeof (FbBits) / 2;
+ dst_stride = dst_stride * sizeof (FbBits) / 2;
+ src_bytes = (CARD8 *)(((CARD16 *)src_bits) + src_stride * (src_y - src_yoff) + (src_x - src_xoff));
+ dst_bytes = (CARD8 *)(((CARD16 *)dst_bits) + dst_stride * (dst_y - dst_yoff) + (dst_x - dst_xoff));
+ byte_width = 2 * width;
+ src_stride *= 2;
+ dst_stride *= 2;
+ }
+ else
+ {
+ src_stride = src_stride * sizeof (FbBits) / 4;
+ dst_stride = dst_stride * sizeof (FbBits) / 4;
+ src_bytes = (CARD8 *)(((CARD32 *)src_bits) + src_stride * (src_y - src_yoff) + (src_x - src_xoff));
+ dst_bytes = (CARD8 *)(((CARD32 *)dst_bits) + dst_stride * (dst_y - dst_yoff) + (dst_x - dst_xoff));
+ byte_width = 4 * width;
+ src_stride *= 4;
+ dst_stride *= 4;
+ }
+
+ while (height--)
+ {
+ int w;
+ CARD8 *s = src_bytes;
+ CARD8 *d = dst_bytes;
+ src_bytes += src_stride;
+ dst_bytes += dst_stride;
+ w = byte_width;
+
+ while (w >= 2 && ((unsigned long)d & 3))
+ {
+ *(CARD16 *)d = *(CARD16 *)s;
+ w -= 2;
+ s += 2;
+ d += 2;
+ }
+
+ while (w >= 4 && ((unsigned int)d & 7))
+ {
+ *(CARD32 *)d = *(CARD32 *)s;
+
+ w -= 4;
+ s += 4;
+ d += 4;
+ }
+
+ while (w >= 64)
+ {
+ *(__m64 *)(d + 0) = *(__m64 *)(s + 0);
+ *(__m64 *)(d + 8) = *(__m64 *)(s + 8);
+ *(__m64 *)(d + 16) = *(__m64 *)(s + 16);
+ *(__m64 *)(d + 24) = *(__m64 *)(s + 24);
+ *(__m64 *)(d + 32) = *(__m64 *)(s + 32);
+ *(__m64 *)(d + 40) = *(__m64 *)(s + 40);
+ *(__m64 *)(d + 48) = *(__m64 *)(s + 48);
+ *(__m64 *)(d + 56) = *(__m64 *)(s + 56);
+ w -= 64;
+ s += 64;
+ d += 64;
+ }
+ while (w >= 4)
+ {
+ *(CARD32 *)d = *(CARD32 *)s;
+
+ w -= 4;
+ s += 4;
+ d += 4;
+ }
+ if (w >= 2)
+ {
+ *(CARD16 *)d = *(CARD16 *)s;
+ w -= 2;
+ s += 2;
+ d += 2;
+ }
+ }
+
+ _mm_empty();
+ return TRUE;
+}
+
+void
+fbCompositeCopyAreammx (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ fbCopyAreammx (pSrc->pDrawable,
+ pDst->pDrawable,
+ xSrc, ySrc,
+ xDst, yDst,
+ width, height);
+}
+
#ifndef __amd64__
Bool
fbHaveMMX (void)
diff --git a/fb/fbmmx.h b/fb/fbmmx.h
index 16949cd31..c0333a344 100644
--- a/fb/fbmmx.h
+++ b/fb/fbmmx.h
@@ -156,6 +156,38 @@ void fbCompositeSolidMask_nx8x0565mmx (CARD8 op,
INT16 yDst,
CARD16 width,
CARD16 height);
+void fbCompositeSrc_8888x8x8888mmx (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+Bool fbCopyAreammx (DrawablePtr pSrc,
+ DrawablePtr pDst,
+ int src_x,
+ int src_y,
+ int dst_x,
+ int dst_y,
+ int width,
+ int height);
+void fbCompositeCopyAreammx (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
Bool fbSolidFillmmx (DrawablePtr pDraw,
int x,
int y,
diff --git a/fb/fbpict.c b/fb/fbpict.c
index 554caf07b..a666a0d40 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -863,6 +863,15 @@ fbComposite (CARD8 op,
if (!pSrc->transform && !(pMask && pMask->transform))
if (!maskAlphaMap && !srcAlphaMap && !dstAlphaMap)
switch (op) {
+ case PictOpSrc:
+#ifdef USE_MMX
+ if (!pMask && pSrc->format == pDst->format &&
+ pSrc->pDrawable != pDst->pDrawable)
+ {
+ func = fbCompositeCopyAreammx;
+ }
+#endif
+ break;
case PictOpOver:
if (pMask)
{
@@ -970,6 +979,7 @@ fbComposite (CARD8 op,
xSrc == xMask && ySrc == yMask &&
!pMask->componentAlpha)
{
+ /* source == mask: non-premultiplied data */
switch (pSrc->format) {
case PICT_x8b8g8r8:
switch (pMask->format) {
@@ -1018,6 +1028,24 @@ fbComposite (CARD8 op,
}
break;
}
+ else
+ {
+ /* non-repeating source, repeating mask => translucent window */
+ if (maskRepeat &&
+ pMask->pDrawable->width == 1 &&
+ pMask->pDrawable->height == 1)
+ {
+ if (pSrc->format == PICT_x8r8g8b8 &&
+ pDst->format == PICT_x8r8g8b8 &&
+ pMask->format == PICT_a8)
+ {
+#ifdef USE_MMX
+ if (fbHaveMMX())
+ func = fbCompositeSrc_8888x8x8888mmx;
+#endif
+ }
+ }
+ }
}
}
else