]> git.pld-linux.org Git - packages/xorg-xserver-server.git/blobdiff - xorg-xserver-server-exa.patch
- up to 1.6.1
[packages/xorg-xserver-server.git] / xorg-xserver-server-exa.patch
index bf4a503b378db2db34cbc6b619e890df0dd29da0..b41cd5b607d2da0b36f3667d4f6c6030c0e592f2 100644 (file)
---- xorg-server-1.4.orig/debian/patches/08_exa_fix_exaFillRegionTiled_fallback.diff
-+++ xorg-server-1.4/debian/patches/08_exa_fix_exaFillRegionTiled_fallback.diff
-@@ -0,0 +1,20 @@
-+commit aa11204d4a81de851155ae3f01d4c897263fd7b0
-+Author: Michel Dänzer <michel@tungstengraphics.com>
-+Date:   Tue Sep 25 19:51:29 2007 +0200
-+
-+    EXA: Punt on fallback case not handled correctly in exaFillRegionTiled.
-+
-+diff --git a/exa/exa_accel.c b/exa/exa_accel.c
-+index cc383cc..acc5dbe 100644
-+--- a/exa/exa_accel.c
-++++ b/exa/exa_accel.c
-+@@ -1223,7 +1223,8 @@ exaFillRegionTiled (DrawablePtr pDrawable,
-+     }
-+ 
-+ fallback:
-+-    if (alu != GXcopy || planemask != FB_ALLONES)
-++    if (alu != GXcopy || planemask != FB_ALLONES || pPatOrg->x != 0 ||
-++     pPatOrg->y != 0)
-+      return FALSE;
-+     EXA_FALLBACK(("from %p to %p (%c,%c)\n", pTile, pDrawable,
-+                exaDrawableLocation(&pTile->drawable),
---- xorg-server-1.4.orig/debian/patches/11_exa_no_negative_tile_offsets.diff
-+++ xorg-server-1.4/debian/patches/11_exa_no_negative_tile_offsets.diff
-@@ -0,0 +1,32 @@
-+commit e1ac9c0e7a6167f14cb7899e585eeae74bb5d55d
-+Author: Michel Dänzer <michel@tungstengraphics.com>
-+Date:   Thu Sep 27 13:08:41 2007 +0200
-+
-+    EXA: Make sure tile offsets passed to drivers are never negative.
-+    
-+    Thanks to Björn Steinbrink for pointing out the problem on IRC.
-+
-+diff --git a/exa/exa_accel.c b/exa/exa_accel.c
-+index cc383cc..d19e3f4 100644
-+--- a/exa/exa_accel.c
-++++ b/exa/exa_accel.c
-+@@ -1187,7 +1187,8 @@ exaFillRegionTiled (DrawablePtr pDrawable,
-+          int dstY = pBox->y1;
-+          int tileY;
-+ 
-+-         tileY = (dstY - pDrawable->y - pPatOrg->y) % tileHeight;
-++         modulus(dstY - pDrawable->y - pPatOrg->y, tileHeight, tileY);
-++
-+          while (height > 0) {
-+              int width = pBox->x2 - pBox->x1;
-+              int dstX = pBox->x1;
-+@@ -1198,7 +1199,8 @@ exaFillRegionTiled (DrawablePtr pDrawable,
-+                  h = height;
-+              height -= h;
-+ 
-+-             tileX = (dstX - pDrawable->x - pPatOrg->x) % tileWidth;
-++             modulus(dstX - pDrawable->x - pPatOrg->x, tileWidth, tileX);
-++
-+              while (width > 0) {
-+                  int w = tileWidth - tileX;
-+                  if (w > width)
+--- 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, &region);
+       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 (&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 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;
+                   }
This page took 0.077767 seconds and 4 git commands to generate.