diff options
author | Adam Jackson <ajax@redhat.com> | 2014-07-17 14:22:14 -0400 |
---|---|---|
committer | Adam Jackson <ajax@redhat.com> | 2015-06-30 13:48:40 -0400 |
commit | 4017e03968f67df0711860ba56acb08bf2b1aeba (patch) | |
tree | c897e29cf505c7bab5912c199f4a529f1baa8a79 | |
parent | 9bed05e8bf36a68565e10e5222399de3f1e69df0 (diff) |
composite: Implement backing store's Always mode (v2)bsbs11
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@redhat.com>
-rw-r--r-- | composite/compalloc.c | 2 | ||||
-rw-r--r-- | composite/compinit.c | 29 | ||||
-rw-r--r-- | composite/compint.h | 8 | ||||
-rw-r--r-- | composite/compwindow.c | 63 |
4 files changed, 92 insertions, 10 deletions
diff --git a/composite/compalloc.c b/composite/compalloc.c index 8daded0a5..81c58f61e 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 791fec922..d7965c2f6 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 09241f2a2..4f1967231 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 77bdfa23c..8028d98a0 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); |