[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