720 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			720 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C
		
	
	
	
| /*
 | |
|  * Copyright © 2001 Keith Packard
 | |
|  *
 | |
|  * Partly based on code that is Copyright © The XFree86 Project Inc.
 | |
|  *
 | |
|  * Permission to use, copy, modify, distribute, and sell this software and its
 | |
|  * documentation for any purpose is hereby granted without fee, provided that
 | |
|  * the above copyright notice appear in all copies and that both that
 | |
|  * copyright notice and this permission notice appear in supporting
 | |
|  * documentation, and that the name of Keith Packard not be used in
 | |
|  * advertising or publicity pertaining to distribution of the software without
 | |
|  * specific, written prior permission.  Keith Packard makes no
 | |
|  * representations about the suitability of this software for any purpose.  It
 | |
|  * is provided "as is" without express or implied warranty.
 | |
|  *
 | |
|  * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 | |
|  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 | |
|  * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 | |
|  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 | |
|  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 | |
|  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 | |
|  * PERFORMANCE OF THIS SOFTWARE.
 | |
|  */
 | |
| 
 | |
| #ifdef HAVE_CONFIG_H
 | |
| #include <kdrive-config.h>
 | |
| #endif
 | |
| #include "kdrive.h"
 | |
| #include "kaa.h"
 | |
| 
 | |
| #ifdef RENDER
 | |
| #include "mipict.h"
 | |
| 
 | |
| #define KAA_DEBUG_FALLBACKS 0
 | |
| 
 | |
| #if KAA_DEBUG_FALLBACKS
 | |
| static void kaaCompositeFallbackPictDesc(PicturePtr pict, char *string, int n)
 | |
| {
 | |
|     char format[20];
 | |
|     char size[20];
 | |
|     char loc;
 | |
|     int temp;
 | |
| 
 | |
|     if (!pict) {
 | |
| 	snprintf(string, n, "None");
 | |
| 	return;
 | |
|     }
 | |
| 
 | |
|     switch (pict->format)
 | |
|     {
 | |
|     case PICT_a8r8g8b8:
 | |
| 	snprintf(format, 20, "ARGB8888");
 | |
| 	break;
 | |
|     case PICT_r5g6b5:
 | |
| 	snprintf(format, 20, "RGB565  ");
 | |
| 	break;
 | |
|     case PICT_x1r5g5b5:
 | |
| 	snprintf(format, 20, "RGB555  ");
 | |
| 	break;
 | |
|     case PICT_a8:
 | |
| 	snprintf(format, 20, "A8      ");
 | |
| 	break;
 | |
|     case PICT_a1:
 | |
| 	snprintf(format, 20, "A1      ");
 | |
| 	break;
 | |
|     default:
 | |
| 	snprintf(format, 20, "0x%x", (int)pict->format);
 | |
| 	break;
 | |
|     }
 | |
| 
 | |
|     loc = kaaGetOffscreenPixmap(pict->pDrawable, &temp, &temp) ? 's' : 'm';
 | |
| 
 | |
|     snprintf(size, 20, "%dx%d%s", pict->pDrawable->width,
 | |
| 	     pict->pDrawable->height, pict->repeat ?
 | |
| 	     " R" : "");
 | |
|     
 | |
|     snprintf(string, n, "0x%lx:%c fmt %s (%s)", (long)pict, loc, format, size);
 | |
| }
 | |
| 
 | |
| static void
 | |
| kaaPrintCompositeFallback(CARD8 op,
 | |
| 			  PicturePtr pSrc,
 | |
| 			  PicturePtr pMask,
 | |
| 			  PicturePtr pDst)
 | |
| {
 | |
|     char sop[20];
 | |
|     char srcdesc[40], maskdesc[40], dstdesc[40];
 | |
| 
 | |
|     switch(op)
 | |
|     {
 | |
|     case PictOpSrc:
 | |
| 	sprintf(sop, "Src");
 | |
| 	break;
 | |
|     case PictOpOver:
 | |
| 	sprintf(sop, "Over");
 | |
| 	break;
 | |
|     default:
 | |
| 	sprintf(sop, "0x%x", (int)op);
 | |
| 	break;
 | |
|     }
 | |
|     
 | |
|     kaaCompositeFallbackPictDesc(pSrc, srcdesc, 40);
 | |
|     kaaCompositeFallbackPictDesc(pMask, maskdesc, 40);
 | |
|     kaaCompositeFallbackPictDesc(pDst, dstdesc, 40);
 | |
| 
 | |
|     ErrorF("Composite fallback: op %s, \n"
 | |
| 	   "                    src  %s, \n"
 | |
| 	   "                    mask %s, \n"
 | |
| 	   "                    dst  %s, \n", 
 | |
| 	   sop, srcdesc, maskdesc, dstdesc);
 | |
| }
 | |
