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;
|
||||
|
||||
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)
|
||||
/*
|
||||
* Copy the composite clip into the backing GC if either
|
||||
* the drawable clip list has changed or the client has changed
|
||||
* the client clip data
|
||||
*/
|
||||
if (pDrawable->serialNumber != pPriv->serialNumber ||
|
||||
(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];
|
||||
RegionPtr pCompositeClip;
|
||||
|
||||
|
@ -254,6 +246,26 @@ cwValidateGC(GCPtr pGC, unsigned long stateChanges, DrawablePtr pDrawable)
|
|||
(GCClipXOrigin | GCClipYOrigin), vals, NULL);
|
||||
|
||||
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);
|
||||
|
|
|
@ -44,6 +44,20 @@ extern int cwGCIndex;
|
|||
#define getCwGC(pGC) ((cwGCPtr)(pGC)->devPrivates[cwGCIndex].ptr)
|
||||
#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;
|
||||
|
||||
#define cwDrawableIsRedirWindow(pDraw) \
|
||||
|
|
|
@ -31,9 +31,8 @@
|
|||
PictureScreenPtr ps = GetPictureScreen (pScreen); \
|
||||
cwScreenPtr pCwScreen = getCwScreen (pScreen)
|
||||
|
||||
#define cwPictureDecl \
|
||||
PicturePtr pBackingPicture = \
|
||||
((pPicture)->devPrivates[cwPictureIndex].ptr)
|
||||
#define cwPicturePrivate \
|
||||
cwPicturePtr pPicturePrivate = getCwPicture(pPicture)
|
||||
|
||||
#define cwSrcPictureDecl \
|
||||
int src_picture_x_off, src_picture_y_off; \
|
||||
|
@ -63,45 +62,60 @@
|
|||
ps->elt = func; \
|
||||
}
|
||||
|
||||
static PicturePtr
|
||||
cwCreateBackingPicture (PicturePtr pPicture)
|
||||
static cwPicturePtr
|
||||
cwCreatePicturePrivate (PicturePtr pPicture)
|
||||
{
|
||||
ScreenPtr pScreen = pPicture->pDrawable->pScreen;
|
||||
WindowPtr pWindow = (WindowPtr) pPicture->pDrawable;
|
||||
PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWindow);
|
||||
int error;
|
||||
PicturePtr pBackingPicture;
|
||||
cwPicturePtr pPicturePrivate;
|
||||
|
||||
pBackingPicture = CreatePicture (0, &pPixmap->drawable, pPicture->pFormat,
|
||||
0, 0, serverClient, &error);
|
||||
if (!pBackingPicture)
|
||||
pPicturePrivate = xalloc (sizeof (cwPictureRec));
|
||||
if (!pPicturePrivate)
|
||||
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 pBackingPicture;
|
||||
return pPicturePrivate;
|
||||
}
|
||||
|
||||
static void
|
||||
cwDestroyBackingPicture (PicturePtr pPicture)
|
||||
cwDestroyPicturePrivate (PicturePtr pPicture)
|
||||
{
|
||||
cwPictureDecl;
|
||||
cwPicturePrivate;
|
||||
|
||||
if (pBackingPicture)
|
||||
if (pPicturePrivate)
|
||||
{
|
||||
FreePicture (pBackingPicture, 0);
|
||||
pPicture->devPrivates[cwPictureIndex].ptr = NULL;
|
||||
if (pPicturePrivate->pBackingPicture)
|
||||
FreePicture (pPicturePrivate->pBackingPicture, 0);
|
||||
xfree (pPicturePrivate);
|
||||
setCwPicture(pPicture, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static PicturePtr
|
||||
cwGetBackingPicture (PicturePtr pPicture, int *x_off, int *y_off)
|
||||
{
|
||||
cwPictureDecl;
|
||||
cwPicturePrivate;
|
||||
|
||||
if (pBackingPicture)
|
||||
if (pPicturePrivate)
|
||||
{
|
||||
DrawablePtr pDrawable = pPicture->pDrawable;
|
||||
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;
|
||||
*y_off = pWin->drawable.y - pPixmap->screen_y;
|
||||
|
||||
return pBackingPicture;
|
||||
return pPicturePrivate->pBackingPicture;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -127,33 +141,22 @@ cwDestroyPicture (PicturePtr pPicture)
|
|||
cwPsDecl(pScreen);
|
||||
|
||||
cwPsUnwrap(DestroyPicture);
|
||||
cwDestroyBackingPicture (pPicture);
|
||||
cwDestroyPicturePrivate (pPicture);
|
||||
(*ps->DestroyPicture) (pPicture);
|
||||
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
|
||||
cwChangePicture (PicturePtr pPicture,
|
||||
Mask mask)
|
||||
cwChangePicture (PicturePtr pPicture, Mask mask)
|
||||
{
|
||||
ScreenPtr pScreen = pPicture->pDrawable->pScreen;
|
||||
cwPsDecl(pScreen);
|
||||
cwPictureDecl;
|
||||
cwPicturePtr pPicturePrivate = getCwPicture(pPicture);
|
||||
|
||||
cwPsUnwrap(ChangePicture);
|
||||
if (pBackingPicture)
|
||||
{
|
||||
(*ps->ChangePicture) (pBackingPicture, mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
(*ps->ChangePicture) (pPicture, mask);
|
||||
}
|
||||
(*ps->ChangePicture) (pPicture, mask);
|
||||
if (pPicturePrivate)
|
||||
pPicturePrivate->stateChanges |= mask;
|
||||
cwPsWrap(ChangePicture, cwChangePicture);
|
||||
}
|
||||
|
||||
|
@ -165,7 +168,7 @@ cwValidatePicture (PicturePtr pPicture,
|
|||
DrawablePtr pDrawable = pPicture->pDrawable;
|
||||
ScreenPtr pScreen = pDrawable->pScreen;
|
||||
cwPsDecl(pScreen);
|
||||
cwPictureDecl;
|
||||
cwPicturePrivate;
|
||||
|
||||
cwPsUnwrap(ValidatePicture);
|
||||
|
||||
|
@ -176,44 +179,54 @@ cwValidatePicture (PicturePtr pPicture,
|
|||
|
||||
if (!cwDrawableIsRedirWindow (pDrawable))
|
||||
{
|
||||
if (pBackingPicture)
|
||||
cwDestroyBackingPicture (pPicture);
|
||||
if (pPicturePrivate)
|
||||
cwDestroyPicturePrivate (pPicture);
|
||||
}
|
||||
else
|
||||
{
|
||||
PicturePtr pBackingPicture;
|
||||
DrawablePtr pBackingDrawable;
|
||||
int x_off, y_off;
|
||||
|
||||
pBackingDrawable = cwGetBackingDrawable(pDrawable, &x_off,
|
||||
&y_off);
|
||||
pBackingDrawable = cwGetBackingDrawable(pDrawable, &x_off, &y_off);
|
||||
|
||||
if (pBackingPicture && pBackingPicture->pDrawable != pBackingDrawable)
|
||||
if (pPicturePrivate &&
|
||||
pPicturePrivate->pBackingPicture->pDrawable != pBackingDrawable)
|
||||
{
|
||||
cwDestroyBackingPicture (pPicture);
|
||||
pBackingPicture = 0;
|
||||
cwDestroyPicturePrivate (pPicture);
|
||||
pPicturePrivate = 0;
|
||||
}
|
||||
|
||||
if (!pBackingPicture)
|
||||
if (!pPicturePrivate)
|
||||
{
|
||||
pBackingPicture = cwCreateBackingPicture (pPicture);
|
||||
if (!pBackingPicture)
|
||||
pPicturePrivate = cwCreatePicturePrivate (pPicture);
|
||||
if (!pPicturePrivate)
|
||||
{
|
||||
cwPsWrap(ValidatePicture, cwValidatePicture);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
pBackingPicture = pPicturePrivate->pBackingPicture;
|
||||
|
||||
SetPictureTransform(pBackingPicture, pPicture->transform);
|
||||
/* 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,
|
||||
x_off - pDrawable->x,
|
||||
y_off - pDrawable->y,
|
||||
pPicture->pCompositeClip);
|
||||
CopyPicture(pPicture, pPicturePrivate->stateChanges, pBackingPicture);
|
||||
|
||||
ValidatePicture (pBackingPicture);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue