[PATCH 4/9] exa: properly wrap GC functions
--- exa/exa.c | 219 exa/exa_priv.h| 33 - exa/exa_unaccel.c | 98 +--- 3 files changed, 234 insertions(+), 116 deletions(-) diff --git a/exa/exa.c b/exa/exa.c index 496b898..42b664f 100644 --- a/exa/exa.c +++ b/exa/exa.c @@ -575,86 +575,164 @@ exaFinishAccess(DrawablePtr pDrawable, int index) } /** - * exaValidateGC() sets the ops to EXA's implementations, which may be - * accelerated or may sync the card and fall back to fb. + * Here begins EXA's GC code. + * Do not ever access the fb/mi layer directly. */ + +static void +exaValidateGC(GCPtr pGC, + unsigned long changes, + DrawablePtr pDrawable); + +static void +exaDestroyGC(GCPtr pGC); + +static void +exaChangeGC (GCPtr pGC, + unsigned long mask); + +static void +exaCopyGC (GCPtr pGCSrc, + unsigned long mask, + GCPtr pGCDst); + +static void +exaChangeClip (GCPtr pGC, + int type, + pointer pvalue, + int nrects); + +static void +exaCopyClip(GCPtr pGCDst, GCPtr pGCSrc); + +static void +exaCopyClip(GCPtr pGCDst, GCPtr pGCSrc); + static void -exaValidateGC (GCPtr pGC, unsigned long changes, DrawablePtr pDrawable) +exaDestroyClip(GCPtr pGC); + +const GCFuncs exaGCFuncs = { +exaValidateGC, +exaChangeGC, +exaCopyGC, +exaDestroyGC, +exaChangeClip, +exaDestroyClip, +exaCopyClip +}; + +/* + * This wrapper exists to allow fbValidateGC to work. + */ +static PixmapPtr +exaCreatePixmapWithPrepare(ScreenPtr pScreen, int w, int h, int depth, + unsigned usage_hint) +{ +PixmapPtr pPixmap = exaCreatePixmap(pScreen, w, h, depth, usage_hint); + +if (!pPixmap) + return NULL; + +/* We use MASK, because SRC is already taken. */ +exaPrepareAccess(pPixmap-drawable, EXA_PREPARE_MASK); + +return pPixmap; +} + +static void +exaValidateGC(GCPtr pGC, + unsigned long changes, + DrawablePtr pDrawable) { /* fbValidateGC will do direct access to pixmaps if the tiling has changed. - * Preempt fbValidateGC by doing its work and masking the change out, so - * that we can do the Prepare/FinishAccess. + * Do a few smart things so fbValidateGC can do it's work. */ -#ifdef FB_24_32BIT -if ((changes GCTile) fbGetRotatedPixmap(pGC)) { - (*pGC-pScreen-DestroyPixmap) (fbGetRotatedPixmap(pGC)); - fbGetRotatedPixmap(pGC) = 0; -} - -if (pGC-fillStyle == FillTiled) { - PixmapPtr pOldTile, pNewTile; - pOldTile = pGC-tile.pixmap; - if (pOldTile-drawable.bitsPerPixel != pDrawable-bitsPerPixel) - { - pNewTile = fbGetRotatedPixmap(pGC); - if (!pNewTile || - pNewTile -drawable.bitsPerPixel != pDrawable-bitsPerPixel) - { - if (pNewTile) - (*pGC-pScreen-DestroyPixmap) (pNewTile); - /* fb24_32ReformatTile will do direct access of a newly- -* allocated pixmap. This isn't a problem yet, since we don't -* put pixmaps in FB until at least one accelerated EXA op. -*/ - exaPrepareAccess(pOldTile-drawable, EXA_PREPARE_SRC); - pNewTile = fb24_32ReformatTile (pOldTile, - pDrawable-bitsPerPixel); - exaPixmapDirty(pNewTile, 0, 0, pNewTile-drawable.width, pNewTile-drawable.height); - exaFinishAccess(pOldTile-drawable, EXA_PREPARE_SRC); - } - if (pNewTile) - { - fbGetRotatedPixmap(pGC) = pOldTile; - pGC-tile.pixmap = pNewTile; - changes |= GCTile; - } - } +ScreenPtr pScreen = pDrawable-pScreen; +CreatePixmapProcPtr old_ptr = NULL; +PixmapPtr pTile = NULL; +EXA_GC_PROLOGUE(pGC); +if (changes GCTile) { + old_ptr = pScreen-CreatePixmap; + pScreen-CreatePixmap = exaCreatePixmapWithPrepare; + if (pGC-fillStyle == FillTiled) + pTile = pGC-tile.pixmap; + if (pTile) + exaPrepareAccess(pTile-drawable, EXA_PREPARE_SRC); } -#endif +exaPrepareAccessGC(pGC); +(*pGC-funcs-ValidateGC)(pGC, changes, pDrawable); +exaFinishAccessGC(pGC); if (changes GCTile) { - if (!pGC-tileIsPixel FbEvenTile (pGC-tile.pixmap-drawable.width * -pDrawable-bitsPerPixel)) - { - exaPrepareAccess(pGC-tile.pixmap-drawable, EXA_PREPARE_SRC); - fbPadPixmap (pGC-tile.pixmap); - exaFinishAccess(pGC-tile.pixmap-drawable, EXA_PREPARE_SRC); + pScreen-CreatePixmap = old_ptr; + if (pTile) + exaFinishAccess(pTile-drawable, EXA_PREPARE_SRC); + + /* A new tile pixmap was created. */ + if (pGC-tile.pixmap != pTile pGC-fillStyle == FillTiled) { +
[PATCH 4/9] exa: properly wrap GC functions
--- exa/exa.c | 233 + exa/exa_priv.h| 33 +++- exa/exa_unaccel.c | 98 --- 3 files changed, 248 insertions(+), 116 deletions(-) diff --git a/exa/exa.c b/exa/exa.c index 496b898..58d1a7d 100644 --- a/exa/exa.c +++ b/exa/exa.c @@ -575,86 +575,178 @@ exaFinishAccess(DrawablePtr pDrawable, int index) } /** - * exaValidateGC() sets the ops to EXA's implementations, which may be - * accelerated or may sync the card and fall back to fb. + * Here begins EXA's GC code. + * Do not ever access the fb/mi layer directly. */ + +static void +exaValidateGC(GCPtr pGC, + unsigned long changes, + DrawablePtr pDrawable); + +static void +exaDestroyGC(GCPtr pGC); + +static void +exaChangeGC (GCPtr pGC, + unsigned long mask); + +static void +exaCopyGC (GCPtr pGCSrc, + unsigned long mask, + GCPtr pGCDst); + +static void +exaChangeClip (GCPtr pGC, + int type, + pointer pvalue, + int nrects); + static void -exaValidateGC (GCPtr pGC, unsigned long changes, DrawablePtr pDrawable) +exaCopyClip(GCPtr pGCDst, GCPtr pGCSrc); + +static void +exaCopyClip(GCPtr pGCDst, GCPtr pGCSrc); + +static void +exaDestroyClip(GCPtr pGC); + +const GCFuncs exaGCFuncs = { +exaValidateGC, +exaChangeGC, +exaCopyGC, +exaDestroyGC, +exaChangeClip, +exaDestroyClip, +exaCopyClip +}; + +/* + * This wrapper exists to allow fbValidateGC to work. + */ +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; + +/* We use MASK, because SRC is already taken. */ +exaPrepareAccess(pPixmap-drawable, EXA_PREPARE_MASK); + +return pPixmap; +} + +static void +exaValidateGC(GCPtr pGC, + unsigned long changes, + DrawablePtr pDrawable) { /* fbValidateGC will do direct access to pixmaps if the tiling has changed. - * Preempt fbValidateGC by doing its work and masking the change out, so - * that we can do the Prepare/FinishAccess. + * Do a few smart things so fbValidateGC can do it's work. */ -#ifdef FB_24_32BIT -if ((changes GCTile) fbGetRotatedPixmap(pGC)) { - (*pGC-pScreen-DestroyPixmap) (fbGetRotatedPixmap(pGC)); - fbGetRotatedPixmap(pGC) = 0; -} - -if (pGC-fillStyle == FillTiled) { - PixmapPtr pOldTile, pNewTile; - pOldTile = pGC-tile.pixmap; - if (pOldTile-drawable.bitsPerPixel != pDrawable-bitsPerPixel) - { - pNewTile = fbGetRotatedPixmap(pGC); - if (!pNewTile || - pNewTile -drawable.bitsPerPixel != pDrawable-bitsPerPixel) - { - if (pNewTile) - (*pGC-pScreen-DestroyPixmap) (pNewTile); - /* fb24_32ReformatTile will do direct access of a newly- -* allocated pixmap. This isn't a problem yet, since we don't -* put pixmaps in FB until at least one accelerated EXA op. -*/ - exaPrepareAccess(pOldTile-drawable, EXA_PREPARE_SRC); - pNewTile = fb24_32ReformatTile (pOldTile, - pDrawable-bitsPerPixel); - exaPixmapDirty(pNewTile, 0, 0, pNewTile-drawable.width, pNewTile-drawable.height); - exaFinishAccess(pOldTile-drawable, EXA_PREPARE_SRC); - } - if (pNewTile) - { - fbGetRotatedPixmap(pGC) = pOldTile; - pGC-tile.pixmap = pNewTile; - changes |= GCTile; - } - } +ScreenPtr pScreen = pDrawable-pScreen; +ExaScreenPriv(pScreen); +CreatePixmapProcPtr old_ptr = NULL; +PixmapPtr pTile = NULL; +EXA_GC_PROLOGUE(pGC); +if (changes GCTile) { + /* save the fb pointer. */ + old_ptr = pExaScr-SavedCreatePixmap; + /* create a new upper layer pointer. */ + wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmapWithPrepare); + if (pGC-fillStyle == FillTiled) + pTile = pGC-tile.pixmap; + if (pTile) + exaPrepareAccess(pTile-drawable, EXA_PREPARE_SRC); } -#endif +exaPrepareAccessGC(pGC); +(*pGC-funcs-ValidateGC)(pGC, changes, pDrawable); +exaFinishAccessGC(pGC); if (changes GCTile) { - if (!pGC-tileIsPixel FbEvenTile (pGC-tile.pixmap-drawable.width * -