| 
 | |
| static void
 | |
| kaaPrintTrapezoidFallback(PicturePtr pDst)
 | |
| {
 | |
|     char dstdesc[40];
 | |
| 
 | |
|     kaaCompositeFallbackPictDesc(pDst, dstdesc, 40);
 | |
| 
 | |
|     ErrorF("Trapezoid fallback: dst  %s, %c/%s\n", 
 | |
| 	   dstdesc,
 | |
| 	   (pDst->polyMode == PolyModePrecise) ? 'p' : 'i',
 | |
| 	   (pDst->polyEdge == PolyEdgeSharp) ? "a" : "aa");
 | |
| }
 | |
| #endif
 | |
| 
 | |
| static Bool
 | |
| kaaGetPixelFromRGBA(CARD32	*pixel,
 | |
| 		    CARD16	red,
 | |
| 		    CARD16	green,
 | |
| 		    CARD16	blue,
 | |
| 		    CARD16	alpha,
 | |
| 		    CARD32	format)
 | |
| {
 | |
|     int rbits, bbits, gbits, abits;
 | |
|     int rshift, bshift, gshift, ashift;
 | |
| 
 | |
|     *pixel = 0;
 | |
| 
 | |
|     if (!PICT_FORMAT_COLOR(format))
 | |
| 	return FALSE;
 | |
| 
 | |
|     rbits = PICT_FORMAT_R(format);
 | |
|     gbits = PICT_FORMAT_G(format);
 | |
|     bbits = PICT_FORMAT_B(format);
 | |
|     abits = PICT_FORMAT_A(format);
 | |
| 
 | |
|     if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) {
 | |
| 	bshift = 0;
 | |
| 	gshift = bbits;
 | |
| 	rshift = gshift + gbits;
 | |
| 	ashift = rshift + rbits;
 | |
|     } else {  /* PICT_TYPE_ABGR */
 | |
| 	rshift = 0;
 | |
| 	gshift = rbits;
 | |
| 	bshift = gshift + gbits;
 | |
| 	ashift = bshift + bbits;
 | |
|     }
 | |
| 
 | |
|     *pixel |=  ( blue >> (16 - bbits)) << bshift;
 | |
|     *pixel |=  (  red >> (16 - rbits)) << rshift;
 | |
|     *pixel |=  (green >> (16 - gbits)) << gshift;
 | |
|     *pixel |=  (alpha >> (16 - abits)) << ashift;
 | |
| 
 | |
|     return TRUE;
 | |
| }
 | |
| 
 | |
| 
 | |
| static Bool
 | |
| kaaGetRGBAFromPixel(CARD32	pixel,
 | |
| 		    CARD16	*red,
 | |
| 		    CARD16	*green,
 | |
| 		    CARD16	*blue,
 | |
| 		    CARD16	*alpha,
 | |
| 		    CARD32	format)
 | |
