1 /*
2 * Copyright (c) 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 "rs_rcd_render_manager.h"
17
18 #include <unordered_set>
19 #include "common/rs_optional_trace.h"
20 #include "common/rs_singleton.h"
21 #include "pipeline/parallel_render/rs_sub_thread_manager.h"
22 #include "pipeline/round_corner_display/rs_message_bus.h"
23 #include "pipeline/rs_uni_render_thread.h"
24 #include "platform/common/rs_log.h"
25 #include "rs_rcd_render_visitor.h"
26 #include "rs_round_corner_display_manager.h"
27
28 namespace OHOS {
29 namespace Rosen {
30 static std::unique_ptr<RSRcdRenderManager> g_rcdRenderManagerInstance =
31 std::make_unique<RSRcdRenderManager>();
32
GetInstance()33 RSRcdRenderManager& RSRcdRenderManager::GetInstance()
34 {
35 return *g_rcdRenderManagerInstance;
36 }
37
InitInstance()38 void RSRcdRenderManager::InitInstance()
39 {
40 g_rcdRenderManagerInstance->rcdRenderEnabled_ = true;
41 }
42
GetRcdRenderEnabled() const43 bool RSRcdRenderManager::GetRcdRenderEnabled() const
44 {
45 return rcdRenderEnabled_;
46 }
47
IsRcdProcessInfoValid(const RcdProcessInfo & info)48 bool RSRcdRenderManager::IsRcdProcessInfoValid(const RcdProcessInfo& info)
49 {
50 if (info.uniProcessor == nullptr) {
51 RS_LOGE("info uniProcessor is nullptr");
52 return false;
53 } else if (info.topLayer == nullptr || info.bottomLayer == nullptr) {
54 RS_LOGE("info toplayer or bottomlayer resource is nullptr");
55 return false;
56 }
57 return true;
58 }
59
CheckExist(NodeId id,const RSRenderNodeMap & map)60 bool RSRcdRenderManager::CheckExist(NodeId id, const RSRenderNodeMap& map)
61 {
62 const auto& node = map.GetRenderNode<RSDisplayRenderNode>(id);
63 if (node == nullptr) {
64 return false;
65 }
66 return true;
67 }
68
RemoveRcdResource(NodeId id)69 void RSRcdRenderManager::RemoveRcdResource(NodeId id)
70 {
71 // to remove the resource which rendertarget display node not exist
72 auto rmTask = [id, this]() {
73 {
74 std::lock_guard<std::mutex> lock(topNodeMapMut_);
75 topSurfaceNodeMap_.erase(id);
76 }
77 {
78 std::lock_guard<std::mutex> lock(bottomNodeMapMut_);
79 bottomSurfaceNodeMap_.erase(id);
80 }
81 RSSingleton<RoundCornerDisplayManager>::GetInstance().RemoveRCDResource(id);
82 RS_LOGI_IF(DEBUG_PIPELINE,
83 "[%{public}s] nodeId:%{public}" PRIu64 " not exist in nodeMap remove the rcd module \n",
84 __func__, id);
85 };
86 RSUniRenderThread::Instance().PostTask(rmTask);
87 }
88
CheckRenderTargetNode(const RSContext & context)89 void RSRcdRenderManager::CheckRenderTargetNode(const RSContext& context)
90 {
91 const auto& nodeMap = context.GetNodeMap();
92 std::unordered_set<NodeId> idSets;
93 {
94 std::lock_guard<std::mutex> lock(topNodeMapMut_);
95 for (const auto& p : topSurfaceNodeMap_) {
96 idSets.insert(p.first);
97 }
98 }
99 {
100 std::lock_guard<std::mutex> lock(bottomNodeMapMut_);
101 for (const auto& p : bottomSurfaceNodeMap_) {
102 idSets.insert(p.first);
103 }
104 }
105 for (auto it = idSets.begin(); it != idSets.end(); it++) {
106 if (!CheckExist(*it, nodeMap)) {
107 // to remove the resource which rendertarget display node not exist
108 RemoveRcdResource(*it);
109 } else {
110 RS_LOGD("[%{public}s] nodeId:%{public}" PRIu64 " detected in nodeMap \n", __func__, *it);
111 }
112 }
113 }
114
GetTopSurfaceNode(NodeId id)115 RSRcdSurfaceRenderNodePtr RSRcdRenderManager::GetTopSurfaceNode(NodeId id)
116 {
117 std::lock_guard<std::mutex> lock(topNodeMapMut_);
118 auto it = topSurfaceNodeMap_.find(id);
119 if (it != topSurfaceNodeMap_.end() && it->second != nullptr) {
120 return it->second;
121 }
122 return nullptr;
123 }
124
GetBottomSurfaceNode(NodeId id)125 RSRcdSurfaceRenderNodePtr RSRcdRenderManager::GetBottomSurfaceNode(NodeId id)
126 {
127 std::lock_guard<std::mutex> lock(bottomNodeMapMut_);
128 auto it = bottomSurfaceNodeMap_.find(id);
129 if (it != bottomSurfaceNodeMap_.end() && it->second != nullptr) {
130 return it->second;
131 }
132 return nullptr;
133 }
134
GetTopRenderNode(NodeId id)135 RSRcdSurfaceRenderNodePtr RSRcdRenderManager::GetTopRenderNode(NodeId id)
136 {
137 std::lock_guard<std::mutex> lock(topNodeMapMut_);
138 auto it = topSurfaceNodeMap_.find(id);
139 if (it != topSurfaceNodeMap_.end() && it->second != nullptr) {
140 return it->second;
141 }
142 // create and insert
143 auto topRcdNode = RSRcdSurfaceRenderNode::Create(TOP_RCD_NODE_ID, RCDSurfaceType::TOP);
144 topRcdNode->SetRenderTargetId(id);
145 topSurfaceNodeMap_[id] = topRcdNode;
146 RS_LOGI_IF(DEBUG_PIPELINE, "RCD: insert a top rendernode");
147 return topRcdNode;
148 }
149
GetBottomRenderNode(NodeId id)150 RSRcdSurfaceRenderNodePtr RSRcdRenderManager::GetBottomRenderNode(NodeId id)
151 {
152 std::lock_guard<std::mutex> lock(bottomNodeMapMut_);
153 auto it = bottomSurfaceNodeMap_.find(id);
154 if (it != bottomSurfaceNodeMap_.end() && it->second != nullptr) {
155 return it->second;
156 }
157 // create and insert
158 auto bottomRcdNode = RSRcdSurfaceRenderNode::Create(BACKGROUND_RCD_NODE_ID, RCDSurfaceType::BOTTOM);
159 bottomRcdNode->SetRenderTargetId(id);
160 bottomSurfaceNodeMap_[id] = bottomRcdNode;
161 RS_LOGI_IF(DEBUG_PIPELINE, "RCD: insert a bottom rendernode");
162 return bottomRcdNode;
163 }
164
DoProcessRenderTask(NodeId id,const RcdProcessInfo & info)165 void RSRcdRenderManager::DoProcessRenderTask(NodeId id, const RcdProcessInfo& info)
166 {
167 RS_TRACE_BEGIN("RSUniRender:DoRCDProcessTask");
168 if (!IsRcdProcessInfoValid(info)) {
169 RS_LOGE("RCD: RcdProcessInfo is incorrect");
170 RS_TRACE_END();
171 return;
172 }
173 auto visitor = std::make_shared<RSRcdRenderVisitor>();
174 visitor->SetUniProcessor(info.uniProcessor);
175 auto bottomRes = visitor->ProcessRcdSurfaceRenderNode(*GetBottomRenderNode(id), info.bottomLayer,
176 info.resourceChanged);
177 auto topRes = visitor->ProcessRcdSurfaceRenderNode(*GetTopRenderNode(id), info.topLayer, info.resourceChanged);
178 if (info.resourceChanged && bottomRes && topRes) {
179 RSSingleton<RsMessageBus>::GetInstance().SendMsg<NodeId, bool>(TOPIC_RCD_DISPLAY_HWRESOURCE, id, true);
180 }
181 RS_TRACE_END();
182 }
183
DoProcessRenderMainThreadTask(NodeId id,const RcdProcessInfo & info)184 void RSRcdRenderManager::DoProcessRenderMainThreadTask(NodeId id, const RcdProcessInfo& info)
185 {
186 RS_TRACE_BEGIN("RSUniRender:DoRCDProcessMainThreadTask");
187 if (!IsRcdProcessInfoValid(info)) {
188 RS_LOGE("RCD: RcdProcessInfo in MainThread is incorrect");
189 RS_TRACE_END();
190 return;
191 }
192 auto visitor = std::make_shared<RSRcdRenderVisitor>();
193 visitor->SetUniProcessor(info.uniProcessor);
194 visitor->ProcessRcdSurfaceRenderNodeMainThread(*GetBottomRenderNode(id), info.resourceChanged);
195 visitor->ProcessRcdSurfaceRenderNodeMainThread(*GetTopRenderNode(id), info.resourceChanged);
196 RS_TRACE_END();
197 }
198
199 } // namespace Rosen
200 } // namespace OHOS