1706f2543Smrg 2706f2543Smrg#ifdef HAVE_XORG_CONFIG_H 3706f2543Smrg#include <xorg-config.h> 4706f2543Smrg#endif 5706f2543Smrg 6706f2543Smrg#include "xaa.h" 7706f2543Smrg#include "xaalocal.h" 8706f2543Smrg#include "xaacexp.h" 9706f2543Smrg#include "xf86.h" 10706f2543Smrg 11706f2543Smrgstatic CARD32* StipplePowerOfTwo(CARD32*, CARD32*, int, int, int); 12706f2543Smrgstatic CARD32* StipplePowerOfTwo_Inverted(CARD32*, CARD32*, int, int, int); 13706f2543Smrgstatic CARD32* StippleUpTo32(CARD32*, CARD32*, int, int, int); 14706f2543Smrgstatic CARD32* StippleUpTo32_Inverted(CARD32*, CARD32*, int, int, int); 15706f2543Smrgstatic CARD32* StippleOver32(CARD32*, CARD32*, int, int, int); 16706f2543Smrgstatic CARD32* StippleOver32_Inverted(CARD32*, CARD32*, int, int, int); 17706f2543Smrg 18706f2543Smrg#ifdef TRIPLE_BITS 19706f2543Smrg#define stipple_scanline_func EXPNAME(XAAStippleScanlineFunc3) 20706f2543Smrg#define stipple_get_scanline_func EXPNAME(XAAGetStippleScanlineFunc3) 21706f2543Smrg#else 22706f2543Smrg#define stipple_scanline_func EXPNAME(XAAStippleScanlineFunc) 23706f2543Smrg#define stipple_get_scanline_func EXPNAME(XAAGetStippleScanlineFunc) 24706f2543Smrg#endif 25706f2543Smrg 26706f2543SmrgStippleScanlineProcPtr stipple_scanline_func[6] = { 27706f2543Smrg StipplePowerOfTwo, 28706f2543Smrg StippleUpTo32, 29706f2543Smrg StippleOver32, 30706f2543Smrg StipplePowerOfTwo_Inverted, 31706f2543Smrg StippleUpTo32_Inverted, 32706f2543Smrg StippleOver32_Inverted 33706f2543Smrg}; 34706f2543Smrg 35706f2543SmrgStippleScanlineProcPtr *stipple_get_scanline_func(void) { 36706f2543Smrg return stipple_scanline_func; 37706f2543Smrg} 38706f2543Smrg 39706f2543Smrg#ifdef FIXEDBASE 40706f2543Smrg# define DEST(i) *dest 41706f2543Smrg# define RETURN(i) return(dest) 42706f2543Smrg#else 43706f2543Smrg# define DEST(i) dest[i] 44706f2543Smrg# define RETURN(i) return(dest + i) 45706f2543Smrg#endif 46706f2543Smrg 47706f2543Smrg 48706f2543Smrg/* TRIPLE_BITS pattern expansion */ 49706f2543Smrg#ifdef TRIPLE_BITS 50706f2543Smrg#define EXPAND_PAT \ 51706f2543Smrg CARD32 pat1 = byte_expand3[pat & 0xFF], \ 52706f2543Smrg pat2 = byte_expand3[(pat & 0xFF00) >> 8], \ 53706f2543Smrg pat3 = byte_expand3[(pat & 0xFF0000) >> 16], \ 54706f2543Smrg pat4 = byte_expand3[(pat & 0xFF000000) >> 24], \ 55706f2543Smrg patA = pat1 | (pat2 << 24), \ 56706f2543Smrg patB = (pat2 >> 8) | (pat3 << 16), \ 57706f2543Smrg patC = (pat3 >> 16) | (pat4 << 8) 58706f2543Smrg#ifdef FIXED_BASE 59706f2543Smrg#define WRITE_PAT1 { \ 60706f2543Smrg *dest = patA; } 61706f2543Smrg#define WRITE_PAT2 { \ 62706f2543Smrg *dest = patA; \ 63706f2543Smrg *dest = patB; } 64706f2543Smrg#define WRITE_PAT3 { \ 65706f2543Smrg *dest = patA; \ 66706f2543Smrg *dest = patB; \ 67706f2543Smrg *dest = patC; } 68706f2543Smrg#else 69706f2543Smrg#define WRITE_PAT1 { \ 70706f2543Smrg *(dest++) = patA; } 71706f2543Smrg#define WRITE_PAT2 { \ 72706f2543Smrg *(dest) = patA; \ 73706f2543Smrg *(dest + 1) = patB; \ 74706f2543Smrg dest += 2; } 75706f2543Smrg#define WRITE_PAT3 { \ 76706f2543Smrg *(dest) = patA; \ 77706f2543Smrg *(dest + 1) = patB; \ 78706f2543Smrg *(dest + 2) = patC; \ 79706f2543Smrg dest += 3; } 80706f2543Smrg#endif 81706f2543Smrg#endif 82706f2543Smrg 83706f2543Smrg 84706f2543Smrg#if !defined(FIXEDBASE) && !defined(MSBFIRST) && !defined(TRIPLE_BITS) 85706f2543Smrg 86706f2543Smrgunsigned int XAAShiftMasks[32] = { 87706f2543Smrg /* gcc is rather pedantic about SHIFT_R(0xFFFFFFFF,32) */ 88706f2543Smrg 0x00000000 , SHIFT_R(0xFFFFFFFF,31), 89706f2543Smrg SHIFT_R(0xFFFFFFFF,30), SHIFT_R(0xFFFFFFFF,29), 90706f2543Smrg SHIFT_R(0xFFFFFFFF,28), SHIFT_R(0xFFFFFFFF,27), 91706f2543Smrg SHIFT_R(0xFFFFFFFF,26), SHIFT_R(0xFFFFFFFF,25), 92706f2543Smrg SHIFT_R(0xFFFFFFFF,24), SHIFT_R(0xFFFFFFFF,23), 93706f2543Smrg SHIFT_R(0xFFFFFFFF,22), SHIFT_R(0xFFFFFFFF,21), 94706f2543Smrg SHIFT_R(0xFFFFFFFF,20), SHIFT_R(0xFFFFFFFF,19), 95706f2543Smrg SHIFT_R(0xFFFFFFFF,18), SHIFT_R(0xFFFFFFFF,17), 96706f2543Smrg SHIFT_R(0xFFFFFFFF,16), SHIFT_R(0xFFFFFFFF,15), 97706f2543Smrg SHIFT_R(0xFFFFFFFF,14), SHIFT_R(0xFFFFFFFF,13), 98706f2543Smrg SHIFT_R(0xFFFFFFFF,12), SHIFT_R(0xFFFFFFFF,11), 99706f2543Smrg SHIFT_R(0xFFFFFFFF,10), SHIFT_R(0xFFFFFFFF,9), 100706f2543Smrg SHIFT_R(0xFFFFFFFF,8), SHIFT_R(0xFFFFFFFF,7), 101706f2543Smrg SHIFT_R(0xFFFFFFFF,6), SHIFT_R(0xFFFFFFFF,5), 102706f2543Smrg SHIFT_R(0xFFFFFFFF,4), SHIFT_R(0xFFFFFFFF,3), 103706f2543Smrg SHIFT_R(0xFFFFFFFF,2), SHIFT_R(0xFFFFFFFF,1) 104706f2543Smrg}; 105706f2543Smrg 106706f2543Smrg#endif 107706f2543Smrg 108706f2543Smrgvoid 109706f2543Smrg#ifdef TRIPLE_BITS 110706f2543SmrgEXPNAME(XAAFillColorExpandRects3)( 111706f2543Smrg#else 112706f2543SmrgEXPNAME(XAAFillColorExpandRects)( 113706f2543Smrg#endif 114706f2543Smrg ScrnInfoPtr pScrn, 115706f2543Smrg int fg, int bg, int rop, 116706f2543Smrg unsigned int planemask, 117706f2543Smrg int nBox, 118706f2543Smrg BoxPtr pBox, 119706f2543Smrg int xorg, int yorg, 120706f2543Smrg PixmapPtr pPix 121706f2543Smrg){ 122706f2543Smrg XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 123706f2543Smrg CARD32 *base; 124706f2543Smrg Bool TwoPass = FALSE, FirstPass = TRUE; 125706f2543Smrg StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc; 126706f2543Smrg int stipplewidth = pPix->drawable.width; 127706f2543Smrg int stippleheight = pPix->drawable.height; 128706f2543Smrg int srcwidth = pPix->devKind; 129706f2543Smrg int dwords, srcy, srcx, funcNo = 2, h; 130706f2543Smrg unsigned char *src = (unsigned char*)pPix->devPrivate.ptr; 131706f2543Smrg unsigned char *srcp; 132706f2543Smrg int flag; 133706f2543Smrg 134706f2543Smrg if(stipplewidth <= 32) { 135706f2543Smrg if(stipplewidth & (stipplewidth - 1)) 136706f2543Smrg funcNo = 1; 137706f2543Smrg else 138706f2543Smrg funcNo = 0; 139706f2543Smrg } 140706f2543Smrg StippleFunc = stipple_scanline_func[funcNo]; 141706f2543Smrg SecondFunc = stipple_scanline_func[funcNo]; 142706f2543Smrg FirstFunc = stipple_scanline_func[funcNo + 3]; 143706f2543Smrg 144706f2543Smrg#ifdef TRIPLE_BITS 145706f2543Smrg if((bg == -1) || 146706f2543Smrg (!(infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) && 147706f2543Smrg (!(infoRec->CPUToScreenColorExpandFillFlags & RGB_EQUAL) || 148706f2543Smrg (CHECK_RGB_EQUAL(bg))))) { 149706f2543Smrg#else 150706f2543Smrg if((bg == -1) || 151706f2543Smrg !(infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) { 152706f2543Smrg#endif 153706f2543Smrg /* one pass */ 154706f2543Smrg } else if((rop == GXcopy) && infoRec->FillSolidRects) { 155706f2543Smrg /* one pass but we fill background rects first */ 156706f2543Smrg (*infoRec->FillSolidRects)(pScrn, bg, rop, planemask, nBox, pBox); 157706f2543Smrg bg = -1; 158706f2543Smrg } else { 159706f2543Smrg /* gotta do two passes */ 160706f2543Smrg TwoPass = TRUE; 161706f2543Smrg } 162706f2543Smrg 163706f2543Smrg if(!TwoPass) 164706f2543Smrg (*infoRec->SetupForCPUToScreenColorExpandFill)( 165706f2543Smrg pScrn, fg, bg, rop, planemask); 166706f2543Smrg 167706f2543Smrg while(nBox--) { 168706f2543Smrg#ifdef TRIPLE_BITS 169706f2543Smrg dwords = (3 * (pBox->x2 - pBox->x1) + 31) >> 5; 170706f2543Smrg#else 171706f2543Smrg dwords = (pBox->x2 - pBox->x1 + 31) >> 5; 172706f2543Smrg#endif 173706f2543Smrg 174706f2543SmrgSECOND_PASS: 175706f2543Smrg if(TwoPass) { 176706f2543Smrg (*infoRec->SetupForCPUToScreenColorExpandFill)(pScrn, 177706f2543Smrg (FirstPass) ? bg : fg, -1, rop, planemask); 178706f2543Smrg StippleFunc = (FirstPass) ? FirstFunc : SecondFunc; 179706f2543Smrg } 180706f2543Smrg 181706f2543Smrg h = pBox->y2 - pBox->y1; 182706f2543Smrg flag = (infoRec->CPUToScreenColorExpandFillFlags 183706f2543Smrg & CPU_TRANSFER_PAD_QWORD) && ((dwords * h) & 0x01); 184706f2543Smrg 185706f2543Smrg (*infoRec->SubsequentCPUToScreenColorExpandFill)( 186706f2543Smrg pScrn, pBox->x1, pBox->y1, 187706f2543Smrg pBox->x2 - pBox->x1, h, 0); 188706f2543Smrg 189706f2543Smrg base = (CARD32*)infoRec->ColorExpandBase; 190706f2543Smrg 191706f2543Smrg srcy = (pBox->y1 - yorg) % stippleheight; 192706f2543Smrg if(srcy < 0) srcy += stippleheight; 193706f2543Smrg srcx = (pBox->x1 - xorg) % stipplewidth; 194706f2543Smrg if(srcx < 0) srcx += stipplewidth; 195706f2543Smrg 196706f2543Smrg srcp = (srcwidth * srcy) + src; 197706f2543Smrg 198706f2543Smrg#ifndef FIXEDBASE 199706f2543Smrg if((dwords * h) <= infoRec->ColorExpandRange) { 200706f2543Smrg while(h--) { 201706f2543Smrg base = (*StippleFunc)( 202706f2543Smrg base, (CARD32*)srcp, srcx, stipplewidth, dwords); 203706f2543Smrg srcy++; 204706f2543Smrg srcp += srcwidth; 205706f2543Smrg if (srcy >= stippleheight) { 206706f2543Smrg srcy = 0; 207706f2543Smrg srcp = src; 208706f2543Smrg } 209706f2543Smrg } 210706f2543Smrg } else 211706f2543Smrg#endif 212706f2543Smrg while(h--) { 213706f2543Smrg (*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords); 214706f2543Smrg srcy++; 215706f2543Smrg srcp += srcwidth; 216706f2543Smrg if (srcy >= stippleheight) { 217706f2543Smrg srcy = 0; 218706f2543Smrg srcp = src; 219706f2543Smrg } 220706f2543Smrg } 221706f2543Smrg 222706f2543Smrg if (flag) { 223706f2543Smrg base = (CARD32*)infoRec->ColorExpandBase; 224706f2543Smrg base[0] = 0x00000000; 225706f2543Smrg } 226706f2543Smrg 227706f2543Smrg if(TwoPass) { 228706f2543Smrg if(FirstPass) { 229706f2543Smrg FirstPass = FALSE; 230706f2543Smrg goto SECOND_PASS; 231706f2543Smrg } else FirstPass = TRUE; 232706f2543Smrg } 233706f2543Smrg 234706f2543Smrg pBox++; 235706f2543Smrg } 236706f2543Smrg 237706f2543Smrg if(infoRec->CPUToScreenColorExpandFillFlags & SYNC_AFTER_COLOR_EXPAND) 238706f2543Smrg (*infoRec->Sync)(pScrn); 239706f2543Smrg else SET_SYNC_FLAG(infoRec); 240706f2543Smrg} 241706f2543Smrg 242706f2543Smrg 243706f2543Smrg 244706f2543Smrgvoid 245706f2543Smrg#ifdef TRIPLE_BITS 246706f2543SmrgEXPNAME(XAAFillColorExpandSpans3)( 247706f2543Smrg#else 248706f2543SmrgEXPNAME(XAAFillColorExpandSpans)( 249706f2543Smrg#endif 250706f2543Smrg ScrnInfoPtr pScrn, 251706f2543Smrg int fg, int bg, int rop, 252706f2543Smrg unsigned int planemask, 253706f2543Smrg int n, 254706f2543Smrg DDXPointPtr ppt, 255706f2543Smrg int *pwidth, 256706f2543Smrg int fSorted, 257706f2543Smrg int xorg, int yorg, 258706f2543Smrg PixmapPtr pPix 259706f2543Smrg){ 260706f2543Smrg XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 261706f2543Smrg CARD32 *base; 262706f2543Smrg Bool TwoPass = FALSE, FirstPass = TRUE; 263706f2543Smrg StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc; 264706f2543Smrg int stipplewidth = pPix->drawable.width; 265706f2543Smrg int stippleheight = pPix->drawable.height; 266706f2543Smrg int dwords, srcy, srcx, funcNo = 2; 267706f2543Smrg unsigned char *srcp; 268706f2543Smrg 269706f2543Smrg if(stipplewidth <= 32) { 270706f2543Smrg if(stipplewidth & (stipplewidth - 1)) 271706f2543Smrg funcNo = 1; 272706f2543Smrg else 273706f2543Smrg funcNo = 0; 274706f2543Smrg } 275706f2543Smrg StippleFunc = stipple_scanline_func[funcNo]; 276706f2543Smrg SecondFunc = stipple_scanline_func[funcNo]; 277706f2543Smrg FirstFunc = stipple_scanline_func[funcNo + 3]; 278706f2543Smrg 279706f2543Smrg#ifdef TRIPLE_BITS 280706f2543Smrg if((bg == -1) || 281706f2543Smrg (!(infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) && 282706f2543Smrg (!(infoRec->CPUToScreenColorExpandFillFlags & RGB_EQUAL) || 283706f2543Smrg (CHECK_RGB_EQUAL(bg))))) { 284706f2543Smrg#else 285706f2543Smrg if((bg == -1) || 286706f2543Smrg !(infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) { 287706f2543Smrg#endif 288706f2543Smrg /* one pass */ 289706f2543Smrg } else if((rop == GXcopy) && infoRec->FillSolidSpans) { 290706f2543Smrg /* one pass but we fill background rects first */ 291706f2543Smrg (*infoRec->FillSolidSpans)( 292706f2543Smrg pScrn, bg, rop, planemask, n, ppt, pwidth, fSorted); 293706f2543Smrg bg = -1; 294706f2543Smrg } else { 295706f2543Smrg /* gotta do two passes */ 296706f2543Smrg TwoPass = TRUE; 297706f2543Smrg } 298706f2543Smrg 299706f2543Smrg if(!TwoPass) 300706f2543Smrg (*infoRec->SetupForCPUToScreenColorExpandFill)( 301706f2543Smrg pScrn, fg, bg, rop, planemask); 302706f2543Smrg 303706f2543Smrg while(n--) { 304706f2543Smrg#ifdef TRIPLE_BITS 305706f2543Smrg dwords = (3 * *pwidth + 31) >> 5; 306706f2543Smrg#else 307706f2543Smrg dwords = (*pwidth + 31) >> 5; 308706f2543Smrg#endif 309706f2543Smrg 310706f2543Smrg srcy = (ppt->y - yorg) % stippleheight; 311706f2543Smrg if(srcy < 0) srcy += stippleheight; 312706f2543Smrg srcx = (ppt->x - xorg) % stipplewidth; 313706f2543Smrg if(srcx < 0) srcx += stipplewidth; 314706f2543Smrg 315706f2543Smrg srcp = (pPix->devKind * srcy) + (unsigned char*)pPix->devPrivate.ptr; 316706f2543Smrg 317706f2543SmrgSECOND_PASS: 318706f2543Smrg if(TwoPass) { 319706f2543Smrg (*infoRec->SetupForCPUToScreenColorExpandFill)(pScrn, 320706f2543Smrg (FirstPass) ? bg : fg, -1, rop, planemask); 321706f2543Smrg StippleFunc = (FirstPass) ? FirstFunc : SecondFunc; 322706f2543Smrg } 323706f2543Smrg 324706f2543Smrg (*infoRec->SubsequentCPUToScreenColorExpandFill)(pScrn, ppt->x, ppt->y, 325706f2543Smrg *pwidth, 1, 0); 326706f2543Smrg 327706f2543Smrg base = (CARD32*)infoRec->ColorExpandBase; 328706f2543Smrg 329706f2543Smrg (*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords); 330706f2543Smrg 331706f2543Smrg if((infoRec->CPUToScreenColorExpandFillFlags & CPU_TRANSFER_PAD_QWORD) 332706f2543Smrg && (dwords & 0x01)) { 333706f2543Smrg base = (CARD32*)infoRec->ColorExpandBase; 334706f2543Smrg base[0] = 0x00000000; 335706f2543Smrg } 336706f2543Smrg 337706f2543Smrg if(TwoPass) { 338706f2543Smrg if(FirstPass) { 339706f2543Smrg FirstPass = FALSE; 340706f2543Smrg goto SECOND_PASS; 341706f2543Smrg } else FirstPass = TRUE; 342706f2543Smrg } 343706f2543Smrg 344706f2543Smrg ppt++; pwidth++; 345706f2543Smrg } 346706f2543Smrg 347706f2543Smrg if(infoRec->CPUToScreenColorExpandFillFlags & SYNC_AFTER_COLOR_EXPAND) 348706f2543Smrg (*infoRec->Sync)(pScrn); 349706f2543Smrg else SET_SYNC_FLAG(infoRec); 350706f2543Smrg} 351706f2543Smrg 352706f2543Smrg 353706f2543Smrg#ifndef FIXEDBASE 354706f2543Smrg 355706f2543Smrgvoid 356706f2543Smrg#ifdef TRIPLE_BITS 357706f2543SmrgEXPNAME(XAAFillScanlineColorExpandRects3)( 358706f2543Smrg#else 359706f2543SmrgEXPNAME(XAAFillScanlineColorExpandRects)( 360706f2543Smrg#endif 361706f2543Smrg ScrnInfoPtr pScrn, 362706f2543Smrg int fg, int bg, int rop, 363706f2543Smrg unsigned int planemask, 364706f2543Smrg int nBox, 365706f2543Smrg BoxPtr pBox, 366706f2543Smrg int xorg, int yorg, 367706f2543Smrg PixmapPtr pPix 368706f2543Smrg){ 369706f2543Smrg XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 370706f2543Smrg CARD32 *base; 371706f2543Smrg Bool TwoPass = FALSE, FirstPass = TRUE; 372706f2543Smrg StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc; 373706f2543Smrg int stipplewidth = pPix->drawable.width; 374706f2543Smrg int stippleheight = pPix->drawable.height; 375706f2543Smrg int srcwidth = pPix->devKind; 376706f2543Smrg int dwords, srcy, srcx, funcNo = 2, bufferNo, h; 377706f2543Smrg unsigned char *src = pPix->devPrivate.ptr; 378706f2543Smrg unsigned char *srcp; 379706f2543Smrg 380706f2543Smrg if(stipplewidth <= 32) { 381706f2543Smrg if(stipplewidth & (stipplewidth - 1)) 382706f2543Smrg funcNo = 1; 383706f2543Smrg else 384706f2543Smrg funcNo = 0; 385706f2543Smrg } 386706f2543Smrg StippleFunc = stipple_scanline_func[funcNo]; 387706f2543Smrg SecondFunc = stipple_scanline_func[funcNo]; 388706f2543Smrg FirstFunc = stipple_scanline_func[funcNo + 3]; 389706f2543Smrg 390706f2543Smrg#ifdef TRIPLE_BITS 391706f2543Smrg if((bg == -1) || 392706f2543Smrg (!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) && 393706f2543Smrg (!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & RGB_EQUAL) || 394706f2543Smrg (CHECK_RGB_EQUAL(bg))))) { 395706f2543Smrg#else 396706f2543Smrg if((bg == -1) || 397706f2543Smrg !(infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) { 398706f2543Smrg#endif 399706f2543Smrg /* one pass */ 400706f2543Smrg } else if((rop == GXcopy) && infoRec->FillSolidRects) { 401706f2543Smrg /* one pass but we fill background rects first */ 402706f2543Smrg (*infoRec->FillSolidRects)(pScrn, bg, rop, planemask, nBox, pBox); 403706f2543Smrg bg = -1; 404706f2543Smrg } else { 405706f2543Smrg /* gotta do two passes */ 406706f2543Smrg TwoPass = TRUE; 407706f2543Smrg } 408706f2543Smrg 409706f2543Smrg if(!TwoPass) 410706f2543Smrg (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)( 411706f2543Smrg pScrn, fg, bg, rop, planemask); 412706f2543Smrg 413706f2543Smrg while(nBox--) { 414706f2543Smrg#ifdef TRIPLE_BITS 415706f2543Smrg dwords = (3 * (pBox->x2 - pBox->x1) + 31) >> 5; 416706f2543Smrg#else 417706f2543Smrg dwords = (pBox->x2 - pBox->x1 + 31) >> 5; 418706f2543Smrg#endif 419706f2543Smrg 420706f2543SmrgSECOND_PASS: 421706f2543Smrg if(TwoPass) { 422706f2543Smrg (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(pScrn, 423706f2543Smrg (FirstPass) ? bg : fg, -1, rop, planemask); 424706f2543Smrg StippleFunc = (FirstPass) ? FirstFunc : SecondFunc; 425706f2543Smrg } 426706f2543Smrg 427706f2543Smrg h = pBox->y2 - pBox->y1; 428706f2543Smrg 429706f2543Smrg (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)( 430706f2543Smrg pScrn, pBox->x1, pBox->y1, pBox->x2 - pBox->x1, h, 0); 431706f2543Smrg 432706f2543Smrg bufferNo = 0; 433706f2543Smrg 434706f2543Smrg srcy = (pBox->y1 - yorg) % stippleheight; 435706f2543Smrg if(srcy < 0) srcy += stippleheight; 436706f2543Smrg srcx = (pBox->x1 - xorg) % stipplewidth; 437706f2543Smrg if(srcx < 0) srcx += stipplewidth; 438706f2543Smrg 439706f2543Smrg srcp = (srcwidth * srcy) + src; 440706f2543Smrg 441706f2543Smrg while(h--) { 442706f2543Smrg base = (CARD32*)infoRec->ScanlineColorExpandBuffers[bufferNo]; 443706f2543Smrg (*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords); 444706f2543Smrg (*infoRec->SubsequentColorExpandScanline)(pScrn, bufferNo++); 445706f2543Smrg if(bufferNo >= infoRec->NumScanlineColorExpandBuffers) 446706f2543Smrg bufferNo = 0; 447706f2543Smrg srcy++; 448706f2543Smrg srcp += srcwidth; 449706f2543Smrg if (srcy >= stippleheight) { 450706f2543Smrg srcy = 0; 451706f2543Smrg srcp = src; 452706f2543Smrg } 453706f2543Smrg } 454706f2543Smrg 455706f2543Smrg if(TwoPass) { 456706f2543Smrg if(FirstPass) { 457706f2543Smrg FirstPass = FALSE; 458706f2543Smrg goto SECOND_PASS; 459706f2543Smrg } else FirstPass = TRUE; 460706f2543Smrg } 461706f2543Smrg 462706f2543Smrg pBox++; 463706f2543Smrg } 464706f2543Smrg 465706f2543Smrg SET_SYNC_FLAG(infoRec); 466706f2543Smrg} 467706f2543Smrg 468706f2543Smrgvoid 469706f2543Smrg#ifdef TRIPLE_BITS 470706f2543SmrgEXPNAME(XAAFillScanlineColorExpandSpans3)( 471706f2543Smrg#else 472706f2543SmrgEXPNAME(XAAFillScanlineColorExpandSpans)( 473706f2543Smrg#endif 474706f2543Smrg ScrnInfoPtr pScrn, 475706f2543Smrg int fg, int bg, int rop, 476706f2543Smrg unsigned int planemask, 477706f2543Smrg int n, 478706f2543Smrg DDXPointPtr ppt, 479706f2543Smrg int *pwidth, 480706f2543Smrg int fSorted, 481706f2543Smrg int xorg, int yorg, 482706f2543Smrg PixmapPtr pPix 483706f2543Smrg){ 484706f2543Smrg XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 485706f2543Smrg CARD32 *base; 486706f2543Smrg Bool TwoPass = FALSE, FirstPass = TRUE; 487706f2543Smrg StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc; 488706f2543Smrg int stipplewidth = pPix->drawable.width; 489706f2543Smrg int stippleheight = pPix->drawable.height; 490706f2543Smrg int dwords, srcy, srcx, funcNo = 2; 491706f2543Smrg unsigned char *srcp; 492706f2543Smrg 493706f2543Smrg if(stipplewidth <= 32) { 494706f2543Smrg if(stipplewidth & (stipplewidth - 1)) 495706f2543Smrg funcNo = 1; 496706f2543Smrg else 497706f2543Smrg funcNo = 0; 498706f2543Smrg } 499706f2543Smrg StippleFunc = stipple_scanline_func[funcNo]; 500706f2543Smrg SecondFunc = stipple_scanline_func[funcNo]; 501706f2543Smrg FirstFunc = stipple_scanline_func[funcNo + 3]; 502706f2543Smrg 503706f2543Smrg#ifdef TRIPLE_BITS 504706f2543Smrg if((bg == -1) || 505706f2543Smrg (!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) && 506706f2543Smrg (!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & RGB_EQUAL) || 507706f2543Smrg (CHECK_RGB_EQUAL(bg))))) { 508706f2543Smrg#else 509706f2543Smrg if((bg == -1) || 510706f2543Smrg !(infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) { 511706f2543Smrg#endif 512706f2543Smrg /* one pass */ 513706f2543Smrg } else if((rop == GXcopy) && infoRec->FillSolidSpans) { 514706f2543Smrg /* one pass but we fill background rects first */ 515706f2543Smrg (*infoRec->FillSolidSpans)( 516706f2543Smrg pScrn, bg, rop, planemask, n, ppt, pwidth, fSorted); 517706f2543Smrg bg = -1; 518706f2543Smrg } else { 519706f2543Smrg /* gotta do two passes */ 520706f2543Smrg TwoPass = TRUE; 521706f2543Smrg } 522706f2543Smrg 523706f2543Smrg if(!TwoPass) 524706f2543Smrg (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)( 525706f2543Smrg pScrn, fg, bg, rop, planemask); 526706f2543Smrg 527706f2543Smrg 528706f2543Smrg while(n--) { 529706f2543Smrg#ifdef TRIPLE_BITS 530706f2543Smrg dwords = (3 * *pwidth + 31) >> 5; 531706f2543Smrg#else 532706f2543Smrg dwords = (*pwidth + 31) >> 5; 533706f2543Smrg#endif 534706f2543Smrg 535706f2543Smrg srcy = (ppt->y - yorg) % stippleheight; 536706f2543Smrg if(srcy < 0) srcy += stippleheight; 537706f2543Smrg srcx = (ppt->x - xorg) % stipplewidth; 538706f2543Smrg if(srcx < 0) srcx += stipplewidth; 539706f2543Smrg 540706f2543Smrg srcp = (pPix->devKind * srcy) + (unsigned char*)pPix->devPrivate.ptr; 541706f2543Smrg 542706f2543SmrgSECOND_PASS: 543706f2543Smrg if(TwoPass) { 544706f2543Smrg (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(pScrn, 545706f2543Smrg (FirstPass) ? bg : fg, -1, rop, planemask); 546706f2543Smrg StippleFunc = (FirstPass) ? FirstFunc : SecondFunc; 547706f2543Smrg } 548706f2543Smrg 549706f2543Smrg (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)( 550706f2543Smrg pScrn, ppt->x, ppt->y, *pwidth, 1, 0); 551706f2543Smrg 552706f2543Smrg base = (CARD32*)infoRec->ScanlineColorExpandBuffers[0]; 553706f2543Smrg 554706f2543Smrg (*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords); 555706f2543Smrg (*infoRec->SubsequentColorExpandScanline)(pScrn, 0); 556706f2543Smrg 557706f2543Smrg if(TwoPass) { 558706f2543Smrg if(FirstPass) { 559706f2543Smrg FirstPass = FALSE; 560706f2543Smrg goto SECOND_PASS; 561706f2543Smrg } else FirstPass = TRUE; 562706f2543Smrg } 563706f2543Smrg 564706f2543Smrg ppt++; pwidth++; 565706f2543Smrg } 566706f2543Smrg 567706f2543Smrg SET_SYNC_FLAG(infoRec); 568706f2543Smrg} 569706f2543Smrg 570706f2543Smrg#endif 571706f2543Smrg 572706f2543Smrgstatic CARD32 * 573706f2543SmrgStipplePowerOfTwo( 574706f2543Smrg CARD32* dest, CARD32* src, 575706f2543Smrg int shift, int width, int dwords 576706f2543Smrg){ 577706f2543Smrg CARD32 pat = *src; 578706f2543Smrg if(width < 32) { 579706f2543Smrg pat &= XAAShiftMasks[width]; 580706f2543Smrg while(width < 32) { 581706f2543Smrg pat |= SHIFT_L(pat,width); 582706f2543Smrg width <<= 1; 583706f2543Smrg } 584706f2543Smrg } 585706f2543Smrg 586706f2543Smrg if(shift) 587706f2543Smrg pat = SHIFT_R(pat,shift) | SHIFT_L(pat,32 - shift); 588706f2543Smrg 589706f2543Smrg#ifdef MSBFIRST 590706f2543Smrg pat = SWAP_BITS_IN_BYTES(pat); 591706f2543Smrg#endif 592706f2543Smrg 593706f2543Smrg#ifdef TRIPLE_BITS 594706f2543Smrg { 595706f2543Smrg EXPAND_PAT; 596706f2543Smrg 597706f2543Smrg while(dwords >= 3) { 598706f2543Smrg WRITE_PAT3; 599706f2543Smrg dwords -= 3; 600706f2543Smrg } 601706f2543Smrg if (dwords == 2) { 602706f2543Smrg WRITE_PAT2; 603706f2543Smrg } else if (dwords == 1) { 604706f2543Smrg WRITE_PAT1; 605706f2543Smrg } 606706f2543Smrg 607706f2543Smrg return dest; 608706f2543Smrg } 609706f2543Smrg#else /* TRIPLE_BITS */ 610706f2543Smrg while(dwords >= 4) { 611706f2543Smrg DEST(0) = pat; 612706f2543Smrg DEST(1) = pat; 613706f2543Smrg DEST(2) = pat; 614706f2543Smrg DEST(3) = pat; 615706f2543Smrg dwords -= 4; 616706f2543Smrg#ifndef FIXEDBASE 617706f2543Smrg dest += 4; 618706f2543Smrg#endif 619706f2543Smrg } 620706f2543Smrg 621706f2543Smrg if(!dwords) return dest; 622706f2543Smrg DEST(0) = pat; 623706f2543Smrg if(dwords == 1) RETURN(1); 624706f2543Smrg DEST(1) = pat; 625706f2543Smrg if(dwords == 2) RETURN(2); 626706f2543Smrg DEST(2) = pat; 627706f2543Smrg RETURN(3); 628706f2543Smrg#endif /* TRIPLE_BITS */ 629706f2543Smrg} 630706f2543Smrg 631706f2543Smrgstatic CARD32 * 632706f2543SmrgStipplePowerOfTwo_Inverted( 633706f2543Smrg CARD32* dest, CARD32* src, 634706f2543Smrg int shift, int width, int dwords 635706f2543Smrg){ 636706f2543Smrg CARD32 pat = *src; 637706f2543Smrg if(width < 32) { 638706f2543Smrg pat &= XAAShiftMasks[width]; 639706f2543Smrg while(width < 32) { 640706f2543Smrg pat |= SHIFT_L(pat,width); 641706f2543Smrg width <<= 1; 642706f2543Smrg } 643706f2543Smrg } 644706f2543Smrg 645706f2543Smrg if(shift) 646706f2543Smrg pat = SHIFT_R(pat,shift) | SHIFT_L(pat,32 - shift); 647706f2543Smrg 648706f2543Smrg#ifdef MSBFIRST 649706f2543Smrg pat = SWAP_BITS_IN_BYTES(pat); 650706f2543Smrg#endif 651706f2543Smrg 652706f2543Smrg pat = ~pat; 653706f2543Smrg 654706f2543Smrg#ifdef TRIPLE_BITS 655706f2543Smrg { 656706f2543Smrg EXPAND_PAT; 657706f2543Smrg 658706f2543Smrg while(dwords >= 3) { 659706f2543Smrg WRITE_PAT3; 660706f2543Smrg dwords -= 3; 661706f2543Smrg } 662706f2543Smrg if (dwords == 2) { 663706f2543Smrg WRITE_PAT2; 664706f2543Smrg } else if (dwords == 1) { 665706f2543Smrg WRITE_PAT1; 666706f2543Smrg } 667706f2543Smrg 668706f2543Smrg return dest; 669706f2543Smrg } 670706f2543Smrg#else /* TRIPLE_BITS */ 671706f2543Smrg while(dwords >= 4) { 672706f2543Smrg DEST(0) = pat; 673706f2543Smrg DEST(1) = pat; 674706f2543Smrg DEST(2) = pat; 675706f2543Smrg DEST(3) = pat; 676706f2543Smrg dwords -= 4; 677706f2543Smrg#ifndef FIXEDBASE 678706f2543Smrg dest += 4; 679706f2543Smrg#endif 680706f2543Smrg } 681706f2543Smrg 682706f2543Smrg if(!dwords) return dest; 683706f2543Smrg DEST(0) = pat; 684706f2543Smrg if(dwords == 1) RETURN(1); 685706f2543Smrg DEST(1) = pat; 686706f2543Smrg if(dwords == 2) RETURN(2); 687706f2543Smrg DEST(2) = pat; 688706f2543Smrg RETURN(3); 689706f2543Smrg#endif /* TRIPLE_BITS */ 690706f2543Smrg} 691706f2543Smrg 692706f2543Smrg 693706f2543Smrgstatic CARD32 * 694706f2543SmrgStippleUpTo32( 695706f2543Smrg CARD32* base, CARD32* src, 696706f2543Smrg int shift, int width, int dwords 697706f2543Smrg){ 698706f2543Smrg CARD32 pat = *src & XAAShiftMasks[width]; 699706f2543Smrg 700706f2543Smrg while(width <= 15) { 701706f2543Smrg pat |= SHIFT_L(pat,width); 702706f2543Smrg width <<= 1; 703706f2543Smrg } 704706f2543Smrg pat |= SHIFT_L(pat,width); 705706f2543Smrg 706706f2543Smrg while(dwords--) { 707706f2543Smrg CARD32 bits = SHIFT_R(pat,shift) | SHIFT_L(pat,width-shift); 708706f2543Smrg#ifdef TRIPLE_BITS 709706f2543Smrg if(dwords >= 2) { 710706f2543Smrg WRITE_BITS3(bits); 711706f2543Smrg dwords -= 2; 712706f2543Smrg } else if(dwords > 0) { 713706f2543Smrg WRITE_BITS2(bits); 714706f2543Smrg dwords--; 715706f2543Smrg } else { 716706f2543Smrg WRITE_BITS1(bits); 717706f2543Smrg } 718706f2543Smrg#else 719706f2543Smrg WRITE_BITS(bits); 720706f2543Smrg#endif 721706f2543Smrg 722706f2543Smrg shift += 32; 723706f2543Smrg shift %= width; 724706f2543Smrg } 725706f2543Smrg return base; 726706f2543Smrg} 727706f2543Smrg 728706f2543Smrg 729706f2543Smrgstatic CARD32 * 730706f2543SmrgStippleUpTo32_Inverted( 731706f2543Smrg CARD32* base, CARD32* src, 732706f2543Smrg int shift, int width, int dwords 733706f2543Smrg){ 734706f2543Smrg CARD32 pat = *src & XAAShiftMasks[width]; 735706f2543Smrg 736706f2543Smrg while(width <= 15) { 737706f2543Smrg pat |= SHIFT_L(pat,width); 738706f2543Smrg width <<= 1; 739706f2543Smrg } 740706f2543Smrg pat |= SHIFT_L(pat,width); 741706f2543Smrg 742706f2543Smrg while(dwords--) { 743706f2543Smrg CARD32 bits = ~(SHIFT_R(pat,shift) | SHIFT_L(pat,width-shift)); 744706f2543Smrg#ifdef TRIPLE_BITS 745706f2543Smrg if(dwords >= 2) { 746706f2543Smrg WRITE_BITS3(bits); 747706f2543Smrg dwords -= 2; 748706f2543Smrg } else if(dwords > 0) { 749706f2543Smrg WRITE_BITS2(bits); 750706f2543Smrg dwords--; 751706f2543Smrg } else { 752706f2543Smrg WRITE_BITS1(bits); 753706f2543Smrg } 754706f2543Smrg#else 755706f2543Smrg WRITE_BITS(bits); 756706f2543Smrg#endif 757706f2543Smrg 758706f2543Smrg shift += 32; 759706f2543Smrg shift %= width; 760706f2543Smrg } 761706f2543Smrg return base; 762706f2543Smrg} 763706f2543Smrg 764706f2543Smrg 765706f2543Smrgstatic CARD32 * 766706f2543SmrgStippleOver32( 767706f2543Smrg CARD32* base, CARD32* src, 768706f2543Smrg int offset, int width, int dwords 769706f2543Smrg){ 770706f2543Smrg CARD32* srcp; 771706f2543Smrg CARD32 bits; 772706f2543Smrg int bitsleft, shift, usable; 773706f2543Smrg 774706f2543Smrg while(dwords--) { 775706f2543Smrg bitsleft = width - offset; 776706f2543Smrg srcp = src + (offset >> 5); 777706f2543Smrg shift = offset & 31; 778706f2543Smrg usable = 32 - shift; 779706f2543Smrg 780706f2543Smrg if(bitsleft < 32) { 781706f2543Smrg if(bitsleft <= usable) { 782706f2543Smrg bits = SHIFT_L(*src,bitsleft) | 783706f2543Smrg (SHIFT_R(*srcp,shift) & XAAShiftMasks[bitsleft]); 784706f2543Smrg } else { 785706f2543Smrg bits = SHIFT_L(*src,bitsleft) | 786706f2543Smrg (SHIFT_L(srcp[1],usable) & XAAShiftMasks[bitsleft]) | 787706f2543Smrg (SHIFT_R(*srcp,shift) & XAAShiftMasks[usable]); 788706f2543Smrg } 789706f2543Smrg } 790706f2543Smrg else if(shift) 791706f2543Smrg bits = SHIFT_R(*srcp,shift) | SHIFT_L(srcp[1],usable); 792706f2543Smrg else 793706f2543Smrg bits = *srcp; 794706f2543Smrg 795706f2543Smrg#ifdef TRIPLE_BITS 796706f2543Smrg if(dwords >= 2) { 797706f2543Smrg WRITE_BITS3(bits); 798706f2543Smrg dwords -= 2; 799706f2543Smrg } else if(dwords > 0) { 800706f2543Smrg WRITE_BITS2(bits); 801706f2543Smrg dwords--; 802706f2543Smrg } else { 803706f2543Smrg WRITE_BITS1(bits); 804706f2543Smrg } 805706f2543Smrg#else 806706f2543Smrg WRITE_BITS(bits); 807706f2543Smrg#endif 808706f2543Smrg 809706f2543Smrg offset += 32; 810706f2543Smrg offset %= width; 811706f2543Smrg } 812706f2543Smrg return base; 813706f2543Smrg} 814706f2543Smrg 815706f2543Smrg 816706f2543Smrgstatic CARD32 * 817706f2543SmrgStippleOver32_Inverted( 818706f2543Smrg CARD32* base, CARD32* src, 819706f2543Smrg int offset, int width, int dwords 820706f2543Smrg){ 821706f2543Smrg CARD32* srcp; 822706f2543Smrg CARD32 bits; 823706f2543Smrg int bitsleft, shift, usable; 824706f2543Smrg 825706f2543Smrg while(dwords--) { 826706f2543Smrg bitsleft = width - offset; 827706f2543Smrg srcp = src + (offset >> 5); 828706f2543Smrg shift = offset & 31; 829706f2543Smrg usable = 32 - shift; 830706f2543Smrg 831706f2543Smrg if(bitsleft < 32) { 832706f2543Smrg if(bitsleft <= usable) { 833706f2543Smrg bits = SHIFT_L(*src,bitsleft) | 834706f2543Smrg (SHIFT_R(*srcp,shift) & XAAShiftMasks[bitsleft]); 835706f2543Smrg } else { 836706f2543Smrg bits = SHIFT_L(*src,bitsleft) | 837706f2543Smrg (SHIFT_L(srcp[1],usable) & XAAShiftMasks[bitsleft]) | 838706f2543Smrg (SHIFT_R(*srcp,shift) & XAAShiftMasks[usable]); 839706f2543Smrg } 840706f2543Smrg } 841706f2543Smrg else if(shift) 842706f2543Smrg bits = SHIFT_R(*srcp,shift) | SHIFT_L(srcp[1],usable); 843706f2543Smrg else 844706f2543Smrg bits = *srcp; 845706f2543Smrg 846706f2543Smrg bits = ~bits; 847706f2543Smrg 848706f2543Smrg#ifdef TRIPLE_BITS 849706f2543Smrg if(dwords >= 2) { 850706f2543Smrg WRITE_BITS3(bits); 851706f2543Smrg dwords -= 2; 852706f2543Smrg } else if(dwords > 0) { 853706f2543Smrg WRITE_BITS2(bits); 854706f2543Smrg dwords--; 855706f2543Smrg } else { 856706f2543Smrg WRITE_BITS1(bits); 857706f2543Smrg } 858706f2543Smrg#else 859706f2543Smrg WRITE_BITS(bits); 860706f2543Smrg#endif 861706f2543Smrg 862706f2543Smrg offset += 32; 863706f2543Smrg offset %= width; 864706f2543Smrg } 865706f2543Smrg return base; 866706f2543Smrg} 867