xserver: Branch 'no-pci-rework' - 16 commits
Michel Daenzer
daenzer at kemper.freedesktop.org
Fri Sep 7 15:20:37 PDT 2007
exa/exa.c | 210 ++++++++++++----
exa/exa_accel.c | 627 +++++++++++++++++++++++++-------------------------
exa/exa_migration.c | 352 +++++++++++++++-------------
exa/exa_priv.h | 65 +++--
exa/exa_render.c | 320 ++++++++++++++-----------
exa/exa_unaccel.c | 89 ++++---
miext/damage/damage.c | 6
miext/damage/damage.h | 3
8 files changed, 965 insertions(+), 707 deletions(-)
New commits:
diff-tree 032c729bb8d925d7b8a4a81ddc9dd03e9031cf91 (from 19149c6669e3a72f81e7c773df734ea98a009d0c)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Mon Sep 3 13:52:29 2007 +0200
EXA: Exclude bits that will be overwritten from migration in exaCopyNtoN.
Also plug a region leak in exaPolyFillRect.
diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index 0a03d71..232ec99 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -483,14 +483,48 @@ exaCopyNtoN (DrawablePtr pSrcDrawable
int src_off_x, src_off_y;
int dst_off_x, dst_off_y;
ExaMigrationRec pixmaps[2];
+ RegionPtr region = NULL;
+
+ 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 (!pGC || !exaGCReadsDestination(pDstDrawable, pGC->planemask,
+ pGC->fillStyle, pGC->alu)) {
+ xRectangle *rects = ALLOCATE_LOCAL(nbox * sizeof(xRectangle));
+
+ if (rects) {
+ int i;
+
+ for (i = 0; i < nbox; i++) {
+ rects[i].x = pbox[i].x1 + dst_off_x;
+ rects[i].y = pbox[i].y1 + dst_off_y;
+ rects[i].width = pbox[i].x2 - pbox[i].x1;
+ rects[i].height = pbox[i].y2 - pbox[i].y1;
+ }
+
+ region = RECTS_TO_REGION(pScreen, nbox, rects, CT_YXBANDED);
+ DEALLOCATE_LOCAL(rects);
+
+ if (region) {
+ src_off_x -= dst_off_x;
+ src_off_y -= dst_off_y;
+ dst_off_x = dst_off_y = 0;
+ pbox = REGION_RECTS(region);
+ nbox = REGION_NUM_RECTS(region);
+ }
+ }
+ }
pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = FALSE;
- pixmaps[0].pPix = pDstPixmap = exaGetDrawablePixmap (pDstDrawable);
- pixmaps[0].pReg = NULL;
+ pixmaps[0].pPix = pDstPixmap;
+ pixmaps[0].pReg = region;
pixmaps[1].as_dst = FALSE;
pixmaps[1].as_src = TRUE;
- pixmaps[1].pPix = pSrcPixmap = exaGetDrawablePixmap (pSrcDrawable);
+ pixmaps[1].pPix = pSrcPixmap;
pixmaps[1].pReg = NULL;
/* Respect maxX/maxY in a trivial way: don't set up drawing when we might
@@ -512,16 +546,10 @@ exaCopyNtoN (DrawablePtr pSrcDrawable
reverse != upsidedown) {
if (exaCopyNtoNTwoDir(pSrcDrawable, pDstDrawable, pGC, pbox, nbox,
dx, dy))
- return;
+ goto out;
goto fallback;
}
- 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 (!exaPixmapIsOffscreen(pSrcPixmap) ||
!exaPixmapIsOffscreen(pDstPixmap) ||
!(*pExaScr->info->PrepareCopy) (pSrcPixmap, pDstPixmap, reverse ? -1 : 1,
@@ -544,18 +572,24 @@ exaCopyNtoN (DrawablePtr pSrcDrawable
(*pExaScr->info->DoneCopy) (pDstPixmap);
exaMarkSync (pDstDrawable->pScreen);
- return;
+ goto out;
fallback:
EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrcDrawable, pDstDrawable,
exaDrawableLocation(pSrcDrawable),
exaDrawableLocation(pDstDrawable)));
- exaPrepareAccessReg (pDstDrawable, EXA_PREPARE_DEST, pixmaps[0].pReg);
+ exaPrepareAccessReg (pDstDrawable, EXA_PREPARE_DEST, region);
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);
+
+out:
+ if (region) {
+ REGION_UNINIT(pScreen, region);
+ REGION_DESTROY(pScreen, region);
+ }
}
RegionPtr
@@ -870,6 +904,7 @@ fallback:
exaMarkSync(pDrawable->pScreen);
out:
+ REGION_UNINIT(pScreen, pReg);
REGION_DESTROY(pScreen, pReg);
}
diff-tree 19149c6669e3a72f81e7c773df734ea98a009d0c (from fac68373b2d5a758a852d58cc91329dba721b221)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Mon Sep 3 13:14:29 2007 +0200
EXA: exaFillRegion{Solid,Tiled} improvements.
Use region to exclude bits that will be overwritten from migration.
Also make exaFillRegionSolid use the same logic as exaFillRegionTiled.
diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index e44ce60..0a03d71 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -1074,7 +1074,11 @@ exaFillRegionSolid (DrawablePtr pDrawabl
pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = FALSE;
pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable);
- pixmaps[0].pReg = NULL;
+ pixmaps[0].pReg = exaGCReadsDestination(pDrawable, planemask, FillSolid,
+ alu) ? NULL : pRegion;
+
+ exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
+ REGION_TRANSLATE(pScreen, pRegion, xoff, yoff);
if (pPixmap->drawable.width > pExaScr->info->maxX ||
pPixmap->drawable.height > pExaScr->info->maxY)
@@ -1090,8 +1094,6 @@ exaFillRegionSolid (DrawablePtr pDrawabl
int nbox;
BoxPtr pBox;
- REGION_TRANSLATE(pScreen, pRegion, xoff, yoff);
-
nbox = REGION_NUM_RECTS (pRegion);
pBox = REGION_RECTS (pRegion);
@@ -1124,19 +1126,21 @@ exaFillRegionSolid (DrawablePtr pDrawabl
}
REGION_TRANSLATE(pScreen, pRegion, -xoff, -yoff);
+ return TRUE;
}
- else
- {
+
fallback:
- if (alu != GXcopy || planemask != FB_ALLONES)
- return FALSE;
- EXA_FALLBACK(("to %p (%c)\n", pDrawable,
- exaDrawableLocation(pDrawable)));
- exaPrepareAccessReg (pDrawable, EXA_PREPARE_DEST, pixmaps[0].pReg);
- fbFillRegionSolid (pDrawable, pRegion, 0,
- fbReplicatePixel (pixel, pDrawable->bitsPerPixel));
- exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ if (alu != GXcopy || !EXA_PM_IS_SOLID(pDrawable, planemask)) {
+ REGION_TRANSLATE(pScreen, pRegion, -xoff, -yoff);
+ return FALSE;
}
+ EXA_FALLBACK(("to %p (%c)\n", pDrawable,
+ exaDrawableLocation(pDrawable)));
+ exaPrepareAccessReg (pDrawable, EXA_PREPARE_DEST, pixmaps[0].pReg);
+ REGION_TRANSLATE(pScreen, pRegion, -xoff, -yoff);
+ fbFillRegionSolid (pDrawable, pRegion, 0,
+ fbReplicatePixel (pixel, pDrawable->bitsPerPixel));
+ exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
return TRUE;
}
@@ -1174,12 +1178,16 @@ exaFillRegionTiled (DrawablePtr pDrawabl
pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = FALSE;
pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable);
- pixmaps[0].pReg = NULL;
+ pixmaps[0].pReg = exaGCReadsDestination(pDrawable, planemask, FillTiled,
+ alu) ? NULL : pRegion;
pixmaps[1].as_dst = FALSE;
pixmaps[1].as_src = TRUE;
pixmaps[1].pPix = pTile;
pixmaps[1].pReg = NULL;
+ exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
+ REGION_TRANSLATE(pScreen, pRegion, xoff, yoff);
+
if (pPixmap->drawable.width > pExaScr->info->maxX ||
pPixmap->drawable.height > pExaScr->info->maxY ||
tileWidth > pExaScr->info->maxX ||
@@ -1208,7 +1216,7 @@ exaFillRegionTiled (DrawablePtr pDrawabl
int dstY = pBox->y1;
int tileY;
- tileY = (dstY - pDrawable->y - pPatOrg->y) % tileHeight;
+ tileY = (dstY - yoff - pDrawable->y - pPatOrg->y) % tileHeight;
while (height > 0) {
int width = pBox->x2 - pBox->x1;
int dstX = pBox->x1;
@@ -1219,7 +1227,7 @@ exaFillRegionTiled (DrawablePtr pDrawabl
h = height;
height -= h;
- tileX = (dstX - pDrawable->x - pPatOrg->x) % tileWidth;
+ tileX = (dstX - xoff - pDrawable->x - pPatOrg->x) % tileWidth;
while (width > 0) {
int w = tileWidth - tileX;
if (w > width)
@@ -1228,8 +1236,7 @@ exaFillRegionTiled (DrawablePtr pDrawabl
(*pExaScr->info->Copy) (pPixmap,
tileX + tileXoff, tileY + tileYoff,
- dstX + xoff, dstY + yoff,
- w, h);
+ dstX, dstY, w, h);
dstX += w;
tileX = 0;
}
@@ -1240,16 +1247,20 @@ exaFillRegionTiled (DrawablePtr pDrawabl
}
(*pExaScr->info->DoneCopy) (pPixmap);
exaMarkSync(pDrawable->pScreen);
+ REGION_TRANSLATE(pScreen, pRegion, -xoff, -yoff);
return TRUE;
}
fallback:
- if (alu != GXcopy || planemask != FB_ALLONES)
+ if (alu != GXcopy || !EXA_PM_IS_SOLID(pDrawable, planemask)) {
+ REGION_TRANSLATE(pScreen, pRegion, -xoff, -yoff);
return FALSE;
+ }
EXA_FALLBACK(("from %p to %p (%c,%c)\n", pTile, pDrawable,
exaDrawableLocation(&pTile->drawable),
exaDrawableLocation(pDrawable)));
exaPrepareAccessReg (pDrawable, EXA_PREPARE_DEST, pixmaps[0].pReg);
+ REGION_TRANSLATE(pScreen, pRegion, -xoff, -yoff);
exaPrepareAccess ((DrawablePtr)pTile, EXA_PREPARE_SRC);
fbFillRegionTiled (pDrawable, pRegion, pTile);
exaFinishAccess ((DrawablePtr)pTile, EXA_PREPARE_SRC);
diff-tree fac68373b2d5a758a852d58cc91329dba721b221 (from fc18cbbc5c1eb1787c116eb3c4b6f3d9cf5f219a)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Fri Aug 31 16:59:28 2007 +0200
EXA: Use exaShmPutImage for pushing glyphs to scratch pixmap in exaGlyphs.
diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index 136fca2..e44ce60 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -287,7 +287,7 @@ exaDoShmPutImage(DrawablePtr pDrawable,
* We also need to set the pending damage to ensure correct migration in all
* cases.
*/
-static void
+void
exaShmPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, unsigned int format,
int w, int h, int sx, int sy, int sw, int sh, int dx, int dy,
char *data)
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index a6ac921..02371d7 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -300,6 +300,11 @@ void
exaPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what);
void
+exaShmPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, unsigned int format,
+ int w, int h, int sx, int sy, int sw, int sh, int dx, int dy,
+ char *data);
+
+void
exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h,
unsigned int format, unsigned long planeMask, char *d);
diff --git a/exa/exa_render.c b/exa/exa_render.c
index 9df795f..943a4c8 100644
--- a/exa/exa_render.c
+++ b/exa/exa_render.c
@@ -1282,6 +1282,15 @@ exaGlyphs (CARD8 op,
pScratchPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
}
+#ifdef MITSHM
+ if (pExaScr->info->PrepareComposite)
+ exaShmPutImage(&pPixmap->drawable, pGC,
+ pPixmap->drawable.depth, ZPixmap,
+ glyph->info.width, glyph->info.height, 0, 0,
+ glyph->info.width, glyph->info.height, 0, 0,
+ glyphdata);
+ else
+#endif
exaCopyArea (&pScratchPixmap->drawable, &pPixmap->drawable, pGC,
0, 0, glyph->info.width, glyph->info.height, 0, 0);
}
diff-tree fc18cbbc5c1eb1787c116eb3c4b6f3d9cf5f219a (from bf8686b002f2965fc8873f46beeadb83cec7d788)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Thu Aug 30 13:59:07 2007 +0200
EXA: exa(Shm)PutImage improvements.
Improve exaShmPutImage performance and reuse its core in exaPutImage as it
seems faster than the previous code when the driver doesn't provide an
UploadToScreen hook.
Make sure all damage records are notified of the damage incurred by actual
ShmPutImage calls.
Remove superfluous manual damage tracking for actual PutImage calls.
diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index df6a62d..136fca2 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -139,10 +139,11 @@ exaFillSpans(DrawablePtr pDrawable, GCPt
static Bool
exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
- int w, int h, int leftPad, int format, char *bits, int src_stride)
+ int w, int h, int format, char *bits, int src_stride)
{
ExaScreenPriv (pDrawable->pScreen);
- PixmapPtr pPix;
+ PixmapPtr pPix = exaGetDrawablePixmap (pDrawable);
+ ExaPixmapPriv(pPix);
ExaMigrationRec pixmaps[1];
RegionPtr pClip;
BoxPtr pbox;
@@ -151,26 +152,28 @@ exaDoPutImage (DrawablePtr pDrawable, GC
int bpp = pDrawable->bitsPerPixel;
Bool access_prepared = FALSE;
- pixmaps[0].as_dst = TRUE;
- pixmaps[0].as_src = FALSE;
- pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable);
- pixmaps[0].pReg = NULL;
-
/* Don't bother with under 8bpp, XYPixmaps. */
if (format != ZPixmap || bpp < 8)
- goto fallback;
+ return FALSE;
/* Only accelerate copies: no rop or planemask. */
if (!EXA_PM_IS_SOLID(pDrawable, pGC->planemask) || pGC->alu != GXcopy)
- goto fallback;
+ return FALSE;
if (pExaScr->swappedOut)
- goto fallback;
+ return FALSE;
+ pixmaps[0].as_dst = TRUE;
+ pixmaps[0].as_src = FALSE;
+ pixmaps[0].pPix = pPix;
+ pixmaps[0].pReg = DamagePendingRegion(pExaPixmap->pDamage);
exaDoMigration (pixmaps, 1, TRUE);
pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
+ if (!pPix || !pExaScr->info->UploadToScreen)
+ return FALSE;
+
x += pDrawable->x;
y += pDrawable->y;
@@ -199,10 +202,8 @@ exaDoPutImage (DrawablePtr pDrawable, GC
continue;
src = bits + (y1 - y) * src_stride + (x1 - x) * (bpp / 8);
- ok = (pPix && pExaScr->info->UploadToScreen) ?
- pExaScr->info->UploadToScreen(pPix, x1 + xoff, y1 + yoff,
- x2 - x1, y2 - y1, src, src_stride) :
- FALSE;
+ ok = pExaScr->info->UploadToScreen(pPix, x1 + xoff, y1 + yoff,
+ x2 - x1, y2 - y1, src, src_stride);
/* If we fail to accelerate the upload, fall back to using unaccelerated
* fb calls.
*/
@@ -231,8 +232,6 @@ exaDoPutImage (DrawablePtr pDrawable, GC
y2 - y1,
GXcopy, FB_ALLONES, dstBpp);
}
-
- exaPixmapDirty(pixmaps[0].pPix, x1 + xoff, y1 + yoff, x2 + xoff, y2 + yoff);
}
if (access_prepared)
@@ -241,45 +240,110 @@ exaDoPutImage (DrawablePtr pDrawable, GC
exaMarkSync(pDrawable->pScreen);
return TRUE;
-
-fallback:
- return FALSE;
}
-static void
-exaPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
- int w, int h, int leftPad, int format, char *bits)
+#ifdef MITSHM
+
+static Bool
+exaDoShmPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth,
+ unsigned int format, int w, int h, int sx, int sy, int sw,
+ int sh, int dx, int dy, char *data)
{
- if (!exaDoPutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits,
- PixmapBytePad(w, pDrawable->depth)))
- ExaCheckPutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format,
- bits);
-}
+ int src_stride = PixmapBytePad(w, depth);
-#ifdef MITSHM
+ if (exaDoPutImage(pDrawable, pGC, depth, dx, dy, sw, sh, format, data +
+ sy * src_stride + sx * BitsPerPixel(depth) / 8,
+ src_stride))
+ return TRUE;
+
+ if (format == ZPixmap)
+ {
+ PixmapPtr pPixmap;
+
+ pPixmap = GetScratchPixmapHeader(pDrawable->pScreen, w, h, depth,
+ BitsPerPixel(depth), PixmapBytePad(w, depth), (pointer)data);
+ if (!pPixmap)
+ return FALSE;
+ if (exaGCReadsDestination(pDrawable, pGC->planemask, pGC->fillStyle,
+ pGC->alu))
+ exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ else
+ ExaDoPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ fbCopyArea((DrawablePtr)pPixmap, pDrawable, pGC, sx, sy, sw, sh, dx, dy);
+ exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
+
+ FreeScratchPixmapHeader(pPixmap);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* The actual ShmPutImage isn't wrapped by the damage layer, so we need to
+ * inform any interested parties of the damage incurred to the drawable.
+ *
+ * We also need to set the pending damage to ensure correct migration in all
+ * cases.
+ */
static void
exaShmPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, unsigned int format,
int w, int h, int sx, int sy, int sw, int sh, int dx, int dy,
char *data)
{
- int src_stride = PixmapBytePad(w, depth);
+ PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
+ ExaPixmapPriv(pPixmap);
+ BoxRec box = { .x1 = pDrawable->x + dx, .y1 = pDrawable->y + dy,
+ .x2 = pDrawable->x + dx + sw, .y2 = pDrawable->y + dy + sh };
+ RegionRec region;
+ int xoff, yoff;
+ RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
- if (exaDoPutImage(pDrawable, pGC, depth, dx, dy, sw, sh, 0, format, data +
- sy * src_stride + sx * BitsPerPixel(depth) / 8,
- src_stride))
- return;
+ REGION_INIT(pScreen, ®ion, &box, 1);
- exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
- fbShmPutImage(pDrawable, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy,
- data);
- exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
+ exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
+
+ REGION_TRANSLATE(pScreen, ®ion, xoff, yoff);
+ REGION_UNION(pScreen, pending_damage, pending_damage, ®ion);
+
+ if (!exaDoShmPutImage(pDrawable, pGC, depth, format, w, h, sx, sy, sw, sh,
+ dx, dy, data)) {
+ if (exaGCReadsDestination(pDrawable, pGC->planemask, pGC->fillStyle,
+ pGC->alu))
+ exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ else
+ ExaDoPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ fbShmPutImage(pDrawable, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy,
+ data);
+ exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
+ }
+
+ REGION_TRANSLATE(pScreen, ®ion, -xoff, -yoff);
+ DamageDamageRegion(pDrawable, ®ion);
+
+ REGION_UNINIT(pScreen, ®ion);
}
ShmFuncs exaShmFuncs = { NULL, exaShmPutImage };
#endif
+static void
+exaPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
+ int w, int h, int leftPad, int format, char *bits)
+{
+#ifdef MITSHM
+ if (!exaDoShmPutImage(pDrawable, pGC, depth, format, w, h, 0, 0, w, h, x, y,
+ bits))
+#else
+ if (!exaDoPutImage(pDrawable, pGC, depth, x, y, w, h, format, bits,
+ PixmapBytePad(w, pDrawable->depth)))
+#endif
+ ExaCheckPutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format,
+ bits);
+}
+
static Bool inline
exaCopyNtoNTwoDir (DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
GCPtr pGC, BoxPtr pbox, int nbox, int dx, int dy)
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index 8e51f5d..a6ac921 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -279,6 +279,16 @@ CARD32
exaGetPixmapFirstPixel (PixmapPtr pPixmap);
/* exa_accel.c */
+
+static _X_INLINE Bool
+exaGCReadsDestination(DrawablePtr pDrawable, unsigned long planemask,
+ unsigned int fillStyle, unsigned char alu)
+{
+ return ((alu != GXcopy && alu != GXclear &&alu != GXset &&
+ alu != GXcopyInverted) || fillStyle == FillStippled ||
+ !EXA_PM_IS_SOLID(pDrawable, planemask));
+}
+
void
exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c
index 8fb7b52..f4d453e 100644
--- a/exa/exa_unaccel.c
+++ b/exa/exa_unaccel.c
@@ -97,14 +97,14 @@ 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);
+ if (exaGCReadsDestination(pDrawable, pGC->planemask, pGC->fillStyle,
+ pGC->alu))
+ exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ else
+ ExaDoPrepareAccess (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);
}
RegionPtr
diff-tree bf8686b002f2965fc8873f46beeadb83cec7d788 (from dbf000df439e99371d65a3b4e90be7f7d123d467)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Thu Aug 30 13:54:18 2007 +0200
EXA: exaGetImage improvements.
Use the new migration infrastructure to cache FB bits we need in the system
copy, for the benefit of repeated calls.
diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index 36815e2..df6a62d 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -1247,22 +1247,43 @@ exaPaintWindow(WindowPtr pWin, RegionPtr
* Accelerates GetImage for solid ZPixmap downloads from framebuffer memory.
*
* This is probably the only case we actually care about. The rest fall through
- * to migration and ExaCheckGetImage, which hopefully will result in migration
- * pushing the pixmap out of framebuffer.
+ * to migration and fbGetImage, which hopefully will result in migration pushing
+ * the pixmap out of framebuffer.
*/
void
exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h,
unsigned int format, unsigned long planeMask, char *d)
{
ExaScreenPriv (pDrawable->pScreen);
+ ExaMigrationRec pixmaps[1];
+ BoxRec Box;
+ RegionRec Reg;
PixmapPtr pPix;
int xoff, yoff;
Bool ok;
- if (pExaScr->swappedOut || (w == 1 && h == 1))
+ if (pExaScr->swappedOut)
goto fallback;
- if (pExaScr->info->DownloadFromScreen == NULL)
+ pixmaps[0].as_dst = FALSE;
+ pixmaps[0].as_src = TRUE;
+ pixmaps[0].pPix = pPix = exaGetDrawablePixmap (pDrawable);
+ pixmaps[0].pReg = &Reg;
+
+ exaGetDrawableDeltas (pDrawable, pPix, &xoff, &yoff);
+
+ Box.x1 = pDrawable->y + x + xoff;
+ Box.y1 = pDrawable->y + y + yoff;
+ Box.x2 = Box.x1 + w;
+ Box.y2 = Box.y1 + h;
+
+ REGION_INIT(pScreen, &Reg, &Box, 1);
+
+ exaDoMigration(pixmaps, 1, FALSE);
+
+ pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
+
+ if (pPix == NULL || pExaScr->info->DownloadFromScreen == NULL)
goto fallback;
/* Only cover the ZPixmap, solid copy case. */
@@ -1275,20 +1296,22 @@ exaGetImage (DrawablePtr pDrawable, int
if (pDrawable->bitsPerPixel < 8)
goto fallback;
- pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
- if (pPix == NULL)
- goto fallback;
-
- xoff += pDrawable->x;
- yoff += pDrawable->y;
-
- ok = pExaScr->info->DownloadFromScreen(pPix, x + xoff, y + yoff, w, h, d,
+ ok = pExaScr->info->DownloadFromScreen(pPix, pDrawable->x + x + xoff,
+ pDrawable->y + y + yoff, w, h, d,
PixmapBytePad(w, pDrawable->depth));
if (ok) {
exaWaitSync(pDrawable->pScreen);
- return;
+ goto out;
}
fallback:
- ExaCheckGetImage (pDrawable, x, y, w, h, format, planeMask, d);
+ EXA_FALLBACK(("from %p (%c)\n", pDrawable,
+ exaDrawableLocation(pDrawable)));
+
+ exaPrepareAccessReg (pDrawable, EXA_PREPARE_SRC, &Reg);
+ fbGetImage (pDrawable, x, y, w, h, format, planeMask, d);
+ exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
+
+out:
+ REGION_UNINIT(pScreen, &Reg);
}
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index a8bdbd6..8e51f5d 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -265,12 +265,6 @@ ExaCheckPushPixels (GCPtr pGC, PixmapPtr
int w, int h, int x, int y);
void
-ExaCheckGetImage (DrawablePtr pDrawable,
- int x, int y, int w, int h,
- unsigned int format, unsigned long planeMask,
- char *d);
-
-void
ExaCheckGetSpans (DrawablePtr pDrawable,
int wMax,
DDXPointPtr ppt,
diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c
index 970c2cb..8fb7b52 100644
--- a/exa/exa_unaccel.c
+++ b/exa/exa_unaccel.c
@@ -265,19 +265,6 @@ ExaCheckPushPixels (GCPtr pGC, PixmapPtr
}
void
-ExaCheckGetImage (DrawablePtr pDrawable,
- int x, int y, int w, int h,
- unsigned int format, unsigned long planeMask,
- char *d)
-{
- EXA_FALLBACK(("from %p (%c)\n", pDrawable,
- exaDrawableLocation(pDrawable)));
- exaPrepareAccess (pDrawable, EXA_PREPARE_SRC);
- fbGetImage (pDrawable, x, y, w, h, format, planeMask, d);
- exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
-}
-
-void
ExaCheckGetSpans (DrawablePtr pDrawable,
int wMax,
DDXPointPtr ppt,
diff-tree dbf000df439e99371d65a3b4e90be7f7d123d467 (from 23da2c0da3817300272933de979572da0feaa698)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Thu Aug 30 13:50:42 2007 +0200
EXA: Remove superfluous manual damage tracking.
These should all be covered by damage wrappers.
diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index 4cae198..36815e2 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -394,8 +394,6 @@ exaCopyNtoNTwoDir (DrawablePtr pSrcDrawa
dst_off_y + pbox->y1 + i,
pbox->x2 - pbox->x1, 1);
}
- exaPixmapDirty(pDstPixmap, dst_off_x + pbox->x1, dst_off_y + pbox->y1,
- dst_off_x + pbox->x2, dst_off_y + pbox->y2);
}
if (dirsetup != 0)
pExaScr->info->DoneCopy(pDstPixmap);
@@ -421,7 +419,6 @@ 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;
@@ -441,18 +438,18 @@ exaCopyNtoN (DrawablePtr pSrcDrawable
pDstPixmap->drawable.width > pExaScr->info->maxX ||
pDstPixmap->drawable.height > pExaScr->info->maxY)
{
- fallback = TRUE;
+ goto fallback;
} else {
exaDoMigration (pixmaps, 2, TRUE);
}
/* Mixed directions must be handled specially if the card is lame */
- if (!fallback && (pExaScr->info->flags & EXA_TWO_BITBLT_DIRECTIONS) &&
+ if ((pExaScr->info->flags & EXA_TWO_BITBLT_DIRECTIONS) &&
reverse != upsidedown) {
if (exaCopyNtoNTwoDir(pSrcDrawable, pDstDrawable, pGC, pbox, nbox,
dx, dy))
return;
- fallback = TRUE;
+ goto fallback;
}
pSrcPixmap = exaGetDrawablePixmap (pSrcDrawable);
@@ -461,43 +458,40 @@ exaCopyNtoN (DrawablePtr pSrcDrawable
exaGetDrawableDeltas (pSrcDrawable, pSrcPixmap, &src_off_x, &src_off_y);
exaGetDrawableDeltas (pDstDrawable, pDstPixmap, &dst_off_x, &dst_off_y);
- if (fallback || !exaPixmapIsOffscreen(pSrcPixmap) ||
+ if (!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)));
- exaPrepareAccessReg (pDstDrawable, EXA_PREPARE_DEST, pixmaps[0].pReg);
- 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);
+ goto fallback;
}
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);
+ (*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);
pbox++;
}
- if (fallback)
- return;
-
(*pExaScr->info->DoneCopy) (pDstPixmap);
exaMarkSync (pDstDrawable->pScreen);
+
+ return;
+
+fallback:
+ EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrcDrawable, pDstDrawable,
+ exaDrawableLocation(pSrcDrawable),
+ exaDrawableLocation(pDstDrawable)));
+ exaPrepareAccessReg (pDstDrawable, EXA_PREPARE_DEST, pixmaps[0].pReg);
+ 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);
}
RegionPtr
@@ -1204,12 +1198,8 @@ void
exaPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
{
ExaScreenPriv (pWin->drawable.pScreen);
- PixmapPtr pPixmap = exaGetDrawablePixmap((DrawablePtr)pWin);
- int xoff, yoff;
- BoxPtr pBox;
- int nbox = REGION_NUM_RECTS(pRegion);
- if (!nbox)
+ if (REGION_NIL(pRegion))
return;
if (!pExaScr->swappedOut) {
@@ -1230,39 +1220,27 @@ exaPaintWindow(WindowPtr pWin, RegionPtr
case BackgroundPixel:
exaFillRegionSolid((DrawablePtr)pWin, pRegion, pWin->background.pixel,
FB_ALLONES, GXcopy);
- goto damage;
+ return;
case BackgroundPixmap:
exaFillRegionTiled((DrawablePtr)pWin, pRegion, pWin->background.pixmap,
&zeros, FB_ALLONES, GXcopy);
- goto damage;
+ return;
}
break;
case PW_BORDER:
if (pWin->borderIsPixel) {
exaFillRegionSolid((DrawablePtr)pWin, pRegion, pWin->border.pixel,
FB_ALLONES, GXcopy);
- goto damage;
+ return;
} else {
exaFillRegionTiled((DrawablePtr)pWin, pRegion, pWin->border.pixmap,
&zeros, FB_ALLONES, GXcopy);
- goto damage;
+ return;
}
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_unaccel.c b/exa/exa_unaccel.c
index 24d5e3f..970c2cb 100644
--- a/exa/exa_unaccel.c
+++ b/exa/exa_unaccel.c
@@ -105,7 +105,6 @@ ExaCheckPutImage (DrawablePtr pDrawable,
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 23da2c0da3817300272933de979572da0feaa698 (from 062f66818d7d125fada919b9f93b23d37b01a23f)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Thu Aug 30 13:48:03 2007 +0200
EXA: RENDER improvements.
Exclude bits that will be overwritten from migration.
Use exaGlyphs even when Composite can't be accelerated, to avoid PolyFillRect
roundtrip via offscreen memory.
Initialize mask pixmap in exaGlyphs in FB in addition to system if the driver
provides Composite hooks to avoid migration overhead.
Remove manual damage tracking where superfluous.
diff --git a/exa/exa.c b/exa/exa.c
index ad8d967..458272d 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -285,15 +285,19 @@ static Bool
exaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
int bitsPerPixel, int devKind, pointer pPixData)
{
- ExaScreenPriv(pPixmap->drawable.pScreen);
- ExaPixmapPriv(pPixmap);
+ ExaScreenPrivPtr pExaScr;
+ ExaPixmapPrivPtr pExaPixmap;
if (!pPixmap)
return FALSE;
+ pExaPixmap = ExaGetPixmapPriv(pPixmap);
+
if (pExaPixmap)
pExaPixmap->sys_ptr = pPixData;
+ pExaScr = ExaGetScreenPriv(pPixmap->drawable.pScreen);
+
return pExaScr->SavedModifyPixmapHeader(pPixmap, width, height, depth,
bitsPerPixel, devKind, pPixData);
}
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index db5bd02..a8bdbd6 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -384,6 +384,9 @@ exaCopyNtoN (DrawablePtr pSrcDrawable
void *closure);
/* exa_render.c */
+Bool
+exaOpReadsDestination (CARD8 op);
+
void
exaComposite(CARD8 op,
PicturePtr pSrc,
diff --git a/exa/exa_render.c b/exa/exa_render.c
index 3cfa81e..9df795f 100644
--- a/exa/exa_render.c
+++ b/exa/exa_render.c
@@ -111,7 +111,7 @@ exaPrintCompositeFallback(CARD8 op,
}
#endif /* DEBUG_TRACE_FALL */
-static Bool
+Bool
exaOpReadsDestination (CARD8 op)
{
/* FALSE (does not read destination) is the list of ops in the protocol
@@ -261,17 +261,21 @@ exaTryDriverSolidFill(PicturePtr pSrc,
width, height))
return 1;
+ pDstPix = exaGetDrawablePixmap (pDst->pDrawable);
+ exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &dst_off_x, &dst_off_y);
+
+ REGION_TRANSLATE(pScreen, ®ion, dst_off_x, dst_off_y);
+
pSrcPix = exaGetDrawablePixmap (pSrc->pDrawable);
pixel = exaGetPixmapFirstPixel (pSrcPix);
pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = FALSE;
- pixmaps[0].pPix = exaGetDrawablePixmap (pDst->pDrawable);
- pixmaps[0].pReg = NULL;
+ pixmaps[0].pPix = pDstPix;
+ pixmaps[0].pReg = ®ion;
exaDoMigration(pixmaps, 1, TRUE);
- pDstPix = exaGetOffscreenPixmap (pDst->pDrawable, &dst_off_x, &dst_off_y);
- if (!pDstPix) {
+ if (!exaPixmapIsOffscreen(pDstPix)) {
REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
return 0;
}
@@ -301,9 +305,7 @@ exaTryDriverSolidFill(PicturePtr pSrc,
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);
+ (*pExaScr->info->Solid) (pDstPix, pbox->x1, pbox->y1, pbox->x2, pbox->y2);
pbox++;
}
@@ -367,22 +369,26 @@ exaTryDriverComposite(CARD8 op,
xSrc += pSrc->pDrawable->x;
ySrc += pSrc->pDrawable->y;
- if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst,
- xSrc, ySrc, xMask, yMask, xDst, yDst,
- width, height))
- return 1;
-
if (pExaScr->info->CheckComposite &&
!(*pExaScr->info->CheckComposite) (op, pSrc, pMask, pDst))
{
- REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
return -1;
}
+ if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst,
+ xSrc, ySrc, xMask, yMask, xDst, yDst,
+ width, height))
+ return 1;
+
+ pDstPix = exaGetDrawablePixmap (pDst->pDrawable);
+ exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &dst_off_x, &dst_off_y);
+
+ REGION_TRANSLATE(pScreen, ®ion, dst_off_x, dst_off_y);
+
pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = exaOpReadsDestination(op);
- pixmaps[0].pPix = exaGetDrawablePixmap (pDst->pDrawable);
- pixmaps[0].pReg = NULL;
+ pixmaps[0].pPix = pDstPix;
+ pixmaps[0].pReg = pixmaps[0].as_src ? NULL : ®ion;
pixmaps[1].as_dst = FALSE;
pixmaps[1].as_src = TRUE;
pixmaps[1].pPix = exaGetDrawablePixmap (pSrc->pDrawable);
@@ -401,9 +407,8 @@ exaTryDriverComposite(CARD8 op,
if (pMask)
pMaskPix = exaGetOffscreenPixmap (pMask->pDrawable, &mask_off_x,
&mask_off_y);
- pDstPix = exaGetOffscreenPixmap (pDst->pDrawable, &dst_off_x, &dst_off_y);
- if (!pDstPix) {
+ if (!exaPixmapIsOffscreen(pDstPix)) {
REGION_UNINIT(pDst->pDrawable->pScreen, ®ion);
return 0;
}
@@ -433,21 +438,21 @@ exaTryDriverComposite(CARD8 op,
nbox = REGION_NUM_RECTS(®ion);
pbox = REGION_RECTS(®ion);
- xMask -= xDst;
- yMask -= yDst;
+ xMask = xMask + mask_off_x - xDst - dst_off_x;
+ yMask = yMask + mask_off_y - yDst - dst_off_y;
- xSrc -= xDst;
- ySrc -= yDst;
+ xSrc = xSrc + src_off_x - xDst - dst_off_x;
+ ySrc = ySrc + src_off_y - yDst - dst_off_y;
while (nbox--)
{
(*pExaScr->info->Composite) (pDstPix,
- pbox->x1 + xSrc + src_off_x,
- pbox->y1 + ySrc + src_off_y,
- pbox->x1 + xMask + mask_off_x,
- pbox->y1 + yMask + mask_off_y,
- pbox->x1 + dst_off_x,
- pbox->y1 + dst_off_y,
+ pbox->x1 + xSrc,
+ pbox->y1 + ySrc,
+ pbox->x1 + xMask,
+ pbox->y1 + yMask,
+ pbox->x1,
+ pbox->y1,
pbox->x2 - pbox->x1,
pbox->y2 - pbox->y1);
pbox++;
@@ -523,9 +528,6 @@ exaTryMagicTwoPassCompositeHelper(CARD8
CARD16 height)
{
ExaScreenPriv (pDst->pDrawable->pScreen);
- DrawablePtr pDstDraw = pDst->pDrawable;
- PixmapPtr pDstPixmap = exaGetDrawablePixmap(pDstDraw);
- int xoff, yoff;
assert(op == PictOpOver);
@@ -544,12 +546,6 @@ 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,
@@ -576,31 +572,8 @@ 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);
- pixmaps[0].pReg = NULL;
-
- if (pSrc->pDrawable) {
- pSrcPixmap = exaGetDrawablePixmap (pSrc->pDrawable);
- pixmaps[npixmaps].as_dst = FALSE;
- pixmaps[npixmaps].as_src = TRUE;
- pixmaps[npixmaps].pPix = pSrcPixmap;
- pixmaps[npixmaps].pReg = NULL;
- npixmaps++;
- }
-
- if (pMask && pMask->pDrawable) {
- pixmaps[npixmaps].as_dst = FALSE;
- pixmaps[npixmaps].as_src = TRUE;
- pixmaps[npixmaps].pPix = exaGetDrawablePixmap (pMask->pDrawable);
- pixmaps[npixmaps].pReg = NULL;
- npixmaps++;
- }
+ RegionRec region;
/* We currently don't support acceleration of gradients, or other pictures
* with a NULL pDrawable.
@@ -638,8 +611,6 @@ exaComposite(CARD8 op,
}
else if (pSrcPixmap && !pSrc->repeat && !pSrc->transform)
{
- RegionRec region;
-
xDst += pDst->pDrawable->x;
yDst += pDst->pDrawable->y;
xSrc += pSrc->pDrawable->x;
@@ -661,7 +632,6 @@ exaComposite(CARD8 op,
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 */
@@ -1092,6 +1062,9 @@ exaGlyphsIntersect(int nlist, GlyphListP
* issue is that miGlyphs' use of ModifyPixmapHeader makes it impossible to
* migrate these pixmaps. So, instead we create a pixmap at the beginning of
* the loop and upload each glyph into the pixmap before compositing.
+ *
+ * This is now used even when Composite can't be accelerated for better
+ * migration control.
*/
void
exaGlyphs (CARD8 op,
@@ -1108,11 +1081,10 @@ 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, x1, y1, xoff, yoff;
+ int x, y, x1, y1;
int xDst = list->xOff, yDst = list->yOff;
int n;
int error;
@@ -1140,16 +1112,6 @@ exaGlyphs (CARD8 op,
}
}
- /* If the driver doesn't support accelerated composite, there's no point in
- * going to this extra work. Assume that any driver that supports Composite
- * will be able to support component alpha using the two-pass helper.
- */
- if (!pExaScr->info->PrepareComposite)
- {
- miGlyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
- return;
- }
-
if (maskFormat)
{
GCPtr pGC;
@@ -1186,8 +1148,11 @@ exaGlyphs (CARD8 op,
rect.y = 0;
rect.width = width;
rect.height = height;
- (*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect);
- exaPixmapDirty(pMaskPixmap, 0, 0, width, height);
+ ExaCheckPolyFillRect (&pMaskPixmap->drawable, pGC, 1, &rect);
+ if (pExaScr->info->PrepareComposite)
+ (*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect);
+ else
+ exaPixmapDirty(pMaskPixmap, 0, 0, width, height);
FreeScratchGC (pGC);
x = -extents.x1;
y = -extents.y1;
@@ -1199,8 +1164,6 @@ exaGlyphs (CARD8 op,
y = 0;
}
- exaGetDrawableDeltas(pDst->pDrawable, pDstPixmap, &xoff, &yoff);
-
while (nlist--)
{
GCPtr pGC = NULL;
@@ -1339,10 +1302,6 @@ exaGlyphs (CARD8 op,
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;
diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c
index fbc48dd..24d5e3f 100644
--- a/exa/exa_unaccel.c
+++ b/exa/exa_unaccel.c
@@ -23,6 +23,10 @@
#include "exa_priv.h"
+#ifdef RENDER
+#include "mipict.h"
+#endif
+
/*
* These functions wrap the low-level fb rendering functions and
* synchronize framebuffer/accelerated drawing by stalling until
@@ -319,9 +323,30 @@ ExaCheckComposite (CARD8 op,
CARD16 width,
CARD16 height)
{
+ RegionRec region;
+ int xoff, yoff;
+
+ REGION_NULL(pScreen, ®ion);
+
+ if (!exaOpReadsDestination(op)) {
+ if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst,
+ xSrc, ySrc, xMask, yMask, xDst, yDst,
+ width, height))
+ return;
+
+ exaGetDrawableDeltas (pDst->pDrawable,
+ exaGetDrawablePixmap(pDst->pDrawable),
+ &xoff, &yoff);
+
+ REGION_TRANSLATE(pScreen, ®ion, xoff, yoff);
+
+ exaPrepareAccessReg (pDst->pDrawable, EXA_PREPARE_DEST, ®ion);
+ } else
+ exaPrepareAccess (pDst->pDrawable, EXA_PREPARE_DEST);
+
EXA_FALLBACK(("from picts %p/%p to pict %p\n",
pSrc, pMask, pDst));
- exaPrepareAccess (pDst->pDrawable, EXA_PREPARE_DEST);
+
if (pSrc->pDrawable != NULL)
exaPrepareAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
if (pMask && pMask->pDrawable != NULL)
@@ -343,6 +368,8 @@ ExaCheckComposite (CARD8 op,
if (pSrc->pDrawable != NULL)
exaFinishAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
exaFinishAccess (pDst->pDrawable, EXA_PREPARE_DEST);
+
+ REGION_UNINIT(pScreen, ®ion);
}
/**
diff-tree 062f66818d7d125fada919b9f93b23d37b01a23f (from eec06c0074f9744d524b27a29db65bba3e221229)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Thu Aug 30 13:44:20 2007 +0200
EXA: Improvements for 1x1 pixmaps.
Initialize system and FB copy in exaFillRegionSolid and adapt
exaGetPixmapFirstPixel to the new migration infrastructure.
This should mostly eliminate migration overhead for these, whether they are
used for acceleration or fallbacks.
diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index e9ca472..4cae198 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -1012,8 +1012,6 @@ exaFillRegionSolid (DrawablePtr pDrawabl
PixmapPtr pPixmap;
int xoff, yoff;
ExaMigrationRec pixmaps[1];
- int nbox = REGION_NUM_RECTS (pRegion);
- BoxPtr pBox = REGION_RECTS (pRegion);
pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = FALSE;
@@ -1031,15 +1029,43 @@ exaFillRegionSolid (DrawablePtr pDrawabl
if ((pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) &&
(*pExaScr->info->PrepareSolid) (pPixmap, alu, planemask, pixel))
{
+ int nbox;
+ BoxPtr pBox;
+
+ REGION_TRANSLATE(pScreen, pRegion, xoff, yoff);
+
+ nbox = REGION_NUM_RECTS (pRegion);
+ pBox = REGION_RECTS (pRegion);
+
while (nbox--)
{
- (*pExaScr->info->Solid) (pPixmap,
- pBox->x1 + xoff, pBox->y1 + yoff,
- pBox->x2 + xoff, pBox->y2 + yoff);
+ (*pExaScr->info->Solid) (pPixmap, pBox->x1, pBox->y1, pBox->x2,
+ pBox->y2);
pBox++;
}
(*pExaScr->info->DoneSolid) (pPixmap);
exaMarkSync(pDrawable->pScreen);
+
+ if (pDrawable->width == 1 && pDrawable->height == 1 &&
+ pDrawable->bitsPerPixel != 24) {
+ ExaPixmapPriv(pPixmap);
+
+ switch (pDrawable->bitsPerPixel) {
+ case 32:
+ *(CARD32*)pExaPixmap->sys_ptr = pixel;
+ break;
+ case 16:
+ *(CARD16*)pExaPixmap->sys_ptr = pixel;
+ break;
+ case 8:
+ *(CARD8*)pExaPixmap->sys_ptr = pixel;
+ }
+
+ REGION_UNION(pScreen, &pExaPixmap->validSys, &pExaPixmap->validSys,
+ pRegion);
+ }
+
+ REGION_TRANSLATE(pScreen, pRegion, -xoff, -yoff);
}
else
{
diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c
index 8dadd06..fbc48dd 100644
--- a/exa/exa_unaccel.c
+++ b/exa/exa_unaccel.c
@@ -358,16 +358,28 @@ exaGetPixmapFirstPixel (PixmapPtr pPixma
void *fb;
Bool need_finish = FALSE;
BoxRec box;
+ RegionRec migration;
ExaPixmapPriv (pPixmap);
+ Bool sys_valid = !miPointInRegion(&pExaPixmap->validSys, 0, 0, &box);
+ Bool damaged = miPointInRegion(DamageRegion(pExaPixmap->pDamage), 0, 0,
+ &box);
+ Bool offscreen = exaPixmapIsOffscreen(pPixmap);
fb = pExaPixmap->sys_ptr;
/* Try to avoid framebuffer readbacks */
- if (exaPixmapIsOffscreen(pPixmap) &&
- miPointInRegion(DamageRegion(pExaPixmap->pDamage), 0, 0, &box))
+ if ((!offscreen && !sys_valid && !damaged) ||
+ (offscreen && (!sys_valid || damaged)))
{
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = 1;
+ box.y2 = 1;
+ REGION_INIT(pScreen, &migration, &box, 1);
+
need_finish = TRUE;
- exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
+
+ exaPrepareAccessReg(&pPixmap->drawable, EXA_PREPARE_SRC, &migration);
fb = pPixmap->devPrivate.ptr;
}
@@ -383,8 +395,10 @@ exaGetPixmapFirstPixel (PixmapPtr pPixma
break;
}
- if (need_finish)
+ if (need_finish) {
exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
+ REGION_UNINIT(pScreen, &migration);
+ }
return pixel;
}
diff-tree eec06c0074f9744d524b27a29db65bba3e221229 (from 7b585e228d86321c6c86149913452225e5ad6189)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Thu Aug 30 13:37:53 2007 +0200
EXA: exaImageGlyphBlt improvements.
As we can't actually accelerate anything interesting here, just migrate out
once and call fbSolidBoxClipped instead of taking a round trip via offscreen
memory with exaSolidBoxClipped.
Reuse pending damage region for extents and to prevent any actual migration of
pixmap contents when we're overwriting the whole pending damage region.
Remove superfluous manual damage tracking.
diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index 1fd299e..e9ca472 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -816,97 +816,6 @@ out:
}
static void
-exaSolidBoxClipped (DrawablePtr pDrawable,
- RegionPtr pClip,
- FbBits pm,
- FbBits fg,
- int x1,
- int y1,
- int x2,
- int y2)
-{
- ExaScreenPriv (pDrawable->pScreen);
- PixmapPtr pPixmap;
- BoxPtr pbox;
- int nbox;
- int xoff, yoff;
- int partX1, partX2, partY1, partY2;
- ExaMigrationRec pixmaps[1];
- Bool fallback = FALSE;
-
- pixmaps[0].as_dst = TRUE;
- pixmaps[0].as_src = FALSE;
- pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable);
- pixmaps[0].pReg = NULL;
-
- if (pExaScr->swappedOut ||
- pPixmap->drawable.width > pExaScr->info->maxX ||
- pPixmap->drawable.height > pExaScr->info->maxY)
- {
- fallback = TRUE;
- } else {
- exaDoMigration (pixmaps, 1, TRUE);
- }
-
- exaGetDrawableDeltas (pDrawable, pPixmap, &xoff, &yoff);
-
- if (fallback || !exaPixmapIsOffscreen(pPixmap) ||
- !(*pExaScr->info->PrepareSolid) (pPixmap, GXcopy, pm, fg))
- {
- EXA_FALLBACK(("to %p (%c)\n", pDrawable,
- exaDrawableLocation(pDrawable)));
- fallback = TRUE;
- exaPrepareAccessReg (pDrawable, EXA_PREPARE_DEST, pixmaps[0].pReg);
- fg = fbReplicatePixel (fg, pDrawable->bitsPerPixel);
- fbSolidBoxClipped (pDrawable, pClip, x1, y1, x2, y2,
- fbAnd (GXcopy, fg, pm),
- fbXor (GXcopy, fg, pm));
- exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
- }
- for (nbox = REGION_NUM_RECTS(pClip), pbox = REGION_RECTS(pClip);
- nbox--;
- pbox++)
- {
- partX1 = pbox->x1;
- if (partX1 < x1)
- partX1 = x1;
-
- partX2 = pbox->x2;
- if (partX2 > x2)
- partX2 = x2;
-
- if (partX2 <= partX1)
- continue;
-
- partY1 = pbox->y1;
- if (partY1 < y1)
- partY1 = y1;
-
- partY2 = pbox->y2;
- if (partY2 > y2)
- partY2 = y2;
-
- if (partY2 <= partY1)
- continue;
-
- if (!fallback) {
- (*pExaScr->info->Solid) (pPixmap,
- partX1 + xoff, partY1 + yoff,
- partX2 + xoff, partY2 + yoff);
- }
-
- exaPixmapDirty (pPixmap, partX1 + xoff, partY1 + yoff, partX2 + xoff,
- partY2 + yoff);
- }
-
- if (fallback)
- return;
-
- (*pExaScr->info->DoneSolid) (pPixmap);
- exaMarkSync(pDrawable->pScreen);
-}
-
-static void
exaImageGlyphBlt (DrawablePtr pDrawable,
GCPtr pGC,
int x,
@@ -922,7 +831,6 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
int gWidth, gHeight; /* width and height of glyph */
FbStride gStride; /* stride of glyph */
Bool opaque;
- int n;
int gx, gy;
void (*glyph) (FbBits *,
FbStride,
@@ -936,37 +844,33 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
int dstBpp;
int dstXoff, dstYoff;
FbBits depthMask;
+ Bool fallback;
PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
+ ExaPixmapPriv(pPixmap);
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);
+ RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
+ BoxRec extents = *REGION_EXTENTS(pScreen, pending_damage);
+ int xoff, yoff;
- if (xBack >= pDrawable->width || yBack >= pDrawable->height ||
- (xBack + widthBack) <= 0 || (yBack + heightBack) <= 0)
+ if (extents.x1 >= extents.x2 || extents.y1 >= extents.y2)
return;
+ depthMask = FbFullMask(pDrawable->depth);
+ fallback = (pGC->planemask & depthMask) != depthMask;
+
pixmaps[0].as_dst = TRUE;
- pixmaps[0].as_src = TRUE;
+ pixmaps[0].as_src = FALSE;
pixmaps[0].pPix = pPixmap;
- pixmaps[0].pReg = NULL;
+ pixmaps[0].pReg = fallback ? NULL : pending_damage;
- depthMask = FbFullMask(pDrawable->depth);
- if ((pGC->planemask & depthMask) != depthMask)
+ exaDoMigration(pixmaps, 1, FALSE);
+
+ if (fallback)
{
ExaCheckImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppciInit, pglyphBase);
- goto damage;
+ return;
}
+
glyph = NULL;
switch (pDrawable->bitsPerPixel) {
case 8: glyph = fbGlyph8; break;
@@ -977,8 +881,14 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
x += pDrawable->x;
y += pDrawable->y;
- xBack += pDrawable->x;
- yBack += pDrawable->y;
+
+ exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
+ extents.x1 -= xoff;
+ extents.x2 -= xoff;
+ extents.y1 -= yoff;
+ extents.y2 -= yoff;
+
+ exaPrepareAccessReg (pDrawable, EXA_PREPARE_DEST, pixmaps[0].pReg);
if (TERMINALFONT (pGC->font) && !glyph)
{
@@ -986,19 +896,22 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
}
else
{
- exaSolidBoxClipped (pDrawable,
- fbGetCompositeClip(pGC),
- pGC->planemask,
- pGC->bgPixel,
- xBack,
- yBack,
- xBack + widthBack,
- yBack + heightBack);
+ FbBits fg = fbReplicatePixel (pGC->bgPixel, pDrawable->bitsPerPixel);
+
+ fbSolidBoxClipped (pDrawable,
+ fbGetCompositeClip(pGC),
+ extents.x1,
+ extents.y1,
+ extents.x2,
+ extents.y2,
+ fbAnd (GXcopy, fg, pGC->planemask),
+ fbXor (GXcopy, fg, pGC->planemask));
+
opaque = FALSE;
}
EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
- exaPrepareAccessReg (pDrawable, EXA_PREPARE_DEST, pixmaps[0].pReg);
+
exaPrepareAccessGC (pGC);
fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
@@ -1011,9 +924,9 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
gx = x + pci->metrics.leftSideBearing;
gy = y - pci->metrics.ascent;
- if (!gWidth || !gHeight || (gx + gWidth) <= xBack ||
- (gy + gHeight) <= yBack || gx >= (xBack + widthBack) ||
- gy >= (yBack + heightBack))
+ if (!gWidth || !gHeight || (gx + gWidth) <= extents.x1 ||
+ (gy + gHeight) <= extents.y1 || gx >= extents.x2 ||
+ gy >= extents.y2)
continue;
pglyph = FONTGLYPHBITS(pglyphBase, pci);
@@ -1036,11 +949,6 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
}
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 7b585e228d86321c6c86149913452225e5ad6189 (from 0b342aa682a5aac383b674a15c937735ae7047b2)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Thu Aug 30 13:30:03 2007 +0200
EXA: Improvements for trapezoids and triangles.
Only migrate once in exaTrapezoids/Triangles instead of every time in
exaRasterizeTrapezoid/AddTriangles. Adapt manual damage tracking to new
infrastructure.
Also move definition of NeedsComponent() closer to where it's used.
diff --git a/exa/exa.c b/exa/exa.c
index 5a85037..ad8d967 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -766,11 +766,8 @@ exaDriverInit (ScreenPtr pScreen,
pExaScr->SavedComposite = ps->Composite;
ps->Composite = exaComposite;
- pExaScr->SavedRasterizeTrapezoid = ps->RasterizeTrapezoid;
- ps->RasterizeTrapezoid = exaRasterizeTrapezoid;
-
- pExaScr->SavedAddTriangles = ps->AddTriangles;
- ps->AddTriangles = exaAddTriangles;
+ pExaScr->SavedTriangles = ps->Triangles;
+ ps->Triangles = exaTriangles;
pExaScr->SavedGlyphs = ps->Glyphs;
ps->Glyphs = exaGlyphs;
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index da5e459..db5bd02 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -111,8 +111,7 @@ typedef struct {
ModifyPixmapHeaderProcPtr SavedModifyPixmapHeader;
#ifdef RENDER
CompositeProcPtr SavedComposite;
- RasterizeTrapezoidProcPtr SavedRasterizeTrapezoid;
- AddTrianglesProcPtr SavedAddTriangles;
+ TrianglesProcPtr SavedTriangles;
GlyphsProcPtr SavedGlyphs;
TrapezoidsProcPtr SavedTrapezoids;
#endif
@@ -405,12 +404,9 @@ exaTrapezoids (CARD8 op, PicturePtr pSrc
int ntrap, xTrapezoid *traps);
void
-exaRasterizeTrapezoid (PicturePtr pPicture, xTrapezoid *trap,
- int x_off, int y_off);
-
-void
-exaAddTriangles (PicturePtr pPicture, INT16 x_off, INT16 y_off, int ntri,
- xTriangle *tris);
+exaTriangles (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+ PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+ int ntri, xTriangle *tris);
void
exaGlyphs (CARD8 op,
diff --git a/exa/exa_render.c b/exa/exa_render.c
index 067f88b..3cfa81e 100644
--- a/exa/exa_render.c
+++ b/exa/exa_render.c
@@ -760,7 +760,7 @@ done:
* of PolyFillRect to initialize the pixmap after creating it, to prevent
* the pixmap from being migrated.
*
- * See the comments about exaTrapezoids.
+ * See the comments about exaTrapezoids and exaTriangles.
*/
static PicturePtr
exaCreateAlphaPicture (ScreenPtr pScreen,
@@ -832,36 +832,70 @@ exaTrapezoids (CARD8 op, PicturePtr pSrc
{
ScreenPtr pScreen = pDst->pDrawable->pScreen;
PictureScreenPtr ps = GetPictureScreen(pScreen);
+ BoxRec bounds;
+ Bool direct = op == PictOpAdd && miIsSolidAlpha (pSrc);
+
+ if (maskFormat || direct) {
+ miTrapezoidBounds (ntrap, traps, &bounds);
+
+ if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
+ return;
+ }
/*
* Check for solid alpha add
*/
- if (op == PictOpAdd && miIsSolidAlpha (pSrc))
+ if (direct)
{
+ DrawablePtr pDraw = pDst->pDrawable;
+ PixmapPtr pixmap = exaGetDrawablePixmap (pDraw);
+ ExaPixmapPriv (pixmap);
+ RegionRec migration;
+ RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
+ int xoff, yoff;
+
+ exaGetDrawableDeltas(pDraw, pixmap, &xoff, &yoff);
+
+ xoff += pDraw->x;
+ yoff += pDraw->y;
+
+ bounds.x1 += xoff;
+ bounds.y1 += yoff;
+ bounds.x2 += xoff;
+ bounds.y2 += yoff;
+
+ REGION_INIT(pScreen, &migration, &bounds, 1);
+ REGION_UNION(pScreen, pending_damage, pending_damage, &migration);
+ REGION_UNINIT(pScreen, &migration);
+
+ exaPrepareAccess(pDraw, EXA_PREPARE_DEST);
+
for (; ntrap; ntrap--, traps++)
(*ps->RasterizeTrapezoid) (pDst, traps, 0, 0);
+
+ exaFinishAccess(pDraw, EXA_PREPARE_DEST);
}
else if (maskFormat)
{
PicturePtr pPicture;
- BoxRec bounds;
INT16 xDst, yDst;
INT16 xRel, yRel;
xDst = traps[0].left.p1.x >> 16;
yDst = traps[0].left.p1.y >> 16;
- miTrapezoidBounds (ntrap, traps, &bounds);
- if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
- return;
pPicture = exaCreateAlphaPicture (pScreen, pDst, maskFormat,
bounds.x2 - bounds.x1,
bounds.y2 - bounds.y1);
if (!pPicture)
return;
+
+ exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
for (; ntrap; ntrap--, traps++)
(*ps->RasterizeTrapezoid) (pPicture, traps,
-bounds.x1, -bounds.y1);
+ exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
+
xRel = bounds.x1 + xSrc - xDst;
yRel = bounds.y1 + ySrc - yDst;
CompositePicture (op, pSrc, pPicture, pDst,
@@ -881,51 +915,102 @@ exaTrapezoids (CARD8 op, PicturePtr pSrc
}
}
-#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
-
/**
- * exaRasterizeTrapezoid is just a wrapper around the software implementation.
+ * exaTriangles is essentially a copy of miTriangles that uses
+ * exaCreateAlphaPicture instead of miCreateAlphaPicture.
*
- * The trapezoid specification is basically too hard to be done in hardware (at
- * the very least, without programmability), so we just do the appropriate
- * Prepare/FinishAccess for it before using fbtrap.c.
+ * The problem with miCreateAlphaPicture is that it calls PolyFillRect
+ * to initialize the contents after creating the pixmap, which
+ * causes the pixmap to be moved in for acceleration. The subsequent
+ * call to AddTriangles won't be accelerated however, which forces the pixmap
+ * to be moved out again.
+ *
+ * exaCreateAlphaPicture avoids this roundtrip by using ExaCheckPolyFillRect
+ * to initialize the contents.
*/
void
-exaRasterizeTrapezoid (PicturePtr pPicture, xTrapezoid *trap,
- int x_off, int y_off)
+exaTriangles (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+ PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc,
+ int ntri, xTriangle *tris)
{
- DrawablePtr pDraw = pPicture->pDrawable;
- PixmapPtr pPixmap = exaGetDrawablePixmap(pDraw);
- int xoff, yoff;
-
- exaPrepareAccess(pDraw, EXA_PREPARE_DEST);
- fbRasterizeTrapezoid(pPicture, trap, x_off, y_off);
- exaGetDrawableDeltas(pDraw, pPixmap, &xoff, &yoff);
- exaPixmapDirty(pPixmap, pDraw->x + xoff, pDraw->y + yoff,
- pDraw->x + xoff + pDraw->width,
- pDraw->y + yoff + pDraw->height);
- exaFinishAccess(pDraw, EXA_PREPARE_DEST);
-}
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ BoxRec bounds;
+ Bool direct = op == PictOpAdd && miIsSolidAlpha (pSrc);
-/**
- * exaAddTriangles does migration and syncing before dumping down to the
- * software implementation.
- */
-void
-exaAddTriangles (PicturePtr pPicture, INT16 x_off, INT16 y_off, int ntri,
- xTriangle *tris)
-{
- DrawablePtr pDraw = pPicture->pDrawable;
- PixmapPtr pPixmap = exaGetDrawablePixmap(pDraw);
- int xoff, yoff;
-
- exaPrepareAccess(pDraw, EXA_PREPARE_DEST);
- fbAddTriangles(pPicture, x_off, y_off, ntri, tris);
- exaGetDrawableDeltas(pDraw, pPixmap, &xoff, &yoff);
- exaPixmapDirty(pPixmap, pDraw->x + xoff, pDraw->y + yoff,
- pDraw->x + xoff + pDraw->width,
- pDraw->y + yoff + pDraw->height);
- exaFinishAccess(pDraw, EXA_PREPARE_DEST);
+ if (maskFormat || direct) {
+ miTriangleBounds (ntri, tris, &bounds);
+
+ if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
+ return;
+ }
+
+ /*
+ * Check for solid alpha add
+ */
+ if (direct)
+ {
+ DrawablePtr pDraw = pDst->pDrawable;
+ PixmapPtr pixmap = exaGetDrawablePixmap (pDraw);
+ ExaPixmapPriv (pixmap);
+ RegionRec migration;
+ RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
+ int xoff, yoff;
+
+ exaGetDrawableDeltas(pDraw, pixmap, &xoff, &yoff);
+
+ xoff += pDraw->x;
+ yoff += pDraw->y;
+
+ bounds.x1 += xoff;
+ bounds.y1 += yoff;
+ bounds.x2 += xoff;
+ bounds.y2 += yoff;
+
+ REGION_INIT(pScreen, &migration, &bounds, 1);
+ REGION_UNION(pScreen, pending_damage, pending_damage, &migration);
+ REGION_UNINIT(pScreen, &migration);
+
+ exaPrepareAccess(pDraw, EXA_PREPARE_DEST);
+ (*ps->AddTriangles) (pDst, 0, 0, ntri, tris);
+ exaFinishAccess(pDraw, EXA_PREPARE_DEST);
+ }
+ else if (maskFormat)
+ {
+ PicturePtr pPicture;
+ INT16 xDst, yDst;
+ INT16 xRel, yRel;
+
+ xDst = tris[0].p1.x >> 16;
+ yDst = tris[0].p1.y >> 16;
+
+ pPicture = exaCreateAlphaPicture (pScreen, pDst, maskFormat,
+ bounds.x2 - bounds.x1,
+ bounds.y2 - bounds.y1);
+ if (!pPicture)
+ return;
+
+ exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
+ (*ps->AddTriangles) (pPicture, -bounds.x1, -bounds.y1, ntri, tris);
+ exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
+
+ xRel = bounds.x1 + xSrc - xDst;
+ yRel = bounds.y1 + ySrc - yDst;
+ CompositePicture (op, pSrc, pPicture, pDst,
+ xRel, yRel, 0, 0, bounds.x1, bounds.y1,
+ bounds.x2 - bounds.x1, bounds.y2 - bounds.y1);
+ FreePicture (pPicture, 0);
+ }
+ else
+ {
+ if (pDst->polyEdge == PolyEdgeSharp)
+ maskFormat = PictureMatchFormat (pScreen, 1, PICT_a1);
+ else
+ maskFormat = PictureMatchFormat (pScreen, 8, PICT_a8);
+
+ for (; ntri; ntri--, tris++)
+ exaTriangles (op, pSrc, pDst, maskFormat, xSrc, ySrc, 1, tris);
+ }
}
/**
@@ -1001,6 +1086,8 @@ exaGlyphsIntersect(int nlist, GlyphListP
return FALSE;
}
+#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0)
+
/* exaGlyphs is a slight variation on miGlyphs, to support acceleration. The
* issue is that miGlyphs' use of ModifyPixmapHeader makes it impossible to
* migrate these pixmaps. So, instead we create a pixmap at the beginning of
diff-tree 0b342aa682a5aac383b674a15c937735ae7047b2 (from 320777ddecbe9f5933eb759678204d2cdd8fe289)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Thu Sep 6 13:10:16 2007 +0200
EXA: Hide pixmap pointer outside of exaPrepare/FinishAccess whenever possible.
We finally want to catch all cases where the pixmap pointer is dereferenced
outside of exaPrepare/FinishAccess.
Also fix a couple of such cases exposed by this change.
diff --git a/exa/exa.c b/exa/exa.c
index 145d5b2..5a85037 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -44,6 +44,17 @@ static int exaGeneration;
int exaScreenPrivateIndex;
int exaPixmapPrivateIndex;
+static _X_INLINE void*
+ExaGetPixmapAddress(PixmapPtr p)
+{
+ ExaPixmapPriv(p);
+
+ if (pExaPixmap->offscreen && pExaPixmap->fb_ptr)
+ return pExaPixmap->fb_ptr;
+ else
+ return pExaPixmap->sys_ptr;
+}
+
/**
* exaGetPixmapOffset() returns the offset (in bytes) within the framebuffer of
* the beginning of the given pixmap.
@@ -58,16 +69,9 @@ unsigned long
exaGetPixmapOffset(PixmapPtr pPix)
{
ExaScreenPriv (pPix->drawable.pScreen);
- ExaPixmapPriv (pPix);
- void *ptr;
- /* Return the offscreen pointer if we've hidden the data. */
- if (pPix->devPrivate.ptr == NULL)
- ptr = pExaPixmap->fb_ptr;
- else
- ptr = pPix->devPrivate.ptr;
-
- return ((unsigned long)ptr - (unsigned long)pExaScr->info->memoryBase);
+ return ((unsigned long)ExaGetPixmapAddress(pPix) -
+ (unsigned long)pExaScr->info->memoryBase);
}
/**
@@ -241,6 +245,9 @@ exaCreatePixmap(ScreenPtr pScreen, int w
pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr;
pExaPixmap->sys_pitch = pPixmap->devKind;
+ pPixmap->devPrivate.ptr = NULL;
+ pExaPixmap->offscreen = FALSE;
+
pExaPixmap->fb_ptr = NULL;
if (pExaScr->info->flags & EXA_OFFSCREEN_ALIGN_POT && w != 1)
pExaPixmap->fb_pitch = (1 << (exaLog2(w - 1) + 1)) * bpp / 8;
@@ -274,6 +281,23 @@ exaCreatePixmap(ScreenPtr pScreen, int w
return pPixmap;
}
+static Bool
+exaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
+ int bitsPerPixel, int devKind, pointer pPixData)
+{
+ ExaScreenPriv(pPixmap->drawable.pScreen);
+ ExaPixmapPriv(pPixmap);
+
+ if (!pPixmap)
+ return FALSE;
+
+ if (pExaPixmap)
+ pExaPixmap->sys_ptr = pPixData;
+
+ return pExaScr->SavedModifyPixmapHeader(pPixmap, width, height, depth,
+ bitsPerPixel, devKind, pPixData);
+}
+
/**
* exaPixmapIsOffscreen() is used to determine if a pixmap is in offscreen
* memory, meaning that acceleration could probably be done to it, and that it
@@ -291,18 +315,25 @@ exaPixmapIsOffscreen(PixmapPtr p)
{
ScreenPtr pScreen = p->drawable.pScreen;
ExaScreenPriv(pScreen);
+ ExaPixmapPriv(p);
+ void *save_ptr;
+ Bool ret;
- /* If the devPrivate.ptr is NULL, it's offscreen but we've hidden the data.
- */
- if (p->devPrivate.ptr == NULL)
- return TRUE;
+ save_ptr = p->devPrivate.ptr;
+
+ if (!save_ptr && pExaPixmap)
+ p->devPrivate.ptr = ExaGetPixmapAddress(p);
if (pExaScr->info->PixmapIsOffscreen)
- return pExaScr->info->PixmapIsOffscreen(p);
+ ret = pExaScr->info->PixmapIsOffscreen(p);
+ else
+ ret = ((unsigned long) ((CARD8 *) p->devPrivate.ptr -
+ (CARD8 *) pExaScr->info->memoryBase) <
+ pExaScr->info->memorySize);
+
+ p->devPrivate.ptr = save_ptr;
- return ((unsigned long) ((CARD8 *) p->devPrivate.ptr -
- (CARD8 *) pExaScr->info->memoryBase) <
- pExaScr->info->memorySize);
+ return ret;
}
/**
@@ -336,22 +367,19 @@ ExaDoPrepareAccess(DrawablePtr pDrawable
{
ScreenPtr pScreen = pDrawable->pScreen;
ExaScreenPriv (pScreen);
- PixmapPtr pPixmap;
-
- pPixmap = exaGetDrawablePixmap (pDrawable);
-
- if (exaPixmapIsOffscreen (pPixmap))
- exaWaitSync (pDrawable->pScreen);
- else
- return;
+ PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable);
+ Bool offscreen = exaPixmapIsOffscreen(pPixmap);
/* Unhide pixmap pointer */
if (pPixmap->devPrivate.ptr == NULL) {
- ExaPixmapPriv (pPixmap);
-
- pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
+ pPixmap->devPrivate.ptr = ExaGetPixmapAddress(pPixmap);
}
+ if (!offscreen)
+ return;
+
+ exaWaitSync (pDrawable->pScreen);
+
if (pExaScr->info->PrepareAccess == NULL)
return;
@@ -400,18 +428,13 @@ exaFinishAccess(DrawablePtr pDrawable, i
{
ScreenPtr pScreen = pDrawable->pScreen;
ExaScreenPriv (pScreen);
- PixmapPtr pPixmap;
- ExaPixmapPrivPtr pExaPixmap;
-
- pPixmap = exaGetDrawablePixmap (pDrawable);
-
- pExaPixmap = ExaGetPixmapPriv(pPixmap);
+ PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable);
+ ExaPixmapPriv (pPixmap);
/* Rehide pixmap pointer if we're doing that. */
- if (pExaPixmap != NULL && pExaScr->hideOffscreenPixmapData &&
- pExaPixmap->fb_ptr == pPixmap->devPrivate.ptr)
+ if (pExaPixmap)
{
- pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
+ pPixmap->devPrivate.ptr = NULL;
}
if (pExaScr->info->FinishAccess == NULL)
@@ -783,6 +806,8 @@ exaDriverInit (ScreenPtr pScreen,
pExaScr->SavedDestroyPixmap = pScreen->DestroyPixmap;
pScreen->DestroyPixmap = exaDestroyPixmap;
+ pExaScr->SavedModifyPixmapHeader = pScreen->ModifyPixmapHeader;
+ pScreen->ModifyPixmapHeader = exaModifyPixmapHeader;
LogMessage(X_INFO, "EXA(%d): Offscreen pixmap area of %d bytes\n",
pScreen->myNum,
pExaScr->info->memorySize - pExaScr->info->offScreenBase);
diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index ceb6c7b..1fd299e 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -213,8 +213,7 @@ exaDoPutImage (DrawablePtr pDrawable, GC
int dstXoff, dstYoff;
if (!access_prepared) {
- exaPrepareAccessReg(pDrawable, EXA_PREPARE_DEST,
- pixmaps[0].pReg);
+ ExaDoPrepareAccess(pDrawable, EXA_PREPARE_DEST);
access_prepared = TRUE;
}
@@ -233,14 +232,14 @@ exaDoPutImage (DrawablePtr pDrawable, GC
GXcopy, FB_ALLONES, dstBpp);
}
- if (access_prepared)
- exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
- else
- exaMarkSync(pDrawable->pScreen);
-
exaPixmapDirty(pixmaps[0].pPix, x1 + xoff, y1 + yoff, x2 + xoff, y2 + yoff);
}
+ if (access_prepared)
+ exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
+ else
+ exaMarkSync(pDrawable->pScreen);
+
return TRUE;
fallback:
@@ -271,8 +270,10 @@ exaShmPutImage(DrawablePtr pDrawable, GC
src_stride))
return;
+ exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
fbShmPutImage(pDrawable, pGC, depth, format, w, h, sx, sy, sw, sh, dx, dy,
data);
+ exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
}
ShmFuncs exaShmFuncs = { NULL, exaShmPutImage };
diff --git a/exa/exa_migration.c b/exa/exa_migration.c
index f48e93a..ace9076 100644
--- a/exa/exa_migration.c
+++ b/exa/exa_migration.c
@@ -323,10 +323,8 @@ exaDoMoveInPixmap (ExaMigrationPtr migra
pPixmap->drawable.height,
exaPixmapIsDirty(pPixmap) ? 'd' : 'c'));
- if (pExaScr->hideOffscreenPixmapData)
- pPixmap->devPrivate.ptr = NULL;
- else
- pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
+ pExaPixmap->offscreen = TRUE;
+
pPixmap->devKind = pExaPixmap->fb_pitch;
pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
}
@@ -365,7 +363,8 @@ exaDoMoveOutPixmap (ExaMigrationPtr migr
pPixmap->drawable.height,
exaPixmapIsDirty(pPixmap) ? 'd' : 'c'));
- pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
+ pExaPixmap->offscreen = FALSE;
+
pPixmap->devKind = pExaPixmap->sys_pitch;
pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
}
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index 491d80b..da5e459 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -108,6 +108,7 @@ typedef struct {
CopyWindowProcPtr SavedCopyWindow;
ChangeWindowAttributesProcPtr SavedChangeWindowAttributes;
BitmapToRegionProcPtr SavedBitmapToRegion;
+ ModifyPixmapHeaderProcPtr SavedModifyPixmapHeader;
#ifdef RENDER
CompositeProcPtr SavedComposite;
RasterizeTrapezoidProcPtr SavedRasterizeTrapezoid;
@@ -118,7 +119,6 @@ typedef struct {
Bool swappedOut;
enum ExaMigrationHeuristic migration;
- Bool hideOffscreenPixmapData;
Bool checkDirtyCorrectness;
unsigned disableFbCount;
} ExaScreenPrivRec, *ExaScreenPrivPtr;
@@ -160,6 +160,7 @@ extern int exaPixmapPrivateIndex;
typedef struct {
ExaOffscreenArea *area;
int score; /**< score for the move-in vs move-out heuristic */
+ Bool offscreen;
CARD8 *sys_ptr; /**< pointer to pixmap data in system memory */
int sys_pitch; /**< pitch of pixmap in system memory */
diff-tree 320777ddecbe9f5933eb759678204d2cdd8fe289 (from 19ca0ab22f9bd5a29716259ac230fee62c1afc10)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Wed Aug 29 19:55:22 2007 +0200
EXA: Support partial migration of pixmap contents between Sys and FB.
The initiator of migration can pass in a region that defines the relevant area
of each source pixmap or the irrelevant area of the destination pixmap. By
default, the pending damage region is assumed relevant for the destination
pixmap, and everything for source pixmaps.
Thanks to Jarno Manninen for reassuring me that my own ideas for this were
feasible and for providing additional ideas.
diff --git a/exa/exa.c b/exa/exa.c
index ecdb761..145d5b2 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -363,20 +363,15 @@ ExaDoPrepareAccess(DrawablePtr pDrawable
}
}
-/**
- * exaPrepareAccess() is EXA's wrapper for the driver's PrepareAccess() handler.
- *
- * It deals with waiting for synchronization with the card, determining if
- * PrepareAccess() is necessary, and working around PrepareAccess() failure.
- */
void
-exaPrepareAccess(DrawablePtr pDrawable, int index)
+exaPrepareAccessReg(DrawablePtr pDrawable, int index, RegionPtr pReg)
{
ExaMigrationRec pixmaps[1];
pixmaps[0].as_dst = index == EXA_PREPARE_DEST;
pixmaps[0].as_src = index != EXA_PREPARE_DEST;
pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable);
+ pixmaps[0].pReg = pReg;
exaDoMigration(pixmaps, 1, FALSE);
@@ -384,6 +379,18 @@ exaPrepareAccess(DrawablePtr pDrawable,
}
/**
+ * exaPrepareAccess() is EXA's wrapper for the driver's PrepareAccess() handler.
+ *
+ * It deals with waiting for synchronization with the card, determining if
+ * PrepareAccess() is necessary, and working around PrepareAccess() failure.
+ */
+void
+exaPrepareAccess(DrawablePtr pDrawable, int index)
+{
+ exaPrepareAccessReg(pDrawable, index, NULL);
+}
+
+/**
* exaFinishAccess() is EXA's wrapper for the driver's FinishAccess() handler.
*
* It deals with calling the driver's FinishAccess() only if necessary.
diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index 07ada15..ceb6c7b 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -55,6 +55,7 @@ exaFillSpans(DrawablePtr pDrawable, GCPt
pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = FALSE;
pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable);
+ pixmaps[0].pReg = NULL;
if (pExaScr->swappedOut ||
pGC->fillStyle != FillSolid ||
@@ -153,6 +154,7 @@ exaDoPutImage (DrawablePtr pDrawable, GC
pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = FALSE;
pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable);
+ pixmaps[0].pReg = NULL;
/* Don't bother with under 8bpp, XYPixmaps. */
if (format != ZPixmap || bpp < 8)
@@ -211,7 +213,8 @@ exaDoPutImage (DrawablePtr pDrawable, GC
int dstXoff, dstYoff;
if (!access_prepared) {
- exaPrepareAccess(pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccessReg(pDrawable, EXA_PREPARE_DEST,
+ pixmaps[0].pReg);
access_prepared = TRUE;
}
@@ -232,6 +235,8 @@ exaDoPutImage (DrawablePtr pDrawable, GC
if (access_prepared)
exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
+ else
+ exaMarkSync(pDrawable->pScreen);
exaPixmapDirty(pixmaps[0].pPix, x1 + xoff, y1 + yoff, x2 + xoff, y2 + yoff);
}
@@ -420,9 +425,11 @@ exaCopyNtoN (DrawablePtr pSrcDrawable
pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = FALSE;
pixmaps[0].pPix = pDstPixmap = exaGetDrawablePixmap (pDstDrawable);
+ pixmaps[0].pReg = NULL;
pixmaps[1].as_dst = FALSE;
pixmaps[1].as_src = TRUE;
pixmaps[1].pPix = pSrcPixmap = exaGetDrawablePixmap (pSrcDrawable);
+ pixmaps[1].pReg = NULL;
/* Respect maxX/maxY in a trivial way: don't set up drawing when we might
* violate the limits. The proper solution would be a temporary pixmap
@@ -463,7 +470,7 @@ exaCopyNtoN (DrawablePtr pSrcDrawable
EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrcDrawable, pDstDrawable,
exaDrawableLocation(pSrcDrawable),
exaDrawableLocation(pDstDrawable)));
- exaPrepareAccess (pDstDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccessReg (pDstDrawable, EXA_PREPARE_DEST, pixmaps[0].pReg);
exaPrepareAccess (pSrcDrawable, EXA_PREPARE_SRC);
fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
pbox, nbox, dx, dy, reverse, upsidedown,
@@ -682,7 +689,8 @@ exaPolyFillRect(DrawablePtr pDrawable,
pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = FALSE;
pixmaps[0].pPix = pPixmap;
-
+ pixmaps[0].pReg = NULL;
+
exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
if (pExaScr->swappedOut ||
@@ -828,6 +836,7 @@ exaSolidBoxClipped (DrawablePtr pDrawabl
pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = FALSE;
pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable);
+ pixmaps[0].pReg = NULL;
if (pExaScr->swappedOut ||
pPixmap->drawable.width > pExaScr->info->maxX ||
@@ -846,7 +855,7 @@ exaSolidBoxClipped (DrawablePtr pDrawabl
EXA_FALLBACK(("to %p (%c)\n", pDrawable,
exaDrawableLocation(pDrawable)));
fallback = TRUE;
- exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccessReg (pDrawable, EXA_PREPARE_DEST, pixmaps[0].pReg);
fg = fbReplicatePixel (fg, pDrawable->bitsPerPixel);
fbSolidBoxClipped (pDrawable, pClip, x1, y1, x2, y2,
fbAnd (GXcopy, fg, pm),
@@ -949,6 +958,7 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = TRUE;
pixmaps[0].pPix = pPixmap;
+ pixmaps[0].pReg = NULL;
depthMask = FbFullMask(pDrawable->depth);
if ((pGC->planemask & depthMask) != depthMask)
@@ -987,7 +997,7 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
}
EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
- exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccessReg (pDrawable, EXA_PREPARE_DEST, pixmaps[0].pReg);
exaPrepareAccessGC (pGC);
fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
@@ -1099,7 +1109,8 @@ exaFillRegionSolid (DrawablePtr pDrawabl
pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = FALSE;
pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable);
-
+ pixmaps[0].pReg = NULL;
+
if (pPixmap->drawable.width > pExaScr->info->maxX ||
pPixmap->drawable.height > pExaScr->info->maxY)
{
@@ -1128,7 +1139,7 @@ fallback:
return FALSE;
EXA_FALLBACK(("to %p (%c)\n", pDrawable,
exaDrawableLocation(pDrawable)));
- exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccessReg (pDrawable, EXA_PREPARE_DEST, pixmaps[0].pReg);
fbFillRegionSolid (pDrawable, pRegion, 0,
fbReplicatePixel (pixel, pDrawable->bitsPerPixel));
exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
@@ -1170,9 +1181,11 @@ exaFillRegionTiled (DrawablePtr pDrawabl
pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = FALSE;
pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable);
+ pixmaps[0].pReg = NULL;
pixmaps[1].as_dst = FALSE;
pixmaps[1].as_src = TRUE;
pixmaps[1].pPix = pTile;
+ pixmaps[1].pReg = NULL;
if (pPixmap->drawable.width > pExaScr->info->maxX ||
pPixmap->drawable.height > pExaScr->info->maxY ||
@@ -1243,7 +1256,7 @@ fallback:
EXA_FALLBACK(("from %p to %p (%c,%c)\n", pTile, pDrawable,
exaDrawableLocation(&pTile->drawable),
exaDrawableLocation(pDrawable)));
- exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccessReg (pDrawable, EXA_PREPARE_DEST, pixmaps[0].pReg);
exaPrepareAccess ((DrawablePtr)pTile, EXA_PREPARE_SRC);
fbFillRegionTiled (pDrawable, pRegion, pTile);
exaFinishAccess ((DrawablePtr)pTile, EXA_PREPARE_SRC);
diff --git a/exa/exa_migration.c b/exa/exa_migration.c
index 99058f1..f48e93a 100644
--- a/exa/exa_migration.c
+++ b/exa/exa_migration.c
@@ -117,28 +117,62 @@ exaPixmapShouldBeInFB (PixmapPtr pPix)
* FB to system or vice versa. Both areas must be allocated.
*/
static _X_INLINE void
-exaCopyDirty(PixmapPtr pPixmap, RegionPtr pValidDst, RegionPtr pValidSrc,
+exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc,
Bool (*transfer) (PixmapPtr pPix, int x, int y, int w, int h,
char *sys, int sys_pitch), CARD8 *fallback_src,
CARD8 *fallback_dst, int fallback_srcpitch, int fallback_dstpitch,
int fallback_index, void (*sync) (ScreenPtr pScreen))
{
+ PixmapPtr pPixmap = migrate->pPix;
ExaPixmapPriv (pPixmap);
- RegionPtr pDamageReg = DamageRegion (pExaPixmap->pDamage);
+ RegionPtr damage = DamageRegion (pExaPixmap->pDamage);
RegionRec CopyReg;
CARD8 *save_ptr;
int save_pitch;
BoxPtr pBox;
int nbox;
- Bool do_sync = FALSE;
+ Bool access_prepared = FALSE;
- /* Damaged bits are valid in source but invalid in destination */
- REGION_UNION(pScreen, pValidSrc, pValidSrc, pDamageReg);
- REGION_SUBTRACT(pScreen, pValidDst, pValidDst, pDamageReg);
+ /* Damaged bits are valid in current copy but invalid in other one */
+ if (exaPixmapIsOffscreen(pPixmap)) {
+ REGION_UNION(pScreen, &pExaPixmap->validFB, &pExaPixmap->validFB,
+ damage);
+ REGION_SUBTRACT(pScreen, &pExaPixmap->validSys, &pExaPixmap->validSys,
+ damage);
+ } else {
+ REGION_UNION(pScreen, &pExaPixmap->validSys, &pExaPixmap->validSys,
+ damage);
+ REGION_SUBTRACT(pScreen, &pExaPixmap->validFB, &pExaPixmap->validFB,
+ damage);
+ }
+
+ REGION_EMPTY(pScreen, damage);
- /* Copy bits valid in ssource but not in destination */
+ /* Copy bits valid in source but not in destination */
REGION_NULL(pScreen, &CopyReg);
REGION_SUBTRACT(pScreen, &CopyReg, pValidSrc, pValidDst);
+
+ if (migrate->as_dst) {
+ RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
+
+ if (REGION_NIL(pending_damage)) {
+ static Bool firsttime = TRUE;
+
+ if (firsttime) {
+ ErrorF("%s: Pending damage region empty!\n", __func__);
+ firsttime = FALSE;
+ }
+ }
+
+ REGION_INTERSECT(pScreen, &CopyReg, &CopyReg, pending_damage);
+
+ if (migrate->pReg)
+ REGION_SUBTRACT(pScreen, &CopyReg, &CopyReg, migrate->pReg);
+ } else {
+ if (migrate->pReg)
+ REGION_INTERSECT(pScreen, &CopyReg, &CopyReg, migrate->pReg);
+ }
+
pBox = REGION_RECTS(&CopyReg);
nbox = REGION_NUM_RECTS(&CopyReg);
@@ -165,29 +199,30 @@ exaCopyDirty(PixmapPtr pPixmap, RegionPt
+ pBox->x1 * pPixmap->drawable.bitsPerPixel / 8,
pExaPixmap->sys_pitch))
{
- ExaDoPrepareAccess(&pPixmap->drawable, fallback_index);
+ if (!access_prepared) {
+ ExaDoPrepareAccess(&pPixmap->drawable, fallback_index);
+ access_prepared = TRUE;
+ }
exaMemcpyBox (pPixmap, pBox,
fallback_src, fallback_srcpitch,
fallback_dst, fallback_dstpitch);
- exaFinishAccess(&pPixmap->drawable, fallback_index);
}
- else
- do_sync = TRUE;
pBox++;
}
- if (do_sync)
+ if (access_prepared)
+ exaFinishAccess(&pPixmap->drawable, fallback_index);
+ else
sync (pPixmap->drawable.pScreen);
pPixmap->devPrivate.ptr = save_ptr;
pPixmap->devKind = save_pitch;
- /* The copied bits are now no longer damaged but valid in destination */
+ /* The copied bits are now valid in destination */
REGION_UNION(pScreen, pValidDst, pValidDst, &CopyReg);
- REGION_SUBTRACT(pScreen, pDamageReg, pDamageReg, &CopyReg);
- REGION_NULL(pScreen, &CopyReg);
+ REGION_UNINIT(pScreen, &CopyReg);
}
/**
@@ -196,12 +231,13 @@ exaCopyDirty(PixmapPtr pPixmap, RegionPt
* allocated.
*/
static void
-exaCopyDirtyToSys (PixmapPtr pPixmap)
+exaCopyDirtyToSys (ExaMigrationPtr migrate)
{
+ PixmapPtr pPixmap = migrate->pPix;
ExaScreenPriv (pPixmap->drawable.pScreen);
ExaPixmapPriv (pPixmap);
- exaCopyDirty(pPixmap, &pExaPixmap->validSys, &pExaPixmap->validFB,
+ exaCopyDirty(migrate, &pExaPixmap->validSys, &pExaPixmap->validFB,
pExaScr->info->DownloadFromScreen, pExaPixmap->fb_ptr,
pExaPixmap->sys_ptr, pExaPixmap->fb_pitch,
pExaPixmap->sys_pitch, EXA_PREPARE_SRC, exaWaitSync);
@@ -213,51 +249,19 @@ exaCopyDirtyToSys (PixmapPtr pPixmap)
* allocated.
*/
static void
-exaCopyDirtyToFb (PixmapPtr pPixmap)
+exaCopyDirtyToFb (ExaMigrationPtr migrate)
{
+ PixmapPtr pPixmap = migrate->pPix;
ExaScreenPriv (pPixmap->drawable.pScreen);
ExaPixmapPriv (pPixmap);
- exaCopyDirty(pPixmap, &pExaPixmap->validFB, &pExaPixmap->validSys,
+ exaCopyDirty(migrate, &pExaPixmap->validFB, &pExaPixmap->validSys,
pExaScr->info->UploadToScreen, pExaPixmap->sys_ptr,
pExaPixmap->fb_ptr, pExaPixmap->sys_pitch,
pExaPixmap->fb_pitch, EXA_PREPARE_DEST, exaMarkSync);
}
/**
- * Copies out important pixmap data and removes references to framebuffer area.
- * Called when the memory manager decides it's time to kick the pixmap out of
- * framebuffer entirely.
- */
-void
-exaPixmapSave (ScreenPtr pScreen, ExaOffscreenArea *area)
-{
- PixmapPtr pPixmap = area->privData;
- ExaPixmapPriv(pPixmap);
-
- DBG_MIGRATE (("Save %p (%p) (%dx%d) (%c)\n", pPixmap,
- (void*)(ExaGetPixmapPriv(pPixmap)->area ?
- ExaGetPixmapPriv(pPixmap)->area->offset : 0),
- pPixmap->drawable.width,
- pPixmap->drawable.height,
- exaPixmapIsDirty(pPixmap) ? 'd' : 'c'));
-
- if (exaPixmapIsOffscreen(pPixmap)) {
- exaCopyDirtyToSys (pPixmap);
- pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
- pPixmap->devKind = pExaPixmap->sys_pitch;
- pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
- }
-
- pExaPixmap->fb_ptr = NULL;
- pExaPixmap->area = NULL;
-
- /* Mark all FB bits as invalid, so all valid system bits get copied to FB
- * next time */
- REGION_NULL(pPixmap->drawable.pScreen, &pExaPixmap->validFB);
-}
-
-/**
* Allocates a framebuffer copy of the pixmap if necessary, and then copies
* any necessary pixmap data into the framebuffer copy and points the pixmap at
* it.
@@ -272,10 +276,11 @@ exaPixmapSave (ScreenPtr pScreen, ExaOff
* we mark the pixmap dirty, so that the next exaMoveInPixmap will actually move
* all the data, since it's almost surely all valid now.
*/
-void
-exaMoveInPixmap (PixmapPtr pPixmap)
+static void
+exaDoMoveInPixmap (ExaMigrationPtr migrate)
{
- ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ PixmapPtr pPixmap = migrate->pPix;
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
ExaScreenPriv (pScreen);
ExaPixmapPriv (pPixmap);
@@ -283,10 +288,6 @@ exaMoveInPixmap (PixmapPtr pPixmap)
if (pExaScr->swappedOut)
return;
- /* If we're already in FB, our work is done. */
- if (exaPixmapIsOffscreen(pPixmap))
- return;
-
/* If we're not allowed to move, then fail. */
if (exaPixmapIsPinned(pPixmap))
return;
@@ -310,6 +311,11 @@ exaMoveInPixmap (PixmapPtr pPixmap)
pExaPixmap->area->offset;
}
+ exaCopyDirtyToFb (migrate);
+
+ if (exaPixmapIsOffscreen(pPixmap))
+ return;
+
DBG_MIGRATE (("-> %p (0x%x) (%dx%d) (%c)\n", pPixmap,
(ExaGetPixmapPriv(pPixmap)->area ?
ExaGetPixmapPriv(pPixmap)->area->offset : 0),
@@ -317,8 +323,6 @@ exaMoveInPixmap (PixmapPtr pPixmap)
pPixmap->drawable.height,
exaPixmapIsDirty(pPixmap) ? 'd' : 'c'));
- exaCopyDirtyToFb (pPixmap);
-
if (pExaScr->hideOffscreenPixmapData)
pPixmap->devPrivate.ptr = NULL;
else
@@ -327,18 +331,31 @@ exaMoveInPixmap (PixmapPtr pPixmap)
pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
}
+void
+exaMoveInPixmap (PixmapPtr pPixmap)
+{
+ static ExaMigrationRec migrate = { .as_dst = FALSE, .as_src = TRUE,
+ .pReg = NULL };
+
+ migrate.pPix = pPixmap;
+ exaDoMoveInPixmap (&migrate);
+}
+
/**
* Switches the current active location of the pixmap to system memory, copying
* updated data out if necessary.
*/
-void
-exaMoveOutPixmap (PixmapPtr pPixmap)
+static void
+exaDoMoveOutPixmap (ExaMigrationPtr migrate)
{
+ PixmapPtr pPixmap = migrate->pPix;
ExaPixmapPriv (pPixmap);
- if (exaPixmapIsPinned(pPixmap))
+ if (!pExaPixmap->area || exaPixmapIsPinned(pPixmap))
return;
+ exaCopyDirtyToSys (migrate);
+
if (exaPixmapIsOffscreen(pPixmap)) {
DBG_MIGRATE (("<- %p (%p) (%dx%d) (%c)\n", pPixmap,
@@ -348,21 +365,52 @@ exaMoveOutPixmap (PixmapPtr pPixmap)
pPixmap->drawable.height,
exaPixmapIsDirty(pPixmap) ? 'd' : 'c'));
- exaCopyDirtyToSys (pPixmap);
-
pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
pPixmap->devKind = pExaPixmap->sys_pitch;
pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
}
}
+void
+exaMoveOutPixmap (PixmapPtr pPixmap)
+{
+ static ExaMigrationRec migrate = { .as_dst = FALSE, .as_src = TRUE,
+ .pReg = NULL };
+
+ migrate.pPix = pPixmap;
+ exaDoMoveOutPixmap (&migrate);
+}
+
+
+/**
+ * Copies out important pixmap data and removes references to framebuffer area.
+ * Called when the memory manager decides it's time to kick the pixmap out of
+ * framebuffer entirely.
+ */
+void
+exaPixmapSave (ScreenPtr pScreen, ExaOffscreenArea *area)
+{
+ PixmapPtr pPixmap = area->privData;
+ ExaPixmapPriv(pPixmap);
+
+ exaMoveOutPixmap(pPixmap);
+
+ pExaPixmap->fb_ptr = NULL;
+ pExaPixmap->area = NULL;
+
+ /* Mark all FB bits as invalid, so all valid system bits get copied to FB
+ * next time */
+ REGION_EMPTY(pPixmap->drawable.pScreen, &pExaPixmap->validFB);
+}
+
/**
* For the "greedy" migration scheme, pushes the pixmap toward being located in
* framebuffer memory.
*/
static void
-exaMigrateTowardFb (PixmapPtr pPixmap)
+exaMigrateTowardFb (ExaMigrationPtr migrate)
{
+ PixmapPtr pPixmap = migrate->pPix;
ExaPixmapPriv (pPixmap);
if (pExaPixmap == NULL) {
@@ -382,7 +430,7 @@ exaMigrateTowardFb (PixmapPtr pPixmap)
(pointer)pPixmap, pExaPixmap->score));
if (pExaPixmap->score == EXA_PIXMAP_SCORE_INIT) {
- exaMoveInPixmap(pPixmap);
+ exaDoMoveInPixmap(migrate);
pExaPixmap->score = 0;
}
@@ -392,7 +440,7 @@ exaMigrateTowardFb (PixmapPtr pPixmap)
if (pExaPixmap->score >= EXA_PIXMAP_SCORE_MOVE_IN &&
!exaPixmapIsOffscreen(pPixmap))
{
- exaMoveInPixmap (pPixmap);
+ exaDoMoveInPixmap(migrate);
}
ExaOffscreenMarkUsed (pPixmap);
@@ -403,8 +451,9 @@ exaMigrateTowardFb (PixmapPtr pPixmap)
* system memory.
*/
static void
-exaMigrateTowardSys (PixmapPtr pPixmap)
+exaMigrateTowardSys (ExaMigrationPtr migrate)
{
+ PixmapPtr pPixmap = migrate->pPix;
ExaPixmapPriv (pPixmap);
if (pExaPixmap == NULL) {
@@ -426,7 +475,7 @@ exaMigrateTowardSys (PixmapPtr pPixmap)
pExaPixmap->score--;
if (pExaPixmap->score <= EXA_PIXMAP_SCORE_MOVE_OUT && pExaPixmap->area)
- exaMoveOutPixmap (pPixmap);
+ exaDoMoveOutPixmap(migrate);
}
/**
@@ -438,15 +487,24 @@ exaAssertNotDirty (PixmapPtr pPixmap)
{
ExaPixmapPriv (pPixmap);
CARD8 *dst, *src;
- RegionPtr pValidReg = exaPixmapIsOffscreen(pPixmap) ? &pExaPixmap->validFB :
- &pExaPixmap->validSys;
- int dst_pitch, src_pitch, cpp, y, nbox = REGION_NUM_RECTS(pValidReg);
- BoxPtr pBox = REGION_RECTS(pValidReg);
+ RegionRec ValidReg;
+ int dst_pitch, src_pitch, cpp, y, nbox;
+ BoxPtr pBox;
Bool ret = TRUE;
- if (!nbox || exaPixmapIsPinned(pPixmap) || pExaPixmap->fb_ptr == NULL)
+ if (exaPixmapIsPinned(pPixmap) || pExaPixmap->area == NULL)
return ret;
+ REGION_NULL(pScreen, &ValidReg);
+ REGION_INTERSECT(pScreen, &ValidReg, &pExaPixmap->validFB,
+ &pExaPixmap->validSys);
+ nbox = REGION_NUM_RECTS(&ValidReg);
+
+ if (!nbox)
+ goto out;
+
+ pBox = REGION_RECTS(&ValidReg);
+
dst_pitch = pExaPixmap->sys_pitch;
src_pitch = pExaPixmap->fb_pitch;
cpp = pPixmap->drawable.bitsPerPixel / 8;
@@ -479,6 +537,8 @@ exaAssertNotDirty (PixmapPtr pPixmap)
}
exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
+out:
+ REGION_UNINIT(pScreen, &ValidReg);
return ret;
}
@@ -533,7 +593,7 @@ exaDoMigration (ExaMigrationPtr pixmaps,
{
for (i = 0; i < npixmaps; i++) {
if (!exaPixmapIsDirty (pixmaps[i].pPix))
- exaMoveOutPixmap (pixmaps[i].pPix);
+ exaDoMoveOutPixmap (pixmaps + i);
}
return;
}
@@ -544,17 +604,17 @@ exaDoMigration (ExaMigrationPtr pixmaps,
*/
if (!can_accel) {
for (i = 0; i < npixmaps; i++) {
- exaMigrateTowardSys (pixmaps[i].pPix);
+ exaMigrateTowardSys (pixmaps + i);
if (!exaPixmapIsDirty (pixmaps[i].pPix))
- exaMoveOutPixmap (pixmaps[i].pPix);
+ exaDoMoveOutPixmap (pixmaps + i);
}
return;
}
/* Finally, the acceleration path. Move them all in. */
for (i = 0; i < npixmaps; i++) {
- exaMigrateTowardFb(pixmaps[i].pPix);
- exaMoveInPixmap(pixmaps[i].pPix);
+ exaMigrateTowardFb(pixmaps + i);
+ exaDoMoveInPixmap(pixmaps + i);
}
} else if (pExaScr->migration == ExaMigrationGreedy) {
/* If we can't accelerate, either because the driver can't or because one of
@@ -570,7 +630,7 @@ exaDoMigration (ExaMigrationPtr pixmaps,
*/
if (!can_accel) {
for (i = 0; i < npixmaps; i++)
- exaMigrateTowardSys (pixmaps[i].pPix);
+ exaMigrateTowardSys (pixmaps + i);
return;
}
@@ -578,14 +638,14 @@ exaDoMigration (ExaMigrationPtr pixmaps,
if (exaPixmapIsOffscreen(pixmaps[i].pPix)) {
/* Found one in FB, so move all to FB. */
for (j = 0; j < npixmaps; j++)
- exaMigrateTowardFb(pixmaps[j].pPix);
+ exaMigrateTowardFb(pixmaps + i);
return;
}
}
/* Nobody's in FB, so move all away from FB. */
for (i = 0; i < npixmaps; i++)
- exaMigrateTowardSys(pixmaps[i].pPix);
+ exaMigrateTowardSys(pixmaps + i);
} else if (pExaScr->migration == ExaMigrationAlways) {
/* Always move the pixmaps out if we can't accelerate. If we can
* accelerate, try to move them all in. If that fails, then move them
@@ -593,13 +653,13 @@ exaDoMigration (ExaMigrationPtr pixmaps,
*/
if (!can_accel) {
for (i = 0; i < npixmaps; i++)
- exaMoveOutPixmap(pixmaps[i].pPix);
+ exaDoMoveOutPixmap(pixmaps + i);
return;
}
/* Now, try to move them all into FB */
for (i = 0; i < npixmaps; i++) {
- exaMoveInPixmap(pixmaps[i].pPix);
+ exaDoMoveInPixmap(pixmaps + i);
}
/* If we couldn't fit everything in, abort */
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index b9e5016..491d80b 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -185,6 +185,7 @@ typedef struct _ExaMigrationRec {
Bool as_dst;
Bool as_src;
PixmapPtr pPix;
+ RegionPtr pReg;
} ExaMigrationRec, *ExaMigrationPtr;
/**
@@ -338,6 +339,9 @@ void
ExaDoPrepareAccess(DrawablePtr pDrawable, int index);
void
+exaPrepareAccessReg(DrawablePtr pDrawable, int index, RegionPtr pReg);
+
+void
exaPrepareAccess(DrawablePtr pDrawable, int index);
void
diff --git a/exa/exa_render.c b/exa/exa_render.c
index 738ac15..067f88b 100644
--- a/exa/exa_render.c
+++ b/exa/exa_render.c
@@ -267,6 +267,7 @@ exaTryDriverSolidFill(PicturePtr pSrc,
pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = FALSE;
pixmaps[0].pPix = exaGetDrawablePixmap (pDst->pDrawable);
+ pixmaps[0].pReg = NULL;
exaDoMigration(pixmaps, 1, TRUE);
pDstPix = exaGetOffscreenPixmap (pDst->pDrawable, &dst_off_x, &dst_off_y);
@@ -381,13 +382,16 @@ exaTryDriverComposite(CARD8 op,
pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = exaOpReadsDestination(op);
pixmaps[0].pPix = exaGetDrawablePixmap (pDst->pDrawable);
+ pixmaps[0].pReg = NULL;
pixmaps[1].as_dst = FALSE;
pixmaps[1].as_src = TRUE;
pixmaps[1].pPix = exaGetDrawablePixmap (pSrc->pDrawable);
+ pixmaps[1].pReg = NULL;
if (pMask) {
pixmaps[2].as_dst = FALSE;
pixmaps[2].as_src = TRUE;
pixmaps[2].pPix = exaGetDrawablePixmap (pMask->pDrawable);
+ pixmaps[2].pReg = NULL;
exaDoMigration(pixmaps, 3, TRUE);
} else {
exaDoMigration(pixmaps, 2, TRUE);
@@ -579,12 +583,14 @@ exaComposite(CARD8 op,
pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = exaOpReadsDestination(op);
pixmaps[0].pPix = exaGetDrawablePixmap (pDst->pDrawable);
+ pixmaps[0].pReg = NULL;
if (pSrc->pDrawable) {
pSrcPixmap = exaGetDrawablePixmap (pSrc->pDrawable);
pixmaps[npixmaps].as_dst = FALSE;
pixmaps[npixmaps].as_src = TRUE;
pixmaps[npixmaps].pPix = pSrcPixmap;
+ pixmaps[npixmaps].pReg = NULL;
npixmaps++;
}
@@ -592,6 +598,7 @@ exaComposite(CARD8 op,
pixmaps[npixmaps].as_dst = FALSE;
pixmaps[npixmaps].as_src = TRUE;
pixmaps[npixmaps].pPix = exaGetDrawablePixmap (pMask->pDrawable);
+ pixmaps[npixmaps].pReg = NULL;
npixmaps++;
}
@@ -1159,8 +1166,9 @@ exaGlyphs (CARD8 op,
* it'll stick there.
*/
pixmaps[0].as_dst = TRUE;
- pixmaps[0].as_src = TRUE;
+ pixmaps[0].as_src = FALSE;
pixmaps[0].pPix = pPixmap;
+ pixmaps[0].pReg = NULL;
exaDoMigration (pixmaps, 1, pExaScr->info->PrepareComposite != NULL);
while (n--)
diff-tree 19ca0ab22f9bd5a29716259ac230fee62c1afc10 (from 47bb63376b4478074bbd445dfc99c35fa4506127)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Wed Aug 29 19:41:52 2007 +0200
Add DamagePendingRegion.
DamagePendingRegion returns a pointer to the region of a drawable that will
be damaged by the current operation for damage records that chose to get damage
reported only at the end of the operation.
diff --git a/miext/damage/damage.c b/miext/damage/damage.c
index 65314d8..472b1b8 100755
--- a/miext/damage/damage.c
+++ b/miext/damage/damage.c
@@ -1987,6 +1987,12 @@ DamageRegion (DamagePtr pDamage)
return &pDamage->damage;
}
+_X_EXPORT RegionPtr
+DamagePendingRegion (DamagePtr pDamage)
+{
+ return &pDamage->pendingDamage;
+}
+
_X_EXPORT void
DamageDamageRegion (DrawablePtr pDrawable,
RegionPtr pRegion)
diff --git a/miext/damage/damage.h b/miext/damage/damage.h
index 4cfc812..102da6e 100755
--- a/miext/damage/damage.h
+++ b/miext/damage/damage.h
@@ -75,6 +75,9 @@ DamageEmpty (DamagePtr pDamage);
RegionPtr
DamageRegion (DamagePtr pDamage);
+RegionPtr
+DamagePendingRegion (DamagePtr pDamage);
+
void
DamageDamageRegion (DrawablePtr pDrawable,
const RegionPtr pRegion);
diff-tree 47bb63376b4478074bbd445dfc99c35fa4506127 (from d92947c8a83d403e94aa61094f07eea10301ddb0)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Fri Aug 24 19:24:18 2007 +0200
EXA: Track valid bits in Sys and FB separately.
Also consolidate exaCopyDirtyToFb/Sys.
diff --git a/exa/exa.c b/exa/exa.c
index 514b88b..ecdb761 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -186,7 +186,8 @@ exaDestroyPixmap (PixmapPtr pPixmap)
pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
pPixmap->devKind = pExaPixmap->sys_pitch;
}
- REGION_UNINIT(pPixmap->drawable.pScreen, &pExaPixmap->validReg);
+ REGION_UNINIT(pPixmap->drawable.pScreen, &pExaPixmap->validSys);
+ REGION_UNINIT(pPixmap->drawable.pScreen, &pExaPixmap->validFB);
}
return fbDestroyPixmap (pPixmap);
}
@@ -267,7 +268,8 @@ exaCreatePixmap(ScreenPtr pScreen, int w
DamageSetReportAfterOp (pExaPixmap->pDamage, TRUE);
/* None of the pixmap bits are valid initially */
- REGION_NULL(pScreen, &pExaPixmap->validReg);
+ REGION_NULL(pScreen, &pExaPixmap->validSys);
+ REGION_NULL(pScreen, &pExaPixmap->validFB);
return pPixmap;
}
diff --git a/exa/exa_migration.c b/exa/exa_migration.c
index 661ff40..99058f1 100644
--- a/exa/exa_migration.c
+++ b/exa/exa_migration.c
@@ -90,7 +90,8 @@ exaPixmapIsDirty (PixmapPtr pPix)
ExaPixmapPriv (pPix);
return pExaPixmap == NULL ||
- REGION_NOTEMPTY (pScreen, DamageRegion(pExaPixmap->pDamage));
+ REGION_NOTEMPTY (pScreen, DamageRegion(pExaPixmap->pDamage)) ||
+ !REGION_EQUAL(pScreen, &pExaPixmap->validSys, &pExaPixmap->validFB);
}
/**
@@ -113,21 +114,34 @@ exaPixmapShouldBeInFB (PixmapPtr pPix)
/**
* If the pixmap is currently dirty, this copies at least the dirty area from
- * the framebuffer memory copy to the system memory copy. Both areas must be
- * allocated.
+ * FB to system or vice versa. Both areas must be allocated.
*/
-static void
-exaCopyDirtyToSys (PixmapPtr pPixmap)
+static _X_INLINE void
+exaCopyDirty(PixmapPtr pPixmap, RegionPtr pValidDst, RegionPtr pValidSrc,
+ Bool (*transfer) (PixmapPtr pPix, int x, int y, int w, int h,
+ char *sys, int sys_pitch), CARD8 *fallback_src,
+ CARD8 *fallback_dst, int fallback_srcpitch, int fallback_dstpitch,
+ int fallback_index, void (*sync) (ScreenPtr pScreen))
{
- ExaScreenPriv (pPixmap->drawable.pScreen);
ExaPixmapPriv (pPixmap);
- RegionPtr pRegion = DamageRegion (pExaPixmap->pDamage);
+ RegionPtr pDamageReg = DamageRegion (pExaPixmap->pDamage);
+ RegionRec CopyReg;
CARD8 *save_ptr;
int save_pitch;
- BoxPtr pBox = REGION_RECTS(pRegion);
- int nbox = REGION_NUM_RECTS(pRegion);
+ BoxPtr pBox;
+ int nbox;
Bool do_sync = FALSE;
+ /* Damaged bits are valid in source but invalid in destination */
+ REGION_UNION(pScreen, pValidSrc, pValidSrc, pDamageReg);
+ REGION_SUBTRACT(pScreen, pValidDst, pValidDst, pDamageReg);
+
+ /* Copy bits valid in ssource but not in destination */
+ REGION_NULL(pScreen, &CopyReg);
+ REGION_SUBTRACT(pScreen, &CopyReg, pValidSrc, pValidDst);
+ pBox = REGION_RECTS(&CopyReg);
+ nbox = REGION_NUM_RECTS(&CopyReg);
+
save_ptr = pPixmap->devPrivate.ptr;
save_pitch = pPixmap->devKind;
pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
@@ -142,21 +156,20 @@ exaCopyDirtyToSys (PixmapPtr pPixmap)
if (pBox->x1 >= pBox->x2 || pBox->y1 >= pBox->y2)
continue;
- if (pExaScr->info->DownloadFromScreen == NULL ||
- !pExaScr->info->DownloadFromScreen (pPixmap,
- pBox->x1, pBox->y1,
- pBox->x2 - pBox->x1,
- pBox->y2 - pBox->y1,
- pExaPixmap->sys_ptr
- + pBox->y1 * pExaPixmap->sys_pitch
- + pBox->x1 * pPixmap->drawable.bitsPerPixel / 8,
- pExaPixmap->sys_pitch))
+ if (!transfer || !transfer (pPixmap,
+ pBox->x1, pBox->y1,
+ pBox->x2 - pBox->x1,
+ pBox->y2 - pBox->y1,
+ pExaPixmap->sys_ptr
+ + pBox->y1 * pExaPixmap->sys_pitch
+ + pBox->x1 * pPixmap->drawable.bitsPerPixel / 8,
+ pExaPixmap->sys_pitch))
{
- ExaDoPrepareAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
+ ExaDoPrepareAccess(&pPixmap->drawable, fallback_index);
exaMemcpyBox (pPixmap, pBox,
- pExaPixmap->fb_ptr, pExaPixmap->fb_pitch,
- pExaPixmap->sys_ptr, pExaPixmap->sys_pitch);
- exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
+ fallback_src, fallback_srcpitch,
+ fallback_dst, fallback_dstpitch);
+ exaFinishAccess(&pPixmap->drawable, fallback_index);
}
else
do_sync = TRUE;
@@ -164,84 +177,51 @@ exaCopyDirtyToSys (PixmapPtr pPixmap)
pBox++;
}
- /* Make sure the bits have actually landed, since we don't necessarily sync
- * when accessing pixmaps in system memory.
- */
if (do_sync)
- exaWaitSync (pPixmap->drawable.pScreen);
+ sync (pPixmap->drawable.pScreen);
pPixmap->devPrivate.ptr = save_ptr;
pPixmap->devKind = save_pitch;
- /* The previously damaged bits are now no longer damaged but valid */
- REGION_UNION(pPixmap->drawable.pScreen,
- &pExaPixmap->validReg, &pExaPixmap->validReg, pRegion);
- DamageEmpty (pExaPixmap->pDamage);
+ /* The copied bits are now no longer damaged but valid in destination */
+ REGION_UNION(pScreen, pValidDst, pValidDst, &CopyReg);
+ REGION_SUBTRACT(pScreen, pDamageReg, pDamageReg, &CopyReg);
+
+ REGION_NULL(pScreen, &CopyReg);
}
/**
* If the pixmap is currently dirty, this copies at least the dirty area from
- * the system memory copy to the framebuffer memory copy. Both areas must be
+ * the framebuffer memory copy to the system memory copy. Both areas must be
* allocated.
*/
static void
-exaCopyDirtyToFb (PixmapPtr pPixmap)
+exaCopyDirtyToSys (PixmapPtr pPixmap)
{
ExaScreenPriv (pPixmap->drawable.pScreen);
ExaPixmapPriv (pPixmap);
- RegionPtr pRegion = DamageRegion (pExaPixmap->pDamage);
- CARD8 *save_ptr;
- int save_pitch;
- BoxPtr pBox = REGION_RECTS(pRegion);
- int nbox = REGION_NUM_RECTS(pRegion);
- Bool do_sync = FALSE;
-
- save_ptr = pPixmap->devPrivate.ptr;
- save_pitch = pPixmap->devKind;
- pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
- pPixmap->devKind = pExaPixmap->fb_pitch;
-
- while (nbox--) {
- pBox->x1 = max(pBox->x1, 0);
- pBox->y1 = max(pBox->y1, 0);
- pBox->x2 = min(pBox->x2, pPixmap->drawable.width);
- pBox->y2 = min(pBox->y2, pPixmap->drawable.height);
- if (pBox->x1 >= pBox->x2 || pBox->y1 >= pBox->y2)
- continue;
-
- if (pExaScr->info->UploadToScreen == NULL ||
- !pExaScr->info->UploadToScreen (pPixmap,
- pBox->x1, pBox->y1,
- pBox->x2 - pBox->x1,
- pBox->y2 - pBox->y1,
- pExaPixmap->sys_ptr
- + pBox->y1 * pExaPixmap->sys_pitch
- + pBox->x1 * pPixmap->drawable.bitsPerPixel / 8,
- pExaPixmap->sys_pitch))
- {
- ExaDoPrepareAccess(&pPixmap->drawable, EXA_PREPARE_DEST);
- exaMemcpyBox (pPixmap, pBox,
- pExaPixmap->sys_ptr, pExaPixmap->sys_pitch,
- pExaPixmap->fb_ptr, pExaPixmap->fb_pitch);
- exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_DEST);
- }
- else
- do_sync = TRUE;
-
- pBox++;
- }
-
- if (do_sync)
- exaMarkSync (pPixmap->drawable.pScreen);
+ exaCopyDirty(pPixmap, &pExaPixmap->validSys, &pExaPixmap->validFB,
+ pExaScr->info->DownloadFromScreen, pExaPixmap->fb_ptr,
+ pExaPixmap->sys_ptr, pExaPixmap->fb_pitch,
+ pExaPixmap->sys_pitch, EXA_PREPARE_SRC, exaWaitSync);
+}
- pPixmap->devPrivate.ptr = save_ptr;
- pPixmap->devKind = save_pitch;
+/**
+ * If the pixmap is currently dirty, this copies at least the dirty area from
+ * the system memory copy to the framebuffer memory copy. Both areas must be
+ * allocated.
+ */
+static void
+exaCopyDirtyToFb (PixmapPtr pPixmap)
+{
+ ExaScreenPriv (pPixmap->drawable.pScreen);
+ ExaPixmapPriv (pPixmap);
- /* The previously damaged bits are now no longer damaged but valid */
- REGION_UNION(pPixmap->drawable.pScreen,
- &pExaPixmap->validReg, &pExaPixmap->validReg, pRegion);
- DamageEmpty (pExaPixmap->pDamage);
+ exaCopyDirty(pPixmap, &pExaPixmap->validFB, &pExaPixmap->validSys,
+ pExaScr->info->UploadToScreen, pExaPixmap->sys_ptr,
+ pExaPixmap->fb_ptr, pExaPixmap->sys_pitch,
+ pExaPixmap->fb_pitch, EXA_PREPARE_DEST, exaMarkSync);
}
/**
@@ -254,7 +234,6 @@ exaPixmapSave (ScreenPtr pScreen, ExaOff
{
PixmapPtr pPixmap = area->privData;
ExaPixmapPriv(pPixmap);
- RegionPtr pDamageReg = DamageRegion(pExaPixmap->pDamage);
DBG_MIGRATE (("Save %p (%p) (%dx%d) (%c)\n", pPixmap,
(void*)(ExaGetPixmapPriv(pPixmap)->area ?
@@ -273,9 +252,9 @@ exaPixmapSave (ScreenPtr pScreen, ExaOff
pExaPixmap->fb_ptr = NULL;
pExaPixmap->area = NULL;
- /* Mark all valid bits as damaged, so they'll get copied to FB next time */
- REGION_UNION(pPixmap->drawable.pScreen, pDamageReg, pDamageReg,
- &pExaPixmap->validReg);
+ /* Mark all FB bits as invalid, so all valid system bits get copied to FB
+ * next time */
+ REGION_NULL(pPixmap->drawable.pScreen, &pExaPixmap->validFB);
}
/**
@@ -459,7 +438,8 @@ exaAssertNotDirty (PixmapPtr pPixmap)
{
ExaPixmapPriv (pPixmap);
CARD8 *dst, *src;
- RegionPtr pValidReg = &pExaPixmap->validReg;
+ RegionPtr pValidReg = exaPixmapIsOffscreen(pPixmap) ? &pExaPixmap->validFB :
+ &pExaPixmap->validSys;
int dst_pitch, src_pitch, cpp, y, nbox = REGION_NUM_RECTS(pValidReg);
BoxPtr pBox = REGION_RECTS(pValidReg);
Bool ret = TRUE;
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index 409bc4d..b9e5016 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -175,10 +175,10 @@ typedef struct {
*/
DamagePtr pDamage;
/**
- * The valid region marks the valid bits of a drawable (at least, as it's
- * derived from damage, which may be overreported).
+ * The valid regions mark the valid bits (at least, as they're derived from
+ * damage, which may be overreported) of a pixmap's system and FB copies.
*/
- RegionRec validReg;
+ RegionRec validSys, validFB;
} ExaPixmapPrivRec, *ExaPixmapPrivPtr;
typedef struct _ExaMigrationRec {
diff-tree d92947c8a83d403e94aa61094f07eea10301ddb0 (from 3a4873a46093c37a707e6be0c336a57ab67115ab)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date: Wed Sep 5 20:10:09 2007 +0200
EXA: Migrate out pixmap in exaPrepareAccess.
Also fix exaFinishAccessGC not to use the same index for tile and stipple.
diff --git a/exa/exa.c b/exa/exa.c
index 46fb557..514b88b 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -329,14 +329,8 @@ exaGetOffscreenPixmap (DrawablePtr pDraw
return NULL;
}
-/**
- * exaPrepareAccess() is EXA's wrapper for the driver's PrepareAccess() handler.
- *
- * It deals with waiting for synchronization with the card, determining if
- * PrepareAccess() is necessary, and working around PrepareAccess() failure.
- */
void
-exaPrepareAccess(DrawablePtr pDrawable, int index)
+ExaDoPrepareAccess(DrawablePtr pDrawable, int index)
{
ScreenPtr pScreen = pDrawable->pScreen;
ExaScreenPriv (pScreen);
@@ -368,6 +362,26 @@ exaPrepareAccess(DrawablePtr pDrawable,
}
/**
+ * exaPrepareAccess() is EXA's wrapper for the driver's PrepareAccess() handler.
+ *
+ * It deals with waiting for synchronization with the card, determining if
+ * PrepareAccess() is necessary, and working around PrepareAccess() failure.
+ */
+void
+exaPrepareAccess(DrawablePtr pDrawable, int index)
+{
+ ExaMigrationRec pixmaps[1];
+
+ pixmaps[0].as_dst = index == EXA_PREPARE_DEST;
+ pixmaps[0].as_src = index != EXA_PREPARE_DEST;
+ pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable);
+
+ exaDoMigration(pixmaps, 1, FALSE);
+
+ ExaDoPrepareAccess(pDrawable, index);
+}
+
+/**
* exaFinishAccess() is EXA's wrapper for the driver's FinishAccess() handler.
*
* It deals with calling the driver's FinishAccess() only if necessary.
@@ -698,7 +712,7 @@ exaDriverInit (ScreenPtr pScreen,
pScreen->GetImage = exaGetImage;
pExaScr->SavedGetSpans = pScreen->GetSpans;
- pScreen->GetSpans = exaGetSpans;
+ pScreen->GetSpans = ExaCheckGetSpans;
pExaScr->SavedCopyWindow = pScreen->CopyWindow;
pScreen->CopyWindow = exaCopyWindow;
diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index feedd49..07ada15 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -61,7 +61,6 @@ exaFillSpans(DrawablePtr pDrawable, GCPt
pPixmap->drawable.width > pExaScr->info->maxX ||
pPixmap->drawable.height > pExaScr->info->maxY)
{
- exaDoMigration (pixmaps, 1, FALSE);
ExaCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted);
return;
} else {
@@ -74,7 +73,6 @@ exaFillSpans(DrawablePtr pDrawable, GCPt
pGC->planemask,
pGC->fgPixel))
{
- exaDoMigration (pixmaps, 1, FALSE);
ExaCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted);
return;
}
@@ -158,11 +156,11 @@ exaDoPutImage (DrawablePtr pDrawable, GC
/* Don't bother with under 8bpp, XYPixmaps. */
if (format != ZPixmap || bpp < 8)
- goto migrate_and_fallback;
+ goto fallback;
/* Only accelerate copies: no rop or planemask. */
if (!EXA_PM_IS_SOLID(pDrawable, pGC->planemask) || pGC->alu != GXcopy)
- goto migrate_and_fallback;
+ goto fallback;
if (pExaScr->swappedOut)
goto fallback;
@@ -240,9 +238,6 @@ exaDoPutImage (DrawablePtr pDrawable, GC
return TRUE;
-migrate_and_fallback:
- exaDoMigration (pixmaps, 1, FALSE);
-
fallback:
return FALSE;
}
@@ -468,7 +463,6 @@ exaCopyNtoN (DrawablePtr pSrcDrawable
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,
@@ -731,15 +725,6 @@ exaPolyFillRect(DrawablePtr pDrawable,
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);
goto out;
}
@@ -860,7 +845,6 @@ exaSolidBoxClipped (DrawablePtr pDrawabl
{
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);
@@ -969,7 +953,6 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
depthMask = FbFullMask(pDrawable->depth);
if ((pGC->planemask & depthMask) != depthMask)
{
- exaDoMigration(pixmaps, 1, FALSE);
ExaCheckImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppciInit, pglyphBase);
goto damage;
}
@@ -1004,7 +987,6 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
}
EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
- exaDoMigration(pixmaps, 1, FALSE);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
exaPrepareAccessGC (pGC);
@@ -1146,7 +1128,6 @@ fallback:
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));
@@ -1262,7 +1243,6 @@ fallback:
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);
@@ -1349,7 +1329,6 @@ exaGetImage (DrawablePtr pDrawable, int
unsigned int format, unsigned long planeMask, char *d)
{
ExaScreenPriv (pDrawable->pScreen);
- ExaMigrationRec pixmaps[1];
PixmapPtr pPix;
int xoff, yoff;
Bool ok;
@@ -1362,13 +1341,13 @@ exaGetImage (DrawablePtr pDrawable, int
/* Only cover the ZPixmap, solid copy case. */
if (format != ZPixmap || !EXA_PM_IS_SOLID(pDrawable, planeMask))
- goto migrate_and_fallback;
+ goto 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;
+ goto fallback;
pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
if (pPix == NULL)
@@ -1384,29 +1363,6 @@ exaGetImage (DrawablePtr pDrawable, int
return;
}
-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);
}
-
-/**
- * GetSpans isn't accelerated yet, but performs migration so that we'll
- * hopefully avoid the read-from-framebuffer cost.
- */
-void
-exaGetSpans (DrawablePtr pDrawable, int wMax, DDXPointPtr ppt, int *pwidth,
- int nspans, char *pdstStart)
-{
- ExaMigrationRec pixmaps[1];
-
- pixmaps[0].as_dst = FALSE;
- pixmaps[0].as_src = TRUE;
- pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable);
- exaDoMigration (pixmaps, 1, FALSE);
-
- ExaCheckGetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
-}
diff --git a/exa/exa_migration.c b/exa/exa_migration.c
index 5f07a8d..661ff40 100644
--- a/exa/exa_migration.c
+++ b/exa/exa_migration.c
@@ -152,7 +152,7 @@ exaCopyDirtyToSys (PixmapPtr pPixmap)
+ pBox->x1 * pPixmap->drawable.bitsPerPixel / 8,
pExaPixmap->sys_pitch))
{
- exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
+ ExaDoPrepareAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
exaMemcpyBox (pPixmap, pBox,
pExaPixmap->fb_ptr, pExaPixmap->fb_pitch,
pExaPixmap->sys_ptr, pExaPixmap->sys_pitch);
@@ -220,7 +220,7 @@ exaCopyDirtyToFb (PixmapPtr pPixmap)
+ pBox->x1 * pPixmap->drawable.bitsPerPixel / 8,
pExaPixmap->sys_pitch))
{
- exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_DEST);
+ ExaDoPrepareAccess(&pPixmap->drawable, EXA_PREPARE_DEST);
exaMemcpyBox (pPixmap, pBox,
pExaPixmap->sys_ptr, pExaPixmap->sys_pitch,
pExaPixmap->fb_ptr, pExaPixmap->fb_pitch);
@@ -471,7 +471,7 @@ exaAssertNotDirty (PixmapPtr pPixmap)
src_pitch = pExaPixmap->fb_pitch;
cpp = pPixmap->drawable.bitsPerPixel / 8;
- exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
+ ExaDoPrepareAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
while (nbox--) {
int rowbytes;
@@ -622,14 +622,9 @@ exaDoMigration (ExaMigrationPtr pixmaps,
exaMoveInPixmap(pixmaps[i].pPix);
}
- /* If we couldn't fit everything in, then kick back out */
+ /* If we couldn't fit everything in, abort */
for (i = 0; i < npixmaps; i++) {
if (!exaPixmapIsOffscreen(pixmaps[i].pPix)) {
- EXA_FALLBACK(("Pixmap %p (%dx%d) not in fb\n", pixmaps[i].pPix,
- pixmaps[i].pPix->drawable.width,
- pixmaps[i].pPix->drawable.height));
- for (j = 0; j < npixmaps; j++)
- exaMoveOutPixmap(pixmaps[j].pPix);
return;
}
}
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index a08acfa..409bc4d 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -298,10 +298,6 @@ void
exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h,
unsigned int format, unsigned long planeMask, char *d);
-void
-exaGetSpans (DrawablePtr pDrawable, int wMax, DDXPointPtr ppt, int *pwidth,
- int nspans, char *pdstStart);
-
extern const GCOps exaOps;
#ifdef MITSHM
@@ -339,6 +335,9 @@ ExaOffscreenFini (ScreenPtr pScreen);
/* exa.c */
void
+ExaDoPrepareAccess(DrawablePtr pDrawable, int index);
+
+void
exaPrepareAccess(DrawablePtr pDrawable, int index);
void
diff --git a/exa/exa_render.c b/exa/exa_render.c
index 2dd3fc1..738ac15 100644
--- a/exa/exa_render.c
+++ b/exa/exa_render.c
@@ -738,7 +738,6 @@ fallback:
exaPrintCompositeFallback (op, pSrc, pMask, pDst);
#endif
- exaDoMigration(pixmaps, npixmaps, FALSE);
ExaCheckComposite (op, pSrc, pMask, pDst, xSrc, ySrc,
xMask, yMask, xDst, yDst, width, height);
@@ -889,18 +888,13 @@ exaRasterizeTrapezoid (PicturePtr pPictu
int x_off, int y_off)
{
DrawablePtr pDraw = pPicture->pDrawable;
- ExaMigrationRec pixmaps[1];
+ PixmapPtr pPixmap = exaGetDrawablePixmap(pDraw);
int xoff, yoff;
- pixmaps[0].as_dst = TRUE;
- pixmaps[0].as_src = TRUE;
- pixmaps[0].pPix = exaGetDrawablePixmap (pDraw);
- exaDoMigration(pixmaps, 1, FALSE);
-
exaPrepareAccess(pDraw, EXA_PREPARE_DEST);
fbRasterizeTrapezoid(pPicture, trap, x_off, y_off);
- exaGetDrawableDeltas(pDraw, pixmaps[0].pPix, &xoff, &yoff);
- exaPixmapDirty(pixmaps[0].pPix, pDraw->x + xoff, pDraw->y + yoff,
+ exaGetDrawableDeltas(pDraw, pPixmap, &xoff, &yoff);
+ exaPixmapDirty(pPixmap, pDraw->x + xoff, pDraw->y + yoff,
pDraw->x + xoff + pDraw->width,
pDraw->y + yoff + pDraw->height);
exaFinishAccess(pDraw, EXA_PREPARE_DEST);
@@ -915,18 +909,13 @@ exaAddTriangles (PicturePtr pPicture, IN
xTriangle *tris)
{
DrawablePtr pDraw = pPicture->pDrawable;
- ExaMigrationRec pixmaps[1];
+ PixmapPtr pPixmap = exaGetDrawablePixmap(pDraw);
int xoff, yoff;
- pixmaps[0].as_dst = TRUE;
- pixmaps[0].as_src = TRUE;
- pixmaps[0].pPix = exaGetDrawablePixmap (pDraw);
- exaDoMigration(pixmaps, 1, FALSE);
-
exaPrepareAccess(pDraw, EXA_PREPARE_DEST);
fbAddTriangles(pPicture, x_off, y_off, ntri, tris);
- exaGetDrawableDeltas(pDraw, pixmaps[0].pPix, &xoff, &yoff);
- exaPixmapDirty(pixmaps[0].pPix, pDraw->x + xoff, pDraw->y + yoff,
+ exaGetDrawableDeltas(pDraw, pPixmap, &xoff, &yoff);
+ exaPixmapDirty(pPixmap, pDraw->x + xoff, pDraw->y + yoff,
pDraw->x + xoff + pDraw->width,
pDraw->y + yoff + pDraw->height);
exaFinishAccess(pDraw, EXA_PREPARE_DEST);
diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c
index 8db2866..8dadd06 100644
--- a/exa/exa_unaccel.c
+++ b/exa/exa_unaccel.c
@@ -41,7 +41,7 @@ void
exaPrepareAccessGC(GCPtr pGC)
{
if (pGC->stipple)
- exaPrepareAccess(&pGC->stipple->drawable, EXA_PREPARE_SRC);
+ exaPrepareAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK);
if (pGC->fillStyle == FillTiled)
exaPrepareAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC);
}
@@ -53,7 +53,7 @@ void
exaFinishAccessGC(GCPtr pGC)
{
if (pGC->fillStyle == FillTiled)
- exaFinishAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC);
+ exaFinishAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_MASK);
if (pGC->stipple)
exaFinishAccess(&pGC->stipple->drawable, EXA_PREPARE_SRC);
}
@@ -358,7 +358,6 @@ exaGetPixmapFirstPixel (PixmapPtr pPixma
void *fb;
Bool need_finish = FALSE;
BoxRec box;
- ExaMigrationRec pixmaps[1];
ExaPixmapPriv (pPixmap);
fb = pExaPixmap->sys_ptr;
@@ -368,10 +367,6 @@ exaGetPixmapFirstPixel (PixmapPtr pPixma
miPointInRegion(DamageRegion(pExaPixmap->pDamage), 0, 0, &box))
{
need_finish = TRUE;
- pixmaps[0].as_dst = FALSE;
- pixmaps[0].as_src = TRUE;
- pixmaps[0].pPix = pPixmap;
- exaDoMigration (pixmaps, 1, FALSE);
exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
fb = pPixmap->devPrivate.ptr;
}
diff-tree 3a4873a46093c37a707e6be0c336a57ab67115ab (from aa7ed1f5f35cd043bc38d985500aa0a32e857e84)
Author: Dave Airlie <airlied at linux.ie>
Date: Tue Jul 17 17:16:51 2007 +1000
EXA: Add a couple of missing exaPrepare/FinishAccess calls.
diff --git a/exa/exa.c b/exa/exa.c
index 99707fa..46fb557 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -452,11 +452,9 @@ exaValidateGC (GCPtr pGC, unsigned long
if (!pGC->tileIsPixel && FbEvenTile (pGC->tile.pixmap->drawable.width *
pDrawable->bitsPerPixel))
{
- /* XXX This fixes corruption with tiled pixmaps, but may just be a
- * workaround for broken drivers
- */
- exaMoveOutPixmap(pGC->tile.pixmap);
+ exaPrepareAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC);
fbPadPixmap (pGC->tile.pixmap);
+ exaFinishAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC);
exaPixmapDirty(pGC->tile.pixmap, 0, 0,
pGC->tile.pixmap->drawable.width,
pGC->tile.pixmap->drawable.height);
@@ -467,7 +465,9 @@ exaValidateGC (GCPtr pGC, unsigned long
changes &= ~GCTile;
}
+ exaPrepareAccessGC(pGC);
fbValidateGC (pGC, changes, pDrawable);
+ exaFinishAccessGC(pGC);
pGC->ops = (GCOps *) &exaOps;
}
@@ -497,6 +497,47 @@ exaCreateGC (GCPtr pGC)
return TRUE;
}
+void
+exaPrepareAccessWindow(WindowPtr pWin)
+{
+ if (pWin->backgroundState == BackgroundPixmap)
+ exaPrepareAccess(&pWin->background.pixmap->drawable, EXA_PREPARE_SRC);
+
+ if (pWin->borderIsPixel == FALSE)
+ exaPrepareAccess(&pWin->border.pixmap->drawable, EXA_PREPARE_SRC);
+}
+
+void
+exaFinishAccessWindow(WindowPtr pWin)
+{
+ if (pWin->backgroundState == BackgroundPixmap)
+ exaFinishAccess(&pWin->background.pixmap->drawable, EXA_PREPARE_SRC);
+
+ if (pWin->borderIsPixel == FALSE)
+ exaFinishAccess(&pWin->border.pixmap->drawable, EXA_PREPARE_SRC);
+}
+
+static Bool
+exaChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
+{
+ Bool ret;
+
+ exaPrepareAccessWindow(pWin);
+ ret = fbChangeWindowAttributes(pWin, mask);
+ exaFinishAccessWindow(pWin);
+ return ret;
+}
+
+static RegionPtr
+exaBitmapToRegion(PixmapPtr pPix)
+{
+ RegionPtr ret;
+ exaPrepareAccess(&pPix->drawable, EXA_PREPARE_SRC);
+ ret = fbPixmapToRegion(pPix);
+ exaFinishAccess(&pPix->drawable, EXA_PREPARE_SRC);
+ return ret;
+}
+
/**
* exaCloseScreen() unwraps its wrapped screen functions and tears down EXA's
* screen private, before calling down to the next CloseSccreen.
@@ -518,6 +559,8 @@ exaCloseScreen(int i, ScreenPtr pScreen)
pScreen->CreatePixmap = pExaScr->SavedCreatePixmap;
pScreen->DestroyPixmap = pExaScr->SavedDestroyPixmap;
pScreen->CopyWindow = pExaScr->SavedCopyWindow;
+ pScreen->ChangeWindowAttributes = pExaScr->SavedChangeWindowAttributes;
+ pScreen->BitmapToRegion = pExaScr->SavedBitmapToRegion;
#ifdef RENDER
if (ps) {
ps->Composite = pExaScr->SavedComposite;
@@ -660,6 +703,12 @@ exaDriverInit (ScreenPtr pScreen,
pExaScr->SavedCopyWindow = pScreen->CopyWindow;
pScreen->CopyWindow = exaCopyWindow;
+ pExaScr->SavedChangeWindowAttributes = pScreen->ChangeWindowAttributes;
+ pScreen->ChangeWindowAttributes = exaChangeWindowAttributes;
+
+ pExaScr->SavedBitmapToRegion = pScreen->BitmapToRegion;
+ pScreen->BitmapToRegion = exaBitmapToRegion;
+
pExaScr->SavedPaintWindowBackground = pScreen->PaintWindowBackground;
pScreen->PaintWindowBackground = exaPaintWindow;
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index a456da0..a08acfa 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -106,6 +106,8 @@ typedef struct {
DestroyPixmapProcPtr SavedDestroyPixmap;
PaintWindowBorderProcPtr SavedPaintWindowBorder;
CopyWindowProcPtr SavedCopyWindow;
+ ChangeWindowAttributesProcPtr SavedChangeWindowAttributes;
+ BitmapToRegionProcPtr SavedBitmapToRegion;
#ifdef RENDER
CompositeProcPtr SavedComposite;
RasterizeTrapezoidProcPtr SavedRasterizeTrapezoid;
@@ -113,6 +115,7 @@ typedef struct {
GlyphsProcPtr SavedGlyphs;
TrapezoidsProcPtr SavedTrapezoids;
#endif
+
Bool swappedOut;
enum ExaMigrationHeuristic migration;
Bool hideOffscreenPixmapData;
@@ -190,6 +193,12 @@ typedef struct _ExaMigrationRec {
*/
void exaDDXDriverInit (ScreenPtr pScreen);
+void
+exaPrepareAccessWindow(WindowPtr pWin);
+
+void
+exaFinishAccessWindow(WindowPtr pWin);
+
/* exa_unaccel.c */
void
exaPrepareAccessGC(GCPtr pGC);
diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c
index d793ec2..8db2866 100644
--- a/exa/exa_unaccel.c
+++ b/exa/exa_unaccel.c
@@ -35,10 +35,13 @@
*
* Solid doesn't use an extra pixmap source, and Stippled/OpaqueStippled are
* 1bpp and never in fb, so we don't worry about them.
+ * We should worry about them for completeness sake and going forward.
*/
void
exaPrepareAccessGC(GCPtr pGC)
{
+ if (pGC->stipple)
+ exaPrepareAccess(&pGC->stipple->drawable, EXA_PREPARE_SRC);
if (pGC->fillStyle == FillTiled)
exaPrepareAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC);
}
@@ -51,6 +54,8 @@ exaFinishAccessGC(GCPtr pGC)
{
if (pGC->fillStyle == FillTiled)
exaFinishAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC);
+ if (pGC->stipple)
+ exaFinishAccess(&pGC->stipple->drawable, EXA_PREPARE_SRC);
}
#if DEBUG_TRACE_FALL
@@ -294,7 +299,9 @@ ExaCheckPaintWindow (WindowPtr pWin, Reg
EXA_FALLBACK(("from %p (%c)\n", pWin,
exaDrawableLocation(&pWin->drawable)));
exaPrepareAccess (&pWin->drawable, EXA_PREPARE_DEST);
+ exaPrepareAccessWindow(pWin);
fbPaintWindow (pWin, pRegion, what);
+ exaFinishAccessWindow(pWin);
exaFinishAccess (&pWin->drawable, EXA_PREPARE_DEST);
}
More information about the xorg-commit
mailing list