1 2#ifdef HAVE_XORG_CONFIG_H 3#include <xorg-config.h> 4#endif 5 6#include "misc.h" 7#include "xf86.h" 8#include "xf86_OSproc.h" 9#include "servermd.h" 10 11#include <X11/X.h> 12#include "scrnintstr.h" 13#include "mi.h" 14#include "pixmapstr.h" 15#include "xf86str.h" 16#include "xaa.h" 17#include "xaalocal.h" 18 19void XAAMoveDWORDS_FixedBase( 20 register CARD32* dest, 21 register CARD32* src, 22 register int dwords ) 23{ 24 while(dwords & ~0x03) { 25 *dest = *src; 26 *dest = *(src + 1); 27 *dest = *(src + 2); 28 *dest = *(src + 3); 29 dwords -= 4; 30 src += 4; 31 } 32 33 if(!dwords) return; 34 *dest = *src; 35 if(dwords == 1) return; 36 *dest = *(src + 1); 37 if(dwords == 2) return; 38 *dest = *(src + 2); 39} 40 41void XAAMoveDWORDS( 42 register CARD32* dest, 43 register CARD32* src, 44 register int dwords ) 45{ 46 while(dwords & ~0x03) { 47 *dest = *src; 48 *(dest + 1) = *(src + 1); 49 *(dest + 2) = *(src + 2); 50 *(dest + 3) = *(src + 3); 51 src += 4; 52 dest += 4; 53 dwords -= 4; 54 } 55 if(!dwords) return; 56 *dest = *src; 57 if(dwords == 1) return; 58 *(dest + 1) = *(src + 1); 59 if(dwords == 2) return; 60 *(dest + 2) = *(src + 2); 61} 62 63void XAAMoveDWORDS_FixedSrc( 64 register CARD32* dest, 65 register CARD32* src, 66 register int dwords ) 67{ 68 while(dwords & ~0x03) { 69 *dest = *src; 70 *(dest + 1) = *src; 71 *(dest + 2) = *src; 72 *(dest + 3) = *src; 73 dest += 4; 74 dwords -= 4; 75 } 76 if(!dwords) return; 77 *dest = *src; 78 if(dwords == 1) return; 79 *(dest + 1) = *src; 80 if(dwords == 2) return; 81 *(dest + 2) = *src; 82} 83 84static void 85XAAWritePixmap32To24( 86 ScrnInfoPtr pScrn, 87 int x, int y, int w, int h, 88 unsigned char *srcInit, 89 int srcwidth, /* bytes */ 90 int rop, 91 unsigned int planemask, 92 int trans 93){ 94 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 95 int count, dwords = bytes_to_int32(w * 3); 96 CARD32 *src, *dst; 97 Bool PlusOne = FALSE; 98 99 if((infoRec->ImageWriteFlags & CPU_TRANSFER_PAD_QWORD) && 100 ((dwords * h) & 0x01)) { 101 PlusOne = TRUE; 102 } 103 104 (*infoRec->SetupForImageWrite)(pScrn, rop, planemask, trans, 24, 24); 105 (*infoRec->SubsequentImageWriteRect)(pScrn, x, y, w, h, 0); 106 107 if(dwords > infoRec->ImageWriteRange) { 108 dst = (CARD32*)infoRec->ImageWriteBase; 109 while(h--) { 110 src = (CARD32*)srcInit; 111 count = w; 112 113 while(count >= 4) { 114 *dst = (src[0] & 0x00ffffff) | (src[1] << 24); 115 *dst = ((src[1] >> 8) & 0x0000ffff) | (src[2] << 16); 116 *dst = ((src[2] >> 16) & 0x000000ff) | (src[3] << 8); 117 src += 4; 118 count -= 4; 119 } 120 switch(count) { 121 case 0: break; 122 case 1: *dst = src[0]; 123 break; 124 case 2: *dst = (src[0] & 0x00ffffff) | (src[1] << 24); 125 *dst = src[1] >> 8; 126 break; 127 default: *dst = (src[0] & 0x00ffffff) | (src[1] << 24); 128 *dst = ((src[1] >> 8) & 0x0000ffff) | (src[2] << 16); 129 *dst = src[2] >> 16; 130 break; 131 } 132 srcInit += srcwidth; 133 } 134 } else { 135 while(h--) { 136 dst = (CARD32*)infoRec->ImageWriteBase; 137 src = (CARD32*)srcInit; 138 count = w; 139 140 while(count >= 4) { 141 dst[0] = (src[0] & 0x00ffffff) | (src[1] << 24); 142 dst[1] = ((src[1] >> 8) & 0x0000ffff) | (src[2] << 16); 143 dst[2] = ((src[2] >> 16) & 0x000000ff) | (src[3] << 8); 144 dst += 3; 145 src += 4; 146 count -= 4; 147 } 148 switch(count) { 149 case 0: break; 150 case 1: dst[0] = src[0]; 151 break; 152 case 2: dst[0] = (src[0] & 0x00ffffff) | (src[1] << 24); 153 dst[1] = src[1] >> 8; 154 break; 155 default: dst[0] = (src[0] & 0x00ffffff) | (src[1] << 24); 156 dst[1] = ((src[1] >> 8) & 0x0000ffff) | (src[2] << 16); 157 dst[2] = src[2] >> 16; 158 break; 159 } 160 srcInit += srcwidth; 161 } 162 } 163 164 if(PlusOne) { 165 CARD32* base = (CARD32*)infoRec->ImageWriteBase; 166 *base = 0x00000000; 167 } 168 169 if(infoRec->ImageWriteFlags & SYNC_AFTER_IMAGE_WRITE) 170 (*infoRec->Sync)(pScrn); 171 else SET_SYNC_FLAG(infoRec); 172 173} 174 175void 176XAAWritePixmap ( 177 ScrnInfoPtr pScrn, 178 int x, int y, int w, int h, 179 unsigned char *src, 180 int srcwidth, /* bytes */ 181 int rop, 182 unsigned int planemask, 183 int trans, 184 int bpp, int depth 185){ 186 XAAInfoRecPtr infoRec; 187 int dwords, skipleft, Bpp; 188 Bool beCareful, PlusOne; 189 190 if((bpp == 32) && (pScrn->bitsPerPixel == 24)) { 191 XAAWritePixmap32To24(pScrn, x, y, w, h, src, srcwidth, 192 rop, planemask, trans); 193 return; 194 } 195 196 infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 197 beCareful = PlusOne = FALSE; 198 Bpp = bpp >> 3; 199 200 if((skipleft = (long)src & 0x03L)) { 201 if(!(infoRec->ImageWriteFlags & LEFT_EDGE_CLIPPING)) { 202 skipleft = 0; 203 beCareful = TRUE; 204 goto BAD_ALIGNMENT; 205 } 206 207 if(Bpp == 3) 208 skipleft = 4 - skipleft; 209 else 210 skipleft /= Bpp; 211 212 if((x < skipleft) && !(infoRec->ImageWriteFlags & 213 LEFT_EDGE_CLIPPING_NEGATIVE_X)) { 214 skipleft = 0; 215 beCareful = TRUE; 216 goto BAD_ALIGNMENT; 217 } 218 219 x -= skipleft; 220 w += skipleft; 221 222 if(Bpp == 3) 223 src -= 3 * skipleft; 224 else /* is this Alpha friendly ? */ 225 src = (unsigned char*)((long)src & ~0x03L); 226 } 227 228BAD_ALIGNMENT: 229 230 dwords = bytes_to_int32(w * Bpp); 231 232 if((infoRec->ImageWriteFlags & CPU_TRANSFER_PAD_QWORD) && 233 ((dwords * h) & 0x01)) { 234 PlusOne = TRUE; 235 } 236 237 238 (*infoRec->SetupForImageWrite)(pScrn, rop, planemask, trans, bpp, depth); 239 (*infoRec->SubsequentImageWriteRect)(pScrn, x, y, w, h, skipleft); 240 241 if(beCareful) { 242 /* in cases with bad alignment we have to be careful not 243 to read beyond the end of the source */ 244 if(((x * Bpp) + (dwords << 2)) > srcwidth) h--; 245 else beCareful = FALSE; 246 } 247 248 if(dwords > infoRec->ImageWriteRange) { 249 while(h--) { 250 XAAMoveDWORDS_FixedBase((CARD32*)infoRec->ImageWriteBase, 251 (CARD32*)src, dwords); 252 src += srcwidth; 253 } 254 if(beCareful) { 255 int shift = ((long)src & 0x03L) << 3; 256 if(--dwords) 257 XAAMoveDWORDS_FixedBase((CARD32*)infoRec->ImageWriteBase, 258 (CARD32*)src, dwords); 259 src = (unsigned char*)((long)(src + (dwords << 2)) & ~0x03L); 260 *((CARD32*)infoRec->ImageWriteBase) = *((CARD32*)src) >> shift; 261 } 262 } else { 263 if(srcwidth == (dwords << 2)) { 264 int decrement = infoRec->ImageWriteRange/dwords; 265 266 while(h > decrement) { 267 XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase, 268 (CARD32*)src, dwords * decrement); 269 src += (srcwidth * decrement); 270 h -= decrement; 271 } 272 if(h) { 273 XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase, 274 (CARD32*)src, dwords * h); 275 if(beCareful) src += (srcwidth * h); 276 } 277 } else { 278 while(h--) { 279 XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase, 280 (CARD32*)src, dwords); 281 src += srcwidth; 282 } 283 } 284 285 if(beCareful) { 286 int shift = ((long)src & 0x03L) << 3; 287 if(--dwords) 288 XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase, 289 (CARD32*)src, dwords); 290 src = (unsigned char*)((long)(src + (dwords << 2)) & ~0x03L); 291 292 ((CARD32*)infoRec->ImageWriteBase)[dwords] = 293 *((CARD32*)src) >> shift; 294 } 295 } 296 297 if(PlusOne) { 298 CARD32* base = (CARD32*)infoRec->ImageWriteBase; 299 *base = 0x00000000; 300 } 301 302 if(infoRec->ImageWriteFlags & SYNC_AFTER_IMAGE_WRITE) 303 (*infoRec->Sync)(pScrn); 304 else SET_SYNC_FLAG(infoRec); 305} 306 307 308void 309XAAWritePixmapScanline ( 310 ScrnInfoPtr pScrn, 311 int x, int y, int w, int h, 312 unsigned char *src, 313 int srcwidth, /* bytes */ 314 int rop, 315 unsigned int planemask, 316 int trans, 317 int bpp, int depth 318){ 319 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 320 int dwords, skipleft, bufferNo = 0, Bpp = bpp >> 3; 321 Bool beCareful = FALSE; 322 CARD32* base; 323 324 if((skipleft = (long)src & 0x03L)) { 325 if(!(infoRec->ScanlineImageWriteFlags & LEFT_EDGE_CLIPPING)) { 326 skipleft = 0; 327 beCareful = TRUE; 328 goto BAD_ALIGNMENT; 329 } 330 331 if(Bpp == 3) 332 skipleft = 4 - skipleft; 333 else 334 skipleft /= Bpp; 335 336 if((x < skipleft) && !(infoRec->ScanlineImageWriteFlags & 337 LEFT_EDGE_CLIPPING_NEGATIVE_X)) { 338 skipleft = 0; 339 beCareful = TRUE; 340 goto BAD_ALIGNMENT; 341 } 342 343 x -= skipleft; 344 w += skipleft; 345 346 if(Bpp == 3) 347 src -= 3 * skipleft; 348 else 349 src = (unsigned char*)((long)src & ~0x03L); 350 } 351 352BAD_ALIGNMENT: 353 354 dwords = bytes_to_int32(w * Bpp); 355 356 (*infoRec->SetupForScanlineImageWrite)( 357 pScrn, rop, planemask, trans, bpp, depth); 358 (*infoRec->SubsequentScanlineImageWriteRect)(pScrn, x, y, w, h, skipleft); 359 360 if(beCareful) { 361 /* in cases with bad alignment we have to be careful not 362 to read beyond the end of the source */ 363 if(((x * Bpp) + (dwords << 2)) > srcwidth) h--; 364 else beCareful = FALSE; 365 } 366 367 while(h--) { 368 base = (CARD32*)infoRec->ScanlineImageWriteBuffers[bufferNo]; 369 XAAMoveDWORDS(base, (CARD32*)src, dwords); 370 (*infoRec->SubsequentImageWriteScanline)(pScrn, bufferNo++); 371 src += srcwidth; 372 if(bufferNo >= infoRec->NumScanlineImageWriteBuffers) 373 bufferNo = 0; 374 } 375 376 if(beCareful) { 377 int shift = ((long)src & 0x03L) << 3; 378 base = (CARD32*)infoRec->ScanlineImageWriteBuffers[bufferNo]; 379 if(--dwords) 380 XAAMoveDWORDS(base,(CARD32*)src, dwords); 381 src = (unsigned char*)((long)(src + (dwords << 2)) & ~0x03L); 382 383 base[dwords] = *((CARD32*)src) >> shift; 384 (*infoRec->SubsequentImageWriteScanline)(pScrn, bufferNo); 385 } 386 387 SET_SYNC_FLAG(infoRec); 388} 389 390 391void 392XAAPutImage( 393 DrawablePtr pDraw, 394 GCPtr pGC, 395 int depth, 396 int x, 397 int y, 398 int w, 399 int h, 400 int leftPad, 401 int format, 402 char *pImage 403){ 404 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); 405 int bpp = BitsPerPixel(depth); 406 Bool depthBug = FALSE; 407 if(!w || !h) return; 408 409 if(!RegionNumRects(pGC->pCompositeClip)) 410 return; 411 412 depthBug = XAA_DEPTH_BUG(pGC); 413 414 if(((format == ZPixmap) && infoRec->WritePixmap && 415 ((pDraw->bitsPerPixel == bpp) || 416 ((pDraw->bitsPerPixel == 24) && (bpp == 32) && 417 (infoRec->WritePixmapFlags & CONVERT_32BPP_TO_24BPP))) && 418 CHECK_ROP(pGC,infoRec->WritePixmapFlags) && 419 CHECK_ROPSRC(pGC,infoRec->WritePixmapFlags) && 420 CHECK_PLANEMASK(pGC,infoRec->WritePixmapFlags) && 421 CHECK_NO_GXCOPY(pGC,infoRec->WritePixmapFlags)) || 422 ((format == XYBitmap) && !depthBug && infoRec->WriteBitmap && 423 CHECK_ROP(pGC,infoRec->WriteBitmapFlags) && 424 CHECK_ROPSRC(pGC,infoRec->WriteBitmapFlags) && 425 CHECK_PLANEMASK(pGC,infoRec->WriteBitmapFlags) && 426 CHECK_COLORS(pGC,infoRec->WriteBitmapFlags) && 427 !(infoRec->WriteBitmapFlags & TRANSPARENCY_ONLY)) || 428 ((format == XYPixmap) && !depthBug && infoRec->WriteBitmap && 429 CHECK_ROP(pGC,infoRec->WriteBitmapFlags) && 430 CHECK_ROPSRC(pGC,infoRec->WriteBitmapFlags) && 431 !(infoRec->WriteBitmapFlags & NO_PLANEMASK) && 432 !(infoRec->WriteBitmapFlags & TRANSPARENCY_ONLY))){ 433 434 int MaxBoxes = RegionNumRects(pGC->pCompositeClip); 435 BoxPtr pbox, pClipBoxes; 436 int nboxes, srcx, srcy, srcwidth; 437 xRectangle TheRect; 438 439 TheRect.x = pDraw->x + x; 440 TheRect.y = pDraw->y + y; 441 TheRect.width = w; 442 TheRect.height = h; 443 444 if(MaxBoxes > (infoRec->PreAllocSize/sizeof(BoxRec))) { 445 pClipBoxes = malloc(MaxBoxes * sizeof(BoxRec)); 446 if(!pClipBoxes) return; 447 } else pClipBoxes = (BoxPtr)infoRec->PreAllocMem; 448 449 nboxes = XAAGetRectClipBoxes(pGC, pClipBoxes, 1, &TheRect); 450 pbox = pClipBoxes; 451 452 if(format == XYBitmap) { 453 srcwidth = BitmapBytePad(leftPad + w); 454 while(nboxes--) { 455 srcx = pbox->x1 - TheRect.x + leftPad; 456 srcy = pbox->y1 - TheRect.y; 457 (*infoRec->WriteBitmap)(infoRec->pScrn, pbox->x1, pbox->y1, 458 pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, 459 (unsigned char*)pImage + 460 (srcwidth * srcy) + ((srcx >> 5) << 2), 461 srcwidth, srcx & 31, pGC->fgPixel, pGC->bgPixel, 462 pGC->alu, pGC->planemask); 463 pbox++; 464 } 465 } else if(format == ZPixmap) { 466 int Bpp = bpp >> 3; 467 srcwidth = PixmapBytePad(leftPad + w, depth); 468 while(nboxes--) { 469 srcx = pbox->x1 - TheRect.x + leftPad; 470 srcy = pbox->y1 - TheRect.y; 471 (*infoRec->WritePixmap)(infoRec->pScrn, pbox->x1, pbox->y1, 472 pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, 473 (unsigned char*)pImage + 474 (srcwidth * srcy) + (srcx * Bpp), 475 srcwidth, pGC->alu, pGC->planemask, -1, 476 Bpp << 3, depth); 477 pbox++; 478 } 479 } else { /* XYPixmap */ 480 int depth = pGC->depth; 481 int numBox, increment; 482 unsigned long i, mask; 483 BoxPtr pntBox; 484 485 srcwidth = BitmapBytePad(w + leftPad); 486 increment = h * srcwidth; 487 i = 1 << (depth - 1); 488 mask = ~0; 489 490 if((infoRec->pScrn->overlayFlags & OVERLAY_8_32_PLANAR) && 491 (pGC->depth == 8)){ 492 i = 0x80000000; mask = 0xff000000; 493 } 494 495 for(; i & mask; i >>= 1, pImage += increment) { 496 if(i & pGC->planemask) { 497 pntBox = pbox; 498 numBox = nboxes; 499 while(numBox--) { 500 srcx = pntBox->x1 - TheRect.x + leftPad; 501 srcy = pntBox->y1 - TheRect.y; 502 (*infoRec->WriteBitmap)(infoRec->pScrn, 503 pntBox->x1, pntBox->y1, 504 pntBox->x2 - pntBox->x1, 505 pntBox->y2 - pntBox->y1, 506 (unsigned char*)pImage + 507 (srcwidth * srcy) + ((srcx >> 5) << 2), 508 srcwidth, srcx & 31, ~0, 0, pGC->alu, i); 509 pntBox++; 510 } 511 } 512 } 513 514 } 515 516 if(pClipBoxes != (BoxPtr)infoRec->PreAllocMem) 517 free(pClipBoxes); 518 } else 519 XAAFallbackOps.PutImage(pDraw, pGC, depth, x, y, w, h, leftPad, 520 format, pImage); 521} 522