[sf] destroy unreachable snapshots

Keep track of unreachable snapshots and destroy
them. This is a more robust way of cleaning up
snapshots rather than going through destroyed
layer handles. This way we will handle mirrored
snapshots when the original layer gets destroyed.

Test: presubmit
Bug: 238781169
Change-Id: Iddd5754ae71086719711ecaab218fc5f52e11ef5
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshot.h b/services/surfaceflinger/FrontEnd/LayerSnapshot.h
index 9757640..07aa122 100644
--- a/services/surfaceflinger/FrontEnd/LayerSnapshot.h
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshot.h
@@ -85,6 +85,7 @@
     ui::Transform::RotationFlags fixedTransformHint;
     bool handleSkipScreenshotFlag = false;
     LayerHierarchy::TraversalPath mirrorRootPath;
+    bool unreachable = true;
     ChildState childState;
 
     static bool isOpaqueFormat(PixelFormat format);
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
index 9ccf6dc..db6e716 100644
--- a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
@@ -435,22 +435,18 @@
         }
     }
 
-    sortSnapshotsByZ(args);
+    const bool hasUnreachableSnapshots = sortSnapshotsByZ(args);
     clearChanges(mRootSnapshot);
 
     // Destroy unreachable snapshots
-    if (args.layerLifecycleManager.getDestroyedLayers().empty()) {
+    if (!hasUnreachableSnapshots) {
         return;
     }
 
-    std::unordered_set<uint32_t> destroyedLayerIds;
-    for (auto& destroyedLayer : args.layerLifecycleManager.getDestroyedLayers()) {
-        destroyedLayerIds.emplace(destroyedLayer->id);
-    }
     auto it = mSnapshots.begin();
     while (it < mSnapshots.end()) {
         auto& traversalPath = it->get()->path;
-        if (destroyedLayerIds.find(traversalPath.id) == destroyedLayerIds.end()) {
+        if (!it->get()->unreachable) {
             it++;
             continue;
         }
@@ -534,18 +530,21 @@
     return snapshot;
 }
 
-void LayerSnapshotBuilder::sortSnapshotsByZ(const Args& args) {
+bool LayerSnapshotBuilder::sortSnapshotsByZ(const Args& args) {
     if (!mResortSnapshots && args.forceUpdate == ForceUpdateFlags::NONE &&
         !args.layerLifecycleManager.getGlobalChanges().any(
                 RequestedLayerState::Changes::Hierarchy |
                 RequestedLayerState::Changes::Visibility)) {
         // We are not force updating and there are no hierarchy or visibility changes. Avoid sorting
         // the snapshots.
-        return;
+        return false;
     }
-
     mResortSnapshots = false;
 
+    for (auto& snapshot : mSnapshots) {
+        snapshot->unreachable = true;
+    }
+
     size_t globalZ = 0;
     args.root.traverseInZOrder(
             [this, &globalZ](const LayerHierarchy&,
@@ -555,11 +554,7 @@
                     return false;
                 }
 
-                if (snapshot->isHiddenByPolicy() &&
-                    !snapshot->changes.test(RequestedLayerState::Changes::Visibility)) {
-                    return false;
-                }
-
+                snapshot->unreachable = false;
                 if (snapshot->getIsVisible() || snapshot->hasInputInfo()) {
                     updateVisibility(*snapshot, snapshot->getIsVisible());
                     size_t oldZ = snapshot->globalZ;
@@ -577,12 +572,17 @@
                 return true;
             });
     mNumInterestingSnapshots = (int)globalZ;
+    bool hasUnreachableSnapshots = false;
     while (globalZ < mSnapshots.size()) {
         mSnapshots[globalZ]->globalZ = globalZ;
         /* mark unreachable snapshots as explicitly invisible */
         updateVisibility(*mSnapshots[globalZ], false);
+        if (mSnapshots[globalZ]->unreachable) {
+            hasUnreachableSnapshots = true;
+        }
         globalZ++;
     }
+    return hasUnreachableSnapshots;
 }
 
 void LayerSnapshotBuilder::updateRelativeState(LayerSnapshot& snapshot,
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h
index 07b0d14..3997a0a 100644
--- a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h
@@ -112,7 +112,8 @@
     void updateInput(LayerSnapshot& snapshot, const RequestedLayerState& requested,
                      const LayerSnapshot& parentSnapshot, const LayerHierarchy::TraversalPath& path,
                      const Args& args);
-    void sortSnapshotsByZ(const Args& args);
+    // Return true if there are unreachable snapshots
+    bool sortSnapshotsByZ(const Args& args);
     LayerSnapshot* createSnapshot(const LayerHierarchy::TraversalPath& id,
                                   const RequestedLayerState& layer,
                                   const LayerSnapshot& parentSnapshot);