Fix clip list computation and setting to ignore clip changes to "real"
GC/Picture and track serial numbers correctly when copying pCompositeClip down.
This commit is contained in:
parent
183c6d0645
commit
cc3ad0ed43
|
@ -218,22 +218,14 @@ cwValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable)
|
||||||
|
|
||||||
pPriv->stateChanges |= stateChanges;
|
pPriv->stateChanges |= stateChanges;
|
||||||
|
|
||||||
if (pPriv->stateChanges) {
|
/*
|
||||||
CopyGC(pGC, pBackingGC, pPriv->stateChanges);
|
* Copy the composite clip into the backing GC if either
|
||||||
pPriv->stateChanges = 0;
|
* the drawable clip list has changed or the client has changed
|
||||||
}
|
* the client clip data
|
||||||
|
*/
|
||||||
if ((pGC->patOrg.x + x_off) != pBackingGC->patOrg.x ||
|
if (pDrawable->serialNumber != pPriv->serialNumber ||
|
||||||
(pGC->patOrg.y + y_off) != pBackingGC->patOrg.y)
|
(pPriv->stateChanges & (GCClipXOrigin|GCClipYOrigin|GCClipMask)))
|
||||||
{
|
{
|
||||||
XID vals[2];
|
|
||||||
vals[0] = pGC->patOrg.x + x_off;
|
|
||||||
vals[1] = pGC->patOrg.y + y_off;
|
|
||||||
dixChangeGC(NullClient, pBackingGC,
|
|
||||||
(GCTileStipXOrigin | GCTileStipYOrigin), vals, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pDrawable->serialNumber != pPriv->serialNumber) {
|
|
||||||
XID vals[2];
|
XID vals[2];
|
||||||
RegionPtr pCompositeClip;
|
RegionPtr pCompositeClip;
|
||||||
|
|
||||||
|
@ -254,6 +246,26 @@ cwValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable)
|
||||||
(GCClipXOrigin | GCClipYOrigin), vals, NULL);
|
(GCClipXOrigin | GCClipYOrigin), vals, NULL);
|
||||||
|
|
||||||
pPriv->serialNumber = pDrawable->serialNumber;
|
pPriv->serialNumber = pDrawable->serialNumber;
|
||||||
|
/*
|
||||||
|
* Mask off any client clip changes to make sure
|
||||||
|
* the clip list set above remains in effect
|
||||||
|
*/
|
||||||
|
pPriv->stateChanges &= ~(GCClipXOrigin|GCClipYOrigin|GCClipMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pPriv->stateChanges) {
|
||||||
|
CopyGC(pGC, pBackingGC, pPriv->stateChanges);
|
||||||
|
pPriv->stateChanges = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((pGC->patOrg.x + x_off) != pBackingGC->patOrg.x ||
|
||||||
|
(pGC->patOrg.y + y_off) != pBackingGC->patOrg.y)
|
||||||
|
{
|
||||||
|
XID vals[2];
|
||||||
|
vals[0] = pGC->patOrg.x + x_off;
|
||||||
|
vals[1] = pGC->patOrg.y + y_off;
|
||||||
|
dixChangeGC(NullClient, pBackingGC,
|
||||||
|
(GCTileStipXOrigin | GCTileStipYOrigin), vals, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
ValidateGC(pBackingDrawable, pBackingGC);
|
ValidateGC(pBackingDrawable, pBackingGC);
|
||||||
|
|
|
@ -44,6 +44,20 @@ extern int cwGCIndex;
|
||||||
#define getCwGC(pGC) ((cwGCPtr)(pGC)->devPrivates[cwGCIndex].ptr)
|
#define getCwGC(pGC) ((cwGCPtr)(pGC)->devPrivates[cwGCIndex].ptr)
|
||||||
#define setCwGC(pGC,p) ((pGC)->devPrivates[cwGCIndex].ptr = (pointer) (p))
|
#define setCwGC(pGC,p) ((pGC)->devPrivates[cwGCIndex].ptr = (pointer) (p))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* One of these structures is allocated per Picture that gets used with a
|
||||||
|
* window with a backing pixmap
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
PicturePtr pBackingPicture;
|
||||||
|
unsigned long serialNumber;
|
||||||
|
unsigned long stateChanges;
|
||||||
|
} cwPictureRec, *cwPicturePtr;
|
||||||
|
|
||||||
|
#define getCwPicture(pPicture) ((cwPicturePtr)(pPicture)->devPrivates[cwPictureIndex].ptr)
|
||||||
|
#define setCwPicture(pPicture,p) ((pPicture)->devPrivates[cwPictureIndex].ptr = (pointer) (p))
|
||||||
|
|
||||||
extern int cwPictureIndex;
|
extern int cwPictureIndex;
|
||||||
|
|
||||||
#define cwDrawableIsRedirWindow(pDraw) \
|
#define cwDrawableIsRedirWindow(pDraw) \
|
||||||
|
|
|
@ -31,9 +31,8 @@
|
||||||
PictureScreenPtr ps = GetPictureScreen (pScreen); \
|
PictureScreenPtr ps = GetPictureScreen (pScreen); \
|
||||||
cwScreenPtr pCwScreen = getCwScreen (pScreen)
|
cwScreenPtr pCwScreen = getCwScreen (pScreen)
|
||||||
|
|
||||||
#define cwPictureDecl \
|
#define cwPicturePrivate \
|
||||||
PicturePtr pBackingPicture = \
|
cwPicturePtr pPicturePrivate = getCwPicture(pPicture)
|
||||||
((pPicture)->devPrivates[cwPictureIndex].ptr)
|
|
||||||
|
|
||||||
#define cwSrcPictureDecl \
|
#define cwSrcPictureDecl \
|
||||||
int src_picture_x_off, src_picture_y_off; \
|
int src_picture_x_off, src_picture_y_off; \
|
||||||
|
@ -63,45 +62,60 @@
|
||||||
ps->elt = func; \
|
ps->elt = func; \
|
||||||
}
|
}
|
||||||
|
|
||||||
static PicturePtr
|
static cwPicturePtr
|
||||||
cwCreateBackingPicture (PicturePtr pPicture)
|
cwCreatePicturePrivate (PicturePtr pPicture)
|
||||||
{
|
{
|
||||||
ScreenPtr pScreen = pPicture->pDrawable->pScreen;
|
ScreenPtr pScreen = pPicture->pDrawable->pScreen;
|
||||||
WindowPtr pWindow = (WindowPtr) pPicture->pDrawable;
|
WindowPtr pWindow = (WindowPtr) pPicture->pDrawable;
|
||||||
PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWindow);
|
PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWindow);
|
||||||
int error;
|
int error;
|
||||||
PicturePtr pBackingPicture;
|
cwPicturePtr pPicturePrivate;
|
||||||
|
|
||||||
pBackingPicture = CreatePicture (0, &pPixmap->drawable, pPicture->pFormat,
|
pPicturePrivate = xalloc (sizeof (cwPictureRec));
|
||||||
0, 0, serverClient, &error);
|
if (!pPicturePrivate)
|
||||||
if (!pBackingPicture)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
pPicturePrivate->pBackingPicture = CreatePicture (0, &pPixmap->drawable,
|
||||||
|
pPicture->pFormat,
|
||||||
|
0, 0, serverClient,
|
||||||
|
&error);
|
||||||
|
if (!pPicturePrivate->pBackingPicture)
|
||||||
|
{
|
||||||
|
xfree (pPicturePrivate);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
pPicture->devPrivates[cwPictureIndex].ptr = pBackingPicture;
|
/*
|
||||||
|
* Ensure that this serial number does not match the window's
|
||||||
|
*/
|
||||||
|
pPicturePrivate->serialNumber = pPixmap->drawable.serialNumber;
|
||||||
|
pPicturePrivate->stateChanges = (1 << (CPLastBit + 1)) - 1;
|
||||||
|
|
||||||
|
setCwPicture(pPicture, pPicturePrivate);
|
||||||
|
|
||||||
CopyPicture(pPicture, (1 << (CPLastBit + 1)) - 1, pBackingPicture);
|
return pPicturePrivate;
|
||||||
|
|
||||||
return pBackingPicture;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cwDestroyBackingPicture (PicturePtr pPicture)
|
cwDestroyPicturePrivate (PicturePtr pPicture)
|
||||||
{
|
{
|
||||||
cwPictureDecl;
|
cwPicturePrivate;
|
||||||
|
|
||||||
if (pBackingPicture)
|
if (pPicturePrivate)
|
||||||
{
|
{
|
||||||
FreePicture (pBackingPicture, 0);
|
if (pPicturePrivate->pBackingPicture)
|
||||||
pPicture->devPrivates[cwPictureIndex].ptr = NULL;
|
FreePicture (pPicturePrivate->pBackingPicture, 0);
|
||||||
|
xfree (pPicturePrivate);
|
||||||
|
setCwPicture(pPicture, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static PicturePtr
|
static PicturePtr
|
||||||
cwGetBackingPicture (PicturePtr pPicture, int *x_off, int *y_off)
|
cwGetBackingPicture (PicturePtr pPicture, int *x_off, int *y_off)
|
||||||
{
|
{
|
||||||
cwPictureDecl;
|
cwPicturePrivate;
|
||||||
|
|
||||||
if (pBackingPicture)
|
if (pPicturePrivate)
|
||||||
{
|
{
|
||||||
DrawablePtr pDrawable = pPicture->pDrawable;
|
DrawablePtr pDrawable = pPicture->pDrawable;
|
||||||
ScreenPtr pScreen = pDrawable->pScreen;
|
ScreenPtr pScreen = pDrawable->pScreen;
|
||||||
|
@ -111,7 +125,7 @@ cwGetBackingPicture (PicturePtr pPicture, int *x_off, int *y_off)
|
||||||
*x_off = pWin->drawable.x - pPixmap->screen_x;
|
*x_off = pWin->drawable.x - pPixmap->screen_x;
|
||||||
*y_off = pWin->drawable.y - pPixmap->screen_y;
|
*y_off = pWin->drawable.y - pPixmap->screen_y;
|
||||||
|
|
||||||
return pBackingPicture;
|
return pPicturePrivate->pBackingPicture;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -127,33 +141,22 @@ cwDestroyPicture (PicturePtr pPicture)
|
||||||
cwPsDecl(pScreen);
|
cwPsDecl(pScreen);
|
||||||
|
|
||||||
cwPsUnwrap(DestroyPicture);
|
cwPsUnwrap(DestroyPicture);
|
||||||
cwDestroyBackingPicture (pPicture);
|
cwDestroyPicturePrivate (pPicture);
|
||||||
(*ps->DestroyPicture) (pPicture);
|
(*ps->DestroyPicture) (pPicture);
|
||||||
cwPsWrap(DestroyPicture, cwDestroyPicture);
|
cwPsWrap(DestroyPicture, cwDestroyPicture);
|
||||||
/* The ChangePicture and ValidatePictures on the window haven't been passed
|
|
||||||
* down the stack, so report all state being changed.
|
|
||||||
*/
|
|
||||||
pPicture->stateChanges |= (1 << (CPLastBit + 1)) - 1;
|
|
||||||
(*ps->ChangePicture) (pPicture, (1 << (CPLastBit + 1)) - 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cwChangePicture (PicturePtr pPicture,
|
cwChangePicture (PicturePtr pPicture, Mask mask)
|
||||||
Mask mask)
|
|
||||||
{
|
{
|
||||||
ScreenPtr pScreen = pPicture->pDrawable->pScreen;
|
ScreenPtr pScreen = pPicture->pDrawable->pScreen;
|
||||||
cwPsDecl(pScreen);
|
cwPsDecl(pScreen);
|
||||||
cwPictureDecl;
|
cwPicturePtr pPicturePrivate = getCwPicture(pPicture);
|
||||||
|
|
||||||
cwPsUnwrap(ChangePicture);
|
cwPsUnwrap(ChangePicture);
|
||||||
if (pBackingPicture)
|
(*ps->ChangePicture) (pPicture, mask);
|
||||||
{
|
if (pPicturePrivate)
|
||||||
(*ps->ChangePicture) (pBackingPicture, mask);
|
pPicturePrivate->stateChanges |= mask;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
(*ps->ChangePicture) (pPicture, mask);
|
|
||||||
}
|
|
||||||
cwPsWrap(ChangePicture, cwChangePicture);
|
cwPsWrap(ChangePicture, cwChangePicture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,7 +168,7 @@ cwValidatePicture (PicturePtr pPicture,
|
||||||
DrawablePtr pDrawable = pPicture->pDrawable;
|
DrawablePtr pDrawable = pPicture->pDrawable;
|
||||||
ScreenPtr pScreen = pDrawable->pScreen;
|
ScreenPtr pScreen = pDrawable->pScreen;
|
||||||
cwPsDecl(pScreen);
|
cwPsDecl(pScreen);
|
||||||
cwPictureDecl;
|
cwPicturePrivate;
|
||||||
|
|
||||||
cwPsUnwrap(ValidatePicture);
|
cwPsUnwrap(ValidatePicture);
|
||||||
|
|
||||||
|
@ -176,44 +179,54 @@ cwValidatePicture (PicturePtr pPicture,
|
||||||
|
|
||||||
if (!cwDrawableIsRedirWindow (pDrawable))
|
if (!cwDrawableIsRedirWindow (pDrawable))
|
||||||
{
|
{
|
||||||
if (pBackingPicture)
|
if (pPicturePrivate)
|
||||||
cwDestroyBackingPicture (pPicture);
|
cwDestroyPicturePrivate (pPicture);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
PicturePtr pBackingPicture;
|
||||||
DrawablePtr pBackingDrawable;
|
DrawablePtr pBackingDrawable;
|
||||||
int x_off, y_off;
|
int x_off, y_off;
|
||||||
|
|
||||||
pBackingDrawable = cwGetBackingDrawable(pDrawable, &x_off,
|
pBackingDrawable = cwGetBackingDrawable(pDrawable, &x_off, &y_off);
|
||||||
&y_off);
|
|
||||||
|
|
||||||
if (pBackingPicture && pBackingPicture->pDrawable != pBackingDrawable)
|
if (pPicturePrivate &&
|
||||||
|
pPicturePrivate->pBackingPicture->pDrawable != pBackingDrawable)
|
||||||
{
|
{
|
||||||
cwDestroyBackingPicture (pPicture);
|
cwDestroyPicturePrivate (pPicture);
|
||||||
pBackingPicture = 0;
|
pPicturePrivate = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pBackingPicture)
|
if (!pPicturePrivate)
|
||||||
{
|
{
|
||||||
pBackingPicture = cwCreateBackingPicture (pPicture);
|
pPicturePrivate = cwCreatePicturePrivate (pPicture);
|
||||||
if (!pBackingPicture)
|
if (!pPicturePrivate)
|
||||||
{
|
{
|
||||||
cwPsWrap(ValidatePicture, cwValidatePicture);
|
cwPsWrap(ValidatePicture, cwValidatePicture);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pBackingPicture = pPicturePrivate->pBackingPicture;
|
||||||
|
|
||||||
SetPictureTransform(pBackingPicture, pPicture->transform);
|
SetPictureTransform(pBackingPicture, pPicture->transform);
|
||||||
/* XXX Set filters */
|
/* XXX Set filters */
|
||||||
|
|
||||||
mask &= ~(CPClipXOrigin | CPClipYOrigin);
|
pPicturePrivate->stateChanges |= mask;
|
||||||
|
|
||||||
CopyPicture(pPicture, mask, pBackingPicture);
|
if (pPicturePrivate->serialNumber != pDrawable->serialNumber ||
|
||||||
|
(pPicturePrivate->stateChanges & (CPClipXOrigin|CPClipYOrigin|CPClipMask)))
|
||||||
|
{
|
||||||
|
SetPictureClipRegion (pBackingPicture,
|
||||||
|
x_off - pDrawable->x,
|
||||||
|
y_off - pDrawable->y,
|
||||||
|
pPicture->pCompositeClip);
|
||||||
|
|
||||||
|
pPicturePrivate->serialNumber = pDrawable->serialNumber;
|
||||||
|
pPicturePrivate->stateChanges &= ~(CPClipXOrigin | CPClipYOrigin | CPClipMask);
|
||||||
|
}
|
||||||
|
|
||||||
SetPictureClipRegion (pBackingPicture,
|
CopyPicture(pPicture, pPicturePrivate->stateChanges, pBackingPicture);
|
||||||
x_off - pDrawable->x,
|
|
||||||
y_off - pDrawable->y,
|
|
||||||
pPicture->pCompositeClip);
|
|
||||||
|
|
||||||
ValidatePicture (pBackingPicture);
|
ValidatePicture (pBackingPicture);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue