[PATCH] composite: Install SourceValidation hooks only when required

Chris Wilson chris at chris-wilson.co.uk
Mon May 18 07:26:29 PDT 2015


Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
 composite/compalloc.c  |  3 +++
 composite/compinit.c   | 49 +++++++++++++++++++++++++++++++------------------
 composite/compint.h    |  4 ++++
 composite/compwindow.c |  8 ++++++++
 4 files changed, 46 insertions(+), 18 deletions(-)

diff --git a/composite/compalloc.c b/composite/compalloc.c
index 8daded0..c3973e9 100644
--- a/composite/compalloc.c
+++ b/composite/compalloc.c
@@ -75,6 +75,8 @@ compReportDamage(DamagePtr pDamage, RegionPtr pRegion, void *closure)
     CompScreenPtr cs = GetCompScreen(pScreen);
     CompWindowPtr cw = GetCompWindow(pWin);
 
+    compMarkDamaged(pScreen);
+
     if (!cs->BlockHandler) {
         cs->BlockHandler = pScreen->BlockHandler;
         pScreen->BlockHandler = compBlockHandler;
@@ -86,6 +88,7 @@ compReportDamage(DamagePtr pDamage, RegionPtr pRegion, void *closure)
     while (pWin) {
         if (pWin->damagedDescendants)
             break;
+	cs->anyDamaged++;
         pWin->damagedDescendants = TRUE;
         pWin = pWin->parent;
     }
diff --git a/composite/compinit.c b/composite/compinit.c
index 3ac075a..988bc58 100644
--- a/composite/compinit.c
+++ b/composite/compinit.c
@@ -77,9 +77,7 @@ compCloseScreen(ScreenPtr pScreen)
     pScreen->CopyWindow = cs->CopyWindow;
     pScreen->PositionWindow = cs->PositionWindow;
 
-    pScreen->GetImage = cs->GetImage;
-    pScreen->GetSpans = cs->GetSpans;
-    pScreen->SourceValidate = cs->SourceValidate;
+    assert(!cs->anyDamaged);
 
     free(cs);
     dixSetPrivate(&pScreen->devPrivates, CompScreenPrivateKey, NULL);
@@ -147,8 +145,11 @@ compGetImage(DrawablePtr pDrawable,
     if (pDrawable->type == DRAWABLE_WINDOW)
         compPaintChildrenToWindow((WindowPtr) pDrawable);
     (*pScreen->GetImage) (pDrawable, sx, sy, w, h, format, planemask, pdstLine);
-    cs->GetImage = pScreen->GetImage;
-    pScreen->GetImage = compGetImage;
+
+    if (cs->anyDamaged) {
+	cs->GetImage = pScreen->GetImage;
+	pScreen->GetImage = compGetImage;
+    }
 }
 
 static void
@@ -162,8 +163,11 @@ compGetSpans(DrawablePtr pDrawable, int wMax, DDXPointPtr ppt, int *pwidth,
     if (pDrawable->type == DRAWABLE_WINDOW)
         compPaintChildrenToWindow((WindowPtr) pDrawable);
     (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
-    cs->GetSpans = pScreen->GetSpans;
-    pScreen->GetSpans = compGetSpans;
+
+    if (cs->anyDamaged) {
+	cs->GetSpans = pScreen->GetSpans;
+	pScreen->GetSpans = compGetSpans;
+    }
 }
 
 static void
@@ -180,8 +184,26 @@ compSourceValidate(DrawablePtr pDrawable,
     if (pScreen->SourceValidate)
         (*pScreen->SourceValidate) (pDrawable, x, y, width, height,
                                     subWindowMode);
-    cs->SourceValidate = pScreen->SourceValidate;
-    pScreen->SourceValidate = compSourceValidate;
+    if (cs->anyDamaged) {
+	cs->SourceValidate = pScreen->SourceValidate;
+	pScreen->SourceValidate = compSourceValidate;
+    }
+}
+
+void compMarkDamaged(ScreenPtr pScreen)
+{
+    CompScreenPtr cs = GetCompScreen(pScreen);
+
+    if (cs->anyDamaged == 0) {
+	cs->GetImage = pScreen->GetImage;
+	pScreen->GetImage = compGetImage;
+
+	cs->GetSpans = pScreen->GetSpans;
+	pScreen->GetSpans = compGetSpans;
+
+	cs->SourceValidate = pScreen->SourceValidate;
+	pScreen->SourceValidate = compSourceValidate;
+    }
 }
 
 /*
@@ -445,15 +467,6 @@ compScreenInit(ScreenPtr pScreen)
     cs->CloseScreen = pScreen->CloseScreen;
     pScreen->CloseScreen = compCloseScreen;
 
-    cs->GetImage = pScreen->GetImage;
-    pScreen->GetImage = compGetImage;
-
-    cs->GetSpans = pScreen->GetSpans;
-    pScreen->GetSpans = compGetSpans;
-
-    cs->SourceValidate = pScreen->SourceValidate;
-    pScreen->SourceValidate = compSourceValidate;
-
     dixSetPrivate(&pScreen->devPrivates, CompScreenPrivateKey, cs);
 
     RegisterRealChildHeadProc(CompositeRealChildHead);
diff --git a/composite/compint.h b/composite/compint.h
index 09241f2..e6b046d 100644
--- a/composite/compint.h
+++ b/composite/compint.h
@@ -167,6 +167,7 @@ typedef struct _CompScreen {
     Window overlayWid;
     CompOverlayClientPtr pOverlayClients;
 
+    int anyDamaged;
     GetImageProcPtr GetImage;
     GetSpansProcPtr GetSpans;
     SourceValidateProcPtr SourceValidate;
@@ -243,6 +244,9 @@ compReallocPixmap(WindowPtr pWin, int x, int y,
 Bool
  compScreenInit(ScreenPtr pScreen);
 
+void
+ compMarkDamaged(ScreenPtr pScreen);
+
 /*
  * compoverlay.c
  */
diff --git a/composite/compwindow.c b/composite/compwindow.c
index 6eacbae..81f2a93 100644
--- a/composite/compwindow.c
+++ b/composite/compwindow.c
@@ -732,6 +732,13 @@ compPaintWindowToParent(WindowPtr pWin)
     }
 }
 
+static void compClearDamaged(WindowPtr pWin)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    CompScreenPtr cs = GetCompScreen(pScreen);
+    cs->anyDamaged--;
+}
+
 void
 compPaintChildrenToWindow(WindowPtr pWin)
 {
@@ -743,6 +750,7 @@ compPaintChildrenToWindow(WindowPtr pWin)
     for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib)
         compPaintWindowToParent(pChild);
 
+    compClearDamaged(pWin);
     pWin->damagedDescendants = FALSE;
 }
 
-- 
2.1.4



More information about the xorg-devel mailing list