1 /*
2 * Copyright (c) 2024 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_round_corner_display_manager.h"
17 #include "platform/common/rs_system_properties.h"
18 #include "common/rs_optional_trace.h"
19 #include "common/rs_singleton.h"
20 #include "rs_trace.h"
21
22 namespace OHOS {
23 namespace Rosen {
RoundCornerDisplayManager()24 RoundCornerDisplayManager::RoundCornerDisplayManager()
25 {
26 RS_LOGD_IF(DEBUG_PIPELINE, "[%{public}s] Created \n", __func__);
27 }
28
~RoundCornerDisplayManager()29 RoundCornerDisplayManager::~RoundCornerDisplayManager()
30 {
31 RS_LOGD_IF(DEBUG_PIPELINE, "[%{public}s] Destroy \n", __func__);
32 }
33
CheckExist(NodeId id)34 bool RoundCornerDisplayManager::CheckExist(NodeId id)
35 {
36 auto it = rcdMap_.find(id);
37 if (rcdMap_.end() == it) {
38 return false;
39 }
40 return true;
41 }
42
AddLayer(const std::string & name,NodeId id,RoundCornerDisplayManager::RCDLayerType type)43 void RoundCornerDisplayManager::AddLayer(const std::string& name, NodeId id,
44 RoundCornerDisplayManager::RCDLayerType type)
45 {
46 std::lock_guard<std::mutex> lock(rcdLayerMapMut_);
47 rcdlayerMap_[name] = {id, type};
48 RS_LOGI_IF(DEBUG_PIPELINE, "[%{public}s] rendertargetNodeId:%{public}" PRIu64 " with rcd layer name %{public}s \n",
49 __func__, id, name.c_str());
50 }
51
GetLayerPair(const std::string & layerName)52 std::pair<NodeId, RoundCornerDisplayManager::RCDLayerType> RoundCornerDisplayManager::GetLayerPair(
53 const std::string& layerName)
54 {
55 std::lock_guard<std::mutex> lock(rcdLayerMapMut_);
56 auto it = rcdlayerMap_.find(layerName);
57 if (rcdlayerMap_.end() == it) {
58 return {0, RoundCornerDisplayManager::RCDLayerType::INVALID};
59 }
60 return rcdlayerMap_.at(layerName);
61 }
62
CheckLayerIsRCD(const std::string & layerName)63 bool RoundCornerDisplayManager::CheckLayerIsRCD(const std::string& layerName)
64 {
65 std::lock_guard<std::mutex> lock(rcdLayerMapMut_);
66 auto it = rcdlayerMap_.find(layerName);
67 if (rcdlayerMap_.end() == it) {
68 return false;
69 }
70 return true;
71 }
72
AddRoundCornerDisplay(NodeId id)73 void RoundCornerDisplayManager::AddRoundCornerDisplay(NodeId id)
74 {
75 std::lock_guard<std::mutex> lock(rcdMapMut_);
76 if (CheckExist(id)) {
77 RS_LOGD_IF(DEBUG_PIPELINE,
78 "[%{public}s] nodeId:%{public}" PRIu64 " rcd module already exist, size:%{public}zd \n",
79 __func__, id, rcdMap_.size());
80 return;
81 }
82 auto rcd = std::make_shared<RoundCornerDisplay>(id);
83 rcdMap_[id] = rcd;
84 if (rcdMap_[id] == nullptr) {
85 RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module create failed \n", __func__, id);
86 return;
87 }
88 rcdMap_[id]->InitOnce();
89 RS_LOGI_IF(DEBUG_PIPELINE, "[%{public}s] size:%{public}zd rcd module after added for screen \n", __func__,
90 rcdMap_.size());
91 }
92
RemoveRCDResource(NodeId id)93 void RoundCornerDisplayManager::RemoveRCDResource(NodeId id)
94 {
95 {
96 std::lock_guard<std::mutex> lock(rcdMapMut_);
97 RemoveRoundCornerDisplay(id);
98 }
99 {
100 std::lock_guard<std::mutex> lock(rcdLayerMapMut_);
101 RemoveRCDLayerInfo(id);
102 }
103 }
104
RemoveRoundCornerDisplay(NodeId id)105 void RoundCornerDisplayManager::RemoveRoundCornerDisplay(NodeId id)
106 {
107 if (!CheckExist(id)) {
108 RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module not exist \n", __func__, id);
109 return;
110 }
111 rcdMap_.erase(id);
112 RS_LOGI_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module removed for screen \n", __func__,
113 id);
114 }
115
RemoveRCDLayerInfo(NodeId id)116 void RoundCornerDisplayManager::RemoveRCDLayerInfo(NodeId id)
117 {
118 const auto& it = std::find_if(rcdlayerMap_.begin(), rcdlayerMap_.end(),
119 [id](const std::pair<std::string, std::pair<NodeId, RCDLayerType>>& p) {
120 return p.second.first == id;
121 });
122 if (rcdlayerMap_.end() == it) {
123 RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd layer not exist \n", __func__, id);
124 return;
125 }
126 rcdlayerMap_.erase(it->first);
127 RS_LOGI_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd layer removed for screen \n", __func__,
128 id);
129 }
130
UpdateDisplayParameter(NodeId id,uint32_t width,uint32_t height)131 void RoundCornerDisplayManager::UpdateDisplayParameter(NodeId id, uint32_t width, uint32_t height)
132 {
133 std::lock_guard<std::mutex> lock(rcdMapMut_);
134 if (!CheckExist(id)) {
135 RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module not exist \n", __func__, id);
136 return;
137 }
138 if (rcdMap_[id] == nullptr) {
139 RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module is null \n", __func__, id);
140 RemoveRoundCornerDisplay(id);
141 return;
142 }
143 rcdMap_[id]->UpdateDisplayParameter(width, height);
144 }
145
UpdateNotchStatus(NodeId id,int status)146 void RoundCornerDisplayManager::UpdateNotchStatus(NodeId id, int status)
147 {
148 std::lock_guard<std::mutex> lock(rcdMapMut_);
149 if (!CheckExist(id)) {
150 RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module not exist \n", __func__, id);
151 return;
152 }
153 if (rcdMap_[id] == nullptr) {
154 RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module is null \n", __func__, id);
155 RemoveRoundCornerDisplay(id);
156 return;
157 }
158 rcdMap_[id]->UpdateNotchStatus(status);
159 }
160
UpdateOrientationStatus(NodeId id,ScreenRotation orientation)161 void RoundCornerDisplayManager::UpdateOrientationStatus(NodeId id, ScreenRotation orientation)
162 {
163 std::lock_guard<std::mutex> lock(rcdMapMut_);
164 if (!CheckExist(id)) {
165 RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module not exist \n", __func__, id);
166 return;
167 }
168 if (rcdMap_[id] == nullptr) {
169 RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module is null \n", __func__, id);
170 RemoveRoundCornerDisplay(id);
171 return;
172 }
173 rcdMap_[id]->UpdateOrientationStatus(orientation);
174 }
175
UpdateHardwareResourcePrepared(NodeId id,bool prepared)176 void RoundCornerDisplayManager::UpdateHardwareResourcePrepared(NodeId id, bool prepared)
177 {
178 std::lock_guard<std::mutex> lock(rcdMapMut_);
179 if (!CheckExist(id)) {
180 RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module not exist \n", __func__, id);
181 return;
182 }
183 if (rcdMap_[id] == nullptr) {
184 RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module is null \n", __func__, id);
185 RemoveRoundCornerDisplay(id);
186 return;
187 }
188 rcdMap_[id]->UpdateHardwareResourcePrepared(prepared);
189 }
190
DrawRoundCorner(const RoundCornerDisplayManager::RCDLayerInfoVec & layerInfos,RSPaintFilterCanvas * canvas)191 void RoundCornerDisplayManager::DrawRoundCorner(const RoundCornerDisplayManager::RCDLayerInfoVec& layerInfos,
192 RSPaintFilterCanvas* canvas)
193 {
194 std::lock_guard<std::mutex> lock(rcdMapMut_);
195 for (const auto& layerInfo : layerInfos) {
196 if (layerInfo.second == RoundCornerDisplayManager::RCDLayerType::TOP) {
197 DrawTopRoundCorner(layerInfo.first, canvas);
198 }
199 if (layerInfo.second == RoundCornerDisplayManager::RCDLayerType::BOTTOM) {
200 DrawBottomRoundCorner(layerInfo.first, canvas);
201 }
202 }
203 }
204
DrawTopRoundCorner(NodeId id,RSPaintFilterCanvas * canvas)205 void RoundCornerDisplayManager::DrawTopRoundCorner(NodeId id, RSPaintFilterCanvas* canvas)
206 {
207 if (!CheckExist(id)) {
208 RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module not exist \n", __func__, id);
209 return;
210 }
211 if (rcdMap_[id] == nullptr) {
212 RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module is null \n", __func__, id);
213 RemoveRoundCornerDisplay(id);
214 return;
215 }
216 rcdMap_[id]->DrawTopRoundCorner(canvas);
217 }
218
DrawBottomRoundCorner(NodeId id,RSPaintFilterCanvas * canvas)219 void RoundCornerDisplayManager::DrawBottomRoundCorner(NodeId id, RSPaintFilterCanvas* canvas)
220 {
221 if (!CheckExist(id)) {
222 RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module not exist \n", __func__, id);
223 return;
224 }
225 if (rcdMap_[id] == nullptr) {
226 RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module is null \n", __func__, id);
227 RemoveRoundCornerDisplay(id);
228 return;
229 }
230 rcdMap_[id]->DrawBottomRoundCorner(canvas);
231 }
232
RunHardwareTask(NodeId id,const std::function<void ()> & task)233 void RoundCornerDisplayManager::RunHardwareTask(NodeId id, const std::function<void()>& task)
234 {
235 {
236 std::lock_guard<std::mutex> lock(rcdMapMut_);
237 if (!CheckExist(id)) {
238 RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module not exist \n", __func__, id);
239 return;
240 }
241 if (rcdMap_[id] == nullptr) {
242 RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module is null \n", __func__, id);
243 RemoveRoundCornerDisplay(id);
244 return;
245 }
246 }
247 rcdMap_[id]->RunHardwareTask(task);
248 }
249
GetHardwareInfo(NodeId id,bool preparing)250 rs_rcd::RoundCornerHardware RoundCornerDisplayManager::GetHardwareInfo(NodeId id, bool preparing)
251 {
252 std::lock_guard<std::mutex> lock(rcdMapMut_);
253 rs_rcd::RoundCornerHardware rcdHardwareInfo{};
254 if (!CheckExist(id)) {
255 RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module not exist \n", __func__, id);
256 return rcdHardwareInfo;
257 }
258 if (rcdMap_.at(id) == nullptr) {
259 RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module is null \n", __func__, id);
260 return rcdHardwareInfo;
261 }
262 return preparing ? rcdMap_.at(id)->GetHardwareInfoPreparing() : rcdMap_.at(id)->GetHardwareInfo();
263 }
264
GetRcdEnable() const265 bool RoundCornerDisplayManager::GetRcdEnable() const
266 {
267 return RSSystemProperties::GetRSScreenRoundCornerEnable();
268 }
269
IsNotchNeedUpdate(NodeId id,bool notchStatus)270 bool RoundCornerDisplayManager::IsNotchNeedUpdate(NodeId id, bool notchStatus)
271 {
272 std::lock_guard<std::mutex> lock(rcdMapMut_);
273 if (!CheckExist(id)) {
274 RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module not exist \n", __func__, id);
275 return false;
276 }
277 if (rcdMap_[id] == nullptr) {
278 RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module is null \n", __func__, id);
279 RemoveRoundCornerDisplay(id);
280 return false;
281 }
282 return rcdMap_[id]->IsNotchNeedUpdate(notchStatus);
283 }
284 } // namespace Rosen
285 } // namespace OHOS