[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