Commit cc3ad0ed authored by Keith Packard's avatar Keith Packard
Browse files

Fix clip list computation and setting to ignore clip changes to "real"

    GC/Picture and track serial numbers correctly when copying
    pCompositeClip down.
parent 183c6d06
......@@ -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;
CopyPicture(pPicture, (1 << (CPLastBit + 1)) - 1, 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);
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);
}
......
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