fbblt.c revision 05b261ec
105b261ecSmrg/* 205b261ecSmrg * Copyright © 1998 Keith Packard 305b261ecSmrg * 405b261ecSmrg * Permission to use, copy, modify, distribute, and sell this software and its 505b261ecSmrg * documentation for any purpose is hereby granted without fee, provided that 605b261ecSmrg * the above copyright notice appear in all copies and that both that 705b261ecSmrg * copyright notice and this permission notice appear in supporting 805b261ecSmrg * documentation, and that the name of Keith Packard not be used in 905b261ecSmrg * advertising or publicity pertaining to distribution of the software without 1005b261ecSmrg * specific, written prior permission. Keith Packard makes no 1105b261ecSmrg * representations about the suitability of this software for any purpose. It 1205b261ecSmrg * is provided "as is" without express or implied warranty. 1305b261ecSmrg * 1405b261ecSmrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 1505b261ecSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 1605b261ecSmrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 1705b261ecSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 1805b261ecSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 1905b261ecSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 2005b261ecSmrg * PERFORMANCE OF THIS SOFTWARE. 2105b261ecSmrg */ 2205b261ecSmrg 2305b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 2405b261ecSmrg#include <dix-config.h> 2505b261ecSmrg#endif 2605b261ecSmrg 2705b261ecSmrg#include <string.h> 2805b261ecSmrg#include "fb.h" 2905b261ecSmrg 3005b261ecSmrg#define InitializeShifts(sx,dx,ls,rs) { \ 3105b261ecSmrg if (sx != dx) { \ 3205b261ecSmrg if (sx > dx) { \ 3305b261ecSmrg ls = sx - dx; \ 3405b261ecSmrg rs = FB_UNIT - ls; \ 3505b261ecSmrg } else { \ 3605b261ecSmrg rs = dx - sx; \ 3705b261ecSmrg ls = FB_UNIT - rs; \ 3805b261ecSmrg } \ 3905b261ecSmrg } \ 4005b261ecSmrg} 4105b261ecSmrg 4205b261ecSmrgvoid 4305b261ecSmrgfbBlt (FbBits *srcLine, 4405b261ecSmrg FbStride srcStride, 4505b261ecSmrg int srcX, 4605b261ecSmrg 4705b261ecSmrg FbBits *dstLine, 4805b261ecSmrg FbStride dstStride, 4905b261ecSmrg int dstX, 5005b261ecSmrg 5105b261ecSmrg int width, 5205b261ecSmrg int height, 5305b261ecSmrg 5405b261ecSmrg int alu, 5505b261ecSmrg FbBits pm, 5605b261ecSmrg int bpp, 5705b261ecSmrg 5805b261ecSmrg Bool reverse, 5905b261ecSmrg Bool upsidedown) 6005b261ecSmrg{ 6105b261ecSmrg FbBits *src, *dst; 6205b261ecSmrg int leftShift, rightShift; 6305b261ecSmrg FbBits startmask, endmask; 6405b261ecSmrg FbBits bits, bits1; 6505b261ecSmrg int n, nmiddle; 6605b261ecSmrg Bool destInvarient; 6705b261ecSmrg int startbyte, endbyte; 6805b261ecSmrg FbDeclareMergeRop (); 6905b261ecSmrg 7005b261ecSmrg#ifdef FB_24BIT 7105b261ecSmrg if (bpp == 24 && !FbCheck24Pix (pm)) 7205b261ecSmrg { 7305b261ecSmrg fbBlt24 (srcLine, srcStride, srcX, dstLine, dstStride, dstX, 7405b261ecSmrg width, height, alu, pm, reverse, upsidedown); 7505b261ecSmrg return; 7605b261ecSmrg } 7705b261ecSmrg#endif 7805b261ecSmrg 7905b261ecSmrg if (alu == GXcopy && pm == FB_ALLONES && !reverse && 8005b261ecSmrg !(srcX & 7) && !(dstX & 7) && !(width & 7)) { 8105b261ecSmrg int i; 8205b261ecSmrg CARD8 *src = (CARD8 *) srcLine; 8305b261ecSmrg CARD8 *dst = (CARD8 *) dstLine; 8405b261ecSmrg 8505b261ecSmrg srcStride *= sizeof(FbBits); 8605b261ecSmrg dstStride *= sizeof(FbBits); 8705b261ecSmrg width >>= 3; 8805b261ecSmrg src += (srcX >> 3); 8905b261ecSmrg dst += (dstX >> 3); 9005b261ecSmrg 9105b261ecSmrg if (!upsidedown) 9205b261ecSmrg for (i = 0; i < height; i++) 9305b261ecSmrg MEMCPY_WRAPPED(dst + i * dstStride, src + i * srcStride, width); 9405b261ecSmrg else 9505b261ecSmrg for (i = height - 1; i >= 0; i--) 9605b261ecSmrg MEMCPY_WRAPPED(dst + i * dstStride, src + i * srcStride, width); 9705b261ecSmrg 9805b261ecSmrg return; 9905b261ecSmrg } 10005b261ecSmrg 10105b261ecSmrg FbInitializeMergeRop(alu, pm); 10205b261ecSmrg destInvarient = FbDestInvarientMergeRop(); 10305b261ecSmrg if (upsidedown) 10405b261ecSmrg { 10505b261ecSmrg srcLine += (height - 1) * (srcStride); 10605b261ecSmrg dstLine += (height - 1) * (dstStride); 10705b261ecSmrg srcStride = -srcStride; 10805b261ecSmrg dstStride = -dstStride; 10905b261ecSmrg } 11005b261ecSmrg FbMaskBitsBytes (dstX, width, destInvarient, startmask, startbyte, 11105b261ecSmrg nmiddle, endmask, endbyte); 11205b261ecSmrg if (reverse) 11305b261ecSmrg { 11405b261ecSmrg srcLine += ((srcX + width - 1) >> FB_SHIFT) + 1; 11505b261ecSmrg dstLine += ((dstX + width - 1) >> FB_SHIFT) + 1; 11605b261ecSmrg srcX = (srcX + width - 1) & FB_MASK; 11705b261ecSmrg dstX = (dstX + width - 1) & FB_MASK; 11805b261ecSmrg } 11905b261ecSmrg else 12005b261ecSmrg { 12105b261ecSmrg srcLine += srcX >> FB_SHIFT; 12205b261ecSmrg dstLine += dstX >> FB_SHIFT; 12305b261ecSmrg srcX &= FB_MASK; 12405b261ecSmrg dstX &= FB_MASK; 12505b261ecSmrg } 12605b261ecSmrg if (srcX == dstX) 12705b261ecSmrg { 12805b261ecSmrg while (height--) 12905b261ecSmrg { 13005b261ecSmrg src = srcLine; 13105b261ecSmrg srcLine += srcStride; 13205b261ecSmrg dst = dstLine; 13305b261ecSmrg dstLine += dstStride; 13405b261ecSmrg if (reverse) 13505b261ecSmrg { 13605b261ecSmrg if (endmask) 13705b261ecSmrg { 13805b261ecSmrg bits = READ(--src); 13905b261ecSmrg --dst; 14005b261ecSmrg FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask); 14105b261ecSmrg } 14205b261ecSmrg n = nmiddle; 14305b261ecSmrg if (destInvarient) 14405b261ecSmrg { 14505b261ecSmrg while (n--) 14605b261ecSmrg WRITE(--dst, FbDoDestInvarientMergeRop(READ(--src))); 14705b261ecSmrg } 14805b261ecSmrg else 14905b261ecSmrg { 15005b261ecSmrg while (n--) 15105b261ecSmrg { 15205b261ecSmrg bits = READ(--src); 15305b261ecSmrg --dst; 15405b261ecSmrg WRITE(dst, FbDoMergeRop (bits, READ(dst))); 15505b261ecSmrg } 15605b261ecSmrg } 15705b261ecSmrg if (startmask) 15805b261ecSmrg { 15905b261ecSmrg bits = READ(--src); 16005b261ecSmrg --dst; 16105b261ecSmrg FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask); 16205b261ecSmrg } 16305b261ecSmrg } 16405b261ecSmrg else 16505b261ecSmrg { 16605b261ecSmrg if (startmask) 16705b261ecSmrg { 16805b261ecSmrg bits = READ(src++); 16905b261ecSmrg FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask); 17005b261ecSmrg dst++; 17105b261ecSmrg } 17205b261ecSmrg n = nmiddle; 17305b261ecSmrg if (destInvarient) 17405b261ecSmrg { 17505b261ecSmrg#if 0 17605b261ecSmrg /* 17705b261ecSmrg * This provides some speedup on screen->screen blts 17805b261ecSmrg * over the PCI bus, usually about 10%. But fb 17905b261ecSmrg * isn't usually used for this operation... 18005b261ecSmrg */ 18105b261ecSmrg if (_ca2 + 1 == 0 && _cx2 == 0) 18205b261ecSmrg { 18305b261ecSmrg FbBits t1, t2, t3, t4; 18405b261ecSmrg while (n >= 4) 18505b261ecSmrg { 18605b261ecSmrg t1 = *src++; 18705b261ecSmrg t2 = *src++; 18805b261ecSmrg t3 = *src++; 18905b261ecSmrg t4 = *src++; 19005b261ecSmrg *dst++ = t1; 19105b261ecSmrg *dst++ = t2; 19205b261ecSmrg *dst++ = t3; 19305b261ecSmrg *dst++ = t4; 19405b261ecSmrg n -= 4; 19505b261ecSmrg } 19605b261ecSmrg } 19705b261ecSmrg#endif 19805b261ecSmrg while (n--) 19905b261ecSmrg WRITE(dst++, FbDoDestInvarientMergeRop(READ(src++))); 20005b261ecSmrg } 20105b261ecSmrg else 20205b261ecSmrg { 20305b261ecSmrg while (n--) 20405b261ecSmrg { 20505b261ecSmrg bits = READ(src++); 20605b261ecSmrg WRITE(dst, FbDoMergeRop (bits, READ(dst))); 20705b261ecSmrg dst++; 20805b261ecSmrg } 20905b261ecSmrg } 21005b261ecSmrg if (endmask) 21105b261ecSmrg { 21205b261ecSmrg bits = READ(src); 21305b261ecSmrg FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask); 21405b261ecSmrg } 21505b261ecSmrg } 21605b261ecSmrg } 21705b261ecSmrg } 21805b261ecSmrg else 21905b261ecSmrg { 22005b261ecSmrg if (srcX > dstX) 22105b261ecSmrg { 22205b261ecSmrg leftShift = srcX - dstX; 22305b261ecSmrg rightShift = FB_UNIT - leftShift; 22405b261ecSmrg } 22505b261ecSmrg else 22605b261ecSmrg { 22705b261ecSmrg rightShift = dstX - srcX; 22805b261ecSmrg leftShift = FB_UNIT - rightShift; 22905b261ecSmrg } 23005b261ecSmrg while (height--) 23105b261ecSmrg { 23205b261ecSmrg src = srcLine; 23305b261ecSmrg srcLine += srcStride; 23405b261ecSmrg dst = dstLine; 23505b261ecSmrg dstLine += dstStride; 23605b261ecSmrg 23705b261ecSmrg bits1 = 0; 23805b261ecSmrg if (reverse) 23905b261ecSmrg { 24005b261ecSmrg if (srcX < dstX) 24105b261ecSmrg bits1 = READ(--src); 24205b261ecSmrg if (endmask) 24305b261ecSmrg { 24405b261ecSmrg bits = FbScrRight(bits1, rightShift); 24505b261ecSmrg if (FbScrRight(endmask, leftShift)) 24605b261ecSmrg { 24705b261ecSmrg bits1 = READ(--src); 24805b261ecSmrg bits |= FbScrLeft(bits1, leftShift); 24905b261ecSmrg } 25005b261ecSmrg --dst; 25105b261ecSmrg FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask); 25205b261ecSmrg } 25305b261ecSmrg n = nmiddle; 25405b261ecSmrg if (destInvarient) 25505b261ecSmrg { 25605b261ecSmrg while (n--) 25705b261ecSmrg { 25805b261ecSmrg bits = FbScrRight(bits1, rightShift); 25905b261ecSmrg bits1 = READ(--src); 26005b261ecSmrg bits |= FbScrLeft(bits1, leftShift); 26105b261ecSmrg --dst; 26205b261ecSmrg WRITE(dst, FbDoDestInvarientMergeRop(bits)); 26305b261ecSmrg } 26405b261ecSmrg } 26505b261ecSmrg else 26605b261ecSmrg { 26705b261ecSmrg while (n--) 26805b261ecSmrg { 26905b261ecSmrg bits = FbScrRight(bits1, rightShift); 27005b261ecSmrg bits1 = READ(--src); 27105b261ecSmrg bits |= FbScrLeft(bits1, leftShift); 27205b261ecSmrg --dst; 27305b261ecSmrg WRITE(dst, FbDoMergeRop(bits, READ(dst))); 27405b261ecSmrg } 27505b261ecSmrg } 27605b261ecSmrg if (startmask) 27705b261ecSmrg { 27805b261ecSmrg bits = FbScrRight(bits1, rightShift); 27905b261ecSmrg if (FbScrRight(startmask, leftShift)) 28005b261ecSmrg { 28105b261ecSmrg bits1 = READ(--src); 28205b261ecSmrg bits |= FbScrLeft(bits1, leftShift); 28305b261ecSmrg } 28405b261ecSmrg --dst; 28505b261ecSmrg FbDoLeftMaskByteMergeRop (dst, bits, startbyte, startmask); 28605b261ecSmrg } 28705b261ecSmrg } 28805b261ecSmrg else 28905b261ecSmrg { 29005b261ecSmrg if (srcX > dstX) 29105b261ecSmrg bits1 = READ(src++); 29205b261ecSmrg if (startmask) 29305b261ecSmrg { 29405b261ecSmrg bits = FbScrLeft(bits1, leftShift); 29505b261ecSmrg if (FbScrLeft(startmask, rightShift)) 29605b261ecSmrg { 29705b261ecSmrg bits1 = READ(src++); 29805b261ecSmrg bits |= FbScrRight(bits1, rightShift); 29905b261ecSmrg } 30005b261ecSmrg FbDoLeftMaskByteMergeRop (dst, bits, startbyte, startmask); 30105b261ecSmrg dst++; 30205b261ecSmrg } 30305b261ecSmrg n = nmiddle; 30405b261ecSmrg if (destInvarient) 30505b261ecSmrg { 30605b261ecSmrg while (n--) 30705b261ecSmrg { 30805b261ecSmrg bits = FbScrLeft(bits1, leftShift); 30905b261ecSmrg bits1 = READ(src++); 31005b261ecSmrg bits |= FbScrRight(bits1, rightShift); 31105b261ecSmrg WRITE(dst, FbDoDestInvarientMergeRop(bits)); 31205b261ecSmrg dst++; 31305b261ecSmrg } 31405b261ecSmrg } 31505b261ecSmrg else 31605b261ecSmrg { 31705b261ecSmrg while (n--) 31805b261ecSmrg { 31905b261ecSmrg bits = FbScrLeft(bits1, leftShift); 32005b261ecSmrg bits1 = READ(src++); 32105b261ecSmrg bits |= FbScrRight(bits1, rightShift); 32205b261ecSmrg WRITE(dst, FbDoMergeRop(bits, READ(dst))); 32305b261ecSmrg dst++; 32405b261ecSmrg } 32505b261ecSmrg } 32605b261ecSmrg if (endmask) 32705b261ecSmrg { 32805b261ecSmrg bits = FbScrLeft(bits1, leftShift); 32905b261ecSmrg if (FbScrLeft(endmask, rightShift)) 33005b261ecSmrg { 33105b261ecSmrg bits1 = READ(src); 33205b261ecSmrg bits |= FbScrRight(bits1, rightShift); 33305b261ecSmrg } 33405b261ecSmrg FbDoRightMaskByteMergeRop (dst, bits, endbyte, endmask); 33505b261ecSmrg } 33605b261ecSmrg } 33705b261ecSmrg } 33805b261ecSmrg } 33905b261ecSmrg} 34005b261ecSmrg 34105b261ecSmrg#ifdef FB_24BIT 34205b261ecSmrg 34305b261ecSmrg#undef DEBUG_BLT24 34405b261ecSmrg#ifdef DEBUG_BLT24 34505b261ecSmrg 34605b261ecSmrgstatic unsigned long 34705b261ecSmrggetPixel (char *src, int x) 34805b261ecSmrg{ 34905b261ecSmrg unsigned long l; 35005b261ecSmrg 35105b261ecSmrg l = 0; 35205b261ecSmrg memcpy (&l, src + x * 3, 3); 35305b261ecSmrg return l; 35405b261ecSmrg} 35505b261ecSmrg#endif 35605b261ecSmrg 35705b261ecSmrgstatic void 35805b261ecSmrgfbBlt24Line (FbBits *src, 35905b261ecSmrg int srcX, 36005b261ecSmrg 36105b261ecSmrg FbBits *dst, 36205b261ecSmrg int dstX, 36305b261ecSmrg 36405b261ecSmrg int width, 36505b261ecSmrg 36605b261ecSmrg int alu, 36705b261ecSmrg FbBits pm, 36805b261ecSmrg 36905b261ecSmrg Bool reverse) 37005b261ecSmrg{ 37105b261ecSmrg#ifdef DEBUG_BLT24 37205b261ecSmrg char *origDst = (char *) dst; 37305b261ecSmrg FbBits *origLine = dst + ((dstX >> FB_SHIFT) - 1); 37405b261ecSmrg int origNlw = ((width + FB_MASK) >> FB_SHIFT) + 3; 37505b261ecSmrg int origX = dstX / 24; 37605b261ecSmrg#endif 37705b261ecSmrg 37805b261ecSmrg int leftShift, rightShift; 37905b261ecSmrg FbBits startmask, endmask; 38005b261ecSmrg int n; 38105b261ecSmrg 38205b261ecSmrg FbBits bits, bits1; 38305b261ecSmrg FbBits mask; 38405b261ecSmrg 38505b261ecSmrg int rot; 38605b261ecSmrg FbDeclareMergeRop (); 38705b261ecSmrg 38805b261ecSmrg FbInitializeMergeRop (alu, FB_ALLONES); 38905b261ecSmrg FbMaskBits(dstX, width, startmask, n, endmask); 39005b261ecSmrg#ifdef DEBUG_BLT24 39105b261ecSmrg ErrorF ("dstX %d width %d reverse %d\n", dstX, width, reverse); 39205b261ecSmrg#endif 39305b261ecSmrg if (reverse) 39405b261ecSmrg { 39505b261ecSmrg src += ((srcX + width - 1) >> FB_SHIFT) + 1; 39605b261ecSmrg dst += ((dstX + width - 1) >> FB_SHIFT) + 1; 39705b261ecSmrg rot = FbFirst24Rot (((dstX + width - 8) & FB_MASK)); 39805b261ecSmrg rot = FbPrev24Rot(rot); 39905b261ecSmrg#ifdef DEBUG_BLT24 40005b261ecSmrg ErrorF ("dstX + width - 8: %d rot: %d\n", (dstX + width - 8) & FB_MASK, rot); 40105b261ecSmrg#endif 40205b261ecSmrg srcX = (srcX + width - 1) & FB_MASK; 40305b261ecSmrg dstX = (dstX + width - 1) & FB_MASK; 40405b261ecSmrg } 40505b261ecSmrg else 40605b261ecSmrg { 40705b261ecSmrg src += srcX >> FB_SHIFT; 40805b261ecSmrg dst += dstX >> FB_SHIFT; 40905b261ecSmrg srcX &= FB_MASK; 41005b261ecSmrg dstX &= FB_MASK; 41105b261ecSmrg rot = FbFirst24Rot (dstX); 41205b261ecSmrg#ifdef DEBUG_BLT24 41305b261ecSmrg ErrorF ("dstX: %d rot: %d\n", dstX, rot); 41405b261ecSmrg#endif 41505b261ecSmrg } 41605b261ecSmrg mask = FbRot24(pm,rot); 41705b261ecSmrg#ifdef DEBUG_BLT24 41805b261ecSmrg ErrorF ("pm 0x%x mask 0x%x\n", pm, mask); 41905b261ecSmrg#endif 42005b261ecSmrg if (srcX == dstX) 42105b261ecSmrg { 42205b261ecSmrg if (reverse) 42305b261ecSmrg { 42405b261ecSmrg if (endmask) 42505b261ecSmrg { 42605b261ecSmrg bits = READ(--src); 42705b261ecSmrg --dst; 42805b261ecSmrg WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask & endmask)); 42905b261ecSmrg mask = FbPrev24Pix (mask); 43005b261ecSmrg } 43105b261ecSmrg while (n--) 43205b261ecSmrg { 43305b261ecSmrg bits = READ(--src); 43405b261ecSmrg --dst; 43505b261ecSmrg WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask)); 43605b261ecSmrg mask = FbPrev24Pix (mask); 43705b261ecSmrg } 43805b261ecSmrg if (startmask) 43905b261ecSmrg { 44005b261ecSmrg bits = READ(--src); 44105b261ecSmrg --dst; 44205b261ecSmrg WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask & startmask)); 44305b261ecSmrg } 44405b261ecSmrg } 44505b261ecSmrg else 44605b261ecSmrg { 44705b261ecSmrg if (startmask) 44805b261ecSmrg { 44905b261ecSmrg bits = READ(src++); 45005b261ecSmrg WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask & startmask)); 45105b261ecSmrg dst++; 45205b261ecSmrg mask = FbNext24Pix(mask); 45305b261ecSmrg } 45405b261ecSmrg while (n--) 45505b261ecSmrg { 45605b261ecSmrg bits = READ(src++); 45705b261ecSmrg WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask)); 45805b261ecSmrg dst++; 45905b261ecSmrg mask = FbNext24Pix(mask); 46005b261ecSmrg } 46105b261ecSmrg if (endmask) 46205b261ecSmrg { 46305b261ecSmrg bits = READ(src); 46405b261ecSmrg WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask & endmask)); 46505b261ecSmrg } 46605b261ecSmrg } 46705b261ecSmrg } 46805b261ecSmrg else 46905b261ecSmrg { 47005b261ecSmrg if (srcX > dstX) 47105b261ecSmrg { 47205b261ecSmrg leftShift = srcX - dstX; 47305b261ecSmrg rightShift = FB_UNIT - leftShift; 47405b261ecSmrg } 47505b261ecSmrg else 47605b261ecSmrg { 47705b261ecSmrg rightShift = dstX - srcX; 47805b261ecSmrg leftShift = FB_UNIT - rightShift; 47905b261ecSmrg } 48005b261ecSmrg 48105b261ecSmrg bits1 = 0; 48205b261ecSmrg if (reverse) 48305b261ecSmrg { 48405b261ecSmrg if (srcX < dstX) 48505b261ecSmrg bits1 = READ(--src); 48605b261ecSmrg if (endmask) 48705b261ecSmrg { 48805b261ecSmrg bits = FbScrRight(bits1, rightShift); 48905b261ecSmrg if (FbScrRight(endmask, leftShift)) 49005b261ecSmrg { 49105b261ecSmrg bits1 = READ(--src); 49205b261ecSmrg bits |= FbScrLeft(bits1, leftShift); 49305b261ecSmrg } 49405b261ecSmrg --dst; 49505b261ecSmrg WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask & endmask)); 49605b261ecSmrg mask = FbPrev24Pix(mask); 49705b261ecSmrg } 49805b261ecSmrg while (n--) 49905b261ecSmrg { 50005b261ecSmrg bits = FbScrRight(bits1, rightShift); 50105b261ecSmrg bits1 = READ(--src); 50205b261ecSmrg bits |= FbScrLeft(bits1, leftShift); 50305b261ecSmrg --dst; 50405b261ecSmrg WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask)); 50505b261ecSmrg mask = FbPrev24Pix(mask); 50605b261ecSmrg } 50705b261ecSmrg if (startmask) 50805b261ecSmrg { 50905b261ecSmrg bits = FbScrRight(bits1, rightShift); 51005b261ecSmrg if (FbScrRight(startmask, leftShift)) 51105b261ecSmrg { 51205b261ecSmrg bits1 = READ(--src); 51305b261ecSmrg bits |= FbScrLeft(bits1, leftShift); 51405b261ecSmrg } 51505b261ecSmrg --dst; 51605b261ecSmrg WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask & startmask)); 51705b261ecSmrg } 51805b261ecSmrg } 51905b261ecSmrg else 52005b261ecSmrg { 52105b261ecSmrg if (srcX > dstX) 52205b261ecSmrg bits1 = READ(src++); 52305b261ecSmrg if (startmask) 52405b261ecSmrg { 52505b261ecSmrg bits = FbScrLeft(bits1, leftShift); 52605b261ecSmrg bits1 = READ(src++); 52705b261ecSmrg bits |= FbScrRight(bits1, rightShift); 52805b261ecSmrg WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask & startmask)); 52905b261ecSmrg dst++; 53005b261ecSmrg mask = FbNext24Pix(mask); 53105b261ecSmrg } 53205b261ecSmrg while (n--) 53305b261ecSmrg { 53405b261ecSmrg bits = FbScrLeft(bits1, leftShift); 53505b261ecSmrg bits1 = READ(src++); 53605b261ecSmrg bits |= FbScrRight(bits1, rightShift); 53705b261ecSmrg WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask)); 53805b261ecSmrg dst++; 53905b261ecSmrg mask = FbNext24Pix(mask); 54005b261ecSmrg } 54105b261ecSmrg if (endmask) 54205b261ecSmrg { 54305b261ecSmrg bits = FbScrLeft(bits1, leftShift); 54405b261ecSmrg if (FbScrLeft(endmask, rightShift)) 54505b261ecSmrg { 54605b261ecSmrg bits1 = READ(src); 54705b261ecSmrg bits |= FbScrRight(bits1, rightShift); 54805b261ecSmrg } 54905b261ecSmrg WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask & endmask)); 55005b261ecSmrg } 55105b261ecSmrg } 55205b261ecSmrg } 55305b261ecSmrg#ifdef DEBUG_BLT24 55405b261ecSmrg { 55505b261ecSmrg int firstx, lastx, x; 55605b261ecSmrg 55705b261ecSmrg firstx = origX; 55805b261ecSmrg if (firstx) 55905b261ecSmrg firstx--; 56005b261ecSmrg lastx = origX + width/24 + 1; 56105b261ecSmrg for (x = firstx; x <= lastx; x++) 56205b261ecSmrg ErrorF ("%06x ", getPixel (origDst, x)); 56305b261ecSmrg ErrorF ("\n"); 56405b261ecSmrg while (origNlw--) 56505b261ecSmrg ErrorF ("%08x ", *origLine++); 56605b261ecSmrg ErrorF ("\n"); 56705b261ecSmrg } 56805b261ecSmrg#endif 56905b261ecSmrg} 57005b261ecSmrg 57105b261ecSmrgvoid 57205b261ecSmrgfbBlt24 (FbBits *srcLine, 57305b261ecSmrg FbStride srcStride, 57405b261ecSmrg int srcX, 57505b261ecSmrg 57605b261ecSmrg FbBits *dstLine, 57705b261ecSmrg FbStride dstStride, 57805b261ecSmrg int dstX, 57905b261ecSmrg 58005b261ecSmrg int width, 58105b261ecSmrg int height, 58205b261ecSmrg 58305b261ecSmrg int alu, 58405b261ecSmrg FbBits pm, 58505b261ecSmrg 58605b261ecSmrg Bool reverse, 58705b261ecSmrg Bool upsidedown) 58805b261ecSmrg{ 58905b261ecSmrg if (upsidedown) 59005b261ecSmrg { 59105b261ecSmrg srcLine += (height-1) * srcStride; 59205b261ecSmrg dstLine += (height-1) * dstStride; 59305b261ecSmrg srcStride = -srcStride; 59405b261ecSmrg dstStride = -dstStride; 59505b261ecSmrg } 59605b261ecSmrg while (height--) 59705b261ecSmrg { 59805b261ecSmrg fbBlt24Line (srcLine, srcX, dstLine, dstX, width, alu, pm, reverse); 59905b261ecSmrg srcLine += srcStride; 60005b261ecSmrg dstLine += dstStride; 60105b261ecSmrg } 60205b261ecSmrg#ifdef DEBUG_BLT24 60305b261ecSmrg ErrorF ("\n"); 60405b261ecSmrg#endif 60505b261ecSmrg} 60605b261ecSmrg#endif /* FB_24BIT */ 60705b261ecSmrg 60805b261ecSmrg#if FB_SHIFT == FB_STIP_SHIFT + 1 60905b261ecSmrg 61005b261ecSmrg/* 61105b261ecSmrg * Could be generalized to FB_SHIFT > FB_STIP_SHIFT + 1 by 61205b261ecSmrg * creating an ring of values stepped through for each line 61305b261ecSmrg */ 61405b261ecSmrg 61505b261ecSmrgvoid 61605b261ecSmrgfbBltOdd (FbBits *srcLine, 61705b261ecSmrg FbStride srcStrideEven, 61805b261ecSmrg FbStride srcStrideOdd, 61905b261ecSmrg int srcXEven, 62005b261ecSmrg int srcXOdd, 62105b261ecSmrg 62205b261ecSmrg FbBits *dstLine, 62305b261ecSmrg FbStride dstStrideEven, 62405b261ecSmrg FbStride dstStrideOdd, 62505b261ecSmrg int dstXEven, 62605b261ecSmrg int dstXOdd, 62705b261ecSmrg 62805b261ecSmrg int width, 62905b261ecSmrg int height, 63005b261ecSmrg 63105b261ecSmrg int alu, 63205b261ecSmrg FbBits pm, 63305b261ecSmrg int bpp) 63405b261ecSmrg{ 63505b261ecSmrg FbBits *src; 63605b261ecSmrg int leftShiftEven, rightShiftEven; 63705b261ecSmrg FbBits startmaskEven, endmaskEven; 63805b261ecSmrg int nmiddleEven; 63905b261ecSmrg 64005b261ecSmrg FbBits *dst; 64105b261ecSmrg int leftShiftOdd, rightShiftOdd; 64205b261ecSmrg FbBits startmaskOdd, endmaskOdd; 64305b261ecSmrg int nmiddleOdd; 64405b261ecSmrg 64505b261ecSmrg int leftShift, rightShift; 64605b261ecSmrg FbBits startmask, endmask; 64705b261ecSmrg int nmiddle; 64805b261ecSmrg 64905b261ecSmrg int srcX, dstX; 65005b261ecSmrg 65105b261ecSmrg FbBits bits, bits1; 65205b261ecSmrg int n; 65305b261ecSmrg 65405b261ecSmrg Bool destInvarient; 65505b261ecSmrg Bool even; 65605b261ecSmrg FbDeclareMergeRop (); 65705b261ecSmrg 65805b261ecSmrg FbInitializeMergeRop (alu, pm); 65905b261ecSmrg destInvarient = FbDestInvarientMergeRop(); 66005b261ecSmrg 66105b261ecSmrg srcLine += srcXEven >> FB_SHIFT; 66205b261ecSmrg dstLine += dstXEven >> FB_SHIFT; 66305b261ecSmrg srcXEven &= FB_MASK; 66405b261ecSmrg dstXEven &= FB_MASK; 66505b261ecSmrg srcXOdd &= FB_MASK; 66605b261ecSmrg dstXOdd &= FB_MASK; 66705b261ecSmrg 66805b261ecSmrg FbMaskBits(dstXEven, width, startmaskEven, nmiddleEven, endmaskEven); 66905b261ecSmrg FbMaskBits(dstXOdd, width, startmaskOdd, nmiddleOdd, endmaskOdd); 67005b261ecSmrg 67105b261ecSmrg even = TRUE; 67205b261ecSmrg InitializeShifts(srcXEven, dstXEven, leftShiftEven, rightShiftEven); 67305b261ecSmrg InitializeShifts(srcXOdd, dstXOdd, leftShiftOdd, rightShiftOdd); 67405b261ecSmrg while (height--) 67505b261ecSmrg { 67605b261ecSmrg src = srcLine; 67705b261ecSmrg dst = dstLine; 67805b261ecSmrg if (even) 67905b261ecSmrg { 68005b261ecSmrg srcX = srcXEven; 68105b261ecSmrg dstX = dstXEven; 68205b261ecSmrg startmask = startmaskEven; 68305b261ecSmrg endmask = endmaskEven; 68405b261ecSmrg nmiddle = nmiddleEven; 68505b261ecSmrg leftShift = leftShiftEven; 68605b261ecSmrg rightShift = rightShiftEven; 68705b261ecSmrg srcLine += srcStrideEven; 68805b261ecSmrg dstLine += dstStrideEven; 68905b261ecSmrg even = FALSE; 69005b261ecSmrg } 69105b261ecSmrg else 69205b261ecSmrg { 69305b261ecSmrg srcX = srcXOdd; 69405b261ecSmrg dstX = dstXOdd; 69505b261ecSmrg startmask = startmaskOdd; 69605b261ecSmrg endmask = endmaskOdd; 69705b261ecSmrg nmiddle = nmiddleOdd; 69805b261ecSmrg leftShift = leftShiftOdd; 69905b261ecSmrg rightShift = rightShiftOdd; 70005b261ecSmrg srcLine += srcStrideOdd; 70105b261ecSmrg dstLine += dstStrideOdd; 70205b261ecSmrg even = TRUE; 70305b261ecSmrg } 70405b261ecSmrg if (srcX == dstX) 70505b261ecSmrg { 70605b261ecSmrg if (startmask) 70705b261ecSmrg { 70805b261ecSmrg bits = READ(src++); 70905b261ecSmrg WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), startmask)); 71005b261ecSmrg dst++; 71105b261ecSmrg } 71205b261ecSmrg n = nmiddle; 71305b261ecSmrg if (destInvarient) 71405b261ecSmrg { 71505b261ecSmrg while (n--) 71605b261ecSmrg { 71705b261ecSmrg bits = READ(src++); 71805b261ecSmrg WRITE(dst, FbDoDestInvarientMergeRop(bits)); 71905b261ecSmrg dst++; 72005b261ecSmrg } 72105b261ecSmrg } 72205b261ecSmrg else 72305b261ecSmrg { 72405b261ecSmrg while (n--) 72505b261ecSmrg { 72605b261ecSmrg bits = READ(src++); 72705b261ecSmrg WRITE(dst, FbDoMergeRop (bits, READ(dst))); 72805b261ecSmrg dst++; 72905b261ecSmrg } 73005b261ecSmrg } 73105b261ecSmrg if (endmask) 73205b261ecSmrg { 73305b261ecSmrg bits = READ(src); 73405b261ecSmrg WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), endmask)); 73505b261ecSmrg } 73605b261ecSmrg } 73705b261ecSmrg else 73805b261ecSmrg { 73905b261ecSmrg bits = 0; 74005b261ecSmrg if (srcX > dstX) 74105b261ecSmrg bits = READ(src++); 74205b261ecSmrg if (startmask) 74305b261ecSmrg { 74405b261ecSmrg bits1 = FbScrLeft(bits, leftShift); 74505b261ecSmrg bits = READ(src++); 74605b261ecSmrg bits1 |= FbScrRight(bits, rightShift); 74705b261ecSmrg WRITE(dst, FbDoMaskMergeRop (bits1, READ(dst), startmask)); 74805b261ecSmrg dst++; 74905b261ecSmrg } 75005b261ecSmrg n = nmiddle; 75105b261ecSmrg if (destInvarient) 75205b261ecSmrg { 75305b261ecSmrg while (n--) 75405b261ecSmrg { 75505b261ecSmrg bits1 = FbScrLeft(bits, leftShift); 75605b261ecSmrg bits = READ(src++); 75705b261ecSmrg bits1 |= FbScrRight(bits, rightShift); 75805b261ecSmrg WRITE(dst, FbDoDestInvarientMergeRop(bits1)); 75905b261ecSmrg dst++; 76005b261ecSmrg } 76105b261ecSmrg } 76205b261ecSmrg else 76305b261ecSmrg { 76405b261ecSmrg while (n--) 76505b261ecSmrg { 76605b261ecSmrg bits1 = FbScrLeft(bits, leftShift); 76705b261ecSmrg bits = READ(src++); 76805b261ecSmrg bits1 |= FbScrRight(bits, rightShift); 76905b261ecSmrg WRITE(dst, FbDoMergeRop(bits1, READ(dst))); 77005b261ecSmrg dst++; 77105b261ecSmrg } 77205b261ecSmrg } 77305b261ecSmrg if (endmask) 77405b261ecSmrg { 77505b261ecSmrg bits1 = FbScrLeft(bits, leftShift); 77605b261ecSmrg if (FbScrLeft(endmask, rightShift)) 77705b261ecSmrg { 77805b261ecSmrg bits = READ(src); 77905b261ecSmrg bits1 |= FbScrRight(bits, rightShift); 78005b261ecSmrg } 78105b261ecSmrg WRITE(dst, FbDoMaskMergeRop (bits1, READ(dst), endmask)); 78205b261ecSmrg } 78305b261ecSmrg } 78405b261ecSmrg } 78505b261ecSmrg} 78605b261ecSmrg 78705b261ecSmrg#ifdef FB_24BIT 78805b261ecSmrgvoid 78905b261ecSmrgfbBltOdd24 (FbBits *srcLine, 79005b261ecSmrg FbStride srcStrideEven, 79105b261ecSmrg FbStride srcStrideOdd, 79205b261ecSmrg int srcXEven, 79305b261ecSmrg int srcXOdd, 79405b261ecSmrg 79505b261ecSmrg FbBits *dstLine, 79605b261ecSmrg FbStride dstStrideEven, 79705b261ecSmrg FbStride dstStrideOdd, 79805b261ecSmrg int dstXEven, 79905b261ecSmrg int dstXOdd, 80005b261ecSmrg 80105b261ecSmrg int width, 80205b261ecSmrg int height, 80305b261ecSmrg 80405b261ecSmrg int alu, 80505b261ecSmrg FbBits pm) 80605b261ecSmrg{ 80705b261ecSmrg Bool even = TRUE; 80805b261ecSmrg 80905b261ecSmrg while (height--) 81005b261ecSmrg { 81105b261ecSmrg if (even) 81205b261ecSmrg { 81305b261ecSmrg fbBlt24Line (srcLine, srcXEven, dstLine, dstXEven, 81405b261ecSmrg width, alu, pm, FALSE); 81505b261ecSmrg srcLine += srcStrideEven; 81605b261ecSmrg dstLine += dstStrideEven; 81705b261ecSmrg even = FALSE; 81805b261ecSmrg } 81905b261ecSmrg else 82005b261ecSmrg { 82105b261ecSmrg fbBlt24Line (srcLine, srcXOdd, dstLine, dstXOdd, 82205b261ecSmrg width, alu, pm, FALSE); 82305b261ecSmrg srcLine += srcStrideOdd; 82405b261ecSmrg dstLine += dstStrideOdd; 82505b261ecSmrg even = TRUE; 82605b261ecSmrg } 82705b261ecSmrg } 82805b261ecSmrg#if 0 82905b261ecSmrg fprintf (stderr, "\n"); 83005b261ecSmrg#endif 83105b261ecSmrg} 83205b261ecSmrg#endif 83305b261ecSmrg 83405b261ecSmrg#endif 83505b261ecSmrg 83605b261ecSmrg#if FB_STIP_SHIFT != FB_SHIFT 83705b261ecSmrgvoid 83805b261ecSmrgfbSetBltOdd (FbStip *stip, 83905b261ecSmrg FbStride stipStride, 84005b261ecSmrg int srcX, 84105b261ecSmrg FbBits **bits, 84205b261ecSmrg FbStride *strideEven, 84305b261ecSmrg FbStride *strideOdd, 84405b261ecSmrg int *srcXEven, 84505b261ecSmrg int *srcXOdd) 84605b261ecSmrg{ 84705b261ecSmrg int srcAdjust; 84805b261ecSmrg int strideAdjust; 84905b261ecSmrg 85005b261ecSmrg /* 85105b261ecSmrg * bytes needed to align source 85205b261ecSmrg */ 85305b261ecSmrg srcAdjust = (((int) stip) & (FB_MASK >> 3)); 85405b261ecSmrg /* 85505b261ecSmrg * FbStip units needed to align stride 85605b261ecSmrg */ 85705b261ecSmrg strideAdjust = stipStride & (FB_MASK >> FB_STIP_SHIFT); 85805b261ecSmrg 85905b261ecSmrg *bits = (FbBits *) ((char *) stip - srcAdjust); 86005b261ecSmrg if (srcAdjust) 86105b261ecSmrg { 86205b261ecSmrg *strideEven = FbStipStrideToBitsStride (stipStride + 1); 86305b261ecSmrg *strideOdd = FbStipStrideToBitsStride (stipStride); 86405b261ecSmrg 86505b261ecSmrg *srcXEven = srcX + (srcAdjust << 3); 86605b261ecSmrg *srcXOdd = srcX + (srcAdjust << 3) - (strideAdjust << FB_STIP_SHIFT); 86705b261ecSmrg } 86805b261ecSmrg else 86905b261ecSmrg { 87005b261ecSmrg *strideEven = FbStipStrideToBitsStride (stipStride); 87105b261ecSmrg *strideOdd = FbStipStrideToBitsStride (stipStride + 1); 87205b261ecSmrg 87305b261ecSmrg *srcXEven = srcX; 87405b261ecSmrg *srcXOdd = srcX + (strideAdjust << FB_STIP_SHIFT); 87505b261ecSmrg } 87605b261ecSmrg} 87705b261ecSmrg#endif 87805b261ecSmrg 87905b261ecSmrgvoid 88005b261ecSmrgfbBltStip (FbStip *src, 88105b261ecSmrg FbStride srcStride, /* in FbStip units, not FbBits units */ 88205b261ecSmrg int srcX, 88305b261ecSmrg 88405b261ecSmrg FbStip *dst, 88505b261ecSmrg FbStride dstStride, /* in FbStip units, not FbBits units */ 88605b261ecSmrg int dstX, 88705b261ecSmrg 88805b261ecSmrg int width, 88905b261ecSmrg int height, 89005b261ecSmrg 89105b261ecSmrg int alu, 89205b261ecSmrg FbBits pm, 89305b261ecSmrg int bpp) 89405b261ecSmrg{ 89505b261ecSmrg#if FB_STIP_SHIFT != FB_SHIFT 89605b261ecSmrg if (FB_STIP_ODDSTRIDE(srcStride) || FB_STIP_ODDPTR(src) || 89705b261ecSmrg FB_STIP_ODDSTRIDE(dstStride) || FB_STIP_ODDPTR(dst)) 89805b261ecSmrg { 89905b261ecSmrg FbStride srcStrideEven, srcStrideOdd; 90005b261ecSmrg FbStride dstStrideEven, dstStrideOdd; 90105b261ecSmrg int srcXEven, srcXOdd; 90205b261ecSmrg int dstXEven, dstXOdd; 90305b261ecSmrg FbBits *s, *d; 90405b261ecSmrg int sx, dx; 90505b261ecSmrg 90605b261ecSmrg src += srcX >> FB_STIP_SHIFT; 90705b261ecSmrg srcX &= FB_STIP_MASK; 90805b261ecSmrg dst += dstX >> FB_STIP_SHIFT; 90905b261ecSmrg dstX &= FB_STIP_MASK; 91005b261ecSmrg 91105b261ecSmrg fbSetBltOdd (src, srcStride, srcX, 91205b261ecSmrg &s, 91305b261ecSmrg &srcStrideEven, &srcStrideOdd, 91405b261ecSmrg &srcXEven, &srcXOdd); 91505b261ecSmrg 91605b261ecSmrg fbSetBltOdd (dst, dstStride, dstX, 91705b261ecSmrg &d, 91805b261ecSmrg &dstStrideEven, &dstStrideOdd, 91905b261ecSmrg &dstXEven, &dstXOdd); 92005b261ecSmrg 92105b261ecSmrg#ifdef FB_24BIT 92205b261ecSmrg if (bpp == 24 && !FbCheck24Pix (pm)) 92305b261ecSmrg { 92405b261ecSmrg fbBltOdd24 (s, srcStrideEven, srcStrideOdd, 92505b261ecSmrg srcXEven, srcXOdd, 92605b261ecSmrg 92705b261ecSmrg d, dstStrideEven, dstStrideOdd, 92805b261ecSmrg dstXEven, dstXOdd, 92905b261ecSmrg 93005b261ecSmrg width, height, alu, pm); 93105b261ecSmrg } 93205b261ecSmrg else 93305b261ecSmrg#endif 93405b261ecSmrg { 93505b261ecSmrg fbBltOdd (s, srcStrideEven, srcStrideOdd, 93605b261ecSmrg srcXEven, srcXOdd, 93705b261ecSmrg 93805b261ecSmrg d, dstStrideEven, dstStrideOdd, 93905b261ecSmrg dstXEven, dstXOdd, 94005b261ecSmrg 94105b261ecSmrg width, height, alu, pm, bpp); 94205b261ecSmrg } 94305b261ecSmrg } 94405b261ecSmrg else 94505b261ecSmrg#endif 94605b261ecSmrg { 94705b261ecSmrg fbBlt ((FbBits *) src, FbStipStrideToBitsStride (srcStride), 94805b261ecSmrg srcX, 94905b261ecSmrg (FbBits *) dst, FbStipStrideToBitsStride (dstStride), 95005b261ecSmrg dstX, 95105b261ecSmrg width, height, 95205b261ecSmrg alu, pm, bpp, FALSE, FALSE); 95305b261ecSmrg } 95405b261ecSmrg} 955