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