diff options
Diffstat (limited to 'xorg-server/fb/fbblt.c')
-rw-r--r-- | xorg-server/fb/fbblt.c | 1886 |
1 files changed, 943 insertions, 943 deletions
diff --git a/xorg-server/fb/fbblt.c b/xorg-server/fb/fbblt.c index a0402986c..053b78ab2 100644 --- a/xorg-server/fb/fbblt.c +++ b/xorg-server/fb/fbblt.c @@ -1,943 +1,943 @@ -/* - * Copyright © 1998 Keith Packard - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Keith Packard not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#include <string.h> -#include "fb.h" - -#define InitializeShifts(sx,dx,ls,rs) { \ - if (sx != dx) { \ - if (sx > dx) { \ - ls = sx - dx; \ - rs = FB_UNIT - ls; \ - } else { \ - rs = dx - sx; \ - ls = FB_UNIT - rs; \ - } \ - } \ -} - -void -fbBlt (FbBits *srcLine, - FbStride srcStride, - int srcX, - - FbBits *dstLine, - FbStride dstStride, - int dstX, - - int width, - int height, - - int alu, - FbBits pm, - int bpp, - - Bool reverse, - Bool upsidedown) -{ - FbBits *src, *dst; - int leftShift, rightShift; - FbBits startmask, endmask; - FbBits bits, bits1; - int n, nmiddle; - Bool destInvarient; - int startbyte, endbyte; - FbDeclareMergeRop (); - - if (bpp == 24 && !FbCheck24Pix (pm)) - { - fbBlt24 (srcLine, srcStride, srcX, dstLine, dstStride, dstX, - width, height, alu, pm, reverse, upsidedown); - return; - } - - if (alu == GXcopy && pm == FB_ALLONES && !reverse && - !(srcX & 7) && !(dstX & 7) && !(width & 7)) { - int i; - CARD8 *src = (CARD8 *) srcLine; - CARD8 *dst = (CARD8 *) dstLine; - - srcStride *= sizeof(FbBits); - dstStride *= sizeof(FbBits); - width >>= 3; - src += (srcX >> 3); - dst += (dstX >> 3); - - if (!upsidedown) - for (i = 0; i < height; i++) - MEMCPY_WRAPPED(dst + i * dstStride, src + i * srcStride, width); - else - for (i = height - 1; i >= 0; i--) - MEMCPY_WRAPPED(dst + i * dstStride, src + i * srcStride, width); - - return; - } - - FbInitializeMergeRop(alu, pm); - destInvarient = FbDestInvarientMergeRop(); - if (upsidedown) - { - srcLine += (height - 1) * (srcStride); - dstLine += (height - 1) * (dstStride); - srcStride = -srcStride; - dstStride = -dstStride; - } - FbMaskBitsBytes (dstX, width, destInvarient, startmask, startbyte, - nmiddle, endmask, endbyte); - if (reverse) - { - srcLine += ((srcX + width - 1) >> FB_SHIFT) + 1; - dstLine += ((dstX + width - 1) >> FB_SHIFT) + 1; - srcX = (srcX + width - 1) & FB_MASK; - dstX = (dstX + width - 1) & FB_MASK; - } - else - { - srcLine += srcX >> FB_SHIFT; - dstLine += dstX >> FB_SHIFT; - srcX &= FB_MASK; - dstX &= FB_MASK; - } - if (srcX == dstX) - { - while (height--) - { - src = srcLine; - srcLine += srcStride; - dst = dstLine; - dstLine += dstStride; - if (reverse) - { - if (endmask) - { - bits = READ(--src); - --dst; - FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask); - } - n = nmiddle; - if (destInvarient) - { - while (n--) - WRITE(--dst, FbDoDestInvarientMergeRop(READ(--src))); - } - else - { - while (n--) - { - bits = READ(--src); - --dst; - WRITE(dst, FbDoMergeRop (bits, READ(dst))); - } - } - if (startmask) - { - bits = READ(--src); - --dst; - FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask); - } - } - else - { - if (startmask) - { - bits = READ(src++); - FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask); - dst++; - } - n = nmiddle; - if (destInvarient) - { -#if 0 - /* - * This provides some speedup on screen->screen blts - * over the PCI bus, usually about 10%. But fb - * isn't usually used for this operation... - */ - if (_ca2 + 1 == 0 && _cx2 == 0) - { - FbBits t1, t2, t3, t4; - while (n >= 4) - { - t1 = *src++; - t2 = *src++; - t3 = *src++; - t4 = *src++; - *dst++ = t1; - *dst++ = t2; - *dst++ = t3; - *dst++ = t4; - n -= 4; - } - } -#endif - while (n--) - WRITE(dst++, FbDoDestInvarientMergeRop(READ(src++))); - } - else - { - while (n--) - { - bits = READ(src++); - WRITE(dst, FbDoMergeRop (bits, READ(dst))); - dst++; - } - } - if (endmask) - { - bits = READ(src); - FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask); - } - } - } - } - else - { - if (srcX > dstX) - { - leftShift = srcX - dstX; - rightShift = FB_UNIT - leftShift; - } - else - { - rightShift = dstX - srcX; - leftShift = FB_UNIT - rightShift; - } - while (height--) - { - src = srcLine; - srcLine += srcStride; - dst = dstLine; - dstLine += dstStride; - - bits1 = 0; - if (reverse) - { - if (srcX < dstX) - bits1 = READ(--src); - if (endmask) - { - bits = FbScrRight(bits1, rightShift); - if (FbScrRight(endmask, leftShift)) - { - bits1 = READ(--src); - bits |= FbScrLeft(bits1, leftShift); - } - --dst; - FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask); - } - n = nmiddle; - if (destInvarient) - { - while (n--) - { - bits = FbScrRight(bits1, rightShift); - bits1 = READ(--src); - bits |= FbScrLeft(bits1, leftShift); - --dst; - WRITE(dst, FbDoDestInvarientMergeRop(bits)); - } - } - else - { - while (n--) - { - bits = FbScrRight(bits1, rightShift); - bits1 = READ(--src); - bits |= FbScrLeft(bits1, leftShift); - --dst; - WRITE(dst, FbDoMergeRop(bits, READ(dst))); - } - } - if (startmask) - { - bits = FbScrRight(bits1, rightShift); - if (FbScrRight(startmask, leftShift)) - { - bits1 = READ(--src); - bits |= FbScrLeft(bits1, leftShift); - } - --dst; - FbDoLeftMaskByteMergeRop (dst, bits, startbyte, startmask); - } - } - else - { - if (srcX > dstX) - bits1 = READ(src++); - if (startmask) - { - bits = FbScrLeft(bits1, leftShift); - if (FbScrLeft(startmask, rightShift)) - { - bits1 = READ(src++); - bits |= FbScrRight(bits1, rightShift); - } - FbDoLeftMaskByteMergeRop (dst, bits, startbyte, startmask); - dst++; - } - n = nmiddle; - if (destInvarient) - { - while (n--) - { - bits = FbScrLeft(bits1, leftShift); - bits1 = READ(src++); - bits |= FbScrRight(bits1, rightShift); - WRITE(dst, FbDoDestInvarientMergeRop(bits)); - dst++; - } - } - else - { - while (n--) - { - bits = FbScrLeft(bits1, leftShift); - bits1 = READ(src++); - bits |= FbScrRight(bits1, rightShift); - WRITE(dst, FbDoMergeRop(bits, READ(dst))); - dst++; - } - } - if (endmask) - { - bits = FbScrLeft(bits1, leftShift); - if (FbScrLeft(endmask, rightShift)) - { - bits1 = READ(src); - bits |= FbScrRight(bits1, rightShift); - } - FbDoRightMaskByteMergeRop (dst, bits, endbyte, endmask); - } - } - } - } -} - - -#undef DEBUG_BLT24 -#ifdef DEBUG_BLT24 - -static unsigned long -getPixel (char *src, int x) -{ - unsigned long l; - - l = 0; - memcpy (&l, src + x * 3, 3); - return l; -} -#endif - -static void -fbBlt24Line (FbBits *src, - int srcX, - - FbBits *dst, - int dstX, - - int width, - - int alu, - FbBits pm, - - Bool reverse) -{ -#ifdef DEBUG_BLT24 - char *origDst = (char *) dst; - FbBits *origLine = dst + ((dstX >> FB_SHIFT) - 1); - int origNlw = ((width + FB_MASK) >> FB_SHIFT) + 3; - int origX = dstX / 24; -#endif - - int leftShift, rightShift; - FbBits startmask, endmask; - int n; - - FbBits bits, bits1; - FbBits mask; - - int rot; - FbDeclareMergeRop (); - - FbInitializeMergeRop (alu, FB_ALLONES); - FbMaskBits(dstX, width, startmask, n, endmask); -#ifdef DEBUG_BLT24 - ErrorF ("dstX %d width %d reverse %d\n", dstX, width, reverse); -#endif - if (reverse) - { - src += ((srcX + width - 1) >> FB_SHIFT) + 1; - dst += ((dstX + width - 1) >> FB_SHIFT) + 1; - rot = FbFirst24Rot (((dstX + width - 8) & FB_MASK)); - rot = FbPrev24Rot(rot); -#ifdef DEBUG_BLT24 - ErrorF ("dstX + width - 8: %d rot: %d\n", (dstX + width - 8) & FB_MASK, rot); -#endif - srcX = (srcX + width - 1) & FB_MASK; - dstX = (dstX + width - 1) & FB_MASK; - } - else - { - src += srcX >> FB_SHIFT; - dst += dstX >> FB_SHIFT; - srcX &= FB_MASK; - dstX &= FB_MASK; - rot = FbFirst24Rot (dstX); -#ifdef DEBUG_BLT24 - ErrorF ("dstX: %d rot: %d\n", dstX, rot); -#endif - } - mask = FbRot24(pm,rot); -#ifdef DEBUG_BLT24 - ErrorF ("pm 0x%x mask 0x%x\n", pm, mask); -#endif - if (srcX == dstX) - { - if (reverse) - { - if (endmask) - { - bits = READ(--src); - --dst; - WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask & endmask)); - mask = FbPrev24Pix (mask); - } - while (n--) - { - bits = READ(--src); - --dst; - WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask)); - mask = FbPrev24Pix (mask); - } - if (startmask) - { - bits = READ(--src); - --dst; - WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask & startmask)); - } - } - else - { - if (startmask) - { - bits = READ(src++); - WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask & startmask)); - dst++; - mask = FbNext24Pix(mask); - } - while (n--) - { - bits = READ(src++); - WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask)); - dst++; - mask = FbNext24Pix(mask); - } - if (endmask) - { - bits = READ(src); - WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask & endmask)); - } - } - } - else - { - if (srcX > dstX) - { - leftShift = srcX - dstX; - rightShift = FB_UNIT - leftShift; - } - else - { - rightShift = dstX - srcX; - leftShift = FB_UNIT - rightShift; - } - - bits1 = 0; - if (reverse) - { - if (srcX < dstX) - bits1 = READ(--src); - if (endmask) - { - bits = FbScrRight(bits1, rightShift); - if (FbScrRight(endmask, leftShift)) - { - bits1 = READ(--src); - bits |= FbScrLeft(bits1, leftShift); - } - --dst; - WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask & endmask)); - mask = FbPrev24Pix(mask); - } - while (n--) - { - bits = FbScrRight(bits1, rightShift); - bits1 = READ(--src); - bits |= FbScrLeft(bits1, leftShift); - --dst; - WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask)); - mask = FbPrev24Pix(mask); - } - if (startmask) - { - bits = FbScrRight(bits1, rightShift); - if (FbScrRight(startmask, leftShift)) - { - bits1 = READ(--src); - bits |= FbScrLeft(bits1, leftShift); - } - --dst; - WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask & startmask)); - } - } - else - { - if (srcX > dstX) - bits1 = READ(src++); - if (startmask) - { - bits = FbScrLeft(bits1, leftShift); - bits1 = READ(src++); - bits |= FbScrRight(bits1, rightShift); - WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask & startmask)); - dst++; - mask = FbNext24Pix(mask); - } - while (n--) - { - bits = FbScrLeft(bits1, leftShift); - bits1 = READ(src++); - bits |= FbScrRight(bits1, rightShift); - WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask)); - dst++; - mask = FbNext24Pix(mask); - } - if (endmask) - { - bits = FbScrLeft(bits1, leftShift); - if (FbScrLeft(endmask, rightShift)) - { - bits1 = READ(src); - bits |= FbScrRight(bits1, rightShift); - } - WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask & endmask)); - } - } - } -#ifdef DEBUG_BLT24 - { - int firstx, lastx, x; - - firstx = origX; - if (firstx) - firstx--; - lastx = origX + width/24 + 1; - for (x = firstx; x <= lastx; x++) - ErrorF ("%06x ", getPixel (origDst, x)); - ErrorF ("\n"); - while (origNlw--) - ErrorF ("%08x ", *origLine++); - ErrorF ("\n"); - } -#endif -} - -void -fbBlt24 (FbBits *srcLine, - FbStride srcStride, - int srcX, - - FbBits *dstLine, - FbStride dstStride, - int dstX, - - int width, - int height, - - int alu, - FbBits pm, - - Bool reverse, - Bool upsidedown) -{ - if (upsidedown) - { - srcLine += (height-1) * srcStride; - dstLine += (height-1) * dstStride; - srcStride = -srcStride; - dstStride = -dstStride; - } - while (height--) - { - fbBlt24Line (srcLine, srcX, dstLine, dstX, width, alu, pm, reverse); - srcLine += srcStride; - dstLine += dstStride; - } -#ifdef DEBUG_BLT24 - ErrorF ("\n"); -#endif -} - -#if FB_SHIFT == FB_STIP_SHIFT + 1 - -/* - * Could be generalized to FB_SHIFT > FB_STIP_SHIFT + 1 by - * creating an ring of values stepped through for each line - */ - -void -fbBltOdd (FbBits *srcLine, - FbStride srcStrideEven, - FbStride srcStrideOdd, - int srcXEven, - int srcXOdd, - - FbBits *dstLine, - FbStride dstStrideEven, - FbStride dstStrideOdd, - int dstXEven, - int dstXOdd, - - int width, - int height, - - int alu, - FbBits pm, - int bpp) -{ - FbBits *src; - int leftShiftEven, rightShiftEven; - FbBits startmaskEven, endmaskEven; - int nmiddleEven; - - FbBits *dst; - int leftShiftOdd, rightShiftOdd; - FbBits startmaskOdd, endmaskOdd; - int nmiddleOdd; - - int leftShift, rightShift; - FbBits startmask, endmask; - int nmiddle; - - int srcX, dstX; - - FbBits bits, bits1; - int n; - - Bool destInvarient; - Bool even; - FbDeclareMergeRop (); - - FbInitializeMergeRop (alu, pm); - destInvarient = FbDestInvarientMergeRop(); - - srcLine += srcXEven >> FB_SHIFT; - dstLine += dstXEven >> FB_SHIFT; - srcXEven &= FB_MASK; - dstXEven &= FB_MASK; - srcXOdd &= FB_MASK; - dstXOdd &= FB_MASK; - - FbMaskBits(dstXEven, width, startmaskEven, nmiddleEven, endmaskEven); - FbMaskBits(dstXOdd, width, startmaskOdd, nmiddleOdd, endmaskOdd); - - even = TRUE; - InitializeShifts(srcXEven, dstXEven, leftShiftEven, rightShiftEven); - InitializeShifts(srcXOdd, dstXOdd, leftShiftOdd, rightShiftOdd); - while (height--) - { - src = srcLine; - dst = dstLine; - if (even) - { - srcX = srcXEven; - dstX = dstXEven; - startmask = startmaskEven; - endmask = endmaskEven; - nmiddle = nmiddleEven; - leftShift = leftShiftEven; - rightShift = rightShiftEven; - srcLine += srcStrideEven; - dstLine += dstStrideEven; - even = FALSE; - } - else - { - srcX = srcXOdd; - dstX = dstXOdd; - startmask = startmaskOdd; - endmask = endmaskOdd; - nmiddle = nmiddleOdd; - leftShift = leftShiftOdd; - rightShift = rightShiftOdd; - srcLine += srcStrideOdd; - dstLine += dstStrideOdd; - even = TRUE; - } - if (srcX == dstX) - { - if (startmask) - { - bits = READ(src++); - WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), startmask)); - dst++; - } - n = nmiddle; - if (destInvarient) - { - while (n--) - { - bits = READ(src++); - WRITE(dst, FbDoDestInvarientMergeRop(bits)); - dst++; - } - } - else - { - while (n--) - { - bits = READ(src++); - WRITE(dst, FbDoMergeRop (bits, READ(dst))); - dst++; - } - } - if (endmask) - { - bits = READ(src); - WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), endmask)); - } - } - else - { - bits = 0; - if (srcX > dstX) - bits = READ(src++); - if (startmask) - { - bits1 = FbScrLeft(bits, leftShift); - bits = READ(src++); - bits1 |= FbScrRight(bits, rightShift); - WRITE(dst, FbDoMaskMergeRop (bits1, READ(dst), startmask)); - dst++; - } - n = nmiddle; - if (destInvarient) - { - while (n--) - { - bits1 = FbScrLeft(bits, leftShift); - bits = READ(src++); - bits1 |= FbScrRight(bits, rightShift); - WRITE(dst, FbDoDestInvarientMergeRop(bits1)); - dst++; - } - } - else - { - while (n--) - { - bits1 = FbScrLeft(bits, leftShift); - bits = READ(src++); - bits1 |= FbScrRight(bits, rightShift); - WRITE(dst, FbDoMergeRop(bits1, READ(dst))); - dst++; - } - } - if (endmask) - { - bits1 = FbScrLeft(bits, leftShift); - if (FbScrLeft(endmask, rightShift)) - { - bits = READ(src); - bits1 |= FbScrRight(bits, rightShift); - } - WRITE(dst, FbDoMaskMergeRop (bits1, READ(dst), endmask)); - } - } - } -} - -void -fbBltOdd24 (FbBits *srcLine, - FbStride srcStrideEven, - FbStride srcStrideOdd, - int srcXEven, - int srcXOdd, - - FbBits *dstLine, - FbStride dstStrideEven, - FbStride dstStrideOdd, - int dstXEven, - int dstXOdd, - - int width, - int height, - - int alu, - FbBits pm) -{ - Bool even = TRUE; - - while (height--) - { - if (even) - { - fbBlt24Line (srcLine, srcXEven, dstLine, dstXEven, - width, alu, pm, FALSE); - srcLine += srcStrideEven; - dstLine += dstStrideEven; - even = FALSE; - } - else - { - fbBlt24Line (srcLine, srcXOdd, dstLine, dstXOdd, - width, alu, pm, FALSE); - srcLine += srcStrideOdd; - dstLine += dstStrideOdd; - even = TRUE; - } - } -} - -#endif - -#if FB_STIP_SHIFT != FB_SHIFT -void -fbSetBltOdd (FbStip *stip, - FbStride stipStride, - int srcX, - FbBits **bits, - FbStride *strideEven, - FbStride *strideOdd, - int *srcXEven, - int *srcXOdd) -{ - int srcAdjust; - int strideAdjust; - - /* - * bytes needed to align source - */ - srcAdjust = (((int) stip) & (FB_MASK >> 3)); - /* - * FbStip units needed to align stride - */ - strideAdjust = stipStride & (FB_MASK >> FB_STIP_SHIFT); - - *bits = (FbBits *) ((char *) stip - srcAdjust); - if (srcAdjust) - { - *strideEven = FbStipStrideToBitsStride (stipStride + 1); - *strideOdd = FbStipStrideToBitsStride (stipStride); - - *srcXEven = srcX + (srcAdjust << 3); - *srcXOdd = srcX + (srcAdjust << 3) - (strideAdjust << FB_STIP_SHIFT); - } - else - { - *strideEven = FbStipStrideToBitsStride (stipStride); - *strideOdd = FbStipStrideToBitsStride (stipStride + 1); - - *srcXEven = srcX; - *srcXOdd = srcX + (strideAdjust << FB_STIP_SHIFT); - } -} -#endif - -void -fbBltStip (FbStip *src, - FbStride srcStride, /* in FbStip units, not FbBits units */ - int srcX, - - FbStip *dst, - FbStride dstStride, /* in FbStip units, not FbBits units */ - int dstX, - - int width, - int height, - - int alu, - FbBits pm, - int bpp) -{ -#if FB_STIP_SHIFT != FB_SHIFT - if (FB_STIP_ODDSTRIDE(srcStride) || FB_STIP_ODDPTR(src) || - FB_STIP_ODDSTRIDE(dstStride) || FB_STIP_ODDPTR(dst)) - { - FbStride srcStrideEven, srcStrideOdd; - FbStride dstStrideEven, dstStrideOdd; - int srcXEven, srcXOdd; - int dstXEven, dstXOdd; - FbBits *s, *d; - int sx, dx; - - src += srcX >> FB_STIP_SHIFT; - srcX &= FB_STIP_MASK; - dst += dstX >> FB_STIP_SHIFT; - dstX &= FB_STIP_MASK; - - fbSetBltOdd (src, srcStride, srcX, - &s, - &srcStrideEven, &srcStrideOdd, - &srcXEven, &srcXOdd); - - fbSetBltOdd (dst, dstStride, dstX, - &d, - &dstStrideEven, &dstStrideOdd, - &dstXEven, &dstXOdd); - - if (bpp == 24 && !FbCheck24Pix (pm)) - { - fbBltOdd24 (s, srcStrideEven, srcStrideOdd, - srcXEven, srcXOdd, - - d, dstStrideEven, dstStrideOdd, - dstXEven, dstXOdd, - - width, height, alu, pm); - } - else - { - fbBltOdd (s, srcStrideEven, srcStrideOdd, - srcXEven, srcXOdd, - - d, dstStrideEven, dstStrideOdd, - dstXEven, dstXOdd, - - width, height, alu, pm, bpp); - } - } - else -#endif - { - fbBlt ((FbBits *) src, FbStipStrideToBitsStride (srcStride), - srcX, - (FbBits *) dst, FbStipStrideToBitsStride (dstStride), - dstX, - width, height, - alu, pm, bpp, FALSE, FALSE); - } -} +/*
+ * Copyright © 1998 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <string.h>
+#include "fb.h"
+
+#define InitializeShifts(sx,dx,ls,rs) { \
+ if (sx != dx) { \
+ if (sx > dx) { \
+ ls = sx - dx; \
+ rs = FB_UNIT - ls; \
+ } else { \
+ rs = dx - sx; \
+ ls = FB_UNIT - rs; \
+ } \
+ } \
+}
+
+void
+fbBlt (FbBits *srcLine,
+ FbStride srcStride,
+ int srcX,
+
+ FbBits *dstLine,
+ FbStride dstStride,
+ int dstX,
+
+ int width,
+ int height,
+
+ int alu,
+ FbBits pm,
+ int bpp,
+
+ Bool reverse,
+ Bool upsidedown)
+{
+ FbBits *src, *dst;
+ int leftShift, rightShift;
+ FbBits startmask, endmask;
+ FbBits bits, bits1;
+ int n, nmiddle;
+ Bool destInvarient;
+ int startbyte, endbyte;
+ FbDeclareMergeRop ();
+
+ if (bpp == 24 && !FbCheck24Pix (pm))
+ {
+ fbBlt24 (srcLine, srcStride, srcX, dstLine, dstStride, dstX,
+ width, height, alu, pm, reverse, upsidedown);
+ return;
+ }
+
+ if (alu == GXcopy && pm == FB_ALLONES && !reverse &&
+ !(srcX & 7) && !(dstX & 7) && !(width & 7)) {
+ int i;
+ CARD8 *src = (CARD8 *) srcLine;
+ CARD8 *dst = (CARD8 *) dstLine;
+
+ srcStride *= sizeof(FbBits);
+ dstStride *= sizeof(FbBits);
+ width >>= 3;
+ src += (srcX >> 3);
+ dst += (dstX >> 3);
+
+ if (!upsidedown)
+ for (i = 0; i < height; i++)
+ MEMCPY_WRAPPED(dst + i * dstStride, src + i * srcStride, width);
+ else
+ for (i = height - 1; i >= 0; i--)
+ MEMCPY_WRAPPED(dst + i * dstStride, src + i * srcStride, width);
+
+ return;
+ }
+
+ FbInitializeMergeRop(alu, pm);
+ destInvarient = FbDestInvarientMergeRop();
+ if (upsidedown)
+ {
+ srcLine += (height - 1) * (srcStride);
+ dstLine += (height - 1) * (dstStride);
+ srcStride = -srcStride;
+ dstStride = -dstStride;
+ }
+ FbMaskBitsBytes (dstX, width, destInvarient, startmask, startbyte,
+ nmiddle, endmask, endbyte);
+ if (reverse)
+ {
+ srcLine += ((srcX + width - 1) >> FB_SHIFT) + 1;
+ dstLine += ((dstX + width - 1) >> FB_SHIFT) + 1;
+ srcX = (srcX + width - 1) & FB_MASK;
+ dstX = (dstX + width - 1) & FB_MASK;
+ }
+ else
+ {
+ srcLine += srcX >> FB_SHIFT;
+ dstLine += dstX >> FB_SHIFT;
+ srcX &= FB_MASK;
+ dstX &= FB_MASK;
+ }
+ if (srcX == dstX)
+ {
+ while (height--)
+ {
+ src = srcLine;
+ srcLine += srcStride;
+ dst = dstLine;
+ dstLine += dstStride;
+ if (reverse)
+ {
+ if (endmask)
+ {
+ bits = READ(--src);
+ --dst;
+ FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
+ }
+ n = nmiddle;
+ if (destInvarient)
+ {
+ while (n--)
+ WRITE(--dst, FbDoDestInvarientMergeRop(READ(--src)));
+ }
+ else
+ {
+ while (n--)
+ {
+ bits = READ(--src);
+ --dst;
+ WRITE(dst, FbDoMergeRop (bits, READ(dst)));
+ }
+ }
+ if (startmask)
+ {
+ bits = READ(--src);
+ --dst;
+ FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask);
+ }
+ }
+ else
+ {
+ if (startmask)
+ {
+ bits = READ(src++);
+ FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask);
+ dst++;
+ }
+ n = nmiddle;
+ if (destInvarient)
+ {
+#if 0
+ /*
+ * This provides some speedup on screen->screen blts
+ * over the PCI bus, usually about 10%. But fb
+ * isn't usually used for this operation...
+ */
+ if (_ca2 + 1 == 0 && _cx2 == 0)
+ {
+ FbBits t1, t2, t3, t4;
+ while (n >= 4)
+ {
+ t1 = *src++;
+ t2 = *src++;
+ t3 = *src++;
+ t4 = *src++;
+ *dst++ = t1;
+ *dst++ = t2;
+ *dst++ = t3;
+ *dst++ = t4;
+ n -= 4;
+ }
+ }
+#endif
+ while (n--)
+ WRITE(dst++, FbDoDestInvarientMergeRop(READ(src++)));
+ }
+ else
+ {
+ while (n--)
+ {
+ bits = READ(src++);
+ WRITE(dst, FbDoMergeRop (bits, READ(dst)));
+ dst++;
+ }
+ }
+ if (endmask)
+ {
+ bits = READ(src);
+ FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
+ }
+ }
+ }
+ }
+ else
+ {
+ if (srcX > dstX)
+ {
+ leftShift = srcX - dstX;
+ rightShift = FB_UNIT - leftShift;
+ }
+ else
+ {
+ rightShift = dstX - srcX;
+ leftShift = FB_UNIT - rightShift;
+ }
+ while (height--)
+ {
+ src = srcLine;
+ srcLine += srcStride;
+ dst = dstLine;
+ dstLine += dstStride;
+
+ bits1 = 0;
+ if (reverse)
+ {
+ if (srcX < dstX)
+ bits1 = READ(--src);
+ if (endmask)
+ {
+ bits = FbScrRight(bits1, rightShift);
+ if (FbScrRight(endmask, leftShift))
+ {
+ bits1 = READ(--src);
+ bits |= FbScrLeft(bits1, leftShift);
+ }
+ --dst;
+ FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
+ }
+ n = nmiddle;
+ if (destInvarient)
+ {
+ while (n--)
+ {
+ bits = FbScrRight(bits1, rightShift);
+ bits1 = READ(--src);
+ bits |= FbScrLeft(bits1, leftShift);
+ --dst;
+ WRITE(dst, FbDoDestInvarientMergeRop(bits));
+ }
+ }
+ else
+ {
+ while (n--)
+ {
+ bits = FbScrRight(bits1, rightShift);
+ bits1 = READ(--src);
+ bits |= FbScrLeft(bits1, leftShift);
+ --dst;
+ WRITE(dst, FbDoMergeRop(bits, READ(dst)));
+ }
+ }
+ if (startmask)
+ {
+ bits = FbScrRight(bits1, rightShift);
+ if (FbScrRight(startmask, leftShift))
+ {
+ bits1 = READ(--src);
+ bits |= FbScrLeft(bits1, leftShift);
+ }
+ --dst;
+ FbDoLeftMaskByteMergeRop (dst, bits, startbyte, startmask);
+ }
+ }
+ else
+ {
+ if (srcX > dstX)
+ bits1 = READ(src++);
+ if (startmask)
+ {
+ bits = FbScrLeft(bits1, leftShift);
+ if (FbScrLeft(startmask, rightShift))
+ {
+ bits1 = READ(src++);
+ bits |= FbScrRight(bits1, rightShift);
+ }
+ FbDoLeftMaskByteMergeRop (dst, bits, startbyte, startmask);
+ dst++;
+ }
+ n = nmiddle;
+ if (destInvarient)
+ {
+ while (n--)
+ {
+ bits = FbScrLeft(bits1, leftShift);
+ bits1 = READ(src++);
+ bits |= FbScrRight(bits1, rightShift);
+ WRITE(dst, FbDoDestInvarientMergeRop(bits));
+ dst++;
+ }
+ }
+ else
+ {
+ while (n--)
+ {
+ bits = FbScrLeft(bits1, leftShift);
+ bits1 = READ(src++);
+ bits |= FbScrRight(bits1, rightShift);
+ WRITE(dst, FbDoMergeRop(bits, READ(dst)));
+ dst++;
+ }
+ }
+ if (endmask)
+ {
+ bits = FbScrLeft(bits1, leftShift);
+ if (FbScrLeft(endmask, rightShift))
+ {
+ bits1 = READ(src);
+ bits |= FbScrRight(bits1, rightShift);
+ }
+ FbDoRightMaskByteMergeRop (dst, bits, endbyte, endmask);
+ }
+ }
+ }
+ }
+}
+
+
+#undef DEBUG_BLT24
+#ifdef DEBUG_BLT24
+
+static unsigned long
+getPixel (char *src, int x)
+{
+ unsigned long l;
+
+ l = 0;
+ memcpy (&l, src + x * 3, 3);
+ return l;
+}
+#endif
+
+static void
+fbBlt24Line (FbBits *src,
+ int srcX,
+
+ FbBits *dst,
+ int dstX,
+
+ int width,
+
+ int alu,
+ FbBits pm,
+
+ Bool reverse)
+{
+#ifdef DEBUG_BLT24
+ char *origDst = (char *) dst;
+ FbBits *origLine = dst + ((dstX >> FB_SHIFT) - 1);
+ int origNlw = ((width + FB_MASK) >> FB_SHIFT) + 3;
+ int origX = dstX / 24;
+#endif
+
+ int leftShift, rightShift;
+ FbBits startmask, endmask;
+ int n;
+
+ FbBits bits, bits1;
+ FbBits mask;
+
+ int rot;
+ FbDeclareMergeRop ();
+
+ FbInitializeMergeRop (alu, FB_ALLONES);
+ FbMaskBits(dstX, width, startmask, n, endmask);
+#ifdef DEBUG_BLT24
+ ErrorF ("dstX %d width %d reverse %d\n", dstX, width, reverse);
+#endif
+ if (reverse)
+ {
+ src += ((srcX + width - 1) >> FB_SHIFT) + 1;
+ dst += ((dstX + width - 1) >> FB_SHIFT) + 1;
+ rot = FbFirst24Rot (((dstX + width - 8) & FB_MASK));
+ rot = FbPrev24Rot(rot);
+#ifdef DEBUG_BLT24
+ ErrorF ("dstX + width - 8: %d rot: %d\n", (dstX + width - 8) & FB_MASK, rot);
+#endif
+ srcX = (srcX + width - 1) & FB_MASK;
+ dstX = (dstX + width - 1) & FB_MASK;
+ }
+ else
+ {
+ src += srcX >> FB_SHIFT;
+ dst += dstX >> FB_SHIFT;
+ srcX &= FB_MASK;
+ dstX &= FB_MASK;
+ rot = FbFirst24Rot (dstX);
+#ifdef DEBUG_BLT24
+ ErrorF ("dstX: %d rot: %d\n", dstX, rot);
+#endif
+ }
+ mask = FbRot24(pm,rot);
+#ifdef DEBUG_BLT24
+ ErrorF ("pm 0x%x mask 0x%x\n", pm, mask);
+#endif
+ if (srcX == dstX)
+ {
+ if (reverse)
+ {
+ if (endmask)
+ {
+ bits = READ(--src);
+ --dst;
+ WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask & endmask));
+ mask = FbPrev24Pix (mask);
+ }
+ while (n--)
+ {
+ bits = READ(--src);
+ --dst;
+ WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask));
+ mask = FbPrev24Pix (mask);
+ }
+ if (startmask)
+ {
+ bits = READ(--src);
+ --dst;
+ WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask & startmask));
+ }
+ }
+ else
+ {
+ if (startmask)
+ {
+ bits = READ(src++);
+ WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask & startmask));
+ dst++;
+ mask = FbNext24Pix(mask);
+ }
+ while (n--)
+ {
+ bits = READ(src++);
+ WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask));
+ dst++;
+ mask = FbNext24Pix(mask);
+ }
+ if (endmask)
+ {
+ bits = READ(src);
+ WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask & endmask));
+ }
+ }
+ }
+ else
+ {
+ if (srcX > dstX)
+ {
+ leftShift = srcX - dstX;
+ rightShift = FB_UNIT - leftShift;
+ }
+ else
+ {
+ rightShift = dstX - srcX;
+ leftShift = FB_UNIT - rightShift;
+ }
+
+ bits1 = 0;
+ if (reverse)
+ {
+ if (srcX < dstX)
+ bits1 = READ(--src);
+ if (endmask)
+ {
+ bits = FbScrRight(bits1, rightShift);
+ if (FbScrRight(endmask, leftShift))
+ {
+ bits1 = READ(--src);
+ bits |= FbScrLeft(bits1, leftShift);
+ }
+ --dst;
+ WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask & endmask));
+ mask = FbPrev24Pix(mask);
+ }
+ while (n--)
+ {
+ bits = FbScrRight(bits1, rightShift);
+ bits1 = READ(--src);
+ bits |= FbScrLeft(bits1, leftShift);
+ --dst;
+ WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask));
+ mask = FbPrev24Pix(mask);
+ }
+ if (startmask)
+ {
+ bits = FbScrRight(bits1, rightShift);
+ if (FbScrRight(startmask, leftShift))
+ {
+ bits1 = READ(--src);
+ bits |= FbScrLeft(bits1, leftShift);
+ }
+ --dst;
+ WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask & startmask));
+ }
+ }
+ else
+ {
+ if (srcX > dstX)
+ bits1 = READ(src++);
+ if (startmask)
+ {
+ bits = FbScrLeft(bits1, leftShift);
+ bits1 = READ(src++);
+ bits |= FbScrRight(bits1, rightShift);
+ WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask & startmask));
+ dst++;
+ mask = FbNext24Pix(mask);
+ }
+ while (n--)
+ {
+ bits = FbScrLeft(bits1, leftShift);
+ bits1 = READ(src++);
+ bits |= FbScrRight(bits1, rightShift);
+ WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask));
+ dst++;
+ mask = FbNext24Pix(mask);
+ }
+ if (endmask)
+ {
+ bits = FbScrLeft(bits1, leftShift);
+ if (FbScrLeft(endmask, rightShift))
+ {
+ bits1 = READ(src);
+ bits |= FbScrRight(bits1, rightShift);
+ }
+ WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask & endmask));
+ }
+ }
+ }
+#ifdef DEBUG_BLT24
+ {
+ int firstx, lastx, x;
+
+ firstx = origX;
+ if (firstx)
+ firstx--;
+ lastx = origX + width/24 + 1;
+ for (x = firstx; x <= lastx; x++)
+ ErrorF ("%06x ", getPixel (origDst, x));
+ ErrorF ("\n");
+ while (origNlw--)
+ ErrorF ("%08x ", *origLine++);
+ ErrorF ("\n");
+ }
+#endif
+}
+
+void
+fbBlt24 (FbBits *srcLine,
+ FbStride srcStride,
+ int srcX,
+
+ FbBits *dstLine,
+ FbStride dstStride,
+ int dstX,
+
+ int width,
+ int height,
+
+ int alu,
+ FbBits pm,
+
+ Bool reverse,
+ Bool upsidedown)
+{
+ if (upsidedown)
+ {
+ srcLine += (height-1) * srcStride;
+ dstLine += (height-1) * dstStride;
+ srcStride = -srcStride;
+ dstStride = -dstStride;
+ }
+ while (height--)
+ {
+ fbBlt24Line (srcLine, srcX, dstLine, dstX, width, alu, pm, reverse);
+ srcLine += srcStride;
+ dstLine += dstStride;
+ }
+#ifdef DEBUG_BLT24
+ ErrorF ("\n");
+#endif
+}
+
+#if FB_SHIFT == FB_STIP_SHIFT + 1
+
+/*
+ * Could be generalized to FB_SHIFT > FB_STIP_SHIFT + 1 by
+ * creating an ring of values stepped through for each line
+ */
+
+void
+fbBltOdd (FbBits *srcLine,
+ FbStride srcStrideEven,
+ FbStride srcStrideOdd,
+ int srcXEven,
+ int srcXOdd,
+
+ FbBits *dstLine,
+ FbStride dstStrideEven,
+ FbStride dstStrideOdd,
+ int dstXEven,
+ int dstXOdd,
+
+ int width,
+ int height,
+
+ int alu,
+ FbBits pm,
+ int bpp)
+{
+ FbBits *src;
+ int leftShiftEven, rightShiftEven;
+ FbBits startmaskEven, endmaskEven;
+ int nmiddleEven;
+
+ FbBits *dst;
+ int leftShiftOdd, rightShiftOdd;
+ FbBits startmaskOdd, endmaskOdd;
+ int nmiddleOdd;
+
+ int leftShift, rightShift;
+ FbBits startmask, endmask;
+ int nmiddle;
+
+ int srcX, dstX;
+
+ FbBits bits, bits1;
+ int n;
+
+ Bool destInvarient;
+ Bool even;
+ FbDeclareMergeRop ();
+
+ FbInitializeMergeRop (alu, pm);
+ destInvarient = FbDestInvarientMergeRop();
+
+ srcLine += srcXEven >> FB_SHIFT;
+ dstLine += dstXEven >> FB_SHIFT;
+ srcXEven &= FB_MASK;
+ dstXEven &= FB_MASK;
+ srcXOdd &= FB_MASK;
+ dstXOdd &= FB_MASK;
+
+ FbMaskBits(dstXEven, width, startmaskEven, nmiddleEven, endmaskEven);
+ FbMaskBits(dstXOdd, width, startmaskOdd, nmiddleOdd, endmaskOdd);
+
+ even = TRUE;
+ InitializeShifts(srcXEven, dstXEven, leftShiftEven, rightShiftEven);
+ InitializeShifts(srcXOdd, dstXOdd, leftShiftOdd, rightShiftOdd);
+ while (height--)
+ {
+ src = srcLine;
+ dst = dstLine;
+ if (even)
+ {
+ srcX = srcXEven;
+ dstX = dstXEven;
+ startmask = startmaskEven;
+ endmask = endmaskEven;
+ nmiddle = nmiddleEven;
+ leftShift = leftShiftEven;
+ rightShift = rightShiftEven;
+ srcLine += srcStrideEven;
+ dstLine += dstStrideEven;
+ even = FALSE;
+ }
+ else
+ {
+ srcX = srcXOdd;
+ dstX = dstXOdd;
+ startmask = startmaskOdd;
+ endmask = endmaskOdd;
+ nmiddle = nmiddleOdd;
+ leftShift = leftShiftOdd;
+ rightShift = rightShiftOdd;
+ srcLine += srcStrideOdd;
+ dstLine += dstStrideOdd;
+ even = TRUE;
+ }
+ if (srcX == dstX)
+ {
+ if (startmask)
+ {
+ bits = READ(src++);
+ WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), startmask));
+ dst++;
+ }
+ n = nmiddle;
+ if (destInvarient)
+ {
+ while (n--)
+ {
+ bits = READ(src++);
+ WRITE(dst, FbDoDestInvarientMergeRop(bits));
+ dst++;
+ }
+ }
+ else
+ {
+ while (n--)
+ {
+ bits = READ(src++);
+ WRITE(dst, FbDoMergeRop (bits, READ(dst)));
+ dst++;
+ }
+ }
+ if (endmask)
+ {
+ bits = READ(src);
+ WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), endmask));
+ }
+ }
+ else
+ {
+ bits = 0;
+ if (srcX > dstX)
+ bits = READ(src++);
+ if (startmask)
+ {
+ bits1 = FbScrLeft(bits, leftShift);
+ bits = READ(src++);
+ bits1 |= FbScrRight(bits, rightShift);
+ WRITE(dst, FbDoMaskMergeRop (bits1, READ(dst), startmask));
+ dst++;
+ }
+ n = nmiddle;
+ if (destInvarient)
+ {
+ while (n--)
+ {
+ bits1 = FbScrLeft(bits, leftShift);
+ bits = READ(src++);
+ bits1 |= FbScrRight(bits, rightShift);
+ WRITE(dst, FbDoDestInvarientMergeRop(bits1));
+ dst++;
+ }
+ }
+ else
+ {
+ while (n--)
+ {
+ bits1 = FbScrLeft(bits, leftShift);
+ bits = READ(src++);
+ bits1 |= FbScrRight(bits, rightShift);
+ WRITE(dst, FbDoMergeRop(bits1, READ(dst)));
+ dst++;
+ }
+ }
+ if (endmask)
+ {
+ bits1 = FbScrLeft(bits, leftShift);
+ if (FbScrLeft(endmask, rightShift))
+ {
+ bits = READ(src);
+ bits1 |= FbScrRight(bits, rightShift);
+ }
+ WRITE(dst, FbDoMaskMergeRop (bits1, READ(dst), endmask));
+ }
+ }
+ }
+}
+
+void
+fbBltOdd24 (FbBits *srcLine,
+ FbStride srcStrideEven,
+ FbStride srcStrideOdd,
+ int srcXEven,
+ int srcXOdd,
+
+ FbBits *dstLine,
+ FbStride dstStrideEven,
+ FbStride dstStrideOdd,
+ int dstXEven,
+ int dstXOdd,
+
+ int width,
+ int height,
+
+ int alu,
+ FbBits pm)
+{
+ Bool even = TRUE;
+
+ while (height--)
+ {
+ if (even)
+ {
+ fbBlt24Line (srcLine, srcXEven, dstLine, dstXEven,
+ width, alu, pm, FALSE);
+ srcLine += srcStrideEven;
+ dstLine += dstStrideEven;
+ even = FALSE;
+ }
+ else
+ {
+ fbBlt24Line (srcLine, srcXOdd, dstLine, dstXOdd,
+ width, alu, pm, FALSE);
+ srcLine += srcStrideOdd;
+ dstLine += dstStrideOdd;
+ even = TRUE;
+ }
+ }
+}
+
+#endif
+
+#if FB_STIP_SHIFT != FB_SHIFT
+void
+fbSetBltOdd (FbStip *stip,
+ FbStride stipStride,
+ int srcX,
+ FbBits **bits,
+ FbStride *strideEven,
+ FbStride *strideOdd,
+ int *srcXEven,
+ int *srcXOdd)
+{
+ int srcAdjust;
+ int strideAdjust;
+
+ /*
+ * bytes needed to align source
+ */
+ srcAdjust = (((int) stip) & (FB_MASK >> 3));
+ /*
+ * FbStip units needed to align stride
+ */
+ strideAdjust = stipStride & (FB_MASK >> FB_STIP_SHIFT);
+
+ *bits = (FbBits *) ((char *) stip - srcAdjust);
+ if (srcAdjust)
+ {
+ *strideEven = FbStipStrideToBitsStride (stipStride + 1);
+ *strideOdd = FbStipStrideToBitsStride (stipStride);
+
+ *srcXEven = srcX + (srcAdjust << 3);
+ *srcXOdd = srcX + (srcAdjust << 3) - (strideAdjust << FB_STIP_SHIFT);
+ }
+ else
+ {
+ *strideEven = FbStipStrideToBitsStride (stipStride);
+ *strideOdd = FbStipStrideToBitsStride (stipStride + 1);
+
+ *srcXEven = srcX;
+ *srcXOdd = srcX + (strideAdjust << FB_STIP_SHIFT);
+ }
+}
+#endif
+
+void
+fbBltStip (FbStip *src,
+ FbStride srcStride, /* in FbStip units, not FbBits units */
+ int srcX,
+
+ FbStip *dst,
+ FbStride dstStride, /* in FbStip units, not FbBits units */
+ int dstX,
+
+ int width,
+ int height,
+
+ int alu,
+ FbBits pm,
+ int bpp)
+{
+#if FB_STIP_SHIFT != FB_SHIFT
+ if (FB_STIP_ODDSTRIDE(srcStride) || FB_STIP_ODDPTR(src) ||
+ FB_STIP_ODDSTRIDE(dstStride) || FB_STIP_ODDPTR(dst))
+ {
+ FbStride srcStrideEven, srcStrideOdd;
+ FbStride dstStrideEven, dstStrideOdd;
+ int srcXEven, srcXOdd;
+ int dstXEven, dstXOdd;
+ FbBits *s, *d;
+ int sx, dx;
+
+ src += srcX >> FB_STIP_SHIFT;
+ srcX &= FB_STIP_MASK;
+ dst += dstX >> FB_STIP_SHIFT;
+ dstX &= FB_STIP_MASK;
+
+ fbSetBltOdd (src, srcStride, srcX,
+ &s,
+ &srcStrideEven, &srcStrideOdd,
+ &srcXEven, &srcXOdd);
+
+ fbSetBltOdd (dst, dstStride, dstX,
+ &d,
+ &dstStrideEven, &dstStrideOdd,
+ &dstXEven, &dstXOdd);
+
+ if (bpp == 24 && !FbCheck24Pix (pm))
+ {
+ fbBltOdd24 (s, srcStrideEven, srcStrideOdd,
+ srcXEven, srcXOdd,
+
+ d, dstStrideEven, dstStrideOdd,
+ dstXEven, dstXOdd,
+
+ width, height, alu, pm);
+ }
+ else
+ {
+ fbBltOdd (s, srcStrideEven, srcStrideOdd,
+ srcXEven, srcXOdd,
+
+ d, dstStrideEven, dstStrideOdd,
+ dstXEven, dstXOdd,
+
+ width, height, alu, pm, bpp);
+ }
+ }
+ else
+#endif
+ {
+ fbBlt ((FbBits *) src, FbStipStrideToBitsStride (srcStride),
+ srcX,
+ (FbBits *) dst, FbStipStrideToBitsStride (dstStride),
+ dstX,
+ width, height,
+ alu, pm, bpp, FALSE, FALSE);
+ }
+}
|