2004-02-26 14:36:15 +01:00
|
|
|
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaStipple.c,v 1.12 2003/08/04 22:18:31 mvojkovi Exp $ */
|
2003-11-14 17:48:57 +01:00
|
|
|
|
|
|
|
#include "xaa.h"
|
|
|
|
#include "xaalocal.h"
|
|
|
|
#include "xaacexp.h"
|
|
|
|
#include "xf86.h"
|
|
|
|
#include "xf86_ansic.h"
|
|
|
|
|
|
|
|
static CARD32* StipplePowerOfTwo(CARD32*, CARD32*, int, int, int);
|
|
|
|
static CARD32* StipplePowerOfTwo_Inverted(CARD32*, CARD32*, int, int, int);
|
|
|
|
static CARD32* StippleUpTo32(CARD32*, CARD32*, int, int, int);
|
|
|
|
static CARD32* StippleUpTo32_Inverted(CARD32*, CARD32*, int, int, int);
|
|
|
|
static CARD32* StippleOver32(CARD32*, CARD32*, int, int, int);
|
|
|
|
static CARD32* StippleOver32_Inverted(CARD32*, CARD32*, int, int, int);
|
|
|
|
|
|
|
|
#ifdef TRIPLE_BITS
|
|
|
|
#define stipple_scanline_func EXPNAME(XAAStippleScanlineFunc3)
|
|
|
|
#else
|
|
|
|
#define stipple_scanline_func EXPNAME(XAAStippleScanlineFunc)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
StippleScanlineProcPtr stipple_scanline_func[6] = {
|
|
|
|
StipplePowerOfTwo,
|
|
|
|
StippleUpTo32,
|
|
|
|
StippleOver32,
|
|
|
|
StipplePowerOfTwo_Inverted,
|
|
|
|
StippleUpTo32_Inverted,
|
|
|
|
StippleOver32_Inverted
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef FIXEDBASE
|
|
|
|
# define DEST(i) *dest
|
|
|
|
# define RETURN(i) return(dest)
|
|
|
|
#else
|
|
|
|
# define DEST(i) dest[i]
|
|
|
|
# define RETURN(i) return(dest + i)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
/* TRIPLE_BITS pattern expansion */
|
|
|
|
#ifdef TRIPLE_BITS
|
|
|
|
#define EXPAND_PAT \
|
|
|
|
CARD32 pat1 = byte_expand3[pat & 0xFF], \
|
|
|
|
pat2 = byte_expand3[(pat & 0xFF00) >> 8], \
|
|
|
|
pat3 = byte_expand3[(pat & 0xFF0000) >> 16], \
|
|
|
|
pat4 = byte_expand3[(pat & 0xFF000000) >> 24], \
|
|
|
|
patA = pat1 | (pat2 << 24), \
|
|
|
|
patB = (pat2 >> 8) | (pat3 << 16), \
|
|
|
|
patC = (pat3 >> 16) | (pat4 << 8)
|
|
|
|
#ifdef FIXED_BASE
|
|
|
|
#define WRITE_PAT1 { \
|
|
|
|
*dest = patA; }
|
|
|
|
#define WRITE_PAT2 { \
|
|
|
|
*dest = patA; \
|
|
|
|
*dest = patB; }
|
|
|
|
#define WRITE_PAT3 { \
|
|
|
|
*dest = patA; \
|
|
|
|
*dest = patB; \
|
|
|
|
*dest = patC; }
|
|
|
|
#else
|
|
|
|
#define WRITE_PAT1 { \
|
|
|
|
*(dest++) = patA; }
|
|
|
|
#define WRITE_PAT2 { \
|
|
|
|
*(dest) = patA; \
|
|
|
|
*(dest + 1) = patB; \
|
|
|
|
dest += 2; }
|
|
|
|
#define WRITE_PAT3 { \
|
|
|
|
*(dest) = patA; \
|
|
|
|
*(dest + 1) = patB; \
|
|
|
|
*(dest + 2) = patC; \
|
|
|
|
dest += 3; }
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#if !defined(FIXEDBASE) && !defined(MSBFIRST) && !defined(TRIPLE_BITS)
|
|
|
|
|
|
|
|
unsigned int XAAShiftMasks[32] = {
|
|
|
|
/* gcc is rather pedantic about SHIFT_R(0xFFFFFFFF,32) */
|
|
|
|
0x00000000 , SHIFT_R(0xFFFFFFFF,31),
|
|
|
|
SHIFT_R(0xFFFFFFFF,30), SHIFT_R(0xFFFFFFFF,29),
|
|
|
|
SHIFT_R(0xFFFFFFFF,28), SHIFT_R(0xFFFFFFFF,27),
|
|
|
|
SHIFT_R(0xFFFFFFFF,26), SHIFT_R(0xFFFFFFFF,25),
|
|
|
|
SHIFT_R(0xFFFFFFFF,24), SHIFT_R(0xFFFFFFFF,23),
|
|
|
|
SHIFT_R(0xFFFFFFFF,22), SHIFT_R(0xFFFFFFFF,21),
|
|
|
|
SHIFT_R(0xFFFFFFFF,20), SHIFT_R(0xFFFFFFFF,19),
|
|
|
|
SHIFT_R(0xFFFFFFFF,18), SHIFT_R(0xFFFFFFFF,17),
|
|
|
|
SHIFT_R(0xFFFFFFFF,16), SHIFT_R(0xFFFFFFFF,15),
|
|
|
|
SHIFT_R(0xFFFFFFFF,14), SHIFT_R(0xFFFFFFFF,13),
|
|
|
|
SHIFT_R(0xFFFFFFFF,12), SHIFT_R(0xFFFFFFFF,11),
|
|
|
|
SHIFT_R(0xFFFFFFFF,10), SHIFT_R(0xFFFFFFFF,9),
|
|
|
|
SHIFT_R(0xFFFFFFFF,8), SHIFT_R(0xFFFFFFFF,7),
|
|
|
|
SHIFT_R(0xFFFFFFFF,6), SHIFT_R(0xFFFFFFFF,5),
|
|
|
|
SHIFT_R(0xFFFFFFFF,4), SHIFT_R(0xFFFFFFFF,3),
|
|
|
|
SHIFT_R(0xFFFFFFFF,2), SHIFT_R(0xFFFFFFFF,1)
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void
|
|
|
|
#ifdef TRIPLE_BITS
|
|
|
|
EXPNAME(XAAFillColorExpandRects3)(
|
|
|
|
#else
|
|
|
|
EXPNAME(XAAFillColorExpandRects)(
|
|
|
|
#endif
|
|
|
|
ScrnInfoPtr pScrn,
|
|
|
|
int fg, int bg, int rop,
|
|
|
|
unsigned int planemask,
|
|
|
|
int nBox,
|
|
|
|
BoxPtr pBox,
|
|
|
|
int xorg, int yorg,
|
|
|
|
PixmapPtr pPix
|
|
|
|
){
|
|
|
|
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
|
|
|
|
CARD32 *base;
|
|
|
|
Bool TwoPass = FALSE, FirstPass = TRUE;
|
|
|
|
StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc;
|
|
|
|
int stipplewidth = pPix->drawable.width;
|
|
|
|
int stippleheight = pPix->drawable.height;
|
|
|
|
int srcwidth = pPix->devKind;
|
|
|
|
int dwords, srcy, srcx, funcNo = 2, h;
|
|
|
|
unsigned char *src = (unsigned char*)pPix->devPrivate.ptr;
|
|
|
|
unsigned char *srcp;
|
|
|
|
int flag;
|
|
|
|
|
|
|
|
if(stipplewidth <= 32) {
|
|
|
|
if(stipplewidth & (stipplewidth - 1))
|
|
|
|
funcNo = 1;
|
|
|
|
else
|
|
|
|
funcNo = 0;
|
|
|
|
}
|
|
|
|
StippleFunc = stipple_scanline_func[funcNo];
|
|
|
|
SecondFunc = stipple_scanline_func[funcNo];
|
|
|
|
FirstFunc = stipple_scanline_func[funcNo + 3];
|
|
|
|
|
|
|
|
#ifdef TRIPLE_BITS
|
|
|
|
if((bg == -1) ||
|
|
|
|
(!(infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) &&
|
|
|
|
(!(infoRec->CPUToScreenColorExpandFillFlags & RGB_EQUAL) ||
|
|
|
|
(CHECK_RGB_EQUAL(bg))))) {
|
|
|
|
#else
|
|
|
|
if((bg == -1) ||
|
|
|
|
!(infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
|
|
|
|
#endif
|
|
|
|
/* one pass */
|
|
|
|
} else if((rop == GXcopy) && infoRec->FillSolidRects) {
|
|
|
|
/* one pass but we fill background rects first */
|
|
|
|
(*infoRec->FillSolidRects)(pScrn, bg, rop, planemask, nBox, pBox);
|
|
|
|
bg = -1;
|
|
|
|
} else {
|
|
|
|
/* gotta do two passes */
|
|
|
|
TwoPass = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!TwoPass)
|
|
|
|
(*infoRec->SetupForCPUToScreenColorExpandFill)(
|
|
|
|
pScrn, fg, bg, rop, planemask);
|
|
|
|
|
|
|
|
while(nBox--) {
|
|
|
|
#ifdef TRIPLE_BITS
|
|
|
|
dwords = (3 * (pBox->x2 - pBox->x1) + 31) >> 5;
|
|
|
|
#else
|
|
|
|
dwords = (pBox->x2 - pBox->x1 + 31) >> 5;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
SECOND_PASS:
|
|
|
|
if(TwoPass) {
|
|
|
|
(*infoRec->SetupForCPUToScreenColorExpandFill)(pScrn,
|
|
|
|
(FirstPass) ? bg : fg, -1, rop, planemask);
|
|
|
|
StippleFunc = (FirstPass) ? FirstFunc : SecondFunc;
|
|
|
|
}
|
|
|
|
|
|
|
|
h = pBox->y2 - pBox->y1;
|
|
|
|
flag = (infoRec->CPUToScreenColorExpandFillFlags
|
|
|
|
& CPU_TRANSFER_PAD_QWORD) && ((dwords * h) & 0x01);
|
|
|
|
|
|
|
|
(*infoRec->SubsequentCPUToScreenColorExpandFill)(
|
|
|
|
pScrn, pBox->x1, pBox->y1,
|
|
|
|
pBox->x2 - pBox->x1, h, 0);
|
|
|
|
|
|
|
|
base = (CARD32*)infoRec->ColorExpandBase;
|
|
|
|
|
|
|
|
srcy = (pBox->y1 - yorg) % stippleheight;
|
|
|
|
if(srcy < 0) srcy += stippleheight;
|
|
|
|
srcx = (pBox->x1 - xorg) % stipplewidth;
|
|
|
|
if(srcx < 0) srcx += stipplewidth;
|
|
|
|
|
|
|
|
srcp = (srcwidth * srcy) + src;
|
|
|
|
|
|
|
|
#ifndef FIXEDBASE
|
|
|
|
if((dwords * h) <= infoRec->ColorExpandRange) {
|
|
|
|
while(h--) {
|
|
|
|
base = (*StippleFunc)(
|
|
|
|
base, (CARD32*)srcp, srcx, stipplewidth, dwords);
|
|
|
|
srcy++;
|
|
|
|
srcp += srcwidth;
|
|
|
|
if (srcy >= stippleheight) {
|
|
|
|
srcy = 0;
|
|
|
|
srcp = src;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
#endif
|
|
|
|
while(h--) {
|
|
|
|
(*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords);
|
|
|
|
srcy++;
|
|
|
|
srcp += srcwidth;
|
|
|
|
if (srcy >= stippleheight) {
|
|
|
|
srcy = 0;
|
|
|
|
srcp = src;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (flag) {
|
|
|
|
base = (CARD32*)infoRec->ColorExpandBase;
|
|
|
|
base[0] = 0x00000000;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(TwoPass) {
|
|
|
|
if(FirstPass) {
|
|
|
|
FirstPass = FALSE;
|
|
|
|
goto SECOND_PASS;
|
|
|
|
} else FirstPass = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
pBox++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(infoRec->CPUToScreenColorExpandFillFlags & SYNC_AFTER_COLOR_EXPAND)
|
|
|
|
(*infoRec->Sync)(pScrn);
|
|
|
|
else SET_SYNC_FLAG(infoRec);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
#ifdef TRIPLE_BITS
|
|
|
|
EXPNAME(XAAFillColorExpandSpans3)(
|
|
|
|
#else
|
|
|
|
EXPNAME(XAAFillColorExpandSpans)(
|
|
|
|
#endif
|
|
|
|
ScrnInfoPtr pScrn,
|
|
|
|
int fg, int bg, int rop,
|
|
|
|
unsigned int planemask,
|
|
|
|
int n,
|
|
|
|
DDXPointPtr ppt,
|
|
|
|
int *pwidth,
|
|
|
|
int fSorted,
|
|
|
|
int xorg, int yorg,
|
|
|
|
PixmapPtr pPix
|
|
|
|
){
|
|
|
|
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
|
|
|
|
CARD32 *base;
|
|
|
|
Bool TwoPass = FALSE, FirstPass = TRUE;
|
|
|
|
StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc;
|
|
|
|
int stipplewidth = pPix->drawable.width;
|
|
|
|
int stippleheight = pPix->drawable.height;
|
|
|
|
int dwords, srcy, srcx, funcNo = 2;
|
|
|
|
unsigned char *srcp;
|
|
|
|
|
|
|
|
if(stipplewidth <= 32) {
|
|
|
|
if(stipplewidth & (stipplewidth - 1))
|
|
|
|
funcNo = 1;
|
|
|
|
else
|
|
|
|
funcNo = 0;
|
|
|
|
}
|
|
|
|
StippleFunc = stipple_scanline_func[funcNo];
|
|
|
|
SecondFunc = stipple_scanline_func[funcNo];
|
|
|
|
FirstFunc = stipple_scanline_func[funcNo + 3];
|
|
|
|
|
|
|
|
#ifdef TRIPLE_BITS
|
|
|
|
if((bg == -1) ||
|
|
|
|
(!(infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) &&
|
|
|
|
(!(infoRec->CPUToScreenColorExpandFillFlags & RGB_EQUAL) ||
|
|
|
|
(CHECK_RGB_EQUAL(bg))))) {
|
|
|
|
#else
|
|
|
|
if((bg == -1) ||
|
|
|
|
!(infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
|
|
|
|
#endif
|
|
|
|
/* one pass */
|
|
|
|
} else if((rop == GXcopy) && infoRec->FillSolidSpans) {
|
|
|
|
/* one pass but we fill background rects first */
|
|
|
|
(*infoRec->FillSolidSpans)(
|
|
|
|
pScrn, bg, rop, planemask, n, ppt, pwidth, fSorted);
|
|
|
|
bg = -1;
|
|
|
|
} else {
|
|
|
|
/* gotta do two passes */
|
|
|
|
TwoPass = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!TwoPass)
|
|
|
|
(*infoRec->SetupForCPUToScreenColorExpandFill)(
|
|
|
|
pScrn, fg, bg, rop, planemask);
|
|
|
|
|
|
|
|
while(n--) {
|
|
|
|
#ifdef TRIPLE_BITS
|
|
|
|
dwords = (3 * *pwidth + 31) >> 5;
|
|
|
|
#else
|
|
|
|
dwords = (*pwidth + 31) >> 5;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
srcy = (ppt->y - yorg) % stippleheight;
|
|
|
|
if(srcy < 0) srcy += stippleheight;
|
|
|
|
srcx = (ppt->x - xorg) % stipplewidth;
|
|
|
|
if(srcx < 0) srcx += stipplewidth;
|
|
|
|
|
|
|
|
srcp = (pPix->devKind * srcy) + (unsigned char*)pPix->devPrivate.ptr;
|
|
|
|
|
|
|
|
SECOND_PASS:
|
|
|
|
if(TwoPass) {
|
|
|
|
(*infoRec->SetupForCPUToScreenColorExpandFill)(pScrn,
|
|
|
|
(FirstPass) ? bg : fg, -1, rop, planemask);
|
|
|
|
StippleFunc = (FirstPass) ? FirstFunc : SecondFunc;
|
|
|
|
}
|
|
|
|
|
|
|
|
(*infoRec->SubsequentCPUToScreenColorExpandFill)(pScrn, ppt->x, ppt->y,
|
|
|
|
*pwidth, 1, 0);
|
|
|
|
|
|
|
|
base = (CARD32*)infoRec->ColorExpandBase;
|
|
|
|
|
|
|
|
(*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords);
|
|
|
|
|
|
|
|
if((infoRec->CPUToScreenColorExpandFillFlags & CPU_TRANSFER_PAD_QWORD)
|
|
|
|
&& (dwords & 0x01)) {
|
|
|
|
base = (CARD32*)infoRec->ColorExpandBase;
|
|
|
|
base[0] = 0x00000000;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(TwoPass) {
|
|
|
|
if(FirstPass) {
|
|
|
|
FirstPass = FALSE;
|
|
|
|
goto SECOND_PASS;
|
|
|
|
} else FirstPass = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
ppt++; pwidth++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(infoRec->CPUToScreenColorExpandFillFlags & SYNC_AFTER_COLOR_EXPAND)
|
|
|
|
(*infoRec->Sync)(pScrn);
|
|
|
|
else SET_SYNC_FLAG(infoRec);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef FIXEDBASE
|
|
|
|
|
|
|
|
void
|
|
|
|
#ifdef TRIPLE_BITS
|
|
|
|
EXPNAME(XAAFillScanlineColorExpandRects3)(
|
|
|
|
#else
|
|
|
|
EXPNAME(XAAFillScanlineColorExpandRects)(
|
|
|
|
#endif
|
|
|
|
ScrnInfoPtr pScrn,
|
|
|
|
int fg, int bg, int rop,
|
|
|
|
unsigned int planemask,
|
|
|
|
int nBox,
|
|
|
|
BoxPtr pBox,
|
|
|
|
int xorg, int yorg,
|
|
|
|
PixmapPtr pPix
|
|
|
|
){
|
|
|
|
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
|
|
|
|
CARD32 *base;
|
|
|
|
Bool TwoPass = FALSE, FirstPass = TRUE;
|
|
|
|
StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc;
|
|
|
|
int stipplewidth = pPix->drawable.width;
|
|
|
|
int stippleheight = pPix->drawable.height;
|
|
|
|
int srcwidth = pPix->devKind;
|
|
|
|
int dwords, srcy, srcx, funcNo = 2, bufferNo, h;
|
|
|
|
unsigned char *src = pPix->devPrivate.ptr;
|
|
|
|
unsigned char *srcp;
|
|
|
|
|
|
|
|
if(stipplewidth <= 32) {
|
|
|
|
if(stipplewidth & (stipplewidth - 1))
|
|
|
|
funcNo = 1;
|
|
|
|
else
|
|
|
|
funcNo = 0;
|
|
|
|
}
|
|
|
|
StippleFunc = stipple_scanline_func[funcNo];
|
|
|
|
SecondFunc = stipple_scanline_func[funcNo];
|
|
|
|
FirstFunc = stipple_scanline_func[funcNo + 3];
|
|
|
|
|
|
|
|
#ifdef TRIPLE_BITS
|
|
|
|
if((bg == -1) ||
|
|
|
|
(!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) &&
|
|
|
|
(!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & RGB_EQUAL) ||
|
|
|
|
(CHECK_RGB_EQUAL(bg))))) {
|
|
|
|
#else
|
|
|
|
if((bg == -1) ||
|
|
|
|
!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
|
|
|
|
#endif
|
|
|
|
/* one pass */
|
|
|
|
} else if((rop == GXcopy) && infoRec->FillSolidRects) {
|
|
|
|
/* one pass but we fill background rects first */
|
|
|
|
(*infoRec->FillSolidRects)(pScrn, bg, rop, planemask, nBox, pBox);
|
|
|
|
bg = -1;
|
|
|
|
} else {
|
|
|
|
/* gotta do two passes */
|
|
|
|
TwoPass = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!TwoPass)
|
|
|
|
(*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(
|
|
|
|
pScrn, fg, bg, rop, planemask);
|
|
|
|
|
|
|
|
while(nBox--) {
|
|
|
|
#ifdef TRIPLE_BITS
|
|
|
|
dwords = (3 * (pBox->x2 - pBox->x1) + 31) >> 5;
|
|
|
|
#else
|
|
|
|
dwords = (pBox->x2 - pBox->x1 + 31) >> 5;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
SECOND_PASS:
|
|
|
|
if(TwoPass) {
|
|
|
|
(*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(pScrn,
|
|
|
|
(FirstPass) ? bg : fg, -1, rop, planemask);
|
|
|
|
StippleFunc = (FirstPass) ? FirstFunc : SecondFunc;
|
|
|
|
}
|
|
|
|
|
|
|
|
h = pBox->y2 - pBox->y1;
|
|
|
|
|
|
|
|
(*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
|
|
|
|
pScrn, pBox->x1, pBox->y1, pBox->x2 - pBox->x1, h, 0);
|
|
|
|
|
|
|
|
bufferNo = 0;
|
|
|
|
|
|
|
|
srcy = (pBox->y1 - yorg) % stippleheight;
|
|
|
|
if(srcy < 0) srcy += stippleheight;
|
|
|
|
srcx = (pBox->x1 - xorg) % stipplewidth;
|
|
|
|
if(srcx < 0) srcx += stipplewidth;
|
|
|
|
|
|
|
|
srcp = (srcwidth * srcy) + src;
|
|
|
|
|
|
|
|
while(h--) {
|
|
|
|
base = (CARD32*)infoRec->ScanlineColorExpandBuffers[bufferNo];
|
|
|
|
(*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords);
|
|
|
|
(*infoRec->SubsequentColorExpandScanline)(pScrn, bufferNo++);
|
|
|
|
if(bufferNo >= infoRec->NumScanlineColorExpandBuffers)
|
|
|
|
bufferNo = 0;
|
|
|
|
srcy++;
|
|
|
|
srcp += srcwidth;
|
|
|
|
if (srcy >= stippleheight) {
|
|
|
|
srcy = 0;
|
|
|
|
srcp = src;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(TwoPass) {
|
|
|
|
if(FirstPass) {
|
|
|
|
FirstPass = FALSE;
|
|
|
|
goto SECOND_PASS;
|
|
|
|
} else FirstPass = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
pBox++;
|
|
|
|
}
|
|
|
|
|
|
|
|
SET_SYNC_FLAG(infoRec);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
#ifdef TRIPLE_BITS
|
|
|
|
EXPNAME(XAAFillScanlineColorExpandSpans3)(
|
|
|
|
#else
|
|
|
|
EXPNAME(XAAFillScanlineColorExpandSpans)(
|
|
|
|
#endif
|
|
|
|
ScrnInfoPtr pScrn,
|
|
|
|
int fg, int bg, int rop,
|
|
|
|
unsigned int planemask,
|
|
|
|
int n,
|
|
|
|
DDXPointPtr ppt,
|
|
|
|
int *pwidth,
|
|
|
|
int fSorted,
|
|
|
|
int xorg, int yorg,
|
|
|
|
PixmapPtr pPix
|
|
|
|
){
|
|
|
|
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
|
|
|
|
CARD32 *base;
|
|
|
|
Bool TwoPass = FALSE, FirstPass = TRUE;
|
|
|
|
StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc;
|
|
|
|
int stipplewidth = pPix->drawable.width;
|
|
|
|
int stippleheight = pPix->drawable.height;
|
|
|
|
int dwords, srcy, srcx, funcNo = 2;
|
|
|
|
unsigned char *srcp;
|
|
|
|
|
|
|
|
if(stipplewidth <= 32) {
|
|
|
|
if(stipplewidth & (stipplewidth - 1))
|
|
|
|
funcNo = 1;
|
|
|
|
else
|
|
|
|
funcNo = 0;
|
|
|
|
}
|
|
|
|
StippleFunc = stipple_scanline_func[funcNo];
|
|
|
|
SecondFunc = stipple_scanline_func[funcNo];
|
|
|
|
FirstFunc = stipple_scanline_func[funcNo + 3];
|
|
|
|
|
|
|
|
#ifdef TRIPLE_BITS
|
|
|
|
if((bg == -1) ||
|
|
|
|
(!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) &&
|
|
|
|
(!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & RGB_EQUAL) ||
|
|
|
|
(CHECK_RGB_EQUAL(bg))))) {
|
|
|
|
#else
|
|
|
|
if((bg == -1) ||
|
|
|
|
!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
|
|
|
|
#endif
|
|
|
|
/* one pass */
|
|
|
|
} else if((rop == GXcopy) && infoRec->FillSolidSpans) {
|
|
|
|
/* one pass but we fill background rects first */
|
|
|
|
(*infoRec->FillSolidSpans)(
|
|
|
|
pScrn, bg, rop, planemask, n, ppt, pwidth, fSorted);
|
|
|
|
bg = -1;
|
|
|
|
} else {
|
|
|
|
/* gotta do two passes */
|
|
|
|
TwoPass = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!TwoPass)
|
|
|
|
(*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(
|
|
|
|
pScrn, fg, bg, rop, planemask);
|
|
|
|
|
|
|
|
|
|
|
|
while(n--) {
|
|
|
|
#ifdef TRIPLE_BITS
|
|
|
|
dwords = (3 * *pwidth + 31) >> 5;
|
|
|
|
#else
|
|
|
|
dwords = (*pwidth + 31) >> 5;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
srcy = (ppt->y - yorg) % stippleheight;
|
|
|
|
if(srcy < 0) srcy += stippleheight;
|
|
|
|
srcx = (ppt->x - xorg) % stipplewidth;
|
|
|
|
if(srcx < 0) srcx += stipplewidth;
|
|
|
|
|
|
|
|
srcp = (pPix->devKind * srcy) + (unsigned char*)pPix->devPrivate.ptr;
|
|
|
|
|
|
|
|
SECOND_PASS:
|
|
|
|
if(TwoPass) {
|
|
|
|
(*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(pScrn,
|
|
|
|
(FirstPass) ? bg : fg, -1, rop, planemask);
|
|
|
|
StippleFunc = (FirstPass) ? FirstFunc : SecondFunc;
|
|
|
|
}
|
|
|
|
|
|
|
|
(*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
|
|
|
|
pScrn, ppt->x, ppt->y, *pwidth, 1, 0);
|
|
|
|
|
|
|
|
base = (CARD32*)infoRec->ScanlineColorExpandBuffers[0];
|
|
|
|
|
|
|
|
(*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords);
|
|
|
|
(*infoRec->SubsequentColorExpandScanline)(pScrn, 0);
|
|
|
|
|
|
|
|
if(TwoPass) {
|
|
|
|
if(FirstPass) {
|
|
|
|
FirstPass = FALSE;
|
|
|
|
goto SECOND_PASS;
|
|
|
|
} else FirstPass = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
ppt++; pwidth++;
|
|
|
|
}
|
|
|
|
|
|
|
|
SET_SYNC_FLAG(infoRec);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static CARD32 *
|
|
|
|
StipplePowerOfTwo(
|
|
|
|
CARD32* dest, CARD32* src,
|
|
|
|
int shift, int width, int dwords
|
|
|
|
){
|
|
|
|
CARD32 pat = *src;
|
|
|
|
if(width < 32) {
|
|
|
|
pat &= XAAShiftMasks[width];
|
|
|
|
while(width < 32) {
|
|
|
|
pat |= SHIFT_L(pat,width);
|
|
|
|
width <<= 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(shift)
|
|
|
|
pat = SHIFT_R(pat,shift) | SHIFT_L(pat,32 - shift);
|
|
|
|
|
|
|
|
#ifdef MSBFIRST
|
|
|
|
pat = SWAP_BITS_IN_BYTES(pat);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef TRIPLE_BITS
|
|
|
|
{
|
|
|
|
EXPAND_PAT;
|
|
|
|
|
|
|
|
while(dwords >= 3) {
|
|
|
|
WRITE_PAT3;
|
|
|
|
dwords -= 3;
|
|
|
|
}
|
|
|
|
if (dwords == 2) {
|
|
|
|
WRITE_PAT2;
|
|
|
|
} else if (dwords == 1) {
|
|
|
|
WRITE_PAT1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return dest;
|
|
|
|
}
|
|
|
|
#else /* TRIPLE_BITS */
|
|
|
|
while(dwords >= 4) {
|
|
|
|
DEST(0) = pat;
|
|
|
|
DEST(1) = pat;
|
|
|
|
DEST(2) = pat;
|
|
|
|
DEST(3) = pat;
|
|
|
|
dwords -= 4;
|
|
|
|
#ifndef FIXEDBASE
|
|
|
|
dest += 4;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!dwords) return dest;
|
|
|
|
DEST(0) = pat;
|
|
|
|
if(dwords == 1) RETURN(1);
|
|
|
|
DEST(1) = pat;
|
|
|
|
if(dwords == 2) RETURN(2);
|
|
|
|
DEST(2) = pat;
|
|
|
|
RETURN(3);
|
|
|
|
#endif /* TRIPLE_BITS */
|
|
|
|
}
|
|
|
|
|
|
|
|
static CARD32 *
|
|
|
|
StipplePowerOfTwo_Inverted(
|
|
|
|
CARD32* dest, CARD32* src,
|
|
|
|
int shift, int width, int dwords
|
|
|
|
){
|
|
|
|
CARD32 pat = *src;
|
|
|
|
if(width < 32) {
|
|
|
|
pat &= XAAShiftMasks[width];
|
|
|
|
while(width < 32) {
|
|
|
|
pat |= SHIFT_L(pat,width);
|
|
|
|
width <<= 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(shift)
|
|
|
|
pat = SHIFT_R(pat,shift) | SHIFT_L(pat,32 - shift);
|
|
|
|
|
|
|
|
#ifdef MSBFIRST
|
|
|
|
pat = SWAP_BITS_IN_BYTES(pat);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
pat = ~pat;
|
|
|
|
|
|
|
|
#ifdef TRIPLE_BITS
|
|
|
|
{
|
|
|
|
EXPAND_PAT;
|
|
|
|
|
|
|
|
while(dwords >= 3) {
|
|
|
|
WRITE_PAT3;
|
|
|
|
dwords -= 3;
|
|
|
|
}
|
|
|
|
if (dwords == 2) {
|
|
|
|
WRITE_PAT2;
|
|
|
|
} else if (dwords == 1) {
|
|
|
|
WRITE_PAT1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return dest;
|
|
|
|
}
|
|
|
|
#else /* TRIPLE_BITS */
|
|
|
|
while(dwords >= 4) {
|
|
|
|
DEST(0) = pat;
|
|
|
|
DEST(1) = pat;
|
|
|
|
DEST(2) = pat;
|
|
|
|
DEST(3) = pat;
|
|
|
|
dwords -= 4;
|
|
|
|
#ifndef FIXEDBASE
|
|
|
|
dest += 4;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!dwords) return dest;
|
|
|
|
DEST(0) = pat;
|
|
|
|
if(dwords == 1) RETURN(1);
|
|
|
|
DEST(1) = pat;
|
|
|
|
if(dwords == 2) RETURN(2);
|
|
|
|
DEST(2) = pat;
|
|
|
|
RETURN(3);
|
|
|
|
#endif /* TRIPLE_BITS */
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static CARD32 *
|
|
|
|
StippleUpTo32(
|
|
|
|
CARD32* base, CARD32* src,
|
|
|
|
int shift, int width, int dwords
|
|
|
|
){
|
|
|
|
CARD32 pat = *src & XAAShiftMasks[width];
|
|
|
|
|
|
|
|
while(width <= 15) {
|
|
|
|
pat |= SHIFT_L(pat,width);
|
|
|
|
width <<= 1;
|
|
|
|
}
|
|
|
|
pat |= SHIFT_L(pat,width);
|
|
|
|
|
|
|
|
while(dwords--) {
|
|
|
|
CARD32 bits = SHIFT_R(pat,shift) | SHIFT_L(pat,width-shift);
|
|
|
|
#ifdef TRIPLE_BITS
|
|
|
|
if(dwords >= 2) {
|
|
|
|
WRITE_BITS3(bits);
|
|
|
|
dwords -= 2;
|
|
|
|
} else if(dwords > 0) {
|
|
|
|
WRITE_BITS2(bits);
|
|
|
|
dwords--;
|
|
|
|
} else {
|
|
|
|
WRITE_BITS1(bits);
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
WRITE_BITS(bits);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
shift += 32;
|
|
|
|
shift %= width;
|
|
|
|
}
|
|
|
|
return base;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static CARD32 *
|
|
|
|
StippleUpTo32_Inverted(
|
|
|
|
CARD32* base, CARD32* src,
|
|
|
|
int shift, int width, int dwords
|
|
|
|
){
|
|
|
|
CARD32 pat = *src & XAAShiftMasks[width];
|
|
|
|
|
|
|
|
while(width <= 15) {
|
|
|
|
pat |= SHIFT_L(pat,width);
|
|
|
|
width <<= 1;
|
|
|
|
}
|
|
|
|
pat |= SHIFT_L(pat,width);
|
|
|
|
|
|
|
|
while(dwords--) {
|
|
|
|
CARD32 bits = ~(SHIFT_R(pat,shift) | SHIFT_L(pat,width-shift));
|
|
|
|
#ifdef TRIPLE_BITS
|
|
|
|
if(dwords >= 2) {
|
|
|
|
WRITE_BITS3(bits);
|
|
|
|
dwords -= 2;
|
|
|
|
} else if(dwords > 0) {
|
|
|
|
WRITE_BITS2(bits);
|
|
|
|
dwords--;
|
|
|
|
} else {
|
|
|
|
WRITE_BITS1(bits);
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
WRITE_BITS(bits);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
shift += 32;
|
|
|
|
shift %= width;
|
|
|
|
}
|
|
|
|
return base;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static CARD32 *
|
|
|
|
StippleOver32(
|
|
|
|
CARD32* base, CARD32* src,
|
|
|
|
int offset, int width, int dwords
|
|
|
|
){
|
|
|
|
CARD32* srcp;
|
|
|
|
CARD32 bits;
|
2003-11-25 20:29:01 +01:00
|
|
|
int bitsleft, shift, usable;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
|
|
|
while(dwords--) {
|
2003-11-25 20:29:01 +01:00
|
|
|
bitsleft = width - offset;
|
|
|
|
srcp = src + (offset >> 5);
|
|
|
|
shift = offset & 31;
|
|
|
|
usable = 32 - shift;
|
|
|
|
|
|
|
|
if(bitsleft < 32) {
|
|
|
|
if(bitsleft <= usable) {
|
|
|
|
bits = SHIFT_L(*src,bitsleft) |
|
|
|
|
(SHIFT_R(*srcp,shift) & XAAShiftMasks[bitsleft]);
|
|
|
|
} else {
|
|
|
|
bits = SHIFT_L(*src,bitsleft) |
|
|
|
|
(SHIFT_L(srcp[1],usable) & XAAShiftMasks[bitsleft]) |
|
|
|
|
(SHIFT_R(*srcp,shift) & XAAShiftMasks[usable]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(shift)
|
|
|
|
bits = SHIFT_R(*srcp,shift) | SHIFT_L(srcp[1],usable);
|
|
|
|
else
|
|
|
|
bits = *srcp;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
|
|
|
#ifdef TRIPLE_BITS
|
|
|
|
if(dwords >= 2) {
|
|
|
|
WRITE_BITS3(bits);
|
|
|
|
dwords -= 2;
|
|
|
|
} else if(dwords > 0) {
|
|
|
|
WRITE_BITS2(bits);
|
|
|
|
dwords--;
|
|
|
|
} else {
|
|
|
|
WRITE_BITS1(bits);
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
WRITE_BITS(bits);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
offset += 32;
|
|
|
|
offset %= width;
|
|
|
|
}
|
|
|
|
return base;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static CARD32 *
|
|
|
|
StippleOver32_Inverted(
|
|
|
|
CARD32* base, CARD32* src,
|
|
|
|
int offset, int width, int dwords
|
|
|
|
){
|
|
|
|
CARD32* srcp;
|
|
|
|
CARD32 bits;
|
2003-11-25 20:29:01 +01:00
|
|
|
int bitsleft, shift, usable;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
|
|
|
while(dwords--) {
|
2003-11-25 20:29:01 +01:00
|
|
|
bitsleft = width - offset;
|
|
|
|
srcp = src + (offset >> 5);
|
|
|
|
shift = offset & 31;
|
|
|
|
usable = 32 - shift;
|
|
|
|
|
|
|
|
if(bitsleft < 32) {
|
|
|
|
if(bitsleft <= usable) {
|
|
|
|
bits = SHIFT_L(*src,bitsleft) |
|
|
|
|
(SHIFT_R(*srcp,shift) & XAAShiftMasks[bitsleft]);
|
|
|
|
} else {
|
|
|
|
bits = SHIFT_L(*src,bitsleft) |
|
|
|
|
(SHIFT_L(srcp[1],usable) & XAAShiftMasks[bitsleft]) |
|
|
|
|
(SHIFT_R(*srcp,shift) & XAAShiftMasks[usable]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(shift)
|
|
|
|
bits = SHIFT_R(*srcp,shift) | SHIFT_L(srcp[1],usable);
|
|
|
|
else
|
|
|
|
bits = *srcp;
|
2003-11-14 17:48:57 +01:00
|
|
|
|
|
|
|
bits = ~bits;
|
|
|
|
|
|
|
|
#ifdef TRIPLE_BITS
|
|
|
|
if(dwords >= 2) {
|
|
|
|
WRITE_BITS3(bits);
|
|
|
|
dwords -= 2;
|
|
|
|
} else if(dwords > 0) {
|
|
|
|
WRITE_BITS2(bits);
|
|
|
|
dwords--;
|
|
|
|
} else {
|
|
|
|
WRITE_BITS1(bits);
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
WRITE_BITS(bits);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
offset += 32;
|
|
|
|
offset %= width;
|
|
|
|
}
|
|
|
|
return base;
|
|
|
|
}
|