xserver-multidpi/hw/xfree86/xaa/xaaStipple.c

916 lines
26 KiB
C
Raw Normal View History

2003-11-14 17:48:57 +01:00
#ifdef HAVE_XORG_CONFIG_H
#include <xorg-config.h>
#endif
2003-11-14 17:48:57 +01:00
#include "xaa.h"
#include "xaalocal.h"
#include "xaacexp.h"
#include "xf86.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);
2003-11-14 17:48:57 +01:00
#ifdef TRIPLE_BITS
#define stipple_scanline_func EXPNAME(XAAStippleScanlineFunc3)
#define stipple_get_scanline_func EXPNAME(XAAGetStippleScanlineFunc3)
2003-11-14 17:48:57 +01:00
#else
#define stipple_scanline_func EXPNAME(XAAStippleScanlineFunc)
#define stipple_get_scanline_func EXPNAME(XAAGetStippleScanlineFunc)
2003-11-14 17:48:57 +01:00
#endif
StippleScanlineProcPtr stipple_scanline_func[6] = {
StipplePowerOfTwo,
StippleUpTo32,
StippleOver32,
StipplePowerOfTwo_Inverted,
StippleUpTo32_Inverted,
StippleOver32_Inverted
2003-11-14 17:48:57 +01:00
};
StippleScanlineProcPtr *
stipple_get_scanline_func(void)
{
return stipple_scanline_func;
}
2003-11-14 17:48:57 +01:00
#ifdef FIXEDBASE
#define DEST(i) *dest
#define RETURN(i) return(dest)
2003-11-14 17:48:57 +01:00
#else
#define DEST(i) dest[i]
#define RETURN(i) return(dest + i)
2003-11-14 17:48:57 +01:00
#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)
2003-11-14 17:48:57 +01:00
};
#endif
void
2003-11-14 17:48:57 +01:00
#ifdef TRIPLE_BITS
EXPNAME(XAAFillColorExpandRects3) (
2003-11-14 17:48:57 +01:00
#else
EXPNAME(XAAFillColorExpandRects) (
2003-11-14 17:48:57 +01:00
#endif
ScrnInfoPtr pScrn,
int fg, int bg, int rop,
unsigned int planemask,
int nBox,
BoxPtr pBox,
int xorg, int yorg, PixmapPtr pPix) {
2003-11-14 17:48:57 +01:00
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;
2003-11-14 17:48:57 +01:00
unsigned char *srcp;
int flag;
if (stipplewidth <= 32) {
if (stipplewidth & (stipplewidth - 1))
funcNo = 1;
else
funcNo = 0;
}
2003-11-14 17:48:57 +01:00
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))))) {
2003-11-14 17:48:57 +01:00
#else
if ((bg == -1) ||
!(infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
2003-11-14 17:48:57 +01:00
#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;
2003-11-14 17:48:57 +01:00
}
if (!TwoPass)
(*infoRec->SetupForCPUToScreenColorExpandFill) (pScrn, fg, bg, rop,
planemask);
2003-11-14 17:48:57 +01:00
while (nBox--) {
2003-11-14 17:48:57 +01:00
#ifdef TRIPLE_BITS
dwords = (3 * (pBox->x2 - pBox->x1) + 31) >> 5;
2003-11-14 17:48:57 +01:00
#else
dwords = (pBox->x2 - pBox->x1 + 31) >> 5;
2003-11-14 17:48:57 +01:00
#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);
2003-11-14 17:48:57 +01:00
(*infoRec->SubsequentCPUToScreenColorExpandFill) (pScrn, pBox->x1,
pBox->y1,
pBox->x2 - pBox->x1,
h, 0);
2003-11-14 17:48:57 +01:00
base = (CARD32 *) infoRec->ColorExpandBase;
2003-11-14 17:48:57 +01:00
srcy = (pBox->y1 - yorg) % stippleheight;
if (srcy < 0)
srcy += stippleheight;
srcx = (pBox->x1 - xorg) % stipplewidth;
if (srcx < 0)
srcx += stipplewidth;
2003-11-14 17:48:57 +01:00
srcp = (srcwidth * srcy) + src;
2003-11-14 17:48:57 +01:00
#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
2003-11-14 17:48:57 +01:00
#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;
}
2003-11-14 17:48:57 +01:00
if (TwoPass) {
if (FirstPass) {
FirstPass = FALSE;
goto SECOND_PASS;
}
else
FirstPass = TRUE;
}
2003-11-14 17:48:57 +01:00
pBox++;
}
if (infoRec->CPUToScreenColorExpandFillFlags & SYNC_AFTER_COLOR_EXPAND)
(*infoRec->Sync) (pScrn);
else
SET_SYNC_FLAG(infoRec);
}
2003-11-14 17:48:57 +01:00
void
2003-11-14 17:48:57 +01:00
#ifdef TRIPLE_BITS
EXPNAME(XAAFillColorExpandSpans3) (
2003-11-14 17:48:57 +01:00
#else
EXPNAME(XAAFillColorExpandSpans) (
2003-11-14 17:48:57 +01:00
#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) {
2003-11-14 17:48:57 +01:00
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;
}
2003-11-14 17:48:57 +01:00
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))))) {
2003-11-14 17:48:57 +01:00
#else
if ((bg == -1) ||
!(infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
2003-11-14 17:48:57 +01:00
#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--) {
2003-11-14 17:48:57 +01:00
#ifdef TRIPLE_BITS
dwords = (3 * *pwidth + 31) >> 5;
2003-11-14 17:48:57 +01:00
#else
dwords = (*pwidth + 31) >> 5;
2003-11-14 17:48:57 +01:00
#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;
}
2003-11-14 17:48:57 +01:00
ppt++;
pwidth++;
}
if (infoRec->CPUToScreenColorExpandFillFlags & SYNC_AFTER_COLOR_EXPAND)
(*infoRec->Sync) (pScrn);
else
SET_SYNC_FLAG(infoRec);
}
2003-11-14 17:48:57 +01:00
#ifndef FIXEDBASE
void
2003-11-14 17:48:57 +01:00
#ifdef TRIPLE_BITS
EXPNAME(XAAFillScanlineColorExpandRects3) (
2003-11-14 17:48:57 +01:00
#else
EXPNAME(XAAFillScanlineColorExpandRects) (
2003-11-14 17:48:57 +01:00
#endif
ScrnInfoPtr pScrn,
int fg, int bg, int rop,
unsigned int planemask,
int nBox,
BoxPtr pBox,
int xorg, int yorg,
PixmapPtr pPix) {
2003-11-14 17:48:57 +01:00
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;
}
2003-11-14 17:48:57 +01:00
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))))) {
2003-11-14 17:48:57 +01:00
#else
if ((bg == -1) ||
!(infoRec->
ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
2003-11-14 17:48:57 +01:00
#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;
2003-11-14 17:48:57 +01:00
}
if (!TwoPass)
(*infoRec->SetupForScanlineCPUToScreenColorExpandFill) (pScrn, fg, bg,
rop, planemask);
2003-11-14 17:48:57 +01:00
while (nBox--) {
2003-11-14 17:48:57 +01:00
#ifdef TRIPLE_BITS
dwords = (3 * (pBox->x2 - pBox->x1) + 31) >> 5;
2003-11-14 17:48:57 +01:00
#else
dwords = (pBox->x2 - pBox->x1 + 31) >> 5;
2003-11-14 17:48:57 +01:00
#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);
2003-11-14 17:48:57 +01:00
}
void
2003-11-14 17:48:57 +01:00
#ifdef TRIPLE_BITS
EXPNAME(XAAFillScanlineColorExpandSpans3) (
2003-11-14 17:48:57 +01:00
#else
EXPNAME(XAAFillScanlineColorExpandSpans) (
2003-11-14 17:48:57 +01:00
#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) {
2003-11-14 17:48:57 +01:00
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;
}
2003-11-14 17:48:57 +01:00
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))))) {
2003-11-14 17:48:57 +01:00
#else
if ((bg == -1) ||
!(infoRec->
ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
2003-11-14 17:48:57 +01:00
#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;
2003-11-14 17:48:57 +01:00
}
if (!TwoPass)
(*infoRec->SetupForScanlineCPUToScreenColorExpandFill) (pScrn, fg, bg,
rop, planemask);
2003-11-14 17:48:57 +01:00
while (n--) {
2003-11-14 17:48:57 +01:00
#ifdef TRIPLE_BITS
dwords = (3 * *pwidth + 31) >> 5;
2003-11-14 17:48:57 +01:00
#else
dwords = (*pwidth + 31) >> 5;
2003-11-14 17:48:57 +01:00
#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;
}
2003-11-14 17:48:57 +01:00
(*infoRec->SubsequentScanlineCPUToScreenColorExpandFill) (pScrn, ppt->x,
ppt->y,
*pwidth, 1,
0);
2003-11-14 17:48:57 +01:00
base = (CARD32 *) infoRec->ScanlineColorExpandBuffers[0];
2003-11-14 17:48:57 +01:00
(*StippleFunc) (base, (CARD32 *) srcp, srcx, stipplewidth, dwords);
(*infoRec->SubsequentColorExpandScanline) (pScrn, 0);
2003-11-14 17:48:57 +01:00
if (TwoPass) {
if (FirstPass) {
FirstPass = FALSE;
goto SECOND_PASS;
}
else
FirstPass = TRUE;
}
2003-11-14 17:48:57 +01:00
ppt++;
pwidth++;
}
2003-11-14 17:48:57 +01:00
SET_SYNC_FLAG(infoRec);
2003-11-14 17:48:57 +01:00
}
#endif
static CARD32 *
StipplePowerOfTwo(CARD32 *dest, CARD32 *src, int shift, int width, int dwords)
{
2003-11-14 17:48:57 +01:00
CARD32 pat = *src;
if (width < 32) {
pat &= XAAShiftMasks[width];
while (width < 32) {
pat |= SHIFT_L(pat, width);
width <<= 1;
}
2003-11-14 17:48:57 +01:00
}
if (shift)
pat = SHIFT_R(pat, shift) | SHIFT_L(pat, 32 - shift);
2003-11-14 17:48:57 +01:00
#ifdef MSBFIRST
pat = SWAP_BITS_IN_BYTES(pat);
2003-11-14 17:48:57 +01:00
#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;
2003-11-14 17:48:57 +01:00
#ifndef FIXEDBASE
dest += 4;
2003-11-14 17:48:57 +01:00
#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 */
2003-11-14 17:48:57 +01:00
}
static CARD32 *
StipplePowerOfTwo_Inverted(CARD32 *dest, CARD32 *src,
int shift, int width, int dwords)
{
2003-11-14 17:48:57 +01:00
CARD32 pat = *src;
if (width < 32) {
pat &= XAAShiftMasks[width];
while (width < 32) {
pat |= SHIFT_L(pat, width);
width <<= 1;
}
2003-11-14 17:48:57 +01:00
}
if (shift)
pat = SHIFT_R(pat, shift) | SHIFT_L(pat, 32 - shift);
2003-11-14 17:48:57 +01:00
#ifdef MSBFIRST
pat = SWAP_BITS_IN_BYTES(pat);
2003-11-14 17:48:57 +01:00
#endif
pat = ~pat;
2003-11-14 17:48:57 +01:00
#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;
2003-11-14 17:48:57 +01:00
#ifndef FIXEDBASE
dest += 4;
2003-11-14 17:48:57 +01:00
#endif
}
2003-11-14 17:48:57 +01:00
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 */
}
2003-11-14 17:48:57 +01:00
static CARD32 *
StippleUpTo32(CARD32 *base, CARD32 *src, int shift, int width, int dwords)
{
2003-11-14 17:48:57 +01:00
CARD32 pat = *src & XAAShiftMasks[width];
while (width <= 15) {
pat |= SHIFT_L(pat, width);
width <<= 1;
2003-11-14 17:48:57 +01:00
}
pat |= SHIFT_L(pat, width);
while (dwords--) {
CARD32 bits = SHIFT_R(pat, shift) | SHIFT_L(pat, width - shift);
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);
}
2003-11-14 17:48:57 +01:00
#else
WRITE_BITS(bits);
2003-11-14 17:48:57 +01:00
#endif
shift += 32;
shift %= width;
2003-11-14 17:48:57 +01:00
}
return base;
}
static CARD32 *
StippleUpTo32_Inverted(CARD32 *base, CARD32 *src,
int shift, int width, int dwords)
{
2003-11-14 17:48:57 +01:00
CARD32 pat = *src & XAAShiftMasks[width];
while (width <= 15) {
pat |= SHIFT_L(pat, width);
width <<= 1;
2003-11-14 17:48:57 +01:00
}
pat |= SHIFT_L(pat, width);
while (dwords--) {
CARD32 bits = ~(SHIFT_R(pat, shift) | SHIFT_L(pat, width - shift));
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);
}
2003-11-14 17:48:57 +01:00
#else
WRITE_BITS(bits);
2003-11-14 17:48:57 +01:00
#endif
shift += 32;
shift %= width;
2003-11-14 17:48:57 +01:00
}
return base;
}
static CARD32 *
StippleOver32(CARD32 *base, CARD32 *src, int offset, int width, int dwords)
{
CARD32 *srcp;
CARD32 bits;
int bitsleft, shift, usable;
while (dwords--) {
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);
}
2003-11-14 17:48:57 +01:00
#else
WRITE_BITS(bits);
2003-11-14 17:48:57 +01:00
#endif
offset += 32;
offset %= width;
}
return base;
2003-11-14 17:48:57 +01:00
}
static CARD32 *
StippleOver32_Inverted(CARD32 *base, CARD32 *src,
int offset, int width, int dwords)
{
CARD32 *srcp;
CARD32 bits;
int bitsleft, shift, usable;
while (dwords--) {
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;
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);
}
2003-11-14 17:48:57 +01:00
#else
WRITE_BITS(bits);
2003-11-14 17:48:57 +01:00
#endif
offset += 32;
offset %= width;
}
return base;
2003-11-14 17:48:57 +01:00
}