OSDN Git Service

SurfaceFlinger: Fix destruction of relatively Z-ordered layers.
authorRobert Carr <racarr@google.com>
Tue, 25 Apr 2017 17:54:24 +0000 (10:54 -0700)
committerRobert Carr <racarr@google.com>
Tue, 25 Apr 2017 17:54:24 +0000 (10:54 -0700)
We need to explicitly remove a layer from it's Z-order relative when
the layer is removed from compositing, and not rely on being the last
reference. In particular, at the time we are generating the list
of visible layers by traversing, any layer which had just been removed
will still be alive (but abandoned) with a ref in the previous list
of visible layers. So we will succeed in promotion, and copy it to the new
list. This way the layer achieves eternal life even after onRemoved is called.

Bug: 36693738
Test: Manual from BR
Change-Id: Ic6c3f64ceb0f603e7c0e51b136c23839858aa639

services/surfaceflinger/Layer.cpp

index d044f37..0e7c214 100644 (file)
@@ -287,6 +287,14 @@ void Layer::onSidebandStreamChanged() {
 // the layer has been remove from the current state list (and just before
 // it's removed from the drawing state list)
 void Layer::onRemoved() {
+    if (mCurrentState.zOrderRelativeOf != nullptr) {
+        sp<Layer> strongRelative = mCurrentState.zOrderRelativeOf.promote();
+        if (strongRelative != nullptr) {
+            strongRelative->removeZOrderRelative(this);
+        }
+        mCurrentState.zOrderRelativeOf = nullptr;
+    }
+
     mSurfaceFlingerConsumer->abandon();
     for (const auto& child : mCurrentChildren) {
         child->onRemoved();
@@ -2555,11 +2563,6 @@ LayerVector Layer::makeTraversalList() {
         sp<Layer> strongRelative = weakRelative.promote();
         if (strongRelative != nullptr) {
             traverse.add(strongRelative);
-        } else {
-            // We need to erase from current state instead of drawing
-            // state so we don't overwrite when copying
-            // the current state to the drawing state.
-            mCurrentState.zOrderRelatives.remove(weakRelative);
         }
     }