[sf] optimize snapshot updates

Modify the snapshot update logic so its easier to maintain. Instead of
walking the tree and updating all the snapshots, this cl introduces a
preliminary step of walking though all the requested changes and
updating the affected snapshots by merging the changes to the snapshot.
This is followed by walking down the tree and updating properties that
are dependent on the parent snapshots.

If the changes are confined to buffer updates, then the fast path avoids
walking down the tree.

Bug: 238781169
Test: presubmit

Change-Id: Ic9aa66c376bf7ea80e38b321dd08b8d0f69559a9
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshot.h b/services/surfaceflinger/FrontEnd/LayerSnapshot.h
index b167d3e..2f45d52 100644
--- a/services/surfaceflinger/FrontEnd/LayerSnapshot.h
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshot.h
@@ -18,6 +18,7 @@
 
 #include <compositionengine/LayerFECompositionState.h>
 #include <renderengine/LayerSettings.h>
+#include "DisplayHardware/ComposerHal.h"
 #include "LayerHierarchy.h"
 #include "RequestedLayerState.h"
 #include "Scheduler/LayerInfo.h"
@@ -57,6 +58,7 @@
     bool isHiddenByPolicyFromParent = false;
     bool isHiddenByPolicyFromRelativeParent = false;
     ftl::Flags<RequestedLayerState::Changes> changes;
+    uint64_t clientChanges = 0;
     // Some consumers of this snapshot (input, layer traces) rely on each snapshot to be unique.
     // For mirrored layers, snapshots will have the same sequence so this unique id provides
     // an alternative identifier when needed.
@@ -93,11 +95,37 @@
     bool handleSkipScreenshotFlag = false;
     int32_t frameRateSelectionPriority;
     LayerHierarchy::TraversalPath mirrorRootPath;
-    bool unreachable = true;
     uint32_t touchCropId;
-    uid_t uid;
-    pid_t pid;
+    gui::Uid uid = gui::Uid::INVALID;
+    gui::Pid pid = gui::Pid::INVALID;
     ChildState childState;
+    enum class Reachablilty : uint32_t {
+        // Can traverse the hierarchy from a root node and reach this snapshot
+        Reachable,
+        // Cannot traverse the hierarchy from a root node and reach this snapshot
+        Unreachable,
+        // Can only reach this node from a relative parent. This means the nodes parents are
+        // not reachable.
+        // See example scenario:
+        // ROOT
+        // ├── 1
+        // │   ├── 11
+        // │   │   └── 111
+        // │   ├── 12
+        // │   │   └ - 111 (relative)
+        // │   ├── 13
+        // │   └── 14
+        // │       └ * 12 (mirroring)
+        // └── 2
+        // 111 will create two snapshots, first when visited from 1 -> 12 or 1 -> 11 and the
+        // second when visited from 1 -> 14 -> 12. Because its parent 11 doesn't exist in the
+        // mirrored hierarchy, the second snapshot will be marked as ReachableByRelativeParent.
+        // This snapshot doesn't have any valid properties because it cannot inherit from its
+        // parent. Therefore, snapshots that are not reachable will be ignored for composition
+        // and input.
+        ReachableByRelativeParent
+    };
+    Reachablilty reachablilty;
 
     static bool isOpaqueFormat(PixelFormat format);
     static bool isTransformValid(const ui::Transform& t);
@@ -116,6 +144,10 @@
     std::string getIsVisibleReason() const;
     bool hasInputInfo() const;
     FloatRect sourceBounds() const;
+    Hwc2::IComposerClient::BlendMode getBlendMode(const RequestedLayerState& requested) const;
+
+    void merge(const RequestedLayerState& requested, bool forceUpdate, bool displayChanges,
+               bool forceFullDamage, uint32_t displayRotationFlags);
 };
 
 } // namespace android::surfaceflinger::frontend