SF: More frontend fixes

- Crop mirrored layers with the mirror root. Previously we were
 cropping the layers with the original layer and not the clone.
- Explicitly make unreachable nodes invisible. Fixes an issue where
we accessed stale snapshots that were no longer reachable.
- Update buffer geometry (inverseTransformDisplay) when display state
changes.
- Blur fixes.

Test: presubmit
Bug: 238781169

Change-Id: I6f88f2456c3fd15c9d819ec2272aee639badcd19
diff --git a/services/surfaceflinger/FrontEnd/LayerHierarchy.h b/services/surfaceflinger/FrontEnd/LayerHierarchy.h
index ca8d301..2ab897b 100644
--- a/services/surfaceflinger/FrontEnd/LayerHierarchy.h
+++ b/services/surfaceflinger/FrontEnd/LayerHierarchy.h
@@ -50,12 +50,32 @@
         ftl_last = Mirror,
     };
     // Represents a unique path to a node.
+    // The layer hierarchy is represented as a graph. Each node can be visited by multiple parents.
+    // This allows us to represent mirroring in an efficient way. See the example below:
+    // root
+    // ├─ A {Traversal path id = 1}
+    // ├─ B {Traversal path id = 2}
+    // │  ├─ C {Traversal path id = 3}
+    // │  ├─ D {Traversal path id = 4}
+    // │  └─ E {Traversal path id = 5}
+    // ├─ F (Mirrors B) {Traversal path id = 6}
+    // └─ G (Mirrors F) {Traversal path id = 7}
+    //
+    // C, D and E can be traversed via B or via F then B or via G then F then B.
+    // Depending on how the node is reached, its properties such as geometry or visibility might be
+    // different. And we can uniquely identify the node by keeping track of the nodes leading up to
+    // it. But to be more efficient we only need to track the nodes id and the top mirror root path.
+    // So C for example, would have the following unique traversal paths:
+    //  - {Traversal path id = 3}
+    //  - {Traversal path id = 3, mirrorRootId = 6}
+    //  - {Traversal path id = 3, mirrorRootId = 7}
+
     struct TraversalPath {
         uint32_t id;
         LayerHierarchy::Variant variant;
         // Mirrored layers can have a different geometry than their parents so we need to track
         // the mirror roots in the traversal.
-        ftl::SmallVector<uint32_t, 5> mirrorRootIds;
+        uint32_t mirrorRootId = UNASSIGNED_LAYER_ID;
         // Relative layers can be visited twice, once by their parent and then once again by
         // their relative parent. We keep track of the roots here to detect any loops in the
         // hierarchy. If a relative root already exists in the list while building the
@@ -73,10 +93,11 @@
         // Returns true if the node or its parents are not Detached.
         bool isAttached() const { return !detached; }
         // Returns true if the node is a clone.
-        bool isClone() const { return !mirrorRootIds.empty(); }
+        bool isClone() const { return mirrorRootId != UNASSIGNED_LAYER_ID; }
+        TraversalPath getMirrorRoot() const;
 
         bool operator==(const TraversalPath& other) const {
-            return id == other.id && mirrorRootIds == other.mirrorRootIds;
+            return id == other.id && mirrorRootId == other.mirrorRootId;
         }
         std::string toString() const;
 
@@ -93,9 +114,7 @@
 
     private:
         TraversalPath& mTraversalPath;
-        uint32_t mParentId;
-        LayerHierarchy::Variant mParentVariant;
-        bool mParentDetached;
+        TraversalPath mParentPath;
     };
     LayerHierarchy(RequestedLayerState* layer);