fbblt.c revision 4642e01f
11.24Sriastrad/* 21.1Smacallan * Copyright © 1998 Keith Packard 31.1Smacallan * 41.1Smacallan * Permission to use, copy, modify, distribute, and sell this software and its 51.1Smacallan * documentation for any purpose is hereby granted without fee, provided that 61.1Smacallan * the above copyright notice appear in all copies and that both that 71.1Smacallan * copyright notice and this permission notice appear in supporting 81.1Smacallan * documentation, and that the name of Keith Packard not be used in 91.1Smacallan * advertising or publicity pertaining to distribution of the software without 101.1Smacallan * specific, written prior permission. Keith Packard makes no 111.1Smacallan * representations about the suitability of this software for any purpose. It 121.1Smacallan * is provided "as is" without express or implied warranty. 131.1Smacallan * 141.1Smacallan * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 151.1Smacallan * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 161.1Smacallan * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 171.1Smacallan * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 181.1Smacallan * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 191.1Smacallan * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 201.1Smacallan * PERFORMANCE OF THIS SOFTWARE. 211.1Smacallan */ 221.1Smacallan 231.1Smacallan#ifdef HAVE_DIX_CONFIG_H 241.1Smacallan#include <dix-config.h> 251.1Smacallan#endif 261.1Smacallan 271.1Smacallan#include <string.h> 281.7Sriastrad#include "fb.h" 291.1Smacallan 301.1Smacallan#define InitializeShifts(sx,dx,ls,rs) { \ 311.4Smacallan if (sx != dx) { \ 321.1Smacallan if (sx > dx) { \ 331.1Smacallan ls = sx - dx; \ 341.1Smacallan rs = FB_UNIT - ls; \ 351.24Sriastrad } else { \ 361.1Smacallan rs = dx - sx; \ 371.1Smacallan ls = FB_UNIT - rs; \ 381.1Smacallan } \ 391.1Smacallan } \ 401.1Smacallan} 411.1Smacallan 421.1Smacallanvoid 431.1SmacallanfbBlt (FbBits *srcLine, 441.1Smacallan FbStride srcStride, 451.1Smacallan int srcX, 461.1Smacallan 471.1Smacallan FbBits *dstLine, 481.1Smacallan FbStride dstStride, 491.1Smacallan int dstX, 501.1Smacallan 511.1Smacallan int width, 521.1Smacallan int height, 531.1Smacallan 541.1Smacallan int alu, 551.1Smacallan FbBits pm, 561.1Smacallan int bpp, 571.1Smacallan 581.1Smacallan Bool reverse, 591.1Smacallan Bool upsidedown) 601.1Smacallan{ 611.1Smacallan FbBits *src, *dst; 621.1Smacallan int leftShift, rightShift; 631.1Smacallan FbBits startmask, endmask; 641.1Smacallan FbBits bits, bits1; 651.1Smacallan int n, nmiddle; 661.1Smacallan Bool destInvarient; 671.1Smacallan int startbyte, endbyte; 681.1Smacallan FbDeclareMergeRop (); 691.1Smacallan 701.1Smacallan#ifdef FB_24BIT 711.1Smacallan if (bpp == 24 && !FbCheck24Pix (pm)) 721.1Smacallan { 731.1Smacallan fbBlt24 (srcLine, srcStride, srcX, dstLine, dstStride, dstX, 741.1Smacallan width, height, alu, pm, reverse, upsidedown); 751.1Smacallan return; 761.1Smacallan } 771.1Smacallan#endif 781.1Smacallan 791.1Smacallan if (alu == GXcopy && pm == FB_ALLONES && !reverse && 801.1Smacallan !(srcX & 7) && !(dstX & 7) && !(width & 7)) { 811.1Smacallan int i; 821.1Smacallan CARD8 *src = (CARD8 *) srcLine; 831.1Smacallan CARD8 *dst = (CARD8 *) dstLine; 841.1Smacallan 851.1Smacallan srcStride *= sizeof(FbBits); 861.1Smacallan dstStride *= sizeof(FbBits); 871.1Smacallan width >>= 3; 881.1Smacallan src += (srcX >> 3); 891.1Smacallan dst += (dstX >> 3); 901.1Smacallan 911.1Smacallan if (!upsidedown) 921.1Smacallan for (i = 0; i < height; i++) 931.1Smacallan MEMCPY_WRAPPED(dst + i * dstStride, src + i * srcStride, width); 941.1Smacallan else 951.1Smacallan for (i = height - 1; i >= 0; i--) 961.1Smacallan MEMCPY_WRAPPED(dst + i * dstStride, src + i * srcStride, width); 971.1Smacallan 981.6Smacallan return; 991.6Smacallan } 1001.6Smacallan 1011.1Smacallan FbInitializeMergeRop(alu, pm); 1021.1Smacallan destInvarient = FbDestInvarientMergeRop(); 1031.1Smacallan if (upsidedown) 1041.1Smacallan { 1051.1Smacallan srcLine += (height - 1) * (srcStride); 1061.1Smacallan dstLine += (height - 1) * (dstStride); 1071.1Smacallan srcStride = -srcStride; 1081.1Smacallan dstStride = -dstStride; 1091.1Smacallan } 1101.1Smacallan FbMaskBitsBytes (dstX, width, destInvarient, startmask, startbyte, 1111.1Smacallan nmiddle, endmask, endbyte); 1121.5Smacallan if (reverse) 1131.5Smacallan { 1141.1Smacallan srcLine += ((srcX + width - 1) >> FB_SHIFT) + 1; 1151.1Smacallan dstLine += ((dstX + width - 1) >> FB_SHIFT) + 1; 1161.1Smacallan srcX = (srcX + width - 1) & FB_MASK; 1171.1Smacallan dstX = (dstX + width - 1) & FB_MASK; 1181.1Smacallan } 1191.1Smacallan else 1201.7Sriastrad { 1211.7Sriastrad srcLine += srcX >> FB_SHIFT; 1221.7Sriastrad dstLine += dstX >> FB_SHIFT; 1231.7Sriastrad srcX &= FB_MASK; 1241.1Smacallan dstX &= FB_MASK; 1251.1Smacallan } 1261.1Smacallan if (srcX == dstX) 1271.1Smacallan { 1281.1Smacallan while (height--) 1291.1Smacallan { 1301.2Smacallan src = srcLine; 1311.2Smacallan srcLine += srcStride; 1321.2Smacallan dst = dstLine; 1331.2Smacallan dstLine += dstStride; 1341.2Smacallan if (reverse) 1351.2Smacallan { 1361.2Smacallan if (endmask) 1371.2Smacallan { 1381.2Smacallan bits = READ(--src); 1391.2Smacallan --dst; 1401.2Smacallan FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask); 1411.2Smacallan } 1421.2Smacallan n = nmiddle; 1431.7Sriastrad if (destInvarient) 1441.7Sriastrad { 1451.2Smacallan while (n--) 1461.2Smacallan WRITE(--dst, FbDoDestInvarientMergeRop(READ(--src))); 1471.2Smacallan } 1481.1Smacallan else 1491.1Smacallan { 1501.1Smacallan while (n--) 1511.1Smacallan { 1521.1Smacallan bits = READ(--src); 1531.1Smacallan --dst; 1541.1Smacallan WRITE(dst, FbDoMergeRop (bits, READ(dst))); 1551.1Smacallan } 1561.1Smacallan } 1571.1Smacallan if (startmask) 1581.1Smacallan { 1591.1Smacallan bits = READ(--src); 1601.1Smacallan --dst; 1611.1Smacallan FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask); 1621.1Smacallan } 1631.1Smacallan } 1641.1Smacallan else 1651.1Smacallan { 1661.1Smacallan if (startmask) 1671.1Smacallan { 1681.1Smacallan bits = READ(src++); 1691.1Smacallan FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask); 1701.1Smacallan dst++; 1711.1Smacallan } 1721.1Smacallan n = nmiddle; 1731.1Smacallan if (destInvarient) 1741.1Smacallan { 1751.1Smacallan#if 0 1761.1Smacallan /* 1771.1Smacallan * This provides some speedup on screen->screen blts 1781.1Smacallan * over the PCI bus, usually about 10%. But fb 1791.1Smacallan * isn't usually used for this operation... 1801.1Smacallan */ 1811.1Smacallan if (_ca2 + 1 == 0 && _cx2 == 0) 1821.1Smacallan { 1831.1Smacallan FbBits t1, t2, t3, t4; 1841.1Smacallan while (n >= 4) 1851.1Smacallan { 1861.1Smacallan t1 = *src++; 1871.1Smacallan t2 = *src++; 1881.1Smacallan t3 = *src++; 1891.1Smacallan t4 = *src++; 1901.1Smacallan *dst++ = t1; 1911.1Smacallan *dst++ = t2; 1921.1Smacallan *dst++ = t3; 1931.1Smacallan *dst++ = t4; 1941.1Smacallan n -= 4; 1951.2Smacallan } 1961.2Smacallan } 1971.2Smacallan#endif 1981.2Smacallan while (n--) 1991.2Smacallan WRITE(dst++, FbDoDestInvarientMergeRop(READ(src++))); 2001.2Smacallan } 2011.2Smacallan else 2021.2Smacallan { 2031.2Smacallan while (n--) 2041.2Smacallan { 2051.5Smacallan bits = READ(src++); 2061.1Smacallan WRITE(dst, FbDoMergeRop (bits, READ(dst))); 2071.1Smacallan dst++; 2081.1Smacallan } 2091.6Smacallan } 2101.6Smacallan if (endmask) 2111.6Smacallan { 2121.6Smacallan bits = READ(src); 2131.1Smacallan FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask); 2141.5Smacallan } 2151.11Sriastrad } 2161.10Smacallan } 2171.5Smacallan } 2181.6Smacallan else 2191.11Sriastrad { 2201.10Smacallan if (srcX > dstX) 2211.6Smacallan { 2221.6Smacallan leftShift = srcX - dstX; 2231.5Smacallan rightShift = FB_UNIT - leftShift; 2241.5Smacallan } 2251.5Smacallan else 2261.5Smacallan { 2271.5Smacallan rightShift = dstX - srcX; 2281.5Smacallan leftShift = FB_UNIT - rightShift; 2291.5Smacallan } 2301.5Smacallan while (height--) 2311.5Smacallan { 2321.5Smacallan src = srcLine; 2331.5Smacallan srcLine += srcStride; 2341.11Sriastrad dst = dstLine; 2351.10Smacallan dstLine += dstStride; 2361.5Smacallan 2371.1Smacallan bits1 = 0; 2381.5Smacallan if (reverse) 2391.1Smacallan { 2401.1Smacallan if (srcX < dstX) 2411.1Smacallan bits1 = READ(--src); 2421.1Smacallan if (endmask) 2431.1Smacallan { 2441.1Smacallan bits = FbScrRight(bits1, rightShift); 2451.1Smacallan if (FbScrRight(endmask, leftShift)) 2461.1Smacallan { 2471.1Smacallan bits1 = READ(--src); 2481.1Smacallan bits |= FbScrLeft(bits1, leftShift); 2491.1Smacallan } 2501.1Smacallan --dst; 2511.1Smacallan FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask); 2521.1Smacallan } 2531.1Smacallan n = nmiddle; 2541.1Smacallan if (destInvarient) 2551.1Smacallan { 2561.1Smacallan while (n--) 2571.1Smacallan { 2581.1Smacallan bits = FbScrRight(bits1, rightShift); 2591.1Smacallan bits1 = READ(--src); 2601.1Smacallan bits |= FbScrLeft(bits1, leftShift); 2611.1Smacallan --dst; 2621.1Smacallan WRITE(dst, FbDoDestInvarientMergeRop(bits)); 2631.1Smacallan } 2641.1Smacallan } 2651.1Smacallan else 2661.1Smacallan { 2671.1Smacallan while (n--) 2681.1Smacallan { 2691.1Smacallan bits = FbScrRight(bits1, rightShift); 2701.1Smacallan bits1 = READ(--src); 2711.1Smacallan bits |= FbScrLeft(bits1, leftShift); 2721.1Smacallan --dst; 2731.1Smacallan WRITE(dst, FbDoMergeRop(bits, READ(dst))); 2741.1Smacallan } 2751.1Smacallan } 2761.1Smacallan if (startmask) 2771.1Smacallan { 2781.1Smacallan bits = FbScrRight(bits1, rightShift); 2791.1Smacallan if (FbScrRight(startmask, leftShift)) 2801.1Smacallan { 2811.1Smacallan bits1 = READ(--src); 2821.1Smacallan bits |= FbScrLeft(bits1, leftShift); 2831.1Smacallan } 2841.1Smacallan --dst; 2851.1Smacallan FbDoLeftMaskByteMergeRop (dst, bits, startbyte, startmask); 2861.1Smacallan } 2871.1Smacallan } 2881.1Smacallan else 2891.1Smacallan { 2901.1Smacallan if (srcX > dstX) 2911.1Smacallan bits1 = READ(src++); 2921.1Smacallan if (startmask) 2931.1Smacallan { 2941.1Smacallan bits = FbScrLeft(bits1, leftShift); 2951.1Smacallan if (FbScrLeft(startmask, rightShift)) 2961.1Smacallan { 2971.1Smacallan bits1 = READ(src++); 2981.1Smacallan bits |= FbScrRight(bits1, rightShift); 2991.1Smacallan } 3001.1Smacallan FbDoLeftMaskByteMergeRop (dst, bits, startbyte, startmask); 3011.1Smacallan dst++; 3021.1Smacallan } 3031.1Smacallan n = nmiddle; 3041.1Smacallan if (destInvarient) 3051.1Smacallan { 3061.1Smacallan while (n--) 3071.1Smacallan { 3081.1Smacallan bits = FbScrLeft(bits1, leftShift); 3091.1Smacallan bits1 = READ(src++); 3101.1Smacallan bits |= FbScrRight(bits1, rightShift); 3111.1Smacallan WRITE(dst, FbDoDestInvarientMergeRop(bits)); 3121.1Smacallan dst++; 3131.1Smacallan } 3141.1Smacallan } 3151.1Smacallan else 3161.1Smacallan { 3171.1Smacallan while (n--) 3181.1Smacallan { 3191.1Smacallan bits = FbScrLeft(bits1, leftShift); 3201.1Smacallan bits1 = READ(src++); 3211.1Smacallan bits |= FbScrRight(bits1, rightShift); 3221.1Smacallan WRITE(dst, FbDoMergeRop(bits, READ(dst))); 3231.1Smacallan dst++; 3241.1Smacallan } 3251.1Smacallan } 3261.1Smacallan if (endmask) 3271.1Smacallan { 3281.1Smacallan bits = FbScrLeft(bits1, leftShift); 3291.1Smacallan if (FbScrLeft(endmask, rightShift)) 3301.1Smacallan { 3311.1Smacallan bits1 = READ(src); 3321.1Smacallan bits |= FbScrRight(bits1, rightShift); 3331.1Smacallan } 3341.1Smacallan FbDoRightMaskByteMergeRop (dst, bits, endbyte, endmask); 3351.1Smacallan } 3361.1Smacallan } 3371.1Smacallan } 3381.1Smacallan } 3391.1Smacallan} 3401.1Smacallan 3411.7Sriastrad#ifdef FB_24BIT 3421.1Smacallan 3431.1Smacallan#undef DEBUG_BLT24 3441.1Smacallan#ifdef DEBUG_BLT24 3451.1Smacallan 3461.1Smacallanstatic unsigned long 3471.1SmacallangetPixel (char *src, int x) 3481.1Smacallan{ 3491.1Smacallan unsigned long l; 3501.1Smacallan 3511.1Smacallan l = 0; 3521.7Sriastrad memcpy (&l, src + x * 3, 3); 3531.7Sriastrad return l; 3541.1Smacallan} 3551.1Smacallan#endif 3561.1Smacallan 3571.1Smacallanstatic void 3581.1SmacallanfbBlt24Line (FbBits *src, 3591.1Smacallan int srcX, 3601.1Smacallan 3611.1Smacallan FbBits *dst, 3621.1Smacallan int dstX, 3631.1Smacallan 3641.1Smacallan int width, 3651.1Smacallan 3661.1Smacallan int alu, 3671.1Smacallan FbBits pm, 3681.7Sriastrad 3691.7Sriastrad Bool reverse) 3701.7Sriastrad{ 3711.1Smacallan#ifdef DEBUG_BLT24 3721.1Smacallan char *origDst = (char *) dst; 3731.1Smacallan FbBits *origLine = dst + ((dstX >> FB_SHIFT) - 1); 3741.1Smacallan int origNlw = ((width + FB_MASK) >> FB_SHIFT) + 3; 3751.1Smacallan int origX = dstX / 24; 3761.1Smacallan#endif 3771.1Smacallan 3781.1Smacallan int leftShift, rightShift; 3791.1Smacallan FbBits startmask, endmask; 3801.1Smacallan int n; 3811.1Smacallan 3821.1Smacallan FbBits bits, bits1; 3831.1Smacallan FbBits mask; 3841.1Smacallan 3851.1Smacallan int rot; 3861.1Smacallan FbDeclareMergeRop (); 3871.1Smacallan 3881.1Smacallan FbInitializeMergeRop (alu, FB_ALLONES); 3891.1Smacallan FbMaskBits(dstX, width, startmask, n, endmask); 3901.1Smacallan#ifdef DEBUG_BLT24 3911.1Smacallan ErrorF ("dstX %d width %d reverse %d\n", dstX, width, reverse); 3921.1Smacallan#endif 3931.1Smacallan if (reverse) 3941.1Smacallan { 3951.5Smacallan src += ((srcX + width - 1) >> FB_SHIFT) + 1; 3961.5Smacallan dst += ((dstX + width - 1) >> FB_SHIFT) + 1; 3971.5Smacallan rot = FbFirst24Rot (((dstX + width - 8) & FB_MASK)); 3981.1Smacallan rot = FbPrev24Rot(rot); 3991.1Smacallan#ifdef DEBUG_BLT24 4001.1Smacallan ErrorF ("dstX + width - 8: %d rot: %d\n", (dstX + width - 8) & FB_MASK, rot); 4011.1Smacallan#endif 4021.1Smacallan srcX = (srcX + width - 1) & FB_MASK; 4031.1Smacallan dstX = (dstX + width - 1) & FB_MASK; 4041.1Smacallan } 4051.1Smacallan else 4061.1Smacallan { 4071.1Smacallan src += srcX >> FB_SHIFT; 4081.1Smacallan dst += dstX >> FB_SHIFT; 4091.1Smacallan srcX &= FB_MASK; 4101.1Smacallan dstX &= FB_MASK; 4111.1Smacallan rot = FbFirst24Rot (dstX); 4121.1Smacallan#ifdef DEBUG_BLT24 4131.1Smacallan ErrorF ("dstX: %d rot: %d\n", dstX, rot); 4141.1Smacallan#endif 4151.1Smacallan } 4161.1Smacallan mask = FbRot24(pm,rot); 4171.1Smacallan#ifdef DEBUG_BLT24 4181.1Smacallan ErrorF ("pm 0x%x mask 0x%x\n", pm, mask); 4191.1Smacallan#endif 4201.19Smacallan if (srcX == dstX) 4211.19Smacallan { 4221.19Smacallan if (reverse) 4231.19Smacallan { 4241.19Smacallan if (endmask) 4251.19Smacallan { 4261.19Smacallan bits = READ(--src); 4271.1Smacallan --dst; 4281.19Smacallan WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask & endmask)); 4291.19Smacallan mask = FbPrev24Pix (mask); 4301.19Smacallan } 4311.19Smacallan while (n--) 4321.19Smacallan { 4331.19Smacallan bits = READ(--src); 4341.1Smacallan --dst; 4351.1Smacallan WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask)); 4361.1Smacallan mask = FbPrev24Pix (mask); 4371.1Smacallan } 4381.1Smacallan if (startmask) 4391.1Smacallan { 4401.1Smacallan bits = READ(--src); 4411.1Smacallan --dst; 4421.1Smacallan WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask & startmask)); 4431.1Smacallan } 4441.1Smacallan } 4451.1Smacallan else 4461.1Smacallan { 4471.1Smacallan if (startmask) 4481.1Smacallan { 4491.1Smacallan bits = READ(src++); 4501.1Smacallan WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask & startmask)); 4511.5Smacallan dst++; 4521.1Smacallan mask = FbNext24Pix(mask); 4531.1Smacallan } 4541.1Smacallan while (n--) 4551.1Smacallan { 4561.1Smacallan bits = READ(src++); 4571.1Smacallan WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask)); 4581.1Smacallan dst++; 4591.1Smacallan mask = FbNext24Pix(mask); 4601.1Smacallan } 4611.1Smacallan if (endmask) 4621.1Smacallan { 4631.14Smacallan bits = READ(src); 4641.14Smacallan WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask & endmask)); 4651.14Smacallan } 4661.1Smacallan } 4671.14Smacallan } 4681.1Smacallan else 4691.7Sriastrad { 4701.1Smacallan if (srcX > dstX) 4711.1Smacallan { 4721.1Smacallan leftShift = srcX - dstX; 4731.1Smacallan rightShift = FB_UNIT - leftShift; 4741.1Smacallan } 4751.1Smacallan else 4761.2Smacallan { 4771.1Smacallan rightShift = dstX - srcX; 4781.1Smacallan leftShift = FB_UNIT - rightShift; 4791.1Smacallan } 4801.1Smacallan 4811.1Smacallan bits1 = 0; 4821.2Smacallan if (reverse) 4831.2Smacallan { 4841.2Smacallan if (srcX < dstX) 4851.2Smacallan bits1 = READ(--src); 4861.2Smacallan if (endmask) 4871.2Smacallan { 4881.2Smacallan bits = FbScrRight(bits1, rightShift); 4891.1Smacallan if (FbScrRight(endmask, leftShift)) 4901.1Smacallan { 4911.1Smacallan bits1 = READ(--src); 4921.1Smacallan bits |= FbScrLeft(bits1, leftShift); 4931.7Sriastrad } 4941.1Smacallan --dst; 4951.1Smacallan WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask & endmask)); 4961.1Smacallan mask = FbPrev24Pix(mask); 4971.1Smacallan } 4981.1Smacallan while (n--) 4991.1Smacallan { 5001.1Smacallan bits = FbScrRight(bits1, rightShift); 5011.1Smacallan bits1 = READ(--src); 5021.1Smacallan bits |= FbScrLeft(bits1, leftShift); 5031.1Smacallan --dst; 5041.1Smacallan WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask)); 5051.12Smacallan mask = FbPrev24Pix(mask); 5061.12Smacallan } 5071.12Smacallan if (startmask) 5081.12Smacallan { 5091.1Smacallan bits = FbScrRight(bits1, rightShift); 5101.1Smacallan if (FbScrRight(startmask, leftShift)) 5111.1Smacallan { 5121.1Smacallan bits1 = READ(--src); 5131.1Smacallan bits |= FbScrLeft(bits1, leftShift); 5141.7Sriastrad } 5151.7Sriastrad --dst; 5161.1Smacallan WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask & startmask)); 5171.1Smacallan } 5181.1Smacallan } 5191.1Smacallan else 5201.1Smacallan { 5211.1Smacallan if (srcX > dstX) 5221.1Smacallan bits1 = READ(src++); 5231.1Smacallan if (startmask) 5241.1Smacallan { 5251.1Smacallan bits = FbScrLeft(bits1, leftShift); 5261.1Smacallan bits1 = READ(src++); 5271.1Smacallan bits |= FbScrRight(bits1, rightShift); 5281.5Smacallan WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask & startmask)); 5291.1Smacallan dst++; 5301.1Smacallan mask = FbNext24Pix(mask); 5311.1Smacallan } 5321.1Smacallan while (n--) 5331.1Smacallan { 5341.1Smacallan bits = FbScrLeft(bits1, leftShift); 5351.7Sriastrad bits1 = READ(src++); 5361.1Smacallan bits |= FbScrRight(bits1, rightShift); 5371.1Smacallan WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), mask)); 5381.1Smacallan dst++; 5391.1Smacallan mask = FbNext24Pix(mask); 5401.1Smacallan } 5411.1Smacallan if (endmask) 5421.1Smacallan { 5431.5Smacallan bits = FbScrLeft(bits1, leftShift); 5441.5Smacallan if (FbScrLeft(endmask, rightShift)) 5451.5Smacallan { 5461.5Smacallan bits1 = READ(src); 5471.5Smacallan bits |= FbScrRight(bits1, rightShift); 5481.1Smacallan } 5491.1Smacallan WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), mask & endmask)); 5501.1Smacallan } 5511.1Smacallan } 5521.1Smacallan } 5531.7Sriastrad#ifdef DEBUG_BLT24 5541.7Sriastrad { 5551.7Sriastrad int firstx, lastx, x; 5561.7Sriastrad 5571.7Sriastrad firstx = origX; 5581.7Sriastrad if (firstx) 5591.7Sriastrad firstx--; 5601.7Sriastrad lastx = origX + width/24 + 1; 5611.7Sriastrad for (x = firstx; x <= lastx; x++) 5621.7Sriastrad ErrorF ("%06x ", getPixel (origDst, x)); 5631.7Sriastrad ErrorF ("\n"); 5641.7Sriastrad while (origNlw--) 5651.7Sriastrad ErrorF ("%08x ", *origLine++); 5661.7Sriastrad ErrorF ("\n"); 5671.7Sriastrad } 5681.7Sriastrad#endif 5691.7Sriastrad} 5701.5Smacallan 5711.1Smacallanvoid 5721.7SriastradfbBlt24 (FbBits *srcLine, 5731.7Sriastrad FbStride srcStride, 5741.1Smacallan int srcX, 5751.7Sriastrad 5761.7Sriastrad FbBits *dstLine, 5771.1Smacallan FbStride dstStride, 5781.7Sriastrad int dstX, 5791.7Sriastrad 5801.7Sriastrad int width, 5811.1Smacallan int height, 5821.1Smacallan 5831.7Sriastrad int alu, 5841.7Sriastrad FbBits pm, 5851.1Smacallan 5861.7Sriastrad Bool reverse, 5871.7Sriastrad Bool upsidedown) 5881.1Smacallan{ 5891.1Smacallan if (upsidedown) 5901.7Sriastrad { 5911.7Sriastrad srcLine += (height-1) * srcStride; 5921.1Smacallan dstLine += (height-1) * dstStride; 5931.7Sriastrad srcStride = -srcStride; 5941.7Sriastrad dstStride = -dstStride; 5951.7Sriastrad } 5961.1Smacallan while (height--) 5971.1Smacallan { 5981.7Sriastrad fbBlt24Line (srcLine, srcX, dstLine, dstX, width, alu, pm, reverse); 5991.7Sriastrad srcLine += srcStride; 6001.1Smacallan dstLine += dstStride; 6011.7Sriastrad } 6021.7Sriastrad#ifdef DEBUG_BLT24 6031.1Smacallan ErrorF ("\n"); 6041.1Smacallan#endif 6051.1Smacallan} 6061.1Smacallan#endif /* FB_24BIT */ 6071.1Smacallan 6081.13Smacallan#if FB_SHIFT == FB_STIP_SHIFT + 1 6091.1Smacallan 6101.13Smacallan/* 6111.1Smacallan * Could be generalized to FB_SHIFT > FB_STIP_SHIFT + 1 by 6121.1Smacallan * creating an ring of values stepped through for each line 6131.1Smacallan */ 6141.1Smacallan 6151.1Smacallanvoid 6161.1SmacallanfbBltOdd (FbBits *srcLine, 6171.1Smacallan FbStride srcStrideEven, 6181.1Smacallan FbStride srcStrideOdd, 6191.1Smacallan int srcXEven, 6201.1Smacallan int srcXOdd, 6211.1Smacallan 6221.1Smacallan FbBits *dstLine, 6231.1Smacallan FbStride dstStrideEven, 6241.1Smacallan FbStride dstStrideOdd, 6251.1Smacallan int dstXEven, 6261.8Smacallan int dstXOdd, 6271.8Smacallan 6281.1Smacallan int width, 6291.7Sriastrad int height, 6301.7Sriastrad 6311.7Sriastrad int alu, 6321.18Smacallan FbBits pm, 6331.1Smacallan int bpp) 6341.1Smacallan{ 6351.1Smacallan FbBits *src; 6361.1Smacallan int leftShiftEven, rightShiftEven; 6371.1Smacallan FbBits startmaskEven, endmaskEven; 6381.1Smacallan int nmiddleEven; 6391.1Smacallan 6401.1Smacallan FbBits *dst; 6411.1Smacallan int leftShiftOdd, rightShiftOdd; 6421.1Smacallan FbBits startmaskOdd, endmaskOdd; 6431.1Smacallan int nmiddleOdd; 6441.1Smacallan 6451.1Smacallan int leftShift, rightShift; 6461.1Smacallan FbBits startmask, endmask; 6471.1Smacallan int nmiddle; 6481.1Smacallan 6491.1Smacallan int srcX, dstX; 6501.1Smacallan 6511.1Smacallan FbBits bits, bits1; 6521.1Smacallan int n; 6531.1Smacallan 6541.1Smacallan Bool destInvarient; 6551.1Smacallan Bool even; 6561.1Smacallan FbDeclareMergeRop (); 6571.1Smacallan 6581.1Smacallan FbInitializeMergeRop (alu, pm); 6591.1Smacallan destInvarient = FbDestInvarientMergeRop(); 6601.1Smacallan 6611.1Smacallan srcLine += srcXEven >> FB_SHIFT; 6621.1Smacallan dstLine += dstXEven >> FB_SHIFT; 6631.1Smacallan srcXEven &= FB_MASK; 6641.1Smacallan dstXEven &= FB_MASK; 6651.1Smacallan srcXOdd &= FB_MASK; 6661.1Smacallan dstXOdd &= FB_MASK; 6671.1Smacallan 6681.1Smacallan FbMaskBits(dstXEven, width, startmaskEven, nmiddleEven, endmaskEven); 6691.1Smacallan FbMaskBits(dstXOdd, width, startmaskOdd, nmiddleOdd, endmaskOdd); 6701.1Smacallan 6711.1Smacallan even = TRUE; 6721.1Smacallan InitializeShifts(srcXEven, dstXEven, leftShiftEven, rightShiftEven); 6731.1Smacallan InitializeShifts(srcXOdd, dstXOdd, leftShiftOdd, rightShiftOdd); 6741.1Smacallan while (height--) 6751.1Smacallan { 6761.1Smacallan src = srcLine; 6771.1Smacallan dst = dstLine; 6781.1Smacallan if (even) 6791.1Smacallan { 6801.1Smacallan srcX = srcXEven; 6811.1Smacallan dstX = dstXEven; 6821.1Smacallan startmask = startmaskEven; 6831.1Smacallan endmask = endmaskEven; 6841.1Smacallan nmiddle = nmiddleEven; 6851.1Smacallan leftShift = leftShiftEven; 6861.1Smacallan rightShift = rightShiftEven; 6871.1Smacallan srcLine += srcStrideEven; 6881.1Smacallan dstLine += dstStrideEven; 6891.1Smacallan even = FALSE; 6901.1Smacallan } 6911.1Smacallan else 6921.1Smacallan { 6931.1Smacallan srcX = srcXOdd; 6941.1Smacallan dstX = dstXOdd; 6951.1Smacallan startmask = startmaskOdd; 6961.1Smacallan endmask = endmaskOdd; 6971.1Smacallan nmiddle = nmiddleOdd; 6981.1Smacallan leftShift = leftShiftOdd; 6991.1Smacallan rightShift = rightShiftOdd; 7001.1Smacallan srcLine += srcStrideOdd; 7011.1Smacallan dstLine += dstStrideOdd; 7021.1Smacallan even = TRUE; 7031.1Smacallan } 7041.1Smacallan if (srcX == dstX) 7051.1Smacallan { 7061.1Smacallan if (startmask) 7071.1Smacallan { 7081.1Smacallan bits = READ(src++); 7091.1Smacallan WRITE(dst, FbDoMaskMergeRop (bits, READ(dst), startmask)); 7101.1Smacallan dst++; 7111.1Smacallan } 7121.1Smacallan n = nmiddle; 7131.1Smacallan if (destInvarient) 7141.1Smacallan { 7151.1Smacallan while (n--) 7161.1Smacallan { 7171.1Smacallan bits = READ(src++); 7181.1Smacallan WRITE(dst, FbDoDestInvarientMergeRop(bits)); 7191.1Smacallan dst++; 7201.1Smacallan } 7211.1Smacallan } 7221.1Smacallan else 7231.1Smacallan { 7241.1Smacallan while (n--) 7251.1Smacallan { 7261.1Smacallan bits = READ(src++); 7271.1Smacallan WRITE(dst, FbDoMergeRop (bits, READ(dst))); 7281.1Smacallan dst++; 7291.1Smacallan } 7301.1Smacallan } 7311.1Smacallan if (endmask) 7321.1Smacallan { 7331.1Smacallan bits = READ(src); 7341.1Smacallan WRITE(dst, FbDoMaskMergeRop(bits, READ(dst), endmask)); 7351.1Smacallan } 7361.1Smacallan } 7371.1Smacallan else 7381.1Smacallan { 7391.1Smacallan bits = 0; 7401.1Smacallan if (srcX > dstX) 7411.1Smacallan bits = READ(src++); 7421.1Smacallan if (startmask) 7431.1Smacallan { 7441.1Smacallan bits1 = FbScrLeft(bits, leftShift); 7451.1Smacallan bits = READ(src++); 7461.1Smacallan bits1 |= FbScrRight(bits, rightShift); 7471.1Smacallan WRITE(dst, FbDoMaskMergeRop (bits1, READ(dst), startmask)); 7481.1Smacallan dst++; 7491.1Smacallan } 7501.1Smacallan n = nmiddle; 7511.1Smacallan if (destInvarient) 7521.23Smacallan { 7531.1Smacallan while (n--) 7541.5Smacallan { 7551.5Smacallan bits1 = FbScrLeft(bits, leftShift); 7561.5Smacallan bits = READ(src++); 7571.7Sriastrad bits1 |= FbScrRight(bits, rightShift); 7581.5Smacallan WRITE(dst, FbDoDestInvarientMergeRop(bits1)); 7591.7Sriastrad dst++; 7601.7Sriastrad } 7611.7Sriastrad } 7621.7Sriastrad else 7631.5Smacallan { 7641.7Sriastrad while (n--) 7651.7Sriastrad { 7661.5Smacallan bits1 = FbScrLeft(bits, leftShift); 7671.5Smacallan bits = READ(src++); 7681.5Smacallan bits1 |= FbScrRight(bits, rightShift); 7691.5Smacallan WRITE(dst, FbDoMergeRop(bits1, READ(dst))); 7701.7Sriastrad dst++; 7711.7Sriastrad } 7721.7Sriastrad } 7731.7Sriastrad if (endmask) 7741.1Smacallan { 7751.5Smacallan bits1 = FbScrLeft(bits, leftShift); 7761.5Smacallan if (FbScrLeft(endmask, rightShift)) 7771.5Smacallan { 7781.5Smacallan bits = READ(src); 7791.7Sriastrad bits1 |= FbScrRight(bits, rightShift); 7801.1Smacallan } 7811.1Smacallan WRITE(dst, FbDoMaskMergeRop (bits1, READ(dst), endmask)); 7821.23Smacallan } 7831.23Smacallan } 7841.23Smacallan } 7851.23Smacallan} 7861.24Sriastrad 7871.24Sriastrad#ifdef FB_24BIT 7881.23Smacallanvoid 7891.23SmacallanfbBltOdd24 (FbBits *srcLine, 7901.23Smacallan FbStride srcStrideEven, 7911.23Smacallan FbStride srcStrideOdd, 7921.24Sriastrad int srcXEven, 7931.23Smacallan int srcXOdd, 7941.23Smacallan 7951.1Smacallan FbBits *dstLine, 7961.5Smacallan FbStride dstStrideEven, 7971.5Smacallan FbStride dstStrideOdd, 7981.5Smacallan int dstXEven, 7991.5Smacallan int dstXOdd, 8001.23Smacallan 8011.1Smacallan int width, 8021.1Smacallan int height, 8031.1Smacallan 8041.1Smacallan int alu, 8051.1Smacallan FbBits pm) 8061.1Smacallan{ 8071.1Smacallan Bool even = TRUE; 8081.7Sriastrad 8091.1Smacallan while (height--) 8101.1Smacallan { 8111.5Smacallan if (even) 8121.1Smacallan { 8131.1Smacallan fbBlt24Line (srcLine, srcXEven, dstLine, dstXEven, 8141.1Smacallan width, alu, pm, FALSE); 8151.7Sriastrad srcLine += srcStrideEven; 8161.5Smacallan dstLine += dstStrideEven; 8171.5Smacallan even = FALSE; 8181.5Smacallan } 8191.5Smacallan else 8201.7Sriastrad { 8211.7Sriastrad fbBlt24Line (srcLine, srcXOdd, dstLine, dstXOdd, 8221.7Sriastrad width, alu, pm, FALSE); 8231.5Smacallan srcLine += srcStrideOdd; 8241.11Sriastrad dstLine += dstStrideOdd; 8251.10Smacallan even = TRUE; 8261.24Sriastrad } 8271.23Smacallan } 8281.23Smacallan} 8291.23Smacallan#endif 8301.23Smacallan 8311.23Smacallan#endif 8321.23Smacallan 8331.23Smacallan#if FB_STIP_SHIFT != FB_SHIFT 8341.23Smacallanvoid 8351.5SmacallanfbSetBltOdd (FbStip *stip, 8361.5Smacallan FbStride stipStride, 8371.23Smacallan int srcX, 8381.5Smacallan FbBits **bits, 8391.5Smacallan FbStride *strideEven, 8401.5Smacallan FbStride *strideOdd, 8411.5Smacallan int *srcXEven, 8421.5Smacallan int *srcXOdd) 8431.5Smacallan{ 8441.5Smacallan int srcAdjust; 8451.5Smacallan int strideAdjust; 8461.7Sriastrad 8471.5Smacallan /* 8481.7Sriastrad * bytes needed to align source 8491.7Sriastrad */ 8501.7Sriastrad srcAdjust = (((int) stip) & (FB_MASK >> 3)); 8511.5Smacallan /* 8521.5Smacallan * FbStip units needed to align stride 8531.19Smacallan */ 8541.7Sriastrad strideAdjust = stipStride & (FB_MASK >> FB_STIP_SHIFT); 8551.5Smacallan 8561.5Smacallan *bits = (FbBits *) ((char *) stip - srcAdjust); 8571.5Smacallan if (srcAdjust) 8581.5Smacallan { 8591.5Smacallan *strideEven = FbStipStrideToBitsStride (stipStride + 1); 8601.5Smacallan *strideOdd = FbStipStrideToBitsStride (stipStride); 8611.5Smacallan 8621.5Smacallan *srcXEven = srcX + (srcAdjust << 3); 8631.5Smacallan *srcXOdd = srcX + (srcAdjust << 3) - (strideAdjust << FB_STIP_SHIFT); 8641.5Smacallan } 8651.5Smacallan else 8661.5Smacallan { 8671.5Smacallan *strideEven = FbStipStrideToBitsStride (stipStride); 8681.5Smacallan *strideOdd = FbStipStrideToBitsStride (stipStride + 1); 8691.5Smacallan 8701.5Smacallan *srcXEven = srcX; 8711.7Sriastrad *srcXOdd = srcX + (strideAdjust << FB_STIP_SHIFT); 8721.7Sriastrad } 8731.5Smacallan} 8741.5Smacallan#endif 8751.7Sriastrad 8761.7Sriastradvoid 8771.5SmacallanfbBltStip (FbStip *src, 8781.5Smacallan FbStride srcStride, /* in FbStip units, not FbBits units */ 8791.1Smacallan int srcX, 8801.1Smacallan 8811.1Smacallan FbStip *dst, 8821.1Smacallan FbStride dstStride, /* in FbStip units, not FbBits units */ 8831.1Smacallan int dstX, 8841.1Smacallan 8851.1Smacallan int width, 8861.7Sriastrad int height, 8871.1Smacallan 8881.1Smacallan int alu, 8891.1Smacallan FbBits pm, 8901.1Smacallan int bpp) 8911.1Smacallan{ 8921.1Smacallan#if FB_STIP_SHIFT != FB_SHIFT 8931.1Smacallan if (FB_STIP_ODDSTRIDE(srcStride) || FB_STIP_ODDPTR(src) || 8941.1Smacallan FB_STIP_ODDSTRIDE(dstStride) || FB_STIP_ODDPTR(dst)) 8951.1Smacallan { 8961.1Smacallan FbStride srcStrideEven, srcStrideOdd; 8971.1Smacallan FbStride dstStrideEven, dstStrideOdd; 8981.1Smacallan int srcXEven, srcXOdd; 8991.1Smacallan int dstXEven, dstXOdd; 9001.1Smacallan FbBits *s, *d; 9011.1Smacallan int sx, dx; 9021.1Smacallan 9031.5Smacallan src += srcX >> FB_STIP_SHIFT; 9041.1Smacallan srcX &= FB_STIP_MASK; 9051.1Smacallan dst += dstX >> FB_STIP_SHIFT; 9061.1Smacallan dstX &= FB_STIP_MASK; 9071.1Smacallan 9081.1Smacallan fbSetBltOdd (src, srcStride, srcX, 9091.1Smacallan &s, 9101.1Smacallan &srcStrideEven, &srcStrideOdd, 9111.1Smacallan &srcXEven, &srcXOdd); 9121.1Smacallan 9131.1Smacallan fbSetBltOdd (dst, dstStride, dstX, 9141.3Smacallan &d, 9151.7Sriastrad &dstStrideEven, &dstStrideOdd, 9161.1Smacallan &dstXEven, &dstXOdd); 9171.3Smacallan 9181.1Smacallan#ifdef FB_24BIT 9191.1Smacallan if (bpp == 24 && !FbCheck24Pix (pm)) 9201.1Smacallan { 9211.1Smacallan fbBltOdd24 (s, srcStrideEven, srcStrideOdd, 9221.1Smacallan srcXEven, srcXOdd, 9231.1Smacallan 9241.7Sriastrad d, dstStrideEven, dstStrideOdd, 9251.1Smacallan dstXEven, dstXOdd, 9261.1Smacallan 9271.7Sriastrad width, height, alu, pm); 9281.1Smacallan } 9291.1Smacallan else 9301.1Smacallan#endif 9311.1Smacallan { 9321.7Sriastrad fbBltOdd (s, srcStrideEven, srcStrideOdd, 9331.1Smacallan srcXEven, srcXOdd, 9341.3Smacallan 9351.1Smacallan d, dstStrideEven, dstStrideOdd, 9361.3Smacallan dstXEven, dstXOdd, 9371.1Smacallan 9381.1Smacallan width, height, alu, pm, bpp); 9391.2Smacallan } 9401.21Smacallan } 9411.21Smacallan else 9421.2Smacallan#endif 9431.2Smacallan { 9441.14Smacallan fbBlt ((FbBits *) src, FbStipStrideToBitsStride (srcStride), 9451.2Smacallan srcX, 9461.2Smacallan (FbBits *) dst, FbStipStrideToBitsStride (dstStride), 9471.2Smacallan dstX, 9481.7Sriastrad width, height, 9491.20Smacallan alu, pm, bpp, FALSE, FALSE); 9501.21Smacallan } 9511.2Smacallan} 9521.2Smacallan