SF: Introduce LayerSnapshot and LayerSnapshotBuilder

Create a builder that walks through the layer hierarchy
to build an ordered list of LayerSnapshots that can be
passed on to CompositionEngine.

This builder does a minimum amount of work to update
an existing set of snapshots based on hierarchy changes
and RequestedLayerState changes.

The builder also introduces a fast path to update
snapshots when there are only buffer updates.

Additionally, pull out LayerSnapshot class from LayerFE
and move it to frontend package.

Bug: 238781169
Test: presubmit
Change-Id: I3fbd6d60968950df2ee97d975c72f9e0aa31b007
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h
new file mode 100644
index 0000000..33b250c
--- /dev/null
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "Display/DisplayMap.h"
+#include "FrontEnd/DisplayInfo.h"
+#include "FrontEnd/LayerLifecycleManager.h"
+#include "LayerHierarchy.h"
+#include "LayerSnapshot.h"
+#include "RequestedLayerState.h"
+
+namespace android::surfaceflinger::frontend {
+
+// Walks through the layer hierarchy to build an ordered list
+// of LayerSnapshots that can be passed on to CompositionEngine.
+// This builder does a minimum amount of work to update
+// an existing set of snapshots based on hierarchy changes
+// and RequestedLayerState changes.
+
+// The builder also uses a fast path to update
+// snapshots when there are only buffer updates.
+class LayerSnapshotBuilder {
+public:
+    struct Args {
+        const LayerHierarchy& root;
+        const LayerLifecycleManager& layerLifecycleManager;
+        bool forceUpdate = false;
+        bool includeMetadata = false;
+        const display::DisplayMap<ui::LayerStack, frontend::DisplayInfo>& displays;
+        // Set to true if there were display changes since last update.
+        bool displayChanges = false;
+        const renderengine::ShadowSettings& globalShadowSettings;
+    };
+    LayerSnapshotBuilder();
+
+    // Rebuild the snapshots from scratch.
+    LayerSnapshotBuilder(Args);
+
+    // Update an existing set of snapshot using change flags in RequestedLayerState
+    // and LayerLifecycleManager. This needs to be called before
+    // LayerLifecycleManager.commitChanges is called as that function will clear all
+    // change flags.
+    void update(const Args&);
+    std::vector<std::unique_ptr<LayerSnapshot>>& getSnapshots();
+
+private:
+    friend class LayerSnapshotTest;
+    LayerSnapshot* getSnapshot(uint32_t layerId) const;
+    LayerSnapshot* getSnapshot(const LayerHierarchy::TraversalPath& id) const;
+    static LayerSnapshot getRootSnapshot();
+
+    // return true if we were able to successfully update the snapshots via
+    // the fast path.
+    bool tryFastUpdate(const Args& args);
+
+    void updateSnapshots(const Args& args);
+
+    void updateSnapshotsInHierarchy(const Args&, const LayerHierarchy& hierarchy,
+                                    LayerHierarchy::TraversalPath& traversalPath,
+                                    const LayerSnapshot& parentSnapshot);
+    void updateSnapshot(LayerSnapshot& snapshot, const Args& args, const RequestedLayerState&,
+                        const LayerSnapshot& parentSnapshot,
+                        const LayerHierarchy::TraversalPath& path);
+    static void updateRelativeState(LayerSnapshot& snapshot, const LayerSnapshot& parentSnapshot,
+                                    bool parentIsRelative, const Args& args);
+    static void resetRelativeState(LayerSnapshot& snapshot);
+    static void updateRoundedCorner(LayerSnapshot& snapshot, const RequestedLayerState& layerState,
+                                    const LayerSnapshot& parentSnapshot);
+    static void updateLayerBounds(LayerSnapshot& snapshot, const RequestedLayerState& layerState,
+                                  const LayerSnapshot& parentSnapshot,
+                                  uint32_t displayRotationFlags);
+    static void updateShadows(LayerSnapshot& snapshot, const RequestedLayerState& requested,
+                              const renderengine::ShadowSettings& globalShadowSettings);
+    void updateInput(LayerSnapshot& snapshot, const RequestedLayerState& requested,
+                     const LayerSnapshot& parentSnapshot, const frontend::DisplayInfo& displayInfo,
+                     bool noValidDisplay, const LayerHierarchy::TraversalPath& path);
+    void sortSnapshotsByZ(const Args& args);
+    LayerSnapshot* getOrCreateSnapshot(const LayerHierarchy::TraversalPath& id,
+                                       const RequestedLayerState& layer);
+
+    struct TraversalPathHash {
+        std::size_t operator()(const LayerHierarchy::TraversalPath& key) const {
+            uint32_t hashCode = key.id * 31;
+            for (auto mirrorRoot : key.mirrorRootIds) {
+                hashCode += mirrorRoot * 31;
+            }
+            return std::hash<size_t>{}(hashCode);
+        }
+    };
+    std::unordered_map<LayerHierarchy::TraversalPath, LayerSnapshot*, TraversalPathHash>
+            mIdToSnapshot;
+    std::vector<std::unique_ptr<LayerSnapshot>> mSnapshots;
+    LayerSnapshot mRootSnapshot;
+};
+
+} // namespace android::surfaceflinger::frontend