xserver: Branch 'master' - 15 commits
Michel Daenzer
daenzer at kemper.freedesktop.org
Mon Apr 30 00:51:56 EEST 2007
exa/exa.c | 25 --
exa/exa_accel.c | 465 ++++++++++++++++++++++++++++------------------------
exa/exa_migration.c | 21 --
exa/exa_offscreen.c | 8
exa/exa_priv.h | 8
exa/exa_render.c | 174 +++++++++++++------
exa/exa_unaccel.c | 36 +---
7 files changed, 414 insertions(+), 323 deletions(-)
New commits:
diff-tree 3c91a993e8c752002adf85c317216e1487c20780 (from a261e1325057974d58440812b93c00c0caa4423a)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Sun Apr 29 23:49:41 2007 +0200
EXA: Fix OffscreenValidate build with DEBUG_OFFSCREEN enabled.
diff --git a/exa/exa_offscreen.c b/exa/exa_offscreen.c
index 38ad58f..6fe646a 100644
--- a/exa/exa_offscreen.c
+++ b/exa/exa_offscreen.c
@@ -54,7 +54,7 @@ ExaOffscreenValidate (ScreenPtr pScreen)
assert (area->offset >= area->base_offset &&
area->offset < (area->base_offset + area->size));
if (prev)
- assert (prev->base_offset + prev->area.size == area->base_offset);
+ assert (prev->base_offset + prev->size == area->base_offset);
prev = area;
}
assert (prev->base_offset + prev->size == pExaScr->info->memorySize);
diff-tree a261e1325057974d58440812b93c00c0caa4423a (from b1b6674a919943a8ac37e54d02e8d0d23a642b1d)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Sun Apr 29 23:49:35 2007 +0200
EXA: Remove DrawableDirty.
Convert the remaining callers to PixmapDirty.
diff --git a/exa/exa.c b/exa/exa.c
index 3d77800..c5b5a66 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -172,29 +172,6 @@ exaPixmapDirty (PixmapPtr pPix, int x1,
REGION_UNINIT(pScreen, ®ion);
}
-/**
- * exaDrawableDirty() marks a pixmap backing a drawable as dirty, allowing for
- * optimizations in pixmap migration when no changes have occurred.
- */
-void
-exaDrawableDirty (DrawablePtr pDrawable, int x1, int y1, int x2, int y2)
-{
- PixmapPtr pPix = exaGetDrawablePixmap(pDrawable);
- int xoff, yoff;
-
- x1 = max(x1, pDrawable->x);
- y1 = max(y1, pDrawable->y);
- x2 = min(x2, pDrawable->x + pDrawable->width);
- y2 = min(y2, pDrawable->y + pDrawable->height);
-
- if (x1 >= x2 || y1 >= y2)
- return;
-
- exaGetDrawableDeltas(pDrawable, pPix, &xoff, &yoff);
-
- exaPixmapDirty(pPix, x1 + xoff, y1 + yoff, x2 + xoff, y2 + yoff);
-}
-
static Bool
exaDestroyPixmap (PixmapPtr pPixmap)
{
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index b976082..ece5898 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -351,9 +351,6 @@ void
exaGetDrawableDeltas (DrawablePtr pDrawable, PixmapPtr pPixmap,
int *xp, int *yp);
-void
-exaDrawableDirty(DrawablePtr pDrawable, int x1, int y1, int x2, int y2);
-
Bool
exaDrawableIsOffscreen (DrawablePtr pDrawable);
diff --git a/exa/exa_render.c b/exa/exa_render.c
index 06881e3..5e7c67f 100644
--- a/exa/exa_render.c
+++ b/exa/exa_render.c
@@ -764,6 +764,7 @@ exaRasterizeTrapezoid (PicturePtr pPictu
{
DrawablePtr pDraw = pPicture->pDrawable;
ExaMigrationRec pixmaps[1];
+ int xoff, yoff;
pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = TRUE;
@@ -772,8 +773,10 @@ exaRasterizeTrapezoid (PicturePtr pPictu
exaPrepareAccess(pDraw, EXA_PREPARE_DEST);
fbRasterizeTrapezoid(pPicture, trap, x_off, y_off);
- exaDrawableDirty(pDraw, pDraw->x, pDraw->y,
- pDraw->x + pDraw->width, pDraw->y + pDraw->height);
+ exaGetDrawableDeltas(pDraw, pixmaps[0].pPix, &xoff, &yoff);
+ exaPixmapDirty(pixmaps[0].pPix, pDraw->x + xoff, pDraw->y + yoff,
+ pDraw->x + xoff + pDraw->width,
+ pDraw->y + yoff + pDraw->height);
exaFinishAccess(pDraw, EXA_PREPARE_DEST);
}
@@ -787,6 +790,7 @@ exaAddTriangles (PicturePtr pPicture, IN
{
DrawablePtr pDraw = pPicture->pDrawable;
ExaMigrationRec pixmaps[1];
+ int xoff, yoff;
pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = TRUE;
@@ -795,8 +799,10 @@ exaAddTriangles (PicturePtr pPicture, IN
exaPrepareAccess(pDraw, EXA_PREPARE_DEST);
fbAddTriangles(pPicture, x_off, y_off, ntri, tris);
- exaDrawableDirty(pDraw, pDraw->x, pDraw->y,
- pDraw->x + pDraw->width, pDraw->y + pDraw->height);
+ exaGetDrawableDeltas(pDraw, pixmaps[0].pPix, &xoff, &yoff);
+ exaPixmapDirty(pixmaps[0].pPix, pDraw->x + xoff, pDraw->y + yoff,
+ pDraw->x + xoff + pDraw->width,
+ pDraw->y + yoff + pDraw->height);
exaFinishAccess(pDraw, EXA_PREPARE_DEST);
}
diff-tree b1b6674a919943a8ac37e54d02e8d0d23a642b1d (from 584697a2231ac782f362a925e1489c15483a8791)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Sun Apr 29 23:49:28 2007 +0200
EXA: FillSpans improvements.
* Don't need to track damage.
* Always migrate for fallbacks.
diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index 4aa2d63..bf63f2c 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -74,6 +74,7 @@ exaFillSpans(DrawablePtr pDrawable, GCPt
pGC->planemask,
pGC->fgPixel))
{
+ exaDoMigration (pixmaps, 1, FALSE);
ExaCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted);
return;
}
@@ -109,8 +110,6 @@ exaFillSpans(DrawablePtr pDrawable, GCPt
(*pExaScr->info->Solid) (pPixmap,
fullX1 + off_x, fullY1 + off_y,
fullX2 + off_x, fullY1 + 1 + off_y);
- exaPixmapDirty (pPixmap, fullX1 + off_x, fullY1 + off_y,
- fullX2 + off_x, fullY1 + 1 + off_y);
}
else
{
@@ -129,8 +128,6 @@ exaFillSpans(DrawablePtr pDrawable, GCPt
(*pExaScr->info->Solid) (pPixmap,
partX1 + off_x, fullY1 + off_y,
partX2 + off_x, fullY1 + 1 + off_y);
- exaPixmapDirty (pPixmap, partX1 + off_x, fullY1 + off_y,
- partX2 + off_x, fullY1 + 1 + off_y);
}
}
pbox++;
diff-tree 584697a2231ac782f362a925e1489c15483a8791 (from 982d7c2c0b948ba04c8eefa475d660981e6ed9f9)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Sun Apr 29 23:49:09 2007 +0200
EXA: SolidBoxClipped improvements.
* Centralize handling of fallbacks and damage tracking.
* Always migrate for fallbacks.
diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index 800c4f0..4aa2d63 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -826,20 +826,19 @@ exaSolidBoxClipped (DrawablePtr pDrawabl
pPixmap->drawable.width > pExaScr->info->maxX ||
pPixmap->drawable.height > pExaScr->info->maxY)
{
- exaDoMigration (pixmaps, 1, FALSE);
- goto fallback;
+ fallback = TRUE;
} else {
exaDoMigration (pixmaps, 1, TRUE);
}
- pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
+ exaGetDrawableDeltas (pDrawable, pPixmap, &xoff, &yoff);
- if (!pPixmap ||
+ if (fallback || !exaPixmapIsOffscreen(pPixmap) ||
!(*pExaScr->info->PrepareSolid) (pPixmap, GXcopy, pm, fg))
{
-fallback:
EXA_FALLBACK(("to %p (%c)\n", pDrawable,
exaDrawableLocation(pDrawable)));
+ exaDoMigration (pixmaps, 1, FALSE);
fallback = TRUE;
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fg = fbReplicatePixel (fg, pDrawable->bitsPerPixel);
@@ -878,10 +877,10 @@ fallback:
(*pExaScr->info->Solid) (pPixmap,
partX1 + xoff, partY1 + yoff,
partX2 + xoff, partY2 + yoff);
- exaPixmapDirty (pPixmap, partX1 + xoff, partY1 + yoff,
- partX2 + xoff, partY2 + yoff);
- } else
- exaDrawableDirty (pDrawable, partX1, partY1, partX2, partY2);
+ }
+
+ exaPixmapDirty (pPixmap, partX1 + xoff, partY1 + yoff, partX2 + xoff,
+ partY2 + yoff);
}
if (fallback)
diff-tree 982d7c2c0b948ba04c8eefa475d660981e6ed9f9 (from d2245386eed200e77a8c84bdda36ab29e39fd593)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Sun Apr 29 23:48:59 2007 +0200
EXA: CopyNtoN improvements.
* Centralize handling of fallbacks and damage tracking.
* Always migrate for fallbacks.
diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index 6a0fbb7..800c4f0 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -390,6 +390,7 @@ exaCopyNtoN (DrawablePtr pSrcDrawable
int src_off_x, src_off_y;
int dst_off_x, dst_off_y;
ExaMigrationRec pixmaps[2];
+ Bool fallback = FALSE;
pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = FALSE;
@@ -407,62 +408,64 @@ exaCopyNtoN (DrawablePtr pSrcDrawable
pDstPixmap->drawable.width > pExaScr->info->maxX ||
pDstPixmap->drawable.height > pExaScr->info->maxY)
{
- exaDoMigration (pixmaps, 2, FALSE);
- goto fallback;
+ fallback = TRUE;
} else {
exaDoMigration (pixmaps, 2, TRUE);
}
/* Mixed directions must be handled specially if the card is lame */
- if (pExaScr->info->flags & EXA_TWO_BITBLT_DIRECTIONS &&
+ if (!fallback && (pExaScr->info->flags & EXA_TWO_BITBLT_DIRECTIONS) &&
reverse != upsidedown) {
- if (!exaCopyNtoNTwoDir(pSrcDrawable, pDstDrawable, pGC, pbox, nbox,
+ if (exaCopyNtoNTwoDir(pSrcDrawable, pDstDrawable, pGC, pbox, nbox,
dx, dy))
- goto fallback;
- return;
+ return;
+ fallback = TRUE;
}
- if ((pSrcPixmap = exaGetOffscreenPixmap (pSrcDrawable, &src_off_x, &src_off_y)) &&
- (pDstPixmap = exaGetOffscreenPixmap (pDstDrawable, &dst_off_x, &dst_off_y)) &&
- (*pExaScr->info->PrepareCopy) (pSrcPixmap, pDstPixmap,
- reverse ? -1 : 1, upsidedown ? -1 : 1,
- pGC ? pGC->alu : GXcopy,
- pGC ? pGC->planemask : FB_ALLONES))
+ pSrcPixmap = exaGetDrawablePixmap (pSrcDrawable);
+ pDstPixmap = exaGetDrawablePixmap (pDstDrawable);
+
+ exaGetDrawableDeltas (pSrcDrawable, pSrcPixmap, &src_off_x, &src_off_y);
+ exaGetDrawableDeltas (pDstDrawable, pDstPixmap, &dst_off_x, &dst_off_y);
+
+ if (fallback || !exaPixmapIsOffscreen(pSrcPixmap) ||
+ !exaPixmapIsOffscreen(pDstPixmap) ||
+ !(*pExaScr->info->PrepareCopy) (pSrcPixmap, pDstPixmap, reverse ? -1 : 1,
+ upsidedown ? -1 : 1,
+ pGC ? pGC->alu : GXcopy,
+ pGC ? pGC->planemask : FB_ALLONES)) {
+ fallback = TRUE;
+ EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrcDrawable, pDstDrawable,
+ exaDrawableLocation(pSrcDrawable),
+ exaDrawableLocation(pDstDrawable)));
+ exaDoMigration (pixmaps, 2, FALSE);
+ exaPrepareAccess (pDstDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccess (pSrcDrawable, EXA_PREPARE_SRC);
+ fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
+ pbox, nbox, dx, dy, reverse, upsidedown,
+ bitplane, closure);
+ exaFinishAccess (pSrcDrawable, EXA_PREPARE_SRC);
+ exaFinishAccess (pDstDrawable, EXA_PREPARE_DEST);
+ }
+
+ while (nbox--)
{
- while (nbox--)
- {
+ if (!fallback)
(*pExaScr->info->Copy) (pDstPixmap,
pbox->x1 + dx + src_off_x,
pbox->y1 + dy + src_off_y,
pbox->x1 + dst_off_x, pbox->y1 + dst_off_y,
- pbox->x2 - pbox->x1,
- pbox->y2 - pbox->y1);
- exaPixmapDirty (pDstPixmap,
- pbox->x1 + dst_off_x, pbox->y1 + dst_off_y,
- pbox->x2 + dst_off_x, pbox->y2 + dst_off_y);
- pbox++;
- }
- (*pExaScr->info->DoneCopy) (pDstPixmap);
- exaMarkSync(pDstDrawable->pScreen);
- return;
- }
-
-fallback:
- EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrcDrawable, pDstDrawable,
- exaDrawableLocation(pSrcDrawable),
- exaDrawableLocation(pDstDrawable)));
- exaPrepareAccess (pDstDrawable, EXA_PREPARE_DEST);
- exaPrepareAccess (pSrcDrawable, EXA_PREPARE_SRC);
- fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
- pbox, nbox, dx, dy, reverse, upsidedown,
- bitplane, closure);
- exaFinishAccess (pSrcDrawable, EXA_PREPARE_SRC);
- exaFinishAccess (pDstDrawable, EXA_PREPARE_DEST);
- while (nbox--)
- {
- exaDrawableDirty (pDstDrawable, pbox->x1, pbox->y1, pbox->x2, pbox->y2);
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
+ exaPixmapDirty (pDstPixmap, pbox->x1 + dst_off_x, pbox->y1 + dst_off_y,
+ pbox->x2 + dst_off_x, pbox->y2 + dst_off_y);
pbox++;
}
+
+ if (fallback)
+ return;
+
+ (*pExaScr->info->DoneCopy) (pDstPixmap);
+ exaMarkSync (pDstDrawable->pScreen);
}
RegionPtr
diff-tree d2245386eed200e77a8c84bdda36ab29e39fd593 (from 0880aaac9c83019fec2e3d32871f74c7a407f8b3)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Sun Apr 29 23:48:31 2007 +0200
EXA: GetImage improvements.
Only migrate when appropriate. In particular, don't migrate to offscreen in the
no-fallback case as copying from system memory should usually be as fast if not
faster than DownloadFromScreen, in particular if the bits need to be uploaded
to offscreen first.
diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index dd02fef..6a0fbb7 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -1330,27 +1330,22 @@ exaGetImage (DrawablePtr pDrawable, int
int xoff, yoff;
Bool ok;
- if (pExaScr->swappedOut || pExaScr->info->DownloadFromScreen == NULL)
- goto fallback;
+ if (pExaScr->info->DownloadFromScreen == NULL)
+ goto migrate_and_fallback;
/* Only cover the ZPixmap, solid copy case. */
if (format != ZPixmap || !EXA_PM_IS_SOLID(pDrawable, planeMask))
- goto fallback;
+ goto migrate_and_fallback;
/* Only try to handle the 8bpp and up cases, since we don't want to think
* about <8bpp.
*/
if (pDrawable->bitsPerPixel < 8)
+ goto migrate_and_fallback;
+
+ if (pExaScr->swappedOut)
goto fallback;
- /* Migrate, but assume that we could accelerate the download. It is up to
- * the migration scheme to ensure that this case doesn't result in bad
- * moving of pixmaps.
- */
- pixmaps[0].as_dst = FALSE;
- pixmaps[0].as_src = TRUE;
- pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable);
- exaDoMigration (pixmaps, 1, TRUE);
pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
if (pPix == NULL)
goto fallback;
@@ -1365,12 +1360,12 @@ exaGetImage (DrawablePtr pDrawable, int
return;
}
-fallback:
+migrate_and_fallback:
pixmaps[0].as_dst = FALSE;
pixmaps[0].as_src = TRUE;
pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable);
exaDoMigration (pixmaps, 1, FALSE);
-
+fallback:
ExaCheckGetImage (pDrawable, x, y, w, h, format, planeMask, d);
}
diff-tree 0880aaac9c83019fec2e3d32871f74c7a407f8b3 (from 7fca16901187ade48e83e6a2684ef464b1912357)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Sun Apr 29 23:48:19 2007 +0200
EXA: PutImage improvements.
* Migrate for fallbacks when appropriate.
* Add damage tracking in ExaCheckPutImage.
diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index fc1f3d7..dd02fef 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -154,8 +154,9 @@ exaPutImage (DrawablePtr pDrawable, GCPt
int xoff, yoff;
int src_stride, bpp = pDrawable->bitsPerPixel;
- if (pExaScr->swappedOut || pExaScr->info->UploadToScreen == NULL)
- goto migrate_and_fallback;
+ pixmaps[0].as_dst = TRUE;
+ pixmaps[0].as_src = FALSE;
+ pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable);
/* Don't bother with under 8bpp, XYPixmaps. */
if (format != ZPixmap || bpp < 8)
@@ -165,10 +166,14 @@ exaPutImage (DrawablePtr pDrawable, GCPt
if (!EXA_PM_IS_SOLID(pDrawable, pGC->planemask) || pGC->alu != GXcopy)
goto migrate_and_fallback;
- pixmaps[0].as_dst = TRUE;
- pixmaps[0].as_src = FALSE;
- pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable);
+ if (pExaScr->swappedOut)
+ goto fallback;
+
exaDoMigration (pixmaps, 1, TRUE);
+
+ if (pExaScr->info->UploadToScreen == NULL)
+ goto fallback;
+
pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
if (pPix == NULL)
@@ -221,25 +226,23 @@ exaPutImage (DrawablePtr pDrawable, GCPt
fbBltStip((FbStip *)bits + (y1 - y) * (src_stride / sizeof(FbStip)),
src_stride / sizeof(FbStip),
- (x1 - x) * bpp,
- dst + (y1 + yoff) * dst_stride,
+ (x1 - x) * dstBpp,
+ dst + (y1 + dstYoff) * dst_stride,
dst_stride,
- (x1 + xoff) * bpp,
- (x2 - x1) * bpp,
+ (x1 + dstXoff) * dstBpp,
+ (x2 - x1) * dstBpp,
y2 - y1,
- GXcopy, FB_ALLONES, bpp);
+ GXcopy, FB_ALLONES, dstBpp);
exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
}
+
exaPixmapDirty(pPix, x1 + xoff, y1 + yoff, x2 + xoff, y2 + yoff);
}
return;
migrate_and_fallback:
- pixmaps[0].as_dst = TRUE;
- pixmaps[0].as_src = FALSE;
- pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable);
exaDoMigration (pixmaps, 1, FALSE);
fallback:
diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c
index a7f9398..708d1ea 100644
--- a/exa/exa_unaccel.c
+++ b/exa/exa_unaccel.c
@@ -88,10 +88,15 @@ ExaCheckPutImage (DrawablePtr pDrawable,
int x, int y, int w, int h, int leftPad, int format,
char *bits)
{
+ PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
+ int xoff, yoff;
+
EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
+ exaPixmapDirty(pPixmap, x + xoff, y + yoff, x + xoff + w, y + yoff + h);
}
RegionPtr
diff-tree 7fca16901187ade48e83e6a2684ef464b1912357 (from a8d6ebdf9338dc2f6ff9a532e6fec460a70d3b1e)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Sun Apr 29 23:48:11 2007 +0200
EXA: ImageGlyphBlt improvements.
* Don't waste effort on invisible glyphs.
* Only track damage for bounding box instead of each glyph separately.
* Always migrate for fallbacks.
diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index 721882b..fc1f3d7 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -915,12 +915,36 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
int dstBpp;
int dstXoff, dstYoff;
FbBits depthMask;
+ PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
+ ExaMigrationRec pixmaps[1];
+ int xBack, widthBack, yBack, heightBack;
+
+ for (ppci = ppciInit, n = nglyph, widthBack = 0; n; n--)
+ widthBack += (*ppci++)->metrics.characterWidth;
+
+ xBack = x;
+ if (widthBack < 0)
+ {
+ xBack += widthBack;
+ widthBack = -widthBack;
+ }
+ yBack = y - FONTASCENT(pGC->font);
+ heightBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
+
+ if (xBack >= pDrawable->width || yBack >= pDrawable->height ||
+ (xBack + widthBack) <= 0 || (yBack + heightBack) <= 0)
+ return;
+
+ pixmaps[0].as_dst = TRUE;
+ pixmaps[0].as_src = TRUE;
+ pixmaps[0].pPix = pPixmap;
depthMask = FbFullMask(pDrawable->depth);
if ((pGC->planemask & depthMask) != depthMask)
{
+ exaDoMigration(pixmaps, 1, FALSE);
ExaCheckImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppciInit, pglyphBase);
- return;
+ goto damage;
}
glyph = NULL;
switch (pDrawable->bitsPerPixel) {
@@ -932,6 +956,8 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
x += pDrawable->x;
y += pDrawable->y;
+ xBack += pDrawable->x;
+ yBack += pDrawable->y;
if (TERMINALFONT (pGC->font) && !glyph)
{
@@ -939,23 +965,6 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
}
else
{
- int xBack, widthBack;
- int yBack, heightBack;
-
- ppci = ppciInit;
- n = nglyph;
- widthBack = 0;
- while (n--)
- widthBack += (*ppci++)->metrics.characterWidth;
-
- xBack = x;
- if (widthBack < 0)
- {
- xBack += widthBack;
- widthBack = -widthBack;
- }
- yBack = y - FONTASCENT(pGC->font);
- heightBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
exaSolidBoxClipped (pDrawable,
fbGetCompositeClip(pGC),
pGC->planemask,
@@ -968,74 +977,50 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
}
EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
+ exaDoMigration(pixmaps, 1, FALSE);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
exaPrepareAccessGC (pGC);
fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
- ppci = ppciInit;
- while (nglyph--)
+ for (ppci = ppciInit; nglyph; nglyph--, x += pci->metrics.characterWidth)
{
pci = *ppci++;
- pglyph = FONTGLYPHBITS(pglyphBase, pci);
gWidth = GLYPHWIDTHPIXELS(pci);
gHeight = GLYPHHEIGHTPIXELS(pci);
- if (gWidth && gHeight)
- {
- gx = x + pci->metrics.leftSideBearing;
- gy = y - pci->metrics.ascent;
- if (glyph && gWidth <= sizeof (FbStip) * 8 &&
- fbGlyphIn (fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight))
- {
- (*glyph) (dst + (gy + dstYoff) * dstStride,
- dstStride,
- dstBpp,
- (FbStip *) pglyph,
- pPriv->fg,
- gx + dstXoff,
- gHeight);
- exaDrawableDirty (pDrawable, gx, gy, gx + gWidth, gy + gHeight);
- }
- else
- {
- RegionPtr pClip = fbGetCompositeClip(pGC);
- int nbox;
- BoxPtr pbox;
-
- gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof (FbStip);
- fbPutXYImage (pDrawable,
- pClip,
- pPriv->fg,
- pPriv->bg,
- pPriv->pm,
- GXcopy,
- opaque,
-
- gx,
- gy,
- gWidth, gHeight,
-
- (FbStip *) pglyph,
- gStride,
- 0);
-
- for (nbox = REGION_NUM_RECTS(pClip), pbox = REGION_RECTS(pClip);
- nbox--; pbox++) {
- int x1 = max(gx, pbox->x1), x2 = min(gx + gWidth, pbox->x2);
- int y1 = max(gy, pbox->y1), y2 = min(gy + gHeight, pbox->y2);
+ gx = x + pci->metrics.leftSideBearing;
+ gy = y - pci->metrics.ascent;
- if (x1 >= x2 || y1 >= y2)
- continue;
+ if (!gWidth || !gHeight || (gx + gWidth) <= xBack ||
+ (gy + gHeight) <= yBack || gx >= (xBack + widthBack) ||
+ gy >= (yBack + heightBack))
+ continue;
- exaDrawableDirty (pDrawable, gx, gy, gx + gWidth,
- gy + gHeight);
- }
- }
+ pglyph = FONTGLYPHBITS(pglyphBase, pci);
+
+ if (glyph && gWidth <= sizeof (FbStip) * 8 &&
+ fbGlyphIn (fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight))
+ {
+ (*glyph) (dst + (gy + dstYoff) * dstStride, dstStride, dstBpp,
+ (FbStip *) pglyph, pPriv->fg, gx + dstXoff, gHeight);
+ }
+ else
+ {
+ RegionPtr pClip = fbGetCompositeClip(pGC);
+
+ gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof (FbStip);
+ fbPutXYImage (pDrawable, pClip, pPriv->fg, pPriv->bg, pPriv->pm,
+ GXcopy, opaque, gx, gy, gWidth, gHeight,
+ (FbStip *) pglyph, gStride, 0);
}
- x += pci->metrics.characterWidth;
}
exaFinishAccessGC (pGC);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+
+damage:
+ exaGetDrawableDeltas(pDrawable, pPixmap, &dstXoff, &dstYoff);
+ exaPixmapDirty(pPixmap, xBack + dstXoff, yBack + dstYoff,
+ xBack + dstXoff + widthBack, yBack + dstYoff + heightBack);
}
const GCOps exaOps = {
diff-tree a8d6ebdf9338dc2f6ff9a532e6fec460a70d3b1e (from 81b055605c34b5823f6c5f63cc0f92f43c6b7252)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Sun Apr 29 23:47:53 2007 +0200
EXA: Defer to FillRegionTiled in Composite when possible.
Committed separately as this case is hard to hit and has only been tested
lightly.
diff --git a/exa/exa_render.c b/exa/exa_render.c
index 63a412c..06881e3 100644
--- a/exa/exa_render.c
+++ b/exa/exa_render.c
@@ -651,6 +651,45 @@ exaComposite(CARD8 op,
REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
goto done;
}
+ else if (pSrcPixmap && !pSrc->transform &&
+ pSrc->repeatType == RepeatNormal)
+ {
+ RegionRec region;
+ DDXPointRec srcOrg;
+
+ /* Let's see if the driver can do the repeat in one go */
+ if (pExaScr->info->PrepareComposite && !pSrc->alphaMap &&
+ !pDst->alphaMap)
+ {
+ ret = exaTryDriverComposite(op, pSrc, pMask, pDst, xSrc,
+ ySrc, xMask, yMask, xDst, yDst,
+ width, height);
+ if (ret == 1)
+ goto done;
+ }
+
+ /* Now see if we can use exaFillRegionTiled() */
+ 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))
+ goto done;
+
+ srcOrg.x = (xSrc - xDst) % pSrcPixmap->drawable.width;
+ srcOrg.y = (ySrc - yDst) % pSrcPixmap->drawable.height;
+
+ ret = exaFillRegionTiled(pDst->pDrawable, ®ion, pSrcPixmap,
+ &srcOrg, FB_ALLONES, GXcopy);
+
+ REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
+
+ if (ret)
+ goto done;
+ }
}
}
diff-tree 81b055605c34b5823f6c5f63cc0f92f43c6b7252 (from ce317a5b76c053f449122c46e1372bf8e067cb4c)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Sun Apr 29 23:47:43 2007 +0200
EXA: Composite improvements.
* Defer to simpler hooks in more cases (inspired by XAA behaviour).
* Move damage tracking from lower to higher level functions.
* Always migrate for fallbacks.
diff --git a/exa/exa_render.c b/exa/exa_render.c
index 2234cdb..63a412c 100644
--- a/exa/exa_render.c
+++ b/exa/exa_render.c
@@ -297,15 +297,15 @@ exaTryDriverSolidFill(PicturePtr pSrc,
nbox = REGION_NUM_RECTS(®ion);
pbox = REGION_RECTS(®ion);
+
while (nbox--)
{
(*pExaScr->info->Solid) (pDstPix,
pbox->x1 + dst_off_x, pbox->y1 + dst_off_y,
pbox->x2 + dst_off_x, pbox->y2 + dst_off_y);
- exaPixmapDirty (pDstPix, pbox->x1 + dst_off_x, pbox->y1 + dst_off_y,
- pbox->x2 + dst_off_x, pbox->y2 + dst_off_y);
pbox++;
}
+
(*pExaScr->info->DoneSolid) (pDstPix);
exaMarkSync(pDst->pDrawable->pScreen);
@@ -446,8 +446,6 @@ exaTryDriverComposite(CARD8 op,
pbox->y1 + dst_off_y,
pbox->x2 - pbox->x1,
pbox->y2 - pbox->y1);
- exaPixmapDirty (pDstPix, pbox->x1 + dst_off_x, pbox->y1 + dst_off_y,
- pbox->x2 + dst_off_x, pbox->y2 + dst_off_y);
pbox++;
}
(*pExaScr->info->DoneComposite) (pDstPix);
@@ -521,6 +519,9 @@ exaTryMagicTwoPassCompositeHelper(CARD8
CARD16 height)
{
ExaScreenPriv (pDst->pDrawable->pScreen);
+ DrawablePtr pDstDraw = pDst->pDrawable;
+ PixmapPtr pDstPixmap = exaGetDrawablePixmap(pDstDraw);
+ int xoff, yoff;
assert(op == PictOpOver);
@@ -539,6 +540,12 @@ exaTryMagicTwoPassCompositeHelper(CARD8
exaComposite(PictOpOutReverse, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask,
xDst, yDst, width, height);
+ exaGetDrawableDeltas(pDstDraw, pDstPixmap, &xoff, &yoff);
+ xoff += pDstDraw->x;
+ yoff += pDstDraw->y;
+ exaPixmapDirty(pDstPixmap, xDst + xoff, yDst + yoff, xDst + xoff + width,
+ yDst + yoff + height);
+
/* Then, add in the source value times the destination alpha factors (1.0).
*/
exaComposite(PictOpAdd, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask,
@@ -565,6 +572,28 @@ exaComposite(CARD8 op,
int ret = -1;
Bool saveSrcRepeat = pSrc->repeat;
Bool saveMaskRepeat = pMask ? pMask->repeat : 0;
+ ExaMigrationRec pixmaps[3];
+ int npixmaps = 1;
+ PixmapPtr pSrcPixmap = NULL;
+
+ pixmaps[0].as_dst = TRUE;
+ pixmaps[0].as_src = exaOpReadsDestination(op);
+ pixmaps[0].pPix = exaGetDrawablePixmap (pDst->pDrawable);
+
+ if (pSrc->pDrawable) {
+ pSrcPixmap = exaGetDrawablePixmap (pSrc->pDrawable);
+ pixmaps[npixmaps].as_dst = FALSE;
+ pixmaps[npixmaps].as_src = TRUE;
+ pixmaps[npixmaps].pPix = pSrcPixmap;
+ npixmaps++;
+ }
+
+ if (pMask && pMask->pDrawable) {
+ pixmaps[npixmaps].as_dst = FALSE;
+ pixmaps[npixmaps].as_src = TRUE;
+ pixmaps[npixmaps].pPix = exaGetDrawablePixmap (pMask->pDrawable);
+ npixmaps++;
+ }
/* We currently don't support acceleration of gradients, or other pictures
* with a NULL pDrawable.
@@ -583,19 +612,24 @@ exaComposite(CARD8 op,
if (!pMask)
{
- if (op == PictOpSrc)
+ if ((op == PictOpSrc &&
+ ((pSrc->format == pDst->format) ||
+ (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)))
{
if (pSrc->pDrawable->width == 1 &&
- pSrc->pDrawable->height == 1 && pSrc->repeat &&
- pSrc->repeatType == RepeatNormal)
+ pSrc->pDrawable->height == 1 &&
+ pSrc->repeat)
{
ret = exaTryDriverSolidFill(pSrc, pDst, xSrc, ySrc, xDst, yDst,
width, height);
if (ret == 1)
goto done;
}
- else if (!pSrc->repeat && !pSrc->transform &&
- pSrc->format == pDst->format)
+ else if (pSrcPixmap && !pSrc->repeat && !pSrc->transform)
{
RegionRec region;
@@ -660,39 +694,14 @@ exaComposite(CARD8 op,
}
}
- if (ret != 0) {
- ExaMigrationRec pixmaps[3];
- /* failure to accelerate was not due to pixmaps being in the wrong
- * locations.
- */
- pixmaps[0].as_dst = TRUE;
- pixmaps[0].as_src = exaOpReadsDestination(op);
- pixmaps[0].pPix = exaGetDrawablePixmap (pDst->pDrawable);
- pixmaps[1].as_dst = FALSE;
- pixmaps[1].as_src = TRUE;
- pixmaps[1].pPix = exaGetDrawablePixmap (pSrc->pDrawable);
- if (pMask) {
- pixmaps[2].as_dst = FALSE;
- pixmaps[2].as_src = TRUE;
- pixmaps[2].pPix = exaGetDrawablePixmap (pMask->pDrawable);
- exaDoMigration(pixmaps, 3, FALSE);
- } else {
- exaDoMigration(pixmaps, 2, FALSE);
- }
- }
-
fallback:
#if DEBUG_TRACE_FALL
exaPrintCompositeFallback (op, pSrc, pMask, pDst);
#endif
+ exaDoMigration(pixmaps, npixmaps, FALSE);
ExaCheckComposite (op, pSrc, pMask, pDst, xSrc, ySrc,
xMask, yMask, xDst, yDst, width, height);
- exaDrawableDirty(pDst->pDrawable,
- pDst->pDrawable->x + xDst,
- pDst->pDrawable->y + yDst,
- pDst->pDrawable->x + xDst + width,
- pDst->pDrawable->y + yDst + height);
done:
pSrc->repeat = saveSrcRepeat;
diff-tree ce317a5b76c053f449122c46e1372bf8e067cb4c (from 0c8905ebc91cf654facef84ee52231a358deec5c)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Sun Apr 29 23:47:16 2007 +0200
EXA: Glyphs improvements.
* Don't waste effort on invisible glyphs.
* Add damage tracking where necessary.
* Always migrate for fallbacks.
diff --git a/exa/exa_render.c b/exa/exa_render.c
index d48a142..2234cdb 100644
--- a/exa/exa_render.c
+++ b/exa/exa_render.c
@@ -845,10 +845,11 @@ exaGlyphs (CARD8 op,
PixmapPtr pPixmap = NULL;
PicturePtr pPicture;
PixmapPtr pMaskPixmap = NULL;
+ PixmapPtr pDstPixmap = exaGetDrawablePixmap(pDst->pDrawable);
PicturePtr pMask;
ScreenPtr pScreen = pDst->pDrawable->pScreen;
int width = 0, height = 0;
- int x, y;
+ int x, y, x1, y1, xoff, yoff;
int xDst = list->xOff, yDst = list->yOff;
int n;
int error;
@@ -892,7 +893,12 @@ exaGlyphs (CARD8 op,
xRectangle rect;
miGlyphExtents (nlist, list, glyphs, &extents);
-
+
+ extents.x1 = max(extents.x1, 0);
+ extents.y1 = max(extents.y1, 0);
+ extents.x2 = min(extents.x2, pDst->pDrawable->width);
+ extents.y2 = min(extents.y2, pDst->pDrawable->height);
+
if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
return;
width = extents.x2 - extents.x1;
@@ -918,6 +924,7 @@ exaGlyphs (CARD8 op,
rect.width = width;
rect.height = height;
(*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect);
+ exaPixmapDirty(pMaskPixmap, 0, 0, width, height);
FreeScratchGC (pGC);
x = -extents.x1;
y = -extents.y1;
@@ -929,6 +936,8 @@ exaGlyphs (CARD8 op,
y = 0;
}
+ exaGetDrawableDeltas(pDst->pDrawable, pDstPixmap, &xoff, &yoff);
+
while (nlist--)
{
GCPtr pGC = NULL;
@@ -983,13 +992,21 @@ exaGlyphs (CARD8 op,
pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = TRUE;
pixmaps[0].pPix = pPixmap;
- exaDoMigration (pixmaps, 1, TRUE);
+ exaDoMigration (pixmaps, 1, pExaScr->info->PrepareComposite != NULL);
while (n--)
{
GlyphPtr glyph = *glyphs++;
pointer glyphdata = (pointer) (glyph + 1);
-
+ DrawablePtr pCmpDrw = (maskFormat ? pMask : pDst)->pDrawable;
+
+ x1 = x - glyph->info.x;
+ y1 = y - glyph->info.y;
+
+ if (x1 >= pCmpDrw->width || y1 >= pCmpDrw->height ||
+ (x1 + glyph->info.width) <= 0 || (y1 + glyph->info.height) <= 0)
+ goto nextglyph;
+
(*pScreen->ModifyPixmapHeader) (pScratchPixmap,
glyph->info.width,
glyph->info.height,
@@ -1048,17 +1065,22 @@ exaGlyphs (CARD8 op,
if (maskFormat)
{
exaComposite (PictOpAdd, pPicture, NULL, pMask, 0, 0, 0, 0,
- x - glyph->info.x, y - glyph->info.y,
- glyph->info.width, glyph->info.height);
+ x1, y1, glyph->info.width, glyph->info.height);
+ exaPixmapDirty(pMaskPixmap, x1, y1, x1 + glyph->info.width,
+ y1 + glyph->info.height);
}
else
{
exaComposite (op, pSrc, pPicture, pDst,
- xSrc + (x - glyph->info.x) - xDst,
- ySrc + (y - glyph->info.y) - yDst,
- 0, 0, x - glyph->info.x, y - glyph->info.y,
- glyph->info.width, glyph->info.height);
+ xSrc + x1 - xDst, ySrc + y1 - yDst,
+ 0, 0, x1, y1, glyph->info.width,
+ glyph->info.height);
+ x1 += pDst->pDrawable->x + xoff;
+ y1 += pDst->pDrawable->y + yoff;
+ exaPixmapDirty(pDstPixmap, x1, y1, x1 + glyph->info.width,
+ y1 + glyph->info.height);
}
+nextglyph:
x += glyph->info.xOff;
y += glyph->info.yOff;
}
diff-tree 0c8905ebc91cf654facef84ee52231a358deec5c (from 567f18a09bfb05f448be40c7ebe0f210f955601c)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Sun Apr 29 23:47:08 2007 +0200
EXA: PolyFillRect improvements.
* Convert rects to region and use it for damage tracking.
* When possible, defer to exaFillRegion{Solid,Tiled} using converted region.
* Always migrate for fallbacks.
* Move damage tracking out of ExaCheckPolyFillRect.
diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index 95084fc..721882b 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -618,6 +618,9 @@ exaPolySegment (DrawablePtr pDrawable, G
DEALLOCATE_LOCAL(prect);
}
+static Bool exaFillRegionSolid (DrawablePtr pDrawable, RegionPtr pRegion,
+ Pixel pixel, CARD32 planemask, CARD32 alu);
+
static void
exaPolyFillRect(DrawablePtr pDrawable,
GCPtr pGC,
@@ -626,7 +629,7 @@ exaPolyFillRect(DrawablePtr pDrawable,
{
ExaScreenPriv (pDrawable->pScreen);
RegionPtr pClip = fbGetCompositeClip(pGC);
- PixmapPtr pPixmap;
+ PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
register BoxPtr pbox;
BoxPtr pextent;
int extentX1, extentX2, extentY1, extentY2;
@@ -635,39 +638,80 @@ exaPolyFillRect(DrawablePtr pDrawable,
int xoff, yoff;
int xorg, yorg;
int n;
- ExaMigrationRec pixmaps[1];
+ ExaMigrationRec pixmaps[2];
+ RegionPtr pReg = RECTS_TO_REGION(pScreen, nrect, prect, CT_UNSORTED);
+ RegionPtr pDamageReg = DamageRegion(ExaGetPixmapPriv(pPixmap)->pDamage);
+
+ /* Compute intersection of rects and clip region */
+ REGION_TRANSLATE(pScreen, pReg, pDrawable->x, pDrawable->y);
+ REGION_INTERSECT(pScreen, pReg, pClip, pReg);
+
+ if (!REGION_NUM_RECTS(pReg)) {
+ REGION_DESTROY(pScreen, pReg);
+ return;
+ }
pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = FALSE;
- pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable);
+ pixmaps[0].pPix = pPixmap;
+ exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
+
if (pExaScr->swappedOut ||
- pGC->fillStyle != FillSolid ||
pPixmap->drawable.width > pExaScr->info->maxX ||
pPixmap->drawable.height > pExaScr->info->maxY)
{
- exaDoMigration (pixmaps, 1, FALSE);
- ExaCheckPolyFillRect (pDrawable, pGC, nrect, prect);
- while (nrect-- >= 0) {
- exaDrawableDirty(pDrawable,
- pDrawable->x + prect->x,
- pDrawable->y + prect->y,
- pDrawable->x + prect->x + prect->width,
- pDrawable->y + prect->y + prect->height);
- prect++;
+ goto fallback;
+ }
+
+ /* For ROPs where overlaps don't matter, convert rectangles to region and
+ * call exaFillRegion{Solid,Tiled}.
+ */
+ if ((pGC->fillStyle == FillSolid || pGC->fillStyle == FillTiled) &&
+ (pGC->alu == GXcopy || pGC->alu == GXclear || pGC->alu == GXnoop ||
+ pGC->alu == GXcopyInverted || pGC->alu == GXset)) {
+ if (((pGC->fillStyle == FillSolid || pGC->tileIsPixel) &&
+ exaFillRegionSolid(pDrawable, pReg, pGC->fillStyle == FillSolid ?
+ pGC->fgPixel : pGC->tile.pixel, pGC->planemask,
+ pGC->alu)) ||
+ (pGC->fillStyle == FillTiled && !pGC->tileIsPixel &&
+ exaFillRegionTiled(pDrawable, pReg, pGC->tile.pixmap, &pGC->patOrg,
+ pGC->planemask, pGC->alu))) {
+ goto damage;
}
- return;
- } else {
- exaDoMigration (pixmaps, 1, TRUE);
}
- if (!(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) ||
+ if (pGC->fillStyle != FillSolid &&
+ !(pGC->tileIsPixel && pGC->fillStyle == FillTiled))
+ {
+ goto fallback;
+ }
+
+ exaDoMigration (pixmaps, 1, TRUE);
+
+ if (!exaPixmapIsOffscreen (pPixmap) ||
!(*pExaScr->info->PrepareSolid) (pPixmap,
pGC->alu,
pGC->planemask,
pGC->fgPixel))
{
+fallback:
+ if (pGC->fillStyle == FillTiled && !pGC->tileIsPixel) {
+ pixmaps[1].as_dst = FALSE;
+ pixmaps[1].as_src = TRUE;
+ pixmaps[1].pPix = pGC->tile.pixmap;
+ exaDoMigration (pixmaps, 2, FALSE);
+ } else {
+ exaDoMigration (pixmaps, 1, FALSE);
+ }
+
ExaCheckPolyFillRect (pDrawable, pGC, nrect, prect);
+
+damage:
+ REGION_TRANSLATE(pScreen, pReg, xoff, yoff);
+ REGION_UNION(pScreen, pDamageReg, pReg, pDamageReg);
+ REGION_DESTROY(pScreen, pReg);
+
return;
}
@@ -715,7 +759,8 @@ exaPolyFillRect(DrawablePtr pDrawable,
pbox = REGION_RECTS(pClip);
/*
* clip the rectangle to each box in the clip region
- * this is logically equivalent to calling Intersect()
+ * this is logically equivalent to calling Intersect(),
+ * but rectangles may overlap each other here.
*/
while(n--)
{
diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c
index 7713a08..a7f9398 100644
--- a/exa/exa_unaccel.c
+++ b/exa/exa_unaccel.c
@@ -201,32 +201,11 @@ ExaCheckPolyFillRect (DrawablePtr pDrawa
{
EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
- if (nrect) {
- int x1 = max(prect->x, 0), y1 = max(prect->y, 0);
- int x2 = min(prect->x + prect->width, pDrawable->width);
- int y2 = min(prect->y + prect->height, pDrawable->height);
-
- exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
- exaPrepareAccessGC (pGC);
- fbPolyFillRect (pDrawable, pGC, nrect, prect);
- exaFinishAccessGC (pGC);
- exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
-
- /* Only track bounding box of damage, as this path can degenerate to
- * zillions of damage boxes
- */
- while (--nrect)
- {
- prect++;
- x1 = min(x1, prect->x);
- x2 = max(x2, prect->x + prect->width);
- y1 = min(y1, prect->y);
- y2 = max(y2, prect->y + prect->height);
- }
-
- exaDrawableDirty (pDrawable, pDrawable->x + x1, pDrawable->y + y1,
- pDrawable->x + x2, pDrawable->y + y2);
- }
+ exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccessGC (pGC);
+ fbPolyFillRect (pDrawable, pGC, nrect, prect);
+ exaFinishAccessGC (pGC);
+ exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
}
void
diff-tree 567f18a09bfb05f448be40c7ebe0f210f955601c (from e869573b52fac69fb88cea120daaeec59c7a3461)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Sun Apr 29 23:46:49 2007 +0200
EXA: FillRegion{Solid,Tiled} improvements.
* Support planemasks, different ALUs and arbitrary tile origin.
* Leave damage tracking and non-trivial fallbacks to callers.
* Always migrate for fallbacks.
This is in preparation for using these from more other functions.
diff --git a/exa/exa.c b/exa/exa.c
index 23fe555..3d77800 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -126,7 +126,7 @@ exaGetDrawablePixmap(DrawablePtr pDrawab
* the backing drawable. These coordinates are nonzero only for redirected
* windows.
*/
-static void
+void
exaGetDrawableDeltas (DrawablePtr pDrawable, PixmapPtr pPixmap,
int *xp, int *yp)
{
diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index e633d80..95084fc 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -1043,10 +1043,12 @@ exaCopyWindow(WindowPtr pWin, DDXPointRe
REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
}
-static void
+static Bool
exaFillRegionSolid (DrawablePtr pDrawable,
RegionPtr pRegion,
- Pixel pixel)
+ Pixel pixel,
+ CARD32 planemask,
+ CARD32 alu)
{
ExaScreenPriv(pDrawable->pScreen);
PixmapPtr pPixmap;
@@ -1062,22 +1064,19 @@ exaFillRegionSolid (DrawablePtr pDrawabl
if (pPixmap->drawable.width > pExaScr->info->maxX ||
pPixmap->drawable.height > pExaScr->info->maxY)
{
- exaDoMigration (pixmaps, 1, FALSE);
goto fallback;
} else {
exaDoMigration (pixmaps, 1, TRUE);
}
if ((pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) &&
- (*pExaScr->info->PrepareSolid) (pPixmap, GXcopy, FB_ALLONES, pixel))
+ (*pExaScr->info->PrepareSolid) (pPixmap, alu, planemask, pixel))
{
while (nbox--)
{
(*pExaScr->info->Solid) (pPixmap,
pBox->x1 + xoff, pBox->y1 + yoff,
pBox->x2 + xoff, pBox->y2 + yoff);
- exaPixmapDirty (pPixmap, pBox->x1 + xoff, pBox->y1 + yoff,
- pBox->x2 + xoff, pBox->y2 + yoff);
pBox++;
}
(*pExaScr->info->DoneSolid) (pPixmap);
@@ -1086,27 +1085,30 @@ exaFillRegionSolid (DrawablePtr pDrawabl
else
{
fallback:
+ if (alu != GXcopy || planemask != FB_ALLONES)
+ return FALSE;
EXA_FALLBACK(("to %p (%c)\n", pDrawable,
exaDrawableLocation(pDrawable)));
+ exaDoMigration (pixmaps, 1, FALSE);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbFillRegionSolid (pDrawable, pRegion, 0,
fbReplicatePixel (pixel, pDrawable->bitsPerPixel));
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
- while (nbox--)
- {
- exaDrawableDirty (pDrawable, pBox->x1, pBox->y1, pBox->x2, pBox->y2);
- pBox++;
- }
}
+
+ return TRUE;
}
/* Try to do an accelerated tile of the pTile into pRegion of pDrawable.
* Based on fbFillRegionTiled(), fbTile().
*/
-static void
+Bool
exaFillRegionTiled (DrawablePtr pDrawable,
RegionPtr pRegion,
- PixmapPtr pTile)
+ PixmapPtr pTile,
+ DDXPointPtr pPatOrg,
+ CARD32 planemask,
+ CARD32 alu)
{
ExaScreenPriv(pDrawable->pScreen);
PixmapPtr pPixmap;
@@ -1122,10 +1124,10 @@ exaFillRegionTiled (DrawablePtr pDrawabl
/* If we're filling with a solid color, grab it out and go to
* FillRegionSolid, saving numerous copies.
*/
- if (tileWidth == 1 && tileHeight == 1) {
- exaFillRegionSolid(pDrawable, pRegion, exaGetPixmapFirstPixel (pTile));
- return;
- }
+ if (tileWidth == 1 && tileHeight == 1)
+ return exaFillRegionSolid(pDrawable, pRegion,
+ exaGetPixmapFirstPixel (pTile), planemask,
+ alu);
pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = FALSE;
@@ -1139,7 +1141,6 @@ exaFillRegionTiled (DrawablePtr pDrawabl
tileWidth > pExaScr->info->maxX ||
tileHeight > pExaScr->info->maxY)
{
- exaDoMigration (pixmaps, 2, FALSE);
goto fallback;
} else {
exaDoMigration (pixmaps, 2, TRUE);
@@ -1153,8 +1154,9 @@ exaFillRegionTiled (DrawablePtr pDrawabl
if (!exaPixmapIsOffscreen(pTile))
goto fallback;
- if ((*pExaScr->info->PrepareCopy) (exaGetOffscreenPixmap((DrawablePtr)pTile, &tileXoff, &tileYoff), pPixmap, 0, 0, GXcopy,
- FB_ALLONES))
+ if ((*pExaScr->info->PrepareCopy) (exaGetOffscreenPixmap((DrawablePtr)pTile,
+ &tileXoff, &tileYoff),
+ pPixmap, 0, 0, alu, planemask))
{
while (nbox--)
{
@@ -1162,7 +1164,7 @@ exaFillRegionTiled (DrawablePtr pDrawabl
int dstY = pBox->y1;
int tileY;
- tileY = (dstY - pDrawable->y) % tileHeight;
+ tileY = (dstY - pDrawable->y - pPatOrg->y) % tileHeight;
while (height > 0) {
int width = pBox->x2 - pBox->x1;
int dstX = pBox->x1;
@@ -1173,7 +1175,7 @@ exaFillRegionTiled (DrawablePtr pDrawabl
h = height;
height -= h;
- tileX = (dstX - pDrawable->x) % tileWidth;
+ tileX = (dstX - pDrawable->x - pPatOrg->x) % tileWidth;
while (width > 0) {
int w = tileWidth - tileX;
if (w > width)
@@ -1190,38 +1192,44 @@ exaFillRegionTiled (DrawablePtr pDrawabl
dstY += h;
tileY = 0;
}
- exaPixmapDirty (pPixmap, pBox->x1 + xoff, pBox->y1 + yoff,
- pBox->x2 + xoff, pBox->y2 + yoff);
pBox++;
}
(*pExaScr->info->DoneCopy) (pPixmap);
exaMarkSync(pDrawable->pScreen);
- return;
+ return TRUE;
}
fallback:
+ if (alu != GXcopy || planemask != FB_ALLONES)
+ return FALSE;
EXA_FALLBACK(("from %p to %p (%c,%c)\n", pTile, pDrawable,
exaDrawableLocation(&pTile->drawable),
exaDrawableLocation(pDrawable)));
+ exaDoMigration (pixmaps, 2, FALSE);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
exaPrepareAccess ((DrawablePtr)pTile, EXA_PREPARE_SRC);
fbFillRegionTiled (pDrawable, pRegion, pTile);
exaFinishAccess ((DrawablePtr)pTile, EXA_PREPARE_SRC);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
- while (nbox--)
- {
- exaDrawableDirty (pDrawable, pBox->x1, pBox->y1, pBox->x2, pBox->y2);
- pBox++;
- }
+
+ return TRUE;
}
void
exaPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
{
ExaScreenPriv (pWin->drawable.pScreen);
- if (!REGION_NUM_RECTS(pRegion))
+ PixmapPtr pPixmap = exaGetDrawablePixmap((DrawablePtr)pWin);
+ int xoff, yoff;
+ BoxPtr pBox;
+ int nbox = REGION_NUM_RECTS(pRegion);
+
+ if (!nbox)
return;
+
if (!pExaScr->swappedOut) {
+ DDXPointRec zeros = { 0, 0 };
+
switch (what) {
case PW_BACKGROUND:
switch (pWin->backgroundState) {
@@ -1235,25 +1243,41 @@ exaPaintWindow(WindowPtr pWin, RegionPtr
what);
return;
case BackgroundPixel:
- exaFillRegionSolid((DrawablePtr)pWin, pRegion, pWin->background.pixel);
- return;
+ exaFillRegionSolid((DrawablePtr)pWin, pRegion, pWin->background.pixel,
+ FB_ALLONES, GXcopy);
+ goto damage;
case BackgroundPixmap:
- exaFillRegionTiled((DrawablePtr)pWin, pRegion, pWin->background.pixmap);
- return;
+ exaFillRegionTiled((DrawablePtr)pWin, pRegion, pWin->background.pixmap,
+ &zeros, FB_ALLONES, GXcopy);
+ goto damage;
}
break;
case PW_BORDER:
if (pWin->borderIsPixel) {
- exaFillRegionSolid((DrawablePtr)pWin, pRegion, pWin->border.pixel);
- return;
+ exaFillRegionSolid((DrawablePtr)pWin, pRegion, pWin->border.pixel,
+ FB_ALLONES, GXcopy);
+ goto damage;
} else {
- exaFillRegionTiled((DrawablePtr)pWin, pRegion, pWin->border.pixmap);
- return;
+ exaFillRegionTiled((DrawablePtr)pWin, pRegion, pWin->border.pixmap,
+ &zeros, FB_ALLONES, GXcopy);
+ goto damage;
}
break;
}
}
ExaCheckPaintWindow (pWin, pRegion, what);
+
+damage:
+ exaGetDrawableDeltas((DrawablePtr)pWin, pPixmap, &xoff, &yoff);
+
+ pBox = REGION_RECTS(pRegion);
+
+ while (nbox--)
+ {
+ exaPixmapDirty (pPixmap, pBox->x1 + xoff, pBox->y1 + yoff,
+ pBox->x2 + xoff, pBox->y2 + yoff);
+ pBox++;
+ }
}
/**
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index 382f059..b976082 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -288,6 +288,10 @@ exaGetPixmapFirstPixel (PixmapPtr pPixma
void
exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
+Bool
+exaFillRegionTiled (DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile,
+ DDXPointPtr pPatOrg, CARD32 planemask, CARD32 alu);
+
void
exaPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what);
@@ -344,6 +348,10 @@ void
exaPixmapDirty(PixmapPtr pPix, int x1, int y1, int x2, int y2);
void
+exaGetDrawableDeltas (DrawablePtr pDrawable, PixmapPtr pPixmap,
+ int *xp, int *yp);
+
+void
exaDrawableDirty(DrawablePtr pDrawable, int x1, int y1, int x2, int y2);
Bool
diff-tree e869573b52fac69fb88cea120daaeec59c7a3461 (from d3f8667341bfe6dc7d0258c4ad69377f37d88d95)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Sun Apr 29 23:45:48 2007 +0200
EXA: exaAssertNotDirty improvements.
* Return early if the valid region is empty or the pixmap is pinned.
* Fix loop for several cliprects.
diff --git a/exa/exa_migration.c b/exa/exa_migration.c
index eedc5fd..70d8e12 100644
--- a/exa/exa_migration.c
+++ b/exa/exa_migration.c
@@ -464,12 +464,10 @@ exaAssertNotDirty (PixmapPtr pPixmap)
BoxPtr pBox = REGION_RECTS(pValidReg);
Bool ret = TRUE;
- if (pExaPixmap == NULL || pExaPixmap->fb_ptr == NULL)
+ if (!nbox || exaPixmapIsPinned(pPixmap) || pExaPixmap->fb_ptr == NULL)
return ret;
- dst = pExaPixmap->sys_ptr;
dst_pitch = pExaPixmap->sys_pitch;
- src = pExaPixmap->fb_ptr;
src_pitch = pExaPixmap->fb_pitch;
cpp = pPixmap->drawable.bitsPerPixel / 8;
@@ -486,21 +484,18 @@ exaAssertNotDirty (PixmapPtr pPixmap)
continue;
rowbytes = (pBox->x2 - pBox->x1) * cpp;
- src += pBox->y1 * src_pitch + pBox->x1 * cpp;
- dst += pBox->y1 * dst_pitch + pBox->x1 * cpp;
+ src = pExaPixmap->fb_ptr + pBox->y1 * src_pitch + pBox->x1 * cpp;
+ dst = pExaPixmap->sys_ptr + pBox->y1 * dst_pitch + pBox->x1 * cpp;
- for (y = pBox->y2 - pBox->y1; y; y--) {
- if (memcmp(dst + pBox->y1 * dst_pitch + pBox->x1 * cpp,
- src + pBox->y1 * src_pitch + pBox->x1 * cpp,
- (pBox->x2 - pBox->x1) * cpp) != 0) {
+ for (y = pBox->y1; y < pBox->y2;
+ y++, src += src_pitch, dst += dst_pitch) {
+ if (memcmp(dst, src, rowbytes) != 0) {
ret = FALSE;
+ exaPixmapDirty(pPixmap, pBox->x1, pBox->y1, pBox->x2,
+ pBox->y2);
break;
}
- src += src_pitch;
- dst += dst_pitch;
}
- src -= pBox->y1 * src_pitch + pBox->x1 * cpp;
- dst -= pBox->y1 * dst_pitch + pBox->x1 * cpp;
}
exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
diff-tree d3f8667341bfe6dc7d0258c4ad69377f37d88d95 (from 5e4b3232dafe3b0dec65bf639bebaba4774210b7)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Sun Apr 29 23:44:27 2007 +0200
EXA: Fix exaEnableDisableFBAccess for nested disables and enables.
diff --git a/exa/exa_offscreen.c b/exa/exa_offscreen.c
index 7708dd7..38ad58f 100644
--- a/exa/exa_offscreen.c
+++ b/exa/exa_offscreen.c
@@ -341,13 +341,15 @@ exaEnableDisableFBAccess (int index, Boo
ScreenPtr pScreen = screenInfo.screens[index];
ExaScreenPriv (pScreen);
- if (!enable) {
+ if (!enable && pExaScr->disableFbCount++ == 0) {
if (pExaScr->info->exa_minor < 1)
ExaOffscreenSwapOut (pScreen);
else
ExaOffscreenEjectPixmaps (pScreen);
pExaScr->swappedOut = TRUE;
- } else {
+ }
+
+ if (enable && --pExaScr->disableFbCount == 0) {
if (pExaScr->info->exa_minor < 1)
ExaOffscreenSwapIn (pScreen);
pExaScr->swappedOut = FALSE;
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index 984cb66..382f059 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -113,6 +113,7 @@ typedef struct {
enum ExaMigrationHeuristic migration;
Bool hideOffscreenPixmapData;
Bool checkDirtyCorrectness;
+ unsigned disableFbCount;
} ExaScreenPrivRec, *ExaScreenPrivPtr;
/*
More information about the xorg-commit
mailing list