diff options
Diffstat (limited to 'src/ffb_rect.c')
-rw-r--r-- | src/ffb_rect.c | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/src/ffb_rect.c b/src/ffb_rect.c new file mode 100644 index 0000000..30ef015 --- /dev/null +++ b/src/ffb_rect.c @@ -0,0 +1,207 @@ +/* + * Acceleration for the Creator and Creator3D framebuffer - Non-filled rects. + * + * Copyright (C) 1999 David S. Miller (davem@redhat.com) + * Copyright (C) 1999 Jakub Jelinek (jakub@redhat.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * DAVID MILLER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sunffb/ffb_rect.c,v 1.2 2000/05/23 04:47:45 dawes Exp $ */ + +#define PSZ 32 + +#include "ffb.h" +#include "ffb_regs.h" +#include "ffb_rcache.h" +#include "ffb_fifo.h" +#include "ffb_loops.h" +#include "ffb_clip.h" + +#include "pixmapstr.h" +#include "scrnintstr.h" + +#include "cfb.h" + +#error If we start using this again, need to fixup FFB_WRITE_ATTRIBUTES for wids -DaveM + +/* Heavily derived from mipolyrect.c code, see there for authors. */ + +/* This about it, capping makes not a single difference ever, + * always the upper left corner coordinate will be pixelated. + */ +void +CreatorPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, + int nrects, xRectangle *pRects) +{ + FFBPtr pFfb = GET_FFB_FROM_SCREEN (pDrawable->pScreen); + CreatorPrivGCPtr gcPriv = CreatorGetGCPrivate (pGC); + ffb_fbcPtr ffb = pFfb->regs; + xRectangle *pR = pRects; + RegionPtr clip; + unsigned int ppc, line_drawop; + int bound_tmp, i, numRects; + + if(nrects <= 0) + return; + clip = ((cfbPrivGC *)(pGC->devPrivates[cfbGCPrivateIndex].ptr))->pCompositeClip; + numRects = REGION_NUM_RECTS(clip); + if (!numRects) + return; + if(!(ppc = FFBSetClip(pFfb, ffb, clip, numRects))) { + miPolyRectangle(pDrawable, pGC, nrects, pRects); + return; + } + if(pGC->lineStyle == LineDoubleDash) + line_drawop = FFB_DRAWOP_DDLINE; + else + line_drawop = FFB_DRAWOP_BRLINECAP; + if(gcPriv->stipple == NULL) { + FFB_WRITE_ATTRIBUTES(pFfb, + ppc|FFB_PPC_APE_DISABLE|FFB_PPC_TBE_OPAQUE| + FFB_PPC_XS_CONST|FFB_PPC_YS_CONST|FFB_PPC_ZS_CONST|FFB_PPC_CS_CONST, + FFB_PPC_VCE_MASK|FFB_PPC_ACE_MASK|FFB_PPC_APE_MASK|FFB_PPC_TBE_MASK| + FFB_PPC_XS_MASK|FFB_PPC_YS_MASK|FFB_PPC_ZS_MASK|FFB_PPC_CS_MASK, + pGC->planemask, + FFB_ROP_EDIT_BIT|pGC->alu, + -1, pGC->fgPixel, + FFB_FBC_DEFAULT); + if(pGC->lineStyle == LineDoubleDash) + FFB_WRITE_BG(pFfb, ffb, pGC->bgPixel); + } else { + FFBSetStipple(pFfb, ffb, gcPriv->stipple, + ppc| + FFB_PPC_XS_CONST|FFB_PPC_YS_CONST|FFB_PPC_ZS_CONST|FFB_PPC_CS_CONST, + FFB_PPC_VCE_MASK|FFB_PPC_ACE_MASK| + FFB_PPC_XS_MASK|FFB_PPC_YS_MASK|FFB_PPC_ZS_MASK|FFB_PPC_CS_MASK); + FFB_WRITE_PMASK(pFfb, ffb, pGC->planemask); + FFB_WRITE_FBC(pFfb, ffb, FFB_FBC_DEFAULT); + } + +#define MINBOUND(dst,eqn) bound_tmp = eqn; \ + if (bound_tmp < -32768) \ + bound_tmp = -32768; \ + dst = bound_tmp; + +#define MAXBOUND(dst,eqn) bound_tmp = eqn; \ + if (bound_tmp > 32767) \ + bound_tmp = 32767; \ + dst = bound_tmp; + +#define MAXUBOUND(dst,eqn) bound_tmp = eqn; \ + if (bound_tmp > 65535) \ + bound_tmp = 65535; \ + dst = bound_tmp; + + if (pGC->lineStyle == LineSolid && + pGC->joinStyle == JoinMiter && + pGC->lineWidth != 0) { + int ntmp; + int offset1, offset2, offset3; + int x, y, width, height; + int tx, ty, tw, th; + + ntmp = (nrects << 2); + offset2 = pGC->lineWidth; + offset1 = offset2 >> 1; + offset3 = offset2 - offset1; + for (i = 0; i < nrects; i++) { + x = pR->x; + y = pR->y; + width = pR->width; + height = pR->height; + pR++; + if (width == 0 && height == 0) { + FFB_WRITE_DRAWOP(pFfb, ffb, FFB_DRAWOP_DOT); + FFBFifo(pFfb, 2); + FFB_WRITE64(&ffb->bh, y + pDrawable->y, x + pDrawable->x); + continue; + } + FFB_WRITE_DRAWOP(pFfb, ffb, FFB_DRAWOP_RECTANGLE); + if (height < offset2 || width < offset1) { + if (height == 0) { + tx = x; + tw = width; + } else { + MINBOUND (tx, x - offset1); + MAXUBOUND (tw, width + offset2); + } + if (width == 0) { + ty = y; + th = height; + } else { + MINBOUND (ty, y - offset1); + MAXUBOUND (th, height + offset2); + } + FFBFifo(pFfb, 4); + FFB_WRITE64(&ffb->by, ty + pDrawable->y, tx + pDrawable->x); + FFB_WRITE64_2(&ffb->bh, th, tw); + } else { + MINBOUND(tx, x - offset1); + MINBOUND(ty, y - offset1); + MAXUBOUND(tw, width + offset2); + th = offset2; + FFBFifo(pFfb, 13); + FFB_WRITE64(&ffb->by, ty + pDrawable->y, tx + pDrawable->x); + FFB_WRITE64_2(&ffb->bh, th, tw); + MAXBOUND(ty, y + offset3); + tw = offset2; + th = height - offset2; + ffb->by = ty + pDrawable->y; + FFB_WRITE64_2(&ffb->bh, th, tw); + MAXBOUND(tx, x + width - offset1); + ffb->bx = tx + pDrawable->x; + ffb->bw = tw; + MINBOUND(tx, x - offset1); + MAXBOUND(ty, y + height - offset1); + MAXUBOUND(tw, width + offset2); + th = offset2; + FFB_WRITE64(&ffb->by, ty + pDrawable->y, tx + pDrawable->x); + FFB_WRITE64_2(&ffb->bh, th, tw); + } + } + } else { + int xOrg = pDrawable->x; + int yOrg = pDrawable->y; + unsigned int linepat = gcPriv->linepat; + + FFB_WRITE_DRAWOP(pFfb, ffb, line_drawop); + if(linepat == 0) { + FFBFifo(pFfb, 1); + ffb->lpat = 0; + } + for (i=0; i < nrects; i++) { + register int x0, xCoord, y0, yCoord; + + x0 = xCoord = pR->x; + y0 = yCoord = pR->y; + FFBFifo(pFfb, 11); + if(linepat) + ffb->lpat = linepat; + else + ffb->ppc = 0; + FFB_WRITE64(&ffb->by, (yCoord + yOrg), (xCoord + xOrg)); + MAXBOUND(xCoord, pR->x + (int) pR->width); + FFB_WRITE64(&ffb->bh, (yCoord + yOrg), (xCoord + xOrg)); + MAXBOUND(yCoord, pR->y + (int) pR->height); + FFB_WRITE64_2(&ffb->bh, (yCoord + yOrg), (xCoord + xOrg)); + FFB_WRITE64_3(&ffb->bh, (yCoord + yOrg), (x0 + xOrg)); + FFB_WRITE64(&ffb->bh, (y0 + yOrg), (x0 + xOrg)); + pR++; + } + } +} |