---- xorg/exa/exa_render.c~ 2009-02-25 20:12:11.000000000 +0100
-+++ xorg/exa/exa_render.c 2009-02-28 18:09:52.562970685 +0100
-@@ -342,7 +342,6 @@
- int src_off_x, src_off_y, dst_off_x, dst_off_y;
- PixmapPtr pSrcPix, pDstPix;
- ExaPixmapPrivPtr pSrcExaPix, pDstExaPix;
-- struct _Pixmap scratch;
- ExaMigrationRec pixmaps[2];
-
- if (!pExaScr->info->PrepareComposite)
-@@ -386,13 +385,6 @@
- if (!exaPixmapIsOffscreen(pDstPix))
- return 0;
-
-- if (!pSrcPix && pExaScr->info->UploadToScratch)
-- {
-- pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable);
-- if ((*pExaScr->info->UploadToScratch) (pSrcPix, &scratch))
-- pSrcPix = &scratch;
-- }
--
- if (!pSrcPix)
- return 0;
-
-@@ -573,7 +565,6 @@
- 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;
-- struct _Pixmap scratch;
- ExaMigrationRec pixmaps[3];
-
- pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
-@@ -652,16 +643,6 @@
- return 0;
- }
-
-- if (!pSrcPix && (!pMask || pMaskPix) && pExaScr->info->UploadToScratch) {
-- pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable);
-- if ((*pExaScr->info->UploadToScratch) (pSrcPix, &scratch))
-- pSrcPix = &scratch;
-- } else if (pSrcPix && pMask && !pMaskPix && pExaScr->info->UploadToScratch) {
-- pMaskPix = exaGetDrawablePixmap (pMask->pDrawable);
-- if ((*pExaScr->info->UploadToScratch) (pMaskPix, &scratch))
-- pMaskPix = &scratch;
-- }
--
- if (!pSrcPix || (pMask && !pMaskPix)) {
- REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
- return 0;
-commit f07f18231a921d3ae9dd9b75881c9e58e9e2e235
-Author: Michel Dänzer <daenzer@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@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 (®ion, pSrc, NULL, pDst,
-- xSrc, ySrc, 0, 0, xDst, yDst,
-+
-+ if (!miComputeCompositeRegion (®ion, 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(®ion);
- pbox = REGION_RECTS(®ion);
-
-+ 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 265d20068af5434489752b6dba0bf0065b3cc3ec
-Author: Michel Dänzer <daenzer@vmware.com>
-Date: Fri Feb 27 16:41:39 2009 +0100
-
- EXA: Fix check for whether the glyph we're evicting from the cache is in use.
-
- Since commit f07f18231a921d3ae9dd9b75881c9e58e9e2e235 ('EXA: Allow using
- exaCompositeRects also when we can't use a mask in exaGlyphs.') we were
- checking the wrong set of coordinates in the buffer where glyphs to be rendered
- are accumulated when no mask is used in exaGlyphs.
-
- This fixes occasional glyph corruption which can be corrected with redraws, in
- particular with Qt4.
-
- Thanks to Maarten Maathuis for asking the right question: 'where do we protect
- against evicting glyphs that are still needed?'
-
- Signed-off-by: Michel Dänzer <daenzer@vmware.com>
-
-diff --git a/exa/exa_glyphs.c b/exa/exa_glyphs.c
-index 918fd85..d55839c 100644
---- a/exa/exa_glyphs.c
-+++ b/exa/exa_glyphs.c
-@@ -469,7 +469,9 @@ exaGlyphCacheBufferGlyph(ScreenPtr pScreen,
- y = CACHE_Y(pos);
-
- for (i = 0; i < buffer->count; i++) {
-- if (buffer->rects[i].xSrc == x && buffer->rects[i].ySrc == y) {
-+ if (pSrc ?
-+ (buffer->rects[i].xMask == x && buffer->rects[i].yMask == y) :
-+ (buffer->rects[i].xSrc == x && buffer->rects[i].ySrc == y)) {
- DBG_GLYPH_CACHE((" must flush buffer\n"));
- return ExaGlyphNeedFlush;
- }