Clip destination instead of source. Should be the same, but it looks nicer

to me.
Clean up transition between cheap and expensive GC wrappers by using the
    prologue and epilogue macros. Before, the GC would be left unvalidated
    sometimes which would cause all kinds of entertaining bugs against a
    DDX which cares (XAA).
This commit is contained in:
Keith Packard 2004-08-15 21:13:11 +00:00
parent a68f350195
commit 9da0c214ab
2 changed files with 64 additions and 58 deletions

View File

@ -702,15 +702,15 @@ compWindowUpdateAutomatic (WindowPtr pWin)
REGION_INTERSECT (pScreen, pRegion, pRegion, &cw->borderClip); REGION_INTERSECT (pScreen, pRegion, pRegion, &cw->borderClip);
/* /*
* Now translate from screen to pixmap coordinates * Now translate from screen to dest coordinates
*/ */
REGION_TRANSLATE (pScreen, pRegion, REGION_TRANSLATE (pScreen, pRegion,
-pSrcPixmap->screen_x, -pSrcPixmap->screen_y); -pParent->drawable.x, -pParent->drawable.y);
/* /*
* Clip the picture * Clip the picture
*/ */
SetPictureClipRegion (pSrcPicture, 0, 0, pRegion); SetPictureClipRegion (pDstPicture, 0, 0, pRegion);
/* /*
* And paint * And paint
@ -719,9 +719,8 @@ compWindowUpdateAutomatic (WindowPtr pWin)
pSrcPicture, pSrcPicture,
0, 0,
pDstPicture, pDstPicture,
0, 0, 0, /* src_x, src_y */
0, 0, 0, /* msk_x, msk_y */
0, 0,
pSrcPixmap->screen_x - pParent->drawable.x, pSrcPixmap->screen_x - pParent->drawable.x,
pSrcPixmap->screen_y - pParent->drawable.y, pSrcPixmap->screen_y - pParent->drawable.y,
pSrcPixmap->drawable.width, pSrcPixmap->drawable.width,

View File

