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 11static CARD32* StipplePowerOfTwo(CARD32*, CARD32*, int, int, int); 12static CARD32* StipplePowerOfTwo_Inverted(CARD32*, CARD32*, int, int, int); 13static CARD32* StippleUpTo32(CARD32*, CARD32*, int, int, int); 14static CARD32* StippleUpTo32_Inverted(CARD32*, CARD32*, int, int, int); 15static CARD32* StippleOver32(CARD32*, CARD32*, int, int, int); 16static 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 26StippleScanlineProcPtr stipple_scanline_func[6] = { 27 StipplePowerOfTwo, 28 StippleUpTo32, 29 StippleOver32, 30 StipplePowerOfTwo_Inverted, 31 StippleUpTo32_Inverted, 32 StippleOver32_Inverted 33}; 34 35StippleScanlineProcPtr *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 86unsigned 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 108void 109#ifdef TRIPLE_BITS 110EXPNAME(XAAFillColorExpandRects3)( 111#else 112EXPNAME(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 174SECOND_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 244void 245#ifdef TRIPLE_BITS 246EXPNAME(XAAFillColorExpandSpans3)( 247#else 248EXPNAME(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 317SECOND_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 355void 356#ifdef TRIPLE_BITS 357EXPNAME(XAAFillScanlineColorExpandRects3)( 358#else 359EXPNAME(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 420SECOND_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 468void 469#ifdef TRIPLE_BITS 470EXPNAME(XAAFillScanlineColorExpandSpans3)( 471#else 472EXPNAME(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 542SECOND_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 572static CARD32 * 573StipplePowerOfTwo( 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 631static CARD32 * 632StipplePowerOfTwo_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 693static CARD32 * 694StippleUpTo32( 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 729static CARD32 * 730StippleUpTo32_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 765static CARD32 * 766StippleOver32( 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 816static CARD32 * 817StippleOver32_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