When destroying layer, add children to offscreen layers
If a layer is destroyed, make sure all children are added to the
offscreen layers. Otherwise, we may dangle a layer that is neither in
current state nor in offscreen layers.
Bug: 141111965
Test: build, boot, manual
Change-Id: Iec6788f10a24cb63faa9b40f246cbde3770d24a7
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 14a2ab1..0953446 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3717,9 +3717,6 @@
}
if (currentMode == HWC_POWER_MODE_OFF) {
- // Turn on the display
- // TODO: @vhau temp fix only! See b/141111965
- mTransactionCompletedThread.clearAllPending();
getHwComposer().setPowerMode(*displayId, mode);
if (display->isPrimary() && mode != HWC_POWER_MODE_DOZE_SUSPEND) {
setVsyncEnabledInHWC(*displayId, mHWCVsyncPendingState);
@@ -5500,6 +5497,20 @@
void SurfaceFlinger::onLayerDestroyed(Layer* layer) {
mNumLayers--;
+ removeFromOffscreenLayers(layer);
+}
+
+// WARNING: ONLY CALL THIS FROM LAYER DTOR
+// Here we add children in the current state to offscreen layers and remove the
+// layer itself from the offscreen layer list. Since
+// this is the dtor, it is safe to access the current state. This keeps us
+// from dangling children layers such that they are not reachable from the
+// Drawing state nor the offscreen layer list
+// See b/141111965
+void SurfaceFlinger::removeFromOffscreenLayers(Layer* layer) {
+ for (auto& child : layer->getCurrentChildren()) {
+ mOffscreenLayers.emplace(child.get());
+ }
mOffscreenLayers.erase(layer);
}