fbblt.c revision 35c4bbdf
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 4335c4bbdfSmrgfbBlt(FbBits * srcLine, 4435c4bbdfSmrg FbStride srcStride, 4535c4bbdfSmrg int srcX, 4635c4bbdfSmrg FbBits * dstLine, 4735c4bbdfSmrg FbStride dstStride, 4835c4bbdfSmrg int dstX, 4935c4bbdfSmrg int width, 5035c4bbdfSmrg int height, int alu, FbBits pm, int bpp, Bool reverse, Bool upsidedown) 5105b261ecSmrg{ 5235c4bbdfSmrg FbBits *src, *dst; 5335c4bbdfSmrg int leftShift, rightShift; 5435c4bbdfSmrg FbBits startmask, endmask; 5535c4bbdfSmrg FbBits bits, bits1; 5635c4bbdfSmrg int n, nmiddle; 5735c4bbdfSmrg Bool destInvarient; 5835c4bbdfSmrg int startbyte, endbyte; 5935c4bbdfSmrg 6035c4bbdfSmrg FbDeclareMergeRop(); 6135c4bbdfSmrg 6235c4bbdfSmrg if (alu == GXcopy && pm == FB_ALLONES && 6335c4bbdfSmrg !(srcX & 7) && !(dstX & 7) && !(width & 7)) 6405b261ecSmrg { 6535c4bbdfSmrg CARD8 *src_byte = (CARD8 *) srcLine + (srcX >> 3); 6635c4bbdfSmrg CARD8 *dst_byte = (CARD8 *) dstLine + (dstX >> 3); 6735c4bbdfSmrg FbStride src_byte_stride = srcStride << (FB_SHIFT - 3); 6835c4bbdfSmrg FbStride dst_byte_stride = dstStride << (FB_SHIFT - 3); 6935c4bbdfSmrg int width_byte = (width >> 3); 7035c4bbdfSmrg 7135c4bbdfSmrg /* Make sure there's no overlap; we can't use memcpy in that 7235c4bbdfSmrg * case as it's not well defined, so fall through to the 7335c4bbdfSmrg * general code 7435c4bbdfSmrg */ 7535c4bbdfSmrg if (src_byte + width_byte <= dst_byte || 7635c4bbdfSmrg dst_byte + width_byte <= src_byte) 7735c4bbdfSmrg { 7835c4bbdfSmrg int i; 7935c4bbdfSmrg 8035c4bbdfSmrg if (!upsidedown) 8135c4bbdfSmrg for (i = 0; i < height; i++) 8235c4bbdfSmrg MEMCPY_WRAPPED(dst_byte + i * dst_byte_stride, 8335c4bbdfSmrg src_byte + i * src_byte_stride, 8435c4bbdfSmrg width_byte); 8535c4bbdfSmrg else 8635c4bbdfSmrg for (i = height - 1; i >= 0; i--) 8735c4bbdfSmrg MEMCPY_WRAPPED(dst_byte + i * dst_byte_stride, 8835c4bbdfSmrg src_byte + i * src_byte_stride, 8935c4bbdfSmrg width_byte); 9035c4bbdfSmrg 9135c4bbdfSmrg return; 9235c4bbdfSmrg } 9305b261ecSmrg } 9405b261ecSmrg 9535c4bbdfSmrg if (bpp == 24 && !FbCheck24Pix(pm)) { 9635c4bbdfSmrg fbBlt24(srcLine, srcStride, srcX, dstLine, dstStride, dstX, 9735c4bbdfSmrg width, height, alu, pm, reverse, upsidedown); 9805b261ecSmrg return; 9905b261ecSmrg } 10005b261ecSmrg 10105b261ecSmrg FbInitializeMergeRop(alu, pm); 10205b261ecSmrg destInvarient = FbDestInvarientMergeRop(); 10335c4bbdfSmrg if (upsidedown) { 10435c4bbdfSmrg srcLine += (height - 1) * (srcStride); 10535c4bbdfSmrg dstLine += (height - 1) * (dstStride); 10635c4bbdfSmrg srcStride = -srcStride; 10735c4bbdfSmrg dstStride = -dstStride; 10805b261ecSmrg } 10935c4bbdfSmrg FbMaskBitsBytes(dstX, width, destInvarient, startmask, startbyte, 11035c4bbdfSmrg nmiddle, endmask, endbyte); 11135c4bbdfSmrg if (reverse) { 11235c4bbdfSmrg srcLine += ((srcX + width - 1) >> FB_SHIFT) + 1; 11335c4bbdfSmrg dstLine += ((dstX + width - 1) >> FB_SHIFT) + 1; 11435c4bbdfSmrg srcX = (srcX + width - 1) & FB_MASK; 11535c4bbdfSmrg dstX = (dstX + width - 1) & FB_MASK; 11605b261ecSmrg } 11735c4bbdfSmrg else { 11835c4bbdfSmrg srcLine += srcX >> FB_SHIFT; 11935c4bbdfSmrg dstLine += dstX >> FB_SHIFT; 12035c4bbdfSmrg srcX &= FB_MASK; 12135c4bbdfSmrg dstX &= FB_MASK; 12205b261ecSmrg } 12335c4bbdfSmrg if (srcX == dstX) { 12435c4bbdfSmrg while (height--) { 12535c4bbdfSmrg src = srcLine; 12635c4bbdfSmrg srcLine += srcStride; 12735c4bbdfSmrg dst = dstLine; 12835c4bbdfSmrg dstLine += dstStride; 12935c4bbdfSmrg if (reverse) { 13035c4bbdfSmrg if (endmask) { 13135c4bbdfSmrg bits = READ(--src); 13235c4bbdfSmrg --dst; 13335c4bbdfSmrg FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask); 13435c4bbdfSmrg } 13535c4bbdfSmrg n = nmiddle; 13635c4bbdfSmrg if (destInvarient) { 13735c4bbdfSmrg while (n--) 13835c4bbdfSmrg WRITE(--dst, FbDoDestInvarientMergeRop(READ(--src))); 13935c4bbdfSmrg } 14035c4bbdfSmrg else { 14135c4bbdfSmrg while (n--) { 14235c4bbdfSmrg bits = READ(--src); 14335c4bbdfSmrg --dst; 14435c4bbdfSmrg WRITE(dst, FbDoMergeRop(bits, READ(dst))); 14535c4bbdfSmrg } 14635c4bbdfSmrg } 14735c4bbdfSmrg if (startmask) { 14835c4bbdfSmrg bits = READ(--src); 14935c4bbdfSmrg --dst; 15035c4bbdfSmrg FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask); 15135c4bbdfSmrg } 15235c4bbdfSmrg } 15335c4bbdfSmrg else { 15435c4bbdfSmrg if (startmask) { 15535c4bbdfSmrg bits = READ(src++); 15635c4bbdfSmrg FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask); 15735c4bbdfSmrg dst++; 15835c4bbdfSmrg } 15935c4bbdfSmrg n = nmiddle; 16035c4bbdfSmrg if (destInvarient) { 16105b261ecSmrg#if 0 16235c4bbdfSmrg /* 16335c4bbdfSmrg * This provides some speedup on screen->screen blts 16435c4bbdfSmrg * over the PCI bus, usually about 10%. But fb 16535c4bbdfSmrg * isn't usually used for this operation... 16635c4bbdfSmrg */ 16735c4bbdfSmrg if (_ca2 + 1 == 0 && _cx2 == 0) { 16835c4bbdfSmrg FbBits t1, t2, t3, t4; 16935c4bbdfSmrg 17035c4bbdfSmrg while (n >= 4) { 17135c4bbdfSmrg t1 = *src++; 17235c4bbdfSmrg t2 = *src++; 17335c4bbdfSmrg t3 = *src++; 17435c4bbdfSmrg t4 = *src++; 17535c4bbdfSmrg *dst++ = t1; 17635c4bbdfSmrg *dst++ = t2; 17735c4bbdfSmrg *dst++ = t3; 17835c4bbdfSmrg *dst++ = t4; 17935c4bbdfSmrg n -= 4; 18035c4bbdfSmrg } 18135c4bbdfSmrg } 18205b261ecSmrg#endif 18335c4bbdfSmrg while (n--) 18435c4bbdfSmrg WRITE(dst++, FbDoDestInvarientMergeRop(READ(src++))); 18535c4bbdfSmrg } 18635c4bbdfSmrg else { 18735c4bbdfSmrg while (n--) { 18835c4bbdfSmrg bits = READ(src++); 18935c4bbdfSmrg WRITE(dst, FbDoMergeRop(bits, READ(dst))); 19035c4bbdfSmrg dst++; 19135c4bbdfSmrg } 19235c4bbdfSmrg } 19335c4bbdfSmrg if (endmask) { 19435c4bbdfSmrg bits = READ(src); 19535c4bbdfSmrg FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask); 19635c4bbdfSmrg } 19735c4bbdfSmrg } 19835c4bbdfSmrg } 19905b261ecSmrg } 20035c4bbdfSmrg else { 20135c4bbdfSmrg if (srcX > dstX) { 20235c4bbdfSmrg leftShift = srcX - dstX; 20335c4bbdfSmrg rightShift = FB_UNIT - leftShift; 20435c4bbdfSmrg } 20535c4bbdfSmrg else { 20635c4bbdfSmrg rightShift = dstX - srcX; 20735c4bbdfSmrg leftShift = FB_UNIT - rightShift; 20835c4bbdfSmrg } 20935c4bbdfSmrg while (height--) { 21035c4bbdfSmrg src = srcLine; 21135c4bbdfSmrg srcLine += srcStride; 21235c4bbdfSmrg dst = dstLine; 21335c4bbdfSmrg dstLine += dstStride; 21435c4bbdfSmrg 21535c4bbdfSmrg bits1 = 0; 21635c4bbdfSmrg if (reverse) { 21735c4bbdfSmrg if (srcX < dstX) 21835c4bbdfSmrg bits1 = READ(--src); 21935c4bbdfSmrg if (endmask) { 22035c4bbdfSmrg bits = FbScrRight(bits1, rightShift); 22135c4bbdfSmrg if (FbScrRight(endmask, leftShift)) { 22235c4bbdfSmrg bits1 = READ(--src); 22335c4bbdfSmrg bits |= FbScrLeft(bits1, leftShift); 22435c4bbdfSmrg } 22535c4bbdfSmrg --dst; 22635c4bbdfSmrg FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask); 22735c4bbdfSmrg } 22835c4bbdfSmrg n = nmiddle; 22935c4bbdfSmrg if (destInvarient) { 23035c4bbdfSmrg while (n--) { 23135c4bbdfSmrg bits = FbScrRight(bits1, rightShift); 23235c4bbdfSmrg bits1 = READ(--src); 23335c4bbdfSmrg bits |= FbScrLeft(bits1, leftShift); 23435c4bbdfSmrg --dst; 23535c4bbdfSmrg WRITE(dst, FbDoDestInvarientMergeRop(bits)); 23635c4bbdfSmrg } 23735c4bbdfSmrg } 23835c4bbdfSmrg else { 23935c4bbdfSmrg while (n--) { 24035c4bbdfSmrg bits = FbScrRight(bits1, rightShift); 24135c4bbdfSmrg bits1 = READ(--src); 24235c4bbdfSmrg bits |= FbScrLeft(bits1, leftShift); 24335c4bbdfSmrg --dst; 24435c4bbdfSmrg WRITE(dst, FbDoMergeRop(bits, READ(dst))); 24535c4bbdfSmrg } 24635c4bbdfSmrg } 24735c4bbdfSmrg if (startmask) { 24835c4bbdfSmrg bits = FbScrRight(bits1, rightShift); 24935c4bbdfSmrg if (FbScrRight(startmask, leftShift)) { 25035c4bbdfSmrg bits1 = READ(--src); 25135c4bbdfSmrg bits |= FbScrLeft(bits1, leftShift); 25235c4bbdfSmrg } 25335c4bbdfSmrg --dst; 25435c4bbdfSmrg FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask); 25535c4bbdfSmrg } 25635c4bbdfSmrg } 25735c4bbdfSmrg else { 25835c4bbdfSmrg if (srcX > dstX) 25935c4bbdfSmrg bits1 = READ(src++); 26035c4bbdfSmrg if (startmask) { 26135c4bbdfSmrg bits = FbScrLeft(bits1, leftShift); 26235c4bbdfSmrg if (FbScrLeft(startmask, rightShift)) { 26335c4bbdfSmrg bits1 = READ(src++); 26435c4bbdfSmrg bits |= FbScrRight(bits1, rightShift); 26535c4bbdfSmrg } 26635c4bbdfSmrg FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask); 26735c4bbdfSmrg dst++; 26835c4bbdfSmrg } 26935c4bbdfSmrg n = nmiddle; 27035c4bbdfSmrg if (destInvarient) { 27135c4bbdfSmrg while (n--) { 27235c4bbdfSmrg bits = FbScrLeft(bits1, leftShift); 27335c4bbdfSmrg bits1 = READ(src++); 27435c4bbdfSmrg bits |= FbScrRight(bits1, rightShift); 27535c4bbdfSmrg WRITE(dst, FbDoDestInvarientMergeRop(bits)); 27635c4bbdfSmrg dst++; 27735c4bbdfSmrg } 27835c4bbdfSmrg } 27935c4bbdfSmrg else { 28035c4bbdfSmrg while (n--) { 28135c4bbdfSmrg bits = FbScrLeft(bits1, leftShift); 28235c4bbdfSmrg bits1 = READ(src++); 28335c4bbdfSmrg bits |= FbScrRight(bits1, rightShift); 28435c4bbdfSmrg WRITE(dst, FbDoMergeRop(bits, READ(dst))); 28535c4bbdfSmrg dst++; 28635c4bbdfSmrg } 28735c4bbdfSmrg } 28835c4bbdfSmrg if (endmask) { 28935c4bbdfSmrg bits = FbScrLeft(bits1, leftShift); 29035c4bbdfSmrg if (FbScrLeft(endmask, rightShift)) { 29135c4bbdfSmrg bits1 = READ(src); 29235c4bbdfSmrg bits |= FbScrRight(bits1, rightShift); 29335c4bbdfSmrg } 29435c4bbdfSmrg FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask); 29535c4bbdfSmrg } 29635c4bbdfSmrg } 29735c4bbdfSmrg } 29805b261ecSmrg } 29905b261ecSmrg} 30005b261ecSmrg 30105b261ecSmrg#undef DEBUG_BLT24 30205b261ecSmrg#ifdef DEBUG_BLT24 30305b261ecSmrg 30405b261ecSmrgstatic unsigned long 30535c4bbdfSmrggetPixel(char *src, int x) 30605b261ecSmrg{ 30735c4bbdfSmrg unsigned long l; 30805b261ecSmrg 30905b261ecSmrg l = 0; 31035c4bbdfSmrg memcpy(&l, src + x * 3, 3); 31105b261ecSmrg return l; 31205b261ecSmrg} 31305b261ecSmrg#endif 31405b261ecSmrg 31505b261ecSmrgstatic void 31635c4bbdfSmrgfbBlt24Line(FbBits * src, 31735c4bbdfSmrg int srcX, 31835c4bbdfSmrg FbBits * dst, int dstX, int width, int alu, FbBits pm, Bool reverse) 31905b261ecSmrg{ 32005b261ecSmrg#ifdef DEBUG_BLT24 32135c4bbdfSmrg char *origDst = (char *) dst; 32235c4bbdfSmrg FbBits *origLine = dst + ((dstX >> FB_SHIFT) - 1); 32335c4bbdfSmrg int origNlw = ((width + FB_MASK) >> FB_SHIFT) + 3; 32435c4bbdfSmrg int origX = dstX / 24; 32505b261ecSmrg#endif 32605b261ecSmrg 32735c4bbdfSmrg int leftShift, rightShift; 32835c4bbdfSmrg FbBits startmask, endmask; 32935c4bbdfSmrg int n; 33035c4bbdfSmrg 33135c4bbdfSmrg FbBits bits, bits1; 33235c4bbdfSmrg FbBits mask; 33335c4bbdfSmrg 33435c4bbdfSmrg int rot; 33535c4bbdfSmrg 33635c4bbdfSmrg FbDeclareMergeRop(); 33735c4bbdfSmrg 33835c4bbdfSmrg FbInitializeMergeRop(alu, FB_ALLONES); 33905b261ecSmrg FbMaskBits(dstX, width, startmask, n, endmask); 34005b261ecSmrg#ifdef DEBUG_BLT24 34135c4bbdfSmrg ErrorF("dstX %d width %d reverse %d\n", dstX, width, reverse); 34205b261ecSmrg#endif 34335c4bbdfSmrg if (reverse) { 34435c4bbdfSmrg src += ((srcX + width - 1) >> FB_SHIFT) + 1; 34535c4bbdfSmrg dst += ((dstX + width - 1) >> FB_SHIFT) + 1; 34635c4bbdfSmrg rot = FbFirst24Rot(((dstX + width - 8) & FB_MASK)); 34735c4bbdfSmrg rot = FbPrev24Rot(rot); 34805b261ecSmrg#ifdef DEBUG_BLT24 34935c4bbdfSmrg ErrorF("dstX + width - 8: %d rot: %d\n", (dstX + width - 8) & FB_MASK, 35035c4bbdfSmrg rot); 35105b261ecSmrg#endif 35235c4bbdfSmrg srcX = (srcX + width - 1) & FB_MASK; 35335c4bbdfSmrg dstX = (dstX + width - 1) & FB_MASK; 35405b261ecSmrg } 35535c4bbdfSmrg else { 35635c4bbdfSmrg src += srcX >> FB_SHIFT; 35735c4bbdfSmrg dst += dstX >> FB_SHIFT; 35835c4bbdfSmrg srcX &= FB_MASK; 35935c4bbdfSmrg dstX &= FB_MASK; 36035c4bbdfSmrg rot = FbFirst24Rot(dstX); 36105b261ecSmrg#ifdef DEBUG_BLT24 36235c4bbdfSmrg ErrorF("dstX: %d rot: %d\n", dstX, rot); 36305b261ecSmrg#endif 36405b261ecSmrg } 36535c4bbdfSmrg mask = FbRot24(pm, rot); 36605b261ecSmrg#ifdef DEBUG_BLT24 36735c4bbdfSmrg ErrorF("pm 0x%x mask 0x%x\n", pm, mask); 36805b261ecSmrg#endif 36935c4bbdfSmrg if (srcX == dstX) { 37035c4bbdfSmrg if (reverse) { 37135c4bbdfSmrg if (endmask) { 37235c4bbdfSmrg bits = READ(--src); 37335c4bbdfSmrg --dst; 37435c4bbdfSmrg WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask & endmask)); 37535c4bbdfSmrg mask = FbPrev24Pix(mask); 37635c4bbdfSmrg } 37735c4bbdfSmrg while (n--) { 37835c4bbdfSmrg bits = READ(--src); 37935c4bbdfSmrg --dst; 38035c4bbdfSmrg WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask)); 38135c4bbdfSmrg mask = FbPrev24Pix(mask); 38235c4bbdfSmrg } 38335c4bbdfSmrg if (startmask) { 38435c4bbdfSmrg bits = READ(--src); 38535c4bbdfSmrg --dst; 38635c4bbdfSmrg WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask & startmask)); 38735c4bbdfSmrg } 38835c4bbdfSmrg } 38935c4bbdfSmrg else { 39035c4bbdfSmrg if (startmask) { 39135c4bbdfSmrg bits = READ(src++); 39235c4bbdfSmrg WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask & startmask)); 39335c4bbdfSmrg dst++; 39435c4bbdfSmrg mask = FbNext24Pix(mask); 39535c4bbdfSmrg } 39635c4bbdfSmrg while (n--) { 39735c4bbdfSmrg bits = READ(src++); 39835c4bbdfSmrg WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask)); 39935c4bbdfSmrg dst++; 40035c4bbdfSmrg mask = FbNext24Pix(mask); 40135c4bbdfSmrg } 40235c4bbdfSmrg if (endmask) { 40335c4bbdfSmrg bits = READ(src); 40435c4bbdfSmrg WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask & endmask)); 40535c4bbdfSmrg } 40635c4bbdfSmrg } 40705b261ecSmrg } 40835c4bbdfSmrg else { 40935c4bbdfSmrg if (srcX > dstX) { 41035c4bbdfSmrg leftShift = srcX - dstX; 41135c4bbdfSmrg rightShift = FB_UNIT - leftShift; 41235c4bbdfSmrg } 41335c4bbdfSmrg else { 41435c4bbdfSmrg rightShift = dstX - srcX; 41535c4bbdfSmrg leftShift = FB_UNIT - rightShift; 41635c4bbdfSmrg } 41735c4bbdfSmrg 41835c4bbdfSmrg bits1 = 0; 41935c4bbdfSmrg if (reverse) { 42035c4bbdfSmrg if (srcX < dstX) 42135c4bbdfSmrg bits1 = READ(--src); 42235c4bbdfSmrg if (endmask) { 42335c4bbdfSmrg bits = FbScrRight(bits1, rightShift); 42435c4bbdfSmrg if (FbScrRight(endmask, leftShift)) { 42535c4bbdfSmrg bits1 = READ(--src); 42635c4bbdfSmrg bits |= FbScrLeft(bits1, leftShift); 42735c4bbdfSmrg } 42835c4bbdfSmrg --dst; 42935c4bbdfSmrg WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask & endmask)); 43035c4bbdfSmrg mask = FbPrev24Pix(mask); 43135c4bbdfSmrg } 43235c4bbdfSmrg while (n--) { 43335c4bbdfSmrg bits = FbScrRight(bits1, rightShift); 43435c4bbdfSmrg bits1 = READ(--src); 43535c4bbdfSmrg bits |= FbScrLeft(bits1, leftShift); 43635c4bbdfSmrg --dst; 43735c4bbdfSmrg WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask)); 43835c4bbdfSmrg mask = FbPrev24Pix(mask); 43935c4bbdfSmrg } 44035c4bbdfSmrg if (startmask) { 44135c4bbdfSmrg bits = FbScrRight(bits1, rightShift); 44235c4bbdfSmrg if (FbScrRight(startmask, leftShift)) { 44335c4bbdfSmrg bits1 = READ(--src); 44435c4bbdfSmrg bits |= FbScrLeft(bits1, leftShift); 44535c4bbdfSmrg } 44635c4bbdfSmrg --dst; 44735c4bbdfSmrg WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask & startmask)); 44835c4bbdfSmrg } 44935c4bbdfSmrg } 45035c4bbdfSmrg else { 45135c4bbdfSmrg if (srcX > dstX) 45235c4bbdfSmrg bits1 = READ(src++); 45335c4bbdfSmrg if (startmask) { 45435c4bbdfSmrg bits = FbScrLeft(bits1, leftShift); 45535c4bbdfSmrg bits1 = READ(src++); 45635c4bbdfSmrg bits |= FbScrRight(bits1, rightShift); 45735c4bbdfSmrg WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask & startmask)); 45835c4bbdfSmrg dst++; 45935c4bbdfSmrg mask = FbNext24Pix(mask); 46035c4bbdfSmrg } 46135c4bbdfSmrg while (n--) { 46235c4bbdfSmrg bits = FbScrLeft(bits1, leftShift); 46335c4bbdfSmrg bits1 = READ(src++); 46435c4bbdfSmrg bits |= FbScrRight(bits1, rightShift); 46535c4bbdfSmrg WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask)); 46635c4bbdfSmrg dst++; 46735c4bbdfSmrg mask = FbNext24Pix(mask); 46835c4bbdfSmrg } 46935c4bbdfSmrg if (endmask) { 47035c4bbdfSmrg bits = FbScrLeft(bits1, leftShift); 47135c4bbdfSmrg if (FbScrLeft(endmask, rightShift)) { 47235c4bbdfSmrg bits1 = READ(src); 47335c4bbdfSmrg bits |= FbScrRight(bits1, rightShift); 47435c4bbdfSmrg } 47535c4bbdfSmrg WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask & endmask)); 47635c4bbdfSmrg } 47735c4bbdfSmrg } 47805b261ecSmrg } 47905b261ecSmrg#ifdef DEBUG_BLT24 48005b261ecSmrg { 48135c4bbdfSmrg int firstx, lastx, x; 48235c4bbdfSmrg 48335c4bbdfSmrg firstx = origX; 48435c4bbdfSmrg if (firstx) 48535c4bbdfSmrg firstx--; 48635c4bbdfSmrg lastx = origX + width / 24 + 1; 48735c4bbdfSmrg for (x = firstx; x <= lastx; x++) 48835c4bbdfSmrg ErrorF("%06x ", getPixel(origDst, x)); 48935c4bbdfSmrg ErrorF("\n"); 49035c4bbdfSmrg while (origNlw--) 49135c4bbdfSmrg ErrorF("%08x ", *origLine++); 49235c4bbdfSmrg ErrorF("\n"); 49305b261ecSmrg } 49405b261ecSmrg#endif 49505b261ecSmrg} 49605b261ecSmrg 49705b261ecSmrgvoid 49835c4bbdfSmrgfbBlt24(FbBits * srcLine, 49935c4bbdfSmrg FbStride srcStride, 50035c4bbdfSmrg int srcX, 50135c4bbdfSmrg FbBits * dstLine, 50235c4bbdfSmrg FbStride dstStride, 50335c4bbdfSmrg int dstX, 50435c4bbdfSmrg int width, 50535c4bbdfSmrg int height, int alu, FbBits pm, Bool reverse, Bool upsidedown) 50605b261ecSmrg{ 50735c4bbdfSmrg if (upsidedown) { 50835c4bbdfSmrg srcLine += (height - 1) * srcStride; 50935c4bbdfSmrg dstLine += (height - 1) * dstStride; 51035c4bbdfSmrg srcStride = -srcStride; 51135c4bbdfSmrg dstStride = -dstStride; 51205b261ecSmrg } 51335c4bbdfSmrg while (height--) { 51435c4bbdfSmrg fbBlt24Line(srcLine, srcX, dstLine, dstX, width, alu, pm, reverse); 51535c4bbdfSmrg srcLine += srcStride; 51635c4bbdfSmrg dstLine += dstStride; 51705b261ecSmrg } 51805b261ecSmrg#ifdef DEBUG_BLT24 51935c4bbdfSmrg ErrorF("\n"); 52005b261ecSmrg#endif 52105b261ecSmrg} 52205b261ecSmrg 52305b261ecSmrgvoid 52435c4bbdfSmrgfbBltStip(FbStip * src, FbStride srcStride, /* in FbStip units, not FbBits units */ 52535c4bbdfSmrg int srcX, FbStip * dst, FbStride dstStride, /* in FbStip units, not FbBits units */ 52635c4bbdfSmrg int dstX, int width, int height, int alu, FbBits pm, int bpp) 52705b261ecSmrg{ 52835c4bbdfSmrg fbBlt((FbBits *) src, FbStipStrideToBitsStride(srcStride), srcX, 52935c4bbdfSmrg (FbBits *) dst, FbStipStrideToBitsStride(dstStride), dstX, 53035c4bbdfSmrg width, height, alu, pm, bpp, FALSE, FALSE); 53105b261ecSmrg} 532