1
/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaStipple.c,v 1.11 2001/10/28 03:34:04 tsi Exp $ */
7
#include "xf86_ansic.h"
9
static CARD32* StipplePowerOfTwo(CARD32*, CARD32*, int, int, int);
10
static CARD32* StipplePowerOfTwo_Inverted(CARD32*, CARD32*, int, int, int);
11
static CARD32* StippleUpTo32(CARD32*, CARD32*, int, int, int);
12
static CARD32* StippleUpTo32_Inverted(CARD32*, CARD32*, int, int, int);
13
static CARD32* StippleOver32(CARD32*, CARD32*, int, int, int);
14
static CARD32* StippleOver32_Inverted(CARD32*, CARD32*, int, int, int);
17
#define stipple_scanline_func EXPNAME(XAAStippleScanlineFunc3)
19
#define stipple_scanline_func EXPNAME(XAAStippleScanlineFunc)
22
StippleScanlineProcPtr stipple_scanline_func[6] = {
26
StipplePowerOfTwo_Inverted,
27
StippleUpTo32_Inverted,
28
StippleOver32_Inverted
33
# define DEST(i) *dest
34
# define RETURN(i) return(dest)
36
# define DEST(i) dest[i]
37
# define RETURN(i) return(dest + i)
41
/* TRIPLE_BITS pattern expansion */
44
CARD32 pat1 = byte_expand3[pat & 0xFF], \
45
pat2 = byte_expand3[(pat & 0xFF00) >> 8], \
46
pat3 = byte_expand3[(pat & 0xFF0000) >> 16], \
47
pat4 = byte_expand3[(pat & 0xFF000000) >> 24], \
48
patA = pat1 | (pat2 << 24), \
49
patB = (pat2 >> 8) | (pat3 << 16), \
50
patC = (pat3 >> 16) | (pat4 << 8)
52
#define WRITE_PAT1 { \
54
#define WRITE_PAT2 { \
57
#define WRITE_PAT3 { \
62
#define WRITE_PAT1 { \
64
#define WRITE_PAT2 { \
68
#define WRITE_PAT3 { \
77
#if !defined(FIXEDBASE) && !defined(MSBFIRST) && !defined(TRIPLE_BITS)
79
unsigned int XAAShiftMasks[32] = {
80
/* gcc is rather pedantic about SHIFT_R(0xFFFFFFFF,32) */
81
0x00000000 , SHIFT_R(0xFFFFFFFF,31),
82
SHIFT_R(0xFFFFFFFF,30), SHIFT_R(0xFFFFFFFF,29),
83
SHIFT_R(0xFFFFFFFF,28), SHIFT_R(0xFFFFFFFF,27),
84
SHIFT_R(0xFFFFFFFF,26), SHIFT_R(0xFFFFFFFF,25),
85
SHIFT_R(0xFFFFFFFF,24), SHIFT_R(0xFFFFFFFF,23),
86
SHIFT_R(0xFFFFFFFF,22), SHIFT_R(0xFFFFFFFF,21),
87
SHIFT_R(0xFFFFFFFF,20), SHIFT_R(0xFFFFFFFF,19),
88
SHIFT_R(0xFFFFFFFF,18), SHIFT_R(0xFFFFFFFF,17),
89
SHIFT_R(0xFFFFFFFF,16), SHIFT_R(0xFFFFFFFF,15),
90
SHIFT_R(0xFFFFFFFF,14), SHIFT_R(0xFFFFFFFF,13),
91
SHIFT_R(0xFFFFFFFF,12), SHIFT_R(0xFFFFFFFF,11),
92
SHIFT_R(0xFFFFFFFF,10), SHIFT_R(0xFFFFFFFF,9),
93
SHIFT_R(0xFFFFFFFF,8), SHIFT_R(0xFFFFFFFF,7),
94
SHIFT_R(0xFFFFFFFF,6), SHIFT_R(0xFFFFFFFF,5),
95
SHIFT_R(0xFFFFFFFF,4), SHIFT_R(0xFFFFFFFF,3),
96
SHIFT_R(0xFFFFFFFF,2), SHIFT_R(0xFFFFFFFF,1)
103
EXPNAME(XAAFillColorExpandRects3)(
105
EXPNAME(XAAFillColorExpandRects)(
108
int fg, int bg, int rop,
109
unsigned int planemask,
115
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
117
Bool TwoPass = FALSE, FirstPass = TRUE;
118
StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc;
119
int stipplewidth = pPix->drawable.width;
120
int stippleheight = pPix->drawable.height;
121
int srcwidth = pPix->devKind;
122
int dwords, srcy, srcx, funcNo = 2, h;
123
unsigned char *src = (unsigned char*)pPix->devPrivate.ptr;
127
if(stipplewidth <= 32) {
128
if(stipplewidth & (stipplewidth - 1))
133
StippleFunc = stipple_scanline_func[funcNo];
134
SecondFunc = stipple_scanline_func[funcNo];
135
FirstFunc = stipple_scanline_func[funcNo + 3];
139
(!(infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) &&
140
(!(infoRec->CPUToScreenColorExpandFillFlags & RGB_EQUAL) ||
141
(CHECK_RGB_EQUAL(bg))))) {
144
!(infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
147
} else if((rop == GXcopy) && infoRec->FillSolidRects) {
148
/* one pass but we fill background rects first */
149
(*infoRec->FillSolidRects)(pScrn, bg, rop, planemask, nBox, pBox);
152
/* gotta do two passes */
157
(*infoRec->SetupForCPUToScreenColorExpandFill)(
158
pScrn, fg, bg, rop, planemask);
162
dwords = (3 * (pBox->x2 - pBox->x1) + 31) >> 5;
164
dwords = (pBox->x2 - pBox->x1 + 31) >> 5;
169
(*infoRec->SetupForCPUToScreenColorExpandFill)(pScrn,
170
(FirstPass) ? bg : fg, -1, rop, planemask);
171
StippleFunc = (FirstPass) ? FirstFunc : SecondFunc;
174
h = pBox->y2 - pBox->y1;
175
flag = (infoRec->CPUToScreenColorExpandFillFlags
176
& CPU_TRANSFER_PAD_QWORD) && ((dwords * h) & 0x01);
178
(*infoRec->SubsequentCPUToScreenColorExpandFill)(
179
pScrn, pBox->x1, pBox->y1,
180
pBox->x2 - pBox->x1, h, 0);
182
base = (CARD32*)infoRec->ColorExpandBase;
184
srcy = (pBox->y1 - yorg) % stippleheight;
185
if(srcy < 0) srcy += stippleheight;
186
srcx = (pBox->x1 - xorg) % stipplewidth;
187
if(srcx < 0) srcx += stipplewidth;
189
srcp = (srcwidth * srcy) + src;
192
if((dwords * h) <= infoRec->ColorExpandRange) {
194
base = (*StippleFunc)(
195
base, (CARD32*)srcp, srcx, stipplewidth, dwords);
198
if (srcy >= stippleheight) {
206
(*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords);
209
if (srcy >= stippleheight) {
216
base = (CARD32*)infoRec->ColorExpandBase;
217
base[0] = 0x00000000;
224
} else FirstPass = TRUE;
230
if(infoRec->CPUToScreenColorExpandFillFlags & SYNC_AFTER_COLOR_EXPAND)
231
(*infoRec->Sync)(pScrn);
232
else SET_SYNC_FLAG(infoRec);
239
EXPNAME(XAAFillColorExpandSpans3)(
241
EXPNAME(XAAFillColorExpandSpans)(
244
int fg, int bg, int rop,
245
unsigned int planemask,
253
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
255
Bool TwoPass = FALSE, FirstPass = TRUE;
256
StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc;
257
int stipplewidth = pPix->drawable.width;
258
int stippleheight = pPix->drawable.height;
259
int dwords, srcy, srcx, funcNo = 2;
262
if(stipplewidth <= 32) {
263
if(stipplewidth & (stipplewidth - 1))
268
StippleFunc = stipple_scanline_func[funcNo];
269
SecondFunc = stipple_scanline_func[funcNo];
270
FirstFunc = stipple_scanline_func[funcNo + 3];
274
(!(infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) &&
275
(!(infoRec->CPUToScreenColorExpandFillFlags & RGB_EQUAL) ||
276
(CHECK_RGB_EQUAL(bg))))) {
279
!(infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
282
} else if((rop == GXcopy) && infoRec->FillSolidSpans) {
283
/* one pass but we fill background rects first */
284
(*infoRec->FillSolidSpans)(
285
pScrn, bg, rop, planemask, n, ppt, pwidth, fSorted);
288
/* gotta do two passes */
293
(*infoRec->SetupForCPUToScreenColorExpandFill)(
294
pScrn, fg, bg, rop, planemask);
298
dwords = (3 * *pwidth + 31) >> 5;
300
dwords = (*pwidth + 31) >> 5;
303
srcy = (ppt->y - yorg) % stippleheight;
304
if(srcy < 0) srcy += stippleheight;
305
srcx = (ppt->x - xorg) % stipplewidth;
306
if(srcx < 0) srcx += stipplewidth;
308
srcp = (pPix->devKind * srcy) + (unsigned char*)pPix->devPrivate.ptr;
312
(*infoRec->SetupForCPUToScreenColorExpandFill)(pScrn,
313
(FirstPass) ? bg : fg, -1, rop, planemask);
314
StippleFunc = (FirstPass) ? FirstFunc : SecondFunc;
317
(*infoRec->SubsequentCPUToScreenColorExpandFill)(pScrn, ppt->x, ppt->y,
320
base = (CARD32*)infoRec->ColorExpandBase;
322
(*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords);
324
if((infoRec->CPUToScreenColorExpandFillFlags & CPU_TRANSFER_PAD_QWORD)
325
&& (dwords & 0x01)) {
326
base = (CARD32*)infoRec->ColorExpandBase;
327
base[0] = 0x00000000;
334
} else FirstPass = TRUE;
340
if(infoRec->CPUToScreenColorExpandFillFlags & SYNC_AFTER_COLOR_EXPAND)
341
(*infoRec->Sync)(pScrn);
342
else SET_SYNC_FLAG(infoRec);
350
EXPNAME(XAAFillScanlineColorExpandRects3)(
352
EXPNAME(XAAFillScanlineColorExpandRects)(
355
int fg, int bg, int rop,
356
unsigned int planemask,
362
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
364
Bool TwoPass = FALSE, FirstPass = TRUE;
365
StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc;
366
int stipplewidth = pPix->drawable.width;
367
int stippleheight = pPix->drawable.height;
368
int srcwidth = pPix->devKind;
369
int dwords, srcy, srcx, funcNo = 2, bufferNo, h;
370
unsigned char *src = pPix->devPrivate.ptr;
373
if(stipplewidth <= 32) {
374
if(stipplewidth & (stipplewidth - 1))
379
StippleFunc = stipple_scanline_func[funcNo];
380
SecondFunc = stipple_scanline_func[funcNo];
381
FirstFunc = stipple_scanline_func[funcNo + 3];
385
(!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) &&
386
(!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & RGB_EQUAL) ||
387
(CHECK_RGB_EQUAL(bg))))) {
390
!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
393
} else if((rop == GXcopy) && infoRec->FillSolidRects) {
394
/* one pass but we fill background rects first */
395
(*infoRec->FillSolidRects)(pScrn, bg, rop, planemask, nBox, pBox);
398
/* gotta do two passes */
403
(*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(
404
pScrn, fg, bg, rop, planemask);
408
dwords = (3 * (pBox->x2 - pBox->x1) + 31) >> 5;
410
dwords = (pBox->x2 - pBox->x1 + 31) >> 5;
415
(*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(pScrn,
416
(FirstPass) ? bg : fg, -1, rop, planemask);
417
StippleFunc = (FirstPass) ? FirstFunc : SecondFunc;
420
h = pBox->y2 - pBox->y1;
422
(*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
423
pScrn, pBox->x1, pBox->y1, pBox->x2 - pBox->x1, h, 0);
427
srcy = (pBox->y1 - yorg) % stippleheight;
428
if(srcy < 0) srcy += stippleheight;
429
srcx = (pBox->x1 - xorg) % stipplewidth;
430
if(srcx < 0) srcx += stipplewidth;
432
srcp = (srcwidth * srcy) + src;
435
base = (CARD32*)infoRec->ScanlineColorExpandBuffers[bufferNo];
436
(*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords);
437
(*infoRec->SubsequentColorExpandScanline)(pScrn, bufferNo++);
438
if(bufferNo >= infoRec->NumScanlineColorExpandBuffers)
442
if (srcy >= stippleheight) {
452
} else FirstPass = TRUE;
458
SET_SYNC_FLAG(infoRec);
463
EXPNAME(XAAFillScanlineColorExpandSpans3)(
465
EXPNAME(XAAFillScanlineColorExpandSpans)(
468
int fg, int bg, int rop,
469
unsigned int planemask,
477
XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
479
Bool TwoPass = FALSE, FirstPass = TRUE;
480
StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc;
481
int stipplewidth = pPix->drawable.width;
482
int stippleheight = pPix->drawable.height;
483
int dwords, srcy, srcx, funcNo = 2;
486
if(stipplewidth <= 32) {
487
if(stipplewidth & (stipplewidth - 1))
492
StippleFunc = stipple_scanline_func[funcNo];
493
SecondFunc = stipple_scanline_func[funcNo];
494
FirstFunc = stipple_scanline_func[funcNo + 3];
498
(!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) &&
499
(!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & RGB_EQUAL) ||
500
(CHECK_RGB_EQUAL(bg))))) {
503
!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
506
} else if((rop == GXcopy) && infoRec->FillSolidSpans) {
507
/* one pass but we fill background rects first */
508
(*infoRec->FillSolidSpans)(
509
pScrn, bg, rop, planemask, n, ppt, pwidth, fSorted);
512
/* gotta do two passes */
517
(*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(
518
pScrn, fg, bg, rop, planemask);
523
dwords = (3 * *pwidth + 31) >> 5;
525
dwords = (*pwidth + 31) >> 5;
528
srcy = (ppt->y - yorg) % stippleheight;
529
if(srcy < 0) srcy += stippleheight;
530
srcx = (ppt->x - xorg) % stipplewidth;
531
if(srcx < 0) srcx += stipplewidth;
533
srcp = (pPix->devKind * srcy) + (unsigned char*)pPix->devPrivate.ptr;
537
(*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(pScrn,
538
(FirstPass) ? bg : fg, -1, rop, planemask);
539
StippleFunc = (FirstPass) ? FirstFunc : SecondFunc;
542
(*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
543
pScrn, ppt->x, ppt->y, *pwidth, 1, 0);
545
base = (CARD32*)infoRec->ScanlineColorExpandBuffers[0];
547
(*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords);
548
(*infoRec->SubsequentColorExpandScanline)(pScrn, 0);
554
} else FirstPass = TRUE;
560
SET_SYNC_FLAG(infoRec);
567
CARD32* dest, CARD32* src,
568
int shift, int width, int dwords
572
pat &= XAAShiftMasks[width];
574
pat |= SHIFT_L(pat,width);
580
pat = SHIFT_R(pat,shift) | SHIFT_L(pat,32 - shift);
583
pat = SWAP_BITS_IN_BYTES(pat);
596
} else if (dwords == 1) {
602
#else /* TRIPLE_BITS */
614
if(!dwords) return dest;
616
if(dwords == 1) RETURN(1);
618
if(dwords == 2) RETURN(2);
621
#endif /* TRIPLE_BITS */
625
StipplePowerOfTwo_Inverted(
626
CARD32* dest, CARD32* src,
627
int shift, int width, int dwords
631
pat &= XAAShiftMasks[width];
633
pat |= SHIFT_L(pat,width);
639
pat = SHIFT_R(pat,shift) | SHIFT_L(pat,32 - shift);
642
pat = SWAP_BITS_IN_BYTES(pat);
657
} else if (dwords == 1) {
663
#else /* TRIPLE_BITS */
675
if(!dwords) return dest;
677
if(dwords == 1) RETURN(1);
679
if(dwords == 2) RETURN(2);
682
#endif /* TRIPLE_BITS */
688
CARD32* base, CARD32* src,
689
int shift, int width, int dwords
691
CARD32 pat = *src & XAAShiftMasks[width];
694
pat |= SHIFT_L(pat,width);
697
pat |= SHIFT_L(pat,width);
700
CARD32 bits = SHIFT_R(pat,shift) | SHIFT_L(pat,width-shift);
705
} else if(dwords > 0) {
723
StippleUpTo32_Inverted(
724
CARD32* base, CARD32* src,
725
int shift, int width, int dwords
727
CARD32 pat = *src & XAAShiftMasks[width];
730
pat |= SHIFT_L(pat,width);
733
pat |= SHIFT_L(pat,width);
736
CARD32 bits = ~(SHIFT_R(pat,shift) | SHIFT_L(pat,width-shift));
741
} else if(dwords > 0) {
760
CARD32* base, CARD32* src,
761
int offset, int width, int dwords
768
bitsleft = width - offset;
769
srcp = src + (offset >> 5);
773
bits = SHIFT_L(*src,bitsleft) |
774
(SHIFT_R(*srcp,shift) & XAAShiftMasks[bitsleft]);
776
bits = SHIFT_R(*srcp,shift) | SHIFT_L(srcp[1],32-shift);
784
} else if(dwords > 0) {
802
StippleOver32_Inverted(
803
CARD32* base, CARD32* src,
804
int offset, int width, int dwords
811
bitsleft = width - offset;
812
srcp = src + (offset >> 5);
816
bits = SHIFT_L(*src,bitsleft) |
817
(SHIFT_R(*srcp,shift) & XAAShiftMasks[bitsleft]);
819
bits = SHIFT_R(*srcp,shift) | SHIFT_L(srcp[1],32-shift);
829
} else if(dwords > 0) {