summaryrefslogtreecommitdiff
path: root/hw/xfree86/xaa/xaaFillRect.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/xfree86/xaa/xaaFillRect.c')
-rw-r--r--hw/xfree86/xaa/xaaFillRect.c1093
1 files changed, 1093 insertions, 0 deletions
diff --git a/hw/xfree86/xaa/xaaFillRect.c b/hw/xfree86/xaa/xaaFillRect.c
new file mode 100644
index 000000000..1d9cd54c1
--- /dev/null
+++ b/hw/xfree86/xaa/xaaFillRect.c
@@ -0,0 +1,1093 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaFillRect.c,v 1.15 2001/12/13 18:01:51 eich Exp $ */
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+
+
+static void XAARenderSolidRects(GCPtr, int, BoxPtr, int, int);
+static void XAARenderColor8x8Rects(GCPtr, int, BoxPtr, int, int);
+static void XAARenderMono8x8Rects(GCPtr, int, BoxPtr, int, int);
+static void XAARenderColorExpandRects(GCPtr, int, BoxPtr, int, int);
+static void XAARenderCacheExpandRects(GCPtr, int, BoxPtr, int, int);
+static void XAARenderCacheBltRects(GCPtr, int, BoxPtr, int, int);
+static void XAARenderImageWriteRects(GCPtr, int, BoxPtr, int, int);
+static void XAARenderPixmapCopyRects(GCPtr, int, BoxPtr, int, int);
+
+void
+XAAPolyFillRect(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nrectFill, /* number of rectangles to fill */
+ xRectangle *prectInit /* Pointer to first rectangle to fill */
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int xorg = pDraw->x;
+ int yorg = pDraw->y;
+ int type = 0;
+ ClipAndRenderRectsFunc function;
+
+ if((nrectFill <= 0) || !pGC->planemask)
+ return;
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ switch(pGC->fillStyle) {
+ case FillSolid:
+ type = DO_SOLID;
+ break;
+ case FillStippled:
+ type = (*infoRec->StippledFillChooser)(pGC);
+ break;
+ case FillOpaqueStippled:
+ if((pGC->fgPixel == pGC->bgPixel) && infoRec->FillSolidRects &&
+ CHECK_PLANEMASK(pGC,infoRec->FillSolidRectsFlags) &&
+ CHECK_ROP(pGC,infoRec->FillSolidRectsFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillSolidRectsFlags) &&
+ CHECK_FG(pGC,infoRec->FillSolidRectsFlags))
+ type = DO_SOLID;
+ else
+ type = (*infoRec->OpaqueStippledFillChooser)(pGC);
+ break;
+ case FillTiled:
+ type = (*infoRec->TiledFillChooser)(pGC);
+ break;
+ }
+
+ switch(type) {
+ case DO_SOLID:
+ function = XAARenderSolidRects;
+ break;
+ case DO_COLOR_8x8:
+ function = XAARenderColor8x8Rects;
+ break;
+ case DO_MONO_8x8:
+ function = XAARenderMono8x8Rects;
+ break;
+ case DO_CACHE_BLT:
+ function = XAARenderCacheBltRects;
+ break;
+ case DO_COLOR_EXPAND:
+ function = XAARenderColorExpandRects;
+ break;
+ case DO_CACHE_EXPAND:
+ function = XAARenderCacheExpandRects;
+ break;
+ case DO_IMAGE_WRITE:
+ function = XAARenderImageWriteRects;
+ break;
+ case DO_PIXMAP_COPY:
+ function = XAARenderPixmapCopyRects;
+ break;
+ default:
+ (*XAAFallbackOps.PolyFillRect)(pDraw, pGC, nrectFill, prectInit);
+ return;
+ }
+
+ if(xorg | yorg) {
+ int n = nrectFill;
+ xRectangle *prect = prectInit;
+
+ while(n--) {
+ prect->x += xorg;
+ prect->y += yorg;
+ prect++;
+ }
+ }
+
+
+ XAAClipAndRenderRects(pGC, function, nrectFill, prectInit, xorg, yorg);
+}
+
+
+
+ /*********************\
+ | Solid Rects |
+ \*********************/
+
+static void
+XAARenderSolidRects(
+ GCPtr pGC,
+ int nboxes,
+ BoxPtr pClipBoxes,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+
+ (*infoRec->FillSolidRects) (infoRec->pScrn,
+ pGC->fgPixel, pGC->alu, pGC->planemask, nboxes, pClipBoxes);
+}
+
+
+ /************************\
+ | Mono 8x8 Rects |
+ \************************/
+
+static void
+XAARenderMono8x8Rects(
+ GCPtr pGC,
+ int nboxes,
+ BoxPtr pClipBoxes,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ XAAPixmapPtr pPriv;
+ int fg, bg;
+
+ switch(pGC->fillStyle) {
+ case FillStippled:
+ pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->stipple);
+ fg = pGC->fgPixel; bg = -1;
+ break;
+ case FillOpaqueStippled:
+ pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->stipple);
+ fg = pGC->fgPixel; bg = pGC->bgPixel;
+ break;
+ case FillTiled:
+ pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
+ fg = pPriv->fg; bg = pPriv->bg;
+ break;
+ default: /* Muffle compiler */
+ pPriv = NULL; /* Kaboom */
+ fg = -1; bg = -1;
+ break;
+ }
+
+ (*infoRec->FillMono8x8PatternRects) (infoRec->pScrn,
+ fg, bg, pGC->alu, pGC->planemask,
+ nboxes, pClipBoxes, pPriv->pattern0, pPriv->pattern1,
+ (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y));
+}
+
+ /*************************\
+ | Color 8x8 Rects |
+ \*************************/
+
+static void
+XAARenderColor8x8Rects(
+ GCPtr pGC,
+ int nboxes,
+ BoxPtr pClipBoxes,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ XAACacheInfoPtr pCache;
+ PixmapPtr pPix;
+ int fg, bg;
+
+ switch(pGC->fillStyle) {
+ case FillStippled:
+ pPix = pGC->stipple;
+ fg = pGC->fgPixel; bg = -1;
+ break;
+ case FillOpaqueStippled:
+ pPix = pGC->stipple;
+ fg = pGC->fgPixel; bg = pGC->bgPixel;
+ break;
+ case FillTiled:
+ pPix = pGC->tile.pixmap;
+ fg = -1; bg = -1;
+ break;
+ default: /* Muffle compiler */
+ pPix = NULL;
+ fg = -1; bg = -1;
+ break;
+ }
+
+ pCache = (*infoRec->CacheColor8x8Pattern)(infoRec->pScrn, pPix, fg, bg);
+ (*infoRec->FillColor8x8PatternRects) (infoRec->pScrn,
+ pGC->alu, pGC->planemask, nboxes, pClipBoxes,
+ (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y), pCache);
+}
+
+
+ /****************************\
+ | Color Expand Rects |
+ \****************************/
+
+static void
+XAARenderColorExpandRects(
+ GCPtr pGC,
+ int nboxes,
+ BoxPtr pClipBoxes,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int fg, bg;
+
+ switch(pGC->fillStyle) {
+ case FillStippled:
+ fg = pGC->fgPixel; bg = -1;
+ break;
+ case FillOpaqueStippled:
+ fg = pGC->fgPixel; bg = pGC->bgPixel;
+ break;
+ default: /* Muffle compiler */
+ fg = -1; bg = -1;
+ break;
+ }
+
+ (*infoRec->FillColorExpandRects) (infoRec->pScrn, fg, bg,
+ pGC->alu, pGC->planemask, nboxes, pClipBoxes,
+ (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y),
+ pGC->stipple);
+}
+
+
+ /*************************\
+ | Cache Blt Rects |
+ \*************************/
+
+static void
+XAARenderCacheBltRects(
+ GCPtr pGC,
+ int nboxes,
+ BoxPtr pClipBoxes,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ XAACacheInfoPtr pCache;
+
+ switch(pGC->fillStyle) {
+ case FillStippled:
+ pCache = (*infoRec->CacheStipple)(infoRec->pScrn, pGC->stipple,
+ pGC->fgPixel, -1);
+ break;
+ case FillOpaqueStippled:
+ pCache = (*infoRec->CacheStipple)(infoRec->pScrn, pGC->stipple,
+ pGC->fgPixel, pGC->bgPixel);
+ break;
+ case FillTiled:
+ pCache = (*infoRec->CacheTile)(infoRec->pScrn, pGC->tile.pixmap);
+ break;
+ default: /* Muffle compiler */
+ pCache = NULL;
+ break;
+ }
+
+ (*infoRec->FillCacheBltRects) (infoRec->pScrn, pGC->alu,
+ pGC->planemask, nboxes, pClipBoxes,
+ (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y), pCache);
+}
+
+
+ /****************************\
+ | Cache Expand Rects |
+ \****************************/
+
+static void
+XAARenderCacheExpandRects(
+ GCPtr pGC,
+ int nboxes,
+ BoxPtr pClipBoxes,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int fg, bg;
+
+ switch(pGC->fillStyle) {
+ case FillStippled:
+ fg = pGC->fgPixel; bg = -1;
+ break;
+ case FillOpaqueStippled:
+ fg = pGC->fgPixel; bg = pGC->bgPixel;
+ break;
+ default: /* Muffle compiler */
+ fg = -1; bg = -1;
+ break;
+ }
+
+ (*infoRec->FillCacheExpandRects) (infoRec->pScrn, fg, bg,
+ pGC->alu, pGC->planemask, nboxes, pClipBoxes,
+ (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y),
+ pGC->stipple);
+}
+
+
+
+ /***************************\
+ | Image Write Rects |
+ \***************************/
+
+static void
+XAARenderImageWriteRects(
+ GCPtr pGC,
+ int nboxes,
+ BoxPtr pClipBoxes,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+
+ (*infoRec->FillImageWriteRects) (infoRec->pScrn, pGC->alu,
+ pGC->planemask, nboxes, pClipBoxes,
+ (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y),
+ pGC->tile.pixmap);
+}
+
+
+
+ /***************************\
+ | Pixmap Copy Rects |
+ \***************************/
+
+static void
+XAARenderPixmapCopyRects(
+ GCPtr pGC,
+ int nboxes,
+ BoxPtr pClipBoxes,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ XAACacheInfoPtr pCache = &(infoRec->ScratchCacheInfoRec);
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
+
+ pCache->x = pPriv->offscreenArea->box.x1;
+ pCache->y = pPriv->offscreenArea->box.y1;
+ pCache->w = pCache->orig_w =
+ pPriv->offscreenArea->box.x2 - pCache->x;
+ pCache->h = pCache->orig_h =
+ pPriv->offscreenArea->box.y2 - pCache->y;
+ pCache->trans_color = -1;
+
+ (*infoRec->FillCacheBltRects) (infoRec->pScrn, pGC->alu,
+ pGC->planemask, nboxes, pClipBoxes,
+ (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y),
+ pCache);
+}
+
+
+
+ /************\
+ | Solid |
+ \************/
+
+void
+XAAFillSolidRects(
+ ScrnInfoPtr pScrn,
+ int fg, int rop,
+ unsigned int planemask,
+ int nBox, /* number of rectangles to fill */
+ BoxPtr pBox /* Pointer to first rectangle to fill */
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ (*infoRec->SetupForSolidFill)(pScrn, fg, rop, planemask);
+ while(nBox--) {
+ (*infoRec->SubsequentSolidFillRect)(pScrn, pBox->x1, pBox->y1,
+ pBox->x2 - pBox->x1, pBox->y2 - pBox->y1);
+ pBox++;
+ }
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+
+
+ /*********************\
+ | 8x8 Mono Patterns |
+ \*********************/
+
+
+void
+XAAFillMono8x8PatternRectsScreenOrigin(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int pattern0, int pattern1,
+ int xorigin, int yorigin
+)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int patx = pattern0, paty = pattern1;
+ int xorg = (-xorigin) & 0x07;
+ int yorg = (-yorigin) & 0x07;
+
+
+ if(infoRec->Mono8x8PatternFillFlags & HARDWARE_PATTERN_PROGRAMMED_BITS) {
+ if(!(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
+ XAARotateMonoPattern(&patx, &paty, xorg, yorg,
+ (infoRec->Mono8x8PatternFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST));
+ xorg = patx; yorg = paty;
+ }
+ } else {
+ XAACacheInfoPtr pCache =
+ (*infoRec->CacheMono8x8Pattern)(pScrn, pattern0, pattern1);
+ patx = pCache->x; paty = pCache->y;
+ if(!(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
+ int slot = (yorg << 3) + xorg;
+ patx += pCache->offsets[slot].x;
+ paty += pCache->offsets[slot].y;
+ xorg = patx; yorg = paty;
+ }
+ }
+
+ (*infoRec->SetupForMono8x8PatternFill)(pScrn, patx, paty,
+ fg, bg, rop, planemask);
+
+ while(nBox--) {
+ (*infoRec->SubsequentMono8x8PatternFillRect)(pScrn,
+ xorg, yorg, pBox->x1, pBox->y1,
+ pBox->x2 - pBox->x1, pBox->y2 - pBox->y1);
+ pBox++;
+ }
+ SET_SYNC_FLAG(infoRec);
+}
+
+void
+XAAFillMono8x8PatternRects(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int pattern0, int pattern1,
+ int xorigin, int yorigin
+)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int patx = pattern0, paty = pattern1;
+ int xorg, yorg;
+ XAACacheInfoPtr pCache = NULL;
+
+
+ if(!(infoRec->Mono8x8PatternFillFlags & HARDWARE_PATTERN_PROGRAMMED_BITS)){
+ pCache = (*infoRec->CacheMono8x8Pattern)(pScrn, pattern0, pattern1);
+ patx = pCache->x; paty = pCache->y;
+ }
+
+
+ (*infoRec->SetupForMono8x8PatternFill)(pScrn, patx, paty,
+ fg, bg, rop, planemask);
+
+
+ while(nBox--) {
+ xorg = (pBox->x1 - xorigin) & 0x07;
+ yorg = (pBox->y1 - yorigin) & 0x07;
+
+ if(!(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
+ if(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_BITS) {
+ patx = pattern0; paty = pattern1;
+ XAARotateMonoPattern(&patx, &paty, xorg, yorg,
+ (infoRec->Mono8x8PatternFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST));
+ xorg = patx; yorg = paty;
+ } else {
+ int slot = (yorg << 3) + xorg;
+ xorg = patx + pCache->offsets[slot].x;
+ yorg = paty + pCache->offsets[slot].y;
+ }
+ }
+
+ (*infoRec->SubsequentMono8x8PatternFillRect)(pScrn,
+ xorg, yorg, pBox->x1, pBox->y1,
+ pBox->x2 - pBox->x1, pBox->y2 - pBox->y1);
+ pBox++;
+ }
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+ /**********************\
+ | 8x8 Color Patterns |
+ \**********************/
+
+
+void
+XAAFillColor8x8PatternRectsScreenOrigin(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorigin, int yorigin,
+ XAACacheInfoPtr pCache
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int patx = pCache->x, paty = pCache->y;
+ int xorg = (-xorigin) & 0x07;
+ int yorg = (-yorigin) & 0x07;
+
+ if(!(infoRec->Color8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
+ int slot = (yorg << 3) + xorg;
+ paty += pCache->offsets[slot].y;
+ patx += pCache->offsets[slot].x;
+ xorg = patx; yorg = paty;
+ }
+
+ (*infoRec->SetupForColor8x8PatternFill)(pScrn, patx, paty,
+ rop, planemask, pCache->trans_color);
+
+ while(nBox--) {
+ (*infoRec->SubsequentColor8x8PatternFillRect)(pScrn,
+ xorg, yorg, pBox->x1, pBox->y1,
+ pBox->x2 - pBox->x1, pBox->y2 - pBox->y1);
+ pBox++;
+ }
+ SET_SYNC_FLAG(infoRec);
+}
+
+void
+XAAFillColor8x8PatternRects(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorigin, int yorigin,
+ XAACacheInfoPtr pCache
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int xorg, yorg;
+
+ (*infoRec->SetupForColor8x8PatternFill)(pScrn, pCache->x, pCache->y,
+ rop, planemask, pCache->trans_color);
+
+ while(nBox--) {
+ xorg = (pBox->x1 - xorigin) & 0x07;
+ yorg = (pBox->y1 - yorigin) & 0x07;
+
+ if(!(infoRec->Color8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
+ int slot = (yorg << 3) + xorg;
+ yorg = pCache->y + pCache->offsets[slot].y;
+ xorg = pCache->x + pCache->offsets[slot].x;
+ }
+
+ (*infoRec->SubsequentColor8x8PatternFillRect)(pScrn,
+ xorg, yorg, pBox->x1, pBox->y1,
+ pBox->x2 - pBox->x1, pBox->y2 - pBox->y1);
+ pBox++;
+ }
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+ /***************\
+ | Cache Blits |
+ \***************/
+
+void
+XAAFillCacheBltRects(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ XAACacheInfoPtr pCache
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int x, y, phaseY, phaseX, skipleft, height, width, w, blit_w, blit_h;
+
+ (*infoRec->SetupForScreenToScreenCopy)(pScrn, 1, 1, rop, planemask,
+ pCache->trans_color);
+
+ while(nBox--) {
+ y = pBox->y1;
+ phaseY = (y - yorg) % pCache->orig_h;
+ if(phaseY < 0) phaseY += pCache->orig_h;
+ phaseX = (pBox->x1 - xorg) % pCache->orig_w;
+ if(phaseX < 0) phaseX += pCache->orig_w;
+ height = pBox->y2 - y;
+ width = pBox->x2 - pBox->x1;
+
+#if 0
+ if (rop == GXcopy) {
+ while(1) {
+ w = width; skipleft = phaseX; x = pBox->x1;
+ blit_h = pCache->h - phaseY;
+ if(blit_h > height) blit_h = height;
+
+ while(1) {
+ blit_w = pCache->w - skipleft;
+ if(blit_w > w) blit_w = w;
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pCache->x + skipleft, pCache->y + phaseY,
+ x, y, blit_w, blit_h);
+ w -= blit_w;
+ if(!w) break;
+ x += blit_w;
+ skipleft = (skipleft + blit_w) % pCache->orig_w;
+ if(blit_w >= pCache->orig_w) break;
+ }
+
+ /* Expand horizontally */
+ if (w) {
+ skipleft -= phaseX;
+ if (skipleft < 0) skipleft += pCache->orig_w;
+ blit_w = x - pBox->x1 - skipleft;
+ while(w) {
+ if (blit_w > w) blit_w = w;
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pBox->x1 + skipleft, y, x, y, blit_w, blit_h);
+ w -= blit_w;
+ x += blit_w;
+ blit_w <<= 1;
+ }
+ }
+
+ height -= blit_h;
+ if(!height) break;
+ y += blit_h;
+ phaseY = (phaseY + blit_h) % pCache->orig_h;
+ if(blit_h >= pCache->orig_h) break;
+ }
+
+ /* Expand vertically */
+ if (height) {
+ blit_w = pBox->x2 - pBox->x1;
+ phaseY -= (pBox->y1 - yorg) % pCache->orig_h;
+ if (phaseY < 0) phaseY += pCache->orig_h;
+ blit_h = y - pBox->y1 - phaseY;
+ while(height) {
+ if (blit_h > height) blit_h = height;
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn, pBox->x1,
+ pBox->y1 + phaseY, pBox->x1, y, blit_w, blit_h);
+ height -= blit_h;
+ y += blit_h;
+ blit_h <<= 1;
+ }
+ }
+ } else
+#endif
+ {
+ while(1) {
+ w = width; skipleft = phaseX; x = pBox->x1;
+ blit_h = pCache->h - phaseY;
+ if(blit_h > height) blit_h = height;
+
+ while(1) {
+ blit_w = pCache->w - skipleft;
+ if(blit_w > w) blit_w = w;
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pCache->x + skipleft, pCache->y + phaseY,
+ x, y, blit_w, blit_h);
+ w -= blit_w;
+ if(!w) break;
+ x += blit_w;
+ skipleft = (skipleft + blit_w) % pCache->orig_w;
+ }
+ height -= blit_h;
+ if(!height) break;
+ y += blit_h;
+ phaseY = (phaseY + blit_h) % pCache->orig_h;
+ }
+ }
+ pBox++;
+ }
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+
+
+ /*******************\
+ | Cache Expansion |
+ \*******************/
+
+
+
+void
+XAAFillCacheExpandRects(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int x, y, phaseY, phaseX, skipleft, height, width, w, blit_w, blit_h;
+ int cacheWidth;
+ XAACacheInfoPtr pCache;
+
+ pCache = (*infoRec->CacheMonoStipple)(pScrn, pPix);
+
+ cacheWidth = (pCache->w * pScrn->bitsPerPixel) /
+ infoRec->CacheColorExpandDensity;
+
+ (*infoRec->SetupForScreenToScreenColorExpandFill)(pScrn, fg, bg, rop,
+ planemask);
+
+ while(nBox--) {
+ y = pBox->y1;
+ phaseY = (y - yorg) % pCache->orig_h;
+ if(phaseY < 0) phaseY += pCache->orig_h;
+ phaseX = (pBox->x1 - xorg) % pCache->orig_w;
+ if(phaseX < 0) phaseX += pCache->orig_w;
+ height = pBox->y2 - y;
+ width = pBox->x2 - pBox->x1;
+
+ while(1) {
+ w = width; skipleft = phaseX; x = pBox->x1;
+ blit_h = pCache->h - phaseY;
+ if(blit_h > height) blit_h = height;
+
+ while(1) {
+ blit_w = cacheWidth - skipleft;
+ if(blit_w > w) blit_w = w;
+ (*infoRec->SubsequentScreenToScreenColorExpandFill)(
+ pScrn, x, y, blit_w, blit_h,
+ pCache->x, pCache->y + phaseY, skipleft);
+ w -= blit_w;
+ if(!w) break;
+ x += blit_w;
+ skipleft = (skipleft + blit_w) % pCache->orig_w;
+ }
+ height -= blit_h;
+ if(!height) break;
+ y += blit_h;
+ phaseY = (phaseY + blit_h) % pCache->orig_h;
+ }
+ pBox++;
+ }
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+ /******************\
+ | Image Writes |
+ \******************/
+
+
+
+/* This requires all LEFT_EDGE clipping. You get too many problems
+ with reading past the edge of the pattern otherwise */
+
+static void
+WriteColumn(
+ ScrnInfoPtr pScrn,
+ unsigned char *pSrc,
+ int x, int y, int w, int h,
+ int xoff, int yoff,
+ int pHeight,
+ int srcwidth,
+ int Bpp
+) {
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ unsigned char *src;
+ Bool PlusOne = FALSE;
+ int skipleft, dwords;
+
+ pSrc += (Bpp * xoff);
+
+ if((skipleft = (long)pSrc & 0x03L)) {
+ if(Bpp == 3)
+ skipleft = 4 - skipleft;
+ else
+ skipleft /= Bpp;
+
+ x -= skipleft;
+ w += skipleft;
+
+ if(Bpp == 3)
+ pSrc -= 3 * skipleft;
+ else /* is this Alpha friendly ? */
+ pSrc = (unsigned char*)((long)pSrc & ~0x03L);
+ }
+
+ src = pSrc + (yoff * srcwidth);
+
+ dwords = ((w * Bpp) + 3) >> 2;
+
+ if((infoRec->ImageWriteFlags & CPU_TRANSFER_PAD_QWORD) &&
+ ((dwords * h) & 0x01)) {
+ PlusOne = TRUE;
+ }
+
+ (*infoRec->SubsequentImageWriteRect)(pScrn, x, y, w, h, skipleft);
+
+ if(dwords > infoRec->ImageWriteRange) {
+ while(h--) {
+ XAAMoveDWORDS_FixedBase((CARD32*)infoRec->ImageWriteBase,
+ (CARD32*)src, dwords);
+ src += srcwidth;
+ yoff++;
+ if(yoff >= pHeight) {
+ yoff = 0;
+ src = pSrc;
+ }
+ }
+ } else {
+ if(srcwidth == (dwords << 2)) {
+ int maxLines = infoRec->ImageWriteRange/dwords;
+ int step;
+
+ while(h) {
+ step = pHeight - yoff;
+ if(step > maxLines) step = maxLines;
+ if(step > h) step = h;
+
+ XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase,
+ (CARD32*)src, dwords * step);
+
+ src += (srcwidth * step);
+ yoff += step;
+ if(yoff >= pHeight) {
+ yoff = 0;
+ src = pSrc;
+ }
+ h -= step;
+ }
+ } else {
+ while(h--) {
+ XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase,
+ (CARD32*)src, dwords);
+ src += srcwidth;
+ yoff++;
+ if(yoff >= pHeight) {
+ yoff = 0;
+ src = pSrc;
+ }
+ }
+ }
+ }
+
+ if(PlusOne) {
+ CARD32* base = (CARD32*)infoRec->ImageWriteBase;
+ *base = 0x00000000;
+ }
+}
+
+void
+XAAFillImageWriteRects(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int x, phaseY, phaseX, height, width, blit_w;
+ int pHeight = pPix->drawable.height;
+ int pWidth = pPix->drawable.width;
+ int Bpp = pPix->drawable.bitsPerPixel >> 3;
+ int srcwidth = pPix->devKind;
+
+ (*infoRec->SetupForImageWrite)(pScrn, rop, planemask, -1,
+ pPix->drawable.bitsPerPixel, pPix->drawable.depth);
+
+ while(nBox--) {
+ x = pBox->x1;
+ phaseY = (pBox->y1 - yorg) % pHeight;
+ if(phaseY < 0) phaseY += pHeight;
+ phaseX = (x - xorg) % pWidth;
+ if(phaseX < 0) phaseX += pWidth;
+ height = pBox->y2 - pBox->y1;
+ width = pBox->x2 - x;
+
+ while(1) {
+ blit_w = pWidth - phaseX;
+ if(blit_w > width) blit_w = width;
+
+ WriteColumn(pScrn, pPix->devPrivate.ptr, x, pBox->y1,
+ blit_w, height, phaseX, phaseY, pHeight, srcwidth, Bpp);
+
+ width -= blit_w;
+ if(!width) break;
+ x += blit_w;
+ phaseX = (phaseX + blit_w) % pWidth;
+ }
+ pBox++;
+ }
+
+ if(infoRec->ImageWriteFlags & SYNC_AFTER_IMAGE_WRITE)
+ (*infoRec->Sync)(pScrn);
+ else SET_SYNC_FLAG(infoRec);
+}
+
+
+ /*************\
+ | Utilities |
+ \*************/
+
+
+void
+XAAClipAndRenderRects(
+ GCPtr pGC,
+ ClipAndRenderRectsFunc BoxFunc,
+ int nrectFill,
+ xRectangle *prect,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int Right, Bottom, MaxBoxes;
+ BoxPtr pextent, pboxClipped, pboxClippedBase;
+
+ MaxBoxes = infoRec->PreAllocSize/sizeof(BoxRec);
+ pboxClippedBase = (BoxPtr)infoRec->PreAllocMem;
+ pboxClipped = pboxClippedBase;
+
+ if (REGION_NUM_RECTS(pGC->pCompositeClip) == 1) {
+ pextent = REGION_RECTS(pGC->pCompositeClip);
+ while (nrectFill--) {
+ pboxClipped->x1 = max(pextent->x1, prect->x);
+ pboxClipped->y1 = max(pextent->y1, prect->y);
+
+ Right = (int)prect->x + (int)prect->width;
+ pboxClipped->x2 = min(pextent->x2, Right);
+
+ Bottom = (int)prect->y + (int)prect->height;
+ pboxClipped->y2 = min(pextent->y2, Bottom);
+
+ prect++;
+ if ((pboxClipped->x1 < pboxClipped->x2) &&
+ (pboxClipped->y1 < pboxClipped->y2)) {
+ pboxClipped++;
+ if(pboxClipped >= (pboxClippedBase + MaxBoxes)) {
+ (*BoxFunc)(pGC, MaxBoxes, pboxClippedBase, xorg, yorg);
+ pboxClipped = pboxClippedBase;
+ }
+ }
+ }
+ } else {
+ pextent = REGION_EXTENTS(pGC->pScreen, pGC->pCompositeClip);
+ while (nrectFill--) {
+ int n;
+ BoxRec box, *pbox;
+
+ box.x1 = max(pextent->x1, prect->x);
+ box.y1 = max(pextent->y1, prect->y);
+
+ Right = (int)prect->x + (int)prect->width;
+ box.x2 = min(pextent->x2, Right);
+
+ Bottom = (int)prect->y + (int)prect->height;
+ box.y2 = min(pextent->y2, Bottom);
+
+ prect++;
+
+ if ((box.x1 >= box.x2) || (box.y1 >= box.y2))
+ continue;
+
+ n = REGION_NUM_RECTS (pGC->pCompositeClip);
+ pbox = REGION_RECTS(pGC->pCompositeClip);
+
+ /* clip the rectangle to each box in the clip region
+ this is logically equivalent to calling Intersect()
+ */
+ while(n--) {
+ pboxClipped->x1 = max(box.x1, pbox->x1);
+ pboxClipped->y1 = max(box.y1, pbox->y1);
+ pboxClipped->x2 = min(box.x2, pbox->x2);
+ pboxClipped->y2 = min(box.y2, pbox->y2);
+ pbox++;
+
+ /* see if clipping left anything */
+ if(pboxClipped->x1 < pboxClipped->x2 &&
+ pboxClipped->y1 < pboxClipped->y2) {
+ pboxClipped++;
+ if(pboxClipped >= (pboxClippedBase + MaxBoxes)) {
+ (*BoxFunc)(pGC, MaxBoxes, pboxClippedBase, xorg, yorg);
+ pboxClipped = pboxClippedBase;
+ }
+ }
+ }
+ }
+ }
+
+ if(pboxClipped != pboxClippedBase)
+ (*BoxFunc)(pGC, pboxClipped - pboxClippedBase, pboxClippedBase,
+ xorg, yorg);
+}
+
+
+int
+XAAGetRectClipBoxes(
+ RegionPtr prgnClip,
+ BoxPtr pboxClippedBase,
+ int nrectFill,
+ xRectangle *prectInit
+){
+ int Right, Bottom;
+ BoxPtr pextent, pboxClipped = pboxClippedBase;
+ xRectangle *prect = prectInit;
+
+
+ if (REGION_NUM_RECTS(prgnClip) == 1) {
+ pextent = REGION_RECTS(prgnClip);
+ while (nrectFill--) {
+ pboxClipped->x1 = max(pextent->x1, prect->x);
+ pboxClipped->y1 = max(pextent->y1, prect->y);
+
+ Right = (int)prect->x + (int)prect->width;
+ pboxClipped->x2 = min(pextent->x2, Right);
+
+ Bottom = (int)prect->y + (int)prect->height;
+ pboxClipped->y2 = min(pextent->y2, Bottom);
+
+ prect++;
+ if ((pboxClipped->x1 < pboxClipped->x2) &&
+ (pboxClipped->y1 < pboxClipped->y2)) {
+ pboxClipped++;
+ }
+ }
+ } else {
+ pextent = REGION_EXTENTS(pGC->pScreen, prgnClip);
+ while (nrectFill--) {
+ int n;
+ BoxRec box, *pbox;
+
+ box.x1 = max(pextent->x1, prect->x);
+ box.y1 = max(pextent->y1, prect->y);
+
+ Right = (int)prect->x + (int)prect->width;
+ box.x2 = min(pextent->x2, Right);
+
+ Bottom = (int)prect->y + (int)prect->height;
+ box.y2 = min(pextent->y2, Bottom);
+
+ prect++;
+
+ if ((box.x1 >= box.x2) || (box.y1 >= box.y2))
+ continue;
+
+ n = REGION_NUM_RECTS (prgnClip);
+ pbox = REGION_RECTS(prgnClip);
+
+ /* clip the rectangle to each box in the clip region
+ this is logically equivalent to calling Intersect()
+ */
+ while(n--) {
+ pboxClipped->x1 = max(box.x1, pbox->x1);
+ pboxClipped->y1 = max(box.y1, pbox->y1);
+ pboxClipped->x2 = min(box.x2, pbox->x2);
+ pboxClipped->y2 = min(box.y2, pbox->y2);
+ pbox++;
+
+ /* see if clipping left anything */
+ if(pboxClipped->x1 < pboxClipped->x2 &&
+ pboxClipped->y1 < pboxClipped->y2) {
+ pboxClipped++;
+ }
+ }
+ }
+ }
+
+ return(pboxClipped - pboxClippedBase);
+}
+