[PATCH 8/8] composite: Implement backing store's Always mode
Adam Jackson
ajax at redhat.com
Mon Nov 17 12:41:15 PST 2014
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 dfbff06..cbb9539 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 09d58a0..347180e 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;
@@ -106,13 +108,25 @@ compInstallColormap(ColormapPtr pColormap)
}
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;
@@ -421,6 +435,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 +450,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 f06b846..1623350 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..40cb83b 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) {
@@ -271,6 +273,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)
{
@@ -282,12 +294,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
@@ -431,6 +467,19 @@ compChangeBorderWidth(WindowPtr pWin, unsigned int bw)
}
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)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
@@ -594,6 +643,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