xserver: Branch 'master' - 8 commits
Keith Packard
keithp at kemper.freedesktop.org
Tue Dec 29 16:11:56 PST 2009
exa/exa.c | 6
exa/exa_accel.c | 46 +----
exa/exa_migration_classic.c | 3
exa/exa_migration_mixed.c | 55 +++---
exa/exa_mixed.c | 18 ++
exa/exa_priv.h | 15 +
exa/exa_unaccel.c | 347 +++++++++++++++++++++++++++++++++++---------
7 files changed, 347 insertions(+), 143 deletions(-)
New commits:
commit db2c6f7c91289b5d49978974093a1002b3b53a56
Author: Michel Dänzer <daenzer at vmware.com>
Date: Tue Dec 29 15:48:44 2009 +0100
EXA: Don't use UTS/DFS directly for Put/GetImage when there's a system copy.
We want to save the result in the system memory copy, in case we'll need it
again for subsequent software fallbacks.
Signed-off-by: Michel Dänzer <daenzer at vmware.com>
Acked-By: Maarten Maathuis <madman2003 at gmail.com>
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index f34b7a7..4c55a4c 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -157,6 +157,10 @@ exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
if (pExaScr->fallback_counter || pExaPixmap->accel_blocked || !pExaScr->info->UploadToScreen)
return FALSE;
+ /* If there's a system copy, we want to save the result there */
+ if (pExaPixmap->pDamage)
+ return FALSE;
+
/* Don't bother with under 8bpp, XYPixmaps. */
if (format != ZPixmap || bpp < 8)
return FALSE;
@@ -168,17 +172,6 @@ exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
if (pExaScr->swappedOut)
return FALSE;
- if (pExaScr->do_migration) {
- ExaMigrationRec pixmaps[1];
-
- 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)
@@ -1261,35 +1254,16 @@ exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h,
{
ExaScreenPriv (pDrawable->pScreen);
PixmapPtr pPix = exaGetDrawablePixmap (pDrawable);
+ ExaPixmapPriv(pPix);
int xoff, yoff;
Bool ok;
if (pExaScr->fallback_counter || pExaScr->swappedOut)
goto fallback;
- exaGetDrawableDeltas (pDrawable, pPix, &xoff, &yoff);
-
- if (pExaScr->do_migration) {
- BoxRec Box;
- RegionRec Reg;
- ExaMigrationRec pixmaps[1];
-
- Box.x1 = pDrawable->x + x + xoff;
- Box.y1 = pDrawable->y + y + yoff;
- Box.x2 = Box.x1 + w;
- Box.y2 = Box.y1 + h;
-
- REGION_INIT(pScreen, &Reg, &Box, 1);
-
- pixmaps[0].as_dst = FALSE;
- pixmaps[0].as_src = TRUE;
- pixmaps[0].pPix = pPix;
- pixmaps[0].pReg = &Reg;
-
- exaDoMigration(pixmaps, 1, FALSE);
-
- REGION_UNINIT(pScreen, &Reg);
- }
+ /* If there's a system copy, we want to save the result there */
+ if (pExaPixmap->pDamage)
+ goto fallback;
pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
commit f28ca728e90ccbb901e8e7215a842525d8e786d3
Author: Thomas Hellstrom <thellstrom at vmware.com>
Date: Tue Dec 29 12:51:30 2009 +0100
EXA: Restrict the regions that need to be migrated for composite fallback for src / mask pictures.
[ Michel: Minor fixups to address compiler warnings ]
Signed-off-by: Thomas Hellstrom <thellstrom at vmware.com>
Signed-off-by: Michel Dänzer <daenzer at vmware.com>
Acked-by: Maarten Maathuis <madman2003 at gmail.com>
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index c559b9a..21d9646 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -165,6 +165,7 @@ typedef struct {
BitmapToRegionProcPtr SavedBitmapToRegion;
CreateScreenResourcesProcPtr SavedCreateScreenResources;
ModifyPixmapHeaderProcPtr SavedModifyPixmapHeader;
+ SourceValidateProcPtr SavedSourceValidate;
#ifdef RENDER
CompositeProcPtr SavedComposite;
TrianglesProcPtr SavedTriangles;
@@ -201,6 +202,15 @@ typedef struct {
unsigned int fallback_counter;
ExaGlyphCacheRec glyphCaches[EXA_NUM_GLYPH_CACHES];
+
+ /**
+ * Regions affected by fallback composite source / mask operations.
+ */
+
+ RegionRec srcReg;
+ RegionRec maskReg;
+ PixmapPtr srcPix;
+
} ExaScreenPrivRec, *ExaScreenPrivPtr;
/*
diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c
index a97a309..b4ead7f 100644
--- a/exa/exa_unaccel.c
+++ b/exa/exa_unaccel.c
@@ -435,6 +435,173 @@ ExaCheckGetSpans (DrawablePtr pDrawable,
EXA_POST_FALLBACK(pScreen);
}
+static void
+ExaSrcValidate(DrawablePtr pDrawable,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ ExaScreenPriv(pScreen);
+ PixmapPtr pPix = exaGetDrawablePixmap (pDrawable);
+ BoxRec box;
+ RegionRec reg;
+ RegionPtr dst;
+ int xoff, yoff;
+
+ exaGetDrawableDeltas(pDrawable, pPix, &xoff, &yoff);
+
+ box.x1 = x + xoff;
+ box.y1 = y + yoff;
+ box.x2 = box.x1 + width;
+ box.y2 = box.y1 + height;
+
+ dst = (pExaScr->srcPix == pPix) ? &pExaScr->srcReg :
+ &pExaScr->maskReg;
+
+ REGION_INIT(pScreen, ®, &box, 1);
+ REGION_UNION(pScreen, dst, dst, ®);
+ REGION_UNINIT(pScreen, ®);
+
+ swap(pExaScr, pScreen, SourceValidate);
+ pScreen->SourceValidate(pDrawable, x, y, width, height);
+ swap(pExaScr, pScreen, SourceValidate);
+}
+
+static Bool
+ExaPrepareCompositeReg(ScreenPtr pScreen,
+ CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ RegionRec region;
+ RegionPtr dstReg = NULL;
+ RegionPtr srcReg = NULL;
+ RegionPtr maskReg = NULL;
+ PixmapPtr pSrcPix = NULL;
+ PixmapPtr pMaskPix = NULL;
+ PixmapPtr pDstPix;
+ ExaScreenPriv(pScreen);
+ Bool ret;
+
+
+ REGION_NULL(pScreen, ®ion);
+
+ if (pSrc->pDrawable) {
+ pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
+ REGION_NULL(pScreen, &pExaScr->srcReg);
+ srcReg = &pExaScr->srcReg;
+ pExaScr->srcPix = pSrcPix;
+ if (pSrc != pDst)
+ REGION_TRANSLATE(pScreen, pSrc->pCompositeClip,
+ -pSrc->pDrawable->x,
+ -pSrc->pDrawable->y);
+ }
+
+ if (pMask && pMask->pDrawable) {
+ pMaskPix = exaGetDrawablePixmap(pMask->pDrawable);
+ REGION_NULL(pScreen, &pExaScr->maskReg);
+ maskReg = &pExaScr->maskReg;
+ if (pMask != pDst && pMask != pSrc)
+ REGION_TRANSLATE(pScreen, pMask->pCompositeClip,
+ -pMask->pDrawable->x,
+ -pMask->pDrawable->y);
+ }
+
+ REGION_TRANSLATE(pScreen, pDst->pCompositeClip,
+ -pDst->pDrawable->x,
+ -pDst->pDrawable->y);
+
+ pExaScr->SavedSourceValidate = ExaSrcValidate;
+ swap(pExaScr, pScreen, SourceValidate);
+ ret = miComputeCompositeRegion (®ion, pSrc, pMask, pDst,
+ xSrc, ySrc, xMask, yMask,
+ xDst,
+ yDst,
+ width, height);
+ swap(pExaScr, pScreen, SourceValidate);
+
+ REGION_TRANSLATE(pScreen, pDst->pCompositeClip,
+ pDst->pDrawable->x,
+ pDst->pDrawable->y);
+ if (pSrc->pDrawable && pSrc != pDst)
+ REGION_TRANSLATE(pScreen, pSrc->pCompositeClip,
+ pSrc->pDrawable->x,
+ pSrc->pDrawable->y);
+ if (pMask && pMask->pDrawable && pMask != pDst && pMask != pSrc)
+ REGION_TRANSLATE(pScreen, pMask->pCompositeClip,
+ pMask->pDrawable->x,
+ pMask->pDrawable->y);
+
+ if (!ret) {
+ if (srcReg)
+ REGION_UNINIT(pScreen, srcReg);
+ if (maskReg)
+ REGION_UNINIT(pScreen, maskReg);
+
+ return FALSE;
+ }
+
+ /**
+ * Don't limit alphamaps readbacks for now until we've figured out how that
+ * should be done.
+ */
+
+ if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
+ pExaScr->prepare_access_reg(exaGetDrawablePixmap(pSrc->alphaMap->pDrawable),
+ EXA_PREPARE_AUX_SRC,
+ NULL);
+ if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
+ pExaScr->prepare_access_reg(exaGetDrawablePixmap(pMask->alphaMap->pDrawable),
+ EXA_PREPARE_AUX_MASK,
+ NULL);
+
+ if (pSrcPix)
+ pExaScr->prepare_access_reg(pSrcPix,
+ EXA_PREPARE_SRC,
+ srcReg);
+
+ if (pMaskPix)
+ pExaScr->prepare_access_reg(pMaskPix,
+ EXA_PREPARE_MASK,
+ maskReg);
+
+ if (srcReg)
+ REGION_UNINIT(pScreen, srcReg);
+ if (maskReg)
+ REGION_UNINIT(pScreen, maskReg);
+
+ pDstPix = exaGetDrawablePixmap(pDst->pDrawable);
+ if (!exaOpReadsDestination(op)) {
+ int xoff;
+ int yoff;
+
+ exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &xoff, &yoff);
+ REGION_TRANSLATE(pScreen, ®ion, pDst->pDrawable->x + xoff,
+ pDst->pDrawable->y + yoff);
+ dstReg = ®ion;
+ }
+
+ if (pDst->alphaMap && pDst->alphaMap->pDrawable)
+ pExaScr->prepare_access_reg(exaGetDrawablePixmap(pDst->alphaMap->pDrawable),
+ EXA_PREPARE_AUX_DEST,
+ dstReg);
+ pExaScr->prepare_access_reg(pDstPix, EXA_PREPARE_DEST, dstReg);
+
+ REGION_UNINIT(pScreen, ®ion);
+ return TRUE;
+}
+
void
ExaCheckComposite (CARD8 op,
PicturePtr pSrc,
@@ -453,54 +620,38 @@ ExaCheckComposite (CARD8 op,
#ifdef RENDER
PictureScreenPtr ps = GetPictureScreen(pScreen);
#endif /* RENDER */
- RegionRec region;
- int xoff, yoff;
EXA_PRE_FALLBACK(pScreen);
- REGION_NULL(pScreen, ®ion);
-
- /* We need to prepare access to any separate alpha maps first, in case the
- * driver doesn't support EXA_PREPARE_AUX*, in which case EXA_PREPARE_SRC
- * may be used for moving them out.
- */
- if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
- exaPrepareAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC);
- if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
- exaPrepareAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK);
-
- if (!exaOpReadsDestination(op) && pExaScr->prepare_access_reg) {
- PixmapPtr pDstPix;
-
- if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst,
- xSrc, ySrc, xMask, yMask,
- xDst + pDst->pDrawable->x,
- yDst + pDst->pDrawable->y,
- width, height))
- goto skip;
-
- pDstPix = exaGetDrawablePixmap(pDst->pDrawable);
- exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &xoff, &yoff);
- REGION_TRANSLATE(pScreen, ®ion, xoff, yoff);
+ if (pExaScr->prepare_access_reg) {
+ if (!ExaPrepareCompositeReg(pScreen, op, pSrc, pMask, pDst, xSrc,
+ ySrc, xMask, yMask, xDst, yDst, width,
+ height))
+ goto out_no_clip;
+ } else {
- if (pDst->alphaMap && pDst->alphaMap->pDrawable)
- pExaScr->prepare_access_reg(exaGetDrawablePixmap(pDst->alphaMap->pDrawable),
- EXA_PREPARE_AUX_DEST, ®ion);
+ /* We need to prepare access to any separate alpha maps first,
+ * in case the driver doesn't support EXA_PREPARE_AUX*,
+ * in which case EXA_PREPARE_SRC may be used for moving them out.
+ */
- pExaScr->prepare_access_reg(pDstPix, EXA_PREPARE_DEST, ®ion);
- } else {
+ if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
+ exaPrepareAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC);
+ if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
+ exaPrepareAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK);
if (pDst->alphaMap && pDst->alphaMap->pDrawable)
exaPrepareAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST);
exaPrepareAccess (pDst->pDrawable, EXA_PREPARE_DEST);
- }
- EXA_FALLBACK(("from picts %p/%p to pict %p\n",
- pSrc, pMask, pDst));
+ EXA_FALLBACK(("from picts %p/%p to pict %p\n",
+ pSrc, pMask, pDst));
+
+ if (pSrc->pDrawable != NULL)
+ exaPrepareAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
+ if (pMask && pMask->pDrawable != NULL)
+ exaPrepareAccess (pMask->pDrawable, EXA_PREPARE_MASK);
+ }
- if (pSrc->pDrawable != NULL)
- exaPrepareAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
- if (pMask && pMask->pDrawable != NULL)
- exaPrepareAccess (pMask->pDrawable, EXA_PREPARE_MASK);
#ifdef RENDER
swap(pExaScr, ps, Composite);
ps->Composite (op,
@@ -524,14 +675,12 @@ ExaCheckComposite (CARD8 op,
exaFinishAccess (pDst->pDrawable, EXA_PREPARE_DEST);
if (pDst->alphaMap && pDst->alphaMap->pDrawable)
exaFinishAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST);
-
-skip:
if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
exaFinishAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC);
if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
exaFinishAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK);
- REGION_UNINIT(pScreen, ®ion);
+out_no_clip:
EXA_POST_FALLBACK(pScreen);
}
commit 0c1f43c0f3e888172f11f62a2f208af70e0183cc
Author: Michel Dänzer <daenzer at vmware.com>
Date: Tue Dec 29 12:51:29 2009 +0100
EXA/mixed: Handle results of software fallbacks in DamageReport hook.
This is more elegant and probably also slightly more correct than doing it
at FinishAccess time.
Signed-off-by: Michel Dänzer <daenzer at vmware.com>
Acked-by: Maarten Maathuis <madman2003 at gmail.com>
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/exa/exa.c b/exa/exa.c
index b3c5bff..c5ac7de 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -425,9 +425,6 @@ exaFinishAccess(DrawablePtr pDrawable, int index)
/* We always hide the devPrivate.ptr. */
pPixmap->devPrivate.ptr = NULL;
- if (pExaScr->finish_access)
- pExaScr->finish_access(pPixmap, index);
-
if (!pExaScr->info->FinishAccess || !exaPixmapHasGpuCopy(pPixmap))
return;
@@ -981,7 +978,6 @@ exaDriverInit (ScreenPtr pScreen,
pExaScr->do_move_in_pixmap = exaMoveInPixmap_mixed;
pExaScr->do_move_out_pixmap = NULL;
pExaScr->prepare_access_reg = exaPrepareAccessReg_mixed;
- pExaScr->finish_access = exaFinishAccess_mixed;
} else {
wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmap_driver);
wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmap_driver);
@@ -991,7 +987,6 @@ exaDriverInit (ScreenPtr pScreen,
pExaScr->do_move_in_pixmap = NULL;
pExaScr->do_move_out_pixmap = NULL;
pExaScr->prepare_access_reg = NULL;
- pExaScr->finish_access = NULL;
}
} else {
wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmap_classic);
@@ -1002,7 +997,6 @@ exaDriverInit (ScreenPtr pScreen,
pExaScr->do_move_in_pixmap = exaMoveInPixmap_classic;
pExaScr->do_move_out_pixmap = exaMoveOutPixmap_classic;
pExaScr->prepare_access_reg = exaPrepareAccessReg_classic;
- pExaScr->finish_access = NULL;
}
if (!(pExaScr->info->flags & EXA_HANDLES_PIXMAPS)) {
LogMessage(X_INFO, "EXA(%d): Offscreen pixmap area of %lu bytes\n",
diff --git a/exa/exa_migration_mixed.c b/exa/exa_migration_mixed.c
index 14cb5a7..6816e6c 100644
--- a/exa/exa_migration_mixed.c
+++ b/exa/exa_migration_mixed.c
@@ -134,10 +134,32 @@ exaMoveInPixmap_mixed(PixmapPtr pPixmap)
exaDoMigration(pixmaps, 1, TRUE);
}
+void
+exaDamageReport_mixed(DamagePtr pDamage, RegionPtr pRegion, void *closure)
+{
+ PixmapPtr pPixmap = closure;
+ ExaPixmapPriv(pPixmap);
+
+ /* Move back results of software rendering on system memory copy of mixed driver
+ * pixmap (see exaPrepareAccessReg_mixed).
+ *
+ * Defer moving the destination back into the driver pixmap, to try and save
+ * overhead on multiple subsequent software fallbacks.
+ */
+ if (!pExaPixmap->use_gpu_copy && exaPixmapHasGpuCopy(pPixmap)) {
+ ExaScreenPriv(pPixmap->drawable.pScreen);
+
+ if (pExaScr->deferred_mixed_pixmap &&
+ pExaScr->deferred_mixed_pixmap != pPixmap)
+ exaMoveInPixmap_mixed(pExaScr->deferred_mixed_pixmap);
+ pExaScr->deferred_mixed_pixmap = pPixmap;
+ }
+}
+
/* With mixed pixmaps, if we fail to get direct access to the driver pixmap, we
* use the DownloadFromScreen hook to retrieve contents to a copy in system
* memory, perform software rendering on that and move back the results with the
- * UploadToScreen hook (see exaFinishAccess_mixed).
+ * UploadToScreen hook (see exaDamageReport_mixed).
*/
void
exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg)
@@ -172,8 +194,9 @@ exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg)
Bool as_dst = pixmaps[0].as_dst;
/* Set up damage tracking */
- pExaPixmap->pDamage = DamageCreate(NULL, NULL, DamageReportNone,
- TRUE, pPixmap->drawable.pScreen,
+ pExaPixmap->pDamage = DamageCreate(exaDamageReport_mixed, NULL,
+ DamageReportNonEmpty, TRUE,
+ pPixmap->drawable.pScreen,
pPixmap);
DamageRegister(&pPixmap->drawable, pExaPixmap->pDamage);
@@ -224,29 +247,3 @@ exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg)
}
}
-/* Move back results of software rendering on system memory copy of mixed driver
- * pixmap (see exaPrepareAccessReg_mixed).
- *
- * Defer moving the destination back into the driver pixmap, to try and save
- * overhead on multiple consequent software fallbacks.
- */
-void exaFinishAccess_mixed(PixmapPtr pPixmap, int index)
-{
- ExaPixmapPriv(pPixmap);
-
- if (pExaPixmap->pDamage && !pExaPixmap->use_gpu_copy &&
- exaPixmapHasGpuCopy(pPixmap)) {
- DamageRegionProcessPending(&pPixmap->drawable);
-
- if (index == EXA_PREPARE_DEST || index == EXA_PREPARE_AUX_DEST) {
- ExaScreenPriv(pPixmap->drawable.pScreen);
-
- if (pExaScr->deferred_mixed_pixmap &&
- pExaScr->deferred_mixed_pixmap != pPixmap)
- exaMoveInPixmap_mixed(pExaScr->deferred_mixed_pixmap);
- pExaScr->deferred_mixed_pixmap = pPixmap;
- pPixmap->devKind = pExaPixmap->fb_pitch;
- } else
- exaMoveInPixmap_mixed(pPixmap);
- }
-}
diff --git a/exa/exa_mixed.c b/exa/exa_mixed.c
index b262fc7..21cc3bd 100644
--- a/exa/exa_mixed.c
+++ b/exa/exa_mixed.c
@@ -101,7 +101,7 @@ exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth,
pExaPixmap->sys_ptr = malloc((pPixmap->drawable.bitsPerPixel + 7) / 8);
/* Set up damage tracking */
- pExaPixmap->pDamage = DamageCreate(NULL, NULL,
+ pExaPixmap->pDamage = DamageCreate(exaDamageReport_mixed, NULL,
DamageReportNonEmpty, TRUE,
pPixmap->drawable.pScreen,
pPixmap);
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index 0852355..c559b9a 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -177,7 +177,6 @@ typedef struct {
void (*do_move_in_pixmap) (PixmapPtr pPixmap);
void (*do_move_out_pixmap) (PixmapPtr pPixmap);
void (*prepare_access_reg)(PixmapPtr pPixmap, int index, RegionPtr pReg);
- void (*finish_access)(PixmapPtr pPixmap, int index);
Bool swappedOut;
enum ExaMigrationHeuristic migration;
@@ -620,10 +619,10 @@ void
exaMoveInPixmap_mixed(PixmapPtr pPixmap);
void
-exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg);
+exaDamageReport_mixed(DamagePtr pDamage, RegionPtr pRegion, void *closure);
void
-exaFinishAccess_mixed(PixmapPtr pPixmap, int index);
+exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg);
/* exa_render.c */
Bool
commit 08bf26c28fc8147b64f2fe8345b9581e0101571c
Author: Michel Dänzer <daenzer at vmware.com>
Date: Tue Dec 29 12:51:28 2009 +0100
EXA: Fix migration avoidance for 1x1 pixmaps.
Signed-off-by: Michel Dänzer <daenzer at vmware.com>
Acked-by: Maarten Maathuis <madman2003 at gmail.com>
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index c56c6bc..f34b7a7 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -1043,6 +1043,7 @@ exaFillRegionSolid (DrawablePtr pDrawable, RegionPtr pRegion, Pixel pixel,
pDrawable->width == 1 && pDrawable->height == 1 &&
pDrawable->bitsPerPixel != 24) {
ExaPixmapPriv(pPixmap);
+ RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
switch (pDrawable->bitsPerPixel) {
case 32:
@@ -1057,6 +1058,9 @@ exaFillRegionSolid (DrawablePtr pDrawable, RegionPtr pRegion, Pixel pixel,
REGION_UNION(pScreen, &pExaPixmap->validSys, &pExaPixmap->validSys,
pRegion);
+ REGION_UNION(pScreen, &pExaPixmap->validFB, &pExaPixmap->validFB,
+ pRegion);
+ REGION_SUBTRACT(pScreen, pending_damage, pending_damage, pRegion);
}
ret = TRUE;
diff --git a/exa/exa_mixed.c b/exa/exa_mixed.c
index 155ed47..b262fc7 100644
--- a/exa/exa_mixed.c
+++ b/exa/exa_mixed.c
@@ -94,9 +94,25 @@ exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth,
if (!w || !h) {
exaCreateDriverPixmap_mixed(pPixmap);
pExaPixmap->use_gpu_copy = exaPixmapHasGpuCopy(pPixmap);
- } else
+ } else {
pExaPixmap->use_gpu_copy = FALSE;
+ if (w == 1 && h == 1) {
+ pExaPixmap->sys_ptr = malloc((pPixmap->drawable.bitsPerPixel + 7) / 8);
+
+ /* Set up damage tracking */
+ pExaPixmap->pDamage = DamageCreate(NULL, NULL,
+ DamageReportNonEmpty, TRUE,
+ pPixmap->drawable.pScreen,
+ pPixmap);
+
+ DamageRegister(&pPixmap->drawable, pExaPixmap->pDamage);
+ /* This ensures that pending damage reflects the current operation. */
+ /* This is used by exa to optimize migration. */
+ DamageSetReportAfterOp(pExaPixmap->pDamage, TRUE);
+ }
+ }
+
/* During a fallback we must prepare access. */
if (pExaScr->fallback_counter)
exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST);
commit 0bd8f0cd7f3823ee17ae8c88fd3e004bfff9982d
Author: Michel Dänzer <daenzer at vmware.com>
Date: Tue Dec 29 12:51:27 2009 +0100
EXA/classic: Fix crash with migration heuristic "smart".
Signed-off-by: Michel Dänzer <daenzer at vmware.com>
Acked-by: Maarten Maathuis <madman2003 at gmail.com>
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/exa/exa_migration_classic.c b/exa/exa_migration_classic.c
index 95189be..871679f 100644
--- a/exa/exa_migration_classic.c
+++ b/exa/exa_migration_classic.c
@@ -75,6 +75,9 @@ exaPixmapIsDirty (PixmapPtr pPix)
if (pExaPixmap == NULL)
EXA_FatalErrorDebugWithRet(("EXA bug: exaPixmapIsDirty was called on a non-exa pixmap.\n"), TRUE);
+ if (!pExaPixmap->pDamage)
+ return FALSE;
+
return REGION_NOTEMPTY (pScreen, DamageRegion(pExaPixmap->pDamage)) ||
!REGION_EQUAL(pScreen, &pExaPixmap->validSys, &pExaPixmap->validFB);
}
commit 40453bf7718f1c3d672b87e9d84991032cbef859
Author: Thomas Hellstrom <thellstrom at vmware.com>
Date: Tue Dec 29 09:34:44 2009 +0100
EXA: Limit src prepareAccess regions for a number of unaccelerated operations.
When we can trivially calculate the affected source regions,
do that before calling region bounded prepareAccess.
[ Michel: Minor fixups to address compiler warnings ]
Signed-off-by: Thomas Hellstrom <thellstrom at vmware.com>
Signed-off-by: Michel Dänzer <daenzer at vmware.com>
Acked-by: Maarten Maathuis <madman2003 at gmail.com>
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c
index f077fc8..a97a309 100644
--- a/exa/exa_unaccel.c
+++ b/exa/exa_unaccel.c
@@ -123,11 +123,36 @@ ExaCheckCopyNtoN (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
BoxPtr pbox, int nbox, int dx, int dy, Bool reverse,
Bool upsidedown, Pixel bitplane, void *closure)
{
+ RegionRec reg;
+ int xoff, yoff;
EXA_PRE_FALLBACK_GC(pGC);
EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
- exaPrepareAccess (pDst, EXA_PREPARE_DEST);
- exaPrepareAccess (pSrc, EXA_PREPARE_SRC);
+
+ if (pExaScr->prepare_access_reg) {
+ PixmapPtr pPixmap = exaGetDrawablePixmap(pSrc);
+
+ exaGetDrawableDeltas(pSrc, pPixmap, &xoff, &yoff);
+ REGION_INIT(pScreen, ®, pbox, nbox);
+ REGION_TRANSLATE(pScreen, ®, xoff + dx, yoff + dy);
+ pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, ®);
+ REGION_UNINIT(pScreen, ®);
+ } else
+ exaPrepareAccess (pSrc, EXA_PREPARE_SRC);
+
+ if (pExaScr->prepare_access_reg &&
+ !exaGCReadsDestination(pDst, pGC->planemask, pGC->fillStyle,
+ pGC->alu, pGC->clientClipType)) {
+ PixmapPtr pPixmap = exaGetDrawablePixmap(pDst);
+
+ exaGetDrawableDeltas(pSrc, pPixmap, &xoff, &yoff);
+ REGION_INIT(pScreen, ®, pbox, nbox);
+ REGION_TRANSLATE(pScreen, ®, xoff, yoff);
+ pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST, ®);
+ REGION_UNINIT(pScreen, ®);
+ } else
+ exaPrepareAccess (pDst, EXA_PREPARE_DEST);
+
/* This will eventually call fbCopyNtoN, with some calculation overhead. */
while (nbox--) {
pGC->ops->CopyArea (pSrc, pDst, pGC, pbox->x1 - pSrc->x + dx, pbox->y1 - pSrc->y + dy,
@@ -139,6 +164,40 @@ ExaCheckCopyNtoN (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
EXA_POST_FALLBACK_GC(pGC);
}
+static void
+ExaFallbackPrepareReg(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x, int y, int width, int height,
+ int index, Bool checkReads)
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ ExaScreenPriv(pScreen);
+
+ if (pExaScr->prepare_access_reg &&
+ !(checkReads && exaGCReadsDestination(pDrawable,
+ pGC->planemask,
+ pGC->fillStyle,
+ pGC->alu,
+ pGC->clientClipType))) {
+ BoxRec box;
+ RegionRec reg;
+ int xoff, yoff;
+ PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
+
+ exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
+ box.x1 = pDrawable->x + x + xoff;
+ box.y1 = pDrawable->y + y + yoff;
+ box.x2 = box.x1 + width;
+ box.y2 = box.y1 + height;
+
+ REGION_INIT(pScreen, ®, &box, 1);
+ pExaScr->prepare_access_reg(pPixmap, index, ®);
+ REGION_UNINIT(pScreen, ®);
+ } else
+ exaPrepareAccess(pDrawable, index);
+}
+
+
RegionPtr
ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
int srcx, int srcy, int w, int h, int dstx, int dsty)
@@ -148,8 +207,10 @@ ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
EXA_PRE_FALLBACK_GC(pGC);
EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
- exaPrepareAccess (pDst, EXA_PREPARE_DEST);
- exaPrepareAccess (pSrc, EXA_PREPARE_SRC);
+ ExaFallbackPrepareReg(pSrc, pGC, srcx, srcy, w, h,
+ EXA_PREPARE_SRC, FALSE);
+ ExaFallbackPrepareReg(pDst, pGC, dstx, dsty, w, h,
+ EXA_PREPARE_DEST, TRUE);
ret = pGC->ops->CopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
exaFinishAccess (pSrc, EXA_PREPARE_SRC);
exaFinishAccess (pDst, EXA_PREPARE_DEST);
@@ -168,8 +229,10 @@ ExaCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
EXA_PRE_FALLBACK_GC(pGC);
EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
- exaPrepareAccess (pDst, EXA_PREPARE_DEST);
- exaPrepareAccess (pSrc, EXA_PREPARE_SRC);
+ ExaFallbackPrepareReg(pSrc, pGC, srcx, srcy, w, h,
+ EXA_PREPARE_SRC, FALSE);
+ ExaFallbackPrepareReg(pDst, pGC, dstx, dsty, w, h,
+ EXA_PREPARE_DEST, TRUE);
ret = pGC->ops->CopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty,
bitPlane);
exaFinishAccess (pSrc, EXA_PREPARE_SRC);
@@ -295,8 +358,10 @@ ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap,
EXA_FALLBACK(("from %p to %p (%c,%c)\n", pBitmap, pDrawable,
exaDrawableLocation(&pBitmap->drawable),
exaDrawableLocation(pDrawable)));
- exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
- exaPrepareAccess (&pBitmap->drawable, EXA_PREPARE_SRC);
+ ExaFallbackPrepareReg(pDrawable, pGC, x, y, w, h,
+ EXA_PREPARE_DEST, TRUE);
+ ExaFallbackPrepareReg(&pBitmap->drawable, pGC, 0, 0, w, h,
+ EXA_PREPARE_SRC, FALSE);
exaPrepareAccessGC (pGC);
pGC->ops->PushPixels (pGC, pBitmap, pDrawable, w, h, x, y);
exaFinishAccessGC (pGC);
@@ -337,29 +402,12 @@ ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
unsigned int format, unsigned long planeMask, char *d)
{
ScreenPtr pScreen = pDrawable->pScreen;
- PixmapPtr pPix = exaGetDrawablePixmap (pDrawable);
EXA_PRE_FALLBACK(pScreen);
EXA_FALLBACK(("from %p (%c)\n", pDrawable,
exaDrawableLocation(pDrawable)));
- if (pExaScr->prepare_access_reg) {
- int xoff, yoff;
- BoxRec Box;
- RegionRec Reg;
-
- exaGetDrawableDeltas(pDrawable, pPix, &xoff, &yoff);
-
- Box.x1 = pDrawable->x + x + xoff;
- Box.y1 = pDrawable->y + y + yoff;
- Box.x2 = Box.x1 + w;
- Box.y2 = Box.y1 + h;
-
- REGION_INIT(pScreen, &Reg, &Box, 1);
-
- pExaScr->prepare_access_reg(pPix, EXA_PREPARE_SRC, &Reg);
- } else
- exaPrepareAccess(pDrawable, EXA_PREPARE_SRC);
-
+ ExaFallbackPrepareReg(pDrawable, NULL, x, y, w, h,
+ EXA_PREPARE_SRC, FALSE);
swap(pExaScr, pScreen, GetImage);
pScreen->GetImage (pDrawable, x, y, w, h, format, planeMask, d);
swap(pExaScr, pScreen, GetImage);
commit aa9ce8ab343d51a67924757c5a43c9572248bb24
Author: Michel Dänzer <daenzer at vmware.com>
Date: Tue Dec 29 09:34:43 2009 +0100
EXA: Use relevant source region to minimize migration on CopyWindow fallbacks.
Signed-off-by: Michel Dänzer <daenzer at vmware.com>
Acked-by: Maarten Maathuis <madman2003 at gmail.com>
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c
index 0dbcd53..f077fc8 100644
--- a/exa/exa_unaccel.c
+++ b/exa/exa_unaccel.c
@@ -313,8 +313,18 @@ ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
EXA_PRE_FALLBACK(pScreen);
EXA_FALLBACK(("from %p\n", pWin));
- /* being both src and dest, src is safest. */
- exaPrepareAccess(pDrawable, EXA_PREPARE_SRC);
+ /* Only need the source bits, the destination region will be overwritten */
+ if (pExaScr->prepare_access_reg) {
+ PixmapPtr pPixmap = pScreen->GetWindowPixmap(pWin);
+ int xoff, yoff;
+
+ exaGetDrawableDeltas(&pWin->drawable, pPixmap, &xoff, &yoff);
+ REGION_TRANSLATE(pScreen, prgnSrc, xoff, yoff);
+ pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, prgnSrc);
+ REGION_TRANSLATE(pScreen, prgnSrc, -xoff, -yoff);
+ } else
+ exaPrepareAccess(pDrawable, EXA_PREPARE_SRC);
+
swap(pExaScr, pScreen, CopyWindow);
pScreen->CopyWindow (pWin, ptOldOrg, prgnSrc);
swap(pExaScr, pScreen, CopyWindow);
commit 39cc110caa1f6481a7213ae39f82669333ec1645
Author: Thomas Hellstrom <thellstrom at vmware.com>
Date: Tue Dec 29 09:34:42 2009 +0100
EXA: Fix bugs in exaGetImage / ExaCheckGetImage migration.
Signed-off-by: Thomas Hellstrom <thellstrom at vmware.com>
Acked-by: Michel Dänzer <michel at daenzer.net>
Acked-by: Maarten Maathuis <madman2003 at gmail.com>
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/exa/exa_accel.c b/exa/exa_accel.c
index 0f6e5f7..c56c6bc 100644
--- a/exa/exa_accel.c
+++ b/exa/exa_accel.c
@@ -1270,7 +1270,7 @@ exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h,
RegionRec Reg;
ExaMigrationRec pixmaps[1];
- Box.x1 = pDrawable->y + x + xoff;
+ Box.x1 = pDrawable->x + x + xoff;
Box.y1 = pDrawable->y + y + yoff;
Box.x2 = Box.x1 + w;
Box.y2 = Box.y1 + h;
diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c
index eee14da..0dbcd53 100644
--- a/exa/exa_unaccel.c
+++ b/exa/exa_unaccel.c
@@ -339,7 +339,7 @@ ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
exaGetDrawableDeltas(pDrawable, pPix, &xoff, &yoff);
- Box.x1 = pDrawable->y + x + xoff;
+ Box.x1 = pDrawable->x + x + xoff;
Box.y1 = pDrawable->y + y + yoff;
Box.x2 = Box.x1 + w;
Box.y2 = Box.y1 + h;
More information about the xorg-commit
mailing list