#include "ffb.h"
#include "ffb_regs.h"
#include "ffb_rcache.h"
#include "ffb_fifo.h"
#include "pixmapstr.h"
#include "scrnintstr.h"
#define PSZ 8
#include "cfb.h"
#undef PSZ
#include "cfb32.h"
static void
CreatorSetScanline(int y, int xOrigin, int xStart, int xEnd,
unsigned int *_psrc, char *sfb, int depth)
{
if (depth == 8) {
unsigned char *psrc = (unsigned char *)_psrc;
unsigned char *pdst = (unsigned char *)(sfb +
(y << 11) +
(xStart << 0));
int w = xEnd - xStart;
psrc += (xStart - xOrigin);
while(w--)
*pdst++ = *psrc++;
} else {
unsigned int *psrc = (unsigned int *)_psrc;
unsigned int *pdst = (unsigned int *)(sfb +
(y << 13) +
(xStart << 2));
int w = xEnd - xStart;
psrc += (xStart - xOrigin);
while(w--)
*pdst++ = *psrc++;
}
}
void
CreatorSetSpans(DrawablePtr pDrawable, GCPtr pGC, char *pcharsrc,
DDXPointPtr ppt, int *pwidth, int nspans, int fSorted)
{
WindowPtr pWin = (WindowPtr) pDrawable;
FFBPtr pFfb = GET_FFB_FROM_SCREEN (pDrawable->pScreen);
ffb_fbcPtr ffb = pFfb->regs;
unsigned int *psrc = (unsigned int *)pcharsrc;
BoxPtr pbox, pboxLast, pboxTest;
DDXPointPtr pptLast;
RegionPtr prgnDst;
char *addrp;
int xStart, xEnd, yMax;
if(pDrawable->type != DRAWABLE_WINDOW) {
if (pDrawable->bitsPerPixel == 8)
cfbSetSpans(pDrawable, pGC, pcharsrc, ppt,
pwidth, nspans, fSorted);
else
cfb32SetSpans(pDrawable, pGC, pcharsrc, ppt,
pwidth, nspans, fSorted);
return;
}
FFBLOG(("CreatorSetSpans: ALU(%x) PMSK(%08x) nspans(%d) fsorted(%d)\n",
pGC->alu, pGC->planemask, nspans, fSorted));
if (pGC->alu == GXnoop)
return;
FFB_ATTR_SFB_VAR_WIN(pFfb, pGC->planemask, pGC->alu, pWin);
FFBWait(pFfb, ffb);
if (pGC->depth == 8)
addrp = (char *) pFfb->sfb8r;
else
addrp = (char *) pFfb->sfb32;
yMax = (int) pDrawable->y + (int) pDrawable->height;
prgnDst = cfbGetCompositeClip(pGC);
pbox = REGION_RECTS(prgnDst);
pboxLast = pbox + REGION_NUM_RECTS(prgnDst);
pptLast = ppt + nspans;
if(fSorted) {
pboxTest = pbox;
while(ppt < pptLast) {
pbox = pboxTest;
if(ppt->y >= yMax)
break;
while(pbox < pboxLast) {
if(pbox->y1 > ppt->y) {
break;
} else if(pbox->y2 <= ppt->y) {
pboxTest = ++pbox;
continue;
} else if(pbox->x1 > ppt->x + *pwidth) {
break;
} else if(pbox->x2 <= ppt->x) {
pbox++;
continue;
}
xStart = max(pbox->x1, ppt->x);
xEnd = min(ppt->x + *pwidth, pbox->x2);
CreatorSetScanline(ppt->y, ppt->x, xStart, xEnd,
psrc, addrp, pGC->depth);
if(ppt->x + *pwidth <= pbox->x2)
break;
else
pbox++;
}
ppt++;
psrc += *pwidth++;
}
} else {
while(ppt < pptLast) {
if(ppt->y >= 0 && ppt->y < yMax) {
for(pbox = REGION_RECTS(prgnDst); pbox < pboxLast; pbox++) {
if(pbox->y1 > ppt->y) {
break;
} else if(pbox->y2 <= ppt->y) {
pbox++;
break;
}
if(pbox->x1 <= ppt->x + *pwidth &&
pbox->x2 > ppt->x) {
xStart = max(pbox->x1, ppt->x);
xEnd = min(pbox->x2, ppt->x + *pwidth);
CreatorSetScanline(ppt->y, ppt->x,
xStart, xEnd,
psrc, addrp, pGC->depth);
}
}
}
ppt++;
psrc += *pwidth++;
}
}
}