xserver: Branch 'master' - 2 commits

Michel Dänzer daenzer at kemper.freedesktop.org
Thu Feb 26 01:37:14 PST 2009


 exa/exa.c        |    9 +
 exa/exa_glyphs.c |  253 ++++++++++++++++++++-----------------------------------
 exa/exa_priv.h   |    4 
 exa/exa_render.c |  123 ++++++++++++++++++--------
 4 files changed, 191 insertions(+), 198 deletions(-)

New commits:
commit f07f18231a921d3ae9dd9b75881c9e58e9e2e235
Author: Michel Dänzer <daenzer at vmware.com>
Date:   Thu Feb 26 10:35:44 2009 +0100

    EXA: Allow using exaCompositeRects also when we can't use a mask in exaGlyphs.
    
    This should give the full benefits of the glyph cache even when we can't use a
    mask.
    
    This also means we no longer need to scan the glyphs to see if they overlap,
    we can just use a mask or not as the client asks.
    
    Signed-off-by: Michel Dänzer <daenzer at vmware.com>

diff --git a/exa/exa_glyphs.c b/exa/exa_glyphs.c
index 688081d..918fd85 100644
--- a/exa/exa_glyphs.c
+++ b/exa/exa_glyphs.c
@@ -68,7 +68,7 @@
 #define GLYPH_BUFFER_SIZE 256
 
 typedef struct {
-    PicturePtr source;
+    PicturePtr mask;
     ExaCompositeRectRec rects[GLYPH_BUFFER_SIZE];
     int count;
 } ExaGlyphBuffer, *ExaGlyphBufferPtr;
