e:/XFree86 for RH 8.0/XFree86-4.2.0/xc/programs/Xserver/hw/xfree86/xaa/xaaImage.c

Go to the documentation of this file.
00001 /* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaImage.c,v 1.19 2000/04/01 22:42:04 mvojkovi Exp $ */ 00002 00003 #include "misc.h" 00004 #include "xf86.h" 00005 #include "xf86_ansic.h" 00006 #include "xf86_OSproc.h" 00007 #include "servermd.h" 00008 00009 #include "X.h" 00010 #include "scrnintstr.h" 00011 #include "mi.h" 00012 #include "pixmapstr.h" 00013 #include "xf86str.h" 00014 #include "xaa.h" 00015 #include "xaalocal.h" 00016 00017 void XAAMoveDWORDS_FixedBase( 00018 register CARD32* dest, 00019 register CARD32* src, 00020 register int dwords ) 00021 { 00022 while(dwords & ~0x03) { 00023 *dest = *src; 00024 *dest = *(src + 1); 00025 *dest = *(src + 2); 00026 *dest = *(src + 3); 00027 dwords -= 4; 00028 src += 4; 00029 } 00030 00031 if(!dwords) return; 00032 *dest = *src; 00033 if(dwords == 1) return; 00034 *dest = *(src + 1); 00035 if(dwords == 2) return; 00036 *dest = *(src + 2); 00037 } 00038 00039 void XAAMoveDWORDS( 00040 register CARD32* dest, 00041 register CARD32* src, 00042 register int dwords ) 00043 { 00044 while(dwords & ~0x03) { 00045 *dest = *src; 00046 *(dest + 1) = *(src + 1); 00047 *(dest + 2) = *(src + 2); 00048 *(dest + 3) = *(src + 3); 00049 src += 4; 00050 dest += 4; 00051 dwords -= 4; 00052 } 00053 if(!dwords) return; 00054 *dest = *src; 00055 if(dwords == 1) return; 00056 *(dest + 1) = *(src + 1); 00057 if(dwords == 2) return; 00058 *(dest + 2) = *(src + 2); 00059 } 00060 00061 void XAAMoveDWORDS_FixedSrc( 00062 register CARD32* dest, 00063 register CARD32* src, 00064 register int dwords ) 00065 { 00066 while(dwords & ~0x03) { 00067 *dest = *src; 00068 *(dest + 1) = *src; 00069 *(dest + 2) = *src; 00070 *(dest + 3) = *src; 00071 dest += 4; 00072 dwords -= 4; 00073 } 00074 if(!dwords) return; 00075 *dest = *src; 00076 if(dwords == 1) return; 00077 *(dest + 1) = *src; 00078 if(dwords == 2) return; 00079 *(dest + 2) = *src; 00080 } 00081 00082 static void 00083 XAAWritePixmap32To24( 00084 ScrnInfoPtr pScrn, 00085 int x, int y, int w, int h, 00086 unsigned char *srcInit, 00087 int srcwidth, /* bytes */ 00088 int rop, 00089 unsigned int planemask, 00090 int trans 00091 ){ 00092 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 00093 int count, dwords = ((w * 3) + 3) >> 2; 00094 CARD32 *src, *dst; 00095 Bool PlusOne = FALSE; 00096 00097 if((infoRec->ImageWriteFlags & CPU_TRANSFER_PAD_QWORD) && 00098 ((dwords * h) & 0x01)) { 00099 PlusOne = TRUE; 00100 } 00101 00102 (*infoRec->SetupForImageWrite)(pScrn, rop, planemask, trans, 24, 24); 00103 (*infoRec->SubsequentImageWriteRect)(pScrn, x, y, w, h, 0); 00104 00105 if(dwords > infoRec->ImageWriteRange) { 00106 dst = (CARD32*)infoRec->ImageWriteBase; 00107 while(h--) { 00108 src = (CARD32*)srcInit; 00109 count = w; 00110 00111 while(count >= 4) { 00112 *dst = (src[0] & 0x00ffffff) | (src[1] << 24); 00113 *dst = ((src[1] >> 8) & 0x0000ffff) | (src[2] << 16); 00114 *dst = ((src[2] >> 16) & 0x000000ff) | (src[3] << 8); 00115 src += 4; 00116 count -= 4; 00117 } 00118 switch(count) { 00119 case 0: break; 00120 case 1: *dst = src[0]; 00121 break; 00122 case 2: *dst = (src[0] & 0x00ffffff) | (src[1] << 24); 00123 *dst = src[1] >> 8; 00124 break; 00125 default: *dst = (src[0] & 0x00ffffff) | (src[1] << 24); 00126 *dst = ((src[1] >> 8) & 0x0000ffff) | (src[2] << 16); 00127 *dst = src[2] >> 16; 00128 break; 00129 } 00130 srcInit += srcwidth; 00131 } 00132 } else { 00133 while(h--) { 00134 dst = (CARD32*)infoRec->ImageWriteBase; 00135 src = (CARD32*)srcInit; 00136 count = w; 00137 00138 while(count >= 4) { 00139 dst[0] = (src[0] & 0x00ffffff) | (src[1] << 24); 00140 dst[1] = ((src[1] >> 8) & 0x0000ffff) | (src[2] << 16); 00141 dst[2] = ((src[2] >> 16) & 0x000000ff) | (src[3] << 8); 00142 dst += 3; 00143 src += 4; 00144 count -= 4; 00145 } 00146 switch(count) { 00147 case 0: break; 00148 case 1: dst[0] = src[0]; 00149 break; 00150 case 2: dst[0] = (src[0] & 0x00ffffff) | (src[1] << 24); 00151 dst[1] = src[1] >> 8; 00152 break; 00153 default: dst[0] = (src[0] & 0x00ffffff) | (src[1] << 24); 00154 dst[1] = ((src[1] >> 8) & 0x0000ffff) | (src[2] << 16); 00155 dst[2] = src[2] >> 16; 00156 break; 00157 } 00158 srcInit += srcwidth; 00159 } 00160 } 00161 00162 if(PlusOne) { 00163 CARD32* base = (CARD32*)infoRec->ImageWriteBase; 00164 *base = 0x00000000; 00165 } 00166 00167 if(infoRec->ImageWriteFlags & SYNC_AFTER_IMAGE_WRITE) 00168 (*infoRec->Sync)(pScrn); 00169 else SET_SYNC_FLAG(infoRec); 00170 00171 } 00172 00173 void 00174 XAAWritePixmap ( 00175 ScrnInfoPtr pScrn, 00176 int x, int y, int w, int h, 00177 unsigned char *src, 00178 int srcwidth, /* bytes */ 00179 int rop, 00180 unsigned int planemask, 00181 int trans, 00182 int bpp, int depth 00183 ){ 00184 XAAInfoRecPtr infoRec; 00185 int dwords, skipleft, Bpp; 00186 Bool beCareful, PlusOne; 00187 00188 if((bpp == 32) && (pScrn->bitsPerPixel == 24)) { 00189 XAAWritePixmap32To24(pScrn, x, y, w, h, src, srcwidth, 00190 rop, planemask, trans); 00191 return; 00192 } 00193 00194 infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 00195 beCareful = PlusOne = FALSE; 00196 Bpp = bpp >> 3; 00197 00198 if((skipleft = (long)src & 0x03L)) { 00199 if(!(infoRec->ImageWriteFlags & LEFT_EDGE_CLIPPING)) { 00200 skipleft = 0; 00201 beCareful = TRUE; 00202 goto BAD_ALIGNMENT; 00203 } 00204 00205 if(Bpp == 3) 00206 skipleft = 4 - skipleft; 00207 else 00208 skipleft /= Bpp; 00209 00210 if((x < skipleft) && !(infoRec->ImageWriteFlags & 00211 LEFT_EDGE_CLIPPING_NEGATIVE_X)) { 00212 skipleft = 0; 00213 beCareful = TRUE; 00214 goto BAD_ALIGNMENT; 00215 } 00216 00217 x -= skipleft; 00218 w += skipleft; 00219 00220 if(Bpp == 3) 00221 src -= 3 * skipleft; 00222 else /* is this Alpha friendly ? */ 00223 src = (unsigned char*)((long)src & ~0x03L); 00224 } 00225 00226 BAD_ALIGNMENT: 00227 00228 dwords = ((w * Bpp) + 3) >> 2; 00229 00230 if((infoRec->ImageWriteFlags & CPU_TRANSFER_PAD_QWORD) && 00231 ((dwords * h) & 0x01)) { 00232 PlusOne = TRUE; 00233 } 00234 00235 00236 (*infoRec->SetupForImageWrite)(pScrn, rop, planemask, trans, bpp, depth); 00237 (*infoRec->SubsequentImageWriteRect)(pScrn, x, y, w, h, skipleft); 00238 00239 if(beCareful) { 00240 /* in cases with bad alignment we have to be careful not 00241 to read beyond the end of the source */ 00242 if(((x * Bpp) + (dwords << 2)) > srcwidth) h--; 00243 else beCareful = FALSE; 00244 } 00245 00246 if(dwords > infoRec->ImageWriteRange) { 00247 while(h--) { 00248 XAAMoveDWORDS_FixedBase((CARD32*)infoRec->ImageWriteBase, 00249 (CARD32*)src, dwords); 00250 src += srcwidth; 00251 } 00252 if(beCareful) { 00253 int shift = ((long)src & 0x03L) << 3; 00254 if(--dwords) 00255 XAAMoveDWORDS_FixedBase((CARD32*)infoRec->ImageWriteBase, 00256 (CARD32*)src, dwords); 00257 src = (unsigned char*)((long)(src + (dwords << 2)) & ~0x03L); 00258 *((CARD32*)infoRec->ImageWriteBase) = *((CARD32*)src) >> shift; 00259 } 00260 } else { 00261 if(srcwidth == (dwords << 2)) { 00262 int decrement = infoRec->ImageWriteRange/dwords; 00263 00264 while(h > decrement) { 00265 XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase, 00266 (CARD32*)src, dwords * decrement); 00267 src += (srcwidth * decrement); 00268 h -= decrement; 00269 } 00270 if(h) { 00271 XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase, 00272 (CARD32*)src, dwords * h); 00273 if(beCareful) src += (srcwidth * h); 00274 } 00275 } else { 00276 while(h--) { 00277 XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase, 00278 (CARD32*)src, dwords); 00279 src += srcwidth; 00280 } 00281 } 00282 00283 if(beCareful) { 00284 int shift = ((long)src & 0x03L) << 3; 00285 if(--dwords) 00286 XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase, 00287 (CARD32*)src, dwords); 00288 src = (unsigned char*)((long)(src + (dwords << 2)) & ~0x03L); 00289 00290 ((CARD32*)infoRec->ImageWriteBase)[dwords] = 00291 *((CARD32*)src) >> shift; 00292 } 00293 } 00294 00295 if(PlusOne) { 00296 CARD32* base = (CARD32*)infoRec->ImageWriteBase; 00297 *base = 0x00000000; 00298 } 00299 00300 if(infoRec->ImageWriteFlags & SYNC_AFTER_IMAGE_WRITE) 00301 (*infoRec->Sync)(pScrn); 00302 else SET_SYNC_FLAG(infoRec); 00303 } 00304 00305 00306 void 00307 XAAWritePixmapScanline ( 00308 ScrnInfoPtr pScrn, 00309 int x, int y, int w, int h, 00310 unsigned char *src, 00311 int srcwidth, /* bytes */ 00312 int rop, 00313 unsigned int planemask, 00314 int trans, 00315 int bpp, int depth 00316 ){ 00317 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn); 00318 int dwords, skipleft, bufferNo = 0, Bpp = bpp >> 3; 00319 Bool beCareful = FALSE; 00320 CARD32* base; 00321 00322 if((skipleft = (long)src & 0x03L)) { 00323 if(!(infoRec->ScanlineImageWriteFlags & LEFT_EDGE_CLIPPING)) { 00324 skipleft = 0; 00325 beCareful = TRUE; 00326 goto BAD_ALIGNMENT; 00327 } 00328 00329 if(Bpp == 3) 00330 skipleft = 4 - skipleft; 00331 else 00332 skipleft /= Bpp; 00333 00334 if((x < skipleft) && !(infoRec->ScanlineImageWriteFlags & 00335 LEFT_EDGE_CLIPPING_NEGATIVE_X)) { 00336 skipleft = 0; 00337 beCareful = TRUE; 00338 goto BAD_ALIGNMENT; 00339 } 00340 00341 x -= skipleft; 00342 w += skipleft; 00343 00344 if(Bpp == 3) 00345 src -= 3 * skipleft; 00346 else 00347 src = (unsigned char*)((long)src & ~0x03L); 00348 } 00349 00350 BAD_ALIGNMENT: 00351 00352 dwords = ((w * Bpp) + 3) >> 2; 00353 00354 (*infoRec->SetupForScanlineImageWrite)( 00355 pScrn, rop, planemask, trans, bpp, depth); 00356 (*infoRec->SubsequentScanlineImageWriteRect)(pScrn, x, y, w, h, skipleft); 00357 00358 if(beCareful) { 00359 /* in cases with bad alignment we have to be careful not 00360 to read beyond the end of the source */ 00361 if(((x * Bpp) + (dwords << 2)) > srcwidth) h--; 00362 else beCareful = FALSE; 00363 } 00364 00365 while(h--) { 00366 base = (CARD32*)infoRec->ScanlineImageWriteBuffers[bufferNo]; 00367 XAAMoveDWORDS(base, (CARD32*)src, dwords); 00368 (*infoRec->SubsequentImageWriteScanline)(pScrn, bufferNo++); 00369 src += srcwidth; 00370 if(bufferNo >= infoRec->NumScanlineImageWriteBuffers) 00371 bufferNo = 0; 00372 } 00373 00374 if(beCareful) { 00375 int shift = ((long)src & 0x03L) << 3; 00376 base = (CARD32*)infoRec->ScanlineImageWriteBuffers[bufferNo]; 00377 if(--dwords) 00378 XAAMoveDWORDS(base,(CARD32*)src, dwords); 00379 src = (unsigned char*)((long)(src + (dwords << 2)) & ~0x03L); 00380 00381 base[dwords] = *((CARD32*)src) >> shift; 00382 (*infoRec->SubsequentImageWriteScanline)(pScrn, bufferNo); 00383 } 00384 00385 SET_SYNC_FLAG(infoRec); 00386 } 00387 00388 00389 void 00390 XAAPutImage( 00391 DrawablePtr pDraw, 00392 GCPtr pGC, 00393 int depth, 00394 int x, 00395 int y, 00396 int w, 00397 int h, 00398 int leftPad, 00399 int format, 00400 char *pImage 00401 ){ 00402 XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); 00403 int bpp = BitsPerPixel(depth); 00404 Bool depthBug = FALSE; 00405 if(!w || !h) return; 00406 00407 if(!REGION_NUM_RECTS(pGC->pCompositeClip)) 00408 return; 00409 00410 depthBug = XAA_DEPTH_BUG(pGC); 00411 00412 if(((format == ZPixmap) && infoRec->WritePixmap && 00413 ((pDraw->bitsPerPixel == bpp) || 00414 ((pDraw->bitsPerPixel == 24) && (bpp == 32) && 00415 (infoRec->WritePixmapFlags & CONVERT_32BPP_TO_24BPP))) && 00416 CHECK_ROP(pGC,infoRec->WritePixmapFlags) && 00417 CHECK_ROPSRC(pGC,infoRec->WritePixmapFlags) && 00418 CHECK_PLANEMASK(pGC,infoRec->WritePixmapFlags) && 00419 CHECK_NO_GXCOPY(pGC,infoRec->WritePixmapFlags)) || 00420 ((format == XYBitmap) && !depthBug && infoRec->WriteBitmap && 00421 CHECK_ROP(pGC,infoRec->WriteBitmapFlags) && 00422 CHECK_ROPSRC(pGC,infoRec->WriteBitmapFlags) && 00423 CHECK_PLANEMASK(pGC,infoRec->WriteBitmapFlags) && 00424 CHECK_COLORS(pGC,infoRec->WriteBitmapFlags) && 00425 !(infoRec->WriteBitmapFlags & TRANSPARENCY_ONLY)) || 00426 ((format == XYPixmap) && !depthBug && infoRec->WriteBitmap && 00427 CHECK_ROP(pGC,infoRec->WriteBitmapFlags) && 00428 CHECK_ROPSRC(pGC,infoRec->WriteBitmapFlags) && 00429 !(infoRec->WriteBitmapFlags & NO_PLANEMASK) && 00430 !(infoRec->WriteBitmapFlags & TRANSPARENCY_ONLY))){ 00431 00432 int MaxBoxes = REGION_NUM_RECTS(pGC->pCompositeClip); 00433 BoxPtr pbox, pClipBoxes; 00434 int nboxes, srcx, srcy, srcwidth; 00435 xRectangle TheRect; 00436 00437 TheRect.x = pDraw->x + x; 00438 TheRect.y = pDraw->y + y; 00439 TheRect.width = w; 00440 TheRect.height = h; 00441 00442 if(MaxBoxes > (infoRec->PreAllocSize/sizeof(BoxRec))) { 00443 pClipBoxes = xalloc(MaxBoxes * sizeof(BoxRec)); 00444 if(!pClipBoxes) return; 00445 } else pClipBoxes = (BoxPtr)infoRec->PreAllocMem; 00446 00447 nboxes = 00448 XAAGetRectClipBoxes(pGC->pCompositeClip, pClipBoxes, 1, &TheRect); 00449 pbox = pClipBoxes; 00450 00451 if(format == XYBitmap) { 00452 srcwidth = BitmapBytePad(leftPad + w); 00453 while(nboxes--) { 00454 srcx = pbox->x1 - TheRect.x + leftPad; 00455 srcy = pbox->y1 - TheRect.y; 00456 (*infoRec->WriteBitmap)(infoRec->pScrn, pbox->x1, pbox->y1, 00457 pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, 00458 (unsigned char*)pImage + 00459 (srcwidth * srcy) + ((srcx >> 5) << 2), 00460 srcwidth, srcx & 31, pGC->fgPixel, pGC->bgPixel, 00461 pGC->alu, pGC->planemask); 00462 pbox++; 00463 } 00464 } else if(format == ZPixmap) { 00465 int Bpp = bpp >> 3; 00466 srcwidth = PixmapBytePad(leftPad + w, depth); 00467 while(nboxes--) { 00468 srcx = pbox->x1 - TheRect.x + leftPad; 00469 srcy = pbox->y1 - TheRect.y; 00470 (*infoRec->WritePixmap)(infoRec->pScrn, pbox->x1, pbox->y1, 00471 pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, 00472 (unsigned char*)pImage + 00473 (srcwidth * srcy) + (srcx * Bpp), 00474 srcwidth, pGC->alu, pGC->planemask, -1, 00475 Bpp << 3, depth); 00476 pbox++; 00477 } 00478 } else { /* XYPixmap */ 00479 int depth = pGC->depth; 00480 int numBox, increment; 00481 unsigned long i, mask; 00482 BoxPtr pntBox; 00483 00484 srcwidth = BitmapBytePad(w + leftPad); 00485 increment = h * srcwidth; 00486 i = 1 << (depth - 1); 00487 mask = ~0; 00488 00489 if((infoRec->pScrn->overlayFlags & OVERLAY_8_32_PLANAR) && 00490 (pGC->depth == 8)){ 00491 i = 0x80000000; mask = 0xff000000; 00492 } 00493 00494 for(; i & mask; i >>= 1, pImage += increment) { 00495 if(i & pGC->planemask) { 00496 pntBox = pbox; 00497 numBox = nboxes; 00498 while(numBox--) { 00499 srcx = pntBox->x1 - TheRect.x + leftPad; 00500 srcy = pntBox->y1 - TheRect.y; 00501 (*infoRec->WriteBitmap)(infoRec->pScrn, 00502 pntBox->x1, pntBox->y1, 00503 pntBox->x2 - pntBox->x1, 00504 pntBox->y2 - pntBox->y1, 00505 (unsigned char*)pImage + 00506 (srcwidth * srcy) + ((srcx >> 5) << 2), 00507 srcwidth, srcx & 31, ~0, 0, pGC->alu, i); 00508 pntBox++; 00509 } 00510 } 00511 } 00512 00513 } 00514 00515 if(pClipBoxes != (BoxPtr)infoRec->PreAllocMem) 00516 xfree(pClipBoxes); 00517 } else 00518 XAAFallbackOps.PutImage(pDraw, pGC, depth, x, y, w, h, leftPad, 00519 format, pImage); 00520 }

Generated on Mon May 10 21:11:41 2004 for XFree86 by doxygen 1.3.7