summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--exa/exa_migration.c33
-rw-r--r--exa/exa_priv.h1
-rw-r--r--hw/xfree86/exa/exa.man.pre6
-rw-r--r--hw/xfree86/exa/examodule.c8
4 files changed, 40 insertions, 8 deletions
diff --git a/exa/exa_migration.c b/exa/exa_migration.c
index d69526b7f..d3646b0b6 100644
--- a/exa/exa_migration.c
+++ b/exa/exa_migration.c
@@ -153,22 +153,39 @@ exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc,
REGION_SUBTRACT(pScreen, &CopyReg, pValidSrc, pValidDst);
if (migrate->as_dst) {
- RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
+ ExaScreenPriv (pPixmap->drawable.pScreen);
- if (REGION_NIL(pending_damage)) {
- static Bool firsttime = TRUE;
+ /* XXX: The pending damage region will be marked as damaged after the
+ * operation, so it should serve as an upper bound for the region that
+ * needs to be synchronized for the operation. Unfortunately, this
+ * causes corruption in some cases, e.g. when starting compiz. See
+ * https://bugs.freedesktop.org/show_bug.cgi?id=12916 .
+ */
+ if (pExaScr->optimize_migration) {
+ 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;
+ if (firsttime) {
+ ErrorF("%s: Pending damage region empty!\n", __func__);
+ firsttime = FALSE;
+ }
}
- }
- REGION_INTERSECT(pScreen, &CopyReg, &CopyReg, pending_damage);
+ REGION_INTERSECT(pScreen, &CopyReg, &CopyReg, pending_damage);
+ }
+ /* The caller may provide a region to be subtracted from the calculated
+ * dirty region. This is to avoid migration of bits that don't
+ * contribute to the result of the operation.
+ */
if (migrate->pReg)
REGION_SUBTRACT(pScreen, &CopyReg, &CopyReg, migrate->pReg);
} else {
+ /* The caller may restrict the region to be migrated for source pixmaps
+ * to what's relevant for the operation.
+ */
if (migrate->pReg)
REGION_INTERSECT(pScreen, &CopyReg, &CopyReg, migrate->pReg);
}
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index a69536372..7656a0278 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -119,6 +119,7 @@ typedef struct {
enum ExaMigrationHeuristic migration;
Bool checkDirtyCorrectness;
unsigned disableFbCount;
+ Bool optimize_migration;
} ExaScreenPrivRec, *ExaScreenPrivPtr;
/*
diff --git a/hw/xfree86/exa/exa.man.pre b/hw/xfree86/exa/exa.man.pre
index 31e1cfe34..14859bc8f 100644
--- a/hw/xfree86/exa/exa.man.pre
+++ b/hw/xfree86/exa/exa.man.pre
@@ -31,6 +31,12 @@ Disables acceleration of downloading of pixmap data from the framebuffer.
Not usable with drivers which rely on DownloadFromScreen succeeding.
Default: No.
.TP
+.BI "Option \*qEXAOptimizeMigration\*q \*q" boolean \*q
+Enables an additional optimization for migration of destination pixmaps. This
+may improve performance in some cases (e.g. when switching virtual desktops with
+no compositing manager) but causes corruption in others (e.g. when starting
+compiz). Default: No.
+.TP
.BI "Option \*qMigrationHeuristic\*q \*q" anystr \*q
Chooses an alternate pixmap migration heuristic, for debugging purposes. The
default is intended to be the best performing one for general use, though others
diff --git a/hw/xfree86/exa/examodule.c b/hw/xfree86/exa/examodule.c
index 4dce58fd8..ceead8219 100644
--- a/hw/xfree86/exa/examodule.c
+++ b/hw/xfree86/exa/examodule.c
@@ -50,6 +50,7 @@ typedef enum {
EXAOPT_NO_COMPOSITE,
EXAOPT_NO_UTS,
EXAOPT_NO_DFS,
+ EXAOPT_OPTIMIZE_MIGRATION
} EXAOpts;
static const OptionInfoRec EXAOptions[] = {
@@ -61,6 +62,8 @@ static const OptionInfoRec EXAOptions[] = {
OPTV_BOOLEAN, {0}, FALSE },
{ EXAOPT_NO_DFS, "EXANoDownloadFromScreen",
OPTV_BOOLEAN, {0}, FALSE },
+ { EXAOPT_OPTIMIZE_MIGRATION, "EXAOptimizeMigration",
+ OPTV_BOOLEAN, {0}, FALSE },
{ -1, NULL,
OPTV_NONE, {0}, FALSE }
};
@@ -144,6 +147,11 @@ exaDDXDriverInit(ScreenPtr pScreen)
heuristicName);
}
}
+
+ pExaScr->optimize_migration =
+ xf86ReturnOptValBool(pScreenPriv->options,
+ EXAOPT_OPTIMIZE_MIGRATION,
+ FALSE);
}
if (xf86IsOptionSet(pScreenPriv->options, EXAOPT_NO_COMPOSITE)) {