/* Wheee, circles... */
static void
CreatorFillEllipseSolid(DrawablePtr pDrawable, GCPtr pGC, xArc *arc)
{
	WindowPtr pWin = (WindowPtr) pDrawable;
	FFBPtr pFfb = GET_FFB_FROM_SCREEN(pDrawable->pScreen);
	CreatorPrivGCPtr gcPriv = CreatorGetGCPrivate (pGC);
	ffb_fbcPtr ffb = pFfb->regs;
	miFillArcRec info;
	int x, y, e, yk, xk, ym, xm, dx, dy, xorg, yorg, slw;

	/* Get the RP ready. */
	if(gcPriv->stipple == NULL) {
		FFB_ATTR_GC(pFfb, pGC, pWin,
			    FFB_PPC_APE_DISABLE | FFB_PPC_CS_CONST,
			    FFB_DRAWOP_RECTANGLE);
	} 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, FFB_DRAWOP_RECTANGLE);
		fbc = FFB_FBC_WIN(pWin);
		fbc = (fbc & ~FFB_FBC_XE_MASK) | FFB_FBC_XE_OFF;
		FFB_WRITE_FBC(pFfb, ffb, fbc);
	}

	/* Start computing the rects. */
	miFillArcSetup(arc, &info);
	MIFILLARCSETUP();
	if(pGC->miTranslate) {
		xorg += pDrawable->x;
		yorg += pDrawable->y;
	}
	while(y > 0) {
		MIFILLARCSTEP(slw);
		if(slw > 0) {
			/* Render. */
			FFBFifo(pFfb, 4);
			FFB_WRITE64(&ffb->by, yorg - y, xorg - x);
			FFB_WRITE64_2(&ffb->bh, 1, slw);
			if(miFillArcLower(slw)) {
				FFBFifo(pFfb, 4);
				FFB_WRITE64(&ffb->by, yorg + y + dy, xorg - x);
				FFB_WRITE64_2(&ffb->bh, 1, slw);
			}
		}
	}
	pFfb->rp_active = 1;
	FFBSync(pFfb, ffb);
}
示例#2
0
static void FFB_BlitRect(ScrnInfoPtr pScrn, int srcx, int srcy,
			 int w, int h, int dstx, int dsty)
{
	FFBPtr pFfb = GET_FFB_FROM_SCRN(pScrn);
	ffb_fbcPtr ffb = pFfb->regs;

	if (!pFfb->disable_vscroll &&
	    dstx == srcx &&
	    dsty != dsty) {
		FFB_WRITE_ATTRIBUTES_VSCROLL(pFfb, 0x00ffffff);
		FFBFifo(pFfb, 7);
		ffb->drawop = FFB_DRAWOP_VSCROLL;
		FFB_WRITE64(&ffb->by, srcy, srcx);
		FFB_WRITE64_2(&ffb->dy, dsty, dstx);
		FFB_WRITE64_3(&ffb->bh, h, w);
		pFfb->rp_active = 1;
	} else {
		unsigned char *base = (unsigned char *)pFfb->fb;
		int use_prefetch = pFfb->use_blkread_prefetch;

		FFB_WRITE_ATTRIBUTES_SFB_VAR(pFfb, 0x00ffffff, GXcopy);
		FFBWait(pFfb, ffb);
		if (use_prefetch) {
			FFBFifo(pFfb, 1);
			ffb->mer = FFB_MER_EIRA;
			pFfb->rp_active = 1;
			FFBWait(pFfb, ffb);
		}
		if (srcx < dstx) {
			VISmoveImageRL((base +
					((srcy + h - 1) * (2048 * 4)) +
					(srcx * (32 / 8))),
				       (base +
					((dsty + h - 1) * (2048 * 4)) +
					(dstx * (32 / 8))),
				       (w * (32 / 8)),
				       h,
				       -(2048 * 4), - (2048 * 4));
		} else {
			VISmoveImageLR((base +
					((srcy + h - 1) * (2048 * 4)) +
					(srcx * (32 / 8))),
				       (base +
					((dsty + h - 1) * (2048 * 4)) +
					(dstx * (32 / 8))),
				       (w * (32 / 8)),
				       h,
				       -(2048 * 4), - (2048 * 4));
		}
		if (use_prefetch) {
			FFBFifo(pFfb, 1);
			ffb->mer = FFB_MER_DRA;
			pFfb->rp_active = 1;
			FFBWait(pFfb, pFfb->regs);
		}
	}
}
示例#3
0
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 {
		/* No reason to optimize the non-brline bug case since
		 * we have to write the line pattern register each loop
		 * anyways.
		 */
		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);
}
示例#4
0
void
CreatorDoHWBitblt(DrawablePtr pSrc, DrawablePtr pDst, int alu, RegionPtr prgnDst,
		  DDXPointPtr pptSrc, unsigned long planemask)
{
	FFBPtr pFfb = GET_FFB_FROM_SCREEN (pSrc->pScreen);
	ffb_fbcPtr ffb = pFfb->regs;
	BoxPtr pboxTmp;
	DDXPointPtr pptTmp;
	int nbox;
	BoxPtr pboxNext, pboxBase, pbox;

	nbox = REGION_NUM_RECTS(prgnDst);
	pbox = REGION_RECTS(prgnDst);

	FFB_WRITE_ATTRIBUTES(pFfb,
			     FFB_PPC_ACE_DISABLE|FFB_PPC_APE_DISABLE|FFB_PPC_CS_CONST,
			     FFB_PPC_ACE_MASK|FFB_PPC_APE_MASK|FFB_PPC_CS_MASK,
			     planemask,
			     FFB_ROP_NEW,
			     FFB_DRAWOP_BCOPY, pFfb->fg_cache,
			     FFB_FBC_DEFAULT);
	
	/* need to blit rectangles in different orders, depending on the direction of copy
           so that an area isnt overwritten before it is blitted */
	if (pptSrc->y < pbox->y1 && nbox > 1) {
		if (pptSrc->x < pbox->x1) {
			pboxTmp = pbox + nbox;
			pptTmp = pptSrc + nbox;
			while(nbox--) {
				pboxTmp--;
				pptTmp--;
				FFBFifo(pFfb, 6);
				FFB_WRITE64(&ffb->by, pptTmp->y, pptTmp->x);
				FFB_WRITE64_2(&ffb->dy, pboxTmp->y1, pboxTmp->x1);
				FFB_WRITE64_3(&ffb->bh,
					      (pboxTmp->y2 - pboxTmp->y1),
					      (pboxTmp->x2 - pboxTmp->x1));
			}
		} else {
			/* keep ordering in each band, reverse order of bands */
			pboxBase = pboxNext = pbox+nbox-1;
			
			while (pboxBase >= pbox) { /* for each band */
				/* find first box in band */
				while (pboxNext >= pbox && pboxBase->y1 == pboxNext->y1)
					pboxNext--;
		
				pboxTmp = pboxNext + 1;			/* first box in band */
				pptTmp = pptSrc + (pboxTmp - pbox);	/* first point in band */
		
				while (pboxTmp <= pboxBase) { /* for each box in band */
					FFBFifo(pFfb, 6);
					FFB_WRITE64(&ffb->by, pptTmp->y, pptTmp->x);
					FFB_WRITE64_2(&ffb->dy, pboxTmp->y1, pboxTmp->x1);
					FFB_WRITE64_3(&ffb->bh,
						      (pboxTmp->y2 - pboxTmp->y1),
						      (pboxTmp->x2 - pboxTmp->x1));
					++pboxTmp;
					++pptTmp;	
				}
				pboxBase = pboxNext;
			}
		}
	} else {
		if((pptSrc->x < pbox->x1) && (nbox > 1)) {
			pboxBase = pboxNext = pbox;
			while(pboxBase < pbox+nbox) {
				while((pboxNext<pbox+nbox) &&
				      (pboxNext->y1 == pboxBase->y1))
					pboxNext++;
				pboxTmp = pboxNext;
				pptTmp = pptSrc + (pboxTmp - pbox);
				while(pboxTmp != pboxBase) {
					--pboxTmp;
					--pptTmp;
					FFBFifo(pFfb, 6);
					FFB_WRITE64(&ffb->by, pptTmp->y, pptTmp->x);
					FFB_WRITE64_2(&ffb->dy, pboxTmp->y1, pboxTmp->x1);
					FFB_WRITE64_3(&ffb->bh,
						      (pboxTmp->y2 - pboxTmp->y1),
						      (pboxTmp->x2 - pboxTmp->x1));
				}
				pboxBase = pboxNext;
			}
		} else {
			/* dont need to change order of anything */
			pptTmp = pptSrc;
			pboxTmp = pbox;
	    
			while (nbox--) {
				FFBFifo(pFfb, 6);
				FFB_WRITE64(&ffb->by, pptTmp->y, pptTmp->x);
				FFB_WRITE64_2(&ffb->dy, pboxTmp->y1, pboxTmp->x1);
				FFB_WRITE64_3(&ffb->bh,
					      (pboxTmp->y2 - pboxTmp->y1),
					      (pboxTmp->x2 - pboxTmp->x1));
				pboxTmp++;
				pptTmp++;
			}
		}
	}
	pFfb->rp_active = 1;
	FFBSync(pFfb, ffb);
}
示例#5
0
/* We know here that only y is changing and that the hw attributes
 * have been set higher up in the call chain.
 */