| {
 | |
|     int rbits, bbits, gbits, abits;
 | |
|     int rshift, bshift, gshift, ashift;
 | |
|     
 | |
|     if (!PICT_FORMAT_COLOR(format))
 | |
| 	return FALSE;
 | |
| 
 | |
|     rbits = PICT_FORMAT_R(format);
 | |
|     gbits = PICT_FORMAT_G(format);
 | |
|     bbits = PICT_FORMAT_B(format);
 | |
|     abits = PICT_FORMAT_A(format);
 | |
| 
 | |
|     if (PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) {
 | |
| 	bshift = 0;
 | |
| 	gshift = bbits;
 | |
| 	rshift = gshift + gbits;
 | |
| 	ashift = rshift + rbits;
 | |
|     } else {  /* PICT_TYPE_ABGR */
 | |
| 	rshift = 0;
 | |
| 	gshift = rbits;
 | |
| 	bshift = gshift + gbits;
 | |
| 	ashift = bshift + bbits;
 | |
|     }
 | |
|  
 | |
|     *red = ((pixel >> rshift ) & ((1 << rbits) - 1)) << (16 - rbits);
 | |
|     while (rbits < 16) {
 | |
| 	*red |= *red >> rbits;
 | |
| 	rbits <<= 1;
 | |
|     }
 | |
| 
 | |
|     *green = ((pixel >> gshift ) & ((1 << gbits) - 1)) << (16 - gbits);
 | |
|     while (gbits < 16) {
 | |
| 	*green |= *green >> gbits;
 | |
| 	gbits <<= 1;
 | |
|     }
 | |
|  
 | |
|     *blue = ((pixel >> bshift ) & ((1 << bbits) - 1)) << (16 - bbits);
 | |
|     while (bbits < 16) {
 | |
| 	*blue |= *blue >> bbits;
 | |
| 	bbits <<= 1;
 | |
|     }  
 | |
| 
 | |
|     if (abits) {
 | |
| 	*alpha = ((pixel >> ashift ) & ((1 << abits) - 1)) << (16 - abits);
 | |
| 	while (abits < 16) {
 | |
| 	    *alpha |= *alpha >> abits;
 | |
| 	    abits <<= 1;
 | |
| 	}     
 | |
|     } else
 | |
| 	*alpha = 0xffff;
 | |
| 
 | |
|     return TRUE;
 | |
| }
 | |
| 
 | |
| static int
 | |
| kaaTryDriverSolidFill(PicturePtr	pSrc,
 | |
| 		      PicturePtr	pDst,
 | |
| 		      INT16		xSrc,
 | |
| 		      INT16		ySrc,
 | |
| 		      INT16		xDst,
 | |
| 		      INT16		yDst,
 | |
| 		      CARD16		width,
 | |
| 		      CARD16		height)
 | |
| {
 | |
|     KaaScreenPriv (pDst->pDrawable->pScreen);
 | |
|     RegionRec region;
 | |
|     BoxPtr pbox;
 | |
|     int nbox;
 | |
|     int dst_off_x, dst_off_y;
 | |
|     PixmapPtr pSrcPix, pDstPix;
 | |
|     CARD32 pixel;
 | |
|     CARD16 red, green, blue, alpha;
 | |
| 
 | |
|     xDst += pDst->pDrawable->x;
 | |
|     yDst += pDst->pDrawable->y;
 | |
|     xSrc += pSrc->pDrawable->x;
 | |
|     ySrc += pSrc->pDrawable->y;
 | |
| 
 | |
|     if (!miComputeCompositeRegion (®ion, pSrc, NULL, pDst,
 | |
| 				   xSrc, ySrc, 0, 0, xDst, yDst,
 | |
| 				   width, height))
 | |
| 	return 1;
 | |
| 
 | |
|     if (pSrc->pDrawable->type == DRAWABLE_PIXMAP)
 | |
| 	kaaPixmapUseMemory ((PixmapPtr) pSrc->pDrawable);
 | |
|     if (pDst->pDrawable->type == DRAWABLE_PIXMAP)
 | |
| 	kaaPixmapUseScreen ((PixmapPtr) pDst->pDrawable);
 | |
| 
 | |
|     pDstPix = kaaGetOffscreenPixmap (pDst->pDrawable, &dst_off_x, &dst_off_y);
 | |
|     if (!pDstPix) {
 | |
| 	REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
 | |
| 	return 0;
 | |
|     }
 | |
| 
 | |
|     if (pSrc->pDrawable->type == DRAWABLE_WINDOW)
 | |
| 	pSrcPix = (*pSrc->pDrawable->pScreen->GetWindowPixmap)(
 | |
| 	    (WindowPtr) (pSrc->pDrawable));
 | |
|     else
 | |
| 	pSrcPix = (PixmapPtr) (pSrc->pDrawable);
 | |
| 
 | |
|     /* If source is offscreen, we need to sync the accelerator
 | |
|      * before accessing it.  We'd prefer for it to be in memory.
 | |
|      */
 | |
|     if (kaaPixmapIsOffscreen(pSrcPix)) {
 | |
| 	kaaWaitSync(pDst->pDrawable->pScreen);
 | |
|     }
 | |
| 
 | |
|     pixel = *(CARD32 *)(pSrcPix->devPrivate.ptr);
 | |
|     if (!kaaGetRGBAFromPixel(pixel, &red, &green, &blue, &alpha,
 | |
| 			 pSrc->format))
 | |
|     {
 | |
| 	REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
 | |
| 	return -1;
 | |
|     }
 | |
|     kaaGetPixelFromRGBA(&pixel, red, green, blue, alpha,
 | |
| 			pDst->format);
 | |
| 
 | |
|     if (!(*pKaaScr->info->PrepareSolid) (pDstPix, GXcopy, 0xffffffff, pixel))
 | |
|     {
 | |
| 	REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
 | |
| 	return -1;
 | |
|     }
 | |
| 
 | |
|     nbox = REGION_NUM_RECTS(®ion);
 | |
|     pbox = REGION_RECTS(®ion);
 | |
|     while (nbox--)
 | |
|     {
 | |
| 	(*pKaaScr->info->Solid) (pbox->x1 + dst_off_x,
 | |
| 				 pbox->y1 + dst_off_y,
 | |
| 				 pbox->x2 + dst_off_x,
 | |
| 				 pbox->y2 + dst_off_y);
 | |
| 	pbox++;
 | |
|     }
 | |
| 
 | |
|     (*pKaaScr->info->DoneSolid) ();
 | |
|     kaaMarkSync (pDst->pDrawable->pScreen);
 | |
|     kaaDrawableDirty (pDst->pDrawable);
 | |
| 
 | |
|     REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
 | |
|     return 1;
 | |
| }
 | |
