xenocara/xserver/hw/xfree86/xaa/xaawrap.h
matthieu 9bd69e2c49 Fix from X.Org master git for XAA screen corruption.
XAA PixmapOps: Sync before accessing unwrapped callbacks.

    When using any XAAPixmapOps, we call into unknown but freshly
    unwrapped callbacks (like fb ones). Unlike the XAA*Fallback calls,
    we did so without syncing first, exposing us to all kinds of
    synchronisation issues.

    I believe that the rendering errors appeared now because *PaintWindow
    vanished (e4d11e58), and we just use miPaintWindow instead. This
    takes a less direct route to the hw and ends up at
    PolyFillRectPixmap, which very often left drawing artifacts.

    We now sync accordingly, and no longer get the rendering artifacts i
    was methodically reproducing on radeonhd, radeon, unichrome...

    Also, in order to allow driver authors to remove extensive syncing
    or flushing to hide this issue, create XAA_VERSION_ defines, put
    them in xaa.h and bump the patchlevel.

tested by naddy@ and Edd Barrett. ok oga@.
2008-11-11 20:31:42 +00:00

82 lines
2.5 KiB
C

#define XAA_SCREEN_PROLOGUE(pScreen, field)\
((pScreen)->field = \
((XAAScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates, XAAGetScreenKey()))->field)
#define XAA_SCREEN_EPILOGUE(pScreen, field, wrapper)\
((pScreen)->field = wrapper)
#define XAA_GC_FUNC_PROLOGUE(pGC)\
XAAGCPtr pGCPriv = (XAAGCPtr)dixLookupPrivate(&(pGC)->devPrivates, XAAGetGCKey()); \
(pGC)->funcs = pGCPriv->wrapFuncs;\
if(pGCPriv->flags)\
(pGC)->ops = pGCPriv->wrapOps
#define XAA_GC_FUNC_EPILOGUE(pGC)\
pGCPriv->wrapFuncs = (pGC)->funcs;\
(pGC)->funcs = &XAAGCFuncs;\
if(pGCPriv->flags) {\
pGCPriv->wrapOps = (pGC)->ops;\
(pGC)->ops = (pGCPriv->flags & OPS_ARE_ACCEL) ? pGCPriv->XAAOps :\
&XAAPixmapOps;\
}
#define XAA_GC_OP_PROLOGUE(pGC)\
XAAGCPtr pGCPriv = (XAAGCPtr)dixLookupPrivate(&(pGC)->devPrivates, XAAGetGCKey()); \
GCFuncs *oldFuncs = pGC->funcs;\
pGC->funcs = pGCPriv->wrapFuncs;\
pGC->ops = pGCPriv->wrapOps
#define XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC)\
XAAGCPtr pGCPriv = (XAAGCPtr)dixLookupPrivate(&(pGC)->devPrivates, XAAGetGCKey()); \
GCFuncs *oldFuncs = pGC->funcs;\
if(!REGION_NUM_RECTS(pGC->pCompositeClip)) return; \
pGC->funcs = pGCPriv->wrapFuncs;\
pGC->ops = pGCPriv->wrapOps
#define XAA_GC_OP_EPILOGUE(pGC)\
pGCPriv->wrapOps = pGC->ops;\
pGC->funcs = oldFuncs;\
pGC->ops = pGCPriv->XAAOps
#define XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw)\
XAAGCPtr pGCPriv = (XAAGCPtr)dixLookupPrivate(&(pGC)->devPrivates, XAAGetGCKey()); \
XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE((PixmapPtr)(pDraw));\
GCFuncs *oldFuncs = pGC->funcs;\
pGC->funcs = pGCPriv->wrapFuncs;\
pGC->ops = pGCPriv->wrapOps; \
SYNC_CHECK(pGC)
#define XAA_PIXMAP_OP_EPILOGUE(pGC)\
pGCPriv->wrapOps = pGC->ops;\
pGC->funcs = oldFuncs;\
pGC->ops = &XAAPixmapOps;\
pixPriv->flags |= DIRTY
#ifdef HAVE_XORG_CONFIG_H
#include <xorg-config.h>
#endif
#ifdef RENDER
#define XAA_RENDER_PROLOGUE(pScreen,field)\
(GetPictureScreen(pScreen)->field = \
((XAAScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates, XAAGetScreenKey()))->field)
#define XAA_RENDER_EPILOGUE(pScreen, field, wrapper)\
(GetPictureScreen(pScreen)->field = wrapper)
#endif
/* This also works fine for drawables */
#define SYNC_CHECK(pGC) {\
XAAInfoRecPtr infoRec =\
((XAAScreenPtr)dixLookupPrivate(&(pGC)->pScreen->devPrivates, XAAGetScreenKey()))->AccelInfoRec; \
if(infoRec->NeedToSync) {\
(*infoRec->Sync)(infoRec->pScrn);\
infoRec->NeedToSync = FALSE;\
}}