xserver: Branch 'master' - 6 commits
Maarten Maathuis
madman2003 at kemper.freedesktop.org
Wed Mar 4 07:53:32 PST 2009
exa/exa.c | 215 +++++++++++++++++++++++++++++++++++++++++-----------
exa/exa.h | 5 +
exa/exa_migration.c | 32 ++-----
exa/exa_priv.h | 16 +++
exa/exa_unaccel.c | 12 +-
5 files changed, 211 insertions(+), 69 deletions(-)
New commits:
commit ce6e1771be5f2c21af6f72a9705795df26210413
Author: Maarten Maathuis <madman2003 at gmail.com>
Date: Mon Mar 2 17:05:28 2009 +0100
exa: fix a serious issue in exaChangeWindowAttributes (and some more related things)
- fbChangeWindowAttributes can create pixmaps (and access them) without use preparing access.
- Also handle the destroyed pixmaps by finishing them first.
- Switch to DEST indices again in exaCreatePixmapWithPrepare, because they are obviously being rendered to.
- Also avoid calling FinishAccess on pixmaps that are destroyed (and their memory potentially invalid).
diff --git a/exa/exa.c b/exa/exa.c
index d4a3cd7..b5f3542 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -743,11 +743,46 @@ exaCreatePixmapWithPrepare(ScreenPtr pScreen, int w, int h, int depth,
if (!pPixmap)
return NULL;
- exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_SRC);
+ /* Note the usage of ExaDoPrepareAccess, this allowed because:
+ * The pixmap is new, so not offscreen in the classic exa case.
+ * For EXA_HANDLES_PIXMAPS the driver will handle whatever is needed.
+ * We want to signal that the pixmaps will be used as destination.
+ */
+ if (pExaScr->prepare_access[EXA_PREPARE_DEST] == NULL) {
+ ExaDoPrepareAccess(&pPixmap->drawable, EXA_PREPARE_DEST);
+ pExaScr->prepare_access[EXA_PREPARE_DEST] = pPixmap;
+ } else if (pExaScr->prepare_access[EXA_PREPARE_AUX_DEST] == NULL) {
+ ExaDoPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST);
+ pExaScr->prepare_access[EXA_PREPARE_AUX_DEST] = pPixmap;
+ } else {
+ FatalError("exaCreatePixmapWithPrepare can only accomodate two pixmaps, we're at three.\n");
+ }
return pPixmap;
}
+static Bool
+exaDestroyPixmapWithFinish(PixmapPtr pPixmap)
+{
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ ExaScreenPriv(pScreen);
+ int i;
+ Bool ret;
+
+ for (i = 0; i < 6; i++)
+ if (pExaScr->prepare_access[i] == pPixmap)
+ exaFinishAccess(&pPixmap->drawable, i);
+
+ /* This swaps between this function and the real upper layer function.
+ * Normally this would swap to the fb layer pointer, this is a very special case.
+ */
+ swap(pExaScr, pScreen, DestroyPixmap);
+ ret = pScreen->DestroyPixmap(pPixmap);
+ swap(pExaScr, pScreen, DestroyPixmap);
+
+ return ret;
+}
+
static void
exaValidateGC(GCPtr pGC,
unsigned long changes,
@@ -760,6 +795,7 @@ exaValidateGC(GCPtr pGC,
ScreenPtr pScreen = pDrawable->pScreen;
ExaScreenPriv(pScreen);
CreatePixmapProcPtr old_ptr = NULL;
+ DestroyPixmapProcPtr old_ptr2 = NULL;
PixmapPtr pTile = NULL;
EXA_GC_PROLOGUE(pGC);
@@ -768,6 +804,11 @@ exaValidateGC(GCPtr pGC,
/* create a new upper layer pointer. */
wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmapWithPrepare);
+ /* save the "fb" pointer. */
+ old_ptr2 = pExaScr->SavedDestroyPixmap;
+ /* create a new upper layer pointer. */
+ wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmapWithFinish);
+
/* Either of these conditions is enough to trigger access to a tile pixmap. */
/* With pGC->tileIsPixel == 1, you run the risk of dereferencing an invalid tile pixmap pointer. */
if (pGC->fillStyle == FillTiled || ((changes & GCTile) && !pGC->tileIsPixel)) {
@@ -792,8 +833,8 @@ exaValidateGC(GCPtr pGC,
(*pGC->funcs->ValidateGC)(pGC, changes, pDrawable);
- if (pTile)
- exaFinishAccess(&pTile->drawable, EXA_PREPARE_SRC);
+ if (pExaScr->prepare_access[EXA_PREPARE_SRC]) /* tile */
+ exaFinishAccess(&pExaScr->prepare_access[EXA_PREPARE_SRC]->drawable, EXA_PREPARE_SRC);
if (pGC->stipple)
exaFinishAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK);
@@ -802,9 +843,18 @@ exaValidateGC(GCPtr pGC,
/* restore copy of fb layer pointer. */
pExaScr->SavedCreatePixmap = old_ptr;
- if (pGC->fillStyle == FillTiled && pTile != pGC->tile.pixmap)
- exaFinishAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_AUX_SRC);
-
+ /* switch back to the normal upper layer. */
+ unwrap(pExaScr, pScreen, DestroyPixmap);
+ /* restore copy of fb layer pointer. */
+ pExaScr->SavedDestroyPixmap = old_ptr2;
+
+ if (pExaScr->prepare_access[EXA_PREPARE_DEST])
+ exaFinishAccess(&pExaScr->prepare_access[EXA_PREPARE_DEST]->drawable,
+ EXA_PREPARE_DEST);
+ if (pExaScr->prepare_access[EXA_PREPARE_AUX_DEST])
+ exaFinishAccess(&pExaScr->prepare_access[EXA_PREPARE_AUX_DEST]->drawable,
+ EXA_PREPARE_AUX_DEST);
+
EXA_GC_EPILOGUE(pGC);
}
@@ -891,22 +941,50 @@ exaChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
Bool ret;
ScreenPtr pScreen = pWin->drawable.pScreen;
ExaScreenPriv(pScreen);
+ CreatePixmapProcPtr old_ptr = NULL;
+ DestroyPixmapProcPtr old_ptr2 = NULL;
+
+ /* save the "fb" pointer. */
+ old_ptr = pExaScr->SavedCreatePixmap;
+ /* create a new upper layer pointer. */
+ wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmapWithPrepare);
+
+ /* save the "fb" pointer. */
+ old_ptr2 = pExaScr->SavedDestroyPixmap;
+ /* create a new upper layer pointer. */
+ wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmapWithFinish);
if ((mask & CWBackPixmap) && pWin->backgroundState == BackgroundPixmap)
- exaPrepareAccess(&pWin->background.pixmap->drawable, EXA_PREPARE_SRC);
+ exaPrepareAccess(&pWin->background.pixmap->drawable, EXA_PREPARE_SRC);
if ((mask & CWBorderPixmap) && pWin->borderIsPixel == FALSE)
- exaPrepareAccess(&pWin->border.pixmap->drawable, EXA_PREPARE_MASK);
+ exaPrepareAccess(&pWin->border.pixmap->drawable, EXA_PREPARE_MASK);
swap(pExaScr, pScreen, ChangeWindowAttributes);
ret = pScreen->ChangeWindowAttributes(pWin, mask);
swap(pExaScr, pScreen, ChangeWindowAttributes);
- if ((mask & CWBorderPixmap) && pWin->borderIsPixel == FALSE)
- exaFinishAccess(&pWin->border.pixmap->drawable, EXA_PREPARE_MASK);
+ if (pExaScr->prepare_access[EXA_PREPARE_SRC]) /* background */
+ exaFinishAccess(&pExaScr->prepare_access[EXA_PREPARE_SRC]->drawable, EXA_PREPARE_SRC);
+ if (pExaScr->prepare_access[EXA_PREPARE_MASK]) /* border */
+ exaFinishAccess(&pExaScr->prepare_access[EXA_PREPARE_MASK]->drawable, EXA_PREPARE_MASK);
- if ((mask & CWBackPixmap) && pWin->backgroundState == BackgroundPixmap)
- exaFinishAccess(&pWin->background.pixmap->drawable, EXA_PREPARE_SRC);
+ /* switch back to the normal upper layer. */
+ unwrap(pExaScr, pScreen, CreatePixmap);
+ /* restore copy of fb layer pointer. */
+ pExaScr->SavedCreatePixmap = old_ptr;
+
+ /* switch back to the normal upper layer. */
+ unwrap(pExaScr, pScreen, DestroyPixmap);
+ /* restore copy of fb layer pointer. */
+ pExaScr->SavedDestroyPixmap = old_ptr2;
+
+ if (pExaScr->prepare_access[EXA_PREPARE_DEST])
+ exaFinishAccess(&pExaScr->prepare_access[EXA_PREPARE_DEST]->drawable,
+ EXA_PREPARE_DEST);
+ if (pExaScr->prepare_access[EXA_PREPARE_AUX_DEST])
+ exaFinishAccess(&pExaScr->prepare_access[EXA_PREPARE_AUX_DEST]->drawable,
+ EXA_PREPARE_AUX_DEST);
return ret;
}
commit 7fb68e8b31d259325ce311ad67befc43a933f009
Author: Maarten Maathuis <madman2003 at gmail.com>
Date: Sat Feb 28 22:29:42 2009 +0100
exa: remove a few pExaPixmap checks.
- And make some fatal for a debug build.
diff --git a/exa/exa_migration.c b/exa/exa_migration.c
index 8b91150..f6805cb 100644
--- a/exa/exa_migration.c
+++ b/exa/exa_migration.c
@@ -43,16 +43,18 @@
/**
* Returns TRUE if the pixmap is not movable. This is the case where it's a
- * fake pixmap for the frontbuffer (no pixmap private) or it's a scratch
- * pixmap created by some other X Server internals (the score says it's
- * pinned).
+ * pixmap which has no private (almost always bad) or it's a scratch pixmap created by
+ * some X Server internal component (the score says it's pinned).
*/
static Bool
exaPixmapIsPinned (PixmapPtr pPix)
{
ExaPixmapPriv (pPix);
- return pExaPixmap == NULL || pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED;
+ if (pExaPixmap == NULL)
+ EXA_FatalErrorDebugWithRet(("EXA bug: exaPixmapIsPinned was called on a non-exa pixmap.\n"), TRUE);
+
+ return pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED;
}
/**
@@ -86,8 +88,10 @@ exaPixmapIsDirty (PixmapPtr pPix)
{
ExaPixmapPriv (pPix);
- return pExaPixmap == NULL ||
- REGION_NOTEMPTY (pScreen, DamageRegion(pExaPixmap->pDamage)) ||
+ if (pExaPixmap == NULL)
+ EXA_FatalErrorDebugWithRet(("EXA bug: exaPixmapIsDirty was called on a non-exa pixmap.\n"), TRUE);
+
+ return REGION_NOTEMPTY (pScreen, DamageRegion(pExaPixmap->pDamage)) ||
!REGION_EQUAL(pScreen, &pExaPixmap->validSys, &pExaPixmap->validFB);
}
@@ -460,13 +464,6 @@ exaMigrateTowardFb (ExaMigrationPtr migrate)
PixmapPtr pPixmap = migrate->pPix;
ExaPixmapPriv (pPixmap);
- if (pExaPixmap == NULL) {
- DBG_MIGRATE(("UseScreen: ignoring exa-uncontrolled pixmap %p (%s)\n",
- (pointer)pPixmap,
- exaPixmapIsOffscreen(pPixmap) ? "s" : "m"));
- return;
- }
-
if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED) {
DBG_MIGRATE(("UseScreen: not migrating pinned pixmap %p\n",
(pointer)pPixmap));
@@ -507,13 +504,6 @@ exaMigrateTowardSys (ExaMigrationPtr migrate)
PixmapPtr pPixmap = migrate->pPix;
ExaPixmapPriv (pPixmap);
- if (pExaPixmap == NULL) {
- DBG_MIGRATE(("UseMem: ignoring exa-uncontrolled pixmap %p (%s)\n",
- (pointer)pPixmap,
- exaPixmapIsOffscreen(pPixmap) ? "s" : "m"));
- return;
- }
-
DBG_MIGRATE(("UseMem: %p score %d\n", (pointer)pPixmap, pExaPixmap->score));
if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED)
@@ -625,6 +615,8 @@ exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
if (pExaScr->info->flags & EXA_HANDLES_PIXMAPS)
return;
+ if (!(pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS))
+ return;
/* If this debugging flag is set, check each pixmap for whether it is marked
* as clean, and if so, actually check if that's the case. This should help
commit bd2f35ef0d4b8c56eb205b8694b4fe5d2fa2c049
Author: Maarten Maathuis <madman2003 at gmail.com>
Date: Sat Feb 28 22:15:04 2009 +0100
exa: fix unwrapping of ModifyPixmapHeader upon CloseScreen.
- Cleanup wrapping too.
diff --git a/exa/exa.c b/exa/exa.c
index 0ecbcf7..d4a3cd7 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -978,6 +978,8 @@ exaCloseScreen(int i, ScreenPtr pScreen)
unwrap(pExaScr, pScreen, CreatePixmap);
if (pExaScr->SavedDestroyPixmap)
unwrap(pExaScr, pScreen, DestroyPixmap);
+ if (pExaScr->SavedModifyPixmapHeader)
+ unwrap(pExaScr, pScreen, ModifyPixmapHeader);
unwrap(pExaScr, pScreen, CopyWindow);
unwrap(pExaScr, pScreen, ChangeWindowAttributes);
unwrap(pExaScr, pScreen, BitmapToRegion);
@@ -1104,7 +1106,6 @@ exaDriverInit (ScreenPtr pScreen,
#endif
pExaScr = xcalloc (sizeof (ExaScreenPrivRec), 1);
-
if (!pExaScr) {
LogMessage(X_WARNING, "EXA(%d): Failed to allocate screen private\n",
pScreen->myNum);
@@ -1169,8 +1170,7 @@ exaDriverInit (ScreenPtr pScreen,
wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmap);
wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmap);
- pExaScr->SavedModifyPixmapHeader = pScreen->ModifyPixmapHeader;
- pScreen->ModifyPixmapHeader = exaModifyPixmapHeader;
+ wrap(pExaScr, pScreen, ModifyPixmapHeader, exaModifyPixmapHeader);
if (!pExaScr->info->CreatePixmap) {
LogMessage(X_INFO, "EXA(%d): Offscreen pixmap area of %lu bytes\n",
pScreen->myNum,
commit da8ea41a542787691ea1120e5c8c7dc3182cbea5
Author: Maarten Maathuis <madman2003 at gmail.com>
Date: Sat Feb 28 21:59:09 2009 +0100
exa: increase/rework safety checks in Prepare/FinishAccess.
diff --git a/exa/exa.c b/exa/exa.c
index f4fba57..0ecbcf7 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -450,15 +450,28 @@ exaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
}
}
-
if (pExaScr->info->ModifyPixmapHeader) {
ret = pExaScr->info->ModifyPixmapHeader(pPixmap, width, height, depth,
bitsPerPixel, devKind, pPixData);
+ /* For EXA_HANDLES_PIXMAPS, we set pPixData to NULL.
+ * If pPixmap->devPrivate.ptr is non-NULL, then we've got a non-offscreen pixmap.
+ * We need to store the pointer, because PrepareAccess won't be called.
+ */
+ if (!pPixData && pPixmap->devPrivate.ptr && pPixmap->devKind) {
+ pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr;
+ pExaPixmap->sys_pitch = pPixmap->devKind;
+ }
if (ret == TRUE)
- return ret;
+ goto out;
}
- return pExaScr->SavedModifyPixmapHeader(pPixmap, width, height, depth,
+ ret = pExaScr->SavedModifyPixmapHeader(pPixmap, width, height, depth,
bitsPerPixel, devKind, pPixData);
+
+out:
+ /* Always NULL this, we don't want lingering pointers. */
+ pPixmap->devPrivate.ptr = NULL;
+
+ return ret;
}
/**
@@ -523,16 +536,43 @@ exaGetOffscreenPixmap (DrawablePtr pDrawable, int *xp, int *yp)
Bool
ExaDoPrepareAccess(DrawablePtr pDrawable, int index)
{
- ScreenPtr pScreen = pDrawable->pScreen;
- ExaScreenPriv (pScreen);
- PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable);
- Bool offscreen = exaPixmapIsOffscreen(pPixmap);
+ ScreenPtr pScreen = pDrawable->pScreen;
+ ExaScreenPriv (pScreen);
+ PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable);
+ ExaPixmapPriv(pPixmap);
+ Bool offscreen;
+
+ if (!(pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS))
+ return FALSE;
+
+ if (pExaPixmap == NULL)
+ EXA_FatalErrorDebugWithRet(("EXA bug: ExaDoPrepareAccess was called on a non-exa pixmap.\n"), FALSE);
- /* Unhide pixmap pointer */
- if (pPixmap->devPrivate.ptr == NULL && !(pExaScr->info->flags & EXA_HANDLES_PIXMAPS)) {
- pPixmap->devPrivate.ptr = ExaGetPixmapAddress(pPixmap);
+ /* Check if we're dealing SRC == DST or similar.
+ * In that case the first PrepareAccess has already set pPixmap->devPrivate.ptr.
+ */
+ if (pPixmap->devPrivate.ptr != NULL) {
+ int i;
+ for (i = 0; i < 6; i++)
+ if (pExaScr->prepare_access[i] == pPixmap)
+ break;
+
+ /* No known PrepareAccess or double prepare on the same index. */
+ if (i == 6 || i == index)
+ EXA_FatalErrorDebug(("EXA bug: pPixmap->devPrivate.ptr was %p, but should have been NULL.\n",
+ pPixmap->devPrivate.ptr));
}
+ offscreen = exaPixmapIsOffscreen(pPixmap);
+
+ if (offscreen)
+ pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr;
+ else
+ pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr;
+
+ /* Store so we can check SRC and DEST being the same. */
+ pExaScr->prepare_access[index] = pPixmap;
+
if (!offscreen)
return FALSE;
@@ -548,9 +588,8 @@ ExaDoPrepareAccess(DrawablePtr pDrawable, int index)
}
if (!(*pExaScr->info->PrepareAccess) (pPixmap, index)) {
- ExaPixmapPriv (pPixmap);
if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED)
- FatalError("Driver failed PrepareAccess on a pinned pixmap\n");
+ FatalError("Driver failed PrepareAccess on a pinned pixmap.\n");
exaMoveOutPixmap (pPixmap);
return FALSE;
@@ -604,10 +643,20 @@ exaFinishAccess(DrawablePtr pDrawable, int index)
PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable);
ExaPixmapPriv (pPixmap);
- /* Rehide pixmap pointer if we're doing that. */
- if (pExaPixmap && !(pExaScr->info->flags & EXA_HANDLES_PIXMAPS)) {
- pPixmap->devPrivate.ptr = NULL;
- }
+ if (!(pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS))
+ return;
+
+ if (pExaPixmap == NULL)
+ EXA_FatalErrorDebugWithRet(("EXA bug: exaFinishAccesss was called on a non-exa pixmap.\n"),);
+
+ /* Avoid mismatching indices. */
+ if (pExaScr->prepare_access[index] != pPixmap)
+ EXA_FatalErrorDebug(("EXA bug: Calling FinishAccess on pixmap %p with index %d while "
+ "it should have been %p.\n", pPixmap, index, pExaScr->prepare_access[index]));
+ pExaScr->prepare_access[index] = NULL;
+
+ /* We always hide the devPrivate.ptr. */
+ pPixmap->devPrivate.ptr = NULL;
if (pExaScr->info->FinishAccess == NULL)
return;
diff --git a/exa/exa.h b/exa/exa.h
index 8339a3e..d7219f0 100644
--- a/exa/exa.h
+++ b/exa/exa.h
@@ -695,6 +695,11 @@ typedef struct _ExaDriver {
/* Hooks to allow driver to its own pixmap memory management */
void *(*CreatePixmap)(ScreenPtr pScreen, int size, int align);
void (*DestroyPixmap)(ScreenPtr pScreen, void *driverPriv);
+ /**
+ * Returning a pixmap with non-NULL devPrivate.ptr implies a pixmap which is
+ * not offscreen, which will never be accelerated and Prepare/FinishAccess won't
+ * be called.
+ */
Bool (*ModifyPixmapHeader)(PixmapPtr pPixmap, int width, int height,
int depth, int bitsPerPixel, int devKind,
pointer pPixData);
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index a037eb0..9efbbc9 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -85,6 +85,18 @@ exaDrawableLocation(DrawablePtr pDrawable);
#define EXA_MAX_FB FB_OVERLAY_MAX
#endif
+#ifdef DEBUG
+#define EXA_FatalErrorDebug(x) FatalError x
+#define EXA_FatalErrorDebugWithRet(x, ret) FatalError x
+#else
+#define EXA_FatalErrorDebug(x) ErrorF x
+#define EXA_FatalErrorDebugWithRet(x, ret) \
+do { \
+ ErrorF x; \
+ return ret; \
+} while (0)
+#endif
+
/**
* This is the list of migration heuristics supported by EXA. See
* exaDoMigration() for what their implementations do.
@@ -158,6 +170,10 @@ typedef struct {
unsigned disableFbCount;
Bool optimize_migration;
unsigned offScreenCounter;
+
+ /* Store all accessed pixmaps, so we can check for duplicates. */
+ PixmapPtr prepare_access[6];
+
/* Holds information on fallbacks that cannot be relayed otherwise. */
unsigned int fallback_flags;
commit 3ea3d505e8128ab3e878edcef697fd5656b0c917
Author: Maarten Maathuis <madman2003 at gmail.com>
Date: Sun Mar 1 01:15:28 2009 +0100
exa: avoid a potential Prepare/FinishAccess inbalance.
diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c
index d16ecf7..4279c87 100644
--- a/exa/exa_unaccel.c
+++ b/exa/exa_unaccel.c
@@ -405,7 +405,7 @@ ExaCheckComposite (CARD8 op,
if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst,
xSrc, ySrc, xMask, yMask, xDst, yDst,
width, height))
- return;
+ goto skip;
exaGetDrawableDeltas (pDst->pDrawable,
exaGetDrawablePixmap(pDst->pDrawable),
@@ -450,16 +450,18 @@ ExaCheckComposite (CARD8 op,
#endif /* RENDER */
if (pMask && pMask->pDrawable != NULL)
exaFinishAccess (pMask->pDrawable, EXA_PREPARE_MASK);
- if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
- exaFinishAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK);
if (pSrc->pDrawable != NULL)
exaFinishAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
- if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
- exaFinishAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC);
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);
}
commit 10334cf7e64e2e633cd507f2aa216027e840c8e5
Author: Maarten Maathuis <madman2003 at gmail.com>
Date: Sat Feb 28 21:46:00 2009 +0100
exa: simplify exaPixmapIsOffscreen
- This includes properly handling the framebuffer.
diff --git a/exa/exa.c b/exa/exa.c
index 994a67a..f4fba57 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -73,8 +73,9 @@ unsigned long
exaGetPixmapOffset(PixmapPtr pPix)
{
ExaScreenPriv (pPix->drawable.pScreen);
+ ExaPixmapPriv (pPix);
- return (CARD8 *)ExaGetPixmapAddress(pPix) - pExaScr->info->memoryBase;
+ return (CARD8 *)pExaPixmap->fb_ptr - pExaScr->info->memoryBase;
}
void *
@@ -424,6 +425,13 @@ exaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
if (devKind > 0)
pExaPixmap->sys_pitch = devKind;
+ /* Is this the framebuffer (for classic exa)? */
+ if (pPixData && pPixData == pExaScr->info->memoryBase) {
+ pExaPixmap->fb_ptr = pPixData;
+ pExaPixmap->fb_pitch = devKind;
+ pExaPixmap->offscreen = TRUE;
+ }
+
if (width > 0 && height > 0 && bitsPerPixel > 0) {
exaSetFbPitch(pExaScr, pExaPixmap,
width, height, bitsPerPixel);
@@ -471,22 +479,14 @@ exaPixmapIsOffscreen(PixmapPtr p)
ScreenPtr pScreen = p->drawable.pScreen;
ExaScreenPriv(pScreen);
ExaPixmapPriv(p);
- void *save_ptr;
Bool ret;
- save_ptr = p->devPrivate.ptr;
-
- if (!save_ptr && pExaPixmap && !(pExaScr->info->flags & EXA_HANDLES_PIXMAPS))
+ if (pExaScr->info->PixmapIsOffscreen) {
p->devPrivate.ptr = ExaGetPixmapAddress(p);
-
- if (pExaScr->info->PixmapIsOffscreen)
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;
+ p->devPrivate.ptr = NULL;
+ } else
+ ret = (pExaPixmap->offscreen && pExaPixmap->fb_ptr);
return ret;
}
More information about the xorg-commit
mailing list