1 /*
2  * Copyright (c) 2021-2022 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_node_map.h"
17 
18 #include <atomic>
19 
20 #include "ui/rs_base_node.h"
21 #include "ui/rs_canvas_node.h"
22 #include "platform/common/rs_log.h"
23 
24 namespace OHOS {
25 namespace Rosen {
26 namespace {
27 static std::atomic_bool g_instance_valid = false;
28 }
29 
RSNodeMap()30 RSNodeMap::RSNodeMap()
31 {
32     // create animation fallback node
33     auto fallback_node = new RSCanvasNode(false);
34     fallback_node->SetId(0);
35     animationFallbackNode_.reset(fallback_node);
36     nodeMap_.emplace(0, animationFallbackNode_);
37     g_instance_valid.store(true);
38 }
39 
~RSNodeMap()40 RSNodeMap::~RSNodeMap()  noexcept
41 {
42     animationFallbackNode_ = nullptr;
43     std::unique_lock<std::mutex> lock(mutex_);
44     nodeMap_.clear();
45     g_instance_valid.store(false);
46 }
47 
MutableInstance()48 RSNodeMap& RSNodeMap::MutableInstance()
49 {
50     static RSNodeMap nodeMap;
51     return nodeMap;
52 }
53 
Instance()54 const RSNodeMap& RSNodeMap::Instance()
55 {
56     return MutableInstance();
57 }
58 
RegisterNode(const RSBaseNode::SharedPtr & nodePtr)59 bool RSNodeMap::RegisterNode(const RSBaseNode::SharedPtr& nodePtr)
60 {
61     std::unique_lock<std::mutex> lock(mutex_);
62     NodeId id = nodePtr->GetId();
63     auto itr = nodeMap_.find(id);
64     if (itr != nodeMap_.end()) {
65         ROSEN_LOGW("RSNodeMap::RegisterNode: node id %{public}" PRIu64 " already exists", id);
66         return false;
67     }
68     RSBaseNode::WeakPtr ptr(nodePtr);
69     nodeMap_.emplace(id, ptr);
70     return true;
71 }
72 
RegisterNodeInstanceId(NodeId id,int32_t instanceId)73 bool RSNodeMap::RegisterNodeInstanceId(NodeId id, int32_t instanceId)
74 {
75     std::unique_lock<std::mutex> lock(mutex_);
76     nodeIdMap_.emplace(id, instanceId);
77     return true;
78 }
79 
UnregisterNode(NodeId id)80 void RSNodeMap::UnregisterNode(NodeId id)
81 {
82     if (!g_instance_valid.load()) {
83         return;
84     }
85     std::unique_lock<std::mutex> lock(mutex_);
86     auto itr = nodeMap_.find(id);
87     if (itr != nodeMap_.end()) {
88         nodeIdMap_.erase(id);
89         nodeMap_.erase(itr);
90     } else {
91         ROSEN_LOGW("RSNodeMap::UnregisterNode: node id %{public}" PRIu64 " not found", id);
92     }
93 }
94 
RegisterAnimationInstanceId(AnimationId animId,NodeId id,int32_t instanceId)95 bool RSNodeMap::RegisterAnimationInstanceId(AnimationId animId, NodeId id, int32_t instanceId)
96 {
97     std::unique_lock<std::mutex> lock(mutex_);
98     animationNodeIdInstanceIdMap_.emplace(animId, std::make_pair(id, instanceId));
99     return true;
100 }
101 
UnregisterAnimation(AnimationId animId)102 void RSNodeMap::UnregisterAnimation(AnimationId animId)
103 {
104     if (!g_instance_valid.load()) {
105         return;
106     }
107     std::unique_lock<std::mutex> lock(mutex_);
108     animationNodeIdInstanceIdMap_.erase(animId);
109 }
110 
111 template<>
112 const std::shared_ptr<RSBaseNode> RSNodeMap::GetNode<RSBaseNode>(NodeId id) const
113 {
114     if (!g_instance_valid.load()) {
115         return nullptr;
116     }
117     std::unique_lock<std::mutex> lock(mutex_);
118     auto itr = nodeMap_.find(id);
119     if (itr == nodeMap_.end()) {
120         return nullptr;
121     }
122     return itr->second.lock();
123 }
124 
GetNodeInstanceId(NodeId id) const125 int32_t RSNodeMap::GetNodeInstanceId(NodeId id) const
126 {
127     if (!g_instance_valid.load()) {
128         return INSTANCE_ID_UNDEFINED;
129     }
130     std::unique_lock<std::mutex> lock(mutex_);
131     auto itr = nodeIdMap_.find(id);
132     if (itr == nodeIdMap_.end()) {
133         return INSTANCE_ID_UNDEFINED;
134     }
135     return itr->second;
136 }
137 
GetInstanceIdForReleasedNode(NodeId id) const138 int32_t RSNodeMap::GetInstanceIdForReleasedNode(NodeId id) const
139 {
140     if (!g_instance_valid.load()) {
141         return INSTANCE_ID_UNDEFINED;
142     }
143     std::unique_lock<std::mutex> lock(mutex_);
144     for (const auto& [animId, node] : animationNodeIdInstanceIdMap_) {
145         if (node.first == id) {
146             return node.second;
147         }
148     }
149     return INSTANCE_ID_UNDEFINED;
150 }
151 
GetAnimationFallbackNode() const152 const std::shared_ptr<RSNode> RSNodeMap::GetAnimationFallbackNode() const
153 {
154     return animationFallbackNode_;
155 }
156 
157 } // namespace Rosen
158 } // namespace OHOS
159