summaryrefslogtreecommitdiff
path: root/exa
diff options
context:
space:
mode:
Diffstat (limited to 'exa')
-rw-r--r--exa/exa.c21
-rw-r--r--exa/exa_migration.c33
-rw-r--r--exa/exa_priv.h11
3 files changed, 36 insertions, 29 deletions
diff --git a/exa/exa.c b/exa/exa.c
index 1f85d8ef0..cbe66e875 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -40,9 +40,8 @@
#include "exa.h"
#include "cw.h"
-static int exaGeneration;
-int exaScreenPrivateIndex;
-int exaPixmapPrivateIndex;
+DevPrivateKey exaScreenPrivateKey = &exaScreenPrivateKey;
+DevPrivateKey exaPixmapPrivateKey = &exaPixmapPrivateKey;
static _X_INLINE void*
ExaGetPixmapAddress(PixmapPtr p)
@@ -257,6 +256,7 @@ exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth,
return NULL;
pExaPixmap = ExaGetPixmapPriv(pPixmap);
+ pExaPixmap->driverPriv = NULL;
bpp = pPixmap->drawable.bitsPerPixel;
@@ -812,12 +812,6 @@ exaDriverInit (ScreenPtr pScreen,
#ifdef RENDER
ps = GetPictureScreenIfSet(pScreen);
#endif
- if (exaGeneration != serverGeneration)
- {
- exaScreenPrivateIndex = AllocateScreenPrivateIndex();
- exaPixmapPrivateIndex = AllocatePixmapPrivateIndex();
- exaGeneration = serverGeneration;
- }
pExaScr = xcalloc (sizeof (ExaScreenPrivRec), 1);
@@ -829,7 +823,7 @@ exaDriverInit (ScreenPtr pScreen,
pExaScr->info = pScreenInfo;
- pScreen->devPrivates[exaScreenPrivateIndex].ptr = (pointer) pExaScr;
+ dixSetPrivate(&pScreen->devPrivates, exaScreenPrivateKey, pExaScr);
pExaScr->migration = ExaMigrationAlways;
@@ -884,8 +878,7 @@ exaDriverInit (ScreenPtr pScreen,
*/
if (pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS)
{
- if (!AllocatePixmapPrivate(pScreen, exaPixmapPrivateIndex,
- sizeof (ExaPixmapPrivRec))) {
+ if (!dixRequestPrivate(exaPixmapPrivateKey, sizeof(ExaPixmapPrivRec))) {
LogMessage(X_WARNING,
"EXA(%d): Failed to allocate pixmap private\n",
pScreen->myNum);
@@ -910,11 +903,7 @@ exaDriverInit (ScreenPtr pScreen,
}
}
else
- {
LogMessage(X_INFO, "EXA(%d): No offscreen pixmaps\n", pScreen->myNum);
- if (!AllocatePixmapPrivate(pScreen, exaPixmapPrivateIndex, 0))
- return FALSE;
- }
if (!pExaScr->info->CreatePixmap) {
DBG_PIXMAP(("============== %ld < %ld\n", pExaScr->info->offScreenBase,
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..de8b2f541 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;
/*
@@ -133,9 +134,9 @@ typedef struct {
(PixmapWidthPaddingInfo[d].padRoundUp+1)))
#endif
-extern int exaScreenPrivateIndex;
-extern int exaPixmapPrivateIndex;
-#define ExaGetScreenPriv(s) ((ExaScreenPrivPtr)(s)->devPrivates[exaScreenPrivateIndex].ptr)
+extern DevPrivateKey exaScreenPrivateKey;
+extern DevPrivateKey exaPixmapPrivateKey;
+#define ExaGetScreenPriv(s) ((ExaScreenPrivPtr)dixLookupPrivate(&(s)->devPrivates, exaScreenPrivateKey))
#define ExaScreenPriv(s) ExaScreenPrivPtr pExaScr = ExaGetScreenPriv(s)
/** Align an offset to an arbitrary alignment */
@@ -151,8 +152,8 @@ extern int exaPixmapPrivateIndex;
#define EXA_PIXMAP_SCORE_PINNED 1000
#define EXA_PIXMAP_SCORE_INIT 1001
-#define ExaGetPixmapPriv(p) ((ExaPixmapPrivPtr)(p)->devPrivates[exaPixmapPrivateIndex].ptr)
-#define ExaSetPixmapPriv(p,a) ((p)->devPrivates[exaPixmapPrivateIndex].ptr = (pointer) (a))
+#define ExaGetPixmapPriv(p) ((ExaPixmapPrivPtr)dixLookupPrivate(&(p)->devPrivates, exaPixmapPrivateKey))
+#define ExaSetPixmapPriv(p,a) dixSetPrivate(&(p)->devPrivates, exaPixmapPrivateKey, a)
#define ExaPixmapPriv(p) ExaPixmapPrivPtr pExaPixmap = ExaGetPixmapPriv(p)
#define EXA_RANGE_PITCH (1 << 0)