diff options
author | Maarten Maathuis <madman2003@gmail.com> | 2009-11-28 10:34:43 +0100 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2009-11-28 12:44:21 -0800 |
commit | 342f3689d17256c92cbfee079d24501d27aa1153 (patch) | |
tree | b017a035edf544e97788f552d68ccfd066328ef3 /exa/exa.c | |
parent | b54bc14ce0ae38c4863794bc3096ca86cdb23908 (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.c | 145 |
1 files changed, 33 insertions, 112 deletions
@@ -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; } |