Home | History | Annotate | Line # | Download | only in xaa
      1 
      2 #ifdef HAVE_XORG_CONFIG_H
      3 #include <xorg-config.h>
      4 #endif
      5 
      6 #include "xaa.h"
      7 #include "xaalocal.h"
      8 #include "xaacexp.h"
      9 #include "xf86.h"
     10 
     11 static CARD32* StipplePowerOfTwo(CARD32*, CARD32*, int, int, int);
     12 static CARD32* StipplePowerOfTwo_Inverted(CARD32*, CARD32*, int, int, int);
     13 static CARD32* StippleUpTo32(CARD32*, CARD32*, int, int, int);
     14 static CARD32* StippleUpTo32_Inverted(CARD32*, CARD32*, int, int, int);
     15 static CARD32* StippleOver32(CARD32*, CARD32*, int, int, int);
     16 static CARD32* StippleOver32_Inverted(CARD32*, CARD32*, int, int, int);
     17 
     18 #ifdef TRIPLE_BITS
     19 #define stipple_scanline_func EXPNAME(XAAStippleScanlineFunc3)
     20 #define stipple_get_scanline_func EXPNAME(XAAGetStippleScanlineFunc3)
     21 #else
     22 #define stipple_scanline_func EXPNAME(XAAStippleScanlineFunc)
     23 #define stipple_get_scanline_func EXPNAME(XAAGetStippleScanlineFunc)
     24 #endif
     25 
     26 StippleScanlineProcPtr stipple_scanline_func[6] = {
     27    StipplePowerOfTwo,
     28    StippleUpTo32,
     29    StippleOver32,
     30    StipplePowerOfTwo_Inverted,
     31    StippleUpTo32_Inverted,
     32    StippleOver32_Inverted
     33 };
     34 
     35 StippleScanlineProcPtr *stipple_get_scanline_func(void) {
     36    return stipple_scanline_func;
     37 }
     38 
     39 #ifdef FIXEDBASE
     40 # define DEST(i)	*dest
     41 # define RETURN(i)	return(dest)
     42 #else
     43 # define DEST(i)	dest[i]
     44 # define RETURN(i)	return(dest + i)
     45 #endif
     46 
     47 
     48 /* TRIPLE_BITS pattern expansion */
     49 #ifdef TRIPLE_BITS
     50 #define EXPAND_PAT \
     51 	CARD32 pat1 = byte_expand3[pat & 0xFF], \
     52 	       pat2 = byte_expand3[(pat & 0xFF00) >> 8], \
     53 	       pat3 = byte_expand3[(pat & 0xFF0000) >> 16], \
     54 	       pat4 = byte_expand3[(pat & 0xFF000000) >> 24], \
     55 	       patA = pat1 | (pat2 << 24), \
     56 	       patB = (pat2 >> 8) | (pat3 << 16), \
     57 	       patC = (pat3 >> 16) | (pat4 << 8)
     58 #ifdef FIXED_BASE
     59 #define WRITE_PAT1 { \
     60 	*dest = patA; }
     61 #define WRITE_PAT2 { \
     62 	*dest = patA; \
     63 	*dest = patB; }
     64 #define WRITE_PAT3 { \
     65 	*dest = patA; \
     66 	*dest = patB; \
     67 	*dest = patC; }
     68 #else
     69 #define WRITE_PAT1 { \
     70 	*(dest++) = patA; }
     71 #define WRITE_PAT2 { \
     72 	*(dest) = patA; \
     73 	*(dest + 1) = patB; \
     74 	dest += 2; }
     75 #define WRITE_PAT3 { \
     76 	*(dest) = patA; \
     77 	*(dest + 1) = patB; \
     78 	*(dest + 2) = patC; \
     79 	dest += 3; }
     80 #endif
     81 #endif
     82 
     83 
     84 #if !defined(FIXEDBASE) && !defined(MSBFIRST) && !defined(TRIPLE_BITS)
     85 
     86 unsigned int XAAShiftMasks[32] = {
     87   /* gcc is rather pedantic about SHIFT_R(0xFFFFFFFF,32) */
     88           0x00000000    , SHIFT_R(0xFFFFFFFF,31),
     89   SHIFT_R(0xFFFFFFFF,30), SHIFT_R(0xFFFFFFFF,29),
     90   SHIFT_R(0xFFFFFFFF,28), SHIFT_R(0xFFFFFFFF,27),
     91   SHIFT_R(0xFFFFFFFF,26), SHIFT_R(0xFFFFFFFF,25),
     92   SHIFT_R(0xFFFFFFFF,24), SHIFT_R(0xFFFFFFFF,23),
     93   SHIFT_R(0xFFFFFFFF,22), SHIFT_R(0xFFFFFFFF,21),
     94   SHIFT_R(0xFFFFFFFF,20), SHIFT_R(0xFFFFFFFF,19),
     95   SHIFT_R(0xFFFFFFFF,18), SHIFT_R(0xFFFFFFFF,17),
     96   SHIFT_R(0xFFFFFFFF,16), SHIFT_R(0xFFFFFFFF,15),
     97   SHIFT_R(0xFFFFFFFF,14), SHIFT_R(0xFFFFFFFF,13),
     98   SHIFT_R(0xFFFFFFFF,12), SHIFT_R(0xFFFFFFFF,11),
     99   SHIFT_R(0xFFFFFFFF,10), SHIFT_R(0xFFFFFFFF,9),
    100   SHIFT_R(0xFFFFFFFF,8),  SHIFT_R(0xFFFFFFFF,7),
    101   SHIFT_R(0xFFFFFFFF,6),  SHIFT_R(0xFFFFFFFF,5),
    102   SHIFT_R(0xFFFFFFFF,4),  SHIFT_R(0xFFFFFFFF,3),
    103   SHIFT_R(0xFFFFFFFF,2),  SHIFT_R(0xFFFFFFFF,1)
    104 };
    105 
    106 #endif
    107 
    108 void
    109 #ifdef TRIPLE_BITS
    110 EXPNAME(XAAFillColorExpandRects3)(
    111 #else
    112 EXPNAME(XAAFillColorExpandRects)(
    113 #endif
    114    ScrnInfoPtr pScrn,
    115    int fg, int bg, int rop,
    116    unsigned int planemask,
    117    int nBox,
    118    BoxPtr pBox,
    119    int xorg, int yorg,
    120    PixmapPtr pPix
    121 ){
    122     XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
    123     CARD32 *base;
    124     Bool TwoPass = FALSE, FirstPass = TRUE;
    125     StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc;
    126     int stipplewidth = pPix->drawable.width;
    127     int stippleheight = pPix->drawable.height;
    128     int srcwidth = pPix->devKind;
    129     int dwords, srcy, srcx, funcNo = 2, h;
    130     unsigned char *src = (unsigned char*)pPix->devPrivate.ptr;
    131     unsigned char *srcp;
    132     int flag;
    133 
    134     if(stipplewidth <= 32) {
    135 	if(stipplewidth & (stipplewidth - 1))
    136 	  funcNo = 1;
    137 	else
    138 	  funcNo = 0;
    139     }
    140     StippleFunc = stipple_scanline_func[funcNo];
    141     SecondFunc = stipple_scanline_func[funcNo];
    142     FirstFunc = stipple_scanline_func[funcNo + 3];
    143 
    144 #ifdef TRIPLE_BITS
    145     if((bg == -1) ||
    146 	(!(infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) &&
    147 	(!(infoRec->CPUToScreenColorExpandFillFlags & RGB_EQUAL) ||
    148 	(CHECK_RGB_EQUAL(bg))))) {
    149 #else
    150     if((bg == -1) ||
    151 	!(infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
    152 #endif
    153 	/* one pass */
    154     } else if((rop == GXcopy) && infoRec->FillSolidRects) {
    155 	/* one pass but we fill background rects first */
    156 	(*infoRec->FillSolidRects)(pScrn, bg, rop, planemask, nBox, pBox);
    157 	bg = -1;
    158     } else {
    159 	/* gotta do two passes */
    160 	TwoPass = TRUE;
    161     }
    162 
    163     if(!TwoPass)
    164 	(*infoRec->SetupForCPUToScreenColorExpandFill)(
    165 					pScrn, fg, bg, rop, planemask);
    166 
    167     while(nBox--) {
    168 #ifdef TRIPLE_BITS
    169 	dwords = (3 * (pBox->x2 - pBox->x1) + 31) >> 5;
    170 #else
    171 	dwords = (pBox->x2 - pBox->x1 + 31) >> 5;
    172 #endif
    173 
    174 SECOND_PASS:
    175 	if(TwoPass) {
    176 	    (*infoRec->SetupForCPUToScreenColorExpandFill)(pScrn,
    177 			(FirstPass) ? bg : fg, -1, rop, planemask);
    178 	    StippleFunc = (FirstPass) ? FirstFunc : SecondFunc;
    179 	}
    180 
    181 	h = pBox->y2 - pBox->y1;
    182 	flag = (infoRec->CPUToScreenColorExpandFillFlags
    183 		& CPU_TRANSFER_PAD_QWORD) && ((dwords * h) & 0x01);
    184 
    185         (*infoRec->SubsequentCPUToScreenColorExpandFill)(
    186 			pScrn, pBox->x1, pBox->y1,
    187  			pBox->x2 - pBox->x1, h, 0);
    188 
    189 	base = (CARD32*)infoRec->ColorExpandBase;
    190 
    191 	srcy = (pBox->y1 - yorg) % stippleheight;
    192 	if(srcy < 0) srcy += stippleheight;
    193 	srcx = (pBox->x1 - xorg) % stipplewidth;
    194 	if(srcx < 0) srcx += stipplewidth;
    195 
    196 	srcp = (srcwidth * srcy) + src;
    197 
    198 #ifndef FIXEDBASE
    199 	if((dwords * h) <= infoRec->ColorExpandRange) {
    200 	   while(h--) {
    201 		base = (*StippleFunc)(
    202 			base, (CARD32*)srcp, srcx, stipplewidth, dwords);
    203 		srcy++;
    204 		srcp += srcwidth;
    205 		if (srcy >= stippleheight) {
    206 		   srcy = 0;
    207 		   srcp = src;
    208 		}
    209 	   }
    210 	} else
    211 #endif
    212 	   while(h--) {
    213 		(*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords);
    214 		srcy++;
    215 		srcp += srcwidth;
    216 		if (srcy >= stippleheight) {
    217 		   srcy = 0;
    218 		   srcp = src;
    219 		}
    220 	   }
    221 
    222 	  if (flag) {
    223 	      base = (CARD32*)infoRec->ColorExpandBase;
    224 	      base[0] = 0x00000000;
    225 	  }
    226 
    227 	if(TwoPass) {
    228 	   if(FirstPass) {
    229 		FirstPass = FALSE;
    230 		goto SECOND_PASS;
    231 	   } else FirstPass = TRUE;
    232 	}
    233 
    234 	pBox++;
    235      }
    236 
    237     if(infoRec->CPUToScreenColorExpandFillFlags & SYNC_AFTER_COLOR_EXPAND)
    238 	(*infoRec->Sync)(pScrn);
    239     else SET_SYNC_FLAG(infoRec);
    240 }
    241 
    242 
    243 
    244 void
    245 #ifdef TRIPLE_BITS
    246 EXPNAME(XAAFillColorExpandSpans3)(
    247 #else
    248 EXPNAME(XAAFillColorExpandSpans)(
    249 #endif
    250    ScrnInfoPtr pScrn,
    251    int fg, int bg, int rop,
    252    unsigned int planemask,
    253    int n,
    254    DDXPointPtr ppt,
    255    int *pwidth,
    256    int fSorted,
    257    int xorg, int yorg,
    258    PixmapPtr pPix
    259 ){
    260     XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
    261     CARD32 *base;
    262     Bool TwoPass = FALSE, FirstPass = TRUE;
    263     StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc;
    264     int stipplewidth = pPix->drawable.width;
    265     int stippleheight = pPix->drawable.height;
    266     int dwords, srcy, srcx, funcNo = 2;
    267     unsigned char *srcp;
    268 
    269     if(stipplewidth <= 32) {
    270 	if(stipplewidth & (stipplewidth - 1))
    271 	  funcNo = 1;
    272 	else
    273 	  funcNo = 0;
    274     }
    275     StippleFunc = stipple_scanline_func[funcNo];
    276     SecondFunc = stipple_scanline_func[funcNo];
    277     FirstFunc = stipple_scanline_func[funcNo + 3];
    278 
    279 #ifdef TRIPLE_BITS
    280     if((bg == -1) ||
    281 	(!(infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) &&
    282 	(!(infoRec->CPUToScreenColorExpandFillFlags & RGB_EQUAL) ||
    283 	(CHECK_RGB_EQUAL(bg))))) {
    284 #else
    285     if((bg == -1) ||
    286 	!(infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
    287 #endif
    288 	/* one pass */
    289     } else if((rop == GXcopy) && infoRec->FillSolidSpans) {
    290 	/* one pass but we fill background rects first */
    291 	(*infoRec->FillSolidSpans)(
    292 		pScrn, bg, rop, planemask, n, ppt, pwidth, fSorted);
    293 	bg = -1;
    294     } else {
    295 	/* gotta do two passes */
    296 	TwoPass = TRUE;
    297     }
    298 
    299     if(!TwoPass)
    300 	(*infoRec->SetupForCPUToScreenColorExpandFill)(
    301 				pScrn, fg, bg, rop, planemask);
    302 
    303     while(n--) {
    304 #ifdef TRIPLE_BITS
    305 	dwords = (3 * *pwidth + 31) >> 5;
    306 #else
    307 	dwords = (*pwidth + 31) >> 5;
    308 #endif
    309 
    310 	srcy = (ppt->y - yorg) % stippleheight;
    311 	if(srcy < 0) srcy += stippleheight;
    312 	srcx = (ppt->x - xorg) % stipplewidth;
    313 	if(srcx < 0) srcx += stipplewidth;
    314 
    315 	srcp = (pPix->devKind * srcy) + (unsigned char*)pPix->devPrivate.ptr;
    316 
    317 SECOND_PASS:
    318 	if(TwoPass) {
    319 	    (*infoRec->SetupForCPUToScreenColorExpandFill)(pScrn,
    320 			(FirstPass) ? bg : fg, -1, rop, planemask);
    321 	    StippleFunc = (FirstPass) ? FirstFunc : SecondFunc;
    322 	}
    323 
    324         (*infoRec->SubsequentCPUToScreenColorExpandFill)(pScrn, ppt->x, ppt->y,
    325  			*pwidth, 1, 0);
    326 
    327 	base = (CARD32*)infoRec->ColorExpandBase;
    328 
    329 	(*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords);
    330 
    331 	if((infoRec->CPUToScreenColorExpandFillFlags & CPU_TRANSFER_PAD_QWORD)
    332 			&& (dwords & 0x01)) {
    333 	    base = (CARD32*)infoRec->ColorExpandBase;
    334 	    base[0] = 0x00000000;
    335     	}
    336 
    337 	if(TwoPass) {
    338 	   if(FirstPass) {
    339 		FirstPass = FALSE;
    340 		goto SECOND_PASS;
    341 	   } else FirstPass = TRUE;
    342 	}
    343 
    344 	ppt++; pwidth++;
    345      }
    346 
    347     if(infoRec->CPUToScreenColorExpandFillFlags & SYNC_AFTER_COLOR_EXPAND)
    348 	(*infoRec->Sync)(pScrn);
    349     else SET_SYNC_FLAG(infoRec);
    350 }
    351 
    352 
    353 #ifndef FIXEDBASE
    354 
    355 void
    356 #ifdef TRIPLE_BITS
    357 EXPNAME(XAAFillScanlineColorExpandRects3)(
    358 #else
    359 EXPNAME(XAAFillScanlineColorExpandRects)(
    360 #endif
    361    ScrnInfoPtr pScrn,
    362    int fg, int bg, int rop,
    363    unsigned int planemask,
    364    int nBox,
    365    BoxPtr pBox,
    366    int xorg, int yorg,
    367    PixmapPtr pPix
    368 ){
    369     XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
    370     CARD32 *base;
    371     Bool TwoPass = FALSE, FirstPass = TRUE;
    372     StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc;
    373     int stipplewidth = pPix->drawable.width;
    374     int stippleheight = pPix->drawable.height;
    375     int srcwidth = pPix->devKind;
    376     int dwords, srcy, srcx, funcNo = 2, bufferNo, h;
    377     unsigned char *src = pPix->devPrivate.ptr;
    378     unsigned char *srcp;
    379 
    380     if(stipplewidth <= 32) {
    381 	if(stipplewidth & (stipplewidth - 1))
    382 	  funcNo = 1;
    383 	else
    384 	  funcNo = 0;
    385     }
    386     StippleFunc = stipple_scanline_func[funcNo];
    387     SecondFunc = stipple_scanline_func[funcNo];
    388     FirstFunc = stipple_scanline_func[funcNo + 3];
    389 
    390 #ifdef TRIPLE_BITS
    391     if((bg == -1) ||
    392       (!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) &&
    393       (!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & RGB_EQUAL) ||
    394       (CHECK_RGB_EQUAL(bg))))) {
    395 #else
    396     if((bg == -1) ||
    397       !(infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
    398 #endif
    399 	/* one pass */
    400     } else if((rop == GXcopy) && infoRec->FillSolidRects) {
    401 	/* one pass but we fill background rects first */
    402 	(*infoRec->FillSolidRects)(pScrn, bg, rop, planemask, nBox, pBox);
    403 	bg = -1;
    404     } else {
    405 	/* gotta do two passes */
    406 	TwoPass = TRUE;
    407     }
    408 
    409     if(!TwoPass)
    410 	(*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(
    411 				pScrn, fg, bg, rop, planemask);
    412 
    413     while(nBox--) {
    414 #ifdef TRIPLE_BITS
    415 	dwords = (3 * (pBox->x2 - pBox->x1) + 31) >> 5;
    416 #else
    417 	dwords = (pBox->x2 - pBox->x1 + 31) >> 5;
    418 #endif
    419 
    420 SECOND_PASS:
    421 	if(TwoPass) {
    422 	    (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(pScrn,
    423 			(FirstPass) ? bg : fg, -1, rop, planemask);
    424 	    StippleFunc = (FirstPass) ? FirstFunc : SecondFunc;
    425 	}
    426 
    427 	h = pBox->y2 - pBox->y1;
    428 
    429         (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
    430 		pScrn, pBox->x1, pBox->y1, pBox->x2 - pBox->x1, h, 0);
    431 
    432 	bufferNo = 0;
    433 
    434 	srcy = (pBox->y1 - yorg) % stippleheight;
    435 	if(srcy < 0) srcy += stippleheight;
    436 	srcx = (pBox->x1 - xorg) % stipplewidth;
    437 	if(srcx < 0) srcx += stipplewidth;
    438 
    439 	srcp = (srcwidth * srcy) + src;
    440 
    441 	while(h--) {
    442    	    base = (CARD32*)infoRec->ScanlineColorExpandBuffers[bufferNo];
    443 	    (*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords);
    444 	    (*infoRec->SubsequentColorExpandScanline)(pScrn, bufferNo++);
    445 	    if(bufferNo >= infoRec->NumScanlineColorExpandBuffers)
    446 		bufferNo = 0;
    447 	    srcy++;
    448 	    srcp += srcwidth;
    449 	    if (srcy >= stippleheight) {
    450 		srcy = 0;
    451 		srcp = src;
    452 	    }
    453 	}
    454 
    455 	if(TwoPass) {
    456 	   if(FirstPass) {
    457 		FirstPass = FALSE;
    458 		goto SECOND_PASS;
    459 	   } else FirstPass = TRUE;
    460 	}
    461 
    462 	pBox++;
    463      }
    464 
    465      SET_SYNC_FLAG(infoRec);
    466 }
    467 
    468 void
    469 #ifdef TRIPLE_BITS
    470 EXPNAME(XAAFillScanlineColorExpandSpans3)(
    471 #else
    472 EXPNAME(XAAFillScanlineColorExpandSpans)(
    473 #endif
    474    ScrnInfoPtr pScrn,
    475    int fg, int bg, int rop,
    476    unsigned int planemask,
    477    int n,
    478    DDXPointPtr ppt,
    479    int *pwidth,
    480    int fSorted,
    481    int xorg, int yorg,
    482    PixmapPtr pPix
    483 ){
    484     XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
    485     CARD32 *base;
    486     Bool TwoPass = FALSE, FirstPass = TRUE;
    487     StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc;
    488     int stipplewidth = pPix->drawable.width;
    489     int stippleheight = pPix->drawable.height;
    490     int dwords, srcy, srcx, funcNo = 2;
    491     unsigned char *srcp;
    492 
    493     if(stipplewidth <= 32) {
    494 	if(stipplewidth & (stipplewidth - 1))
    495 	  funcNo = 1;
    496 	else
    497 	  funcNo = 0;
    498     }
    499     StippleFunc = stipple_scanline_func[funcNo];
    500     SecondFunc = stipple_scanline_func[funcNo];
    501     FirstFunc = stipple_scanline_func[funcNo + 3];
    502 
    503 #ifdef TRIPLE_BITS
    504     if((bg == -1) ||
    505       (!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) &&
    506       (!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & RGB_EQUAL) ||
    507       (CHECK_RGB_EQUAL(bg))))) {
    508 #else
    509     if((bg == -1) ||
    510       !(infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
    511 #endif
    512 	/* one pass */
    513     } else if((rop == GXcopy) && infoRec->FillSolidSpans) {
    514 	/* one pass but we fill background rects first */
    515 	(*infoRec->FillSolidSpans)(
    516 		pScrn, bg, rop, planemask, n, ppt, pwidth, fSorted);
    517 	bg = -1;
    518     } else {
    519 	/* gotta do two passes */
    520 	TwoPass = TRUE;
    521     }
    522 
    523     if(!TwoPass)
    524 	(*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(
    525 				pScrn, fg, bg, rop, planemask);
    526 
    527 
    528     while(n--) {
    529 #ifdef TRIPLE_BITS
    530 	dwords = (3 * *pwidth + 31) >> 5;
    531 #else
    532 	dwords = (*pwidth + 31) >> 5;
    533 #endif
    534 
    535 	srcy = (ppt->y - yorg) % stippleheight;
    536 	if(srcy < 0) srcy += stippleheight;
    537 	srcx = (ppt->x - xorg) % stipplewidth;
    538 	if(srcx < 0) srcx += stipplewidth;
    539 
    540 	srcp = (pPix->devKind * srcy) + (unsigned char*)pPix->devPrivate.ptr;
    541 
    542 SECOND_PASS:
    543 	if(TwoPass) {
    544 	    (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(pScrn,
    545 			(FirstPass) ? bg : fg, -1, rop, planemask);
    546 	    StippleFunc = (FirstPass) ? FirstFunc : SecondFunc;
    547 	}
    548 
    549         (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
    550 				pScrn, ppt->x, ppt->y, *pwidth, 1, 0);
    551 
    552 	base = (CARD32*)infoRec->ScanlineColorExpandBuffers[0];
    553 
    554 	(*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords);
    555 	(*infoRec->SubsequentColorExpandScanline)(pScrn, 0);
    556 
    557 	if(TwoPass) {
    558 	   if(FirstPass) {
    559 		FirstPass = FALSE;
    560 		goto SECOND_PASS;
    561 	   } else FirstPass = TRUE;
    562 	}
    563 
    564 	ppt++; pwidth++;
    565      }
    566 
    567      SET_SYNC_FLAG(infoRec);
    568 }
    569 
    570 #endif
    571 
    572 static CARD32 *
    573 StipplePowerOfTwo(
    574    CARD32* dest, CARD32* src,
    575    int shift, int width, int dwords
    576 ){
    577     CARD32 pat = *src;
    578     if(width < 32) {
    579 	pat &= XAAShiftMasks[width];
    580 	while(width < 32) {
    581 	    pat |= SHIFT_L(pat,width);
    582 	    width <<= 1;
    583 	}
    584     }
    585 
    586     if(shift)
    587 	pat = SHIFT_R(pat,shift) | SHIFT_L(pat,32 - shift);
    588 
    589 #ifdef MSBFIRST
    590     pat = SWAP_BITS_IN_BYTES(pat);
    591 #endif
    592 
    593 #ifdef TRIPLE_BITS
    594     {
    595 	EXPAND_PAT;
    596 
    597 	while(dwords >= 3) {
    598 	    WRITE_PAT3;
    599 	    dwords -= 3;
    600 	}
    601 	if (dwords == 2) {
    602 	    WRITE_PAT2;
    603 	} else if (dwords == 1) {
    604 	    WRITE_PAT1;
    605 	}
    606 
    607 	return dest;
    608     }
    609 #else /* TRIPLE_BITS */
    610    while(dwords >= 4) {
    611 	DEST(0) = pat;
    612 	DEST(1) = pat;
    613 	DEST(2) = pat;
    614 	DEST(3) = pat;
    615 	dwords -= 4;
    616 #ifndef FIXEDBASE
    617 	dest += 4;
    618 #endif
    619    }
    620 
    621    if(!dwords) return dest;
    622    DEST(0) = pat;
    623    if(dwords == 1) RETURN(1);
    624    DEST(1) = pat;
    625    if(dwords == 2) RETURN(2);
    626    DEST(2) = pat;
    627    RETURN(3);
    628 #endif /* TRIPLE_BITS */
    629 }
    630 
    631 static CARD32 *
    632 StipplePowerOfTwo_Inverted(
    633    CARD32* dest, CARD32* src,
    634    int shift, int width, int dwords
    635 ){
    636     CARD32 pat = *src;
    637     if(width < 32) {
    638 	pat &= XAAShiftMasks[width];
    639 	while(width < 32) {
    640 	    pat |= SHIFT_L(pat,width);
    641 	    width <<= 1;
    642 	}
    643     }
    644 
    645     if(shift)
    646 	pat = SHIFT_R(pat,shift) | SHIFT_L(pat,32 - shift);
    647 
    648 #ifdef MSBFIRST
    649     pat = SWAP_BITS_IN_BYTES(pat);
    650 #endif
    651 
    652    pat = ~pat;
    653 
    654 #ifdef TRIPLE_BITS
    655     {
    656 	EXPAND_PAT;
    657 
    658 	while(dwords >= 3) {
    659 	    WRITE_PAT3;
    660 	    dwords -= 3;
    661 	}
    662 	if (dwords == 2) {
    663 	    WRITE_PAT2;
    664 	} else if (dwords == 1) {
    665 	    WRITE_PAT1;
    666 	}
    667 
    668 	return dest;
    669     }
    670 #else /* TRIPLE_BITS */
    671    while(dwords >= 4) {
    672 	DEST(0) = pat;
    673 	DEST(1) = pat;
    674 	DEST(2) = pat;
    675 	DEST(3) = pat;
    676 	dwords -= 4;
    677 #ifndef FIXEDBASE
    678 	dest += 4;
    679 #endif
    680    }
    681 
    682    if(!dwords) return dest;
    683    DEST(0) = pat;
    684    if(dwords == 1) RETURN(1);
    685    DEST(1) = pat;
    686    if(dwords == 2) RETURN(2);
    687    DEST(2) = pat;
    688    RETURN(3);
    689 #endif /* TRIPLE_BITS */
    690 }
    691 
    692 
    693 static CARD32 *
    694 StippleUpTo32(
    695    CARD32* base, CARD32* src,
    696    int shift, int width, int dwords
    697 ){
    698     CARD32 pat = *src & XAAShiftMasks[width];
    699 
    700     while(width <= 15) {
    701 	pat |= SHIFT_L(pat,width);
    702 	width <<= 1;
    703     }
    704     pat |= SHIFT_L(pat,width);
    705 
    706     while(dwords--) {
    707 	CARD32 bits = SHIFT_R(pat,shift) | SHIFT_L(pat,width-shift);
    708 #ifdef TRIPLE_BITS
    709 	if(dwords >= 2) {
    710 	    WRITE_BITS3(bits);
    711 	    dwords -= 2;
    712 	} else if(dwords > 0) {
    713 	    WRITE_BITS2(bits);
    714 	    dwords--;
    715 	} else {
    716 	    WRITE_BITS1(bits);
    717 	}
    718 #else
    719 	WRITE_BITS(bits);
    720 #endif
    721 
    722 	shift += 32;
    723 	shift %= width;
    724     }
    725     return base;
    726 }
    727 
    728 
    729 static CARD32 *
    730 StippleUpTo32_Inverted(
    731    CARD32* base, CARD32* src,
    732    int shift, int width, int dwords
    733 ){
    734     CARD32 pat = *src & XAAShiftMasks[width];
    735 
    736     while(width <= 15) {
    737 	pat |= SHIFT_L(pat,width);
    738 	width <<= 1;
    739     }
    740     pat |= SHIFT_L(pat,width);
    741 
    742     while(dwords--) {
    743 	CARD32 bits = ~(SHIFT_R(pat,shift) | SHIFT_L(pat,width-shift));
    744 #ifdef TRIPLE_BITS
    745 	if(dwords >= 2) {
    746 	    WRITE_BITS3(bits);
    747 	    dwords -= 2;
    748 	} else if(dwords > 0) {
    749 	    WRITE_BITS2(bits);
    750 	    dwords--;
    751 	} else {
    752 	    WRITE_BITS1(bits);
    753 	}
    754 #else
    755 	WRITE_BITS(bits);
    756 #endif
    757 
    758 	shift += 32;
    759 	shift %= width;
    760     }
    761     return base;
    762 }
    763 
    764 
    765 static CARD32 *
    766 StippleOver32(
    767    CARD32* base, CARD32* src,
    768    int offset, int width, int dwords
    769 ){
    770    CARD32* srcp;
    771    CARD32 bits;
    772    int bitsleft, shift, usable;
    773 
    774    while(dwords--) {
    775         bitsleft = width - offset;
    776         srcp = src + (offset >> 5);
    777         shift = offset & 31;
    778         usable = 32 - shift;
    779 
    780         if(bitsleft < 32) {
    781             if(bitsleft <= usable) {
    782                  bits = SHIFT_L(*src,bitsleft) |
    783                        (SHIFT_R(*srcp,shift) & XAAShiftMasks[bitsleft]);
    784             } else {
    785                  bits = SHIFT_L(*src,bitsleft) |
    786                        (SHIFT_L(srcp[1],usable) & XAAShiftMasks[bitsleft]) |
    787                        (SHIFT_R(*srcp,shift) & XAAShiftMasks[usable]);
    788             }
    789         }
    790         else if(shift)
    791             bits = SHIFT_R(*srcp,shift) | SHIFT_L(srcp[1],usable);
    792         else
    793             bits = *srcp;
    794 
    795 #ifdef TRIPLE_BITS
    796 	if(dwords >= 2) {
    797 	    WRITE_BITS3(bits);
    798 	    dwords -= 2;
    799 	} else if(dwords > 0) {
    800 	    WRITE_BITS2(bits);
    801 	    dwords--;
    802 	} else {
    803 	    WRITE_BITS1(bits);
    804 	}
    805 #else
    806 	WRITE_BITS(bits);
    807 #endif
    808 
    809 	offset += 32;
    810 	offset %= width;
    811    }
    812    return base;
    813 }
    814 
    815 
    816 static CARD32 *
    817 StippleOver32_Inverted(
    818    CARD32* base, CARD32* src,
    819    int offset, int width, int dwords
    820 ){
    821    CARD32* srcp;
    822    CARD32 bits;
    823    int bitsleft, shift, usable;
    824 
    825    while(dwords--) {
    826         bitsleft = width - offset;
    827         srcp = src + (offset >> 5);
    828         shift = offset & 31;
    829         usable = 32 - shift;
    830 
    831         if(bitsleft < 32) {
    832             if(bitsleft <= usable) {
    833                  bits = SHIFT_L(*src,bitsleft) |
    834                        (SHIFT_R(*srcp,shift) & XAAShiftMasks[bitsleft]);
    835             } else {
    836                  bits = SHIFT_L(*src,bitsleft) |
    837                        (SHIFT_L(srcp[1],usable) & XAAShiftMasks[bitsleft]) |
    838                        (SHIFT_R(*srcp,shift) & XAAShiftMasks[usable]);
    839             }
    840         }
    841         else if(shift)
    842             bits = SHIFT_R(*srcp,shift) | SHIFT_L(srcp[1],usable);
    843         else
    844             bits = *srcp;
    845 
    846 	bits = ~bits;
    847 
    848 #ifdef TRIPLE_BITS
    849 	if(dwords >= 2) {
    850 	    WRITE_BITS3(bits);
    851 	    dwords -= 2;
    852 	} else if(dwords > 0) {
    853 	    WRITE_BITS2(bits);
    854 	    dwords--;
    855 	} else {
    856 	    WRITE_BITS1(bits);
    857 	}
    858 #else
    859 	WRITE_BITS(bits);
    860 #endif
    861 
    862 	offset += 32;
    863 	offset %= width;
    864    }
    865    return base;
    866 }
    867