916 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			916 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			C
		
	
	
	
| 
 | |
| #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;
 | |
| }
 |