@@ -144,7 +144,7 @@ exaUnrealizeGlyphCaches(ScreenPtr    pScreen,
 
 /* All caches for a single format share a single pixmap for glyph storage,
  * allowing mixing glyphs of different sizes without paying a penalty
- * for switching between source pixmaps. (Note that for a size of font
+ * for switching between mask pixmaps. (Note that for a size of font
  * right at the border between two sizes, we might be switching for almost
  * every glyph.)
  *
@@ -417,13 +417,19 @@ exaGlyphCacheBufferGlyph(ScreenPtr         pScreen,
 			 ExaGlyphCachePtr  cache,
 			 ExaGlyphBufferPtr buffer,
 			 GlyphPtr          pGlyph,
-			 int               xGlyph,
-			 int               yGlyph)
+			 PicturePtr        pSrc,
+			 PicturePtr        pDst,
+			 INT16             xSrc,
+			 INT16             ySrc,
+			 INT16             xMask,
+			 INT16             yMask,
+			 INT16             xDst,
+			 INT16             yDst)
 {
     ExaCompositeRectPtr rect;
     int pos;
     
-    if (buffer->source && buffer->source != cache->picture)
+    if (buffer->mask && buffer->mask != cache->picture)
 	return ExaGlyphNeedFlush;
 
     if (!cache->picture) {
@@ -497,13 +503,28 @@ exaGlyphCacheBufferGlyph(ScreenPtr         pScreen,
 
     }
 
-    buffer->source = cache->picture;
+    buffer->mask = cache->picture;
 	    
     rect = &buffer->rects[buffer->count];
-    rect->xSrc = CACHE_X(pos);
-    rect->ySrc = CACHE_Y(pos);
-    rect->xDst = xGlyph - pGlyph->info.x;
-    rect->yDst = yGlyph - pGlyph->info.y;
+
+    if (pSrc)
+    {
+	rect->xSrc = xSrc;
+	rect->ySrc = ySrc;
+	rect->xMask = CACHE_X(pos);
+	rect->yMask = CACHE_Y(pos);
+    }
+    else
+    {
+	rect->xSrc = CACHE_X(pos);
+	rect->ySrc = CACHE_Y(pos);
+	rect->xMask = 0;
+	rect->yMask = 0;
+    }
+
+    rect->pDst = pDst;
+    rect->xDst = xDst - pGlyph->info.x;
+    rect->yDst = yDst - pGlyph->info.y;
     rect->width = pGlyph->info.width;
     rect->height = pGlyph->info.height;
 
@@ -519,15 +540,21 @@ static ExaGlyphCacheResult
 exaBufferGlyph(ScreenPtr         pScreen,
 	       ExaGlyphBufferPtr buffer,
 	       GlyphPtr          pGlyph,
-	       int               xGlyph,
-	       int               yGlyph)
+	       PicturePtr        pSrc,
+	       PicturePtr        pDst,
+	       INT16             xSrc,
+	       INT16             ySrc,
+	       INT16             xMask,
+	       INT16             yMask,
+	       INT16             xDst,
+	       INT16             yDst)
 {
     ExaScreenPriv(pScreen);
     unsigned int format = (GlyphPicture(pGlyph)[pScreen->myNum])->format;
     int width = pGlyph->info.width;
     int height = pGlyph->info.height;
     ExaCompositeRectPtr rect;
-    PicturePtr source;
+    PicturePtr mask;
     int i;
 
     if (buffer->count == GLYPH_BUFFER_SIZE)
@@ -542,9 +569,15 @@ exaBufferGlyph(ScreenPtr         pScreen,
 	if (format == cache->format &&
 	    width <= cache->glyphWidth &&
 	    height <= cache->glyphHeight) {
-	    ExaGlyphCacheResult result = exaGlyphCacheBufferGlyph(pScreen, &pExaScr->glyphCaches[i],
+	    ExaGlyphCacheResult result = exaGlyphCacheBufferGlyph(pScreen,
+								  &pExaScr->glyphCaches[i],
 								  buffer,
-								  pGlyph, xGlyph, yGlyph);
+								  pGlyph,
+								  pSrc,
+								  pDst,
+								  xSrc, ySrc,
+								  xMask, yMask,
+								  xDst, yDst);
 	    switch (result) {
 	    case ExaGlyphFail:
 		break;
@@ -557,19 +590,21 @@ exaBufferGlyph(ScreenPtr         pScreen,
 
     /* Couldn't find the glyph in the cache, use the glyph picture directly */
 
-    source = GlyphPicture(pGlyph)[pScreen->myNum];
-    if (buffer->source && buffer->source != source)
+    mask = GlyphPicture(pGlyph)[pScreen->myNum];
+    if (buffer->mask && buffer->mask != mask)
 	return ExaGlyphNeedFlush;
 
-    buffer->source = source;
-    
+    buffer->mask = mask;
+
     rect = &buffer->rects[buffer->count];
-    rect->xSrc = 0;
-    rect->ySrc = 0;
-    rect->xDst = xGlyph - pGlyph->info.x;
-    rect->yDst = yGlyph - pGlyph->info.y;
-    rect->width = pGlyph->info.width;
-    rect->height = pGlyph->info.height;
+    rect->xSrc = xSrc;
+    rect->ySrc = ySrc;
+    rect->xMask = xMask;
+    rect->yMask = yMask;
+    rect->xDst = xDst - pGlyph->info.x;
+    rect->yDst = yDst - pGlyph->info.y;
+    rect->width = width;
+    rect->height = height;
 
     buffer->count++;
 
@@ -580,44 +615,23 @@ static void
 exaGlyphsToMask(PicturePtr        pMask,
 		ExaGlyphBufferPtr buffer)
 {
-    exaCompositeRects(PictOpAdd, buffer->source, pMask,
+    exaCompositeRects(PictOpAdd, buffer->mask, NULL, pMask,
 		      buffer->count, buffer->rects);
     
     buffer->count = 0;
-    buffer->source = NULL;
+    buffer->mask = NULL;
 }
 
 static void
-exaGlyphsToDst(CARD8		 op,
-	       PicturePtr	 pSrc,
+exaGlyphsToDst(PicturePtr	 pSrc,
 	       PicturePtr	 pDst,
-	       ExaGlyphBufferPtr buffer,
-	       INT16		 xSrc,
-	       INT16		 ySrc,
-	       INT16		 xDst,
-	       INT16		 yDst)
+	       ExaGlyphBufferPtr buffer)
 {
-    int i;
-
-    for (i = 0; i < buffer->count; i++) {
-	ExaCompositeRectPtr rect = &buffer->rects[i];
-
-	CompositePicture (op,
-			  pSrc,
-			  buffer->source,
-			  pDst,
-			  xSrc + rect->xDst - xDst,
-			  ySrc + rect->yDst - yDst,
-			  rect->xSrc,
-			  rect->ySrc,
-			  rect->xDst,
-			  rect->yDst,
-			  rect->width,
-			  rect->height);
-    }
+    exaCompositeRects(PictOpOver, pSrc, buffer->mask, pDst, buffer->count,
+		      buffer->rects);
     
     buffer->count = 0;
-    buffer->source = NULL;
+    buffer->mask = NULL;
 }
 
 /* Cut and paste from render/glyph.c - probably should export it instead */
@@ -673,79 +687,6 @@ GlyphExtents (int		nlist,
     }
 }
 
-/**
- * Returns TRUE if the glyphs in the lists intersect.  Only checks based on
- * bounding box, which appears to be good enough to catch most cases at least.
- */
-static Bool
-exaGlyphsIntersect(int nlist, GlyphListPtr list, GlyphPtr *glyphs)
-{
-    int x1, x2, y1, y2;
-    int n;
-    GlyphPtr glyph;
-    int x, y;
-    BoxRec extents;
-    Bool first = TRUE;
-
-    x = 0;
-    y = 0;
-    while (nlist--) {
-       x += list->xOff;
-       y += list->yOff;
-       n = list->len;
-       list++;
-       while (n--) {
-           glyph = *glyphs++;
-
-           if (glyph->info.width == 0 || glyph->info.height == 0) {
-               x += glyph->info.xOff;
-               y += glyph->info.yOff;
-               continue;
-           }
-
-           x1 = x - glyph->info.x;
-           if (x1 < MINSHORT)
-               x1 = MINSHORT;
-           y1 = y - glyph->info.y;
-           if (y1 < MINSHORT)
-               y1 = MINSHORT;
-           x2 = x1 + glyph->info.width;
-           if (x2 > MAXSHORT)
-               x2 = MAXSHORT;
-           y2 = y1 + glyph->info.height;
-           if (y2 > MAXSHORT)
-               y2 = MAXSHORT;
-
-           if (first) {
-               extents.x1 = x1;
-               extents.y1 = y1;
-               extents.x2 = x2;
-               extents.y2 = y2;
-               first = FALSE;
-           } else {
-               if (x1 < extents.x2 && x2 > extents.x1 &&
-                   y1 < extents.y2 && y2 > extents.y1)
-               {
-                   return TRUE;
-               }
-
-               if (x1 < extents.x1)
-                  extents.x1 = x1;
-               if (x2 > extents.x2)
-                   extents.x2 = x2;
-               if (y1 < extents.y1)
-                   extents.y1 = y1;
-               if (y2 > extents.y2)
-                   extents.y2 = y2;
-           }
-           x += glyph->info.xOff;
-           y += glyph->info.yOff;
-       }
-    }
-
-    return FALSE;
-}
-
 void
 exaGlyphs (CARD8 	 op,
 	   PicturePtr	 pSrc,
@@ -759,7 +700,7 @@ exaGlyphs (CARD8 	 op,
 {
     PicturePtr	pPicture;
     PixmapPtr   pMaskPixmap = 0;
-    PicturePtr  pMask;
+    PicturePtr  pMask = NULL;
     ScreenPtr   pScreen = pDst->pDrawable->pScreen;
     int		width = 0, height = 0;
     int		x, y;
@@ -771,29 +712,6 @@ exaGlyphs (CARD8 	 op,
     CARD32	component_alpha;
     ExaGlyphBuffer buffer;
 
-    /* If we don't have a mask format but all the glyphs have the same format
-     * and don't intersect, use the glyph format as mask format for the full
-     * benefits of the glyph cache.
-     */
-    if (!maskFormat) {
-       Bool sameFormat = TRUE;
-       int i;
-
-       maskFormat = list[0].format;
-
-       for (i = 0; i < nlist; i++) {
-           if (maskFormat->format != list[i].format->format) {
-               sameFormat = FALSE;
-               break;
-           }
-       }
-
-       if (!sameFormat || (maskFormat->depth != 1 &&
-			   exaGlyphsIntersect(nlist, list, glyphs))) {
-	   maskFormat = NULL;
-       }
-    }
-
     if (maskFormat)
     {
 	GCPtr	    pGC;
@@ -840,12 +758,11 @@ exaGlyphs (CARD8 	 op,
     }
     else
     {
-	pMask = pDst;
 	x = 0;
 	y = 0;
     }
     buffer.count = 0;
-    buffer.source = NULL;
+    buffer.mask = NULL;
     while (nlist--)
     {
 	x += list->xOff;
@@ -856,16 +773,31 @@ exaGlyphs (CARD8 	 op,
 	    glyph = *glyphs++;
 	    pPicture = GlyphPicture (glyph)[pScreen->myNum];
 
-	    if (glyph->info.width > 0 && glyph->info.height > 0 &&
-		exaBufferGlyph(pScreen, &buffer, glyph, x, y) == ExaGlyphNeedFlush)
+	    if (glyph->info.width > 0 && glyph->info.height > 0)
 	    {
 		if (maskFormat)
-		    exaGlyphsToMask(pMask, &buffer);
+		{
+		    if (exaBufferGlyph(pScreen, &buffer, glyph, NULL, pMask,
+				       0, 0, 0, 0, x, y) == ExaGlyphNeedFlush)
+		    {
+			exaGlyphsToMask(pMask, &buffer);
+			exaBufferGlyph(pScreen, &buffer, glyph, NULL, pMask,
+				       0, 0, 0, 0, x, y);
+		    }
+		}
 		else
-		    exaGlyphsToDst(op, pSrc, pDst, &buffer,
-				   xSrc, ySrc, xDst, yDst);
-
-		exaBufferGlyph(pScreen, &buffer, glyph, x, y);
+		{
+		    if (exaBufferGlyph(pScreen, &buffer, glyph, pSrc, pDst,
+				       xSrc + x - xDst, ySrc + y - yDst,
+				       x, y, x + extents.x1, y + extents.y1)
+			== ExaGlyphNeedFlush)
+		    {
+			exaGlyphsToDst(pSrc, pDst, &buffer);
+			exaBufferGlyph(pScreen, &buffer, glyph, pSrc, pDst,
+				       xSrc + x - xDst, ySrc + y - yDst,
+				       x, y, x + extents.x1, y + extents.y1);
+		    }
+		}
 	    }
 
 	    x += glyph->info.xOff;
@@ -878,8 +810,7 @@ exaGlyphs (CARD8 	 op,
         if (maskFormat)
 	    exaGlyphsToMask(pMask, &buffer);
         else
-	    exaGlyphsToDst(op, pSrc, pDst, &buffer,
-		           xSrc, ySrc, xDst, yDst);
+	    exaGlyphsToDst(pSrc, pDst, &buffer);
     }
 
     if (maskFormat)
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index ea8c3da..8f83701 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -287,8 +287,11 @@ typedef struct _ExaMigrationRec {
 } ExaMigrationRec, *ExaMigrationPtr;
 
 typedef struct {
+    PicturePtr pDst;
     INT16 xSrc;
     INT16 ySrc;
+    INT16 xMask;
+    INT16 yMask;
     INT16 xDst;
     INT16 yDst;
     INT16 width;
@@ -519,6 +522,7 @@ exaComposite(CARD8	op,
 void
 exaCompositeRects(CARD8	              op,
 		  PicturePtr	      Src,
+		  PicturePtr	      pMask,
 		  PicturePtr	      pDst,
 		  int                 nrect,
 		  ExaCompositeRectPtr rects);
diff --git a/exa/exa_render.c b/exa/exa_render.c
index bdc1ed1..d53f13b 100644
--- a/exa/exa_render.c
+++ b/exa/exa_render.c
@@ -334,15 +334,16 @@ exaTryDriverSolidFill(PicturePtr	pSrc,
 static int
 exaTryDriverCompositeRects(CARD8	       op,
 			   PicturePtr	       pSrc,
+			   PicturePtr	       pMask,
 			   PicturePtr	       pDst,
 			   int                 nrect,
 			   ExaCompositeRectPtr rects)
 {
     ExaScreenPriv (pDst->pDrawable->pScreen);
-    int src_off_x, src_off_y, dst_off_x, dst_off_y;
-    PixmapPtr pSrcPix, pDstPix;
-    ExaPixmapPrivPtr pSrcExaPix, pDstExaPix;
-    ExaMigrationRec pixmaps[2];
+    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;
+    ExaMigrationRec pixmaps[3];
 
     if (!pExaScr->info->PrepareComposite)
 	return -1;
@@ -350,6 +351,11 @@ exaTryDriverCompositeRects(CARD8	       op,
     pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
     pSrcExaPix = ExaGetPixmapPriv(pSrcPix);
 
+    if (pMask) {
+	pMaskPix = exaGetDrawablePixmap(pMask->pDrawable);
+	pMaskExaPix = ExaGetPixmapPriv(pMaskPix);
+    }
+
     pDstPix = exaGetDrawablePixmap(pDst->pDrawable);
     pDstExaPix = ExaGetPixmapPriv(pDstPix);
 
@@ -357,20 +363,18 @@ exaTryDriverCompositeRects(CARD8	       op,
      * FIXME: If it cannot, use temporary pixmaps so that the drawing
      * happens within limits.
      */
-    if (pSrcExaPix->accel_blocked ||
-	pDstExaPix->accel_blocked)
+    if (pSrcExaPix->accel_blocked || pDstExaPix->accel_blocked ||
+	(pMask && pMaskExaPix->accel_blocked))
     {
 	return -1;
     }
 
     if (pExaScr->info->CheckComposite &&
-	!(*pExaScr->info->CheckComposite) (op, pSrc, NULL, pDst))
+	!(*pExaScr->info->CheckComposite) (op, pSrc, pMask, pDst))
     {
 	return -1;
     }
     
-    exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &dst_off_x, &dst_off_y);
-
     pixmaps[0].as_dst = TRUE;
     pixmaps[0].as_src = exaOpReadsDestination(op);
     pixmaps[0].pPix = pDstPix;
@@ -379,32 +383,49 @@ exaTryDriverCompositeRects(CARD8	       op,
     pixmaps[1].as_src = TRUE;
     pixmaps[1].pPix = pSrcPix;
     pixmaps[1].pReg = NULL;
-    exaDoMigration(pixmaps, 2, TRUE);
+    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);
 
-    pSrcPix = exaGetOffscreenPixmap (pSrc->pDrawable, &src_off_x, &src_off_y);
-    if (!exaPixmapIsOffscreen(pDstPix))
+    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 (!(*pExaScr->info->PrepareComposite) (op, pSrc, NULL, pDst, pSrcPix,
-					     NULL, pDstPix))
+    if (pMask) {
+	pMaskPix = exaGetOffscreenPixmap (pMask->pDrawable, &mask_off_x, &mask_off_y);
+
+	if (!pMaskPix)
+	    return 0;
+    }
+
+    if (!(*pExaScr->info->PrepareComposite) (op, pSrc, pMask, pDst, pSrcPix,
+					     pMaskPix, pDstPix))
 	return -1;
 
     while (nrect--)
     {
 	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;
 
 	RegionRec region;
 	BoxPtr pbox;
 	int nbox;
-
-	if (!miComputeCompositeRegion (&region, pSrc, NULL, pDst,
-				       xSrc, ySrc, 0, 0, xDst, yDst,
+	
+	if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
+				       xSrc, ySrc, xMask, yMask, xDst, yDst,
 				       rects->width, rects->height))
 	    goto next_rect;
 
@@ -413,6 +434,8 @@ exaTryDriverCompositeRects(CARD8	       op,
 	nbox = REGION_NUM_RECTS(&region);
 	pbox = REGION_RECTS(&region);
 
+	xMask = xMask + mask_off_x - xDst - dst_off_x;
+	yMask = yMask + mask_off_y - yDst - dst_off_y;
 	xSrc = xSrc + src_off_x - xDst - dst_off_x;
 	ySrc = ySrc + src_off_y - yDst - dst_off_y;
 
@@ -421,7 +444,8 @@ exaTryDriverCompositeRects(CARD8	       op,
 	    (*pExaScr->info->Composite) (pDstPix,
 					 pbox->x1 + xSrc,
 					 pbox->y1 + ySrc,
-					 0, 0,
+					 pbox->x1 + xMask,
+					 pbox->y1 + yMask,
 					 pbox->x1,
 					 pbox->y1,
 					 pbox->x2 - pbox->x1,
@@ -443,25 +467,30 @@ exaTryDriverCompositeRects(CARD8	       op,
 
 /**
  * Copy a number of rectangles from source to destination in a single
- * operation. This is specialized for building a glyph mask: we don'y
- * have a mask argument because we don't need it for that, and we
- * don't have he special-case fallbacks found in exaComposite() - if the
- * driver can support it, we use the driver functionality, otherwise we
- * fallback straight to software.
+ * operation. This is specialized for glyph rendering: we don't have the
+ * special-case fallbacks found in exaComposite() - if the driver can support
+ * it, we use the driver functionality, otherwise we fall back straight to
+ * software.
  */
 void
 exaCompositeRects(CARD8	              op,
 		  PicturePtr	      pSrc,
+		  PicturePtr	      pMask,
 		  PicturePtr	      pDst,
 		  int                 nrect,
 		  ExaCompositeRectPtr rects)
 {
+    ExaScreenPriv (pDst->pDrawable->pScreen);
     PixmapPtr pPixmap = exaGetDrawablePixmap(pDst->pDrawable);
     ExaPixmapPriv(pPixmap);
     int n;
     ExaCompositeRectPtr r;
-    
-    if (pExaPixmap->pDamage) {
+    int ret;
+
+    /* If we get a mask, that means we're rendering to the exaGlyphs
+     * destination directly, so the damage layer takes care of this.
+     */
+    if (!pMask && pExaPixmap->pDamage) {
 	RegionRec region;
 	int x1 = MAXSHORT;
 	int y1 = MAXSHORT;
@@ -518,24 +547,44 @@ exaCompositeRects(CARD8	              op,
     /************************************************************/
     
     ValidatePicture (pSrc);
+    if (pMask)
+	ValidatePicture (pMask);
     ValidatePicture (pDst);
-    
-    if (exaTryDriverCompositeRects(op, pSrc, pDst, nrect, rects) != 1) {
-	n = nrect;
-	r = rects;
-	while (n--) {
-	    ExaCheckComposite (op, pSrc, NULL, pDst,
-			       r->xSrc, r->ySrc,
-			       0, 0,
-			       r->xDst, r->yDst,
-			       r->width, r->height);
-	    r++;
+
+    ret = exaTryDriverCompositeRects(op, pSrc, pMask, pDst, nrect, rects);
+
+    if (ret != 1) {
+	if (ret == -1 && op == PictOpOver && pMask && pMask->componentAlpha &&
+	    (!pExaScr->info->CheckComposite ||
+	     ((*pExaScr->info->CheckComposite)(PictOpOutReverse, pSrc, pMask,
+					       pDst) &&
+	      (*pExaScr->info->CheckComposite)(PictOpAdd, pSrc, pMask, pDst)))) {
+	    ret = exaTryDriverCompositeRects(PictOpOutReverse, pSrc, pMask,
+					     pDst, nrect, rects);
+	    if (ret == 1) {
+		op = PictOpAdd;
+		ret = exaTryDriverCompositeRects(op, pSrc, pMask, pDst, nrect,
+						 rects);
+	    }
+	}
+
+	if (ret != 1) {
+	    n = nrect;
+	    r = rects;
+	    while (n--) {
+		ExaCheckComposite (op, pSrc, pMask, pDst,
+				   r->xSrc, r->ySrc,
+				   r->xMask, r->yMask,
+				   r->xDst, r->yDst,
+				   r->width, r->height);
+		r++;
+	    }
 	}
     }
     
     /************************************************************/
 
-    if (pExaPixmap->pDamage) {
+    if (!pMask && pExaPixmap->pDamage) {
 	/* Now we have to flush the damage out from pendingDamage => damage 
 	 * Calling DamageRegionProcessPending has that effect.
 	 */
commit b26c136ee9bf7015c583136af53d0c9e9da67ace
Author: Michel Dänzer <daenzer at vmware.com>
Date:   Thu Feb 26 10:35:44 2009 +0100

    EXA: Stop tracking damage for pixmaps subject to ModifyPixmapHeader.
    
    Signed-off-by: Michel Dänzer <daenzer at vmware.com>

diff --git a/exa/exa.c b/exa/exa.c
index 9329f10..a647699 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -431,6 +431,15 @@ exaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
             exaSetAccelBlock(pExaScr, pExaPixmap,
                              width, height, bitsPerPixel);
         }
+
+	/* Pixmaps subject to ModifyPixmapHeader will be pinned to system or
+	 * offscreen memory, so there's no need to track damage.
+	 */
+	if (pExaPixmap->pDamage) {
+	    DamageUnregister(&pPixmap->drawable, pExaPixmap->pDamage);
+	    DamageDestroy(pExaPixmap->pDamage);
+	    pExaPixmap->pDamage = NULL;
+	}
     }
 
 


More information about the xorg-commit mailing list