First import
[xorg_rtime.git] / xorg-server-1.4 / hw / xfree86 / xaa / xaaFillRect.c
blob55a30bbd65d0713edd028e107e2d861691876bcf
2 #ifdef HAVE_XORG_CONFIG_H
3 #include <xorg-config.h>
4 #endif
6 #include "misc.h"
7 #include "xf86.h"
8 #include "xf86_OSproc.h"
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"
18 static void XAARenderSolidRects(GCPtr, int, BoxPtr, int, int);
19 static void XAARenderColor8x8Rects(GCPtr, int, BoxPtr, int, int);
20 static void XAARenderMono8x8Rects(GCPtr, int, BoxPtr, int, int);
21 static void XAARenderColorExpandRects(GCPtr, int, BoxPtr, int, int);
22 static void XAARenderCacheExpandRects(GCPtr, int, BoxPtr, int, int);
23 static void XAARenderCacheBltRects(GCPtr, int, BoxPtr, int, int);
24 static void XAARenderImageWriteRects(GCPtr, int, BoxPtr, int, int);
25 static void XAARenderPixmapCopyRects(GCPtr, int, BoxPtr, int, int);
27 void
28 XAAPolyFillRect(
29 DrawablePtr pDraw,
30 GCPtr pGC,
31 int nrectFill, /* number of rectangles to fill */
32 xRectangle *prectInit /* Pointer to first rectangle to fill */
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;
40 if((nrectFill <= 0) || !pGC->planemask)
41 return;
43 if(!REGION_NUM_RECTS(pGC->pCompositeClip))
44 return;
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;
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;
98 if(xorg | yorg) {
99 int n = nrectFill;
100 xRectangle *prect = prectInit;
102 while(n--) {
103 prect->x += xorg;
104 prect->y += yorg;
105 prect++;
110 XAAClipAndRenderRects(pGC, function, nrectFill, prectInit, xorg, yorg);
115 /*********************\
116 | Solid Rects |
117 \*********************/
119 static void
120 XAARenderSolidRects(
121 GCPtr pGC,
122 int nboxes,
123 BoxPtr pClipBoxes,
124 int xorg, int yorg
126 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
128 (*infoRec->FillSolidRects) (infoRec->pScrn,
129 pGC->fgPixel, pGC->alu, pGC->planemask, nboxes, pClipBoxes);
133 /************************\
134 | Mono 8x8 Rects |
135 \************************/
137 static void
138 XAARenderMono8x8Rects(
139 GCPtr pGC,
140 int nboxes,
141 BoxPtr pClipBoxes,
142 int xorg, int yorg
144 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
145 XAAPixmapPtr pPriv;
146 int fg, bg;
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;
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));
173 /*************************\
174 | Color 8x8 Rects |
175 \*************************/
177 static void
178 XAARenderColor8x8Rects(
179 GCPtr pGC,
180 int nboxes,
181 BoxPtr pClipBoxes,
182 int xorg, int yorg
184 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
185 XAACacheInfoPtr pCache;
186 PixmapPtr pPix;
187 int fg, bg;
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;
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);
215 /****************************\
216 | Color Expand Rects |
217 \****************************/
219 static void
220 XAARenderColorExpandRects(
221 GCPtr pGC,
222 int nboxes,
223 BoxPtr pClipBoxes,
224 int xorg, int yorg
226 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
227 int fg, bg;
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;
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);
248 /*************************\
249 | Cache Blt Rects |
250 \*************************/
252 static void
253 XAARenderCacheBltRects(
254 GCPtr pGC,
255 int nboxes,
256 BoxPtr pClipBoxes,
257 int xorg, int yorg
259 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
260 XAACacheInfoPtr pCache;
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;
279 (*infoRec->FillCacheBltRects) (infoRec->pScrn, pGC->alu,
280 pGC->planemask, nboxes, pClipBoxes,
281 (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y), pCache);
285 /****************************\
286 | Cache Expand Rects |
287 \****************************/
289 static void
290 XAARenderCacheExpandRects(
291 GCPtr pGC,
292 int nboxes,
293 BoxPtr pClipBoxes,
294 int xorg, int yorg
296 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
297 int fg, bg;
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;
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);
319 /***************************\
320 | Image Write Rects |
321 \***************************/
323 static void
324 XAARenderImageWriteRects(
325 GCPtr pGC,
326 int nboxes,
327 BoxPtr pClipBoxes,
328 int xorg, int yorg
330 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
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);
340 /***************************\
341 | Pixmap Copy Rects |
342 \***************************/
344 static void
345 XAARenderPixmapCopyRects(
346 GCPtr pGC,
347 int nboxes,
348 BoxPtr pClipBoxes,
349 int xorg, int yorg
351 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
352 XAACacheInfoPtr pCache = &(infoRec->ScratchCacheInfoRec);
353 XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
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;
363 (*infoRec->FillCacheBltRects) (infoRec->pScrn, pGC->alu,
364 pGC->planemask, nboxes, pClipBoxes,
365 (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y),
366 pCache);
371 /************\
372 | Solid |
373 \************/
375 void
376 XAAFillSolidRects(
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 */
383 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
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++;
391 SET_SYNC_FLAG(infoRec);
397 /*********************\
398 | 8x8 Mono Patterns |
399 \*********************/
402 void
403 XAAFillMono8x8PatternRectsScreenOrigin(
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
413 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
414 int patx = pattern0, paty = pattern1;
415 int xorg = (-xorigin) & 0x07;
416 int yorg = (-yorigin) & 0x07;
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;
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;
440 (*infoRec->SetupForMono8x8PatternFill)(pScrn, patx, paty,
441 fg, bg, rop, planemask);
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++;
449 SET_SYNC_FLAG(infoRec);
452 void
453 XAAFillMono8x8PatternRects(
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
463 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
464 int patx = pattern0, paty = pattern1;
465 int xorg, yorg;
466 XAACacheInfoPtr pCache = NULL;
469 if(!(infoRec->Mono8x8PatternFillFlags & HARDWARE_PATTERN_PROGRAMMED_BITS)){
470 pCache = (*infoRec->CacheMono8x8Pattern)(pScrn, pattern0, pattern1);
471 patx = pCache->x; paty = pCache->y;
475 (*infoRec->SetupForMono8x8PatternFill)(pScrn, patx, paty,
476 fg, bg, rop, planemask);
479 while(nBox--) {
480 xorg = (pBox->x1 - xorigin) & 0x07;
481 yorg = (pBox->y1 - yorigin) & 0x07;
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;
499 (*infoRec->SubsequentMono8x8PatternFillRect)(pScrn,
500 xorg, yorg, pBox->x1, pBox->y1,
501 pBox->x2 - pBox->x1, pBox->y2 - pBox->y1);
502 pBox++;
505 SET_SYNC_FLAG(infoRec);
509 /**********************\
510 | 8x8 Color Patterns |
511 \**********************/
514 void
515 XAAFillColor8x8PatternRectsScreenOrigin(
516 ScrnInfoPtr pScrn,
517 int rop,
518 unsigned int planemask,
519 int nBox,
520 BoxPtr pBox,
521 int xorigin, int yorigin,
522 XAACacheInfoPtr pCache
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;
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;
537 (*infoRec->SetupForColor8x8PatternFill)(pScrn, patx, paty,
538 rop, planemask, pCache->trans_color);
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++;
546 SET_SYNC_FLAG(infoRec);
549 void
550 XAAFillColor8x8PatternRects(
551 ScrnInfoPtr pScrn,
552 int rop,
553 unsigned int planemask,
554 int nBox,
555 BoxPtr pBox,
556 int xorigin, int yorigin,
557 XAACacheInfoPtr pCache
559 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
560 int xorg, yorg;
562 (*infoRec->SetupForColor8x8PatternFill)(pScrn, pCache->x, pCache->y,
563 rop, planemask, pCache->trans_color);
565 while(nBox--) {
566 xorg = (pBox->x1 - xorigin) & 0x07;
567 yorg = (pBox->y1 - yorigin) & 0x07;
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;
576 (*infoRec->SubsequentColor8x8PatternFillRect)(pScrn,
577 xorg, yorg, pBox->x1, pBox->y1,
578 pBox->x2 - pBox->x1, pBox->y2 - pBox->y1);
579 pBox++;
582 SET_SYNC_FLAG(infoRec);
586 /***************\
587 | Cache Blits |
588 \***************/
590 void
591 XAAFillCacheBltRects(
592 ScrnInfoPtr pScrn,
593 int rop,
594 unsigned int planemask,
595 int nBox,
596 BoxPtr pBox,
597 int xorg, int yorg,
598 XAACacheInfoPtr pCache
600 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
601 int x, y, phaseY, phaseX, skipleft, height, width, w, blit_w, blit_h;
603 (*infoRec->SetupForScreenToScreenCopy)(pScrn, 1, 1, rop, planemask,
604 pCache->trans_color);
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;
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;
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;
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;
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;
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;
672 } else
673 #endif
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;
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;
691 height -= blit_h;
692 if(!height) break;
693 y += blit_h;
694 phaseY = (phaseY + blit_h) % pCache->orig_h;
697 pBox++;
700 SET_SYNC_FLAG(infoRec);
706 /*******************\
707 | Cache Expansion |
708 \*******************/
712 void
713 XAAFillCacheExpandRects(
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
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;
727 pCache = (*infoRec->CacheMonoStipple)(pScrn, pPix);
729 cacheWidth = (pCache->w * pScrn->bitsPerPixel) /
730 infoRec->CacheColorExpandDensity;
732 (*infoRec->SetupForScreenToScreenColorExpandFill)(pScrn, fg, bg, rop,
733 planemask);
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;
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;
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;
760 height -= blit_h;
761 if(!height) break;
762 y += blit_h;
763 phaseY = (phaseY + blit_h) % pCache->orig_h;
765 pBox++;
768 SET_SYNC_FLAG(infoRec);
772 /******************\
773 | Image Writes |
774 \******************/
778 /* This requires all LEFT_EDGE clipping. You get too many problems
779 with reading past the edge of the pattern otherwise */
781 static void
782 WriteColumn(
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
791 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
792 unsigned char *src;
793 Bool PlusOne = FALSE;
794 int skipleft, dwords;
796 pSrc += (Bpp * xoff);
798 if((skipleft = (long)pSrc & 0x03L)) {
799 if(Bpp == 3)
800 skipleft = 4 - skipleft;
801 else
802 skipleft /= Bpp;
804 x -= skipleft;
805 w += skipleft;
807 if(Bpp == 3)
808 pSrc -= 3 * skipleft;
809 else /* is this Alpha friendly ? */
810 pSrc = (unsigned char*)((long)pSrc & ~0x03L);
813 src = pSrc + (yoff * srcwidth);
815 dwords = ((w * Bpp) + 3) >> 2;
817 if((infoRec->ImageWriteFlags & CPU_TRANSFER_PAD_QWORD) &&
818 ((dwords * h) & 0x01)) {
819 PlusOne = TRUE;
822 (*infoRec->SubsequentImageWriteRect)(pScrn, x, y, w, h, skipleft);
824 if(dwords > infoRec->ImageWriteRange) {
825 while(h--) {
826 XAAMoveDWORDS_FixedBase((CARD32*)infoRec->ImageWriteBase,
827 (CARD32*)src, dwords);
828 src += srcwidth;
829 yoff++;
830 if(yoff >= pHeight) {
831 yoff = 0;
832 src = pSrc;
835 } else {
836 if(srcwidth == (dwords << 2)) {
837 int maxLines = infoRec->ImageWriteRange/dwords;
838 int step;
840 while(h) {
841 step = pHeight - yoff;
842 if(step > maxLines) step = maxLines;
843 if(step > h) step = h;
845 XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase,
846 (CARD32*)src, dwords * step);
848 src += (srcwidth * step);
849 yoff += step;
850 if(yoff >= pHeight) {
851 yoff = 0;
852 src = pSrc;
854 h -= step;
856 } else {
857 while(h--) {
858 XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase,
859 (CARD32*)src, dwords);
860 src += srcwidth;
861 yoff++;
862 if(yoff >= pHeight) {
863 yoff = 0;
864 src = pSrc;
870 if(PlusOne) {
871 CARD32* base = (CARD32*)infoRec->ImageWriteBase;
872 *base = 0x00000000;
876 void
877 XAAFillImageWriteRects(
878 ScrnInfoPtr pScrn,
879 int rop,
880 unsigned int planemask,
881 int nBox,
882 BoxPtr pBox,
883 int xorg, int yorg,
884 PixmapPtr pPix
886 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
887 int x, phaseY, phaseX, height, width, blit_w;
888 int pHeight = pPix->drawable.height;
889 int pWidth = pPix->drawable.width;
890 int Bpp = pPix->drawable.bitsPerPixel >> 3;
891 int srcwidth = pPix->devKind;
893 (*infoRec->SetupForImageWrite)(pScrn, rop, planemask, -1,
894 pPix->drawable.bitsPerPixel, pPix->drawable.depth);
896 while(nBox--) {
897 x = pBox->x1;
898 phaseY = (pBox->y1 - yorg) % pHeight;
899 if(phaseY < 0) phaseY += pHeight;
900 phaseX = (x - xorg) % pWidth;
901 if(phaseX < 0) phaseX += pWidth;
902 height = pBox->y2 - pBox->y1;
903 width = pBox->x2 - x;
905 while(1) {
906 blit_w = pWidth - phaseX;
907 if(blit_w > width) blit_w = width;
909 WriteColumn(pScrn, pPix->devPrivate.ptr, x, pBox->y1,
910 blit_w, height, phaseX, phaseY, pHeight, srcwidth, Bpp);
912 width -= blit_w;
913 if(!width) break;
914 x += blit_w;
915 phaseX = (phaseX + blit_w) % pWidth;
917 pBox++;
920 if(infoRec->ImageWriteFlags & SYNC_AFTER_IMAGE_WRITE)
921 (*infoRec->Sync)(pScrn);
922 else SET_SYNC_FLAG(infoRec);
926 /*************\
927 | Utilities |
928 \*************/
931 void
932 XAAClipAndRenderRects(
933 GCPtr pGC,
934 ClipAndRenderRectsFunc BoxFunc,
935 int nrectFill,
936 xRectangle *prect,
937 int xorg, int yorg
939 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
940 int Right, Bottom, MaxBoxes;
941 BoxPtr pextent, pboxClipped, pboxClippedBase;
943 MaxBoxes = infoRec->PreAllocSize/sizeof(BoxRec);
944 pboxClippedBase = (BoxPtr)infoRec->PreAllocMem;
945 pboxClipped = pboxClippedBase;
947 if (REGION_NUM_RECTS(pGC->pCompositeClip) == 1) {
948 pextent = REGION_RECTS(pGC->pCompositeClip);
949 while (nrectFill--) {
950 pboxClipped->x1 = max(pextent->x1, prect->x);
951 pboxClipped->y1 = max(pextent->y1, prect->y);
953 Right = (int)prect->x + (int)prect->width;
954 pboxClipped->x2 = min(pextent->x2, Right);
956 Bottom = (int)prect->y + (int)prect->height;
957 pboxClipped->y2 = min(pextent->y2, Bottom);
959 prect++;
960 if ((pboxClipped->x1 < pboxClipped->x2) &&
961 (pboxClipped->y1 < pboxClipped->y2)) {
962 pboxClipped++;
963 if(pboxClipped >= (pboxClippedBase + MaxBoxes)) {
964 (*BoxFunc)(pGC, MaxBoxes, pboxClippedBase, xorg, yorg);
965 pboxClipped = pboxClippedBase;
969 } else {
970 pextent = REGION_EXTENTS(pGC->pScreen, pGC->pCompositeClip);
971 while (nrectFill--) {
972 int n;
973 BoxRec box, *pbox;
975 box.x1 = max(pextent->x1, prect->x);
976 box.y1 = max(pextent->y1, prect->y);
978 Right = (int)prect->x + (int)prect->width;
979 box.x2 = min(pextent->x2, Right);
981 Bottom = (int)prect->y + (int)prect->height;
982 box.y2 = min(pextent->y2, Bottom);
984 prect++;
986 if ((box.x1 >= box.x2) || (box.y1 >= box.y2))
987 continue;
989 n = REGION_NUM_RECTS (pGC->pCompositeClip);
990 pbox = REGION_RECTS(pGC->pCompositeClip);
992 /* clip the rectangle to each box in the clip region
993 this is logically equivalent to calling Intersect()
995 while(n--) {
996 pboxClipped->x1 = max(box.x1, pbox->x1);
997 pboxClipped->y1 = max(box.y1, pbox->y1);
998 pboxClipped->x2 = min(box.x2, pbox->x2);
999 pboxClipped->y2 = min(box.y2, pbox->y2);
1000 pbox++;
1002 /* see if clipping left anything */
1003 if(pboxClipped->x1 < pboxClipped->x2 &&
1004 pboxClipped->y1 < pboxClipped->y2) {
1005 pboxClipped++;
1006 if(pboxClipped >= (pboxClippedBase + MaxBoxes)) {
1007 (*BoxFunc)(pGC, MaxBoxes, pboxClippedBase, xorg, yorg);
1008 pboxClipped = pboxClippedBase;
1015 if(pboxClipped != pboxClippedBase)
1016 (*BoxFunc)(pGC, pboxClipped - pboxClippedBase, pboxClippedBase,
1017 xorg, yorg);
1022 XAAGetRectClipBoxes(
1023 GCPtr pGC,
1024 BoxPtr pboxClippedBase,
1025 int nrectFill,
1026 xRectangle *prectInit
1028 int Right, Bottom;
1029 BoxPtr pextent, pboxClipped = pboxClippedBase;
1030 xRectangle *prect = prectInit;
1031 RegionPtr prgnClip = pGC->pCompositeClip;
1033 if (REGION_NUM_RECTS(prgnClip) == 1) {
1034 pextent = REGION_RECTS(prgnClip);
1035 while (nrectFill--) {
1036 pboxClipped->x1 = max(pextent->x1, prect->x);
1037 pboxClipped->y1 = max(pextent->y1, prect->y);
1039 Right = (int)prect->x + (int)prect->width;
1040 pboxClipped->x2 = min(pextent->x2, Right);
1042 Bottom = (int)prect->y + (int)prect->height;
1043 pboxClipped->y2 = min(pextent->y2, Bottom);
1045 prect++;
1046 if ((pboxClipped->x1 < pboxClipped->x2) &&
1047 (pboxClipped->y1 < pboxClipped->y2)) {
1048 pboxClipped++;
1051 } else {
1052 pextent = REGION_EXTENTS(pGC->pScreen, prgnClip);
1053 while (nrectFill--) {
1054 int n;
1055 BoxRec box, *pbox;
1057 box.x1 = max(pextent->x1, prect->x);
1058 box.y1 = max(pextent->y1, prect->y);
1060 Right = (int)prect->x + (int)prect->width;
1061 box.x2 = min(pextent->x2, Right);
1063 Bottom = (int)prect->y + (int)prect->height;
1064 box.y2 = min(pextent->y2, Bottom);
1066 prect++;
1068 if ((box.x1 >= box.x2) || (box.y1 >= box.y2))
1069 continue;
1071 n = REGION_NUM_RECTS (prgnClip);
1072 pbox = REGION_RECTS(prgnClip);
1074 /* clip the rectangle to each box in the clip region
1075 this is logically equivalent to calling Intersect()
1077 while(n--) {
1078 pboxClipped->x1 = max(box.x1, pbox->x1);
1079 pboxClipped->y1 = max(box.y1, pbox->y1);
1080 pboxClipped->x2 = min(box.x2, pbox->x2);
1081 pboxClipped->y2 = min(box.y2, pbox->y2);
1082 pbox++;
1084 /* see if clipping left anything */
1085 if(pboxClipped->x1 < pboxClipped->x2 &&
1086 pboxClipped->y1 < pboxClipped->y2) {
1087 pboxClipped++;
1093 return(pboxClipped - pboxClippedBase);