| 
 | |
| static int
 | |
| kaaTryDriverBlend(CARD8		op,
 | |
| 		  PicturePtr	pSrc,
 | |
| 		  PicturePtr	pDst,
 | |
| 		  INT16		xSrc,
 | |
| 		  INT16		ySrc,
 | |
| 		  INT16		xDst,
 | |
| 		  INT16		yDst,
 | |
| 		  CARD16	width,
 | |
| 		  CARD16	height)
 | |
| {
 | |
|     KaaScreenPriv (pDst->pDrawable->pScreen);
 | |
|     RegionRec region;
 | |
|     BoxPtr pbox;
 | |
|     int nbox;
 | |
|     int src_off_x, src_off_y, dst_off_x, dst_off_y;
 | |
|     PixmapPtr pSrcPix, pDstPix;
 | |
|     struct _Pixmap srcScratch;
 | |
| 
 | |
|     xDst += pDst->pDrawable->x;
 | |
|     yDst += pDst->pDrawable->y;
 | |
| 
 | |
|     xSrc += pSrc->pDrawable->x;
 | |
|     ySrc += pSrc->pDrawable->y;
 | |
| 
 | |
|     if (!miComputeCompositeRegion (®ion, pSrc, NULL, pDst,
 | |
| 				   xSrc, ySrc, 0, 0, xDst, yDst,
 | |
| 				   width, height))
 | |
| 	return 1;
 | |
| 
 | |
| 
 | |
|     if (pSrc->pDrawable->type == DRAWABLE_PIXMAP)
 | |
| 	kaaPixmapUseScreen ((PixmapPtr) pSrc->pDrawable);
 | |
|     if (pDst->pDrawable->type == DRAWABLE_PIXMAP)
 | |
| 	kaaPixmapUseScreen ((PixmapPtr) pDst->pDrawable);
 | |
|     
 | |
|     pSrcPix = kaaGetOffscreenPixmap (pSrc->pDrawable, &src_off_x, &src_off_y);
 | |
|     pDstPix = kaaGetOffscreenPixmap (pDst->pDrawable, &dst_off_x, &dst_off_y);
 | |
| 
 | |
|     if (!pDstPix) {
 | |
| 	REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
 | |
| 	return 0;
 | |
|     }
 | |
| 
 | |
|     if (!pSrcPix && pKaaScr->info->UploadToScratch) {
 | |
| 	if ((*pKaaScr->info->UploadToScratch) ((PixmapPtr) pSrc->pDrawable,
 | |
| 					       &srcScratch))
 | |
| 	    pSrcPix = &srcScratch;
 | |
|     }
 | |
| 
 | |
|     if (!pSrcPix) {
 | |
| 	REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
 | |
| 	return 0;
 | |
|     }
 | |
| 
 | |
|     if (!(*pKaaScr->info->PrepareBlend) (op, pSrc, pDst, pSrcPix,
 | |
| 					 pDstPix))
 | |
|     {
 | |
| 	REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
 | |
| 	return -1;
 | |
|     }
 | |
|     
 | |
|     nbox = REGION_NUM_RECTS(®ion);
 | |
|     pbox = REGION_RECTS(®ion);
 | |
| 
 | |
|     xSrc -= xDst;
 | |
|     ySrc -= yDst;
 | |
| 
 | |
|     while (nbox--)
 | |
|     {
 | |
| 	(*pKaaScr->info->Blend) (pbox->x1 + xSrc + src_off_x,
 | |
| 				 pbox->y1 + ySrc + src_off_y,
 | |
| 				 pbox->x1 + dst_off_x,
 | |
| 				 pbox->y1 + dst_off_y,
 | |
| 				 pbox->x2 - pbox->x1,
 | |
| 				 pbox->y2 - pbox->y1);
 | |
| 	pbox++;
 | |
|     }
 | |
|     
 | |
|     (*pKaaScr->info->DoneBlend) ();
 | |
|     kaaMarkSync (pDst->pDrawable->pScreen);
 | |
|     kaaDrawableDirty (pDst->pDrawable);
 | |
| 
 | |
|     REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
 | |
|     return 1;
 | |
| }
 | |
