[PATCH] EXA: Stop hiding solid or gradient pictures from the driver.

Michel Dänzer michel at daenzer.net
Fri Sep 4 01:24:05 PDT 2009


On Fri, 2009-09-04 at 12:59 +1000, Peter Hutterer wrote: 
> On Thu, Sep 03, 2009 at 02:30:11PM +0200, Michel Dänzer wrote:
> > From: Michel Dänzer <daenzer at vmware.com>
> > 
> > Add support for solid pictures in exaTryDriverSolidFill(), but otherwise just
> > pass solid and gradient pictures to the driver Composite hook.
> > 
> > While we're at it, clean up the logic to detect Composite operations which are
> > effectively solid fills or copies. This should also fix some false negatives
> > and positives.
> > ---
> > 
> > Daniel / Peter, is it okay if I push this for 1.7? E.g. the Gallium Xorg state
> > tracker will be able to accelerate solid and gradient pictures soon, and it
> > would be too bad if xserver 1.7 still prevented that.
> > 
> > There's some potential for regressions (though I haven't found any with a
> > hacked rendercheck -t fill), but I'm confident that those could be fixed for
> > the release.
> > 
> >  exa/exa_render.c |  349 ++++++++++++++++++++++++++++++++----------------------
> >  1 files changed, 206 insertions(+), 143 deletions(-)
> > 
> > diff --git a/exa/exa_render.c b/exa/exa_render.c
> > index 1ac29f2..1468c5c 100644
> > --- a/exa/exa_render.c
> > +++ b/exa/exa_render.c
> > @@ -77,11 +77,17 @@ static void exaCompositeFallbackPictDesc(PicturePtr pict, char *string, int n)
> >  	break;
> >      }
> >  
> > -    loc = exaGetOffscreenPixmap(pict->pDrawable, &temp, &temp) ? 's' : 'm';
> > +    if (pict->pDrawable)
> > +	loc = exaGetOffscreenPixmap(pict->pDrawable, &temp, &temp) ? 's' : 'm';
> >  
> > -    snprintf(size, 20, "%dx%d%s", pict->pDrawable->width,
> > -	     pict->pDrawable->height, pict->repeat ?
> > -	     " R" : "");
> > +	snprintf(size, 20, "%dx%d%s", pict->pDrawable->width,
> > +		 pict->pDrawable->height, pict->repeat ?
> > +		 " R" : "");
> 
> there are { } missing from this bit, it doesn't compile. Please make sure
> that you've tested the correct version.

I did test the version I sent, but I failed to notice that
exaCompositeFallbackPictDesc is guarded by DEBUG_TRACE_FALL. Thanks for
pointing this out.

> other than that, airlied acked it, that's good enough for me.

Thanks. The updated patch below fixes the above and simplifies
exaGetRGBAFromPixel / exaGetPixelFromRGBA and their usage a bit. Unless
there are any new objections, I'm planning to push this tonight.


>From d6c2531282cba8fb6aa257674c523ab757eec5ae Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Michel=20D=C3=A4nzer?= <daenzer at vmware.com>
Date: Fri, 4 Sep 2009 10:17:42 +0200
Subject: [PATCH] EXA: Stop hiding solid or gradient pictures from the driver.

Add support for solid pictures in exaTryDriverSolidFill(), but otherwise just
pass solid and gradient pictures to the driver Composite hook.

While we're at it, clean up the logic to detect Composite operations which are
effectively solid fills or copies. This should also fix some false negatives
and positives.
---
 exa/exa_render.c |  387 ++++++++++++++++++++++++++++--------------------------
 1 files changed, 202 insertions(+), 185 deletions(-)

diff --git a/exa/exa_render.c b/exa/exa_render.c
index 1ac29f2..d469301 100644
--- a/exa/exa_render.c
+++ b/exa/exa_render.c
@@ -77,11 +77,17 @@ static void exaCompositeFallbackPictDesc(PicturePtr pict, char *string, int n)
 	break;
     }
 
