diff options
Diffstat (limited to 'xc/programs/Xserver/hw/xfree86/accel/mach32/mach32frect.c')
-rw-r--r-- | xc/programs/Xserver/hw/xfree86/accel/mach32/mach32frect.c | 386 |
1 files changed, 386 insertions, 0 deletions
diff --git a/xc/programs/Xserver/hw/xfree86/accel/mach32/mach32frect.c b/xc/programs/Xserver/hw/xfree86/accel/mach32/mach32frect.c new file mode 100644 index 000000000..2942536ad --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/accel/mach32/mach32frect.c @@ -0,0 +1,386 @@ +/* $XConsortium$ */ +/* + * Fill rectangles. + */ + +/* +Copyright 1989 by the Massachusetts Institute of Technology +Copyright 1993 by Kevin E. Martin, Chapel Hill, North Carolina. + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of M.I.T. not be used in +advertising or publicity pertaining to distribution of the software +without specific, written prior permission. M.I.T. makes no +representations about the suitability of this software for any +purpose. It is provided "as is" without express or implied warranty. + +Modified for the 8514/A by Kevin E. Martin (martin@cs.unc.edu) + +KEVIN E. MARTIN AND RICKARD E. FAITH DISCLAIM ALL WARRANTIES WITH REGARD TO +THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS, IN NO EVENT SHALL KEVIN E. MARTIN BE LIABLE FOR ANY SPECIAL, +INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. + +Modified for the Mach-8 by Rickard E. Faith (faith@cs.unc.edu) +Modified for the Mach32 by Kevin E. Martin (martin@cs.unc.edu) + +*/ + + +/* $XConsortium: cfbfillrct.c,v 5.13 90/05/15 18:40:19 keith Exp $ */ + +#include "X.h" +#include "Xmd.h" +#include "servermd.h" +#include "gcstruct.h" +#include "window.h" +#include "pixmapstr.h" +#include "scrnintstr.h" +#include "windowstr.h" + +#include "cfb.h" +#include "cfbmskbits.h" +#include "mergerop.h" + +#include "regmach32.h" +#include "mach32.h" + +#define NUM_STACK_RECTS 1024 + +void +mach32PolyFillRect(pDrawable, pGC, nrectFill, prectInit) + DrawablePtr pDrawable; + register GCPtr pGC; + int nrectFill; /* number of rectangles to fill */ + xRectangle *prectInit; /* Pointer to first rectangle to fill */ +{ + xRectangle *prect; + RegionPtr prgnClip; + register BoxPtr pbox; + register BoxPtr pboxClipped; + BoxPtr pboxClippedBase; + BoxPtr pextent; + BoxRec stackRects[NUM_STACK_RECTS]; + cfbPrivGC *priv; + int numRects; + int n; + int xorg, yorg; + int width, height; + PixmapPtr pPix; + int pixWidth; + int xrot, yrot; + + if (!xf86VTSema) + { + cfbPolyFillRect(pDrawable, pGC, nrectFill, prectInit); + return; + } + + priv = (cfbPrivGC *) pGC->devPrivates[cfbGCPrivateIndex].ptr; + prgnClip = priv->pCompositeClip; + + prect = prectInit; + xorg = pDrawable->x; + yorg = pDrawable->y; + if (xorg || yorg) + { + prect = prectInit; + n = nrectFill; + while(n--) + { + prect->x += xorg; + prect->y += yorg; + prect++; + } + } + + prect = prectInit; + + numRects = REGION_NUM_RECTS(prgnClip) * nrectFill; + if (numRects > NUM_STACK_RECTS) + { + pboxClippedBase = (BoxPtr)ALLOCATE_LOCAL(numRects * sizeof(BoxRec)); + if (!pboxClippedBase) + return; + } + else + pboxClippedBase = stackRects; + + pboxClipped = pboxClippedBase; + + if (REGION_NUM_RECTS(prgnClip) == 1) + { + int x1, y1, x2, y2, bx2, by2; + + pextent = REGION_RECTS(prgnClip); + x1 = pextent->x1; + y1 = pextent->y1; + x2 = pextent->x2; + y2 = pextent->y2; + while (nrectFill--) + { + if ((pboxClipped->x1 = prect->x) < x1) + pboxClipped->x1 = x1; + + if ((pboxClipped->y1 = prect->y) < y1) + pboxClipped->y1 = y1; + + bx2 = (int) prect->x + (int) prect->width; + if (bx2 > x2) + bx2 = x2; + pboxClipped->x2 = bx2; + + by2 = (int) prect->y + (int) prect->height; + if (by2 > y2) + by2 = y2; + pboxClipped->y2 = by2; + + prect++; + if ((pboxClipped->x1 < pboxClipped->x2) && + (pboxClipped->y1 < pboxClipped->y2)) + { + pboxClipped++; + } + } + } + else + { + int x1, y1, x2, y2, bx2, by2; + + pextent = (*pGC->pScreen->RegionExtents)(prgnClip); + x1 = pextent->x1; + y1 = pextent->y1; + x2 = pextent->x2; + y2 = pextent->y2; + while (nrectFill--) + { + BoxRec box; + + if ((box.x1 = prect->x) < x1) + box.x1 = x1; + + if ((box.y1 = prect->y) < y1) + box.y1 = y1; + + bx2 = (int) prect->x + (int) prect->width; + if (bx2 > x2) + bx2 = x2; + box.x2 = bx2; + + by2 = (int) prect->y + (int) prect->height; + if (by2 > y2) + by2 = y2; + box.y2 = by2; + + 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++; + } + } + } + } + + if (pboxClipped != pboxClippedBase) { + n = pboxClipped-pboxClippedBase; + switch (pGC->fillStyle) { + case FillSolid: + WaitQueue(3); + outw(FRGD_COLOR, (short)(pGC->fgPixel)); + outw(FRGD_MIX, FSS_FRGDCOL | mach32alu[pGC->alu]); + outw(WRT_MASK, (short)pGC->planemask); + + pboxClipped = pboxClippedBase; + while (n--) { + WaitQueue(5); + outw(CUR_X, (short)(pboxClipped->x1)); + outw(CUR_Y, (short)(pboxClipped->y1)); + outw(MAJ_AXIS_PCNT, + (short)(pboxClipped->x2 - pboxClipped->x1 - 1)); + outw(MULTIFUNC_CNTL, MIN_AXIS_PCNT | + (short)(pboxClipped->y2 - pboxClipped->y1 - 1)); + outw(CMD, CMD_RECT | INC_Y | INC_X | DRAW | PLANAR | WRTDATA); + + pboxClipped++; + } + + WaitQueue(2); + outw(FRGD_MIX, FSS_FRGDCOL | MIX_SRC); + outw(BKGD_MIX, BSS_BKGDCOL | MIX_SRC); + break; + case FillTiled: + xrot = pDrawable->x + pGC->patOrg.x; + yrot = pDrawable->y + pGC->patOrg.y; + + pPix = pGC->tile.pixmap; + width = pPix->drawable.width; + height = pPix->drawable.height; + pixWidth = PixmapBytePad(width, pPix->drawable.depth); + + pboxClipped = pboxClippedBase; +#ifdef PIXPRIV + if (mach32CacheTile(pPix)) { + int w, h; + while (n--) { + w = pboxClipped->x2 - pboxClipped->x1; + h = pboxClipped->y2 - pboxClipped->y1; + if ((w > 9) || (h > 9)) + mach32CImageFill(pPix->slot, + pboxClipped->x1, pboxClipped->y1, + w, h, + xrot, yrot, + mach32alu[pGC->alu], pGC->planemask); + else + (mach32ImageFillFunc)(pboxClipped->x1, pboxClipped->y1, + w, h, + pPix->devPrivate.ptr, pixWidth, + width, height, xrot, yrot, + mach32alu[pGC->alu], pGC->planemask); + pboxClipped++; + } + } else +#endif + { + while (n--) { + (mach32ImageFillFunc)(pboxClipped->x1, pboxClipped->y1, + pboxClipped->x2 - pboxClipped->x1, + pboxClipped->y2 - pboxClipped->y1, + pPix->devPrivate.ptr, pixWidth, + width, height, xrot, yrot, + mach32alu[pGC->alu], pGC->planemask); + pboxClipped++; + } + } + break; + case FillStippled: + xrot = pDrawable->x + pGC->patOrg.x; + yrot = pDrawable->y + pGC->patOrg.y; + + pPix = pGC->stipple; + width = pPix->drawable.width; + height = pPix->drawable.height; + pixWidth = PixmapBytePad(width, pPix->drawable.depth); + + pboxClipped = pboxClippedBase; +#ifdef PIXPRIV + if (mach32CacheStipple(pPix)) { + int w, h; + while (n--) { + w = pboxClipped->x2 - pboxClipped->x1; + h = pboxClipped->y2 - pboxClipped->y1; + if ((w > 9) || (h > 9)) + mach32CImageStipple(pPix->slot, + pboxClipped->x1, pboxClipped->y1, + w, h, + xrot, yrot, pGC->fgPixel, + mach32alu[pGC->alu], + pGC->planemask); + else + mach32ImageStipple(pboxClipped->x1, pboxClipped->y1, + w, h, + pPix->devPrivate.ptr, pixWidth, + width, height, xrot, yrot, + pGC->fgPixel, + mach32alu[pGC->alu], + pGC->planemask); + pboxClipped++; + } + } else +#endif + { + while (n--) { + mach32ImageStipple(pboxClipped->x1, pboxClipped->y1, + pboxClipped->x2 - pboxClipped->x1, + pboxClipped->y2 - pboxClipped->y1, + pPix->devPrivate.ptr, pixWidth, + width, height, xrot, yrot, + pGC->fgPixel, + mach32alu[pGC->alu], pGC->planemask); + pboxClipped++; + } + } + break; + case FillOpaqueStippled: + xrot = pDrawable->x + pGC->patOrg.x; + yrot = pDrawable->y + pGC->patOrg.y; + + pPix = pGC->stipple; + width = pPix->drawable.width; + height = pPix->drawable.height; + pixWidth = PixmapBytePad(width, pPix->drawable.depth); + + pboxClipped = pboxClippedBase; +#ifdef PIXPRIV + if (mach32CacheOpStipple(pPix)) { + int w, h; + while (n--) { + w = pboxClipped->x2 - pboxClipped->x1; + h = pboxClipped->y2 - pboxClipped->y1; + if ((w > 9) || (h > 9)) + mach32CImageOpStipple(pPix->slot, + pboxClipped->x1, pboxClipped->y1, + w, h, + xrot, yrot, + pGC->fgPixel, pGC->bgPixel, + mach32alu[pGC->alu], + pGC->planemask); + else + mach32ImageOpStipple(pboxClipped->x1, pboxClipped->y1, + w, h, + pPix->devPrivate.ptr, pixWidth, + width, height, + xrot, yrot, + pGC->fgPixel, pGC->bgPixel, + mach32alu[pGC->alu], + pGC->planemask); + pboxClipped++; + } + } else +#endif + { + while (n--) { + mach32ImageOpStipple(pboxClipped->x1, pboxClipped->y1, + pboxClipped->x2 - pboxClipped->x1, + pboxClipped->y2 - pboxClipped->y1, + pPix->devPrivate.ptr, pixWidth, + width, height, xrot, yrot, + pGC->fgPixel, pGC->bgPixel, + mach32alu[pGC->alu], + pGC->planemask); + pboxClipped++; + } + } + break; + } + } + if (pboxClippedBase != stackRects) + DEALLOCATE_LOCAL(pboxClippedBase); + + WaitIdleEmpty(); /* Make sure that all commands have finished */ +} |