composite: Support updating an arbitrary subtree

Rename compUpdateWindow to compPaintWindowToParent and split the child
walk to compPaintChildrenToWindow. Calling compPaintChildrenToWindow
allows an arbitrary subtree to be updated, instead of having to update
all the windows. This will be used to make sure all the descendants are
copied to the parent when the parent window contents need to be accessed
in IncludeInferios sub-window mode.

WindowRec has a new member 'damagedDescendants' that is used to keep
track of which subtrees need updating. When a window is damaged,
'damagedDescendants' will be set for all the ancestors, and when a
subtree is updated, the tree walk can be stopped early if no damaged
descendants are present.

CompScreenRec no longer needs the 'damaged' member since the root
window's 'damagedDescendants' provides the same information.

Signed-off-by: Ville Syrjälä <ville.syrjala@nokia.com>
Signed-off-by: Keith Packard <keithp@keithp.com>
This commit is contained in:
Ville Syrjälä 2011-01-05 20:41:09 +02:00 committed by Keith Packard
parent b89e6dbdfb
commit f3480286ae
6 changed files with 38 additions and 13 deletions

View File

@ -47,11 +47,11 @@
#include "compint.h" #include "compint.h"
void static void
compScreenUpdate (ScreenPtr pScreen) compScreenUpdate (ScreenPtr pScreen)
{ {
compCheckTree (pScreen); compCheckTree (pScreen);
compWindowUpdate (pScreen->root); compPaintChildrenToWindow (pScreen->root);
} }
static void static void
@ -84,6 +84,15 @@ compReportDamage (DamagePtr pDamage, RegionPtr pRegion, void *closure)
pScreen->BlockHandler = compBlockHandler; pScreen->BlockHandler = compBlockHandler;
} }
cw->damaged = TRUE; cw->damaged = TRUE;
/* Mark the ancestors */
pWin = pWin->parent;
while (pWin) {
if (pWin->damagedDescendants)
break;
pWin->damagedDescendants = TRUE;
pWin = pWin->parent;
}
} }
static void static void

View File

@ -145,7 +145,7 @@ compGetImage (DrawablePtr pDrawable,
pScreen->GetImage = cs->GetImage; pScreen->GetImage = cs->GetImage;
if (pDrawable->type == DRAWABLE_WINDOW) if (pDrawable->type == DRAWABLE_WINDOW)
compScreenUpdate (pScreen); compPaintChildrenToWindow ((WindowPtr) pDrawable);
(*pScreen->GetImage) (pDrawable, sx, sy, w, h, format, planemask, pdstLine); (*pScreen->GetImage) (pDrawable, sx, sy, w, h, format, planemask, pdstLine);
cs->GetImage = pScreen->GetImage; cs->GetImage = pScreen->GetImage;
pScreen->GetImage = compGetImage; pScreen->GetImage = compGetImage;
@ -161,7 +161,7 @@ static void compSourceValidate(DrawablePtr pDrawable,
pScreen->SourceValidate = cs->SourceValidate; pScreen->SourceValidate = cs->SourceValidate;
if (pDrawable->type == DRAWABLE_WINDOW && subWindowMode == IncludeInferiors) if (pDrawable->type == DRAWABLE_WINDOW && subWindowMode == IncludeInferiors)
compScreenUpdate (pScreen); compPaintChildrenToWindow ((WindowPtr) pDrawable);
if (pScreen->SourceValidate) if (pScreen->SourceValidate)
(*pScreen->SourceValidate) (pDrawable, x, y, width, height, (*pScreen->SourceValidate) (pDrawable, x, y, width, height,
subWindowMode); subWindowMode);

View File

@ -315,10 +315,7 @@ void
compCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc); compCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
void void
compWindowUpdate (WindowPtr pWin); compPaintChildrenToWindow (WindowPtr pWin);
void
compScreenUpdate (ScreenPtr pScreen);
WindowPtr WindowPtr
CompositeRealChildHead (WindowPtr pWin); CompositeRealChildHead (WindowPtr pWin);

View File

@ -720,13 +720,11 @@ compWindowUpdateAutomatic (WindowPtr pWin)
DamageEmpty (cw->damage); DamageEmpty (cw->damage);
} }
void static void
compWindowUpdate (WindowPtr pWin) compPaintWindowToParent (WindowPtr pWin)
{ {
WindowPtr pChild; compPaintChildrenToWindow (pWin);
for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib)
compWindowUpdate (pChild);
if (pWin->redirectDraw != RedirectDrawNone) if (pWin->redirectDraw != RedirectDrawNone)
{ {
CompWindowPtr cw = GetCompWindow(pWin); CompWindowPtr cw = GetCompWindow(pWin);
@ -739,6 +737,20 @@ compWindowUpdate (WindowPtr pWin)
} }
} }
void
compPaintChildrenToWindow (WindowPtr pWin)
{
WindowPtr pChild;
if (!pWin->damagedDescendants)
return;
for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib)
compPaintWindowToParent (pChild);
pWin->damagedDescendants = FALSE;
}
WindowPtr WindowPtr
CompositeRealChildHead (WindowPtr pWin) CompositeRealChildHead (WindowPtr pWin)
{ {

View File

@ -298,6 +298,10 @@ SetWindowToDefaults(WindowPtr pWin)
#ifdef ROOTLESS #ifdef ROOTLESS
pWin->rootlessUnhittable = FALSE; pWin->rootlessUnhittable = FALSE;
#endif #endif
#ifdef COMPOSITE
pWin->damagedDescendants = FALSE;
#endif
} }
static void static void

View File

@ -167,6 +167,9 @@ typedef struct _Window {
#ifdef ROOTLESS #ifdef ROOTLESS
unsigned rootlessUnhittable:1; /* doesn't hit-test */ unsigned rootlessUnhittable:1; /* doesn't hit-test */
#endif #endif
#ifdef COMPOSITE
unsigned damagedDescendants:1; /* some descendants are damaged */
#endif
} WindowRec; } WindowRec;
/* /*