[PATCH xserver 7/7] composite: Implement backing store's Always mode

Adam Jackson ajax at redhat.com
Tue Jul 24 19:51:28 UTC 2018


Keep the pixmap at unmap, always try to realize backing store, always
mark them when marking, and update paintable when backed.

Signed-off-by: Adam Jackson <ajax at redhat.com>
---
 composite/compalloc.c  |  2 +-
 composite/compinit.c   | 24 +++++++++++++++--
 composite/compint.h    |  8 ++++++
 composite/compwindow.c | 61 ++++++++++++++++++++++++++++++++++++++++--
 4 files changed, 90 insertions(+), 5 deletions(-)

diff --git a/composite/compalloc.c b/composite/compalloc.c
index 433dc820a4..7484b55818 100644
--- a/composite/compalloc.c
+++ b/composite/compalloc.c
@@ -111,7 +111,7 @@ compMarkWindows(WindowPtr pWin, WindowPtr *ppLayerWin)
     ScreenPtr pScreen = pWin->drawable.pScreen;
     WindowPtr pLayerWin = pWin;
 
-    if (!pWin->viewable)
+    if (!pWin->viewable && pWin->backingStore != Always)
         return FALSE;
 
     (*pScreen->MarkOverlappedWindows) (pWin, pWin, &pLayerWin);
diff --git a/composite/compinit.c b/composite/compinit.c
index 2590aa46df..c02c8f31b5 100644
--- a/composite/compinit.c
+++ b/composite/compinit.c
@@ -67,6 +67,7 @@ compCloseScreen(ScreenPtr pScreen)
     pScreen->ConfigNotify = cs->ConfigNotify;
     pScreen->MoveWindow = cs->MoveWindow;
     pScreen->ResizeWindow = cs->ResizeWindow;
+    pScreen->MarkUnrealizedWindow = cs->MarkUnrealizedWindow;
     pScreen->ChangeBorderWidth = cs->ChangeBorderWidth;
 
     pScreen->ClipNotify = cs->ClipNotify;
@@ -74,6 +75,7 @@ compCloseScreen(ScreenPtr pScreen)
     pScreen->RealizeWindow = cs->RealizeWindow;
     pScreen->DestroyWindow = cs->DestroyWindow;
     pScreen->CreateWindow = cs->CreateWindow;
+    pScreen->WindowExposures = cs->WindowExposures;
     pScreen->CopyWindow = cs->CopyWindow;
     pScreen->PositionWindow = cs->PositionWindow;
 
@@ -105,14 +107,26 @@ compInstallColormap(ColormapPtr pColormap)
     pScreen->InstallColormap = compInstallColormap;
 }
 
+static void
+compCheckPaintable(WindowPtr pWin)
+{
+    pWin->paintable = pWin->viewable || pWin->backingStore == Always;
+}
+
 static void
 compCheckBackingStore(WindowPtr pWin)
 {
-    if (pWin->backingStore != NotUseful && !pWin->backStorage) {
+    Bool should =
+        (pWin->backingStore == Always) ||
+        (pWin->backingStore == WhenMapped && pWin->viewable);
+
+    if (should && !pWin->backStorage) {
+        compCheckPaintable(pWin);
         compRedirectWindow(serverClient, pWin, CompositeRedirectAutomatic);
         pWin->backStorage = TRUE;
     }
-    else if (pWin->backingStore == NotUseful && pWin->backStorage) {
+    else if (!should && pWin->backStorage) {
+        compCheckPaintable(pWin);
         compUnredirectWindow(serverClient, pWin,
                              CompositeRedirectAutomatic);
         pWin->backStorage = FALSE;
@@ -418,6 +432,9 @@ compScreenInit(ScreenPtr pScreen)
     cs->UnrealizeWindow = pScreen->UnrealizeWindow;
     pScreen->UnrealizeWindow = compUnrealizeWindow;
 
+    cs->WindowExposures = pScreen->WindowExposures;
+    pScreen->WindowExposures = compWindowExposures;
+
     cs->ClipNotify = pScreen->ClipNotify;
     pScreen->ClipNotify = compClipNotify;
 
@@ -430,6 +447,9 @@ compScreenInit(ScreenPtr pScreen)
     cs->ResizeWindow = pScreen->ResizeWindow;
     pScreen->ResizeWindow = compResizeWindow;
 
+    cs->MarkUnrealizedWindow = pScreen->MarkUnrealizedWindow;
+    pScreen->MarkUnrealizedWindow = compMarkUnrealizedWindow;
+
     cs->ChangeBorderWidth = pScreen->ChangeBorderWidth;
     pScreen->ChangeBorderWidth = compChangeBorderWidth;
 
diff --git a/composite/compint.h b/composite/compint.h
index 89f6507b95..a4d56f2828 100644
--- a/composite/compint.h
+++ b/composite/compint.h
@@ -131,6 +131,7 @@ typedef struct _CompScreen {
     DestroyWindowProcPtr DestroyWindow;
     RealizeWindowProcPtr RealizeWindow;
     UnrealizeWindowProcPtr UnrealizeWindow;
+    WindowExposuresProcPtr WindowExposures;
     ClipNotifyProcPtr ClipNotify;
     /*
      * Called from ConfigureWindow, these
@@ -140,6 +141,7 @@ typedef struct _CompScreen {
     ConfigNotifyProcPtr ConfigNotify;
     MoveWindowProcPtr MoveWindow;
     ResizeWindowProcPtr ResizeWindow;
+    MarkUnrealizedWindowProcPtr MarkUnrealizedWindow;
     ChangeBorderWidthProcPtr ChangeBorderWidth;
     /*
      * Reparenting has an effect on Subwindows redirect
@@ -290,6 +292,9 @@ Bool
 Bool
  compUnrealizeWindow(WindowPtr pWin);
 
+void
+compWindowExposures(WindowPtr pWin, RegionPtr reg);
+
 void
  compClipNotify(WindowPtr pWin, int dx, int dy);
 
@@ -301,6 +306,9 @@ void
 compResizeWindow(WindowPtr pWin, int x, int y,
                  unsigned int w, unsigned int h, WindowPtr pSib);
 
+void
+ compMarkUnrealizedWindow(WindowPtr pChild, WindowPtr pWin, Bool fromConfigure);
+
 void
  compChangeBorderWidth(WindowPtr pWin, unsigned int border_width);
 
diff --git a/composite/compwindow.c b/composite/compwindow.c
index 54b4e6ac4c..5b9071e59c 100644
--- a/composite/compwindow.c
+++ b/composite/compwindow.c
@@ -152,8 +152,10 @@ compCheckRedirect(WindowPtr pWin)
     CompScreenPtr cs = GetCompScreen(pWin->drawable.pScreen);
     Bool should;
 
-    should = pWin->realized && (pWin->drawable.class != InputOnly) &&
-        (cw != NULL) && (pWin->parent != NULL);
+    should = (pWin->realized || pWin->backingStore == Always) &&
+        (pWin->drawable.class != InputOnly) &&
+        (cw != NULL) &&
+        (pWin->parent != NULL);
 
     /* Never redirect the overlay window */
     if (cs->pOverlayWin != NULL) {
@@ -273,6 +275,16 @@ compRealizeWindow(WindowPtr pWin)
     return ret;
 }
 
+static Bool
+backed(WindowPtr pWin)
+{
+    for (; pWin; pWin = pWin->parent)
+        if (pWin->backStorage)
+            return TRUE;
+
+    return FALSE;
+}
+
 Bool
 compUnrealizeWindow(WindowPtr pWin)
 {
@@ -284,12 +296,36 @@ compUnrealizeWindow(WindowPtr pWin)
     compCheckRedirect(pWin);
     if (!(*pScreen->UnrealizeWindow) (pWin))
         ret = FALSE;
+
+    /* UnrealizeTree walks from root to leaves, so only need to check parent */
+    if (backed(pWin) && pWin->parent->paintable)
+        pWin->paintable = TRUE;
+
     cs->UnrealizeWindow = pScreen->UnrealizeWindow;
     pScreen->UnrealizeWindow = compUnrealizeWindow;
     compCheckTree(pWin->drawable.pScreen);
     return ret;
 }
 
+void
+compWindowExposures(WindowPtr pWin, RegionPtr reg)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    CompScreenPtr cs = GetCompScreen(pScreen);
+
+    pScreen->WindowExposures = cs->WindowExposures;
+
+    if (pWin->backStorage) {
+        DamageDamageRegion(&pWin->drawable, reg);
+        RegionEmpty(reg);
+    }
+
+    pScreen->WindowExposures(pWin, reg);
+
+    cs->WindowExposures = pScreen->WindowExposures;
+    pScreen->WindowExposures = compWindowExposures;
+}
+
 /*
  * Called after the borderClip for the window has settled down
  * We use this to make sure our extra borderClip has the right origin
@@ -427,6 +463,19 @@ compChangeBorderWidth(WindowPtr pWin, unsigned int bw)
     compCheckTree(pWin->drawable.pScreen);
 }
 
+void
+compMarkUnrealizedWindow(WindowPtr pChild, WindowPtr pWin, Bool fromConfigure)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    CompScreenPtr cs = GetCompScreen(pScreen);
+
+    pScreen->MarkUnrealizedWindow = cs->MarkUnrealizedWindow;
+    if (!pChild->paintable)
+        (*pScreen->MarkUnrealizedWindow) (pChild, pWin, fromConfigure);
+    cs->MarkUnrealizedWindow = pScreen->MarkUnrealizedWindow;
+    pScreen->MarkUnrealizedWindow = compMarkUnrealizedWindow;
+}
+
 void
 compReparentWindow(WindowPtr pWin, WindowPtr pPriorParent)
 {
@@ -598,6 +647,14 @@ compDestroyWindow(WindowPtr pWin)
     CompSubwindowsPtr csw;
     Bool ret;
 
+    /*
+     * Take down bs explicitly, to get ->backStorage cleared
+     */
+    if (pWin->backingStore != NotUseful) {
+        pWin->backingStore = NotUseful;
+        pScreen->ChangeWindowAttributes(pWin, CWBackingStore);
+    }
+
     pScreen->DestroyWindow = cs->DestroyWindow;
     while ((cw = GetCompWindow(pWin)))
         FreeResource(cw->clients->id, RT_NONE);
-- 
2.17.0



More information about the xorg-devel mailing list