#include "ffb.h"
#include "ffb_regs.h"
#include "ffb_rcache.h"
#include "ffb_fifo.h"
#include "ffb_loops.h"
#include "ffb_stip.h"
#include "pixmapstr.h"
#include "scrnintstr.h"
#define PSZ 8
#include "cfb.h"
#undef PSZ
#include "cfb32.h"
#include "miline.h"
#define SEG_DRAWOP(__pgc) ((__pgc)->capStyle == CapNotLast ? \
FFB_DRAWOP_BRLINEOPEN : \
FFB_DRAWOP_BRLINECAP)
static void
ReloadSegmentAttrs(FFBPtr pFfb, CreatorPrivGCPtr gcPriv, GCPtr pGC, WindowPtr pWin)
{
if(gcPriv->stipple == NULL) {
FFB_ATTR_GC(pFfb, pGC, pWin,
FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST,
SEG_DRAWOP(pGC));
} else {
ffb_fbcPtr ffb = pFfb->regs;
unsigned int fbc;
FFBSetStipple(pFfb, ffb, gcPriv->stipple,
FFB_PPC_CS_CONST, FFB_PPC_CS_MASK);
FFB_WRITE_PMASK(pFfb, ffb, pGC->planemask);
FFB_WRITE_DRAWOP(pFfb, ffb, SEG_DRAWOP(pGC));
fbc = FFB_FBC_WIN(pWin);
fbc = (fbc & ~FFB_FBC_XE_MASK) | FFB_FBC_XE_OFF;
FFB_WRITE_FBC(pFfb, ffb, fbc);
}
}
void
CreatorPolySegment (DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment *pSeg)
{
WindowPtr pWin = (WindowPtr) pDrawable;
CreatorPrivGCPtr gcPriv = CreatorGetGCPrivate (pGC);
FFBPtr pFfb = GET_FFB_FROM_SCREEN (pGC->pScreen);
ffb_fbcPtr ffb = pFfb->regs;
BoxPtr extent;
int xorg, yorg, lpat;
if (nseg == 0)
return;
FFBLOG(("CreatorPolySegment: ALU(%x) PMSK(%08x) nseg(%d) lpat(%08x)\n",
pGC->alu, pGC->planemask, nseg, gcPriv->linepat));
if (gcPriv->stipple == NULL) {
FFB_ATTR_GC(pFfb, pGC, pWin,
FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST,
SEG_DRAWOP(pGC));
} else {
unsigned int fbc;
FFBSetStipple(pFfb, ffb, gcPriv->stipple,
FFB_PPC_CS_CONST, FFB_PPC_CS_MASK);
FFB_WRITE_PMASK(pFfb, ffb, pGC->planemask);
FFB_WRITE_DRAWOP(pFfb, ffb, SEG_DRAWOP(pGC));
fbc = FFB_FBC_WIN(pWin);
fbc = (fbc & ~FFB_FBC_XE_MASK) | FFB_FBC_XE_OFF;
FFB_WRITE_FBC(pFfb, ffb, fbc);
}
pFfb->rp_active = 1;
xorg = pDrawable->x;
yorg = pDrawable->y;
extent = REGION_RECTS(cfbGetCompositeClip(pGC));
lpat = gcPriv->linepat;
if (lpat == 0) {
FFBFifo(pFfb, 1);
ffb->lpat = 0;
if (pFfb->has_brline_bug) {
while (nseg--) {
register int x1 = pSeg->x1 + xorg;
register int y1 = pSeg->y1 + yorg;
register int x2 = pSeg->x2 + xorg;
register int y2 = pSeg->y2 + yorg;
if (x1 >= extent->x1 &&
x2 >= extent->x1 &&
x1 < extent->x2 &&
x2 < extent->x2 &&
y1 >= extent->y1 &&
y2 >= extent->y1 &&
y1 < extent->y2 &&
y2 < extent->y2) {
FFBFifo(pFfb, 5);
ffb->ppc = 0;
FFB_WRITE64(&ffb->by, y1, x1);
FFB_WRITE64_2(&ffb->bh, y2, x2);
} else {
gcPriv->PolySegment(pDrawable, pGC, 1, pSeg);
ReloadSegmentAttrs(pFfb, gcPriv, pGC, pWin);
pFfb->rp_active = 1;
}
pSeg++;
}
} else {
while (nseg--) {
register int x1 = pSeg->x1 + xorg;
register int y1 = pSeg->y1 + yorg;
register int x2 = pSeg->x2 + xorg;
register int y2 = pSeg->y2 + yorg;
if (x1 >= extent->x1 &&
x2 >= extent->x1 &&
x1 < extent->x2 &&
x2 < extent->x2 &&
y1 >= extent->y1 &&
y2 >= extent->y1 &&
y1 < extent->y2 &&
y2 < extent->y2) {
FFBFifo(pFfb, 4);
FFB_WRITE64(&ffb->by, y1, x1);
FFB_WRITE64_2(&ffb->bh, y2, x2);
} else {
gcPriv->PolySegment(pDrawable, pGC, 1, pSeg);
ReloadSegmentAttrs(pFfb, gcPriv, pGC, pWin);
pFfb->rp_active = 1;
}
pSeg++;
}
}
} else {
while (nseg--) {
register int x1 = pSeg->x1 + xorg;
register int y1 = pSeg->y1 + yorg;
register int x2 = pSeg->x2 + xorg;
register int y2 = pSeg->y2 + yorg;
if (x1 >= extent->x1 && x2 >= extent->x1 &&
x1 < extent->x2 && x2 < extent->x2 &&
y1 >= extent->y1 && y2 >= extent->y1 &&
y1 < extent->y2 && y2 < extent->y2) {
FFBFifo(pFfb, 5);
ffb->lpat = lpat;
FFB_WRITE64(&ffb->by, y1, x1);
FFB_WRITE64_2(&ffb->bh, y2, x2);
} else {
gcPriv->PolySegment(pDrawable, pGC, 1, pSeg);
ReloadSegmentAttrs(pFfb, gcPriv, pGC, pWin);
pFfb->rp_active = 1;
}
pSeg++;
}
}
FFBSync(pFfb, ffb);
}