-    loc = exaGetOffscreenPixmap(pict->pDrawable, &temp, &temp) ? 's' : 'm';
+    if (pict->pDrawable) {
+	loc = exaGetOffscreenPixmap(pict->pDrawable, &temp, &temp) ? 's' : 'm';
 
-    snprintf(size, 20, "%dx%d%s", pict->pDrawable->width,
-	     pict->pDrawable->height, pict->repeat ?
-	     " R" : "");
+	snprintf(size, 20, "%dx%d%s", pict->pDrawable->width,
+		 pict->pDrawable->height, pict->repeat ?
+		 " R" : "");
+    } else {
+	loc = '-';
+
+	snprintf(size, 20, "%s", pict->repeat ? " R" : "");
+    }
 
     snprintf(string, n, "%p:%c fmt %s (%s)", pict->pDrawable, loc, format, size);
 }
@@ -144,38 +150,26 @@ exaGetPixelFromRGBA(CARD32	*pixel,
 		    CARD16	green,
 		    CARD16	blue,
 		    CARD16	alpha,
-		    CARD32	format)
+		    PictFormatPtr pFormat)
 {
     int rbits, bbits, gbits, abits;
     int rshift, bshift, gshift, ashift;
 
     *pixel = 0;
 
-    if (!PICT_FORMAT_COLOR(format))
+    if (!PICT_FORMAT_COLOR(pFormat->format) &&
+	PICT_FORMAT_TYPE(pFormat->format) != PICT_TYPE_A)
 	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 if(PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) {
-	rshift = 0;
-	gshift = rbits;
-	bshift = gshift + gbits;
-	ashift = bshift + bbits;
-    } else if(PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) {
-	bshift = PICT_FORMAT_BPP(format) - bbits;
-	gshift = bshift - gbits;
-	rshift = gshift - rbits;
-	ashift = 0;
-    } else
-	return FALSE;
+    rbits = PICT_FORMAT_R(pFormat->format);
+    gbits = PICT_FORMAT_G(pFormat->format);
+    bbits = PICT_FORMAT_B(pFormat->format);
+    abits = PICT_FORMAT_A(pFormat->format);
+
+    rshift = pFormat->direct.red;
+    gshift = pFormat->direct.green;
+    bshift = pFormat->direct.blue;
+    ashift = pFormat->direct.alpha;
 
     *pixel |=  ( blue >> (16 - bbits)) << bshift;
     *pixel |=  (  red >> (16 - rbits)) << rshift;
@@ -191,36 +185,24 @@ exaGetRGBAFromPixel(CARD32	pixel,
 		    CARD16	*green,
 		    CARD16	*blue,
 		    CARD16	*alpha,
-		    CARD32	format)
+		    PictFormatPtr pFormat)
 {
     int rbits, bbits, gbits, abits;
     int rshift, bshift, gshift, ashift;
 
-    if (!PICT_FORMAT_COLOR(format))
+    if (!PICT_FORMAT_COLOR(pFormat->format) &&
+	PICT_FORMAT_TYPE(pFormat->format) != PICT_TYPE_A)
 	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 if(PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) {
-	rshift = 0;
-	gshift = rbits;
-	bshift = gshift + gbits;
-	ashift = bshift + bbits;
-    } else if(PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) {
-	bshift = PICT_FORMAT_BPP(format) - bbits;
-	gshift = bshift - gbits;
-	rshift = gshift - rbits;
-	ashift = 0;
-    } else
-	return FALSE;
+    rbits = PICT_FORMAT_R(pFormat->format);
+    gbits = PICT_FORMAT_G(pFormat->format);
+    bbits = PICT_FORMAT_B(pFormat->format);
+    abits = PICT_FORMAT_A(pFormat->format);
+
+    rshift = pFormat->direct.red;
+    gshift = pFormat->direct.green;
+    bshift = pFormat->direct.blue;
+    ashift = pFormat->direct.alpha;
 
     *red = ((pixel >> rshift ) & ((1 << rbits) - 1)) << (16 - rbits);
     while (rbits < 16) {
@@ -268,27 +250,22 @@ exaTryDriverSolidFill(PicturePtr	pSrc,
     int nbox;
     int dst_off_x, dst_off_y;
     PixmapPtr pSrcPix, pDstPix;
-    ExaPixmapPrivPtr pSrcExaPix, pDstExaPix;
+    ExaPixmapPrivPtr pDstExaPix;
     CARD32 pixel;
     CARD16 red, green, blue, alpha;
 
     pDstPix = exaGetDrawablePixmap (pDst->pDrawable);
-    pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable);
-
-    pSrcExaPix = ExaGetPixmapPriv(pSrcPix);
     pDstExaPix = ExaGetPixmapPriv(pDstPix);
 
-    /* Check whether the accelerator can use these pixmaps.
+    /* Check whether the accelerator can use the destination pixmap.
      */
-    if (pSrcExaPix->accel_blocked || pDstExaPix->accel_blocked)
+    if (pDstExaPix->accel_blocked)
     {
 	return -1;
     }
 
     xDst += pDst->pDrawable->x;
     yDst += pDst->pDrawable->y;
-    xSrc += pSrc->pDrawable->x;
-    ySrc += pSrc->pDrawable->y;
 
     if (!miComputeCompositeRegion (&region, pSrc, NULL, pDst,
 				   xSrc, ySrc, 0, 0, xDst, yDst,
@@ -299,7 +276,23 @@ exaTryDriverSolidFill(PicturePtr	pSrc,
 
     REGION_TRANSLATE(pScreen, &region, dst_off_x, dst_off_y);
 
-    pixel = exaGetPixmapFirstPixel (pSrcPix);
+    if (pSrc->pDrawable) {
+	xSrc += pSrc->pDrawable->x;
+	ySrc += pSrc->pDrawable->y;
+
+	pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable);
+	pixel = exaGetPixmapFirstPixel (pSrcPix);
+    } else
+	pixel = pSrc->pSourcePict->solidFill.color;
+
+    if (!exaGetRGBAFromPixel(pixel, &red, &green, &blue, &alpha,
+			     pSrc->pFormat) ||
+	!exaGetPixelFromRGBA(&pixel, red, green, blue, alpha,
+			     pDst->pFormat))
+    {
+	REGION_UNINIT(pDst->pDrawable->pScreen, &region);
+	return -1;
+    }
 
     if (pExaScr->do_migration) {
 	ExaMigrationRec pixmaps[1];
@@ -316,20 +309,6 @@ exaTryDriverSolidFill(PicturePtr	pSrc,
 	return 0;
     }
 
-    if (!exaGetRGBAFromPixel(pixel, &red, &green, &blue, &alpha,
-			 pSrc->format))
-    {
-	REGION_UNINIT(pDst->pDrawable->pScreen, &region);
-	return -1;
-    }
-
-    if (!exaGetPixelFromRGBA(&pixel, red, green, blue, alpha,
-			pDst->format))
-    {
-	REGION_UNINIT(pDst->pDrawable->pScreen, &region);
-	return -1;
-    }
-
     if (!(*pExaScr->info->PrepareSolid) (pDstPix, GXcopy, 0xffffffff, pixel))
     {
 	REGION_UNINIT(pDst->pDrawable->pScreen, &region);
@@ -362,16 +341,18 @@ exaTryDriverCompositeRects(CARD8	       op,
 {
     ExaScreenPriv (pDst->pDrawable->pScreen);
     int src_off_x, src_off_y, mask_off_x, mask_off_y, dst_off_x, dst_off_y;
-    PixmapPtr pSrcPix, pMaskPix = NULL, pDstPix;
-    ExaPixmapPrivPtr pSrcExaPix, pMaskExaPix = NULL, pDstExaPix;
+    PixmapPtr pSrcPix = NULL, pMaskPix = NULL, pDstPix;
+    ExaPixmapPrivPtr pSrcExaPix = NULL, pMaskExaPix = NULL, pDstExaPix;
 
     if (!pExaScr->info->PrepareComposite)
 	return -1;
 
-    pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
-    pSrcExaPix = ExaGetPixmapPriv(pSrcPix);
+    if (pSrc->pDrawable) {
+	pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
+	pSrcExaPix = ExaGetPixmapPriv(pSrcPix);
+    }
 
-    if (pMask) {
+    if (pMask && pMask->pDrawable) {
 	pMaskPix = exaGetDrawablePixmap(pMask->pDrawable);
 	pMaskExaPix = ExaGetPixmapPriv(pMaskPix);
     }
@@ -383,8 +364,9 @@ exaTryDriverCompositeRects(CARD8	       op,
      * FIXME: If it cannot, use temporary pixmaps so that the drawing
      * happens within limits.
      */
-    if (pSrcExaPix->accel_blocked || pDstExaPix->accel_blocked ||
-	(pMask && pMaskExaPix->accel_blocked))
+    if (pDstExaPix->accel_blocked ||
+	(pSrcExaPix && pSrcExaPix->accel_blocked) ||
+	(pMaskExaPix && pMaskExaPix->accel_blocked))
     {
 	return -1;
     }
@@ -397,37 +379,45 @@ exaTryDriverCompositeRects(CARD8	       op,
 
     if (pExaScr->do_migration) {
 	ExaMigrationRec pixmaps[3];
+	int i = 0;
+
+	pixmaps[i].as_dst = TRUE;
+	pixmaps[i].as_src = exaOpReadsDestination(op);
+	pixmaps[i].pPix = pDstPix;
+	pixmaps[i].pReg = NULL;
+	i++;
+
+	if (pSrcPix) {
+	    pixmaps[i].as_dst = FALSE;
+	    pixmaps[i].as_src = TRUE;
+	    pixmaps[i].pPix = pSrcPix;
+	    pixmaps[i].pReg = NULL;
+	    i++;
+	}
 
-	pixmaps[0].as_dst = TRUE;
-	pixmaps[0].as_src = exaOpReadsDestination(op);
-	pixmaps[0].pPix = pDstPix;
-	pixmaps[0].pReg = NULL;
-	pixmaps[1].as_dst = FALSE;
-	pixmaps[1].as_src = TRUE;
-	pixmaps[1].pPix = pSrcPix;
-	pixmaps[1].pReg = NULL;
-	if (pMask) {
-	    pixmaps[2].as_dst = FALSE;
-	    pixmaps[2].as_src = TRUE;
-	    pixmaps[2].pPix = pMaskPix;
-	    pixmaps[2].pReg = NULL;
-	    exaDoMigration(pixmaps, 3, TRUE);
-	} else
-	    exaDoMigration(pixmaps, 2, TRUE);
+	if (pMaskPix) {
+	    pixmaps[i].as_dst = FALSE;
+	    pixmaps[i].as_src = TRUE;
+	    pixmaps[i].pPix = pMaskPix;
+	    pixmaps[i].pReg = NULL;
+	    i++;
+	}
+
+	exaDoMigration(pixmaps, i, TRUE);
     }
 
     pDstPix = exaGetOffscreenPixmap (pDst->pDrawable, &dst_off_x, &dst_off_y);
     if (!pDstPix)
 	return 0;
-    
-    pSrcPix = exaGetOffscreenPixmap (pSrc->pDrawable, &src_off_x, &src_off_y);
 
-    if (!pSrcPix)
-	return 0;
+    if (pSrcPix) {
+	pSrcPix = exaGetOffscreenPixmap (pSrc->pDrawable, &src_off_x, &src_off_y);
+	if (!pSrcPix)
+	    return 0;
+    }
 
-    if (pMask) {
+    if (pMaskPix) {
 	pMaskPix = exaGetOffscreenPixmap (pMask->pDrawable, &mask_off_x, &mask_off_y);
-
 	if (!pMaskPix)
 	    return 0;
     }
@@ -440,15 +430,24 @@ exaTryDriverCompositeRects(CARD8	       op,
     {
 	INT16 xDst = rects->xDst + pDst->pDrawable->x;
 	INT16 yDst = rects->yDst + pDst->pDrawable->y;
-	INT16 xMask = pMask ? rects->xMask + pMask->pDrawable->x : 0;
-	INT16 yMask = pMask ? rects->yMask + pMask->pDrawable->y : 0;
-	INT16 xSrc = rects->xSrc + pSrc->pDrawable->x;
-	INT16 ySrc = rects->ySrc + pSrc->pDrawable->y;
-
+	INT16 xMask = rects->xMask;
+	INT16 yMask = rects->yMask;
+	INT16 xSrc = rects->xSrc;
+	INT16 ySrc = rects->ySrc;
 	RegionRec region;
 	BoxPtr pbox;
 	int nbox;
-	
+
+	if (pMaskPix) {
+	    xMask += pMask->pDrawable->x;
+	    yMask += pMask->pDrawable->y;
+	}
+
+	if (pSrcPix) {
+	    xSrc += pSrc->pDrawable->x;
+	    ySrc += pSrc->pDrawable->y;
+	}
+
 	if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
 				       xSrc, ySrc, xMask, yMask, xDst, yDst,
 				       rects->width, rects->height))
@@ -635,16 +634,18 @@ exaTryDriverComposite(CARD8		op,
     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;
-    ExaPixmapPrivPtr pSrcExaPix, pMaskExaPix = NULL, pDstExaPix;
+    PixmapPtr pSrcPix = NULL, pMaskPix = NULL, pDstPix;
+    ExaPixmapPrivPtr pSrcExaPix = NULL, pMaskExaPix = NULL, pDstExaPix;
 
-    pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
-    pSrcExaPix = ExaGetPixmapPriv(pSrcPix);
+    if (pSrc->pDrawable) {
+	pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
+	pSrcExaPix = ExaGetPixmapPriv(pSrcPix);
+    }
 
     pDstPix = exaGetDrawablePixmap(pDst->pDrawable);
     pDstExaPix = ExaGetPixmapPriv(pDstPix);
 
-    if (pMask) {
+    if (pMask && pMask->pDrawable) {
 	pMaskPix = exaGetDrawablePixmap(pMask->pDrawable);
         pMaskExaPix = ExaGetPixmapPriv(pMaskPix);
     }
@@ -653,8 +654,8 @@ exaTryDriverComposite(CARD8		op,
      * FIXME: If it cannot, use temporary pixmaps so that the drawing
      * happens within limits.
      */
-    if (pSrcExaPix->accel_blocked ||
-	pDstExaPix->accel_blocked ||
+    if (pDstExaPix->accel_blocked ||
+	(pSrcExaPix && pSrcExaPix->accel_blocked) ||
 	(pMask && (pMaskExaPix->accel_blocked)))
     {
 	return -1;
@@ -663,13 +664,15 @@ exaTryDriverComposite(CARD8		op,
     xDst += pDst->pDrawable->x;
     yDst += pDst->pDrawable->y;
 
-    if (pMask) {
+    if (pMaskPix) {
 	xMask += pMask->pDrawable->x;
 	yMask += pMask->pDrawable->y;
     }
 
-    xSrc += pSrc->pDrawable->x;
-    ySrc += pSrc->pDrawable->y;
+    if (pSrcPix) {
+	xSrc += pSrc->pDrawable->x;
+	ySrc += pSrc->pDrawable->y;
+    }
 
     if (pExaScr->info->CheckComposite &&
 	!(*pExaScr->info->CheckComposite) (op, pSrc, pMask, pDst))
@@ -688,36 +691,51 @@ exaTryDriverComposite(CARD8		op,
 
     if (pExaScr->do_migration) {
 	ExaMigrationRec pixmaps[3];
+	int i = 0;
+
+	pixmaps[i].as_dst = TRUE;
+	pixmaps[i].as_src = exaOpReadsDestination(op);
+	pixmaps[i].pPix = pDstPix;
+	pixmaps[i].pReg = pixmaps[0].as_src ? NULL : &region;
+	i++;
+
+	if (pSrcPix) {
+	    pixmaps[i].as_dst = FALSE;
+	    pixmaps[i].as_src = TRUE;
+	    pixmaps[i].pPix = pSrcPix;
+	    pixmaps[i].pReg = NULL;
+	    i++;
+	}
 
-	pixmaps[0].as_dst = TRUE;
-	pixmaps[0].as_src = exaOpReadsDestination(op);
-	pixmaps[0].pPix = pDstPix;
-	pixmaps[0].pReg = pixmaps[0].as_src ? NULL : &region;
-	pixmaps[1].as_dst = FALSE;
-	pixmaps[1].as_src = TRUE;
-	pixmaps[1].pPix = pSrcPix;
-	pixmaps[1].pReg = NULL;
-	if (pMask) {
-	    pixmaps[2].as_dst = FALSE;
-	    pixmaps[2].as_src = TRUE;
-	    pixmaps[2].pPix = pMaskPix;
-	    pixmaps[2].pReg = NULL;
-	    exaDoMigration(pixmaps, 3, TRUE);
-	} else
-	    exaDoMigration(pixmaps, 2, TRUE);
+	if (pMaskPix) {
+	    pixmaps[i].as_dst = FALSE;
+	    pixmaps[i].as_src = TRUE;
+	    pixmaps[i].pPix = pMaskPix;
+	    pixmaps[i].pReg = NULL;
+	    i++;
+	}
+
+	exaDoMigration(pixmaps, i, TRUE);
     }
 
-    pSrcPix = exaGetOffscreenPixmap (pSrc->pDrawable, &src_off_x, &src_off_y);
-    if (pMask)
+    if (pSrcPix) {
+	pSrcPix = exaGetOffscreenPixmap (pSrc->pDrawable, &src_off_x, &src_off_y);
+	if (!pSrcPix) {
+	    REGION_UNINIT(pDst->pDrawable->pScreen, &region);
+	    return 0;
+	}
+    }
+
+    if (pMaskPix) {
 	pMaskPix = exaGetOffscreenPixmap (pMask->pDrawable, &mask_off_x,
 					  &mask_off_y);
-
-    if (!exaPixmapIsOffscreen(pDstPix)) {
-	REGION_UNINIT(pDst->pDrawable->pScreen, &region);
-	return 0;
+	if (!pMaskPix) {
+	    REGION_UNINIT(pDst->pDrawable->pScreen, &region);
+	    return 0;
+	}
     }
 
-    if (!pSrcPix || (pMask && !pMaskPix)) {
+    if (!exaPixmapIsOffscreen(pDstPix)) {
 	REGION_UNINIT(pDst->pDrawable->pScreen, &region);
 	return 0;
     }
@@ -868,45 +886,44 @@ exaComposite(CARD8	op,
     Bool saveMaskRepeat = pMask ? pMask->repeat : 0;
     RegionRec region;
 
-    /* We currently don't support acceleration of gradients, or other pictures
-     * with a NULL pDrawable.
-     */
-    if (pExaScr->swappedOut ||
-	pSrc->pDrawable == NULL || (pMask != NULL && pMask->pDrawable == NULL))
-    {
+    if (pExaScr->swappedOut)
 	goto fallback;
-    }
 
     /* Remove repeat in source if useless */
-    if (pSrc->repeat && !pSrc->transform && xSrc >= 0 &&
+    if (pSrc->pDrawable && pSrc->repeat && !pSrc->transform && xSrc >= 0 &&
 	(xSrc + width) <= pSrc->pDrawable->width && ySrc >= 0 &&
 	(ySrc + height) <= pSrc->pDrawable->height)
 	    pSrc->repeat = 0;
 
-    if (!pMask)
+    if (!pMask && !pSrc->alphaMap && !pDst->alphaMap &&
+	(op == PictOpSrc || (op == PictOpOver && !PICT_FORMAT_A(pSrc->format))))
     {
-      if ((op == PictOpSrc &&
-	   ((pSrc->format == pDst->format) ||
-	    (pSrc->format==PICT_b8g8r8a8 && pDst->format==PICT_b8g8r8x8) ||
-	    (pSrc->format==PICT_a8r8g8b8 && pDst->format==PICT_x8r8g8b8) ||
-	    (pSrc->format==PICT_a8b8g8r8 && pDst->format==PICT_x8b8g8r8))) ||
-	  (op == PictOpOver && !pSrc->alphaMap && !pDst->alphaMap &&
-	   pSrc->format == pDst->format &&
-	   (pSrc->format==PICT_x8r8g8b8 || pSrc->format==PICT_x8b8g8r8 ||
-	    pSrc->format==PICT_b8g8r8x8)))
+	if (pSrc->pDrawable ?
+	    (pSrc->pDrawable->width == 1 && pSrc->pDrawable->height == 1 &&
+	     pSrc->repeat) :
+	    (pSrc->pSourcePict->type == SourcePictTypeSolidFill))
 	{
-	    if (pSrc->pDrawable->width == 1 &&
-		pSrc->pDrawable->height == 1 &&
-		pSrc->repeat)
-	    {
-		ret = exaTryDriverSolidFill(pSrc, pDst, xSrc, ySrc, xDst, yDst,
-					    width, height);
-		if (ret == 1)
-		    goto done;
-	    }
-	    else if (pSrc->pDrawable != NULL &&
-		     !pSrc->repeat &&
-		     !pSrc->transform)
+	    ret = exaTryDriverSolidFill(pSrc, pDst, xSrc, ySrc, xDst, yDst,
+					width, height);
+	    if (ret == 1)
+		goto done;
+	} else if (pSrc->pDrawable && !pSrc->transform &&
+	    ((op == PictOpSrc &&
+	      (pSrc->format == pDst->format ||
+	       (PICT_FORMAT_COLOR(pDst->format) &&
+		PICT_FORMAT_COLOR(pSrc->format) &&
+		pDst->format == PICT_FORMAT(PICT_FORMAT_BPP(pSrc->format),
+					    PICT_FORMAT_TYPE(pSrc->format),
+					    0,
+					    PICT_FORMAT_R(pSrc->format),
+					    PICT_FORMAT_G(pSrc->format),
+					    PICT_FORMAT_B(pSrc->format))))) ||
+	     (op == PictOpOver && pSrc->format == pDst->format &&
+	      !PICT_FORMAT_A(pSrc->format))))
+	{
+	    if (!pSrc->repeat && xSrc >= 0 && ySrc >= 0 &&
+		(xSrc + width <= pSrc->pDrawable->width) &&
+		(ySrc + height <= pSrc->pDrawable->height))
 	    {
 		Bool ret;
 		xDst += pDst->pDrawable->x;
@@ -935,10 +952,9 @@ exaComposite(CARD8	op,
 
 		goto done;
 	    }
-	    else if (pSrc->pDrawable != NULL &&
-		     pSrc->pDrawable->type == DRAWABLE_PIXMAP &&
-		     !pSrc->transform &&
-		     pSrc->repeatType == RepeatNormal)
+
+	    if (pSrc->repeat && pSrc->repeatType == RepeatNormal &&
+		pSrc->pDrawable->type == DRAWABLE_PIXMAP)
 	    {
 		DDXPointRec patOrg;
 
@@ -988,9 +1004,9 @@ exaComposite(CARD8	op,
     }
 
     /* Remove repeat in mask if useless */
-    if (pMask && pMask->repeat && !pMask->transform && xMask >= 0 &&
-	(xMask + width) <= pMask->pDrawable->width && yMask >= 0 &&
-	(yMask + height) <= pMask->pDrawable->height)
+    if (pMask && pMask->pDrawable && pMask->repeat && !pMask->transform &&
+	xMask >= 0 && (xMask + width) <= pMask->pDrawable->width &&
+	yMask >= 0 && (yMask + height) <= pMask->pDrawable->height)
 	    pMask->repeat = 0;
 
     if (pExaScr->info->PrepareComposite &&
@@ -1006,9 +1022,10 @@ exaComposite(CARD8	op,
 	/* For generic masks and solid src pictures, mach64 can do Over in two
 	 * passes, similar to the component-alpha case.
 	 */
-	isSrcSolid = pSrc->pDrawable->width == 1 &&
-		     pSrc->pDrawable->height == 1 &&
-		     pSrc->repeat;
+	isSrcSolid = pSrc->pDrawable ?
+	    (pSrc->pDrawable->width == 1 && pSrc->pDrawable->height == 1 &&
+	     pSrc->repeat) :
+	    (pSrc->pSourcePict->type == SourcePictTypeSolidFill);
 
 	/* If we couldn't do the Composite in a single pass, and it was a
 	 * component-alpha Over, see if we can do it in two passes with
-- 
1.6.3.3


-- 
Earthling Michel Dänzer           |                http://www.vmware.com
Libre software enthusiast         |          Debian, X and DRI developer


More information about the xorg-devel mailing list