| 
 | |
| static int
 | |
| kaaTryDriverComposite(CARD8		op,
 | |
| 		      PicturePtr	pSrc,
 | |
| 		      PicturePtr	pMask,
 | |
| 		      PicturePtr	pDst,
 | |
| 		      INT16		xSrc,
 | |
| 		      INT16		ySrc,
 | |
| 		      INT16		xMask,
 | |
| 		      INT16		yMask,
 | |
| 		      INT16		xDst,
 | |
| 		      INT16		yDst,
 | |
| 		      CARD16		width,
 | |
| 		      CARD16		height)
 | |
| {
 | |
|     KaaScreenPriv (pDst->pDrawable->pScreen);
 | |
|     RegionRec region;
 | |
|     BoxPtr pbox;
 | |
|     int nbox;
 | |
|     int src_off_x, src_off_y, mask_off_x, mask_off_y, dst_off_x, dst_off_y;
 | |
|     PixmapPtr pSrcPix, pMaskPix = NULL, pDstPix;
 | |
|     struct _Pixmap scratch;
 | |
| 
 | |
|     xDst += pDst->pDrawable->x;
 | |
|     yDst += pDst->pDrawable->y;
 | |
| 
 | |
|     if (pMask) {
 | |
| 	xMask += pMask->pDrawable->x;
 | |
| 	yMask += pMask->pDrawable->y;
 | |
|     }
 | |
| 
 | |
|     xSrc += pSrc->pDrawable->x;
 | |
|     ySrc += pSrc->pDrawable->y;
 | |
| 
 | |
|     if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst,
 | |
| 				   xSrc, ySrc, xMask, yMask, xDst, yDst,
 | |
| 				   width, height))
 | |
| 	return 1;
 | |
| 
 | |
|     if (pKaaScr->info->CheckComposite &&
 | |
| 	!(*pKaaScr->info->CheckComposite) (op, pSrc, pMask, pDst))
 | |
|     {
 | |
| 	REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
 | |
| 	return -1;
 | |
|     }
 | |
| 
 | |
|     if (pSrc->pDrawable->type == DRAWABLE_PIXMAP)
 | |
| 	kaaPixmapUseScreen ((PixmapPtr) pSrc->pDrawable);
 | |
|     if (pMask && pMask->pDrawable->type == DRAWABLE_PIXMAP)
 | |
| 	kaaPixmapUseScreen ((PixmapPtr) pMask->pDrawable);
 | |
|     if (pDst->pDrawable->type == DRAWABLE_PIXMAP)
 | |
| 	kaaPixmapUseScreen ((PixmapPtr) pDst->pDrawable);
 | |
| 
 | |
|     pSrcPix = kaaGetOffscreenPixmap (pSrc->pDrawable, &src_off_x, &src_off_y);
 | |
|     if (pMask)
 | |
| 	pMaskPix = kaaGetOffscreenPixmap (pMask->pDrawable, &mask_off_x,
 | |
| 					  &mask_off_y);
 | |
|     pDstPix = kaaGetOffscreenPixmap (pDst->pDrawable, &dst_off_x, &dst_off_y);
 | |
| 
 | |
|     if (!pDstPix) {
 | |
| 	REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
 | |
| 	return 0;
 | |
|     }
 | |
| 
 | |
