From f3480286aeb3009623d8d4b0202eadda0049552d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Wed, 5 Jan 2011 20:41:09 +0200 Subject: [PATCH] composite: Support updating an arbitrary subtree MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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ä Signed-off-by: Keith Packard --- composite/compalloc.c | 13 +++++++++++-- composite/compinit.c | 4 ++-- composite/compint.h | 5 +---- composite/compwindow.c | 22 +++++++++++++++++----- dix/window.c | 4 ++++ include/windowstr.h | 3 +++ 6 files changed, 38 insertions(+), 13 deletions(-) diff --git a/composite/compalloc.c b/composite/compalloc.c index b2e3f71656..e4064f6b10 100644 --- a/composite/compalloc.c +++ b/composite/compalloc.c @@ -47,11 +47,11 @@ #include "compint.h" -void +static void compScreenUpdate (ScreenPtr pScreen) { compCheckTree (pScreen); - compWindowUpdate (pScreen->root); + compPaintChildrenToWindow (pScreen->root); } static void @@ -84,6 +84,15 @@ compReportDamage (DamagePtr pDamage, RegionPtr pRegion, void *closure) pScreen->BlockHandler = compBlockHandler; } cw->damaged = TRUE; + + /* Mark the ancestors */ + pWin = pWin->parent; + while (pWin) { + if (pWin->damagedDescendants) + break; + pWin->damagedDescendants = TRUE; + pWin = pWin->parent; + } } static void diff --git a/composite/compinit.c b/composite/compinit.c index 74689be1f4..90ee66c889 100644 --- a/composite/compinit.c +++ b/composite/compinit.c @@ -145,7 +145,7 @@ compGetImage (DrawablePtr pDrawable, pScreen->GetImage = cs->GetImage; if (pDrawable->type == DRAWABLE_WINDOW) - compScreenUpdate (pScreen); + compPaintChildrenToWindow ((WindowPtr) pDrawable); (*pScreen->GetImage) (pDrawable, sx, sy, w, h, format, planemask, pdstLine); cs->GetImage = pScreen->GetImage; pScreen->GetImage = compGetImage; @@ -161,7 +161,7 @@ static void compSourceValidate(DrawablePtr pDrawable, pScreen->SourceValidate = cs->SourceValidate; if (pDrawable->type == DRAWABLE_WINDOW && subWindowMode == IncludeInferiors) - compScreenUpdate (pScreen); + compPaintChildrenToWindow ((WindowPtr) pDrawable); if (pScreen->SourceValidate) (*pScreen->SourceValidate) (pDrawable, x, y, width, height, subWindowMode); diff --git a/composite/compint.h b/composite/compint.h index 681f651e93..57e0b5dea7 100644 --- a/composite/compint.h +++ b/composite/compint.h @@ -315,10 +315,7 @@ void compCopyWindow (WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc); void -compWindowUpdate (WindowPtr pWin); - -void -compScreenUpdate (ScreenPtr pScreen); +compPaintChildrenToWindow (WindowPtr pWin); WindowPtr CompositeRealChildHead (WindowPtr pWin); diff --git a/composite/compwindow.c b/composite/compwindow.c index 22d2374817..2440f18977 100644 --- a/composite/compwindow.c +++ b/composite/compwindow.c @@ -720,13 +720,11 @@ compWindowUpdateAutomatic (WindowPtr pWin) DamageEmpty (cw->damage); } -void -compWindowUpdate (WindowPtr pWin) +static void +compPaintWindowToParent (WindowPtr pWin) { - WindowPtr pChild; + compPaintChildrenToWindow (pWin); - for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib) - compWindowUpdate (pChild); if (pWin->redirectDraw != RedirectDrawNone) { 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 CompositeRealChildHead (WindowPtr pWin) { diff --git a/dix/window.c b/dix/window.c index d140ddade7..9be70649ac 100644 --- a/dix/window.c +++ b/dix/window.c @@ -298,6 +298,10 @@ SetWindowToDefaults(WindowPtr pWin) #ifdef ROOTLESS pWin->rootlessUnhittable = FALSE; #endif + +#ifdef COMPOSITE + pWin->damagedDescendants = FALSE; +#endif } static void diff --git a/include/windowstr.h b/include/windowstr.h index 0b66ebbccd..4a7a0f4884 100644 --- a/include/windowstr.h +++ b/include/windowstr.h @@ -167,6 +167,9 @@ typedef struct _Window { #ifdef ROOTLESS unsigned rootlessUnhittable:1; /* doesn't hit-test */ #endif +#ifdef COMPOSITE + unsigned damagedDescendants:1; /* some descendants are damaged */ +#endif } WindowRec; /*