@ -120,8 +120,39 @@ cwGetBackingDrawable(DrawablePtr pDrawable, int *x_off, int *y_off)
} }
} }
/* GCFuncs wrappers. These only get used when the drawable is a window with a
* backing pixmap, to avoid the overhead in the non-window-backing-pixmap case.
*/
#define FUNC_PROLOGUE(pGC, pPriv) do { \
(pGC)->funcs = (pPriv)->wrapFuncs; \
(pGC)->ops = (pPriv)->wrapOps; \
} while (0)
#define FUNC_EPILOGUE(pGC, pPriv) do { \
(pPriv)->wrapFuncs = (pGC)->funcs; \
(pPriv)->wrapOps = (pGC)->ops; \
(pGC)->funcs = &cwGCFuncs; \
(pGC)->ops = &cwGCOps; \
} while (0)
/* /*
* create the full func/op wrappers for a GC * Cheap GC func wrappers. Pass everything through unless we find a window with
* a backing pixmap, then turn on the real wrappers.
*/
#define CHEAP_FUNC_PROLOGUE(pGC) \
((pGC)->funcs = (GCFuncs *)getCwGC(pGC))
#define CHEAP_FUNC_EPILOGUE(pGC) do { \
setCwGC(pGC,(pGC)->funcs); \
(pGC)->funcs = &cwCheapGCFuncs; \
} while (0)
/*
* create the full func/op wrappers for a GC.
* This enters with the GC unwrapped. If successful, it must leave
* with the GC wrapped. If unsuccessful, it leaves the GC alone
*/ */
static Bool static Bool
@ -144,44 +175,36 @@ cwCreateGCPrivate(GCPtr pGC, DrawablePtr pDrawable)
} }
pPriv->serialNumber = 0; pPriv->serialNumber = 0;
pPriv->stateChanges = (1 << (GCLastBit + 1)) - 1; pPriv->stateChanges = (1 << (GCLastBit + 1)) - 1;
pPriv->wrapOps = pGC->ops;
pPriv->wrapFuncs = pGC->funcs; setCwGC(pGC,pPriv);
pGC->funcs = &cwGCFuncs;
pGC->ops = &cwGCOps; FUNC_EPILOGUE(pGC,pPriv);
setCwGC (pGC, pPriv);
return TRUE; return TRUE;
} }
/*
* Destroy the full func/op wrappers for a GC and
* switch backto the cheap ones
* This enters with the GC unwrapped and must leave
* with the GC cheap wrapped
*/
static void static void
cwDestroyGCPrivate(GCPtr pGC) cwDestroyGCPrivate(GCPtr pGC)
{ {
cwGCPtr pPriv; cwGCPtr pPriv;
pPriv = (cwGCPtr) getCwGC (pGC); pPriv = (cwGCPtr) getCwGC (pGC);
pGC->funcs = &cwCheapGCFuncs;
pGC->ops = pPriv->wrapOps;
if (pPriv->pBackingGC) if (pPriv->pBackingGC)
FreeGC(pPriv->pBackingGC, (XID)0); FreeGC(pPriv->pBackingGC, (XID)0);
setCwGC (pGC, pPriv->wrapFuncs);
xfree((pointer)pPriv); xfree((pointer)pPriv);
CHEAP_FUNC_EPILOGUE (pGC);
} }
/* GCFuncs wrappers. These only get used when the drawable is a window with a
* backing pixmap, to avoid the overhead in the non-window-backing-pixmap case.
*/
#define FUNC_PROLOGUE(pGC, pPriv) do { \
(pGC)->funcs = (pPriv)->wrapFuncs; \
(pGC)->ops = (pPriv)->wrapOps; \
} while (0)
#define FUNC_EPILOGUE(pGC, pPriv) do { \
(pPriv)->wrapFuncs = (pGC)->funcs; \
(pPriv)->wrapOps = (pGC)->ops; \
(pGC)->funcs = &cwGCFuncs; \
(pGC)->ops = &cwGCOps; \
} while (0)
static void static void
cwValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable) cwValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable)
{ {
@ -343,42 +366,26 @@ cwDestroyClip(GCPtr pGC)
FUNC_EPILOGUE(pGC, pPriv); FUNC_EPILOGUE(pGC, pPriv);
} }
/*
* Cheap GC func wrappers. Pass everything through unless we find a window with
* a backing pixmap, then turn on the real wrappers.
*/
#define CHEAP_FUNC_PROLOGUE(pGC) \
((pGC)->funcs = (GCFuncs *)(pGC)->devPrivates[cwGCIndex].ptr)
#define CHEAP_FUNC_EPILOGUE(pGC) do { \
(pGC)->devPrivates[cwGCIndex].ptr = (pointer)(pGC)->funcs; \
(pGC)->funcs = &cwCheapGCFuncs; \
} while (0)
static void static void
cwCheapValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable) cwCheapValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable)
{ {
CHEAP_FUNC_PROLOGUE(pGC); CHEAP_FUNC_PROLOGUE(pGC);
/* Check if the drawable is a window with backing pixmap. If so, /*
* cwCreateGCPrivate will wrap with the backing-pixmap GC funcs and we won't * If the drawable is a redirected window, switch the GC
* re-wrap on return. * around and revalidate with cwValidateGC.
*/ */
if (cwDrawableIsRedirWindow(pDrawable) && if (cwDrawableIsRedirWindow(pDrawable) &&
cwCreateGCPrivate(pGC, pDrawable)) cwCreateGCPrivate (pGC, pDrawable))
{ {
(*pGC->funcs->ValidateGC)(pGC, stateChanges, pDrawable); cwValidateGC (pGC, stateChanges, pDrawable);
} return;
else
{
(*pGC->funcs->ValidateGC)(pGC, stateChanges, pDrawable);
/* rewrap funcs as Validate may have changed them */
pGC->devPrivates[cwGCIndex].ptr = (pointer) pGC->funcs;
CHEAP_FUNC_EPILOGUE(pGC);
} }
(*pGC->funcs->ValidateGC)(pGC, stateChanges, pDrawable);
CHEAP_FUNC_EPILOGUE(pGC);
} }
static void static void