1 /*
2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "pipeline/rs_render_node_map.h"
17 #include "common/rs_common_def.h"
18 #include "pipeline/rs_render_node.h"
19 #include "pipeline/rs_display_render_node.h"
20 #include "pipeline/rs_surface_render_node.h"
21 #include "platform/common/rs_log.h"
22
23 namespace OHOS {
24 namespace Rosen {
25 namespace {
26 constexpr const char* ENTRY_VIEW = "SCBDesktop";
27 constexpr const char* WALLPAPER_VIEW = "SCBWallpaper";
28 constexpr const char* SCREENLOCK_WINDOW = "SCBScreenLock";
29 constexpr const char* SYSUI_DROPDOWN = "SCBDropdownPanel";
30 };
RSRenderNodeMap()31 RSRenderNodeMap::RSRenderNodeMap()
32 {
33 // add animation fallback node, NOTE: this is different from RSContext::globalRootRenderNode_
34 renderNodeMap_.emplace(0, new RSRenderNode(0));
35 }
36
Initialize(const std::weak_ptr<RSContext> & context)37 void RSRenderNodeMap::Initialize(const std::weak_ptr<RSContext>& context)
38 {
39 context_ = context;
40 }
41
ObtainLauncherNodeId(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode)42 void RSRenderNodeMap::ObtainLauncherNodeId(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode)
43 {
44 if (surfaceNode == nullptr) {
45 return;
46 }
47 if (surfaceNode->GetName().find(ENTRY_VIEW) != std::string::npos) {
48 entryViewNodeId_ = surfaceNode->GetId();
49 }
50 if (surfaceNode->GetName().find(WALLPAPER_VIEW) != std::string::npos) {
51 wallpaperViewNodeId_ = surfaceNode->GetId();
52 }
53 }
54
ObtainScreenLockWindowNodeId(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode)55 void RSRenderNodeMap::ObtainScreenLockWindowNodeId(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode)
56 {
57 if (surfaceNode == nullptr) {
58 return;
59 }
60 if (surfaceNode->GetName().find(SCREENLOCK_WINDOW) != std::string::npos) {
61 screenLockWindowNodeId_ = surfaceNode->GetId();
62 }
63 }
64
GetEntryViewNodeId() const65 NodeId RSRenderNodeMap::GetEntryViewNodeId() const
66 {
67 return entryViewNodeId_;
68 }
69
GetWallPaperViewNodeId() const70 NodeId RSRenderNodeMap::GetWallPaperViewNodeId() const
71 {
72 return wallpaperViewNodeId_;
73 }
74
GetScreenLockWindowNodeId() const75 NodeId RSRenderNodeMap::GetScreenLockWindowNodeId() const
76 {
77 return screenLockWindowNodeId_;
78 }
79
IsResidentProcess(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode)80 static bool IsResidentProcess(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode)
81 {
82 return surfaceNode->GetName().find(ENTRY_VIEW) != std::string::npos ||
83 surfaceNode->GetName().find(SYSUI_DROPDOWN) != std::string::npos ||
84 surfaceNode->GetName().find(SCREENLOCK_WINDOW) != std::string::npos ||
85 surfaceNode->GetName().find(WALLPAPER_VIEW) != std::string::npos;
86 }
87
IsResidentProcessNode(NodeId id) const88 bool RSRenderNodeMap::IsResidentProcessNode(NodeId id) const
89 {
90 auto nodePid = ExtractPid(id);
91 return std::any_of(residentSurfaceNodeMap_.begin(), residentSurfaceNodeMap_.end(),
92 [nodePid](const auto& pair) -> bool { return ExtractPid(pair.first) == nodePid; });
93 }
94
RegisterRenderNode(const std::shared_ptr<RSBaseRenderNode> & nodePtr)95 bool RSRenderNodeMap::RegisterRenderNode(const std::shared_ptr<RSBaseRenderNode>& nodePtr)
96 {
97 NodeId id = nodePtr->GetId();
98 if (renderNodeMap_.count(id)) {
99 return false;
100 }
101 renderNodeMap_.emplace(id, nodePtr);
102 nodePtr->OnRegister(context_);
103 if (nodePtr->GetType() == RSRenderNodeType::SURFACE_NODE) {
104 auto surfaceNode = nodePtr->ReinterpretCastTo<RSSurfaceRenderNode>();
105 surfaceNodeMap_.emplace(id, surfaceNode);
106 if (IsResidentProcess(surfaceNode)) {
107 residentSurfaceNodeMap_.emplace(id, surfaceNode);
108 }
109 ObtainLauncherNodeId(surfaceNode);
110 ObtainScreenLockWindowNodeId(surfaceNode);
111 }
112 return true;
113 }
114
RegisterDisplayRenderNode(const std::shared_ptr<RSDisplayRenderNode> & nodePtr)115 bool RSRenderNodeMap::RegisterDisplayRenderNode(const std::shared_ptr<RSDisplayRenderNode>& nodePtr)
116 {
117 NodeId id = nodePtr->GetId();
118 if (renderNodeMap_.count(id)) {
119 return false;
120 }
121 renderNodeMap_.emplace(id, nodePtr);
122 displayNodeMap_.emplace(id, nodePtr);
123 nodePtr->OnRegister(context_);
124 return true;
125 }
126
UnregisterRenderNode(NodeId id)127 void RSRenderNodeMap::UnregisterRenderNode(NodeId id)
128 {
129 renderNodeMap_.erase(id);
130 surfaceNodeMap_.erase(id);
131 drivenRenderNodeMap_.erase(id);
132 residentSurfaceNodeMap_.erase(id);
133 displayNodeMap_.erase(id);
134 }
135
AddDrivenRenderNode(const std::shared_ptr<RSBaseRenderNode> & nodePtr)136 void RSRenderNodeMap::AddDrivenRenderNode(const std::shared_ptr<RSBaseRenderNode>& nodePtr)
137 {
138 NodeId id = nodePtr->GetId();
139 if (!renderNodeMap_.count(id)) {
140 return;
141 }
142 drivenRenderNodeMap_.emplace(id, nodePtr);
143 }
144
RemoveDrivenRenderNode(NodeId id)145 void RSRenderNodeMap::RemoveDrivenRenderNode(NodeId id)
146 {
147 drivenRenderNodeMap_.erase(id);
148 }
149
MoveRenderNodeMap(std::shared_ptr<std::unordered_map<NodeId,std::shared_ptr<RSBaseRenderNode>>> subRenderNodeMap,pid_t pid)150 void RSRenderNodeMap::MoveRenderNodeMap(
151 std::shared_ptr<std::unordered_map<NodeId, std::shared_ptr<RSBaseRenderNode>>> subRenderNodeMap, pid_t pid)
152 {
153 std::unordered_map<NodeId, std::shared_ptr<RSBaseRenderNode>>::iterator iter = renderNodeMap_.begin();
154 for (; iter != renderNodeMap_.end();) {
155 if (ExtractPid(iter->first) != pid) {
156 ++iter;
157 continue;
158 }
159 // update node flag to avoid animation fallback
160 iter->second->fallbackAnimationOnDestroy_ = false;
161 // remove node from tree
162 iter->second->RemoveFromTree(false);
163 subRenderNodeMap->emplace(iter->first, iter->second);
164 iter = renderNodeMap_.erase(iter);
165 }
166 }
167
FilterNodeByPid(pid_t pid)168 void RSRenderNodeMap::FilterNodeByPid(pid_t pid)
169 {
170 ROSEN_LOGD("RSRenderNodeMap::FilterNodeByPid removing all nodes belong to pid %{public}llu",
171 (unsigned long long)pid);
172 // remove all nodes belong to given pid (by matching higher 32 bits of node id)
173
174 EraseIf(surfaceNodeMap_, [pid](const auto& pair) -> bool {
175 return ExtractPid(pair.first) == pid;
176 });
177
178 EraseIf(drivenRenderNodeMap_, [pid](const auto& pair) -> bool {
179 return ExtractPid(pair.first) == pid;
180 });
181
182 EraseIf(residentSurfaceNodeMap_, [pid](const auto& pair) -> bool {
183 return ExtractPid(pair.first) == pid;
184 });
185
186 EraseIf(displayNodeMap_, [pid](const auto& pair) -> bool {
187 if (ExtractPid(pair.first) != pid && pair.second) {
188 ROSEN_LOGD("RSRenderNodeMap::FilterNodeByPid removing all nodes belong to pid %{public}llu",
189 (unsigned long long)pid);
190 pair.second->FilterModifiersByPid(pid);
191 }
192 return ExtractPid(pair.first) == pid;
193 });
194
195 if (auto fallbackNode = GetAnimationFallbackNode()) {
196 // remove all fallback animations belong to given pid
197 fallbackNode->GetAnimationManager().FilterAnimationByPid(pid);
198 }
199 }
200
TraversalNodes(std::function<void (const std::shared_ptr<RSBaseRenderNode> &)> func) const201 void RSRenderNodeMap::TraversalNodes(std::function<void (const std::shared_ptr<RSBaseRenderNode>&)> func) const
202 {
203 for (const auto& [_, node] : renderNodeMap_) {
204 func(node);
205 }
206 }
207
TraverseSurfaceNodes(std::function<void (const std::shared_ptr<RSSurfaceRenderNode> &)> func) const208 void RSRenderNodeMap::TraverseSurfaceNodes(std::function<void (const std::shared_ptr<RSSurfaceRenderNode>&)> func) const
209 {
210 for (const auto& [_, node] : surfaceNodeMap_) {
211 func(node);
212 }
213 }
214
ContainPid(pid_t pid) const215 bool RSRenderNodeMap::ContainPid(pid_t pid) const
216 {
217 return std::any_of(surfaceNodeMap_.begin(), surfaceNodeMap_.end(),
218 [pid](const auto& pair) -> bool { return ExtractPid(pair.first) == pid; });
219 }
220
TraverseDrivenRenderNodes(std::function<void (const std::shared_ptr<RSRenderNode> &)> func) const221 void RSRenderNodeMap::TraverseDrivenRenderNodes(std::function<void (const std::shared_ptr<RSRenderNode>&)> func) const
222 {
223 for (const auto& [_, node] : drivenRenderNodeMap_) {
224 func(node);
225 }
226 }
227
TraverseDisplayNodes(std::function<void (const std::shared_ptr<RSDisplayRenderNode> &)> func) const228 void RSRenderNodeMap::TraverseDisplayNodes(std::function<void (const std::shared_ptr<RSDisplayRenderNode>&)> func) const
229 {
230 for (const auto& [_, node] : displayNodeMap_) {
231 func(node);
232 }
233 }
234
GetResidentSurfaceNodeMap() const235 std::unordered_map<NodeId, std::shared_ptr<RSSurfaceRenderNode>> RSRenderNodeMap::GetResidentSurfaceNodeMap() const
236 {
237 return residentSurfaceNodeMap_;
238 }
239
240 template<>
GetRenderNode(NodeId id) const241 const std::shared_ptr<RSBaseRenderNode> RSRenderNodeMap::GetRenderNode(NodeId id) const
242 {
243 auto itr = renderNodeMap_.find(id);
244 if (itr == renderNodeMap_.end()) {
245 return nullptr;
246 }
247 return itr->second;
248 }
249
GetAnimationFallbackNode() const250 const std::shared_ptr<RSRenderNode> RSRenderNodeMap::GetAnimationFallbackNode() const
251 {
252 auto itr = renderNodeMap_.find(0);
253 if (itr == renderNodeMap_.end()) {
254 return nullptr;
255 }
256 return itr->second;
257 }
258 } // namespace Rosen
259 } // namespace OHOS
260