• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_canvas_drawing_render_node.h"
19 #include "pipeline/rs_render_node.h"
20 #include "pipeline/rs_display_render_node.h"
21 #include "pipeline/rs_render_node_gc.h"
22 #include "pipeline/rs_surface_render_node.h"
23 #include "platform/common/rs_log.h"
24 
25 namespace OHOS {
26 namespace Rosen {
27 namespace {
28 constexpr const char* ENTRY_VIEW = "SCBDesktop";
29 constexpr const char* WALLPAPER_VIEW = "SCBWallpaper";
30 constexpr const char* SCREENLOCK_WINDOW = "SCBScreenLock";
31 constexpr const char* SYSUI_DROPDOWN = "SCBDropdownPanel";
32 constexpr const char* NEGATIVE_SCREEN = "SCBNegativeScreen";
33 };
34 
35 using ResidentSurfaceNodeMap = std::unordered_map<NodeId, std::shared_ptr<RSSurfaceRenderNode>>;
36 
RSRenderNodeMap()37 RSRenderNodeMap::RSRenderNodeMap()
38 {
39     // add animation fallback node, NOTE: this is different from RSContext::globalRootRenderNode_
40     renderNodeMap_.emplace(0, new RSRenderNode(0));
41 }
42 
Initialize(const std::weak_ptr<RSContext> & context)43 void RSRenderNodeMap::Initialize(const std::weak_ptr<RSContext>& context)
44 {
45     context_ = context;
46 }
47 
ObtainLauncherNodeId(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode)48 void RSRenderNodeMap::ObtainLauncherNodeId(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode)
49 {
50     if (surfaceNode == nullptr) {
51         return;
52     }
53     if (surfaceNode->GetName().find(ENTRY_VIEW) != std::string::npos) {
54         entryViewNodeId_ = surfaceNode->GetId();
55     }
56     if (surfaceNode->GetName().find(WALLPAPER_VIEW) != std::string::npos) {
57         wallpaperViewNodeId_ = surfaceNode->GetId();
58     }
59     if (surfaceNode->GetName().find(NEGATIVE_SCREEN) != std::string::npos) {
60         negativeScreenNodeId_ = surfaceNode->GetId();
61     }
62 }
63 
ObtainScreenLockWindowNodeId(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode)64 void RSRenderNodeMap::ObtainScreenLockWindowNodeId(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode)
65 {
66     if (surfaceNode == nullptr) {
67         return;
68     }
69     if (surfaceNode->GetName().find(SCREENLOCK_WINDOW) != std::string::npos) {
70         screenLockWindowNodeId_ = surfaceNode->GetId();
71     }
72 }
73 
GetEntryViewNodeId() const74 NodeId RSRenderNodeMap::GetEntryViewNodeId() const
75 {
76     return entryViewNodeId_;
77 }
78 
GetWallPaperViewNodeId() const79 NodeId RSRenderNodeMap::GetWallPaperViewNodeId() const
80 {
81     return wallpaperViewNodeId_;
82 }
83 
GetScreenLockWindowNodeId() const84 NodeId RSRenderNodeMap::GetScreenLockWindowNodeId() const
85 {
86     return screenLockWindowNodeId_;
87 }
88 
GetNegativeScreenNodeId() const89 NodeId RSRenderNodeMap::GetNegativeScreenNodeId() const
90 {
91     return negativeScreenNodeId_;
92 }
93 
IsResidentProcess(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode)94 static bool IsResidentProcess(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode)
95 {
96     return surfaceNode->GetName().find(ENTRY_VIEW) != std::string::npos ||
97            surfaceNode->GetName().find(SYSUI_DROPDOWN) != std::string::npos ||
98            surfaceNode->GetName().find(SCREENLOCK_WINDOW) != std::string::npos ||
99            surfaceNode->GetName().find(WALLPAPER_VIEW) != std::string::npos;
100 }
101 
GetVisibleLeashWindowCount() const102 uint32_t RSRenderNodeMap::GetVisibleLeashWindowCount() const
103 {
104     if (surfaceNodeMap_.empty()) {
105         return 0;
106     }
107 
108     return std::count_if(surfaceNodeMap_.begin(), surfaceNodeMap_.end(),
109         [](const auto& pair) -> bool {
110             return pair.second && pair.second->IsLeashWindowSurfaceNodeVisible();
111         });
112 }
113 
IsResidentProcessNode(NodeId id) const114 bool RSRenderNodeMap::IsResidentProcessNode(NodeId id) const
115 {
116     auto nodePid = ExtractPid(id);
117     return std::any_of(residentSurfaceNodeMap_.begin(), residentSurfaceNodeMap_.end(),
118         [nodePid](const auto& pair) -> bool { return ExtractPid(pair.first) == nodePid; });
119 }
120 
IsUIExtensionSurfaceNode(NodeId id) const121 bool RSRenderNodeMap::IsUIExtensionSurfaceNode(NodeId id) const
122 {
123     std::lock_guard<std::mutex> lock(uiExtensionSurfaceNodesMutex_);
124     return uiExtensionSurfaceNodes_.find(id) != uiExtensionSurfaceNodes_.end();
125 }
126 
AddUIExtensionSurfaceNode(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode)127 void RSRenderNodeMap::AddUIExtensionSurfaceNode(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode)
128 {
129     if (surfaceNode && surfaceNode->IsUIExtension()) {
130         std::lock_guard<std::mutex> lock(uiExtensionSurfaceNodesMutex_);
131         uiExtensionSurfaceNodes_.insert(surfaceNode->GetId());
132     }
133 }
134 
RemoveUIExtensionSurfaceNode(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode)135 void RSRenderNodeMap::RemoveUIExtensionSurfaceNode(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode)
136 {
137     if (surfaceNode && surfaceNode->IsUIExtension()) {
138         std::lock_guard<std::mutex> lock(uiExtensionSurfaceNodesMutex_);
139         uiExtensionSurfaceNodes_.erase(surfaceNode->GetId());
140     }
141 }
142 
RegisterRenderNode(const std::shared_ptr<RSBaseRenderNode> & nodePtr)143 bool RSRenderNodeMap::RegisterRenderNode(const std::shared_ptr<RSBaseRenderNode>& nodePtr)
144 {
145     NodeId id = nodePtr->GetId();
146     if (renderNodeMap_.count(id)) {
147         return false;
148     }
149     renderNodeMap_.emplace(id, nodePtr);
150     nodePtr->OnRegister(context_);
151     if (nodePtr->GetType() == RSRenderNodeType::SURFACE_NODE) {
152         auto surfaceNode = nodePtr->ReinterpretCastTo<RSSurfaceRenderNode>();
153         surfaceNodeMap_.emplace(id, surfaceNode);
154         if (IsResidentProcess(surfaceNode)) {
155             residentSurfaceNodeMap_.emplace(id, surfaceNode);
156         }
157         AddUIExtensionSurfaceNode(surfaceNode);
158         ObtainLauncherNodeId(surfaceNode);
159         ObtainScreenLockWindowNodeId(surfaceNode);
160     } else if (nodePtr->GetType() == RSRenderNodeType::CANVAS_DRAWING_NODE) {
161         auto canvasDrawingNode = nodePtr->ReinterpretCastTo<RSCanvasDrawingRenderNode>();
162         canvasDrawingNodeMap_.emplace(id, canvasDrawingNode);
163     }
164     return true;
165 }
166 
RegisterDisplayRenderNode(const std::shared_ptr<RSDisplayRenderNode> & nodePtr)167 bool RSRenderNodeMap::RegisterDisplayRenderNode(const std::shared_ptr<RSDisplayRenderNode>& nodePtr)
168 {
169     NodeId id = nodePtr->GetId();
170     if (renderNodeMap_.count(id)) {
171         return false;
172     }
173     renderNodeMap_.emplace(id, nodePtr);
174     displayNodeMap_.emplace(id, nodePtr);
175     nodePtr->OnRegister(context_);
176     return true;
177 }
178 
UnregisterRenderNode(NodeId id)179 void RSRenderNodeMap::UnregisterRenderNode(NodeId id)
180 {
181     // temp solution to address the dma leak
182     auto it = surfaceNodeMap_.find(id);
183     if (it != surfaceNodeMap_.end()) {
184         if (it->second->GetName().find("ShellAssistantAnco") == std::string::npos) {
185             renderNodeMap_.erase(id);
186         }
187         RemoveUIExtensionSurfaceNode(it->second);
188     } else {
189         renderNodeMap_.erase(id);
190     }
191     renderNodeMap_.erase(id);
192     surfaceNodeMap_.erase(id);
193     residentSurfaceNodeMap_.erase(id);
194     displayNodeMap_.erase(id);
195     canvasDrawingNodeMap_.erase(id);
196     purgeableNodeMap_.erase(id);
197 }
198 
MoveRenderNodeMap(std::shared_ptr<std::unordered_map<NodeId,std::shared_ptr<RSBaseRenderNode>>> subRenderNodeMap,pid_t pid)199 void RSRenderNodeMap::MoveRenderNodeMap(
200     std::shared_ptr<std::unordered_map<NodeId, std::shared_ptr<RSBaseRenderNode>>> subRenderNodeMap, pid_t pid)
201 {
202     std::unordered_map<NodeId, std::shared_ptr<RSBaseRenderNode>>::iterator iter = renderNodeMap_.begin();
203     for (; iter != renderNodeMap_.end();) {
204         if (ExtractPid(iter->first) != pid) {
205             ++iter;
206             continue;
207         }
208         // remove node from tree
209         iter->second->RemoveFromTree(false);
210         subRenderNodeMap->emplace(iter->first, iter->second);
211         iter = renderNodeMap_.erase(iter);
212     }
213 }
214 
FilterNodeByPid(pid_t pid)215 void RSRenderNodeMap::FilterNodeByPid(pid_t pid)
216 {
217     ROSEN_LOGD("RSRenderNodeMap::FilterNodeByPid removing all nodes belong to pid %{public}llu",
218         (unsigned long long)pid);
219     bool useBatchRemoving =
220         RSUniRenderJudgement::IsUniRender() && RSSystemProperties::GetBatchRemovingOnRemoteDiedEnabled();
221     // remove all nodes belong to given pid (by matching higher 32 bits of node id)
222     EraseIf(renderNodeMap_, [pid, useBatchRemoving](const auto& pair) -> bool {
223         if (ExtractPid(pair.first) != pid) {
224             return false;
225         }
226         if (pair.second == nullptr) {
227             return true;
228         }
229         if (useBatchRemoving) {
230             RSRenderNodeGC::Instance().AddToOffTreeNodeBucket(pair.second);
231         } else {
232             if (auto parent = pair.second->GetParent().lock()) {
233                 parent->RemoveChildFromFulllist(pair.second->GetId());
234             }
235             pair.second->RemoveFromTree(false);
236         }
237         pair.second->GetAnimationManager().FilterAnimationByPid(pid);
238         return true;
239     });
240 
241     EraseIf(surfaceNodeMap_, [pid, useBatchRemoving, this](const auto& pair) -> bool {
242         bool shouldErase = (ExtractPid(pair.first) == pid);
243         if (shouldErase) {
244             RemoveUIExtensionSurfaceNode(pair.second);
245         }
246         if (shouldErase && pair.second && useBatchRemoving) {
247             if (auto parent = pair.second->GetParent().lock()) {
248                 parent->RemoveChildFromFulllist(pair.second->GetId());
249             }
250             pair.second->RemoveFromTree(false);
251         }
252         return shouldErase;
253     });
254 
255     EraseIf(residentSurfaceNodeMap_, [pid](const auto& pair) -> bool {
256         return ExtractPid(pair.first) == pid;
257     });
258 
259     EraseIf(canvasDrawingNodeMap_, [pid](const auto& pair) -> bool {
260         return ExtractPid(pair.first) == pid;
261     });
262 
263     EraseIf(displayNodeMap_, [pid](const auto& pair) -> bool {
264         if (ExtractPid(pair.first) != pid && pair.second) {
265             ROSEN_LOGD("RSRenderNodeMap::FilterNodeByPid removing all nodes belong to pid %{public}llu",
266                 (unsigned long long)pid);
267             pair.second->FilterModifiersByPid(pid);
268         }
269         return ExtractPid(pair.first) == pid;
270     });
271 
272     if (auto fallbackNode = GetAnimationFallbackNode()) {
273         // remove all fallback animations belong to given pid
274         fallbackNode->GetAnimationManager().FilterAnimationByPid(pid);
275     }
276 }
277 
TraversalNodes(std::function<void (const std::shared_ptr<RSBaseRenderNode> &)> func) const278 void RSRenderNodeMap::TraversalNodes(std::function<void (const std::shared_ptr<RSBaseRenderNode>&)> func) const
279 {
280     for (const auto& [_, node] : renderNodeMap_) {
281         func(node);
282     }
283 }
284 
TraverseCanvasDrawingNodes(std::function<void (const std::shared_ptr<RSCanvasDrawingRenderNode> &)> func) const285 void RSRenderNodeMap::TraverseCanvasDrawingNodes(
286     std::function<void(const std::shared_ptr<RSCanvasDrawingRenderNode>&)> func) const
287 {
288     for (const auto& [_, node] : canvasDrawingNodeMap_) {
289         func(node);
290     }
291 }
292 
TraverseSurfaceNodes(std::function<void (const std::shared_ptr<RSSurfaceRenderNode> &)> func) const293 void RSRenderNodeMap::TraverseSurfaceNodes(std::function<void (const std::shared_ptr<RSSurfaceRenderNode>&)> func) const
294 {
295     for (const auto& [_, node] : surfaceNodeMap_) {
296         func(node);
297     }
298 }
299 
ContainPid(pid_t pid) const300 bool RSRenderNodeMap::ContainPid(pid_t pid) const
301 {
302     return std::any_of(surfaceNodeMap_.begin(), surfaceNodeMap_.end(),
303         [pid](const auto& pair) -> bool { return ExtractPid(pair.first) == pid; });
304 }
305 
TraverseDisplayNodes(std::function<void (const std::shared_ptr<RSDisplayRenderNode> &)> func) const306 void RSRenderNodeMap::TraverseDisplayNodes(std::function<void (const std::shared_ptr<RSDisplayRenderNode>&)> func) const
307 {
308     for (const auto& [_, node] : displayNodeMap_) {
309         func(node);
310     }
311 }
312 
GetResidentSurfaceNodeMap() const313 const ResidentSurfaceNodeMap& RSRenderNodeMap::GetResidentSurfaceNodeMap() const
314 {
315     return residentSurfaceNodeMap_;
316 }
317 
318 template<>
GetRenderNode(NodeId id) const319 const std::shared_ptr<RSBaseRenderNode> RSRenderNodeMap::GetRenderNode(NodeId id) const
320 {
321     auto itr = renderNodeMap_.find(id);
322     if (itr == renderNodeMap_.end()) {
323         return nullptr;
324     }
325     return itr->second;
326 }
327 
GetAnimationFallbackNode() const328 const std::shared_ptr<RSRenderNode> RSRenderNodeMap::GetAnimationFallbackNode() const
329 {
330     auto itr = renderNodeMap_.find(0);
331     if (itr == renderNodeMap_.end()) {
332         return nullptr;
333     }
334     return itr->second;
335 }
336 
AddOffTreeNode(NodeId nodeId)337 void RSRenderNodeMap::AddOffTreeNode(NodeId nodeId)
338 {
339     purgeableNodeMap_.insert(std::pair(nodeId, true));
340 }
341 
RemoveOffTreeNode(NodeId nodeId)342 void RSRenderNodeMap::RemoveOffTreeNode(NodeId nodeId)
343 {
344     purgeableNodeMap_.insert(std::pair(nodeId, false));
345 }
346 
GetAndClearPurgeableNodeIds()347 std::unordered_map<NodeId, bool>&& RSRenderNodeMap::GetAndClearPurgeableNodeIds()
348 {
349     return std::move(purgeableNodeMap_);
350 }
351 
GetSelfDrawSurfaceNameByPid(pid_t nodePid) const352 const std::string RSRenderNodeMap::GetSelfDrawSurfaceNameByPid(pid_t nodePid) const
353 {
354     for (auto &t : surfaceNodeMap_) {
355         if (ExtractPid(t.first) == nodePid && t.second->IsSelfDrawingType()) {
356             return t.second->GetName();
357         }
358     }
359     ROSEN_LOGD("RSRenderNodeMap::GetSurfaceNameByPid no self drawing nodes belong to pid %{public}d",
360         static_cast<int32_t>(nodePid));
361     return "";
362 }
363 
364 } // namespace Rosen
365 } // namespace OHOS
366