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:
Keith Packard 2004-08-14 19:53:36 +00:00
parent 183c6d0645
commit cc3ad0ed43
3 changed files with 109 additions and 70 deletions

View File

@ -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);

View File

@ -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) \

View File

@ -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);
} }