• 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 "params/rs_render_params.h"
19 #include "pipeline/rs_canvas_drawing_render_node.h"
20 #include "pipeline/rs_render_node.h"
21 #include "pipeline/rs_screen_render_node.h"
22 #include "pipeline/rs_logical_display_render_node.h"
23 #include "pipeline/rs_render_node_gc.h"
24 #include "pipeline/rs_surface_render_node.h"
25 #include "platform/common/rs_log.h"
26 #include "gfx/fps_info/rs_surface_fps_manager.h"
27 
28 namespace OHOS {
29 namespace Rosen {
30 
31 using ResidentSurfaceNodeMap = std::unordered_map<NodeId, std::shared_ptr<RSSurfaceRenderNode>>;
32 
RSRenderNodeMap()33 RSRenderNodeMap::RSRenderNodeMap()
34 {
35     // add animation fallback node, NOTE: this is different from RSContext::globalRootRenderNode_
36     renderNodeMap_[0][0] = std::make_shared<RSBaseRenderNode>(0);
37     renderNodeMap_[0][0]->stagingRenderParams_ = std::make_unique<RSRenderParams>(0);
38 }
39 
Initialize(const std::weak_ptr<RSContext> & context)40 void RSRenderNodeMap::Initialize(const std::weak_ptr<RSContext>& context)
41 {
42     context_ = context;
43 }
44 
ObtainLauncherNodeId(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode)45 void RSRenderNodeMap::ObtainLauncherNodeId(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode)
46 {
47     if (surfaceNode == nullptr) {
48         return;
49     }
50     if (surfaceNode->GetSurfaceWindowType() == SurfaceWindowType::SCB_DESKTOP) {
51         entryViewNodeId_ = surfaceNode->GetId();
52     }
53     if (surfaceNode->GetSurfaceWindowType() == SurfaceWindowType::SCB_WALLPAPER) {
54         wallpaperViewNodeId_ = surfaceNode->GetId();
55     }
56     if (surfaceNode->GetSurfaceWindowType() == SurfaceWindowType::SCB_NEGATIVE_SCREEN) {
57         negativeScreenNodeId_ = surfaceNode->GetId();
58     }
59 }
60 
ObtainScreenLockWindowNodeId(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode)61 void RSRenderNodeMap::ObtainScreenLockWindowNodeId(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode)
62 {
63     if (surfaceNode == nullptr) {
64         return;
65     }
66     if (surfaceNode->GetSurfaceWindowType() == SurfaceWindowType::SCB_SCREEN_LOCK) {
67         screenLockWindowNodeId_ = surfaceNode->GetId();
68     }
69 }
70 
GetEntryViewNodeId() const71 NodeId RSRenderNodeMap::GetEntryViewNodeId() const
72 {
73     return entryViewNodeId_;
74 }
75 
GetWallPaperViewNodeId() const76 NodeId RSRenderNodeMap::GetWallPaperViewNodeId() const
77 {
78     return wallpaperViewNodeId_;
79 }
80 
GetScreenLockWindowNodeId() const81 NodeId RSRenderNodeMap::GetScreenLockWindowNodeId() const
82 {
83     return screenLockWindowNodeId_;
84 }
85 
GetNegativeScreenNodeId() const86 NodeId RSRenderNodeMap::GetNegativeScreenNodeId() const
87 {
88     return negativeScreenNodeId_;
89 }
90 
IsResidentProcess(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode)91 static bool IsResidentProcess(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode)
92 {
93     switch (surfaceNode->GetSurfaceWindowType()) {
94         case SurfaceWindowType::SCB_DESKTOP:
95         case SurfaceWindowType::SCB_DROPDOWN_PANEL:
96         case SurfaceWindowType::SCB_SCREEN_LOCK:
97         case SurfaceWindowType::SCB_WALLPAPER:
98             return true;
99         default:
100             return false;
101     }
102 }
103 
GetVisibleLeashWindowCount() const104 uint32_t RSRenderNodeMap::GetVisibleLeashWindowCount() const
105 {
106     if (surfaceNodeMap_.empty()) {
107         return 0;
108     }
109 
110     return std::count_if(surfaceNodeMap_.begin(), surfaceNodeMap_.end(),
111         [](const auto& pair) -> bool {
112             return pair.second && pair.second->IsLeashWindowSurfaceNodeVisible();
113         });
114 }
115 
GetSize() const116 uint64_t RSRenderNodeMap::GetSize() const
117 {
118     size_t mapSize = 0;
119     for (const auto& [_, subMap] : renderNodeMap_) {
120         mapSize += subMap.size();
121     }
122     return static_cast<uint64_t>(mapSize);
123 }
124 
IsResidentProcessNode(NodeId id) const125 bool RSRenderNodeMap::IsResidentProcessNode(NodeId id) const
126 {
127     auto nodePid = ExtractPid(id);
128     return std::any_of(residentSurfaceNodeMap_.begin(), residentSurfaceNodeMap_.end(),
129         [nodePid](const auto& pair) -> bool { return ExtractPid(pair.first) == nodePid; });
130 }
131 
IsUIExtensionSurfaceNode(NodeId id) const132 bool RSRenderNodeMap::IsUIExtensionSurfaceNode(NodeId id) const
133 {
134     std::lock_guard<std::mutex> lock(uiExtensionSurfaceNodesMutex_);
135     return uiExtensionSurfaceNodes_.find(id) != uiExtensionSurfaceNodes_.end();
136 }
137 
AddUIExtensionSurfaceNode(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode)138 void RSRenderNodeMap::AddUIExtensionSurfaceNode(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode)
139 {
140     if (surfaceNode && surfaceNode->IsUIExtension()) {
141         std::lock_guard<std::mutex> lock(uiExtensionSurfaceNodesMutex_);
142         uiExtensionSurfaceNodes_.insert(surfaceNode->GetId());
143     }
144 }
145 
RemoveUIExtensionSurfaceNode(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode)146 void RSRenderNodeMap::RemoveUIExtensionSurfaceNode(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode)
147 {
148     if (surfaceNode && surfaceNode->IsUIExtension()) {
149         std::lock_guard<std::mutex> lock(uiExtensionSurfaceNodesMutex_);
150         uiExtensionSurfaceNodes_.erase(surfaceNode->GetId());
151     }
152 }
153 
RegisterRenderNode(const std::shared_ptr<RSBaseRenderNode> & nodePtr)154 bool RSRenderNodeMap::RegisterRenderNode(const std::shared_ptr<RSBaseRenderNode>& nodePtr)
155 {
156     NodeId id = nodePtr->GetId();
157     pid_t pid = ExtractPid(id);
158     if (!(renderNodeMap_[pid].insert({ id, nodePtr })).second) {
159         ROSEN_LOGE("RegisterRenderNode insert to Map failed, pid:%{public}d, nodeId:%{public}" PRIu64 " ", static_cast<int32_t>(pid), id);
160         return false;
161     }
162     nodePtr->OnRegister(context_);
163     if (nodePtr->GetType() == RSRenderNodeType::SURFACE_NODE) {
164         auto surfaceNode = nodePtr->ReinterpretCastTo<RSSurfaceRenderNode>();
165         surfaceNodeMap_.emplace(id, surfaceNode);
166         if (IsResidentProcess(surfaceNode)) {
167             residentSurfaceNodeMap_.emplace(id, surfaceNode);
168         }
169         AddUIExtensionSurfaceNode(surfaceNode);
170         ObtainLauncherNodeId(surfaceNode);
171         ObtainScreenLockWindowNodeId(surfaceNode);
172         if (surfaceNode->IsSelfDrawingType()) {
173             RSSurfaceFpsManager::GetInstance().RegisterSurfaceFps(id, surfaceNode->GetName());
174         }
175     } else if (nodePtr->GetType() == RSRenderNodeType::CANVAS_DRAWING_NODE) {
176         auto canvasDrawingNode = nodePtr->ReinterpretCastTo<RSCanvasDrawingRenderNode>();
177         canvasDrawingNodeMap_.emplace(id, canvasDrawingNode);
178     } else if (nodePtr->GetType() == RSRenderNodeType::LOGICAL_DISPLAY_NODE) {
179         auto logicalDisplayNode = nodePtr->ReinterpretCastTo<RSLogicalDisplayRenderNode>();
180         logicalDisplayNodeMap_.emplace(id, logicalDisplayNode);
181     } else if (nodePtr->GetType() == RSRenderNodeType::SCREEN_NODE) {
182         auto screenNode = nodePtr->ReinterpretCastTo<RSScreenRenderNode>();
183         screenNodeMap_.emplace(id, screenNode);
184     }
185     return true;
186 }
187 
RegisterUnTreeNode(NodeId id)188 void RSRenderNodeMap::RegisterUnTreeNode(NodeId id)
189 {
190     unInTreeNodeSet_.emplace(id);
191 }
192 
UnRegisterUnTreeNode(NodeId id)193 bool RSRenderNodeMap::UnRegisterUnTreeNode(NodeId id)
194 {
195     auto iter = unInTreeNodeSet_.find(id);
196     if (iter != unInTreeNodeSet_.end()) {
197         unInTreeNodeSet_.erase(iter);
198         return true;
199     }
200     return false;
201 }
202 
UnregisterRenderNode(NodeId id)203 void RSRenderNodeMap::UnregisterRenderNode(NodeId id)
204 {
205     pid_t pid = ExtractPid(id);
206     auto iter = renderNodeMap_.find(pid);
207     if (iter != renderNodeMap_.end()) {
208         auto& subMap = iter->second;
209         subMap.erase(id);
210         if (subMap.empty()) {
211             renderNodeMap_.erase(iter);
212         }
213     }
214 
215     auto it = surfaceNodeMap_.find(id);
216     if (it != surfaceNodeMap_.end()) {
217         RemoveUIExtensionSurfaceNode(it->second);
218         surfaceNodeMap_.erase(id);
219         RSSurfaceFpsManager::GetInstance().UnregisterSurfaceFps(id);
220     }
221     residentSurfaceNodeMap_.erase(id);
222     screenNodeMap_.erase(id);
223     logicalDisplayNodeMap_.erase(id);
224     canvasDrawingNodeMap_.erase(id);
225 }
226 
MoveRenderNodeMap(std::shared_ptr<std::unordered_map<NodeId,std::shared_ptr<RSBaseRenderNode>>> subRenderNodeMap,pid_t pid)227 void RSRenderNodeMap::MoveRenderNodeMap(
228     std::shared_ptr<std::unordered_map<NodeId, std::shared_ptr<RSBaseRenderNode>>> subRenderNodeMap, pid_t pid)
229 {
230     if (!subRenderNodeMap) {
231         return;
232     }
233     auto iter = renderNodeMap_.find(pid);
234     if (iter != renderNodeMap_.end()) {
235         auto& subMap = iter->second;
236         // remove node from tree
237         for (auto subIter = subMap.begin(); subIter != subMap.end();) {
238             subIter->second->RemoveFromTree(false);
239             subRenderNodeMap->emplace(subIter->first, subIter->second);
240             subIter = subMap.erase(subIter);
241         }
242         renderNodeMap_.erase(iter);
243     }
244 }
245 
FilterNodeByPid(pid_t pid,bool immediate)246 void RSRenderNodeMap::FilterNodeByPid(pid_t pid, bool immediate)
247 {
248     ROSEN_LOGD("RSRenderNodeMap::FilterNodeByPid removing all nodes belong to pid %{public}llu",
249         (unsigned long long)pid);
250     bool useBatchRemoving = !immediate &&
251         RSUniRenderJudgement::IsUniRender() && RSSystemProperties::GetBatchRemovingOnRemoteDiedEnabled();
252     bool optMode = RSSystemProperties::GetOptBatchRemovingOnRemoteDiedEnabled();
253     // remove all nodes belong to given pid (by matching higher 32 bits of node id)
254     auto iter = renderNodeMap_.find(pid);
255     if (iter != renderNodeMap_.end()) {
256         auto& subMap = iter->second;
257         for (auto subIter = subMap.begin(); subIter != subMap.end();) {
258             if (subIter->second == nullptr) {
259                 subIter = subMap.erase(subIter);
260                 continue;
261             }
262             if (optMode && useBatchRemoving) {
263                 RSRenderNodeGC::Instance().AddToOffTreeNodeBucket(iter->first, iter->second);
264                 break;
265             }
266             if (useBatchRemoving) {
267                 RSRenderNodeGC::Instance().AddToOffTreeNodeBucket(subIter->second);
268             } else if (auto parent = subIter->second->GetParent().lock()) {
269                 parent->RemoveChildFromFulllist(subIter->second->GetId());
270                 subIter->second->RemoveFromTree(false);
271             } else {
272                 subIter->second->RemoveFromTree(false);
273             }
274             subIter->second->GetAnimationManager().FilterAnimationByPid(pid);
275             subIter = subMap.erase(subIter);
276         }
277         renderNodeMap_.erase(iter);
278     }
279     EraseIf(surfaceNodeMap_, [pid, useBatchRemoving, this](const auto& pair) -> bool {
280         bool shouldErase = (ExtractPid(pair.first) == pid);
281         if (shouldErase) {
282             RSSurfaceFpsManager::GetInstance().UnregisterSurfaceFps(pair.first);
283             RemoveUIExtensionSurfaceNode(pair.second);
284         }
285         if (shouldErase && pair.second && useBatchRemoving) {
286             if (auto parent = pair.second->GetParent().lock()) {
287                 parent->RemoveChildFromFulllist(pair.second->GetId());
288             }
289             pair.second->RemoveFromTree(false);
290         }
291         return shouldErase;
292     });
293 
294     EraseIf(residentSurfaceNodeMap_, [pid](const auto& pair) -> bool {
295         return ExtractPid(pair.first) == pid;
296     });
297 
298     EraseIf(canvasDrawingNodeMap_, [pid](const auto& pair) -> bool {
299         return ExtractPid(pair.first) == pid;
300     });
301 
302     EraseIf(selfDrawingNodeInProcess_, [pid](const auto& pair) -> bool {
303         return pair.first == pid;
304     });
305 
306     EraseIf(logicalDisplayNodeMap_, [pid](const auto& pair) -> bool {
307         if (ExtractPid(pair.first) != pid && pair.second) {
308             ROSEN_LOGD("RSRenderNodeMap::FilterNodeByPid removing all nodes belong to pid %{public}llu",
309                 (unsigned long long)pid);
310             pair.second->FilterModifiersByPid(pid);
311         }
312         return ExtractPid(pair.first) == pid;
313     });
314 
315     EraseIf(unInTreeNodeSet_, [pid](const auto& nodeId) -> bool {
316         return ExtractPid(nodeId) == pid;
317     });
318 
319     if (auto fallbackNode = GetAnimationFallbackNode()) {
320         // remove all fallback animations belong to given pid
321         fallbackNode->GetAnimationManager().FilterAnimationByPid(pid);
322     }
323 }
324 
TraversalNodes(std::function<void (const std::shared_ptr<RSBaseRenderNode> &)> func) const325 void RSRenderNodeMap::TraversalNodes(std::function<void (const std::shared_ptr<RSBaseRenderNode>&)> func) const
326 {
327     for (const auto& [_, subMap] : renderNodeMap_) {
328         for (const auto& [_, node] : subMap) {
329             func(node);
330         }
331     }
332 }
333 
TraversalNodesByPid(int pid,std::function<void (const std::shared_ptr<RSBaseRenderNode> &)> func) const334 void RSRenderNodeMap::TraversalNodesByPid(int pid,
335     std::function<void (const std::shared_ptr<RSBaseRenderNode>&)> func) const
336 {
337     const auto& itr = renderNodeMap_.find(pid);
338     if (itr != renderNodeMap_.end()) {
339         for (const auto& [_, node] : itr->second) {
340             func(node);
341         }
342     }
343 }
344 
TraverseCanvasDrawingNodes(std::function<void (const std::shared_ptr<RSCanvasDrawingRenderNode> &)> func) const345 void RSRenderNodeMap::TraverseCanvasDrawingNodes(
346     std::function<void(const std::shared_ptr<RSCanvasDrawingRenderNode>&)> func) const
347 {
348     for (const auto& [_, node] : canvasDrawingNodeMap_) {
349         func(node);
350     }
351 }
352 
TraverseSurfaceNodes(std::function<void (const std::shared_ptr<RSSurfaceRenderNode> &)> func) const353 void RSRenderNodeMap::TraverseSurfaceNodes(std::function<void (const std::shared_ptr<RSSurfaceRenderNode>&)> func) const
354 {
355     for (const auto& [_, node] : surfaceNodeMap_) {
356         func(node);
357     }
358 }
359 
TraverseSurfaceNodesBreakOnCondition(std::function<bool (const std::shared_ptr<RSSurfaceRenderNode> &)> func) const360 void RSRenderNodeMap::TraverseSurfaceNodesBreakOnCondition(
361     std::function<bool (const std::shared_ptr<RSSurfaceRenderNode>&)> func) const
362 {
363     for (const auto& [_, node] : surfaceNodeMap_) {
364         if (func(node)) {
365             break;
366         }
367     }
368 }
369 
ContainPid(pid_t pid) const370 bool RSRenderNodeMap::ContainPid(pid_t pid) const
371 {
372     return std::any_of(surfaceNodeMap_.begin(), surfaceNodeMap_.end(),
373         [pid](const auto& pair) -> bool { return ExtractPid(pair.first) == pid; });
374 }
375 
TraverseScreenNodes(std::function<void (const std::shared_ptr<RSScreenRenderNode> &)> func) const376 void RSRenderNodeMap::TraverseScreenNodes(std::function<void (const std::shared_ptr<RSScreenRenderNode>&)> func) const
377 {
378     for (const auto& [_, node] : screenNodeMap_) {
379         func(node);
380     }
381 }
382 
TraverseLogicalDisplayNodes(std::function<void (const std::shared_ptr<RSLogicalDisplayRenderNode> &)> func) const383 void RSRenderNodeMap::TraverseLogicalDisplayNodes(
384     std::function<void (const std::shared_ptr<RSLogicalDisplayRenderNode>&)> func) const
385 {
386     for (const auto& [_, node] : logicalDisplayNodeMap_) {
387         func(node);
388     }
389 }
390 
GetResidentSurfaceNodeMap() const391 const ResidentSurfaceNodeMap& RSRenderNodeMap::GetResidentSurfaceNodeMap() const
392 {
393     return residentSurfaceNodeMap_;
394 }
395 
396 template<>
GetRenderNode(NodeId id) const397 const std::shared_ptr<RSBaseRenderNode> RSRenderNodeMap::GetRenderNode(NodeId id) const
398 {
399     pid_t pid = ExtractPid(id);
400     auto iter = renderNodeMap_.find(pid);
401     if (iter != renderNodeMap_.end()) {
402         auto subIter = (iter->second).find(id);
403         if (subIter != (iter->second).end()) {
404             return subIter->second;
405         }
406     }
407     return nullptr;
408 }
409 
GetAnimationFallbackNode() const410 const std::shared_ptr<RSRenderNode> RSRenderNodeMap::GetAnimationFallbackNode() const
411 {
412     auto iter = renderNodeMap_.find(0);
413     if (iter != renderNodeMap_.cend()) {
414         if (auto subIter = iter->second.find(0); subIter != iter->second.end()) {
415             return subIter->second;
416         }
417     }
418     return nullptr;
419 }
420 
GetSelfDrawingNodeInProcess(pid_t pid)421 std::vector<NodeId> RSRenderNodeMap::GetSelfDrawingNodeInProcess(pid_t pid)
422 {
423     std::vector<NodeId> selfDrawingNodes;
424     std::vector<NodeId> sortedSelfDrawingNodes;
425     std::map<NodeId, std::shared_ptr<RSBaseRenderNode>> instanceNodeMap;
426     auto iter = renderNodeMap_.find(pid);
427     std::shared_ptr<RSBaseRenderNode> instanceRootNode;
428 
429     if (iter == renderNodeMap_.end()) {
430         return selfDrawingNodes;
431     }
432     for (auto subIter = iter->second.begin(); subIter != iter->second.end(); ++subIter) {
433         if (!subIter->second) {
434             continue;
435         }
436         auto surfaceNode = subIter->second->ReinterpretCastTo<RSSurfaceRenderNode>();
437         if (surfaceNode && surfaceNode->IsSelfDrawingType() && surfaceNode->IsOnTheTree()) {
438             selfDrawingNodes.push_back(surfaceNode->GetId());
439             auto rootNode = surfaceNode->GetInstanceRootNode();
440             if (rootNode) {
441                 instanceNodeMap.insert({ rootNode->GetId(), rootNode });
442             }
443         }
444     }
445 
446     if (selfDrawingNodes.size() <= 1) {
447         return selfDrawingNodes;
448     }
449 
450     std::vector<std::shared_ptr<RSSurfaceRenderNode>> instanceNodeVector;
451     for (const auto& pair : instanceNodeMap) {
452         auto node = pair.second->ReinterpretCastTo<RSSurfaceRenderNode>();
453         if (node && node->IsAppWindow()) {
454             instanceNodeVector.push_back(node);
455         } else {
456             return selfDrawingNodes;
457         }
458     }
459 
460     std::stable_sort(
461         instanceNodeVector.begin(), instanceNodeVector.end(), [](const auto& first, const auto& second) -> bool {
462         return first->GetAppWindowZOrder() < second->GetAppWindowZOrder();
463     });
464 
465     for (const auto& instanceNode : instanceNodeVector) {
466         instanceNode->CollectSelfDrawingChild(instanceNode, sortedSelfDrawingNodes);
467     }
468     return sortedSelfDrawingNodes;
469 }
470 
GetSelfDrawSurfaceNameByPid(pid_t nodePid) const471 const std::string RSRenderNodeMap::GetSelfDrawSurfaceNameByPid(pid_t nodePid) const
472 {
473     for (auto &t : surfaceNodeMap_) {
474         if (ExtractPid(t.first) == nodePid && t.second->IsSelfDrawingType() && !t.second->IsRosenWeb()) {
475             return t.second->GetName();
476         }
477     }
478     ROSEN_LOGD("RSRenderNodeMap::GetSurfaceNameByPid no self drawing nodes belong to pid %{public}d",
479         static_cast<int32_t>(nodePid));
480     return "";
481 }
482 
483 } // namespace Rosen
484 } // namespace OHOS
485