1 2#ifdef HAVE_XORG_CONFIG_H 3#include <xorg-config.h> 4#endif 5 6#include "misc.h" 7#include "xf86.h" 8#include "xf86_OSproc.h" 9 10#include <X11/X.h> 11#include "scrnintstr.h" 12#include "pixmapstr.h" 13#include "xf86str.h" 14#include "xaa.h" 15#include "xaalocal.h" 16 17 18static void XAARenderSolidRects(GCPtr, int, BoxPtr, int, int); 19static void XAARenderColor8x8Rects(GCPtr, int, BoxPtr, int, int); 20static void XAARenderMono8x8Rects(GCPtr, int, BoxPtr, int, int); 21static void XAARenderColorExpandRects(GCPtr, int, BoxPtr, int, int); 22static void XAARenderCacheExpandRects(GCPtr, int, BoxPtr, int, int); 23static void XAARenderCacheBltRects(GCPtr, int, BoxPtr, int, int); 24static void XAARenderImageWriteRects(GCPtr, int, BoxPtr, int, int); 25static void XAARenderPixmapCopyRects(GCPtr, int, BoxPtr, int, int); 26 27void 28XAAPolyFillRect( 29 DrawablePtr pDraw, 30 GCPtr pGC, 31 int nrectFill, /* number of rectangles to fill */ 32 xRectangle *prectInit /* Pointer to first rectangle to fill */ 33){ 34 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); 35 int xorg = pDraw->x; 36 int yorg = pDraw->y; 37 int type = 0; 38 ClipAndRenderRectsFunc function; 39 40 if((nrectFill <= 0) || !pGC->planemask) 41 return; 42 43 if(!RegionNumRects(pGC->pCompositeClip)) 44 return; 45 46 switch(pGC->fillStyle) { 47 case FillSolid: 48 type = DO_SOLID; 49 break; 50 case FillStippled: 51 type = (*infoRec->StippledFillChooser)(pGC); 52 break; 53 case FillOpaqueStippled: 54 if((pGC->fgPixel == pGC->bgPixel) && infoRec->FillSolidRects && 55 CHECK_PLANEMASK(pGC,infoRec->FillSolidRectsFlags) && 56 CHECK_ROP(pGC,infoRec->FillSolidRectsFlags) && 57 CHECK_ROPSRC(pGC,infoRec->FillSolidRectsFlags) && 58 CHECK_FG(pGC,infoRec->FillSolidRectsFlags)) 59 type = DO_SOLID; 60 else 61 type = (*infoRec->OpaqueStippledFillChooser)(pGC); 62 break; 63 case FillTiled: 64 type = (*infoRec->TiledFillChooser)(pGC); 65 break; 66 } 67 68 switch(type) { 69 case DO_SOLID: 70 function = XAARenderSolidRects; 71 break; 72 case DO_COLOR_8x8: 73 function = XAARenderColor8x8Rects; 74 break; 75 case DO_MONO_8x8: 76 function = XAARenderMono8x8Rects; 77 break; 78 case DO_CACHE_BLT: 79 function = XAARenderCacheBltRects; 80 break; 81 case DO_COLOR_EXPAND: 82 function = XAARenderColorExpandRects; 83 break; 84 case DO_CACHE_EXPAND: 85 function = XAARenderCacheExpandRects; 86 break; 87 case DO_IMAGE_WRITE: 88 function = XAARenderImageWriteRects; 89 break; 90 case DO_PIXMAP_COPY: 91 function = XAARenderPixmapCopyRects; 92 break; 93 default: 94 (*XAAFallbackOps.PolyFillRect)(pDraw, pGC, nrectFill, prectInit); 95 return; 96 } 97 98 if(xorg | yorg) { 99 int n = nrectFill; 100 xRectangle *prect = prectInit; 101 102 while(n--) { 103 prect->x += xorg; 104 prect->y += yorg; 105 prect++; 106 } 107 } 108 109 110 XAAClipAndRenderRects(pGC, function, nrectFill, prectInit, xorg, yorg); 111} 112 113 114 115 /*********************\ 116 | Solid Rects | 117 \*********************/ 118 119static void 120XAARenderSolidRects( 121 GCPtr pGC, 122 int nboxes, 123 BoxPtr pClipBoxes, 124 int xorg, int yorg 125){ 126 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); 127 128 (*infoRec->FillSolidRects) (infoRec->pScrn, 129 pGC->fgPixel, pGC->alu, pGC->planemask, nboxes, pClipBoxes); 130} 131 132 133 /************************\ 134 | Mono 8x8 Rects | 135 \************************/ 136 137static void 138XAARenderMono8x8Rects( 139 GCPtr pGC, 140 int nboxes, 141 BoxPtr pClipBoxes, 142 int xorg, int yorg 143){ 144 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); 145 XAAPixmapPtr pPriv; 146 int fg, bg; 147 148 switch(pGC->fillStyle) { 149 case FillStippled: 150 pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->stipple); 151 fg = pGC->fgPixel; bg = -1; 152 break; 153 case FillOpaqueStippled: 154 pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->stipple); 155 fg = pGC->fgPixel; bg = pGC->bgPixel; 156 break; 157 case FillTiled: 158 pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap); 159 fg = pPriv->fg; bg = pPriv->bg; 160 break; 161 default: /* Muffle compiler */ 162 pPriv = NULL; /* Kaboom */ 163 fg = -1; bg = -1; 164 break; 165 } 166 167 (*infoRec->FillMono8x8PatternRects) (infoRec->pScrn, 168 fg, bg, pGC->alu, pGC->planemask, 169 nboxes, pClipBoxes, pPriv->pattern0, pPriv->pattern1, 170 (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y)); 171} 172 173 /*************************\ 174 | Color 8x8 Rects | 175 \*************************/ 176 177static void 178XAARenderColor8x8Rects( 179 GCPtr pGC, 180 int nboxes, 181 BoxPtr pClipBoxes, 182 int xorg, int yorg 183){ 184 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); 185 XAACacheInfoPtr pCache; 186 PixmapPtr pPix; 187 int fg, bg; 188 189 switch(pGC->fillStyle) { 190 case FillStippled: 191 pPix = pGC->stipple; 192 fg = pGC->fgPixel; bg = -1; 193 break; 194 case FillOpaqueStippled: 195 pPix = pGC->stipple; 196 fg = pGC->fgPixel; bg = pGC->bgPixel; 197 break; 198 case FillTiled: 199 pPix = pGC->tile.pixmap; 200 fg = -1; bg = -1; 201 break; 202 default: /* Muffle compiler */ 203 pPix = NULL; 204 fg = -1; bg = -1; 205 break; 206 } 207 208 pCache = (*infoRec->CacheColor8x8Pattern)(infoRec->pScrn, pPix, fg, bg); 209 (*infoRec->FillColor8x8PatternRects) (infoRec->pScrn, 210 pGC->alu, pGC->planemask, nboxes, pClipBoxes, 211 (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y), pCache); 212} 213 214 215 /****************************\ 216 | Color Expand Rects | 217 \****************************/ 218 219static void 220XAARenderColorExpandRects( 221 GCPtr pGC, 222 int nboxes, 223 BoxPtr pClipBoxes, 224 int xorg, int yorg 225){ 226 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); 227 int fg, bg; 228 229 switch(pGC->fillStyle) { 230 case FillStippled: 231 fg = pGC->fgPixel; bg = -1; 232 break; 233 case FillOpaqueStippled: 234 fg = pGC->fgPixel; bg = pGC->bgPixel; 235 break; 236 default: /* Muffle compiler */ 237 fg = -1; bg = -1; 238 break; 239 } 240 241 (*infoRec->FillColorExpandRects) (infoRec->pScrn, fg, bg, 242 pGC->alu, pGC->planemask, nboxes, pClipBoxes, 243 (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y), 244 pGC->stipple); 245} 246 247 248 /*************************\ 249 | Cache Blt Rects | 250 \*************************/ 251 252static void 253XAARenderCacheBltRects( 254 GCPtr pGC, 255 int nboxes, 256 BoxPtr pClipBoxes, 257 int xorg, int yorg 258){ 259 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); 260 XAACacheInfoPtr pCache; 261 262 switch(pGC->fillStyle) { 263 case FillStippled: 264 pCache = (*infoRec->CacheStipple)(infoRec->pScrn, pGC->stipple, 265 pGC->fgPixel, -1); 266 break; 267 case FillOpaqueStippled: 268 pCache = (*infoRec->CacheStipple)(infoRec->pScrn, pGC->stipple, 269 pGC->fgPixel, pGC->bgPixel); 270 break; 271 case FillTiled: 272 pCache = (*infoRec->CacheTile)(infoRec->pScrn, pGC->tile.pixmap); 273 break; 274 default: /* Muffle compiler */ 275 pCache = NULL; 276 break; 277 } 278 279 (*infoRec->FillCacheBltRects) (infoRec->pScrn, pGC->alu, 280 pGC->planemask, nboxes, pClipBoxes, 281 (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y), pCache); 282} 283 284 285 /****************************\ 286 | Cache Expand Rects | 287 \****************************/ 288 289static void 290XAARenderCacheExpandRects( 291 GCPtr pGC, 292 int nboxes, 293 BoxPtr pClipBoxes, 294 int xorg, int yorg 295){ 296 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); 297 int fg, bg; 298 299 switch(pGC->fillStyle) { 300 case FillStippled: 301 fg = pGC->fgPixel; bg = -1; 302 break; 303 case FillOpaqueStippled: 304 fg = pGC->fgPixel; bg = pGC->bgPixel; 305 break; 306 default: /* Muffle compiler */ 307 fg = -1; bg = -1; 308 break; 309 } 310 311 (*infoRec->FillCacheExpandRects) (infoRec->pScrn, fg, bg, 312 pGC->alu, pGC->planemask, nboxes, pClipBoxes, 313 (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y), 314 pGC->stipple); 315} 316 317 318 319 /***************************\ 320 | Image Write Rects | 321 \***************************/ 322 323static void 324XAARenderImageWriteRects( 325 GCPtr pGC, 326 int nboxes, 327 BoxPtr pClipBoxes, 328 int xorg, int yorg 329){ 330 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); 331 332 (*infoRec->FillImageWriteRects) (infoRec->pScrn, pGC->alu, 333 pGC->planemask, nboxes, pClipBoxes, 334 (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y), 335 pGC->tile.pixmap); 336} 337 338 339 340 /***************************\ 341 | Pixmap Copy Rects | 342 \***************************/ 343 344static void 345XAARenderPixmapCopyRects( 346 GCPtr pGC, 347 int nboxes, 348 BoxPtr pClipBoxes, 349 int xorg, int yorg 350){ 351 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); 352 XAACacheInfoPtr pCache = &(infoRec->ScratchCacheInfoRec); 353 XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap); 354 355 pCache->x = pPriv->offscreenArea->box.x1; 356 pCache->y = pPriv->offscreenArea->box.y1; 357 pCache->w = pCache->orig_w = 358 pPriv->offscreenArea->box.x2 - pCache->x; 359 pCache->h = pCache->orig_h = 360 pPriv->offscreenArea->box.y2 - pCache->y; 361 pCache->trans_color = -1; 362 363 (*infoRec->FillCacheBltRects) (infoRec->pScrn, pGC->alu, 364 pGC->planemask, nboxes, pClipBoxes, 365 (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y), 366 pCache); 367} 368 369 370 371 /************\ 372 | Solid | 373 \************/ 374 375void 376XAAFillSolidRects( 377 ScrnInfoPtr pScrn, 378 int fg, int rop, 379 unsigned int planemask, 380 int nBox, /* number of rectangles to fill */ 381 BoxPtr pBox /* Pointer to first rectangle to fill */ 382){ 383 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 384 385 (*infoRec->SetupForSolidFill)(pScrn, fg, rop, planemask); 386 while(nBox--) { 387 (*infoRec->SubsequentSolidFillRect)(pScrn, pBox->x1, pBox->y1, 388 pBox->x2 - pBox->x1, pBox->y2 - pBox->y1); 389 pBox++; 390 } 391 SET_SYNC_FLAG(infoRec); 392} 393 394 395 396 397 /*********************\ 398 | 8x8 Mono Patterns | 399 \*********************/ 400 401 402void 403XAAFillMono8x8PatternRectsScreenOrigin( 404 ScrnInfoPtr pScrn, 405 int fg, int bg, int rop, 406 unsigned int planemask, 407 int nBox, 408 BoxPtr pBox, 409 int pattern0, int pattern1, 410 int xorigin, int yorigin 411) 412{ 413 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 414 int patx = pattern0, paty = pattern1; 415 int xorg = (-xorigin) & 0x07; 416 int yorg = (-yorigin) & 0x07; 417 418 419 if(infoRec->Mono8x8PatternFillFlags & HARDWARE_PATTERN_PROGRAMMED_BITS) { 420 if(!(infoRec->Mono8x8PatternFillFlags & 421 HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){ 422 XAARotateMonoPattern(&patx, &paty, xorg, yorg, 423 (infoRec->Mono8x8PatternFillFlags & 424 BIT_ORDER_IN_BYTE_MSBFIRST)); 425 xorg = patx; yorg = paty; 426 } 427 } else { 428 XAACacheInfoPtr pCache = 429 (*infoRec->CacheMono8x8Pattern)(pScrn, pattern0, pattern1); 430 patx = pCache->x; paty = pCache->y; 431 if(!(infoRec->Mono8x8PatternFillFlags & 432 HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){ 433 int slot = (yorg << 3) + xorg; 434 patx += pCache->offsets[slot].x; 435 paty += pCache->offsets[slot].y; 436 xorg = patx; yorg = paty; 437 } 438 } 439 440 (*infoRec->SetupForMono8x8PatternFill)(pScrn, patx, paty, 441 fg, bg, rop, planemask); 442 443 while(nBox--) { 444 (*infoRec->SubsequentMono8x8PatternFillRect)(pScrn, 445 xorg, yorg, pBox->x1, pBox->y1, 446 pBox->x2 - pBox->x1, pBox->y2 - pBox->y1); 447 pBox++; 448 } 449 SET_SYNC_FLAG(infoRec); 450} 451 452void 453XAAFillMono8x8PatternRects( 454 ScrnInfoPtr pScrn, 455 int fg, int bg, int rop, 456 unsigned int planemask, 457 int nBox, 458 BoxPtr pBox, 459 int pattern0, int pattern1, 460 int xorigin, int yorigin 461) 462{ 463 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 464 int patx = pattern0, paty = pattern1; 465 int xorg, yorg; 466 XAACacheInfoPtr pCache = NULL; 467 468 469 if(!(infoRec->Mono8x8PatternFillFlags & HARDWARE_PATTERN_PROGRAMMED_BITS)){ 470 pCache = (*infoRec->CacheMono8x8Pattern)(pScrn, pattern0, pattern1); 471 patx = pCache->x; paty = pCache->y; 472 } 473 474 475 (*infoRec->SetupForMono8x8PatternFill)(pScrn, patx, paty, 476 fg, bg, rop, planemask); 477 478 479 while(nBox--) { 480 xorg = (pBox->x1 - xorigin) & 0x07; 481 yorg = (pBox->y1 - yorigin) & 0x07; 482 483 if(!(infoRec->Mono8x8PatternFillFlags & 484 HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){ 485 if(infoRec->Mono8x8PatternFillFlags & 486 HARDWARE_PATTERN_PROGRAMMED_BITS) { 487 patx = pattern0; paty = pattern1; 488 XAARotateMonoPattern(&patx, &paty, xorg, yorg, 489 (infoRec->Mono8x8PatternFillFlags & 490 BIT_ORDER_IN_BYTE_MSBFIRST)); 491 xorg = patx; yorg = paty; 492 } else { 493 int slot = (yorg << 3) + xorg; 494 xorg = patx + pCache->offsets[slot].x; 495 yorg = paty + pCache->offsets[slot].y; 496 } 497 } 498 499 (*infoRec->SubsequentMono8x8PatternFillRect)(pScrn, 500 xorg, yorg, pBox->x1, pBox->y1, 501 pBox->x2 - pBox->x1, pBox->y2 - pBox->y1); 502 pBox++; 503 } 504 505 SET_SYNC_FLAG(infoRec); 506} 507 508 509 /**********************\ 510 | 8x8 Color Patterns | 511 \**********************/ 512 513 514void 515XAAFillColor8x8PatternRectsScreenOrigin( 516 ScrnInfoPtr pScrn, 517 int rop, 518 unsigned int planemask, 519 int nBox, 520 BoxPtr pBox, 521 int xorigin, int yorigin, 522 XAACacheInfoPtr pCache 523){ 524 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 525 int patx = pCache->x, paty = pCache->y; 526 int xorg = (-xorigin) & 0x07; 527 int yorg = (-yorigin) & 0x07; 528 529 if(!(infoRec->Color8x8PatternFillFlags & 530 HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){ 531 int slot = (yorg << 3) + xorg; 532 paty += pCache->offsets[slot].y; 533 patx += pCache->offsets[slot].x; 534 xorg = patx; yorg = paty; 535 } 536 537 (*infoRec->SetupForColor8x8PatternFill)(pScrn, patx, paty, 538 rop, planemask, pCache->trans_color); 539 540 while(nBox--) { 541 (*infoRec->SubsequentColor8x8PatternFillRect)(pScrn, 542 xorg, yorg, pBox->x1, pBox->y1, 543 pBox->x2 - pBox->x1, pBox->y2 - pBox->y1); 544 pBox++; 545 } 546 SET_SYNC_FLAG(infoRec); 547} 548 549void 550XAAFillColor8x8PatternRects( 551 ScrnInfoPtr pScrn, 552 int rop, 553 unsigned int planemask, 554 int nBox, 555 BoxPtr pBox, 556 int xorigin, int yorigin, 557 XAACacheInfoPtr pCache 558){ 559 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 560 int xorg, yorg; 561 562 (*infoRec->SetupForColor8x8PatternFill)(pScrn, pCache->x, pCache->y, 563 rop, planemask, pCache->trans_color); 564 565 while(nBox--) { 566 xorg = (pBox->x1 - xorigin) & 0x07; 567 yorg = (pBox->y1 - yorigin) & 0x07; 568 569 if(!(infoRec->Color8x8PatternFillFlags & 570 HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){ 571 int slot = (yorg << 3) + xorg; 572 yorg = pCache->y + pCache->offsets[slot].y; 573 xorg = pCache->x + pCache->offsets[slot].x; 574 } 575 576 (*infoRec->SubsequentColor8x8PatternFillRect)(pScrn, 577 xorg, yorg, pBox->x1, pBox->y1, 578 pBox->x2 - pBox->x1, pBox->y2 - pBox->y1); 579 pBox++; 580 } 581 582 SET_SYNC_FLAG(infoRec); 583} 584 585 586 /***************\ 587 | Cache Blits | 588 \***************/ 589 590void 591XAAFillCacheBltRects( 592 ScrnInfoPtr pScrn, 593 int rop, 594 unsigned int planemask, 595 int nBox, 596 BoxPtr pBox, 597 int xorg, int yorg, 598 XAACacheInfoPtr pCache 599){ 600 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 601 int x, y, phaseY, phaseX, skipleft, height, width, w, blit_w, blit_h; 602 603 (*infoRec->SetupForScreenToScreenCopy)(pScrn, 1, 1, rop, planemask, 604 pCache->trans_color); 605 606 while(nBox--) { 607 y = pBox->y1; 608 phaseY = (y - yorg) % pCache->orig_h; 609 if(phaseY < 0) phaseY += pCache->orig_h; 610 phaseX = (pBox->x1 - xorg) % pCache->orig_w; 611 if(phaseX < 0) phaseX += pCache->orig_w; 612 height = pBox->y2 - y; 613 width = pBox->x2 - pBox->x1; 614 615#if 0 616 if (rop == GXcopy) { 617 while(1) { 618 w = width; skipleft = phaseX; x = pBox->x1; 619 blit_h = pCache->h - phaseY; 620 if(blit_h > height) blit_h = height; 621 622 while(1) { 623 blit_w = pCache->w - skipleft; 624 if(blit_w > w) blit_w = w; 625 (*infoRec->SubsequentScreenToScreenCopy)(pScrn, 626 pCache->x + skipleft, pCache->y + phaseY, 627 x, y, blit_w, blit_h); 628 w -= blit_w; 629 if(!w) break; 630 x += blit_w; 631 skipleft = (skipleft + blit_w) % pCache->orig_w; 632 if(blit_w >= pCache->orig_w) break; 633 } 634 635 /* Expand horizontally */ 636 if (w) { 637 skipleft -= phaseX; 638 if (skipleft < 0) skipleft += pCache->orig_w; 639 blit_w = x - pBox->x1 - skipleft; 640 while(w) { 641 if (blit_w > w) blit_w = w; 642 (*infoRec->SubsequentScreenToScreenCopy)(pScrn, 643 pBox->x1 + skipleft, y, x, y, blit_w, blit_h); 644 w -= blit_w; 645 x += blit_w; 646 blit_w <<= 1; 647 } 648 } 649 650 height -= blit_h; 651 if(!height) break; 652 y += blit_h; 653 phaseY = (phaseY + blit_h) % pCache->orig_h; 654 if(blit_h >= pCache->orig_h) break; 655 } 656 657 /* Expand vertically */ 658 if (height) { 659 blit_w = pBox->x2 - pBox->x1; 660 phaseY -= (pBox->y1 - yorg) % pCache->orig_h; 661 if (phaseY < 0) phaseY += pCache->orig_h; 662 blit_h = y - pBox->y1 - phaseY; 663 while(height) { 664 if (blit_h > height) blit_h = height; 665 (*infoRec->SubsequentScreenToScreenCopy)(pScrn, pBox->x1, 666 pBox->y1 + phaseY, pBox->x1, y, blit_w, blit_h); 667 height -= blit_h; 668 y += blit_h; 669 blit_h <<= 1; 670 } 671 } 672 } else 673#endif 674 { 675 while(1) { 676 w = width; skipleft = phaseX; x = pBox->x1; 677 blit_h = pCache->h - phaseY; 678 if(blit_h > height) blit_h = height; 679 680 while(1) { 681 blit_w = pCache->w - skipleft; 682 if(blit_w > w) blit_w = w; 683 (*infoRec->SubsequentScreenToScreenCopy)(pScrn, 684 pCache->x + skipleft, pCache->y + phaseY, 685 x, y, blit_w, blit_h); 686 w -= blit_w; 687 if(!w) break; 688 x += blit_w; 689 skipleft = (skipleft + blit_w) % pCache->orig_w; 690 } 691 height -= blit_h; 692 if(!height) break; 693 y += blit_h; 694 phaseY = (phaseY + blit_h) % pCache->orig_h; 695 } 696 } 697 pBox++; 698 } 699 700 SET_SYNC_FLAG(infoRec); 701} 702 703 704 705 706 /*******************\ 707 | Cache Expansion | 708 \*******************/ 709 710 711 712void 713XAAFillCacheExpandRects( 714 ScrnInfoPtr pScrn, 715 int fg, int bg, int rop, 716 unsigned int planemask, 717 int nBox, 718 BoxPtr pBox, 719 int xorg, int yorg, 720 PixmapPtr pPix 721){ 722 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 723 int x, y, phaseY, phaseX, skipleft, height, width, w, blit_w, blit_h; 724 int cacheWidth; 725 XAACacheInfoPtr pCache; 726 727 pCache = (*infoRec->CacheMonoStipple)(pScrn, pPix); 728 729 cacheWidth = (pCache->w * pScrn->bitsPerPixel) / 730 infoRec->CacheColorExpandDensity; 731 732 (*infoRec->SetupForScreenToScreenColorExpandFill)(pScrn, fg, bg, rop, 733 planemask); 734 735 while(nBox--) { 736 y = pBox->y1; 737 phaseY = (y - yorg) % pCache->orig_h; 738 if(phaseY < 0) phaseY += pCache->orig_h; 739 phaseX = (pBox->x1 - xorg) % pCache->orig_w; 740 if(phaseX < 0) phaseX += pCache->orig_w; 741 height = pBox->y2 - y; 742 width = pBox->x2 - pBox->x1; 743 744 while(1) { 745 w = width; skipleft = phaseX; x = pBox->x1; 746 blit_h = pCache->h - phaseY; 747 if(blit_h > height) blit_h = height; 748 749 while(1) { 750 blit_w = cacheWidth - skipleft; 751 if(blit_w > w) blit_w = w; 752 (*infoRec->SubsequentScreenToScreenColorExpandFill)( 753 pScrn, x, y, blit_w, blit_h, 754 pCache->x, pCache->y + phaseY, skipleft); 755 w -= blit_w; 756 if(!w) break; 757 x += blit_w; 758 skipleft = (skipleft + blit_w) % pCache->orig_w; 759 } 760 height -= blit_h; 761 if(!height) break; 762 y += blit_h; 763 phaseY = (phaseY + blit_h) % pCache->orig_h; 764 } 765 pBox++; 766 } 767 768 SET_SYNC_FLAG(infoRec); 769} 770 771 772 /******************\ 773 | Image Writes | 774 \******************/ 775 776 777 778/* This requires all LEFT_EDGE clipping. You get too many problems 779 with reading past the edge of the pattern otherwise */ 780 781static void 782WriteColumnScanlines( 783 ScrnInfoPtr pScrn, 784 unsigned char *pSrc, 785 int x, int y, int w, int h, 786 int xoff, int yoff, 787 int pHeight, 788 int srcwidth, 789 int Bpp 790) { 791 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 792 unsigned char *src; 793 int skipleft, bytes, line, sline; 794 int buffer; 795 796 pSrc += (Bpp * xoff); 797 798 if((skipleft = (long)pSrc & 0x03L)) { 799 if(Bpp == 3) 800 skipleft = 4 - skipleft; 801 else 802 skipleft /= Bpp; 803 804 x -= skipleft; 805 w += skipleft; 806 807 if(Bpp == 3) 808 pSrc -= 3 * skipleft; 809 else /* is this Alpha friendly ? */ 810 pSrc = (unsigned char*)((long)pSrc & ~0x03L); 811 } 812 813 src = pSrc + (yoff * srcwidth); 814 815 bytes = w * Bpp; 816 817 (*infoRec->SubsequentScanlineImageWriteRect)(pScrn, x, y, w, h, skipleft); 818 819 buffer = 0; 820 sline = yoff; 821 for (line = 0; line < h; line++) { 822 memcpy(infoRec->ScanlineImageWriteBuffers[buffer], src, bytes); 823 (*infoRec->SubsequentImageWriteScanline)(pScrn, buffer); 824 buffer++; 825 src += srcwidth; 826 sline++; 827 if (sline >= pHeight) { 828 sline = 0; 829 src = pSrc; 830 } 831 if (buffer >= infoRec->NumScanlineImageWriteBuffers) 832 buffer = 0; 833 } 834} 835 836void 837XAAFillScanlineImageWriteRects( 838 ScrnInfoPtr pScrn, 839 int rop, 840 unsigned int planemask, 841 int nBox, 842 BoxPtr pBox, 843 int xorg, int yorg, 844 PixmapPtr pPix 845){ 846 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 847 int x, phaseY, phaseX, height, width, blit_w; 848 int pHeight = pPix->drawable.height; 849 int pWidth = pPix->drawable.width; 850 int Bpp = pPix->drawable.bitsPerPixel >> 3; 851 int srcwidth = pPix->devKind; 852 853 (*infoRec->SetupForScanlineImageWrite)(pScrn, rop, planemask, -1, 854 pPix->drawable.bitsPerPixel, pPix->drawable.depth); 855 856 while(nBox--) { 857 x = pBox->x1; 858 phaseY = (pBox->y1 - yorg) % pHeight; 859 if(phaseY < 0) phaseY += pHeight; 860 phaseX = (x - xorg) % pWidth; 861 if(phaseX < 0) phaseX += pWidth; 862 height = pBox->y2 - pBox->y1; 863 width = pBox->x2 - x; 864 865 while(1) { 866 blit_w = pWidth - phaseX; 867 if(blit_w > width) blit_w = width; 868 869 WriteColumnScanlines(pScrn, pPix->devPrivate.ptr, x, pBox->y1, 870 blit_w, height, phaseX, phaseY, pHeight, srcwidth, Bpp); 871 872 width -= blit_w; 873 if(!width) break; 874 x += blit_w; 875 phaseX = (phaseX + blit_w) % pWidth; 876 } 877 pBox++; 878 } 879 880 if(infoRec->ScanlineImageWriteFlags & SYNC_AFTER_IMAGE_WRITE) 881 (*infoRec->Sync)(pScrn); 882 else SET_SYNC_FLAG(infoRec); 883} 884 885static void 886WriteColumn( 887 ScrnInfoPtr pScrn, 888 unsigned char *pSrc, 889 int x, int y, int w, int h, 890 int xoff, int yoff, 891 int pHeight, 892 int srcwidth, 893 int Bpp 894) { 895 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 896 unsigned char *src; 897 Bool PlusOne = FALSE; 898 int skipleft, dwords; 899 900 pSrc += (Bpp * xoff); 901 902 if((skipleft = (long)pSrc & 0x03L)) { 903 if(Bpp == 3) 904 skipleft = 4 - skipleft; 905 else 906 skipleft /= Bpp; 907 908 x -= skipleft; 909 w += skipleft; 910 911 if(Bpp == 3) 912 pSrc -= 3 * skipleft; 913 else /* is this Alpha friendly ? */ 914 pSrc = (unsigned char*)((long)pSrc & ~0x03L); 915 } 916 917 src = pSrc + (yoff * srcwidth); 918 919 dwords = bytes_to_int32(w * Bpp); 920 921 if((infoRec->ImageWriteFlags & CPU_TRANSFER_PAD_QWORD) && 922 ((dwords * h) & 0x01)) { 923 PlusOne = TRUE; 924 } 925 926 (*infoRec->SubsequentImageWriteRect)(pScrn, x, y, w, h, skipleft); 927 928 if(dwords > infoRec->ImageWriteRange) { 929 while(h--) { 930 XAAMoveDWORDS_FixedBase((CARD32*)infoRec->ImageWriteBase, 931 (CARD32*)src, dwords); 932 src += srcwidth; 933 yoff++; 934 if(yoff >= pHeight) { 935 yoff = 0; 936 src = pSrc; 937 } 938 } 939 } else { 940 if(srcwidth == (dwords << 2)) { 941 int maxLines = infoRec->ImageWriteRange/dwords; 942 int step; 943 944 while(h) { 945 step = pHeight - yoff; 946 if(step > maxLines) step = maxLines; 947 if(step > h) step = h; 948 949 XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase, 950 (CARD32*)src, dwords * step); 951 952 src += (srcwidth * step); 953 yoff += step; 954 if(yoff >= pHeight) { 955 yoff = 0; 956 src = pSrc; 957 } 958 h -= step; 959 } 960 } else { 961 while(h--) { 962 XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase, 963 (CARD32*)src, dwords); 964 src += srcwidth; 965 yoff++; 966 if(yoff >= pHeight) { 967 yoff = 0; 968 src = pSrc; 969 } 970 } 971 } 972 } 973 974 if(PlusOne) { 975 CARD32* base = (CARD32*)infoRec->ImageWriteBase; 976 *base = 0x00000000; 977 } 978} 979 980void 981XAAFillImageWriteRects( 982 ScrnInfoPtr pScrn, 983 int rop, 984 unsigned int planemask, 985 int nBox, 986 BoxPtr pBox, 987 int xorg, int yorg, 988 PixmapPtr pPix 989){ 990 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 991 int x, phaseY, phaseX, height, width, blit_w; 992 int pHeight = pPix->drawable.height; 993 int pWidth = pPix->drawable.width; 994 int Bpp = pPix->drawable.bitsPerPixel >> 3; 995 int srcwidth = pPix->devKind; 996 997 (*infoRec->SetupForImageWrite)(pScrn, rop, planemask, -1, 998 pPix->drawable.bitsPerPixel, pPix->drawable.depth); 999 1000 while(nBox--) { 1001 x = pBox->x1; 1002 phaseY = (pBox->y1 - yorg) % pHeight; 1003 if(phaseY < 0) phaseY += pHeight; 1004 phaseX = (x - xorg) % pWidth; 1005 if(phaseX < 0) phaseX += pWidth; 1006 height = pBox->y2 - pBox->y1; 1007 width = pBox->x2 - x; 1008 1009 while(1) { 1010 blit_w = pWidth - phaseX; 1011 if(blit_w > width) blit_w = width; 1012 1013 WriteColumn(pScrn, pPix->devPrivate.ptr, x, pBox->y1, 1014 blit_w, height, phaseX, phaseY, pHeight, srcwidth, Bpp); 1015 1016 width -= blit_w; 1017 if(!width) break; 1018 x += blit_w; 1019 phaseX = (phaseX + blit_w) % pWidth; 1020 } 1021 pBox++; 1022 } 1023 1024 if(infoRec->ImageWriteFlags & SYNC_AFTER_IMAGE_WRITE) 1025 (*infoRec->Sync)(pScrn); 1026 else SET_SYNC_FLAG(infoRec); 1027} 1028 1029 1030 /*************\ 1031 | Utilities | 1032 \*************/ 1033 1034 1035void 1036XAAClipAndRenderRects( 1037 GCPtr pGC, 1038 ClipAndRenderRectsFunc BoxFunc, 1039 int nrectFill, 1040 xRectangle *prect, 1041 int xorg, int yorg 1042){ 1043 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); 1044 int Right, Bottom, MaxBoxes; 1045 BoxPtr pextent, pboxClipped, pboxClippedBase; 1046 1047 MaxBoxes = infoRec->PreAllocSize/sizeof(BoxRec); 1048 pboxClippedBase = (BoxPtr)infoRec->PreAllocMem; 1049 pboxClipped = pboxClippedBase; 1050 1051 if (RegionNumRects(pGC->pCompositeClip) == 1) { 1052 pextent = RegionRects(pGC->pCompositeClip); 1053 while (nrectFill--) { 1054 pboxClipped->x1 = max(pextent->x1, prect->x); 1055 pboxClipped->y1 = max(pextent->y1, prect->y); 1056 1057 Right = (int)prect->x + (int)prect->width; 1058 pboxClipped->x2 = min(pextent->x2, Right); 1059 1060 Bottom = (int)prect->y + (int)prect->height; 1061 pboxClipped->y2 = min(pextent->y2, Bottom); 1062 1063 prect++; 1064 if ((pboxClipped->x1 < pboxClipped->x2) && 1065 (pboxClipped->y1 < pboxClipped->y2)) { 1066 pboxClipped++; 1067 if(pboxClipped >= (pboxClippedBase + MaxBoxes)) { 1068 (*BoxFunc)(pGC, MaxBoxes, pboxClippedBase, xorg, yorg); 1069 pboxClipped = pboxClippedBase; 1070 } 1071 } 1072 } 1073 } else { 1074 pextent = RegionExtents(pGC->pCompositeClip); 1075 while (nrectFill--) { 1076 int n; 1077 BoxRec box, *pbox; 1078 1079 box.x1 = max(pextent->x1, prect->x); 1080 box.y1 = max(pextent->y1, prect->y); 1081 1082 Right = (int)prect->x + (int)prect->width; 1083 box.x2 = min(pextent->x2, Right); 1084 1085 Bottom = (int)prect->y + (int)prect->height; 1086 box.y2 = min(pextent->y2, Bottom); 1087 1088 prect++; 1089 1090 if ((box.x1 >= box.x2) || (box.y1 >= box.y2)) 1091 continue; 1092 1093 n = RegionNumRects (pGC->pCompositeClip); 1094 pbox = RegionRects(pGC->pCompositeClip); 1095 1096 /* clip the rectangle to each box in the clip region 1097 this is logically equivalent to calling Intersect() 1098 */ 1099 while(n--) { 1100 pboxClipped->x1 = max(box.x1, pbox->x1); 1101 pboxClipped->y1 = max(box.y1, pbox->y1); 1102 pboxClipped->x2 = min(box.x2, pbox->x2); 1103 pboxClipped->y2 = min(box.y2, pbox->y2); 1104 pbox++; 1105 1106 /* see if clipping left anything */ 1107 if(pboxClipped->x1 < pboxClipped->x2 && 1108 pboxClipped->y1 < pboxClipped->y2) { 1109 pboxClipped++; 1110 if(pboxClipped >= (pboxClippedBase + MaxBoxes)) { 1111 (*BoxFunc)(pGC, MaxBoxes, pboxClippedBase, xorg, yorg); 1112 pboxClipped = pboxClippedBase; 1113 } 1114 } 1115 } 1116 } 1117 } 1118 1119 if(pboxClipped != pboxClippedBase) 1120 (*BoxFunc)(pGC, pboxClipped - pboxClippedBase, pboxClippedBase, 1121 xorg, yorg); 1122} 1123 1124 1125int 1126XAAGetRectClipBoxes( 1127 GCPtr pGC, 1128 BoxPtr pboxClippedBase, 1129 int nrectFill, 1130 xRectangle *prectInit 1131){ 1132 int Right, Bottom; 1133 BoxPtr pextent, pboxClipped = pboxClippedBase; 1134 xRectangle *prect = prectInit; 1135 RegionPtr prgnClip = pGC->pCompositeClip; 1136 1137 if (RegionNumRects(prgnClip) == 1) { 1138 pextent = RegionRects(prgnClip); 1139 while (nrectFill--) { 1140 pboxClipped->x1 = max(pextent->x1, prect->x); 1141 pboxClipped->y1 = max(pextent->y1, prect->y); 1142 1143 Right = (int)prect->x + (int)prect->width; 1144 pboxClipped->x2 = min(pextent->x2, Right); 1145 1146 Bottom = (int)prect->y + (int)prect->height; 1147 pboxClipped->y2 = min(pextent->y2, Bottom); 1148 1149 prect++; 1150 if ((pboxClipped->x1 < pboxClipped->x2) && 1151 (pboxClipped->y1 < pboxClipped->y2)) { 1152 pboxClipped++; 1153 } 1154 } 1155 } else { 1156 pextent = RegionExtents(prgnClip); 1157 while (nrectFill--) { 1158 int n; 1159 BoxRec box, *pbox; 1160 1161 box.x1 = max(pextent->x1, prect->x); 1162 box.y1 = max(pextent->y1, prect->y); 1163 1164 Right = (int)prect->x + (int)prect->width; 1165 box.x2 = min(pextent->x2, Right); 1166 1167 Bottom = (int)prect->y + (int)prect->height; 1168 box.y2 = min(pextent->y2, Bottom); 1169 1170 prect++; 1171 1172 if ((box.x1 >= box.x2) || (box.y1 >= box.y2)) 1173 continue; 1174 1175 n = RegionNumRects (prgnClip); 1176 pbox = RegionRects(prgnClip); 1177 1178 /* clip the rectangle to each box in the clip region 1179 this is logically equivalent to calling Intersect() 1180 */ 1181 while(n--) { 1182 pboxClipped->x1 = max(box.x1, pbox->x1); 1183 pboxClipped->y1 = max(box.y1, pbox->y1); 1184 pboxClipped->x2 = min(box.x2, pbox->x2); 1185 pboxClipped->y2 = min(box.y2, pbox->y2); 1186 pbox++; 1187 1188 /* see if clipping left anything */ 1189 if(pboxClipped->x1 < pboxClipped->x2 && 1190 pboxClipped->y1 < pboxClipped->y2) { 1191 pboxClipped++; 1192 } 1193 } 1194 } 1195 } 1196 1197 return pboxClipped - pboxClippedBase; 1198} 1199 1200