Commit 87842285 authored by Kevin E Martin's avatar Kevin E Martin
Browse files

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

parent 9223baf9
......@@ -65,21 +65,6 @@ cwCopyClip(GCPtr pgcDst, GCPtr pgcSrc);
static void
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 = {
cwValidateGC,
cwChangeGC,
......@@ -90,16 +75,6 @@ static GCFuncs cwGCFuncs = {
cwCopyClip,
};
static GCFuncs cwCheapGCFuncs = {
cwCheapValidateGC,
cwCheapChangeGC,
cwCheapCopyGC,
cwCheapDestroyGC,
cwCheapChangeClip,
cwCheapDestroyClip,
cwCheapCopyClip,
};
/* Find the real drawable to draw to, and provide offsets that will translate
* 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 { \
(pGC)->funcs = (pPriv)->wrapFuncs; \
(pGC)->ops = (pPriv)->wrapOps; \
......@@ -136,73 +107,38 @@ cwGetBackingDrawable(DrawablePtr pDrawable, int *x_off, int *y_off)
(pGC)->ops = &cwGCOps; \
} 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
cwCreateGCPrivate(GCPtr pGC, DrawablePtr pDrawable)
cwCreateBackingGC(GCPtr pGC, DrawablePtr pDrawable)
{
cwGCRec *pPriv;
cwGCRec *pPriv = getCwGC(pGC);
int status, x_off, y_off;
XID noexpose = xFalse;
DrawablePtr pBackingDrawable;
pPriv = (cwGCRec *)xalloc(sizeof (cwGCRec));
if (!pPriv)
return FALSE;
pBackingDrawable = cwGetBackingDrawable(pDrawable, &x_off, &y_off);
pPriv->pBackingGC = CreateGC(pBackingDrawable, GCGraphicsExposures,
&noexpose, &status);
if (status != Success) {
xfree(pPriv);
if (status != Success)
return FALSE;
}
pPriv->serialNumber = 0;
pPriv->stateChanges = (1 << (GCLastBit + 1)) - 1;
setCwGC(pGC,pPriv);
FUNC_EPILOGUE(pGC,pPriv);
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
cwDestroyGCPrivate(GCPtr pGC)
cwDestroyBackingGC(GCPtr pGC)
{
cwGCPtr pPriv;
pPriv = (cwGCPtr) getCwGC (pGC);
if (pPriv->pBackingGC)
if (pPriv->pBackingGC) {
FreeGC(pPriv->pBackingGC, (XID)0);
xfree((pointer)pPriv);
CHEAP_FUNC_EPILOGUE (pGC);
pPriv->pBackingGC = NULL;
}
}
static void
......@@ -221,15 +157,16 @@ cwValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable)
* Must call ValidateGC to ensure pGC->pCompositeClip is valid
*/
(*pGC->funcs->ValidateGC)(pGC, stateChanges, pDrawable);
if (pDrawable->serialNumber != pPriv->serialNumber &&
!cwDrawableIsRedirWindow(pDrawable))
{
/* The drawable is no longer a window with backing store, so kill the
* private and go back to cheap functions.
*/
cwDestroyGCPrivate(pGC);
if (!cwDrawableIsRedirWindow(pDrawable)) {
cwDestroyBackingGC(pGC);
FUNC_EPILOGUE(pGC, pPriv);
return;
} else {
if (!pPriv->pBackingGC && !cwCreateBackingGC(pGC, pDrawable)) {
FUNC_EPILOGUE(pGC, pPriv);
return;
}
}
pBackingGC = pPriv->pBackingGC;
......@@ -323,7 +260,7 @@ cwDestroyGC(GCPtr pGC)
FUNC_PROLOGUE(pGC, pPriv);
cwDestroyGCPrivate(pGC);
cwDestroyBackingGC(pGC);
(*pGC->funcs->DestroyGC) (pGC);
......@@ -366,91 +303,8 @@ cwDestroyClip(GCPtr pGC)
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
* GC validation on BackingStore windows.
* Screen wrappers.
*/
#define SCREEN_PROLOGUE(pScreen, field) \
......@@ -464,16 +318,15 @@ cwCheapDestroyClip(GCPtr pGC)
static Bool
cwCreateGC(GCPtr pGC)
{
cwGCPtr pPriv = getCwGC(pGC);
ScreenPtr pScreen = pGC->pScreen;
Bool ret;
bzero(pPriv, sizeof(cwGCRec));
SCREEN_PROLOGUE(pScreen, CreateGC);
if ( (ret = (*pScreen->CreateGC)(pGC)) )
{
pGC->devPrivates[cwGCIndex].ptr = (pointer)pGC->funcs;
pGC->funcs = &cwCheapGCFuncs;
}
FUNC_EPILOGUE(pGC, pPriv);
SCREEN_EPILOGUE(pScreen, CreateGC, cwCreateGC);
......@@ -774,7 +627,7 @@ miInitializeCompositeWrapper(ScreenPtr pScreen)
#endif
cwGeneration = serverGeneration;
}
if (!AllocateGCPrivate(pScreen, cwGCIndex, 0))
if (!AllocateGCPrivate(pScreen, cwGCIndex, sizeof(cwGCRec)))
return;
if (!AllocateWindowPrivate(pScreen, cwWindowIndex, 0))
return;
......
......@@ -26,10 +26,10 @@
#define SETUP_BACKING_DST(_pDst, _pGC) \
cwGCPtr pGCPrivate = getCwGC (_pGC); \
GCPtr pBackingGC = pGCPrivate->pBackingGC; \
int dst_off_x, dst_off_y; \
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) \
int src_off_x, src_off_y; \
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment