[PATCH 8/8] composite: Implement backing store's Always mode (v2)

Adam Jackson ajax at redhat.com
Wed Feb 25 13:03:14 PST 2015


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

v2: Handle allocation failure when redirecting

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

diff --git a/composite/compalloc.c b/composite/compalloc.c
index 8daded0..81c58f6 100644
--- a/composite/compalloc.c
+++ b/composite/compalloc.c
@@ -106,7 +106,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 f9426c7..7dc0b6e 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;
 
@@ -108,15 +110,22 @@ compInstallColormap(ColormapPtr pColormap)
 static void
 compCheckBackingStore(WindowPtr pWin)
 {
-    if (pWin->backingStore != NotUseful && !pWin->backStorage) {
-        compRedirectWindow(serverClient, pWin, CompositeRedirectAutomatic);
-        pWin->backStorage = TRUE;
+    Bool should =
+        (pWin->backingStore == Always) ||
+        (pWin->backingStore == WhenMapped && pWin->viewable);
+
+    if (should && !pWin->backStorage) {
+        if (Success == compRedirectWindow(serverClient, pWin,
+                                          CompositeRedirectAutomatic))
+            pWin->backStorage = TRUE;
     }
-    else if (pWin->backingStore == NotUseful && pWin->backStorage) {
-        compUnredirectWindow(serverClient, pWin,
-                             CompositeRedirectAutomatic);
-        pWin->backStorage = FALSE;
+    else if (!should && pWin->backStorage) {
+        if (Success == compUnredirectWindow(serverClient, pWin,
+                                            CompositeRedirectAutomatic))
+            pWin->backStorage = FALSE;
     }
+    pWin->paintable = pWin->viewable ||
+        (pWin->backingStore == Always && pWin->backStorage);
 }
 
 /* Fake backing store via automatic redirection */
@@ -421,6 +430,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;
 
@@ -433,6 +445,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 09241f2..4f19672 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
@@ -289,6 +291,9 @@ Bool
  compUnrealizeWindow(WindowPtr pWin);
 
 void
+compWindowExposures(WindowPtr pWin, RegionPtr reg);
+
+void
  compClipNotify(WindowPtr pWin, int dx, int dy);
 
 void
@@ -300,6 +305,9 @@ 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);
 
 void
diff --git a/composite/compwindow.c b/composite/compwindow.c
index 77bdfa2..8028d98 100644
--- a/composite/compwindow.c
+++ b/composite/compwindow.c
@@ -150,8 +150,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) {
@@ -288,6 +290,25 @@ compUnrealizeWindow(WindowPtr pWin)
     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
@@ -430,6 +451,36 @@ compChangeBorderWidth(WindowPtr pWin, unsigned int bw)
     compCheckTree(pWin->drawable.pScreen);
 }
 
+/*
+ * pWin is the top-level window being unmapped, pChild is one of its
+ * (previously viewable) descendents.  MUW under us will try to empty
+ * the child clip.
+ */
+void
+compMarkUnrealizedWindow(WindowPtr pChild, WindowPtr pWin, Bool fromConfigure)
+{
+    Bool should = FALSE;
+
+    if (pWin == pChild && pWin->backingStore == Always && pWin->backStorage) {
+        /* this is the top-level being unmapped, restore paintable */
+        pWin->paintable = (pWin->drawable.class == InputOutput);
+    } else if (pChild->parent->paintable && pChild->mapped) {
+        pChild->paintable = (pWin->drawable.class == InputOutput);
+    } else {
+        should = TRUE;
+    }
+
+    if (should) {
+        ScreenPtr pScreen = pWin->drawable.pScreen;
+        CompScreenPtr cs = GetCompScreen(pScreen);
+
+        pScreen->MarkUnrealizedWindow = cs->MarkUnrealizedWindow;
+        (*pScreen->MarkUnrealizedWindow) (pChild, pWin, fromConfigure);
+        cs->MarkUnrealizedWindow = pScreen->MarkUnrealizedWindow;
+        pScreen->MarkUnrealizedWindow = compMarkUnrealizedWindow;
+    }
+}
+
 void
 compReparentWindow(WindowPtr pWin, WindowPtr pPriorParent)
 {
@@ -594,6 +645,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);
-- 
1.9.3



More information about the xorg-devel mailing list