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_[0][0] = std::make_shared<RSBaseRenderNode>(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 GetSize() const114 uint64_t RSRenderNodeMap::GetSize() const 115 { 116 size_t mapSize = 0; 117 for (const auto& [_, subMap] : renderNodeMap_) { 118 mapSize += subMap.size(); 119 } 120 return static_cast<uint64_t>(mapSize); 121 } 122 IsResidentProcessNode(NodeId id) const123 bool RSRenderNodeMap::IsResidentProcessNode(NodeId id) const 124 { 125 auto nodePid = ExtractPid(id); 126 return std::any_of(residentSurfaceNodeMap_.begin(), residentSurfaceNodeMap_.end(), 127 [nodePid](const auto& pair) -> bool { return ExtractPid(pair.first) == nodePid; }); 128 } 129 IsUIExtensionSurfaceNode(NodeId id) const130 bool RSRenderNodeMap::IsUIExtensionSurfaceNode(NodeId id) const 131 { 132 std::lock_guard<std::mutex> lock(uiExtensionSurfaceNodesMutex_); 133 return uiExtensionSurfaceNodes_.find(id) != uiExtensionSurfaceNodes_.end(); 134 } 135 AddUIExtensionSurfaceNode(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode)136 void RSRenderNodeMap::AddUIExtensionSurfaceNode(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode) 137 { 138 if (surfaceNode && surfaceNode->IsUIExtension()) { 139 std::lock_guard<std::mutex> lock(uiExtensionSurfaceNodesMutex_); 140 uiExtensionSurfaceNodes_.insert(surfaceNode->GetId()); 141 } 142 } 143 RemoveUIExtensionSurfaceNode(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode)144 void RSRenderNodeMap::RemoveUIExtensionSurfaceNode(const std::shared_ptr<RSSurfaceRenderNode> surfaceNode) 145 { 146 if (surfaceNode && surfaceNode->IsUIExtension()) { 147 std::lock_guard<std::mutex> lock(uiExtensionSurfaceNodesMutex_); 148 uiExtensionSurfaceNodes_.erase(surfaceNode->GetId()); 149 } 150 } 151 RegisterRenderNode(const std::shared_ptr<RSBaseRenderNode> & nodePtr)152 bool RSRenderNodeMap::RegisterRenderNode(const std::shared_ptr<RSBaseRenderNode>& nodePtr) 153 { 154 NodeId id = nodePtr->GetId(); 155 pid_t pid = ExtractPid(id); 156 if (!(renderNodeMap_[pid].insert({ id, nodePtr })).second) { 157 return false; 158 } 159 nodePtr->OnRegister(context_); 160 if (nodePtr->GetType() == RSRenderNodeType::SURFACE_NODE) { 161 auto surfaceNode = nodePtr->ReinterpretCastTo<RSSurfaceRenderNode>(); 162 surfaceNodeMap_.emplace(id, surfaceNode); 163 if (IsResidentProcess(surfaceNode)) { 164 residentSurfaceNodeMap_.emplace(id, surfaceNode); 165 } 166 AddUIExtensionSurfaceNode(surfaceNode); 167 ObtainLauncherNodeId(surfaceNode); 168 ObtainScreenLockWindowNodeId(surfaceNode); 169 } else if (nodePtr->GetType() == RSRenderNodeType::CANVAS_DRAWING_NODE) { 170 auto canvasDrawingNode = nodePtr->ReinterpretCastTo<RSCanvasDrawingRenderNode>(); 171 canvasDrawingNodeMap_.emplace(id, canvasDrawingNode); 172 } 173 return true; 174 } 175 RegisterDisplayRenderNode(const std::shared_ptr<RSDisplayRenderNode> & nodePtr)176 bool RSRenderNodeMap::RegisterDisplayRenderNode(const std::shared_ptr<RSDisplayRenderNode>& nodePtr) 177 { 178 NodeId id = nodePtr->GetId(); 179 pid_t pid = ExtractPid(id); 180 if (!(renderNodeMap_[pid].insert({ id, nodePtr })).second) { 181 return false; 182 } 183 displayNodeMap_.emplace(id, nodePtr); 184 nodePtr->OnRegister(context_); 185 return true; 186 } 187 UnregisterRenderNode(NodeId id)188 void RSRenderNodeMap::UnregisterRenderNode(NodeId id) 189 { 190 pid_t pid = ExtractPid(id); 191 auto it = surfaceNodeMap_.find(id); 192 if (it != surfaceNodeMap_.end()) { 193 if (it->second->GetName().find("ShellAssistantAnco") == std::string::npos) { 194 renderNodeMap_[pid].erase(id); 195 } 196 RemoveUIExtensionSurfaceNode(it->second); 197 surfaceNodeMap_.erase(id); 198 } 199 auto iter = renderNodeMap_.find(pid); 200 if (iter != renderNodeMap_.end()) { 201 iter->second.erase(id); 202 if (iter->second.empty()) { 203 renderNodeMap_.erase(iter); 204 } 205 } 206 residentSurfaceNodeMap_.erase(id); 207 displayNodeMap_.erase(id); 208 canvasDrawingNodeMap_.erase(id); 209 purgeableNodeMap_.erase(id); 210 } 211 MoveRenderNodeMap(std::shared_ptr<std::unordered_map<NodeId,std::shared_ptr<RSBaseRenderNode>>> subRenderNodeMap,pid_t pid)212 void RSRenderNodeMap::MoveRenderNodeMap( 213 std::shared_ptr<std::unordered_map<NodeId, std::shared_ptr<RSBaseRenderNode>>> subRenderNodeMap, pid_t pid) 214 { 215 if (!subRenderNodeMap) { 216 return; 217 } 218 auto iter = renderNodeMap_.find(pid); 219 if (iter != renderNodeMap_.end()) { 220 auto& subMap = iter->second; 221 // remove node from tree 222 for (auto subIter = subMap.begin(); subIter != subMap.end();) { 223 subIter->second->RemoveFromTree(false); 224 subRenderNodeMap->emplace(subIter->first, subIter->second); 225 subIter = subMap.erase(subIter); 226 } 227 renderNodeMap_.erase(iter); 228 } 229 } 230 FilterNodeByPid(pid_t pid)231 void RSRenderNodeMap::FilterNodeByPid(pid_t pid) 232 { 233 ROSEN_LOGD("RSRenderNodeMap::FilterNodeByPid removing all nodes belong to pid %{public}llu", 234 (unsigned long long)pid); 235 bool useBatchRemoving = 236 RSUniRenderJudgement::IsUniRender() && RSSystemProperties::GetBatchRemovingOnRemoteDiedEnabled(); 237 // remove all nodes belong to given pid (by matching higher 32 bits of node id) 238 auto iter = renderNodeMap_.find(pid); 239 if (iter != renderNodeMap_.end()) { 240 auto& subMap = iter->second; 241 for (auto subIter = subMap.begin(); subIter != subMap.end();) { 242 if (subIter->second == nullptr) { 243 subIter = subMap.erase(subIter); 244 continue; 245 } 246 if (useBatchRemoving) { 247 RSRenderNodeGC::Instance().AddToOffTreeNodeBucket(subIter->second); 248 } else if (auto parent = subIter->second->GetParent().lock()) { 249 parent->RemoveChildFromFulllist(subIter->second->GetId()); 250 subIter->second->RemoveFromTree(false); 251 } else { 252 subIter->second->RemoveFromTree(false); 253 } 254 subIter->second->GetAnimationManager().FilterAnimationByPid(pid); 255 subIter = subMap.erase(subIter); 256 } 257 renderNodeMap_.erase(iter); 258 } 259 EraseIf(surfaceNodeMap_, [pid, useBatchRemoving, this](const auto& pair) -> bool { 260 bool shouldErase = (ExtractPid(pair.first) == pid); 261 if (shouldErase) { 262 RemoveUIExtensionSurfaceNode(pair.second); 263 } 264 if (shouldErase && pair.second && useBatchRemoving) { 265 if (auto parent = pair.second->GetParent().lock()) { 266 parent->RemoveChildFromFulllist(pair.second->GetId()); 267 } 268 pair.second->RemoveFromTree(false); 269 } 270 return shouldErase; 271 }); 272 273 EraseIf(residentSurfaceNodeMap_, [pid](const auto& pair) -> bool { 274 return ExtractPid(pair.first) == pid; 275 }); 276 277 EraseIf(canvasDrawingNodeMap_, [pid](const auto& pair) -> bool { 278 return ExtractPid(pair.first) == pid; 279 }); 280 281 EraseIf(displayNodeMap_, [pid](const auto& pair) -> bool { 282 if (ExtractPid(pair.first) != pid && pair.second) { 283 ROSEN_LOGD("RSRenderNodeMap::FilterNodeByPid removing all nodes belong to pid %{public}llu", 284 (unsigned long long)pid); 285 pair.second->FilterModifiersByPid(pid); 286 } 287 return ExtractPid(pair.first) == pid; 288 }); 289 290 if (auto fallbackNode = GetAnimationFallbackNode()) { 291 // remove all fallback animations belong to given pid 292 fallbackNode->GetAnimationManager().FilterAnimationByPid(pid); 293 } 294 } 295 TraversalNodes(std::function<void (const std::shared_ptr<RSBaseRenderNode> &)> func) const296 void RSRenderNodeMap::TraversalNodes(std::function<void (const std::shared_ptr<RSBaseRenderNode>&)> func) const 297 { 298 for (const auto& [_, subMap] : renderNodeMap_) { 299 for (const auto& [_, node] : subMap) { 300 func(node); 301 } 302 } 303 } 304 TraverseCanvasDrawingNodes(std::function<void (const std::shared_ptr<RSCanvasDrawingRenderNode> &)> func) const305 void RSRenderNodeMap::TraverseCanvasDrawingNodes( 306 std::function<void(const std::shared_ptr<RSCanvasDrawingRenderNode>&)> func) const 307 { 308 for (const auto& [_, node] : canvasDrawingNodeMap_) { 309 func(node); 310 } 311 } 312 TraverseSurfaceNodes(std::function<void (const std::shared_ptr<RSSurfaceRenderNode> &)> func) const313 void RSRenderNodeMap::TraverseSurfaceNodes(std::function<void (const std::shared_ptr<RSSurfaceRenderNode>&)> func) const 314 { 315 for (const auto& [_, node] : surfaceNodeMap_) { 316 func(node); 317 } 318 } 319 ContainPid(pid_t pid) const320 bool RSRenderNodeMap::ContainPid(pid_t pid) const 321 { 322 return std::any_of(surfaceNodeMap_.begin(), surfaceNodeMap_.end(), 323 [pid](const auto& pair) -> bool { return ExtractPid(pair.first) == pid; }); 324 } 325 TraverseDisplayNodes(std::function<void (const std::shared_ptr<RSDisplayRenderNode> &)> func) const326 void RSRenderNodeMap::TraverseDisplayNodes(std::function<void (const std::shared_ptr<RSDisplayRenderNode>&)> func) const 327 { 328 for (const auto& [_, node] : displayNodeMap_) { 329 func(node); 330 } 331 } 332 GetResidentSurfaceNodeMap() const333 const ResidentSurfaceNodeMap& RSRenderNodeMap::GetResidentSurfaceNodeMap() const 334 { 335 return residentSurfaceNodeMap_; 336 } 337 338 template<> GetRenderNode(NodeId id) const339 const std::shared_ptr<RSBaseRenderNode> RSRenderNodeMap::GetRenderNode(NodeId id) const 340 { 341 pid_t pid = ExtractPid(id); 342 auto iter = renderNodeMap_.find(pid); 343 if (iter != renderNodeMap_.end()) { 344 auto subIter = (iter->second).find(id); 345 if (subIter != (iter->second).end()) { 346 return subIter->second; 347 } 348 } 349 return nullptr; 350 } 351 GetAnimationFallbackNode() const352 const std::shared_ptr<RSRenderNode> RSRenderNodeMap::GetAnimationFallbackNode() const 353 { 354 auto iter = renderNodeMap_.find(0); 355 if (iter != renderNodeMap_.cend()) { 356 if (auto subIter = iter->second.find(0); subIter != iter->second.end()) { 357 return subIter->second; 358 } 359 } 360 return nullptr; 361 } 362 AddOffTreeNode(NodeId nodeId)363 void RSRenderNodeMap::AddOffTreeNode(NodeId nodeId) 364 { 365 purgeableNodeMap_.insert(std::pair(nodeId, true)); 366 } 367 RemoveOffTreeNode(NodeId nodeId)368 void RSRenderNodeMap::RemoveOffTreeNode(NodeId nodeId) 369 { 370 purgeableNodeMap_.insert(std::pair(nodeId, false)); 371 } 372 GetAndClearPurgeableNodeIds()373 std::unordered_map<NodeId, bool>&& RSRenderNodeMap::GetAndClearPurgeableNodeIds() 374 { 375 return std::move(purgeableNodeMap_); 376 } 377 GetSelfDrawSurfaceNameByPid(pid_t nodePid) const378 const std::string RSRenderNodeMap::GetSelfDrawSurfaceNameByPid(pid_t nodePid) const 379 { 380 for (auto &t : surfaceNodeMap_) { 381 if (ExtractPid(t.first) == nodePid && t.second->IsSelfDrawingType()) { 382 return t.second->GetName(); 383 } 384 } 385 ROSEN_LOGD("RSRenderNodeMap::GetSurfaceNameByPid no self drawing nodes belong to pid %{public}d", 386 static_cast<int32_t>(nodePid)); 387 return ""; 388 } 389 390 } // namespace Rosen 391 } // namespace OHOS 392