#ifdef HAVE_XORG_CONFIG_H #include #endif #include "xaa.h" #include "xaalocal.h" #include "xaacexp.h" #include "xf86.h" /********** byte swapping ***************/ #ifdef FIXEDBASE #define DEST(i) *dest #define RETURN(i) return(dest) #else #define DEST(i) dest[i] #define RETURN(i) return(dest + i) #endif #ifdef MSBFIRST #define SOURCE(i) SWAP_BITS_IN_BYTES(src[i]) #else #define SOURCE(i) src[i] #endif typedef CARD32 *(*BitmapScanlineProcPtr) (CARD32 *, CARD32 *, int, int); #ifdef TRIPLE_BITS static CARD32 * BitmapScanline(CARD32 *src, CARD32 *base, int count, int skipleft) { CARD32 bits; while (count >= 3) { bits = *src; WRITE_BITS3(bits); src++; count -= 3; } if (count == 2) { bits = *src; WRITE_BITS2(bits); } else if (count == 1) { bits = *src; WRITE_BITS1(bits); } return base; } static CARD32 * BitmapScanline_Inverted(CARD32 *src, CARD32 *base, int count, int skipleft) { CARD32 bits; while (count >= 3) { bits = ~(*src); WRITE_BITS3(bits); src++; count -= 3; } if (count == 2) { bits = ~(*src); WRITE_BITS2(bits); } else if (count == 1) { bits = ~(*src); WRITE_BITS1(bits); } return base; } static CARD32 * BitmapScanline_Shifted(CARD32 *src, CARD32 *base, int count, int skipleft) { CARD32 bits; while (count >= 3) { bits = SHIFT_R(*src, skipleft) | SHIFT_L(*(src + 1), (32 - skipleft)); WRITE_BITS3(bits); src++; count -= 3; } if (count == 2) { bits = SHIFT_R(*src, skipleft) | SHIFT_L(*(src + 1), (32 - skipleft)); WRITE_BITS2(bits); } else if (count == 1) { bits = SHIFT_R(*src, skipleft) | SHIFT_L(*(src + 1), (32 - skipleft)); WRITE_BITS1(bits); } return base; } static CARD32 * BitmapScanline_Shifted_Inverted(CARD32 *src, CARD32 *base, int count, int skipleft) { CARD32 bits; while (count >= 3) { bits = ~(SHIFT_R(*src, skipleft) | SHIFT_L(*(src + 1), (32 - skipleft))); WRITE_BITS3(bits); src++; count -= 3; } if (count == 2) { bits = ~(SHIFT_R(*src, skipleft) | SHIFT_L(*(src + 1), (32 - skipleft))); WRITE_BITS2(bits); } else if (count == 1) { bits = ~(SHIFT_R(*src, skipleft) | SHIFT_L(*(src + 1), (32 - skipleft))); WRITE_BITS1(bits); } return base; } #define BitmapScanline_Shifted_Careful BitmapScanline_Shifted #define BitmapScanline_Shifted_Inverted_Careful BitmapScanline_Shifted_Inverted #else static CARD32 * BitmapScanline(CARD32 *src, CARD32 *dest, int count, int skipleft) { while (count >= 4) { DEST(0) = SOURCE(0); DEST(1) = SOURCE(1); DEST(2) = SOURCE(2); DEST(3) = SOURCE(3); count -= 4; src += 4; #ifndef FIXEDBASE dest += 4; #endif } if (!count) return dest; DEST(0) = SOURCE(0); if (count == 1) RETURN(1); DEST(1) = SOURCE(1); if (count == 2) RETURN(2); DEST(2) = SOURCE(2); RETURN(3); } static CARD32 * BitmapScanline_Inverted(CARD32 *src, CARD32 *dest, int count, int skipleft) { while (count >= 4) { DEST(0) = ~SOURCE(0); DEST(1) = ~SOURCE(1); DEST(2) = ~SOURCE(2); DEST(3) = ~SOURCE(3); count -= 4; src += 4; #ifndef FIXEDBASE dest += 4; #endif } if (!count) return dest; DEST(0) = ~SOURCE(0); if (count == 1) RETURN(1); DEST(1) = ~SOURCE(1); if (count == 2) RETURN(2); DEST(2) = ~SOURCE(2); RETURN(3); } static CARD32 * BitmapScanline_Shifted(CARD32 *bits, CARD32 *base, int count, int skipleft) { while (count--) { register CARD32 tmp = SHIFT_R(*bits, skipleft) | SHIFT_L(*(bits + 1), (32 - skipleft)); WRITE_BITS(tmp); bits++; } return base; } static CARD32 * BitmapScanline_Shifted_Inverted(CARD32 *bits, CARD32 *base, int count, int skipleft) { while (count--) { register CARD32 tmp = ~(SHIFT_R(*bits, skipleft) | SHIFT_L(*(bits + 1), (32 - skipleft))); WRITE_BITS(tmp); bits++; } return base; } static CARD32 * BitmapScanline_Shifted_Careful(CARD32 *bits, CARD32 *base, int count, int skipleft) { register CARD32 tmp; while (--count) { tmp = SHIFT_R(*bits, skipleft) | SHIFT_L(*(bits + 1), (32 - skipleft)); WRITE_BITS(tmp); bits++; } tmp = SHIFT_R(*bits, skipleft); WRITE_BITS(tmp); return base; } static CARD32 * BitmapScanline_Shifted_Inverted_Careful(CARD32 *bits, CARD32 *base, int count, int skipleft) { register CARD32 tmp; while (--count) { tmp = ~(SHIFT_R(*bits, skipleft) | SHIFT_L(*(bits + 1), (32 - skipleft))); WRITE_BITS(tmp); bits++; } tmp = ~(SHIFT_R(*bits, skipleft)); WRITE_BITS(tmp); return base; } #endif /* When the accelerator is TRANSPARENCY_ONLY, WriteBitmap can do the fill in two passes, inverting the source on the second pass. For GXcopy we can fill the backing rectangle as a solid rect and avoid the invert. */ void #ifdef TRIPLE_BITS EXPNAME(XAAWriteBitmapColorExpand3) ( #else EXPNAME(XAAWriteBitmapColorExpand) ( #endif ScrnInfoPtr pScrn, int x, int y, int w, int H, unsigned char *src, int srcwidth, int skipleft, int fg, int bg, int rop, unsigned int planemask) { XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); CARD32 *base; unsigned char *srcp = src; int SecondPassColor = -1; int shift = 0, dwords; BitmapScanlineProcPtr firstFunc; BitmapScanlineProcPtr secondFunc; int flag; int h = H; #ifdef TRIPLE_BITS if ((bg != -1) && ((infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) || ((infoRec->CPUToScreenColorExpandFillFlags & RGB_EQUAL) && (!CHECK_RGB_EQUAL(bg))))) { #else if ((bg != -1) && (infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) { #endif if ((rop == GXcopy) && infoRec->SetupForSolidFill) { (*infoRec->SetupForSolidFill) (pScrn, bg, rop, planemask); (*infoRec->SubsequentSolidFillRect) (pScrn, x, y, w, h); } else SecondPassColor = bg; bg = -1; } #ifdef TRIPLE_BITS if (skipleft) { #else if (skipleft && (!(infoRec->CPUToScreenColorExpandFillFlags & LEFT_EDGE_CLIPPING) || (!(infoRec-> CPUToScreenColorExpandFillFlags & LEFT_EDGE_CLIPPING_NEGATIVE_X) && (skipleft > x)))) { #endif if ((skipleft + ((w + 31) & ~31)) > ((skipleft + w + 31) & ~31)) { /* don't read past the end */ firstFunc = BitmapScanline_Shifted_Careful; secondFunc = BitmapScanline_Shifted_Inverted_Careful; } else { firstFunc = BitmapScanline_Shifted; secondFunc = BitmapScanline_Shifted_Inverted; } shift = skipleft; skipleft = 0; } else { firstFunc = BitmapScanline; secondFunc = BitmapScanline_Inverted; w += skipleft; x -= skipleft; } #ifdef TRIPLE_BITS dwords = (3 * w + 31) >> 5; #else dwords = (w + 31) >> 5; #endif SECOND_PASS: flag = (infoRec->CPUToScreenColorExpandFillFlags & CPU_TRANSFER_PAD_QWORD) && ((dwords * h) & 0x01); (*infoRec->SetupForCPUToScreenColorExpandFill) (pScrn, fg, bg, rop, planemask); (*infoRec->SubsequentCPUToScreenColorExpandFill) (pScrn, x, y, w, h, skipleft); base = (CARD32 *) infoRec->ColorExpandBase; #ifndef FIXEDBASE if ((dwords * h) <= infoRec->ColorExpandRange) while (h--) { base = (*firstFunc) ((CARD32 *) srcp, base, dwords, shift); srcp += srcwidth; } else #endif while (h--) { (*firstFunc) ((CARD32 *) srcp, base, dwords, shift); srcp += srcwidth; } if (flag) { base = (CARD32 *) infoRec->ColorExpandBase; base[0] = 0x00000000; } if (SecondPassColor != -1) { h = H; /* Reset height */ fg = SecondPassColor; SecondPassColor = -1; firstFunc = secondFunc; srcp = src; goto SECOND_PASS; } if (infoRec->CPUToScreenColorExpandFillFlags & SYNC_AFTER_COLOR_EXPAND) (*infoRec->Sync) (pScrn); else SET_SYNC_FLAG(infoRec); } #ifndef FIXEDBASE void #ifdef TRIPLE_BITS EXPNAME(XAAWriteBitmapScanlineColorExpand3) ( #else EXPNAME(XAAWriteBitmapScanlineColorExpand) ( #endif ScrnInfoPtr pScrn, int x, int y, int w, int h, unsigned char *src, int srcwidth, int skipleft, int fg, int bg, int rop, unsigned int planemask) { XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); CARD32 *base; unsigned char *srcp = src; int SecondPassColor = -1; int shift = 0, dwords, bufferNo; BitmapScanlineProcPtr firstFunc; BitmapScanlineProcPtr secondFunc; #ifdef TRIPLE_BITS if ((bg != -1) && ((infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) || ((infoRec->ScanlineCPUToScreenColorExpandFillFlags & RGB_EQUAL) && (!CHECK_RGB_EQUAL(bg))))) { #else if ((bg != -1) && (infoRec-> ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) { #endif if ((rop == GXcopy) && infoRec->SetupForSolidFill) { (*infoRec->SetupForSolidFill) (pScrn, bg, rop, planemask); (*infoRec->SubsequentSolidFillRect) (pScrn, x, y, w, h); } else SecondPassColor = bg; bg = -1; } #ifdef TRIPLE_BITS if (skipleft) { #else if (skipleft && (!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & LEFT_EDGE_CLIPPING) || (!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & LEFT_EDGE_CLIPPING_NEGATIVE_X) && (skipleft > x)))) { #endif if ((skipleft + ((w + 31) & ~31)) > ((skipleft + w + 31) & ~31)) { /* don't read past the end */ firstFunc = BitmapScanline_Shifted_Careful; secondFunc = BitmapScanline_Shifted_Inverted_Careful; } else { firstFunc = BitmapScanline_Shifted; secondFunc = BitmapScanline_Shifted_Inverted; } shift = skipleft; skipleft = 0; } else { firstFunc = BitmapScanline; secondFunc = BitmapScanline_Inverted; w += skipleft; x -= skipleft; } #ifdef TRIPLE_BITS dwords = (3 * w + 31) >> 5; #else dwords = (w + 31) >> 5; #endif SECOND_PASS: (*infoRec->SetupForScanlineCPUToScreenColorExpandFill) (pScrn, fg, bg, rop, planemask); (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill) (pScrn, x, y, w, h, skipleft); bufferNo = 0; while (h--) { base = (CARD32 *) infoRec->ScanlineColorExpandBuffers[bufferNo]; (*firstFunc) ((CARD32 *) srcp, base, dwords, shift); (*infoRec->SubsequentColorExpandScanline) (pScrn, bufferNo++); srcp += srcwidth; if (bufferNo >= infoRec->NumScanlineColorExpandBuffers) bufferNo = 0; } if (SecondPassColor != -1) { fg = SecondPassColor; SecondPassColor = -1; firstFunc = secondFunc; srcp = src; goto SECOND_PASS; } SET_SYNC_FLAG(infoRec); } #endif