|     if (!pSrcPix && (!pMask || pMaskPix) && pKaaScr->info->UploadToScratch) {
 | |
| 	if (pSrc->pDrawable->type == DRAWABLE_WINDOW)
 | |
| 	    pSrcPix = (*pSrc->pDrawable->pScreen->GetWindowPixmap) (
 | |
| 		(WindowPtr) pSrc->pDrawable);
 | |
| 	else
 | |
| 	    pSrcPix = (PixmapPtr) pSrc->pDrawable;
 | |
| 	if ((*pKaaScr->info->UploadToScratch) (pSrcPix, &scratch))
 | |
| 	    pSrcPix = &scratch;
 | |
|     } else if (pSrcPix && pMask && !pMaskPix && pKaaScr->info->UploadToScratch) {
 | |
| 	if (pMask->pDrawable->type == DRAWABLE_WINDOW)
 | |
| 	    pMaskPix = (*pMask->pDrawable->pScreen->GetWindowPixmap) (
 | |
| 		(WindowPtr) pMask->pDrawable);
 | |
| 	else
 | |
| 	    pMaskPix = (PixmapPtr) pMask->pDrawable;
 | |
| 	if ((*pKaaScr->info->UploadToScratch) (pMaskPix, &scratch))
 | |
| 	    pMaskPix = &scratch;
 | |
|     }
 | |
| 
 | |
|     if (!pSrcPix || (pMask && !pMaskPix)) {
 | |
| 	REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
 | |
| 	return 0;
 | |
|     }
 | |
| 
 | |
|     if (!(*pKaaScr->info->PrepareComposite) (op, pSrc, pMask, pDst, pSrcPix,
 | |
| 					     pMaskPix, pDstPix))
 | |
|     {
 | |
| 	REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
 | |
| 	return -1;
 | |
|     }
 | |
| 
 | |
|     nbox = REGION_NUM_RECTS(®ion);
 | |
|     pbox = REGION_RECTS(®ion);
 | |
| 
 | |
|     xMask -= xDst;
 | |
|     yMask -= yDst;
 | |
| 
 | |
|     xSrc -= xDst;
 | |
|     ySrc -= yDst;
 | |
| 
 | |
|     while (nbox--)
 | |
|     {
 | |
| 	(*pKaaScr->info->Composite) (pbox->x1 + xSrc + src_off_x,
 | |
| 				     pbox->y1 + ySrc + src_off_y,
 | |
| 				     pbox->x1 + xMask + mask_off_x,
 | |
| 				     pbox->y1 + yMask + mask_off_y,
 | |
| 				     pbox->x1 + dst_off_x,
 | |
| 				     pbox->y1 + dst_off_y,
 | |
| 				     pbox->x2 - pbox->x1,
 | |
| 				     pbox->y2 - pbox->y1);
 | |
| 	pbox++;
 | |
|     }
 | |
| 
 | |
|     (*pKaaScr->info->DoneComposite) ();
 | |
|     kaaMarkSync (pDst->pDrawable->pScreen);
 | |
|     kaaDrawableDirty (pDst->pDrawable);
 | |
| 
 | |
|     REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
 | |
|     return 1;
 | |
| }
 | |
| 
 | |
| 
 | |
| void
 | |
| kaaComposite(CARD8	op,
 | |
| 	     PicturePtr pSrc,
 | |
| 	     PicturePtr pMask,
 | |
| 	     PicturePtr pDst,
 | |
| 	     INT16	xSrc,
 | |
| 	     INT16	ySrc,
 | |
| 	     INT16	xMask,
 | |
| 	     INT16	yMask,
 | |
| 	     INT16	xDst,
 | |
| 	     INT16	yDst,
 | |
| 	     CARD16	width,
 | |
| 	     CARD16	height)
 | |
