573 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			573 lines
		
	
	
		
			16 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 <config.h>
 | 
						|
#endif
 | 
						|
#include "exaPriv.h"
 | 
						|
 | 
						|
#ifdef RENDER
 | 
						|
#include "mipict.h"
 | 
						|
 | 
						|
#define EXA_DEBUG_FALLBACKS 0
 | 
						|
 | 
						|
#if EXA_DEBUG_FALLBACKS
 | 
						|
static void exaCompositeFallbackPictDesc(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 = exaGetOffscreenPixmap(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
 | 
						|
exaPrintCompositeFallback(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;
 | 
						|
    }
 | 
						|
 | 
						|
    exaCompositeFallbackPictDesc(pSrc, srcdesc, 40);
 | 
						|
    exaCompositeFallbackPictDesc(pMask, maskdesc, 40);
 | 
						|
    exaCompositeFallbackPictDesc(pDst, dstdesc, 40);
 | 
						|
 | 
						|
    ErrorF("Composite fallback: op %s, \n"
 | 
						|
	   "                    src  %s, \n"
 | 
						|
	   "                    mask %s, \n"
 | 
						|
	   "                    dst  %s, \n",
 | 
						|
	   sop, srcdesc, maskdesc, dstdesc);
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
static Bool
 | 
						|
exaGetPixelFromRGBA(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
 | 
						|
exaGetRGBAFromPixel(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
 | 
						|
exaTryDriverSolidFill(PicturePtr	pSrc,
 | 
						|
		      PicturePtr	pDst,
 | 
						|
		      INT16		xSrc,
 | 
						|
		      INT16		ySrc,
 | 
						|
		      INT16		xDst,
 | 
						|
		      INT16		yDst,
 | 
						|
		      CARD16		width,
 | 
						|
		      CARD16		height)
 | 
						|
{
 | 
						|
    ExaScreenPriv (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)
 | 
						|
	exaPixmapUseMemory ((PixmapPtr) pSrc->pDrawable);
 | 
						|
    if (pDst->pDrawable->type == DRAWABLE_PIXMAP)
 | 
						|
	exaPixmapUseScreen ((PixmapPtr) pDst->pDrawable);
 | 
						|
 | 
						|
    pDstPix = exaGetOffscreenPixmap (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 (exaPixmapIsOffscreen(pSrcPix)) {
 | 
						|
	exaWaitSync(pDst->pDrawable->pScreen);
 | 
						|
    }
 | 
						|
 | 
						|
    pixel = *(CARD32 *)(pSrcPix->devPrivate.ptr);
 | 
						|
    if (!exaGetRGBAFromPixel(pixel, &red, &green, &blue, &alpha,
 | 
						|
			 pSrc->format))
 | 
						|
    {
 | 
						|
	REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
 | 
						|
	return -1;
 | 
						|
    }
 | 
						|
    exaGetPixelFromRGBA(&pixel, red, green, blue, alpha,
 | 
						|
			pDst->format);
 | 
						|
 | 
						|
    if (!(*pExaScr->info->accel.PrepareSolid) (pDstPix, GXcopy, 0xffffffff, pixel))
 | 
						|
    {
 | 
						|
	REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
 | 
						|
	return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    nbox = REGION_NUM_RECTS(®ion);
 | 
						|
    pbox = REGION_RECTS(®ion);
 | 
						|
    while (nbox--)
 | 
						|
    {
 | 
						|
	(*pExaScr->info->accel.Solid) (pDstPix,
 | 
						|
                                       pbox->x1 + dst_off_x,
 | 
						|
                                       pbox->y1 + dst_off_y,
 | 
						|
                                       pbox->x2 + dst_off_x,
 | 
						|
                                       pbox->y2 + dst_off_y);
 | 
						|
	pbox++;
 | 
						|
    }
 | 
						|
 | 
						|
    (*pExaScr->info->accel.DoneSolid) (pDstPix);
 | 
						|
    exaMarkSync(pDst->pDrawable->pScreen);
 | 
						|
    exaDrawableDirty (pDst->pDrawable);
 | 
						|
 | 
						|
    REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
 | 
						|
    return 1;
 | 
						|
}
 | 
						|
 | 
						|
static int
 | 
						|
exaTryDriverComposite(CARD8		op,
 | 
						|
		      PicturePtr	pSrc,
 | 
						|
		      PicturePtr	pMask,
 | 
						|
		      PicturePtr	pDst,
 | 
						|
		      INT16		xSrc,
 | 
						|
		      INT16		ySrc,
 | 
						|
		      INT16		xMask,
 | 
						|
		      INT16		yMask,
 | 
						|
		      INT16		xDst,
 | 
						|
		      INT16		yDst,
 | 
						|
		      CARD16		width,
 | 
						|
		      CARD16		height)
 | 
						|
{
 | 
						|
    ExaScreenPriv (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;
 | 
						|
 | 
						|
    if (pExaScr->info->card.maxX < width ||
 | 
						|
        pExaScr->info->card.maxY < height)
 | 
						|
    {
 | 
						|
        int total_width  = width;
 | 
						|
        int total_height = height;
 | 
						|
        int xOff = 0;
 | 
						|
        int yOff = 0;
 | 
						|
        while (total_width  > pExaScr->info->card.maxX) {
 | 
						|
            while (total_height > pExaScr->info->card.maxY) {
 | 
						|
                exaTryDriverComposite(op,
 | 
						|
                                      pSrc,
 | 
						|
                                      pMask,
 | 
						|
                                      pDst,
 | 
						|
                                      xSrc  + xOff,
 | 
						|
                                      ySrc  + yOff,
 | 
						|
                                      xMask + xOff,
 | 
						|
                                      yMask + yOff,
 | 
						|
                                      xDst  + xOff,
 | 
						|
                                      yDst  + yOff,
 | 
						|
                                      pExaScr->info->card.maxX,
 | 
						|
                                      pExaScr->info->card.maxY);
 | 
						|
                total_width -= pExaScr->info->card.maxX;
 | 
						|
                xOff += pExaScr->info->card.maxX;
 | 
						|
                yOff = 0;
 | 
						|
            }
 | 
						|
            if (total_height)
 | 
						|
                exaTryDriverComposite(op,
 | 
						|
                                      pSrc,
 | 
						|
                                      pMask,
 | 
						|
                                      pDst,
 | 
						|
                                      xSrc  + xOff,
 | 
						|
                                      ySrc  + yOff,
 | 
						|
                                      xMask + xOff,
 | 
						|
                                      yMask + yOff,
 | 
						|
                                      xDst  + xOff,
 | 
						|
                                      yDst  + yOff,
 | 
						|
                                      pExaScr->info->card.maxX,
 | 
						|
                                      total_height);
 | 
						|
            total_height -= pExaScr->info->card.maxY;
 | 
						|
            yOff += pExaScr->info->card.maxY;
 | 
						|
        }
 | 
						|
        if (total_width && total_height)
 | 
						|
            exaTryDriverComposite(op,
 | 
						|
                                  pSrc,
 | 
						|
                                  pMask,
 | 
						|
                                  pDst,
 | 
						|
                                  xSrc  + xOff,
 | 
						|
                                  ySrc  + yOff,
 | 
						|
                                  xMask + xOff,
 | 
						|
                                  yMask + yOff,
 | 
						|
                                  xDst  + xOff,
 | 
						|
                                  yDst  + yOff,
 | 
						|
                                  total_width,
 | 
						|
                                  total_height);
 | 
						|
 | 
						|
        return -1;
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    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 (pExaScr->info->accel.CheckComposite &&
 | 
						|
	!(*pExaScr->info->accel.CheckComposite) (op, pSrc, pMask, pDst))
 | 
						|
    {
 | 
						|
	REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
 | 
						|
	return -1;
 | 
						|
    }
 | 
						|
 | 
						|
    if (pSrc->pDrawable->type == DRAWABLE_PIXMAP)
 | 
						|
	exaPixmapUseScreen ((PixmapPtr) pSrc->pDrawable);
 | 
						|
    if (pMask && pMask->pDrawable->type == DRAWABLE_PIXMAP)
 | 
						|
	exaPixmapUseScreen ((PixmapPtr) pMask->pDrawable);
 | 
						|
    if (pDst->pDrawable->type == DRAWABLE_PIXMAP)
 | 
						|
	exaPixmapUseScreen ((PixmapPtr) pDst->pDrawable);
 | 
						|
 | 
						|
    pSrcPix = exaGetOffscreenPixmap (pSrc->pDrawable, &src_off_x, &src_off_y);
 | 
						|
    if (pMask)
 | 
						|
	pMaskPix = exaGetOffscreenPixmap (pMask->pDrawable, &mask_off_x,
 | 
						|
					  &mask_off_y);
 | 
						|
    pDstPix = exaGetOffscreenPixmap (pDst->pDrawable, &dst_off_x, &dst_off_y);
 | 
						|
 | 
						|
    if (!pDstPix) {
 | 
						|
	REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
 | 
						|
	return 0;
 | 
						|
    }
 | 
						|
 | 
						|
    if (!pSrcPix && (!pMask || pMaskPix) && pExaScr->info->accel.UploadToScratch) {
 | 
						|
	if (pSrc->pDrawable->type == DRAWABLE_WINDOW)
 | 
						|
	    pSrcPix = (*pSrc->pDrawable->pScreen->GetWindowPixmap) (
 | 
						|
		(WindowPtr) pSrc->pDrawable);
 | 
						|
	else
 | 
						|
	    pSrcPix = (PixmapPtr) pSrc->pDrawable;
 | 
						|
	if ((*pExaScr->info->accel.UploadToScratch) (pSrcPix, &scratch))
 | 
						|
	    pSrcPix = &scratch;
 | 
						|
    } else if (pSrcPix && pMask && !pMaskPix && pExaScr->info->accel.UploadToScratch) {
 | 
						|
	if (pMask->pDrawable->type == DRAWABLE_WINDOW)
 | 
						|
	    pMaskPix = (*pMask->pDrawable->pScreen->GetWindowPixmap) (
 | 
						|
		(WindowPtr) pMask->pDrawable);
 | 
						|
	else
 | 
						|
	    pMaskPix = (PixmapPtr) pMask->pDrawable;
 | 
						|
	if ((*pExaScr->info->accel.UploadToScratch) (pMaskPix, &scratch))
 | 
						|
	    pMaskPix = &scratch;
 | 
						|
    }
 | 
						|
 | 
						|
    if (!pSrcPix || (pMask && !pMaskPix)) {
 | 
						|
	REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
 | 
						|
	return 0;
 | 
						|
    }
 | 
						|
 | 
						|
    if (!(*pExaScr->info->accel.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--)
 | 
						|
    {
 | 
						|
	(*pExaScr->info->accel.Composite) (pDstPix,
 | 
						|
                                           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++;
 | 
						|
    }
 | 
						|
 | 
						|
    (*pExaScr->info->accel.DoneComposite) (pDstPix);
 | 
						|
    exaMarkSync(pDst->pDrawable->pScreen);
 | 
						|
    exaDrawableDirty (pDst->pDrawable);
 | 
						|
 | 
						|
    REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
 | 
						|
    return 1;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
void
 | 
						|
exaComposite(CARD8	op,
 | 
						|
	     PicturePtr pSrc,
 | 
						|
	     PicturePtr pMask,
 | 
						|
	     PicturePtr pDst,
 | 
						|
	     INT16	xSrc,
 | 
						|
	     INT16	ySrc,
 | 
						|
	     INT16	xMask,
 | 
						|
	     INT16	yMask,
 | 
						|
	     INT16	xDst,
 | 
						|
	     INT16	yDst,
 | 
						|
	     CARD16	width,
 | 
						|
	     CARD16	height)
 | 
						|
{
 | 
						|
    ExaScreenPriv (pDst->pDrawable->pScreen);
 | 
						|
    int ret = -1;
 | 
						|
 | 
						|
    if (!pMask && pSrc->pDrawable)
 | 
						|
    {
 | 
						|
	if (op == PictOpSrc)
 | 
						|
	{
 | 
						|
	    if (pSrc->pDrawable->width == 1 &&
 | 
						|
		pSrc->pDrawable->height == 1 && pSrc->repeat)
 | 
						|
	    {
 | 
						|
		ret = exaTryDriverSolidFill(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;
 | 
						|
 | 
						|
 | 
						|
		exaCopyNtoN (pSrc->pDrawable, pDst->pDrawable, 0,
 | 
						|
			     REGION_RECTS(®ion), REGION_NUM_RECTS(®ion),
 | 
						|
			     xSrc - xDst, ySrc - yDst,
 | 
						|
			     FALSE, FALSE, 0, 0);
 | 
						|
		return;
 | 
						|
	    }
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
    if (pSrc->pDrawable && (!pMask || pMask->pDrawable) &&
 | 
						|
        pExaScr->info->accel.PrepareComposite &&
 | 
						|
	!pSrc->alphaMap && (!pMask || !pMask->alphaMap) && !pDst->alphaMap)
 | 
						|
    {
 | 
						|
	ret = exaTryDriverComposite(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)
 | 
						|
	    exaPixmapUseMemory ((PixmapPtr) pSrc->pDrawable);
 | 
						|
	if (pMask && pMask->pDrawable->type == DRAWABLE_PIXMAP)
 | 
						|
	    exaPixmapUseMemory ((PixmapPtr) pMask->pDrawable);
 | 
						|
	if (pDst->pDrawable->type == DRAWABLE_PIXMAP)
 | 
						|
	    exaPixmapUseMemory ((PixmapPtr) pDst->pDrawable);
 | 
						|
    }
 | 
						|
 | 
						|
#if EXA_DEBUG_FALLBACKS
 | 
						|
    exaPrintCompositeFallback (op, pSrc, pMask, pDst);
 | 
						|
#endif
 | 
						|
 | 
						|
    ExaCheckComposite (op, pSrc, pMask, pDst, xSrc, ySrc,
 | 
						|
		      xMask, yMask, xDst, yDst, width, height);
 | 
						|
}
 | 
						|
#endif
 |