summaryrefslogtreecommitdiff
path: root/exa/exa.c
diff options
context:
space:
mode:
authorMaarten Maathuis <madman2003@gmail.com>2009-11-28 10:34:43 +0100
committerKeith Packard <keithp@keithp.com>2009-11-28 12:44:21 -0800
commit342f3689d17256c92cbfee079d24501d27aa1153 (patch)
treeb017a035edf544e97788f552d68ccfd066328ef3 /exa/exa.c
parentb54bc14ce0ae38c4863794bc3096ca86cdb23908 (diff)
exa: handle pixmap create/destroy in lower layers
- Pixmaps that are created during a fallback are automatically prepared access. - During the fallback accelerated ops are blocked to prevent new/scratch gc's from triggering accelerated ops on mapped pixmaps. - A few cases of incorrect wrapping (on the top level pointer instead of between damage and (w)fb) have been removed. Signed-off-by: Maarten Maathuis <madman2003@gmail.com> Acked-by: Michel Dänzer <michel@daenzer.net> Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'exa/exa.c')
-rw-r--r--exa/exa.c145
1 files changed, 33 insertions, 112 deletions
diff --git a/exa/exa.c b/exa/exa.c
index 46e91820b..ed2843127 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -480,57 +480,6 @@ const GCFuncs exaGCFuncs = {
exaCopyClip
};
-/*
- * This wrapper exists to allow fbValidateGC to work.
- * Note that we no longer assume newly created pixmaps to be in normal ram.
- * This assumption is certainly not garuanteed with driver allocated pixmaps.
- */
-static PixmapPtr
-exaCreatePixmapWithPrepare(ScreenPtr pScreen, int w, int h, int depth,
- unsigned usage_hint)
-{
- PixmapPtr pPixmap;
- ExaScreenPriv(pScreen);
-
- /* 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, CreatePixmap);
- pPixmap = pScreen->CreatePixmap(pScreen, w, h, depth, usage_hint);
- swap(pExaScr, pScreen, CreatePixmap);
-
- if (!pPixmap)
- return NULL;
-
- /* 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.
- */
- ExaDoPrepareAccess(pPixmap, EXA_PREPARE_AUX_DEST);
-
- return pPixmap;
-}
-
-static Bool
-exaDestroyPixmapWithFinish(PixmapPtr pPixmap)
-{
- ScreenPtr pScreen = pPixmap->drawable.pScreen;
- ExaScreenPriv(pScreen);
- Bool ret;
-
- exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST);
-
- /* 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,
@@ -542,20 +491,9 @@ exaValidateGC(GCPtr pGC,
ScreenPtr pScreen = pDrawable->pScreen;
ExaScreenPriv(pScreen);
- CreatePixmapProcPtr old_ptr = NULL;
- DestroyPixmapProcPtr old_ptr2 = NULL;
+ ExaGCPriv(pGC);
PixmapPtr pTile = NULL;
- EXA_GC_PROLOGUE(pGC);
-
- /* 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);
+ Bool finish_current_tile = FALSE;
/* 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. */
@@ -569,8 +507,10 @@ exaValidateGC(GCPtr pGC,
*/
if (pTile && pTile->drawable.depth != pDrawable->depth && !(changes & GCTile)) {
PixmapPtr pRotatedTile = fbGetRotatedPixmap(pGC);
- if (pRotatedTile->drawable.depth == pDrawable->depth)
+ if (pRotatedTile && pRotatedTile->drawable.depth == pDrawable->depth)
pTile = pRotatedTile;
+ else
+ finish_current_tile = TRUE; /* CreatePixmap will be called. */
}
}
@@ -579,42 +519,39 @@ exaValidateGC(GCPtr pGC,
if (pTile)
exaPrepareAccess(&pTile->drawable, EXA_PREPARE_SRC);
+ /* Calls to Create/DestroyPixmap have to be identified as special. */
+ pExaScr->fallback_counter++;
+ swap(pExaGC, pGC, funcs);
(*pGC->funcs->ValidateGC)(pGC, changes, pDrawable);
+ swap(pExaGC, pGC, funcs);
+ pExaScr->fallback_counter--;
if (pTile)
exaFinishAccess(&pTile->drawable, EXA_PREPARE_SRC);
+ if (finish_current_tile && pGC->tile.pixmap)
+ exaFinishAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_AUX_DEST);
if (pGC->stipple)
- exaFinishAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK);
-
- /* 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;
-
- EXA_GC_EPILOGUE(pGC);
+ exaFinishAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK);
}
/* Is exaPrepareAccessGC() needed? */
static void
exaDestroyGC(GCPtr pGC)
{
- EXA_GC_PROLOGUE (pGC);
+ ExaGCPriv(pGC);
+ swap(pExaGC, pGC, funcs);
(*pGC->funcs->DestroyGC)(pGC);
- EXA_GC_EPILOGUE (pGC);
+ swap(pExaGC, pGC, funcs);
}
static void
exaChangeGC (GCPtr pGC,
unsigned long mask)
{
- EXA_GC_PROLOGUE (pGC);
+ ExaGCPriv(pGC);
+ swap(pExaGC, pGC, funcs);
(*pGC->funcs->ChangeGC) (pGC, mask);
- EXA_GC_EPILOGUE (pGC);
+ swap(pExaGC, pGC, funcs);
}
static void
@@ -622,9 +559,10 @@ exaCopyGC (GCPtr pGCSrc,
unsigned long mask,
GCPtr pGCDst)
{
- EXA_GC_PROLOGUE (pGCDst);
+ ExaGCPriv(pGCDst);
+ swap(pExaGC, pGCDst, funcs);
(*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
- EXA_GC_EPILOGUE (pGCDst);
+ swap(pExaGC, pGCDst, funcs);
}
static void
@@ -633,25 +571,28 @@ exaChangeClip (GCPtr pGC,
pointer pvalue,
int nrects)
{
- EXA_GC_PROLOGUE (pGC);
+ ExaGCPriv(pGC);
+ swap(pExaGC, pGC, funcs);
(*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
- EXA_GC_EPILOGUE (pGC);
+ swap(pExaGC, pGC, funcs);
}
static void
exaCopyClip(GCPtr pGCDst, GCPtr pGCSrc)
{
- EXA_GC_PROLOGUE (pGCDst);
+ ExaGCPriv(pGCDst);
+ swap(pExaGC, pGCDst, funcs);
(*pGCDst->funcs->CopyClip)(pGCDst, pGCSrc);
- EXA_GC_EPILOGUE (pGCDst);
+ swap(pExaGC, pGCDst, funcs);
}
static void
exaDestroyClip(GCPtr pGC)
{
- EXA_GC_PROLOGUE (pGC);
+ ExaGCPriv(pGC);
+ swap(pExaGC, pGC, funcs);
(*pGC->funcs->DestroyClip)(pGC);
- EXA_GC_EPILOGUE (pGC);
+ swap(pExaGC, pGC, funcs);
}
/**
@@ -682,18 +623,6 @@ 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);
@@ -701,25 +630,17 @@ exaChangeWindowAttributes(WindowPtr pWin, unsigned long mask)
if ((mask & CWBorderPixmap) && pWin->borderIsPixel == FALSE)
exaPrepareAccess(&pWin->border.pixmap->drawable, EXA_PREPARE_MASK);
+ pExaScr->fallback_counter++;
swap(pExaScr, pScreen, ChangeWindowAttributes);
ret = pScreen->ChangeWindowAttributes(pWin, mask);
swap(pExaScr, pScreen, ChangeWindowAttributes);
+ pExaScr->fallback_counter--;
if ((mask & CWBackPixmap) && pWin->backgroundState == BackgroundPixmap)
exaFinishAccess(&pWin->background.pixmap->drawable, EXA_PREPARE_SRC);
if ((mask & CWBorderPixmap) && pWin->borderIsPixel == FALSE)
exaFinishAccess(&pWin->border.pixmap->drawable, EXA_PREPARE_MASK);
- /* 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;
-
return ret;
}