Fix CopyArea for non-redir dst, redir src (Bug #1105, Eric Anholt).

This commit is contained in:
Kevin E Martin 2004-08-18 21:11:17 +00:00
parent 9223baf985
commit 8784228500
2 changed files with 26 additions and 173 deletions

View File

@ -65,21 +65,6 @@ cwCopyClip(GCPtr pgcDst, GCPtr pgcSrc);
static void static void
cwDestroyClip(GCPtr pGC); cwDestroyClip(GCPtr pGC);
static void
cwCheapValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable);
static void
cwCheapChangeGC(GCPtr pGC, unsigned long mask);
static void
cwCheapCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
static void
cwCheapDestroyGC(GCPtr pGC);
static void
cwCheapChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects);
static void
cwCheapCopyClip(GCPtr pgcDst, GCPtr pgcSrc);
static void
cwCheapDestroyClip(GCPtr pGC);
static GCFuncs cwGCFuncs = { static GCFuncs cwGCFuncs = {
cwValidateGC, cwValidateGC,
cwChangeGC, cwChangeGC,
@ -90,16 +75,6 @@ static GCFuncs cwGCFuncs = {
cwCopyClip, cwCopyClip,
}; };
static GCFuncs cwCheapGCFuncs = {
cwCheapValidateGC,
cwCheapChangeGC,
cwCheapCopyGC,
cwCheapDestroyGC,
cwCheapChangeClip,
cwCheapDestroyClip,
cwCheapCopyClip,
};
/* Find the real drawable to draw to, and provide offsets that will translate /* Find the real drawable to draw to, and provide offsets that will translate
* window coordinates to backing pixmap coordinates. * window coordinates to backing pixmap coordinates.
*/ */
@ -120,10 +95,6 @@ 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 { \ #define FUNC_PROLOGUE(pGC, pPriv) do { \
(pGC)->funcs = (pPriv)->wrapFuncs; \ (pGC)->funcs = (pPriv)->wrapFuncs; \
(pGC)->ops = (pPriv)->wrapOps; \ (pGC)->ops = (pPriv)->wrapOps; \
@ -136,73 +107,38 @@ cwGetBackingDrawable(DrawablePtr pDrawable, int *x_off, int *y_off)
(pGC)->ops = &cwGCOps; \ (pGC)->ops = &cwGCOps; \
} while (0) } while (0)
/*
* 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
cwCreateGCPrivate(GCPtr pGC, DrawablePtr pDrawable) cwCreateBackingGC(GCPtr pGC, DrawablePtr pDrawable)
{ {
cwGCRec *pPriv; cwGCRec *pPriv = getCwGC(pGC);
int status, x_off, y_off; int status, x_off, y_off;
XID noexpose = xFalse; XID noexpose = xFalse;
DrawablePtr pBackingDrawable; DrawablePtr pBackingDrawable;
pPriv = (cwGCRec *)xalloc(sizeof (cwGCRec));
if (!pPriv)
return FALSE;
pBackingDrawable = cwGetBackingDrawable(pDrawable, &x_off, &y_off); pBackingDrawable = cwGetBackingDrawable(pDrawable, &x_off, &y_off);
pPriv->pBackingGC = CreateGC(pBackingDrawable, GCGraphicsExposures, pPriv->pBackingGC = CreateGC(pBackingDrawable, GCGraphicsExposures,
&noexpose, &status); &noexpose, &status);
if (status != Success) { if (status != Success)
xfree(pPriv);
return FALSE; return FALSE;
}
pPriv->serialNumber = 0; pPriv->serialNumber = 0;
pPriv->stateChanges = (1 << (GCLastBit + 1)) - 1; pPriv->stateChanges = (1 << (GCLastBit + 1)) - 1;
setCwGC(pGC,pPriv);
FUNC_EPILOGUE(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) cwDestroyBackingGC(GCPtr pGC)
{ {
cwGCPtr pPriv; cwGCPtr pPriv;
pPriv = (cwGCPtr) getCwGC (pGC); pPriv = (cwGCPtr) getCwGC (pGC);
if (pPriv->pBackingGC) if (pPriv->pBackingGC) {
FreeGC(pPriv->pBackingGC, (XID)0); FreeGC(pPriv->pBackingGC, (XID)0);
pPriv->pBackingGC = NULL;
xfree((pointer)pPriv); }
CHEAP_FUNC_EPILOGUE (pGC);
} }
static void static void
@ -221,15 +157,16 @@ cwValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable)
* Must call ValidateGC to ensure pGC->pCompositeClip is valid * Must call ValidateGC to ensure pGC->pCompositeClip is valid
*/ */
(*pGC->funcs->ValidateGC)(pGC, stateChanges, pDrawable); (*pGC->funcs->ValidateGC)(pGC, stateChanges, pDrawable);
if (pDrawable->serialNumber != pPriv->serialNumber && if (!cwDrawableIsRedirWindow(pDrawable)) {
!cwDrawableIsRedirWindow(pDrawable)) cwDestroyBackingGC(pGC);
{ FUNC_EPILOGUE(pGC, pPriv);
/* The drawable is no longer a window with backing store, so kill the
* private and go back to cheap functions.
*/
cwDestroyGCPrivate(pGC);
return; return;
} else {
if (!pPriv->pBackingGC && !cwCreateBackingGC(pGC, pDrawable)) {
FUNC_EPILOGUE(pGC, pPriv);
return;
}
} }
pBackingGC = pPriv->pBackingGC; pBackingGC = pPriv->pBackingGC;
@ -323,7 +260,7 @@ cwDestroyGC(GCPtr pGC)
FUNC_PROLOGUE(pGC, pPriv); FUNC_PROLOGUE(pGC, pPriv);
cwDestroyGCPrivate(pGC); cwDestroyBackingGC(pGC);
(*pGC->funcs->DestroyGC) (pGC); (*pGC->funcs->DestroyGC) (pGC);
@ -366,91 +303,8 @@ cwDestroyClip(GCPtr pGC)
FUNC_EPILOGUE(pGC, pPriv); FUNC_EPILOGUE(pGC, pPriv);
} }
static void
cwCheapValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable)
{
CHEAP_FUNC_PROLOGUE(pGC);
/*
* If the drawable is a redirected window, switch the GC
* around and revalidate with cwValidateGC.
*/
if (cwDrawableIsRedirWindow(pDrawable) &&
cwCreateGCPrivate (pGC, pDrawable))
{
cwValidateGC (pGC, stateChanges, pDrawable);
return;
}
(*pGC->funcs->ValidateGC)(pGC, stateChanges, pDrawable);
CHEAP_FUNC_EPILOGUE(pGC);
}
static void
cwCheapChangeGC(GCPtr pGC, unsigned long mask)
{
CHEAP_FUNC_PROLOGUE(pGC);
(*pGC->funcs->ChangeGC)(pGC, mask);
CHEAP_FUNC_EPILOGUE(pGC);
}
static void
cwCheapCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst)
{
CHEAP_FUNC_PROLOGUE(pGCDst);
(*pGCDst->funcs->CopyGC)(pGCSrc, mask, pGCDst);
CHEAP_FUNC_EPILOGUE(pGCDst);
}
static void
cwCheapDestroyGC(GCPtr pGC)
{
CHEAP_FUNC_PROLOGUE(pGC);
(*pGC->funcs->DestroyGC)(pGC);
/* leave it unwrapped */
}
static void
cwCheapChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects)
{
CHEAP_FUNC_PROLOGUE(pGC);
(*pGC->funcs->ChangeClip)(pGC, type, pvalue, nrects);
CHEAP_FUNC_EPILOGUE(pGC);
}
static void
cwCheapCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
{
CHEAP_FUNC_PROLOGUE(pgcDst);
(*pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
CHEAP_FUNC_EPILOGUE(pgcDst);
}
static void
cwCheapDestroyClip(GCPtr pGC)
{
CHEAP_FUNC_PROLOGUE(pGC);
(*pGC->funcs->DestroyClip)(pGC);
CHEAP_FUNC_EPILOGUE(pGC);
}
/* /*
* GC Create wrapper. Set up the cheap GC func wrappers to track * Screen wrappers.
* GC validation on BackingStore windows.
*/ */
#define SCREEN_PROLOGUE(pScreen, field) \ #define SCREEN_PROLOGUE(pScreen, field) \
@ -464,16 +318,15 @@ cwCheapDestroyClip(GCPtr pGC)
static Bool static Bool
cwCreateGC(GCPtr pGC) cwCreateGC(GCPtr pGC)
{ {
cwGCPtr pPriv = getCwGC(pGC);
ScreenPtr pScreen = pGC->pScreen; ScreenPtr pScreen = pGC->pScreen;
Bool ret; Bool ret;
bzero(pPriv, sizeof(cwGCRec));
SCREEN_PROLOGUE(pScreen, CreateGC); SCREEN_PROLOGUE(pScreen, CreateGC);
if ( (ret = (*pScreen->CreateGC)(pGC)) ) if ( (ret = (*pScreen->CreateGC)(pGC)) )
{ FUNC_EPILOGUE(pGC, pPriv);
pGC->devPrivates[cwGCIndex].ptr = (pointer)pGC->funcs;
pGC->funcs = &cwCheapGCFuncs;
}
SCREEN_EPILOGUE(pScreen, CreateGC, cwCreateGC); SCREEN_EPILOGUE(pScreen, CreateGC, cwCreateGC);
@ -774,7 +627,7 @@ miInitializeCompositeWrapper(ScreenPtr pScreen)
#endif #endif
cwGeneration = serverGeneration; cwGeneration = serverGeneration;
} }
if (!AllocateGCPrivate(pScreen, cwGCIndex, 0)) if (!AllocateGCPrivate(pScreen, cwGCIndex, sizeof(cwGCRec)))
return; return;
if (!AllocateWindowPrivate(pScreen, cwWindowIndex, 0)) if (!AllocateWindowPrivate(pScreen, cwWindowIndex, 0))
return; return;

View File

@ -26,10 +26,10 @@
#define SETUP_BACKING_DST(_pDst, _pGC) \ #define SETUP_BACKING_DST(_pDst, _pGC) \
cwGCPtr pGCPrivate = getCwGC (_pGC); \ cwGCPtr pGCPrivate = getCwGC (_pGC); \
GCPtr pBackingGC = pGCPrivate->pBackingGC; \
int dst_off_x, dst_off_y; \ int dst_off_x, dst_off_y; \
DrawablePtr pBackingDst = cwGetBackingDrawable(pDst, &dst_off_x, \ DrawablePtr pBackingDst = cwGetBackingDrawable(pDst, &dst_off_x, \
&dst_off_y) &dst_off_y); \
GCPtr pBackingGC = pGCPrivate->pBackingGC ? pGCPrivate->pBackingGC : _pGC
#define SETUP_BACKING_SRC(pSrc, pGC) \ #define SETUP_BACKING_SRC(pSrc, pGC) \
int src_off_x, src_off_y; \ int src_off_x, src_off_y; \