1 2 3#ifdef HAVE_XORG_CONFIG_H 4#include <xorg-config.h> 5#endif 6 7#include "xaa.h" 8#include "xaalocal.h" 9#include "xaacexp.h" 10#include "xf86.h" 11 12 13/********** byte swapping ***************/ 14 15 16#ifdef FIXEDBASE 17# define DEST(i) *dest 18# define RETURN(i) return(dest) 19#else 20# define DEST(i) dest[i] 21# define RETURN(i) return(dest + i) 22#endif 23 24#ifdef MSBFIRST 25# define SOURCE(i) SWAP_BITS_IN_BYTES(src[i]) 26#else 27# define SOURCE(i) src[i] 28#endif 29 30 31typedef CARD32 *(* BitmapScanlineProcPtr)(CARD32 *, CARD32 *, int, int); 32 33#ifdef TRIPLE_BITS 34static CARD32* 35BitmapScanline( 36 CARD32 *src, CARD32 *base, 37 int count, int skipleft ) 38{ 39 CARD32 bits; 40 41 while(count >= 3) { 42 bits = *src; 43 WRITE_BITS3(bits); 44 src++; 45 count -= 3; 46 } 47 if (count == 2) { 48 bits = *src; 49 WRITE_BITS2(bits); 50 } else if (count == 1) { 51 bits = *src; 52 WRITE_BITS1(bits); 53 } 54 55 return base; 56} 57 58static CARD32* 59BitmapScanline_Inverted( 60 CARD32 *src, CARD32 *base, 61 int count, int skipleft ) 62{ 63 CARD32 bits; 64 65 while(count >= 3) { 66 bits = ~(*src); 67 WRITE_BITS3(bits); 68 src++; 69 count -= 3; 70 } 71 if (count == 2) { 72 bits = ~(*src); 73 WRITE_BITS2(bits); 74 } else if (count == 1) { 75 bits = ~(*src); 76 WRITE_BITS1(bits); 77 } 78 79 return base; 80} 81 82 83static CARD32* 84BitmapScanline_Shifted( 85 CARD32 *src, CARD32 *base, 86 int count, int skipleft ) 87{ 88 CARD32 bits; 89 90 while(count >= 3) { 91 bits = SHIFT_R(*src,skipleft) | SHIFT_L(*(src + 1),(32 - skipleft)); 92 WRITE_BITS3(bits); 93 src++; 94 count -= 3; 95 } 96 if (count == 2) { 97 bits = SHIFT_R(*src,skipleft) | SHIFT_L(*(src + 1),(32 - skipleft)); 98 WRITE_BITS2(bits); 99 } else if (count == 1) { 100 bits = SHIFT_R(*src,skipleft) | SHIFT_L(*(src + 1),(32 - skipleft)); 101 WRITE_BITS1(bits); 102 } 103 104 return base; 105} 106 107static CARD32* 108BitmapScanline_Shifted_Inverted( 109 CARD32 *src, CARD32 *base, 110 int count, int skipleft ) 111{ 112 CARD32 bits; 113 114 while(count >= 3) { 115 bits = ~(SHIFT_R(*src,skipleft) | SHIFT_L(*(src + 1),(32 - skipleft))); 116 WRITE_BITS3(bits); 117 src++; 118 count -= 3; 119 } 120 if (count == 2) { 121 bits = ~(SHIFT_R(*src,skipleft) | SHIFT_L(*(src + 1),(32 - skipleft))); 122 WRITE_BITS2(bits); 123 } else if (count == 1) { 124 bits = ~(SHIFT_R(*src,skipleft) | SHIFT_L(*(src + 1),(32 - skipleft))); 125 WRITE_BITS1(bits); 126 } 127 128 return base; 129} 130 131#define BitmapScanline_Shifted_Careful BitmapScanline_Shifted 132#define BitmapScanline_Shifted_Inverted_Careful BitmapScanline_Shifted_Inverted 133 134#else 135static CARD32* 136BitmapScanline( 137 CARD32 *src, CARD32 *dest, 138 int count, int skipleft ) 139{ 140 while(count >= 4) { 141 DEST(0) = SOURCE(0); 142 DEST(1) = SOURCE(1); 143 DEST(2) = SOURCE(2); 144 DEST(3) = SOURCE(3); 145 count -= 4; 146 src += 4; 147#ifndef FIXEDBASE 148 dest += 4; 149#endif 150 } 151 152 if(!count) return dest; 153 DEST(0) = SOURCE(0); 154 if(count == 1) RETURN(1); 155 DEST(1) = SOURCE(1); 156 if(count == 2) RETURN(2); 157 DEST(2) = SOURCE(2); 158 RETURN(3); 159} 160 161static CARD32* 162BitmapScanline_Inverted( 163 CARD32 *src, CARD32 *dest, 164 int count, int skipleft ) 165{ 166 while(count >= 4) { 167 DEST(0) = ~SOURCE(0); 168 DEST(1) = ~SOURCE(1); 169 DEST(2) = ~SOURCE(2); 170 DEST(3) = ~SOURCE(3); 171 count -= 4; 172 src += 4; 173#ifndef FIXEDBASE 174 dest += 4; 175#endif 176 } 177 178 if(!count) return dest; 179 DEST(0) = ~SOURCE(0); 180 if(count == 1) RETURN(1); 181 DEST(1) = ~SOURCE(1); 182 if(count == 2) RETURN(2); 183 DEST(2) = ~SOURCE(2); 184 RETURN(3); 185} 186 187 188static CARD32* 189BitmapScanline_Shifted( 190 CARD32 *bits, CARD32 *base, 191 int count, int skipleft ) 192{ 193 while(count--) { 194 register CARD32 tmp = SHIFT_R(*bits,skipleft) | 195 SHIFT_L(*(bits + 1),(32 - skipleft)); 196 WRITE_BITS(tmp); 197 bits++; 198 } 199 return base; 200} 201 202static CARD32* 203BitmapScanline_Shifted_Inverted( 204 CARD32 *bits, CARD32 *base, 205 int count, int skipleft ) 206{ 207 while(count--) { 208 register CARD32 tmp = ~(SHIFT_R(*bits,skipleft) | 209 SHIFT_L(*(bits + 1),(32 - skipleft))); 210 WRITE_BITS(tmp); 211 bits++; 212 } 213 return base; 214} 215 216static CARD32* 217BitmapScanline_Shifted_Careful( 218 CARD32 *bits, CARD32 *base, 219 int count, int skipleft ) 220{ 221 register CARD32 tmp; 222 while(--count) { 223 tmp = SHIFT_R(*bits,skipleft) | SHIFT_L(*(bits + 1),(32 - skipleft)); 224 WRITE_BITS(tmp); 225 bits++; 226 } 227 tmp = SHIFT_R(*bits,skipleft); 228 WRITE_BITS(tmp); 229 230 return base; 231} 232 233static CARD32* 234BitmapScanline_Shifted_Inverted_Careful( 235 CARD32 *bits, CARD32 *base, 236 int count, int skipleft ) 237{ 238 register CARD32 tmp; 239 while(--count) { 240 tmp = ~(SHIFT_R(*bits,skipleft) | SHIFT_L(*(bits + 1),(32 - skipleft))); 241 WRITE_BITS(tmp); 242 bits++; 243 } 244 tmp = ~(SHIFT_R(*bits,skipleft)); 245 WRITE_BITS(tmp); 246 return base; 247} 248 249#endif 250 251/* 252 When the accelerator is TRANSPARENCY_ONLY, WriteBitmap can do 253 the fill in two passes, inverting the source on the second pass. 254 For GXcopy we can fill the backing rectangle as a solid rect and 255 avoid the invert. 256*/ 257 258void 259#ifdef TRIPLE_BITS 260EXPNAME(XAAWriteBitmapColorExpand3)( 261#else 262EXPNAME(XAAWriteBitmapColorExpand)( 263#endif 264 ScrnInfoPtr pScrn, 265 int x, int y, int w, int H, 266 unsigned char *src, 267 int srcwidth, 268 int skipleft, 269 int fg, int bg, 270 int rop, 271 unsigned int planemask 272) 273{ 274 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 275 CARD32* base; 276 unsigned char *srcp = src; 277 int SecondPassColor = -1; 278 int shift = 0, dwords; 279 BitmapScanlineProcPtr firstFunc; 280 BitmapScanlineProcPtr secondFunc; 281 int flag; 282 int h = H; 283 284#ifdef TRIPLE_BITS 285 if((bg != -1) && 286 ((infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) || 287 ((infoRec->CPUToScreenColorExpandFillFlags & RGB_EQUAL) && 288 (!CHECK_RGB_EQUAL(bg))))) { 289#else 290 if((bg != -1) && 291 (infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) { 292#endif 293 if((rop == GXcopy) && infoRec->SetupForSolidFill) { 294 (*infoRec->SetupForSolidFill)(pScrn, bg, rop, planemask); 295 (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h); 296 } else SecondPassColor = bg; 297 bg = -1; 298 } 299 300#ifdef TRIPLE_BITS 301 if(skipleft) { 302#else 303 if(skipleft && 304 (!(infoRec->CPUToScreenColorExpandFillFlags & LEFT_EDGE_CLIPPING) || 305 (!(infoRec->CPUToScreenColorExpandFillFlags & LEFT_EDGE_CLIPPING_NEGATIVE_X) && 306 (skipleft > x)))) { 307#endif 308 if((skipleft + ((w + 31) & ~31)) > ((skipleft + w + 31) & ~31)) { 309 /* don't read past the end */ 310 firstFunc = BitmapScanline_Shifted_Careful; 311 secondFunc = BitmapScanline_Shifted_Inverted_Careful; 312 } else { 313 firstFunc = BitmapScanline_Shifted; 314 secondFunc = BitmapScanline_Shifted_Inverted; 315 } 316 shift = skipleft; 317 skipleft = 0; 318 } else { 319 firstFunc = BitmapScanline; 320 secondFunc = BitmapScanline_Inverted; 321 w += skipleft; 322 x -= skipleft; 323 } 324 325#ifdef TRIPLE_BITS 326 dwords = (3 * w + 31) >> 5; 327#else 328 dwords = (w + 31) >> 5; 329#endif 330 331SECOND_PASS: 332 333 flag = (infoRec->CPUToScreenColorExpandFillFlags 334 & CPU_TRANSFER_PAD_QWORD) && ((dwords * h) & 0x01); 335 (*infoRec->SetupForCPUToScreenColorExpandFill)( 336 pScrn, fg, bg, rop, planemask); 337 (*infoRec->SubsequentCPUToScreenColorExpandFill)( 338 pScrn, x, y, w, h, skipleft); 339 340 base = (CARD32*)infoRec->ColorExpandBase; 341 342#ifndef FIXEDBASE 343 if((dwords * h) <= infoRec->ColorExpandRange) 344 while(h--) { 345 base = (*firstFunc)((CARD32*)srcp, base, dwords, shift); 346 srcp += srcwidth; 347 } 348 else 349#endif 350 while(h--) { 351 (*firstFunc)((CARD32*)srcp, base, dwords, shift); 352 srcp += srcwidth; 353 } 354 355 if(flag){ 356 base = (CARD32*)infoRec->ColorExpandBase; 357 base[0] = 0x00000000; 358 } 359 360 if(SecondPassColor != -1) { 361 h = H; /* Reset height */ 362 fg = SecondPassColor; 363 SecondPassColor = -1; 364 firstFunc = secondFunc; 365 srcp = src; 366 goto SECOND_PASS; 367 } 368 369 if(infoRec->CPUToScreenColorExpandFillFlags & SYNC_AFTER_COLOR_EXPAND) 370 (*infoRec->Sync)(pScrn); 371 else SET_SYNC_FLAG(infoRec); 372} 373 374#ifndef FIXEDBASE 375 376void 377#ifdef TRIPLE_BITS 378EXPNAME(XAAWriteBitmapScanlineColorExpand3)( 379#else 380EXPNAME(XAAWriteBitmapScanlineColorExpand)( 381#endif 382 ScrnInfoPtr pScrn, 383 int x, int y, int w, int h, 384 unsigned char *src, 385 int srcwidth, 386 int skipleft, 387 int fg, int bg, 388 int rop, 389 unsigned int planemask 390) 391{ 392 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 393 CARD32* base; 394 unsigned char *srcp = src; 395 int SecondPassColor = -1; 396 int shift = 0, dwords, bufferNo; 397 BitmapScanlineProcPtr firstFunc; 398 BitmapScanlineProcPtr secondFunc; 399 400#ifdef TRIPLE_BITS 401 if((bg != -1) && 402 ((infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) 403 || ((infoRec->ScanlineCPUToScreenColorExpandFillFlags & RGB_EQUAL) && 404 (!CHECK_RGB_EQUAL(bg))))) { 405#else 406 if((bg != -1) && 407 (infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)){ 408#endif 409 if((rop == GXcopy) && infoRec->SetupForSolidFill) { 410 (*infoRec->SetupForSolidFill)(pScrn, bg, rop, planemask); 411 (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h); 412 } else SecondPassColor = bg; 413 bg = -1; 414 } 415 416#ifdef TRIPLE_BITS 417 if(skipleft) { 418#else 419 if(skipleft && 420 (!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & 421 LEFT_EDGE_CLIPPING) || 422 (!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & 423 LEFT_EDGE_CLIPPING_NEGATIVE_X) && (skipleft > x)))) { 424#endif 425 if((skipleft + ((w + 31) & ~31)) > ((skipleft + w + 31) & ~31)) { 426 /* don't read past the end */ 427 firstFunc = BitmapScanline_Shifted_Careful; 428 secondFunc = BitmapScanline_Shifted_Inverted_Careful; 429 } else { 430 firstFunc = BitmapScanline_Shifted; 431 secondFunc = BitmapScanline_Shifted_Inverted; 432 } 433 shift = skipleft; 434 skipleft = 0; 435 } else { 436 firstFunc = BitmapScanline; 437 secondFunc = BitmapScanline_Inverted; 438 w += skipleft; 439 x -= skipleft; 440 } 441 442#ifdef TRIPLE_BITS 443 dwords = (3 * w + 31) >> 5; 444#else 445 dwords = (w + 31) >> 5; 446#endif 447 448SECOND_PASS: 449 450 (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(pScrn, fg, bg, rop, planemask); 451 (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)( 452 pScrn, x, y, w, h, skipleft); 453 454 bufferNo = 0; 455 456 while(h--) { 457 base = (CARD32*)infoRec->ScanlineColorExpandBuffers[bufferNo]; 458 (*firstFunc)((CARD32*)srcp, base, dwords, shift); 459 (*infoRec->SubsequentColorExpandScanline)(pScrn, bufferNo++); 460 srcp += srcwidth; 461 if(bufferNo >= infoRec->NumScanlineColorExpandBuffers) 462 bufferNo = 0; 463 } 464 465 if(SecondPassColor != -1) { 466 fg = SecondPassColor; 467 SecondPassColor = -1; 468 firstFunc = secondFunc; 469 srcp = src; 470 goto SECOND_PASS; 471 } 472 473 SET_SYNC_FLAG(infoRec); 474} 475 476#endif 477