diff options
Diffstat (limited to 'xorg-server/hw/xfree86/xaa/xaaStipple.c')
-rw-r--r-- | xorg-server/hw/xfree86/xaa/xaaStipple.c | 866 |
1 files changed, 866 insertions, 0 deletions
diff --git a/xorg-server/hw/xfree86/xaa/xaaStipple.c b/xorg-server/hw/xfree86/xaa/xaaStipple.c new file mode 100644 index 000000000..0dd8e9fcf --- /dev/null +++ b/xorg-server/hw/xfree86/xaa/xaaStipple.c @@ -0,0 +1,866 @@ + +#ifdef HAVE_XORG_CONFIG_H +#include <xorg-config.h> +#endif + +#include "xaa.h" +#include "xaalocal.h" +#include "xaacexp.h" +#include "xf86.h" + +static CARD32* StipplePowerOfTwo(CARD32*, CARD32*, int, int, int); +static CARD32* StipplePowerOfTwo_Inverted(CARD32*, CARD32*, int, int, int); +static CARD32* StippleUpTo32(CARD32*, CARD32*, int, int, int); +static CARD32* StippleUpTo32_Inverted(CARD32*, CARD32*, int, int, int); +static CARD32* StippleOver32(CARD32*, CARD32*, int, int, int); +static CARD32* StippleOver32_Inverted(CARD32*, CARD32*, int, int, int); + +#ifdef TRIPLE_BITS +#define stipple_scanline_func EXPNAME(XAAStippleScanlineFunc3) +#define stipple_get_scanline_func EXPNAME(XAAGetStippleScanlineFunc3) +#else +#define stipple_scanline_func EXPNAME(XAAStippleScanlineFunc) +#define stipple_get_scanline_func EXPNAME(XAAGetStippleScanlineFunc) +#endif + +StippleScanlineProcPtr stipple_scanline_func[6] = { + StipplePowerOfTwo, + StippleUpTo32, + StippleOver32, + StipplePowerOfTwo_Inverted, + StippleUpTo32_Inverted, + StippleOver32_Inverted +}; + +StippleScanlineProcPtr *stipple_get_scanline_func(void) { + return stipple_scanline_func; +} + +#ifdef FIXEDBASE +# define DEST(i) *dest +# define RETURN(i) return(dest) +#else +# define DEST(i) dest[i] +# define RETURN(i) return(dest + i) +#endif + + +/* TRIPLE_BITS pattern expansion */ +#ifdef TRIPLE_BITS +#define EXPAND_PAT \ + CARD32 pat1 = byte_expand3[pat & 0xFF], \ + pat2 = byte_expand3[(pat & 0xFF00) >> 8], \ + pat3 = byte_expand3[(pat & 0xFF0000) >> 16], \ + pat4 = byte_expand3[(pat & 0xFF000000) >> 24], \ + patA = pat1 | (pat2 << 24), \ + patB = (pat2 >> 8) | (pat3 << 16), \ + patC = (pat3 >> 16) | (pat4 << 8) +#ifdef FIXED_BASE +#define WRITE_PAT1 { \ + *dest = patA; } +#define WRITE_PAT2 { \ + *dest = patA; \ + *dest = patB; } +#define WRITE_PAT3 { \ + *dest = patA; \ + *dest = patB; \ + *dest = patC; } +#else +#define WRITE_PAT1 { \ + *(dest++) = patA; } +#define WRITE_PAT2 { \ + *(dest) = patA; \ + *(dest + 1) = patB; \ + dest += 2; } +#define WRITE_PAT3 { \ + *(dest) = patA; \ + *(dest + 1) = patB; \ + *(dest + 2) = patC; \ + dest += 3; } +#endif +#endif + + +#if !defined(FIXEDBASE) && !defined(MSBFIRST) && !defined(TRIPLE_BITS) + +unsigned int XAAShiftMasks[32] = { + /* gcc is rather pedantic about SHIFT_R(0xFFFFFFFF,32) */ + 0x00000000 , SHIFT_R(0xFFFFFFFF,31), + SHIFT_R(0xFFFFFFFF,30), SHIFT_R(0xFFFFFFFF,29), + SHIFT_R(0xFFFFFFFF,28), SHIFT_R(0xFFFFFFFF,27), + SHIFT_R(0xFFFFFFFF,26), SHIFT_R(0xFFFFFFFF,25), + SHIFT_R(0xFFFFFFFF,24), SHIFT_R(0xFFFFFFFF,23), + SHIFT_R(0xFFFFFFFF,22), SHIFT_R(0xFFFFFFFF,21), + SHIFT_R(0xFFFFFFFF,20), SHIFT_R(0xFFFFFFFF,19), + SHIFT_R(0xFFFFFFFF,18), SHIFT_R(0xFFFFFFFF,17), + SHIFT_R(0xFFFFFFFF,16), SHIFT_R(0xFFFFFFFF,15), + SHIFT_R(0xFFFFFFFF,14), SHIFT_R(0xFFFFFFFF,13), + SHIFT_R(0xFFFFFFFF,12), SHIFT_R(0xFFFFFFFF,11), + SHIFT_R(0xFFFFFFFF,10), SHIFT_R(0xFFFFFFFF,9), + SHIFT_R(0xFFFFFFFF,8), SHIFT_R(0xFFFFFFFF,7), + SHIFT_R(0xFFFFFFFF,6), SHIFT_R(0xFFFFFFFF,5), + SHIFT_R(0xFFFFFFFF,4), SHIFT_R(0xFFFFFFFF,3), + SHIFT_R(0xFFFFFFFF,2), SHIFT_R(0xFFFFFFFF,1) +}; + +#endif + +void +#ifdef TRIPLE_BITS +EXPNAME(XAAFillColorExpandRects3)( +#else +EXPNAME(XAAFillColorExpandRects)( +#endif + ScrnInfoPtr pScrn, + int fg, int bg, int rop, + unsigned int planemask, + int nBox, + BoxPtr pBox, + int xorg, int yorg, + PixmapPtr pPix +){ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + CARD32 *base; + Bool TwoPass = FALSE, FirstPass = TRUE; + StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc; + int stipplewidth = pPix->drawable.width; + int stippleheight = pPix->drawable.height; + int srcwidth = pPix->devKind; + int dwords, srcy, srcx, funcNo = 2, h; + unsigned char *src = (unsigned char*)pPix->devPrivate.ptr; + unsigned char *srcp; + int flag; + + if(stipplewidth <= 32) { + if(stipplewidth & (stipplewidth - 1)) + funcNo = 1; + else + funcNo = 0; + } + StippleFunc = stipple_scanline_func[funcNo]; + SecondFunc = stipple_scanline_func[funcNo]; + FirstFunc = stipple_scanline_func[funcNo + 3]; + +#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 + /* one pass */ + } else if((rop == GXcopy) && infoRec->FillSolidRects) { + /* one pass but we fill background rects first */ + (*infoRec->FillSolidRects)(pScrn, bg, rop, planemask, nBox, pBox); + bg = -1; + } else { + /* gotta do two passes */ + TwoPass = TRUE; + } + + if(!TwoPass) + (*infoRec->SetupForCPUToScreenColorExpandFill)( + pScrn, fg, bg, rop, planemask); + + while(nBox--) { +#ifdef TRIPLE_BITS + dwords = (3 * (pBox->x2 - pBox->x1) + 31) >> 5; +#else + dwords = (pBox->x2 - pBox->x1 + 31) >> 5; +#endif + +SECOND_PASS: + if(TwoPass) { + (*infoRec->SetupForCPUToScreenColorExpandFill)(pScrn, + (FirstPass) ? bg : fg, -1, rop, planemask); + StippleFunc = (FirstPass) ? FirstFunc : SecondFunc; + } + + h = pBox->y2 - pBox->y1; + flag = (infoRec->CPUToScreenColorExpandFillFlags + & CPU_TRANSFER_PAD_QWORD) && ((dwords * h) & 0x01); + + (*infoRec->SubsequentCPUToScreenColorExpandFill)( + pScrn, pBox->x1, pBox->y1, + pBox->x2 - pBox->x1, h, 0); + + base = (CARD32*)infoRec->ColorExpandBase; + + srcy = (pBox->y1 - yorg) % stippleheight; + if(srcy < 0) srcy += stippleheight; + srcx = (pBox->x1 - xorg) % stipplewidth; + if(srcx < 0) srcx += stipplewidth; + + srcp = (srcwidth * srcy) + src; + +#ifndef FIXEDBASE + if((dwords * h) <= infoRec->ColorExpandRange) { + while(h--) { + base = (*StippleFunc)( + base, (CARD32*)srcp, srcx, stipplewidth, dwords); + srcy++; + srcp += srcwidth; + if (srcy >= stippleheight) { + srcy = 0; + srcp = src; + } + } + } else +#endif + while(h--) { + (*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords); + srcy++; + srcp += srcwidth; + if (srcy >= stippleheight) { + srcy = 0; + srcp = src; + } + } + + if (flag) { + base = (CARD32*)infoRec->ColorExpandBase; + base[0] = 0x00000000; + } + + if(TwoPass) { + if(FirstPass) { + FirstPass = FALSE; + goto SECOND_PASS; + } else FirstPass = TRUE; + } + + pBox++; + } + + if(infoRec->CPUToScreenColorExpandFillFlags & SYNC_AFTER_COLOR_EXPAND) + (*infoRec->Sync)(pScrn); + else SET_SYNC_FLAG(infoRec); +} + + + +void +#ifdef TRIPLE_BITS +EXPNAME(XAAFillColorExpandSpans3)( +#else +EXPNAME(XAAFillColorExpandSpans)( +#endif + ScrnInfoPtr pScrn, + int fg, int bg, int rop, + unsigned int planemask, + int n, + DDXPointPtr ppt, + int *pwidth, + int fSorted, + int xorg, int yorg, + PixmapPtr pPix +){ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + CARD32 *base; + Bool TwoPass = FALSE, FirstPass = TRUE; + StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc; + int stipplewidth = pPix->drawable.width; + int stippleheight = pPix->drawable.height; + int dwords, srcy, srcx, funcNo = 2; + unsigned char *srcp; + + if(stipplewidth <= 32) { + if(stipplewidth & (stipplewidth - 1)) + funcNo = 1; + else + funcNo = 0; + } + StippleFunc = stipple_scanline_func[funcNo]; + SecondFunc = stipple_scanline_func[funcNo]; + FirstFunc = stipple_scanline_func[funcNo + 3]; + +#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 + /* one pass */ + } else if((rop == GXcopy) && infoRec->FillSolidSpans) { + /* one pass but we fill background rects first */ + (*infoRec->FillSolidSpans)( + pScrn, bg, rop, planemask, n, ppt, pwidth, fSorted); + bg = -1; + } else { + /* gotta do two passes */ + TwoPass = TRUE; + } + + if(!TwoPass) + (*infoRec->SetupForCPUToScreenColorExpandFill)( + pScrn, fg, bg, rop, planemask); + + while(n--) { +#ifdef TRIPLE_BITS + dwords = (3 * *pwidth + 31) >> 5; +#else + dwords = (*pwidth + 31) >> 5; +#endif + + srcy = (ppt->y - yorg) % stippleheight; + if(srcy < 0) srcy += stippleheight; + srcx = (ppt->x - xorg) % stipplewidth; + if(srcx < 0) srcx += stipplewidth; + + srcp = (pPix->devKind * srcy) + (unsigned char*)pPix->devPrivate.ptr; + +SECOND_PASS: + if(TwoPass) { + (*infoRec->SetupForCPUToScreenColorExpandFill)(pScrn, + (FirstPass) ? bg : fg, -1, rop, planemask); + StippleFunc = (FirstPass) ? FirstFunc : SecondFunc; + } + + (*infoRec->SubsequentCPUToScreenColorExpandFill)(pScrn, ppt->x, ppt->y, + *pwidth, 1, 0); + + base = (CARD32*)infoRec->ColorExpandBase; + + (*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords); + + if((infoRec->CPUToScreenColorExpandFillFlags & CPU_TRANSFER_PAD_QWORD) + && (dwords & 0x01)) { + base = (CARD32*)infoRec->ColorExpandBase; + base[0] = 0x00000000; + } + + if(TwoPass) { + if(FirstPass) { + FirstPass = FALSE; + goto SECOND_PASS; + } else FirstPass = TRUE; + } + + ppt++; pwidth++; + } + + if(infoRec->CPUToScreenColorExpandFillFlags & SYNC_AFTER_COLOR_EXPAND) + (*infoRec->Sync)(pScrn); + else SET_SYNC_FLAG(infoRec); +} + + +#ifndef FIXEDBASE + +void +#ifdef TRIPLE_BITS +EXPNAME(XAAFillScanlineColorExpandRects3)( +#else +EXPNAME(XAAFillScanlineColorExpandRects)( +#endif + ScrnInfoPtr pScrn, + int fg, int bg, int rop, + unsigned int planemask, + int nBox, + BoxPtr pBox, + int xorg, int yorg, + PixmapPtr pPix +){ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + CARD32 *base; + Bool TwoPass = FALSE, FirstPass = TRUE; + StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc; + int stipplewidth = pPix->drawable.width; + int stippleheight = pPix->drawable.height; + int srcwidth = pPix->devKind; + int dwords, srcy, srcx, funcNo = 2, bufferNo, h; + unsigned char *src = pPix->devPrivate.ptr; + unsigned char *srcp; + + if(stipplewidth <= 32) { + if(stipplewidth & (stipplewidth - 1)) + funcNo = 1; + else + funcNo = 0; + } + StippleFunc = stipple_scanline_func[funcNo]; + SecondFunc = stipple_scanline_func[funcNo]; + FirstFunc = stipple_scanline_func[funcNo + 3]; + +#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 + /* one pass */ + } else if((rop == GXcopy) && infoRec->FillSolidRects) { + /* one pass but we fill background rects first */ + (*infoRec->FillSolidRects)(pScrn, bg, rop, planemask, nBox, pBox); + bg = -1; + } else { + /* gotta do two passes */ + TwoPass = TRUE; + } + + if(!TwoPass) + (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)( + pScrn, fg, bg, rop, planemask); + + while(nBox--) { +#ifdef TRIPLE_BITS + dwords = (3 * (pBox->x2 - pBox->x1) + 31) >> 5; +#else + dwords = (pBox->x2 - pBox->x1 + 31) >> 5; +#endif + +SECOND_PASS: + if(TwoPass) { + (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(pScrn, + (FirstPass) ? bg : fg, -1, rop, planemask); + StippleFunc = (FirstPass) ? FirstFunc : SecondFunc; + } + + h = pBox->y2 - pBox->y1; + + (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)( + pScrn, pBox->x1, pBox->y1, pBox->x2 - pBox->x1, h, 0); + + bufferNo = 0; + + srcy = (pBox->y1 - yorg) % stippleheight; + if(srcy < 0) srcy += stippleheight; + srcx = (pBox->x1 - xorg) % stipplewidth; + if(srcx < 0) srcx += stipplewidth; + + srcp = (srcwidth * srcy) + src; + + while(h--) { + base = (CARD32*)infoRec->ScanlineColorExpandBuffers[bufferNo]; + (*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords); + (*infoRec->SubsequentColorExpandScanline)(pScrn, bufferNo++); + if(bufferNo >= infoRec->NumScanlineColorExpandBuffers) + bufferNo = 0; + srcy++; + srcp += srcwidth; + if (srcy >= stippleheight) { + srcy = 0; + srcp = src; + } + } + + if(TwoPass) { + if(FirstPass) { + FirstPass = FALSE; + goto SECOND_PASS; + } else FirstPass = TRUE; + } + + pBox++; + } + + SET_SYNC_FLAG(infoRec); +} + +void +#ifdef TRIPLE_BITS +EXPNAME(XAAFillScanlineColorExpandSpans3)( +#else +EXPNAME(XAAFillScanlineColorExpandSpans)( +#endif + ScrnInfoPtr pScrn, + int fg, int bg, int rop, + unsigned int planemask, + int n, + DDXPointPtr ppt, + int *pwidth, + int fSorted, + int xorg, int yorg, + PixmapPtr pPix +){ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); + CARD32 *base; + Bool TwoPass = FALSE, FirstPass = TRUE; + StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc; + int stipplewidth = pPix->drawable.width; + int stippleheight = pPix->drawable.height; + int dwords, srcy, srcx, funcNo = 2; + unsigned char *srcp; + + if(stipplewidth <= 32) { + if(stipplewidth & (stipplewidth - 1)) + funcNo = 1; + else + funcNo = 0; + } + StippleFunc = stipple_scanline_func[funcNo]; + SecondFunc = stipple_scanline_func[funcNo]; + FirstFunc = stipple_scanline_func[funcNo + 3]; + +#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 + /* one pass */ + } else if((rop == GXcopy) && infoRec->FillSolidSpans) { + /* one pass but we fill background rects first */ + (*infoRec->FillSolidSpans)( + pScrn, bg, rop, planemask, n, ppt, pwidth, fSorted); + bg = -1; + } else { + /* gotta do two passes */ + TwoPass = TRUE; + } + + if(!TwoPass) + (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)( + pScrn, fg, bg, rop, planemask); + + + while(n--) { +#ifdef TRIPLE_BITS + dwords = (3 * *pwidth + 31) >> 5; +#else + dwords = (*pwidth + 31) >> 5; +#endif + + srcy = (ppt->y - yorg) % stippleheight; + if(srcy < 0) srcy += stippleheight; + srcx = (ppt->x - xorg) % stipplewidth; + if(srcx < 0) srcx += stipplewidth; + + srcp = (pPix->devKind * srcy) + (unsigned char*)pPix->devPrivate.ptr; + +SECOND_PASS: + if(TwoPass) { + (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(pScrn, + (FirstPass) ? bg : fg, -1, rop, planemask); + StippleFunc = (FirstPass) ? FirstFunc : SecondFunc; + } + + (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)( + pScrn, ppt->x, ppt->y, *pwidth, 1, 0); + + base = (CARD32*)infoRec->ScanlineColorExpandBuffers[0]; + + (*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords); + (*infoRec->SubsequentColorExpandScanline)(pScrn, 0); + + if(TwoPass) { + if(FirstPass) { + FirstPass = FALSE; + goto SECOND_PASS; + } else FirstPass = TRUE; + } + + ppt++; pwidth++; + } + + SET_SYNC_FLAG(infoRec); +} + +#endif + +static CARD32 * +StipplePowerOfTwo( + CARD32* dest, CARD32* src, + int shift, int width, int dwords +){ + CARD32 pat = *src; + if(width < 32) { + pat &= XAAShiftMasks[width]; + while(width < 32) { + pat |= SHIFT_L(pat,width); + width <<= 1; + } + } + + if(shift) + pat = SHIFT_R(pat,shift) | SHIFT_L(pat,32 - shift); + +#ifdef MSBFIRST + pat = SWAP_BITS_IN_BYTES(pat); +#endif + +#ifdef TRIPLE_BITS + { + EXPAND_PAT; + + while(dwords >= 3) { + WRITE_PAT3; + dwords -= 3; + } + if (dwords == 2) { + WRITE_PAT2; + } else if (dwords == 1) { + WRITE_PAT1; + } + + return dest; + } +#else /* TRIPLE_BITS */ + while(dwords >= 4) { + DEST(0) = pat; + DEST(1) = pat; + DEST(2) = pat; + DEST(3) = pat; + dwords -= 4; +#ifndef FIXEDBASE + dest += 4; +#endif + } + + if(!dwords) return dest; + DEST(0) = pat; + if(dwords == 1) RETURN(1); + DEST(1) = pat; + if(dwords == 2) RETURN(2); + DEST(2) = pat; + RETURN(3); +#endif /* TRIPLE_BITS */ +} + +static CARD32 * +StipplePowerOfTwo_Inverted( + CARD32* dest, CARD32* src, + int shift, int width, int dwords +){ + CARD32 pat = *src; + if(width < 32) { + pat &= XAAShiftMasks[width]; + while(width < 32) { + pat |= SHIFT_L(pat,width); + width <<= 1; + } + } + + if(shift) + pat = SHIFT_R(pat,shift) | SHIFT_L(pat,32 - shift); + +#ifdef MSBFIRST + pat = SWAP_BITS_IN_BYTES(pat); +#endif + + pat = ~pat; + +#ifdef TRIPLE_BITS + { + EXPAND_PAT; + + while(dwords >= 3) { + WRITE_PAT3; + dwords -= 3; + } + if (dwords == 2) { + WRITE_PAT2; + } else if (dwords == 1) { + WRITE_PAT1; + } + + return dest; + } +#else /* TRIPLE_BITS */ + while(dwords >= 4) { + DEST(0) = pat; + DEST(1) = pat; + DEST(2) = pat; + DEST(3) = pat; + dwords -= 4; +#ifndef FIXEDBASE + dest += 4; +#endif + } + + if(!dwords) return dest; + DEST(0) = pat; + if(dwords == 1) RETURN(1); + DEST(1) = pat; + if(dwords == 2) RETURN(2); + DEST(2) = pat; + RETURN(3); +#endif /* TRIPLE_BITS */ +} + + +static CARD32 * +StippleUpTo32( + CARD32* base, CARD32* src, + int shift, int width, int dwords +){ + CARD32 pat = *src & XAAShiftMasks[width]; + + while(width <= 15) { + pat |= SHIFT_L(pat,width); + width <<= 1; + } + pat |= SHIFT_L(pat,width); + + while(dwords--) { + CARD32 bits = SHIFT_R(pat,shift) | SHIFT_L(pat,width-shift); +#ifdef TRIPLE_BITS + if(dwords >= 2) { + WRITE_BITS3(bits); + dwords -= 2; + } else if(dwords > 0) { + WRITE_BITS2(bits); + dwords--; + } else { + WRITE_BITS1(bits); + } +#else + WRITE_BITS(bits); +#endif + + shift += 32; + shift %= width; + } + return base; +} + + +static CARD32 * +StippleUpTo32_Inverted( + CARD32* base, CARD32* src, + int shift, int width, int dwords +){ + CARD32 pat = *src & XAAShiftMasks[width]; + + while(width <= 15) { + pat |= SHIFT_L(pat,width); + width <<= 1; + } + pat |= SHIFT_L(pat,width); + + while(dwords--) { + CARD32 bits = ~(SHIFT_R(pat,shift) | SHIFT_L(pat,width-shift)); +#ifdef TRIPLE_BITS + if(dwords >= 2) { + WRITE_BITS3(bits); + dwords -= 2; + } else if(dwords > 0) { + WRITE_BITS2(bits); + dwords--; + } else { + WRITE_BITS1(bits); + } +#else + WRITE_BITS(bits); +#endif + + shift += 32; + shift %= width; + } + return base; +} + + +static CARD32 * +StippleOver32( + CARD32* base, CARD32* src, + int offset, int width, int dwords +){ + CARD32* srcp; + CARD32 bits; + int bitsleft, shift, usable; + + while(dwords--) { + bitsleft = width - offset; + srcp = src + (offset >> 5); + shift = offset & 31; + usable = 32 - shift; + + if(bitsleft < 32) { + if(bitsleft <= usable) { + bits = SHIFT_L(*src,bitsleft) | + (SHIFT_R(*srcp,shift) & XAAShiftMasks[bitsleft]); + } else { + bits = SHIFT_L(*src,bitsleft) | + (SHIFT_L(srcp[1],usable) & XAAShiftMasks[bitsleft]) | + (SHIFT_R(*srcp,shift) & XAAShiftMasks[usable]); + } + } + else if(shift) + bits = SHIFT_R(*srcp,shift) | SHIFT_L(srcp[1],usable); + else + bits = *srcp; + +#ifdef TRIPLE_BITS + if(dwords >= 2) { + WRITE_BITS3(bits); + dwords -= 2; + } else if(dwords > 0) { + WRITE_BITS2(bits); + dwords--; + } else { + WRITE_BITS1(bits); + } +#else + WRITE_BITS(bits); +#endif + + offset += 32; + offset %= width; + } + return base; +} + + +static CARD32 * +StippleOver32_Inverted( + CARD32* base, CARD32* src, + int offset, int width, int dwords +){ + CARD32* srcp; + CARD32 bits; + int bitsleft, shift, usable; + + while(dwords--) { + bitsleft = width - offset; + srcp = src + (offset >> 5); + shift = offset & 31; + usable = 32 - shift; + + if(bitsleft < 32) { + if(bitsleft <= usable) { + bits = SHIFT_L(*src,bitsleft) | + (SHIFT_R(*srcp,shift) & XAAShiftMasks[bitsleft]); + } else { + bits = SHIFT_L(*src,bitsleft) | + (SHIFT_L(srcp[1],usable) & XAAShiftMasks[bitsleft]) | + (SHIFT_R(*srcp,shift) & XAAShiftMasks[usable]); + } + } + else if(shift) + bits = SHIFT_R(*srcp,shift) | SHIFT_L(srcp[1],usable); + else + bits = *srcp; + + bits = ~bits; + +#ifdef TRIPLE_BITS + if(dwords >= 2) { + WRITE_BITS3(bits); + dwords -= 2; + } else if(dwords > 0) { + WRITE_BITS2(bits); + dwords--; + } else { + WRITE_BITS1(bits); + } +#else + WRITE_BITS(bits); +#endif + + offset += 32; + offset %= width; + } + return base; +} |