summaryrefslogtreecommitdiff
path: root/services/surfaceflinger/SurfaceFlinger.cpp
diff options
context:
space:
mode:
author Robert Carr <racarr@google.com> 2017-02-13 11:32:32 -0800
committer Robert Carr <racarr@google.com> 2017-02-27 10:21:55 -0800
commit9524cb3b37a91b5741790c77ff24fd825b02bca7 (patch)
treebe35f6724ed74a7ebb4f0deb424d903eb1f96159 /services/surfaceflinger/SurfaceFlinger.cpp
parent0d48072f6047140119ff194c1194ce402fca2c0b (diff)
Add detachChildren transaction.
Add SurfaceControl#detachChildren for use by the WindowManager. This method is used in cases where the WM would previously preserve windows the client tried to destroy. For example, when becoming invisible (in the activity lifecycle sense, not in the SurfaceFlinger sense) an app will destroy its child surfaces. Previously the WM would keep child windows alive until the animation finishes to prevent glitches. The new scheme for this is the WM will detach the children at this point, at which point the parent layer becomes the owner of the children and the WM can control the lifecycle as it wishes. I also included a test for reparentChildren as I realized I had forgotten that. Test: New test in Transaction_test.cpp Change-Id: I79c22b2ccccceb9bdcc37b70c491bdf33dcf83d2
Diffstat (limited to 'services/surfaceflinger/SurfaceFlinger.cpp')
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp24
1 files changed, 14 insertions, 10 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 7a31a1528c..62c9f25da3 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2534,14 +2534,7 @@ status_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
return NO_ERROR;
}
-status_t SurfaceFlinger::removeLayer(const wp<Layer>& weakLayer) {
- Mutex::Autolock _l(mStateLock);
- sp<Layer> layer = weakLayer.promote();
- if (layer == nullptr) {
- // The layer has already been removed, carry on
- return NO_ERROR;
- }
-
+status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
const auto& p = layer->getParent();
const ssize_t index = (p != nullptr) ? p->removeChild(layer) :
mCurrentState.layersSortedByZ.remove(layer);
@@ -2824,6 +2817,9 @@ uint32_t SurfaceFlinger::setClientStateLocked(
flags |= eTransactionNeeded|eTraversalNeeded;
}
}
+ if (what & layer_state_t::eDetachChildren) {
+ layer->detachChildren();
+ }
if (what & layer_state_t::eOverrideScalingModeChanged) {
layer->setOverrideScalingMode(s.overrideScalingMode);
// We don't trigger a traversal here because if no other state is
@@ -2920,7 +2916,7 @@ status_t SurfaceFlinger::createDimLayer(const sp<Client>& client,
status_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle)
{
- // called by the window manager when it wants to remove a Layer
+ // called by a client when it wants to remove a Layer
status_t err = NO_ERROR;
sp<Layer> l(client->getLayerUser(handle));
if (l != NULL) {
@@ -2936,7 +2932,15 @@ status_t SurfaceFlinger::onLayerDestroyed(const wp<Layer>& layer)
{
// called by ~LayerCleaner() when all references to the IBinder (handle)
// are gone
- return removeLayer(layer);
+ sp<Layer> l = layer.promote();
+ if (l == nullptr) {
+ // The layer has already been removed, carry on
+ return NO_ERROR;
+ } if (l->getParent() != nullptr) {
+ // If we have a parent, then we can continue to live as long as it does.
+ return NO_ERROR;
+ }
+ return removeLayer(l);
}
// ---------------------------------------------------------------------------