void
CreatorDoVertBitblt(DrawablePtr pSrc, DrawablePtr pDst, int alu, RegionPtr prgnDst,
		    DDXPointPtr pptSrc, unsigned long planemask)
{
	FFBPtr pFfb = GET_FFB_FROM_SCREEN (pSrc->pScreen);
	ffb_fbcPtr ffb = pFfb->regs;
	BoxPtr pbox;
	int nbox;

	pbox = REGION_RECTS(prgnDst);
	nbox = REGION_NUM_RECTS(prgnDst);

	/* No garbage please. */
	if(nbox <= 0)
		return;

	FFBLOG(("VSCROLL(%d): ", nbox));

	/* Need to blit rectangles in different orders, depending
	 * on the direction of copy so that an area isnt overwritten
	 * before it is blitted.
	 */
	if (nbox > 1 && pptSrc->y < pbox->y1) {
		BoxPtr pboxBase = pbox + nbox - 1;
		BoxPtr pboxNext = pboxBase;

		/* Keep ordering in each band, reverse order of bands. */
		while (pboxBase >= pbox) { /* for each band */
			BoxPtr pboxTmp;
			DDXPointPtr pptTmp;

			/* find first box in band */
			while (pboxNext >= pbox && pboxBase->y1 == pboxNext->y1)
				pboxNext--;
		
			pboxTmp = pboxNext + 1;			/* first box in band */
			pptTmp = pptSrc + (pboxTmp - pbox);	/* first point in band */
			while (pboxTmp <= pboxBase) {
				FFBLOG(("1[%08x:%08x:%08x:%08x:%08x:%08x] ",
					pptTmp->x, pptTmp->y, pboxTmp->x1, pboxTmp->y1,
					pboxTmp->x2, pboxTmp->y2));
				FFBFifo(pFfb, 7);
				ffb->drawop = FFB_DRAWOP_VSCROLL;
				FFB_WRITE64(&ffb->by, pptTmp->y, pptTmp->x);
				FFB_WRITE64_2(&ffb->dy, pboxTmp->y1, pboxTmp->x1);
				FFB_WRITE64_3(&ffb->bh, (pboxTmp->y2 - pboxTmp->y1),
					      (pboxTmp->x2 - pboxTmp->x1));
				pboxTmp++;
				pptTmp++;
			}
			pboxBase = pboxNext;
		}
	} else {
		/* Dont need to change order of anything. */
		while (nbox--) {
			FFBLOG(("2[%08x:%08x:%08x:%08x:%08x:%08x] ",
				pptSrc->x, pptSrc->y, pbox->x1, pbox->y1,
				pbox->x2, pbox->y2));
			FFBFifo(pFfb, 7);
			ffb->drawop = FFB_DRAWOP_VSCROLL;
			FFB_WRITE64(&ffb->by, pptSrc->y, pptSrc->x);
			FFB_WRITE64_2(&ffb->dy, pbox->y1, pbox->x1);
			FFB_WRITE64_3(&ffb->bh, (pbox->y2 - pbox->y1),
				      (pbox->x2 - pbox->x1));
			pbox++;
			pptSrc++;
		}
	}
	pFfb->rp_active = 1;
	FFBLOG(("done\n"));
	FFBSync(pFfb, ffb);
}