blob: d70bdb9920fd6177ca9ed4eaec19d1bcd37b995d [file] [log] [blame]
Vishnu Nair8fc721b2022-12-22 20:06:32 +00001/*
2 * Copyright 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19#include "Display/DisplayMap.h"
20#include "FrontEnd/DisplayInfo.h"
21#include "FrontEnd/LayerLifecycleManager.h"
22#include "LayerHierarchy.h"
23#include "LayerSnapshot.h"
24#include "RequestedLayerState.h"
25
26namespace android::surfaceflinger::frontend {
27
28// Walks through the layer hierarchy to build an ordered list
29// of LayerSnapshots that can be passed on to CompositionEngine.
30// This builder does a minimum amount of work to update
31// an existing set of snapshots based on hierarchy changes
32// and RequestedLayerState changes.
33
34// The builder also uses a fast path to update
35// snapshots when there are only buffer updates.
36class LayerSnapshotBuilder {
37public:
Vishnu Naird47bcee2023-02-24 18:08:51 +000038 enum class ForceUpdateFlags {
39 NONE,
40 ALL,
41 HIERARCHY,
42 };
Vishnu Nair8fc721b2022-12-22 20:06:32 +000043 struct Args {
Vishnu Nair3af0ec02023-02-10 04:13:48 +000044 LayerHierarchy root;
Vishnu Nair8fc721b2022-12-22 20:06:32 +000045 const LayerLifecycleManager& layerLifecycleManager;
Vishnu Naird47bcee2023-02-24 18:08:51 +000046 ForceUpdateFlags forceUpdate = ForceUpdateFlags::NONE;
Vishnu Nair8fc721b2022-12-22 20:06:32 +000047 bool includeMetadata = false;
48 const display::DisplayMap<ui::LayerStack, frontend::DisplayInfo>& displays;
49 // Set to true if there were display changes since last update.
50 bool displayChanges = false;
51 const renderengine::ShadowSettings& globalShadowSettings;
Vishnu Naircfb2d252023-01-19 04:44:02 +000052 bool supportsBlur = true;
53 bool forceFullDamage = false;
Vishnu Nair3af0ec02023-02-10 04:13:48 +000054 std::optional<FloatRect> parentCrop = std::nullopt;
55 std::unordered_set<uint32_t> excludeLayerIds;
Vishnu Nair8fc721b2022-12-22 20:06:32 +000056 };
57 LayerSnapshotBuilder();
58
59 // Rebuild the snapshots from scratch.
60 LayerSnapshotBuilder(Args);
61
62 // Update an existing set of snapshot using change flags in RequestedLayerState
63 // and LayerLifecycleManager. This needs to be called before
64 // LayerLifecycleManager.commitChanges is called as that function will clear all
65 // change flags.
66 void update(const Args&);
67 std::vector<std::unique_ptr<LayerSnapshot>>& getSnapshots();
Vishnu Naircfb2d252023-01-19 04:44:02 +000068 LayerSnapshot* getSnapshot(uint32_t layerId) const;
69
70 typedef std::function<void(const LayerSnapshot& snapshot)> ConstVisitor;
71
72 // Visit each visible snapshot in z-order
73 void forEachVisibleSnapshot(const ConstVisitor& visitor) const;
74
Vishnu Nair3af0ec02023-02-10 04:13:48 +000075 // Visit each visible snapshot in z-order
76 void forEachVisibleSnapshot(const ConstVisitor& visitor, const LayerHierarchy& root) const;
77
Vishnu Naircfb2d252023-01-19 04:44:02 +000078 typedef std::function<void(std::unique_ptr<LayerSnapshot>& snapshot)> Visitor;
79 // Visit each visible snapshot in z-order and move the snapshot if needed
80 void forEachVisibleSnapshot(const Visitor& visitor);
81
82 // Visit each snapshot interesting to input reverse z-order
83 void forEachInputSnapshot(const ConstVisitor& visitor) const;
Vishnu Nair8fc721b2022-12-22 20:06:32 +000084
85private:
86 friend class LayerSnapshotTest;
Vishnu Nair8fc721b2022-12-22 20:06:32 +000087 LayerSnapshot* getSnapshot(const LayerHierarchy::TraversalPath& id) const;
88 static LayerSnapshot getRootSnapshot();
89
90 // return true if we were able to successfully update the snapshots via
91 // the fast path.
92 bool tryFastUpdate(const Args& args);
93
94 void updateSnapshots(const Args& args);
95
Vishnu Naircfb2d252023-01-19 04:44:02 +000096 const LayerSnapshot& updateSnapshotsInHierarchy(const Args&, const LayerHierarchy& hierarchy,
97 LayerHierarchy::TraversalPath& traversalPath,
98 const LayerSnapshot& parentSnapshot);
99 void updateSnapshot(LayerSnapshot&, const Args&, const RequestedLayerState&,
100 const LayerSnapshot& parentSnapshot, const LayerHierarchy::TraversalPath&,
101 bool newSnapshot);
Vishnu Nair8fc721b2022-12-22 20:06:32 +0000102 static void updateRelativeState(LayerSnapshot& snapshot, const LayerSnapshot& parentSnapshot,
103 bool parentIsRelative, const Args& args);
104 static void resetRelativeState(LayerSnapshot& snapshot);
105 static void updateRoundedCorner(LayerSnapshot& snapshot, const RequestedLayerState& layerState,
106 const LayerSnapshot& parentSnapshot);
Vishnu Naircfb2d252023-01-19 04:44:02 +0000107 void updateLayerBounds(LayerSnapshot& snapshot, const RequestedLayerState& layerState,
108 const LayerSnapshot& parentSnapshot, uint32_t displayRotationFlags);
Vishnu Nair8fc721b2022-12-22 20:06:32 +0000109 static void updateShadows(LayerSnapshot& snapshot, const RequestedLayerState& requested,
110 const renderengine::ShadowSettings& globalShadowSettings);
111 void updateInput(LayerSnapshot& snapshot, const RequestedLayerState& requested,
Vishnu Naircfb2d252023-01-19 04:44:02 +0000112 const LayerSnapshot& parentSnapshot, const LayerHierarchy::TraversalPath& path,
113 const Args& args);
Vishnu Nair8fc721b2022-12-22 20:06:32 +0000114 void sortSnapshotsByZ(const Args& args);
Vishnu Naircfb2d252023-01-19 04:44:02 +0000115 LayerSnapshot* createSnapshot(const LayerHierarchy::TraversalPath& id,
116 const RequestedLayerState& layer);
117 void updateChildState(LayerSnapshot& snapshot, const LayerSnapshot& childSnapshot,
118 const Args& args);
Vishnu Nair8fc721b2022-12-22 20:06:32 +0000119
120 struct TraversalPathHash {
121 std::size_t operator()(const LayerHierarchy::TraversalPath& key) const {
122 uint32_t hashCode = key.id * 31;
Vishnu Nair80a5a702023-02-11 01:21:51 +0000123 if (key.mirrorRootId != UNASSIGNED_LAYER_ID) {
124 hashCode += key.mirrorRootId * 31;
Vishnu Nair8fc721b2022-12-22 20:06:32 +0000125 }
126 return std::hash<size_t>{}(hashCode);
127 }
128 };
129 std::unordered_map<LayerHierarchy::TraversalPath, LayerSnapshot*, TraversalPathHash>
130 mIdToSnapshot;
131 std::vector<std::unique_ptr<LayerSnapshot>> mSnapshots;
132 LayerSnapshot mRootSnapshot;
Vishnu Naircfb2d252023-01-19 04:44:02 +0000133 bool mResortSnapshots = false;
134 int mNumInterestingSnapshots = 0;
Vishnu Nair8fc721b2022-12-22 20:06:32 +0000135};
136
137} // namespace android::surfaceflinger::frontend