Home | History | Annotate | Line # | Download | only in xaa
      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 
     19 void 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 
     41 void 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 
     63 void 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 
     84 static void
     85 XAAWritePixmap32To24(
     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 
    175 void
    176 XAAWritePixmap (
    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 
    228 BAD_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 
    308 void
    309 XAAWritePixmapScanline (
    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 
    352 BAD_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 
    391 void
    392 XAAPutImage(
    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