diff options
Diffstat (limited to 'exa')
-rw-r--r-- | exa/exa.c | 21 | ||||
-rw-r--r-- | exa/exa_migration.c | 33 | ||||
-rw-r--r-- | exa/exa_priv.h | 11 |
3 files changed, 36 insertions, 29 deletions
@@ -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) |