| {
 | |
|     KdScreenPriv (pDst->pDrawable->pScreen);
 | |
|     KaaScreenPriv (pDst->pDrawable->pScreen);
 | |
|     int ret = -1;
 | |
| 
 | |
|     if (!pMask && pSrc->pDrawable)
 | |
|     {
 | |
| 	if (op == PictOpSrc)
 | |
| 	{
 | |
| 	    if (pScreenPriv->enabled && pSrc->pDrawable && pSrc->pDrawable->width == 1 &&
 | |
| 		pSrc->pDrawable->height == 1 && pSrc->repeat)
 | |
| 	    {
 | |
| 		ret = kaaTryDriverSolidFill(pSrc, pDst, xSrc, ySrc, xDst, yDst,
 | |
| 					    width, height);
 | |
| 		if (ret == 1)
 | |
| 		    return;
 | |
| 	    }
 | |
| 	    else if (!pSrc->repeat && !pSrc->transform &&
 | |
| 		     pSrc->format == pDst->format)
 | |
| 	    {
 | |
| 		RegionRec	region;
 | |
| 
 | |
| 		xDst += pDst->pDrawable->x;
 | |
| 		yDst += pDst->pDrawable->y;
 | |
| 		xSrc += pSrc->pDrawable->x;
 | |
| 		ySrc += pSrc->pDrawable->y;
 | |
| 
 | |
| 		if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst,
 | |
| 					       xSrc, ySrc, xMask, yMask, xDst,
 | |
| 					       yDst, width, height))
 | |
| 		    return;
 | |
| 
 | |
| 
 | |
| 		kaaCopyNtoN (pSrc->pDrawable, pDst->pDrawable, 0,
 | |
| 			     REGION_RECTS(®ion), REGION_NUM_RECTS(®ion),
 | |
| 			     xSrc - xDst, ySrc - yDst,
 | |
| 			     FALSE, FALSE, 0, 0);
 | |
| 		return;
 | |
| 	    }
 | |
| 	}
 | |
| 
 | |
| 	if (pScreenPriv->enabled && pKaaScr->info->PrepareBlend &&
 | |
| 	    !pSrc->alphaMap && !pDst->alphaMap)
 | |
| 	{
 | |
| 	    ret = kaaTryDriverBlend(op, pSrc, pDst, xSrc, ySrc, xDst, yDst,
 | |
| 				    width, height);
 | |
| 	    if (ret == 1)
 | |
| 		return;
 | |
| 	}
 | |
|     }
 | |
| 
 | |
|     if (pSrc->pDrawable && (!pMask || pMask->pDrawable) &&
 | |
|         pScreenPriv->enabled && pKaaScr->info->PrepareComposite &&
 | |
| 	!pSrc->alphaMap && (!pMask || !pMask->alphaMap) && !pDst->alphaMap)
 | |
|     {
 | |
| 	ret = kaaTryDriverComposite(op, pSrc, pMask, pDst, xSrc, ySrc, xMask,
 | |
| 				    yMask, xDst, yDst, width, height);
 | |
| 	if (ret == 1)
 | |
| 	    return;
 | |
|     }
 | |
| 
 | |
|     if (ret != 0) {
 | |
| 	/* failure to accelerate was not due to pixmaps being in the wrong
 | |
| 	 * locations.
 | |
| 	 */
 | |
| 	if (pSrc->pDrawable->type == DRAWABLE_PIXMAP)
 | |
| 	    kaaPixmapUseMemory ((PixmapPtr) pSrc->pDrawable);
 | |
| 	if (pMask && pMask->pDrawable->type == DRAWABLE_PIXMAP)
 | |
| 	    kaaPixmapUseMemory ((PixmapPtr) pMask->pDrawable);
 | |
| 	if (pDst->pDrawable->type == DRAWABLE_PIXMAP)
 | |
| 	    kaaPixmapUseMemory ((PixmapPtr) pDst->pDrawable);
 | |
|     }
 | |
| 
 | |
| #if KAA_DEBUG_FALLBACKS
 | |
|     kaaPrintCompositeFallback (op, pSrc, pMask, pDst);
 | |
| #endif
 | |
| 
 | |
|     KdCheckComposite (op, pSrc, pMask, pDst, xSrc, ySrc, 
 | |
| 		      xMask, yMask, xDst, yDst, width, height);
 | |
| }
 | |
| #endif
 | |
| 
 | |
| static xFixed
 | |
| miLineFixedX (xLineFixed *l, xFixed y, Bool ceil)
 | |
| {
 | |
|     xFixed	    dx = l->p2.x - l->p1.x;
 | |
|     xFixed_32_32    ex = (xFixed_32_32) (y - l->p1.y) * dx;
 | |
|     xFixed	    dy = l->p2.y - l->p1.y;
 | |
|     if (ceil)
 | |
| 	ex += (dy - 1);
 | |
|     return l->p1.x + (xFixed) (ex / dy);
 | |
| }
 | |
| 
 | |
| /* Need to decide just how much to trim, to maintain translation independence
 | |
|  * when converted to floating point.
 | |
|  */
 | |
| #define XFIXED_TO_FLOAT(x) (((float)((x) & 0xffffff00)) / 65536.0)
 | |
| 
 | |
| /* This is just to allow us to work on the hardware side of the problem while
 | |
|  * waiting for cairo to get a new tesselator.  We may not be able to support
 | |
|  * RasterizeTrapezoid at all due to the abutting edges requirement, but it might
 | |
|  * be technically legal if we widened the trap by some epsilon, so that alpha
 | |
|  * values at abutting edges were a little too big and capped at one, rather than
 | |
|  * a little too small and looked bad.
 | |
|  */
 | |
| void kaaRasterizeTrapezoid(PicturePtr pDst,
 | |
| 			   xTrapezoid *trap,
 | |
| 			   int xoff,
 | |
| 			   int yoff)
 | |
| {
 | |
|     KdScreenPriv (pDst->pDrawable->pScreen);
 | |
|     KaaScreenPriv (pDst->pDrawable->pScreen);
 | |
|     KaaTrapezoid ktrap;
 | |
|     PixmapPtr pPix;
 | |
|     xFixed x1, x2;
 | |
| 
 | |
|     if (!pScreenPriv->enabled ||
 | |
| 	!pKaaScr->info->PrepareTrapezoids ||
 | |
| 	pDst->pDrawable->type != DRAWABLE_PIXMAP ||
 | |
|         pDst->alphaMap || pDst->format != PICT_a8)
 | |
|     {
 | |
| 	KdCheckRasterizeTrapezoid (pDst, trap, xoff, yoff);
 | |
| #if KAA_DEBUG_FALLBACKS
 | |
| 	kaaPrintTrapezoidFallback (pDst);
 | |
| #endif
 | |
| 	return;
 | |
|     }
 | |
|     pPix = (PixmapPtr)pDst->pDrawable;
 | |
| 
 | |
|     kaaPixmapUseScreen (pPix);
 | |
| 
 | |
|     if (!kaaPixmapIsOffscreen (pPix) ||
 | |
| 	!(*pKaaScr->info->PrepareTrapezoids) (pDst, pPix))
 | |
|     {
 | |
| #if KAA_DEBUG_FALLBACKS
 | |
| 	kaaPrintTrapezoidFallback (pDst);
 | |
| #endif
 | |
| 	KdCheckRasterizeTrapezoid (pDst, trap, xoff, yoff);
 | |
| 	return;
 | |
|     }
 | |
| 
 | |
|     ktrap.ty = XFIXED_TO_FLOAT(trap->top) + yoff;
 | |
|     x1 = miLineFixedX (&trap->left, trap->top, FALSE);
 | |
|     x2 = miLineFixedX (&trap->right, trap->top, TRUE);
 | |
|     ktrap.tl = XFIXED_TO_FLOAT(x1) + xoff;
 | |
|     ktrap.tr = XFIXED_TO_FLOAT(x2) + xoff;
 | |
|     ktrap.by = XFIXED_TO_FLOAT(trap->bottom) + yoff;
 | |
|     x1 = miLineFixedX (&trap->left, trap->bottom, FALSE);
 | |
|     x2 = miLineFixedX (&trap->right, trap->bottom, TRUE);
 | |
|     ktrap.bl = XFIXED_TO_FLOAT(x1) + xoff;
 | |
|     ktrap.br = XFIXED_TO_FLOAT(x2) + xoff;
 | |
| 
 | |
|     (*pKaaScr->info->Trapezoids) (&ktrap, 1);
 | |
|     (*pKaaScr->info->DoneTrapezoids) ();
 | |
| }
 | |
| 
 | |
| void
 | |
| kaaInitTrapOffsets(int grid_order, float *x_offsets, float *y_offsets,
 | |
| 		   float x_offset, float y_offset)
 | |
| {
 | |
|     int i = 0;
 | |
|     float x, y, x_count, y_count;
 | |
| 
 | |
|     x_count = (1 << (grid_order / 2)) + 1;
 | |
|     y_count = (1 << (grid_order / 2)) - 1;
 | |
| 
 | |
|     x_offset += 1.0 / x_count / 2.0;
 | |
|     y_offset += 1.0 / y_count / 2.0;
 | |
| 
 | |
|     for (x = 0; x < x_count; x++) {
 | |
| 	for (y = 0; y < y_count; y++) {
 | |
| 	    x_offsets[i] = x / x_count + x_offset;
 | |
| 	    y_offsets[i] = y / y_count + y_offset;
 | |
| 	    i++;
 | |
| 	}
 | |
|     }
 | |
| }
 | |
| 
 |