• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_message_bus.h"
21 #include "rs_trace.h"
22 
23 namespace OHOS {
24 namespace Rosen {
RoundCornerDisplayManager()25 RoundCornerDisplayManager::RoundCornerDisplayManager()
26 {
27     RS_LOGD_IF(DEBUG_PIPELINE, "[%{public}s] Created \n", __func__);
28 }
29 
~RoundCornerDisplayManager()30 RoundCornerDisplayManager::~RoundCornerDisplayManager()
31 {
32     RS_LOGD_IF(DEBUG_PIPELINE, "[%{public}s] Destroy \n", __func__);
33 }
34 
CheckExist(NodeId id)35 bool RoundCornerDisplayManager::CheckExist(NodeId id)
36 {
37     auto it = rcdMap_.find(id);
38     if (rcdMap_.end() == it) {
39         return false;
40     }
41     return true;
42 }
43 
RegisterRcdMsg()44 void RoundCornerDisplayManager::RegisterRcdMsg()
45 {
46     if (RSSingleton<RoundCornerDisplayManager>::GetInstance().GetRcdEnable()) {
47         RS_LOGD("RSSubThreadManager::RegisterRcdMsg");
48         if (!isRcdMessageRegisted_) {
49             auto& rcdInstance = RSSingleton<RoundCornerDisplayManager>::GetInstance();
50             auto& msgBus = RSSingleton<RsMessageBus>::GetInstance();
51             msgBus.RegisterTopic<NodeId, uint32_t, uint32_t, uint32_t, uint32_t>(
52                 TOPIC_RCD_DISPLAY_SIZE, &rcdInstance,
53                 &RoundCornerDisplayManager::UpdateDisplayParameter);
54             msgBus.RegisterTopic<NodeId, ScreenRotation>(
55                 TOPIC_RCD_DISPLAY_ROTATION, &rcdInstance,
56                 &RoundCornerDisplayManager::UpdateOrientationStatus);
57             msgBus.RegisterTopic<NodeId, int>(
58                 TOPIC_RCD_DISPLAY_NOTCH, &rcdInstance,
59                 &RoundCornerDisplayManager::UpdateNotchStatus);
60             msgBus.RegisterTopic<NodeId, bool>(
61                 TOPIC_RCD_DISPLAY_HWRESOURCE, &rcdInstance,
62                 &RoundCornerDisplayManager::UpdateHardwareResourcePrepared);
63             isRcdMessageRegisted_ = true;
64             RS_LOGD("RSSubThreadManager::RegisterRcdMsg Registed rcd renderservice end");
65             return;
66         }
67         RS_LOGD("RSSubThreadManager::RegisterRcdMsg Registed rcd renderservice already.");
68     }
69 }
70 
AddLayer(const std::string & name,NodeId id,RoundCornerDisplayManager::RCDLayerType type)71 void RoundCornerDisplayManager::AddLayer(const std::string& name, NodeId id,
72     RoundCornerDisplayManager::RCDLayerType type)
73 {
74     std::lock_guard<std::mutex> lock(rcdLayerMapMut_);
75     rcdlayerMap_[name] = {id, type};
76     RS_LOGI_IF(DEBUG_PIPELINE, "[%{public}s] rendertargetNodeId:%{public}" PRIu64 " with rcd layer name %{public}s \n",
77         __func__, id, name.c_str());
78 }
79 
GetLayerPair(const std::string & layerName)80 std::pair<NodeId, RoundCornerDisplayManager::RCDLayerType> RoundCornerDisplayManager::GetLayerPair(
81     const std::string& layerName)
82 {
83     std::lock_guard<std::mutex> lock(rcdLayerMapMut_);
84     auto it = rcdlayerMap_.find(layerName);
85     if (rcdlayerMap_.end() == it) {
86         return {0, RoundCornerDisplayManager::RCDLayerType::INVALID};
87     }
88     return rcdlayerMap_.at(layerName);
89 }
90 
CheckLayerIsRCD(const std::string & layerName)91 bool RoundCornerDisplayManager::CheckLayerIsRCD(const std::string& layerName)
92 {
93     std::lock_guard<std::mutex> lock(rcdLayerMapMut_);
94     auto it = rcdlayerMap_.find(layerName);
95     if (rcdlayerMap_.end() == it) {
96         return false;
97     }
98     return true;
99 }
100 
AddRoundCornerDisplay(NodeId id)101 void RoundCornerDisplayManager::AddRoundCornerDisplay(NodeId id)
102 {
103     std::lock_guard<std::mutex> lock(rcdMapMut_);
104     if (CheckExist(id)) {
105         RS_LOGD_IF(DEBUG_PIPELINE,
106             "[%{public}s] nodeId:%{public}" PRIu64 " rcd module already exist, size:%{public}zd \n",
107             __func__, id, rcdMap_.size());
108         return;
109     }
110     auto rcd = std::make_shared<RoundCornerDisplay>(id);
111     rcdMap_[id] = rcd;
112     if (rcdMap_[id] == nullptr) {
113         RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module create failed \n", __func__, id);
114         return;
115     }
116     rcdMap_[id]->InitOnce();
117     RS_LOGI_IF(DEBUG_PIPELINE, "[%{public}s] size:%{public}zd rcd module after added for screen \n", __func__,
118         rcdMap_.size());
119 }
120 
RemoveRCDResource(NodeId id)121 void RoundCornerDisplayManager::RemoveRCDResource(NodeId id)
122 {
123     {
124         std::lock_guard<std::mutex> lock(rcdMapMut_);
125         RemoveRoundCornerDisplay(id);
126     }
127     {
128         std::lock_guard<std::mutex> lock(rcdLayerMapMut_);
129         RemoveRCDLayerInfo(id);
130     }
131 }
132 
RemoveRoundCornerDisplay(NodeId id)133 void RoundCornerDisplayManager::RemoveRoundCornerDisplay(NodeId id)
134 {
135     if (!CheckExist(id)) {
136         RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module not exist \n", __func__, id);
137         return;
138     }
139     rcdMap_.erase(id);
140     RS_LOGI_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module removed for screen \n", __func__,
141         id);
142 }
143 
RemoveRCDLayerInfo(NodeId id)144 void RoundCornerDisplayManager::RemoveRCDLayerInfo(NodeId id)
145 {
146     const auto& it = std::find_if(rcdlayerMap_.begin(), rcdlayerMap_.end(),
147         [id](const std::pair<std::string, std::pair<NodeId, RCDLayerType>>& p) {
148             return p.second.first == id;
149         });
150     if (rcdlayerMap_.end() == it) {
151         RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd layer not exist \n", __func__, id);
152         return;
153     }
154     rcdlayerMap_.erase(it->first);
155     RS_LOGI_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd layer removed for screen \n", __func__,
156         id);
157 }
158 
UpdateDisplayParameter(NodeId id,uint32_t left,uint32_t top,uint32_t width,uint32_t height)159 void RoundCornerDisplayManager::UpdateDisplayParameter(NodeId id, uint32_t left, uint32_t top,
160     uint32_t width, uint32_t height)
161 {
162     std::lock_guard<std::mutex> lock(rcdMapMut_);
163     if (!CheckExist(id)) {
164         RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module not exist \n", __func__, id);
165         return;
166     }
167     if (rcdMap_[id] == nullptr) {
168         RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module is null \n", __func__, id);
169         RemoveRoundCornerDisplay(id);
170         return;
171     }
172     rcdMap_[id]->UpdateDisplayParameter(left, top, width, height);
173 }
174 
UpdateNotchStatus(NodeId id,int status)175 void RoundCornerDisplayManager::UpdateNotchStatus(NodeId id, int status)
176 {
177     std::lock_guard<std::mutex> lock(rcdMapMut_);
178     if (!CheckExist(id)) {
179         RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module not exist \n", __func__, id);
180         return;
181     }
182     if (rcdMap_[id] == nullptr) {
183         RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module is null \n", __func__, id);
184         RemoveRoundCornerDisplay(id);
185         return;
186     }
187     rcdMap_[id]->UpdateNotchStatus(status);
188 }
189 
UpdateOrientationStatus(NodeId id,ScreenRotation orientation)190 void RoundCornerDisplayManager::UpdateOrientationStatus(NodeId id, ScreenRotation orientation)
191 {
192     std::lock_guard<std::mutex> lock(rcdMapMut_);
193     if (!CheckExist(id)) {
194         RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module not exist \n", __func__, id);
195         return;
196     }
197     if (rcdMap_[id] == nullptr) {
198         RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module is null \n", __func__, id);
199         RemoveRoundCornerDisplay(id);
200         return;
201     }
202     rcdMap_[id]->UpdateOrientationStatus(orientation);
203 }
204 
UpdateHardwareResourcePrepared(NodeId id,bool prepared)205 void RoundCornerDisplayManager::UpdateHardwareResourcePrepared(NodeId id, bool prepared)
206 {
207     std::lock_guard<std::mutex> lock(rcdMapMut_);
208     if (!CheckExist(id)) {
209         RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module not exist \n", __func__, id);
210         return;
211     }
212     if (rcdMap_[id] == nullptr) {
213         RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module is null \n", __func__, id);
214         RemoveRoundCornerDisplay(id);
215         return;
216     }
217     rcdMap_[id]->UpdateHardwareResourcePrepared(prepared);
218 }
219 
RefreshFlagAndUpdateResource(NodeId id)220 void RoundCornerDisplayManager::RefreshFlagAndUpdateResource(NodeId id)
221 {
222     std::lock_guard<std::mutex> lock(rcdMapMut_);
223     if (!CheckExist(id)) {
224         RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module not exist \n", __func__, id);
225         return;
226     }
227     if (rcdMap_[id] == nullptr) {
228         RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module is null \n", __func__, id);
229         RemoveRoundCornerDisplay(id);
230         return;
231     }
232     rcdMap_[id]->RefreshFlagAndUpdateResource();
233 }
234 
DrawRoundCorner(const RoundCornerDisplayManager::RCDLayerInfoVec & layerInfos,RSPaintFilterCanvas * canvas)235 void RoundCornerDisplayManager::DrawRoundCorner(const RoundCornerDisplayManager::RCDLayerInfoVec& layerInfos,
236     RSPaintFilterCanvas* canvas)
237 {
238     std::lock_guard<std::mutex> lock(rcdMapMut_);
239     for (const auto& layerInfo : layerInfos) {
240         if (layerInfo.second == RoundCornerDisplayManager::RCDLayerType::TOP) {
241             DrawTopRoundCorner(layerInfo.first, canvas);
242         }
243         if (layerInfo.second == RoundCornerDisplayManager::RCDLayerType::BOTTOM) {
244             DrawBottomRoundCorner(layerInfo.first, canvas);
245         }
246     }
247 }
248 
DrawTopRoundCorner(NodeId id,RSPaintFilterCanvas * canvas)249 void RoundCornerDisplayManager::DrawTopRoundCorner(NodeId id, RSPaintFilterCanvas* canvas)
250 {
251     if (!CheckExist(id)) {
252         RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module not exist \n", __func__, id);
253         return;
254     }
255     if (rcdMap_[id] == nullptr) {
256         RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module is null \n", __func__, id);
257         RemoveRoundCornerDisplay(id);
258         return;
259     }
260     rcdMap_[id]->DrawTopRoundCorner(canvas);
261 }
262 
DrawBottomRoundCorner(NodeId id,RSPaintFilterCanvas * canvas)263 void RoundCornerDisplayManager::DrawBottomRoundCorner(NodeId id, RSPaintFilterCanvas* canvas)
264 {
265     if (!CheckExist(id)) {
266         RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module not exist \n", __func__, id);
267         return;
268     }
269     if (rcdMap_[id] == nullptr) {
270         RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module is null \n", __func__, id);
271         RemoveRoundCornerDisplay(id);
272         return;
273     }
274     rcdMap_[id]->DrawBottomRoundCorner(canvas);
275 }
276 
HandleRoundCornerDirtyRect(NodeId id,RectI & dirtyRect,const RCDLayerType type)277 bool RoundCornerDisplayManager::HandleRoundCornerDirtyRect(NodeId id, RectI &dirtyRect, const RCDLayerType type)
278 {
279     std::lock_guard<std::mutex> lock(rcdMapMut_);
280     if (!CheckExist(id)) {
281         RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module not exist \n", __func__, id);
282         return false;
283     }
284     if (rcdMap_[id] == nullptr) {
285         RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module is null \n", __func__, id);
286         RemoveRoundCornerDisplay(id);
287         return false;
288     }
289     bool isDirty = false;
290     if (type == RCDLayerType::TOP) {
291         isDirty = rcdMap_[id]->HandleTopRcdDirty(dirtyRect) || isDirty;
292     }
293     if (type == RCDLayerType::BOTTOM) {
294         isDirty = rcdMap_[id]->HandleBottomRcdDirty(dirtyRect) || isDirty;
295     }
296     return isDirty;
297 }
298 
RunHardwareTask(NodeId id,const std::function<void ()> & task)299 void RoundCornerDisplayManager::RunHardwareTask(NodeId id, const std::function<void()>& task)
300 {
301     {
302         std::lock_guard<std::mutex> lock(rcdMapMut_);
303         if (!CheckExist(id)) {
304             RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module not exist \n", __func__, id);
305             return;
306         }
307         if (rcdMap_[id] == nullptr) {
308             RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module is null \n", __func__, id);
309             RemoveRoundCornerDisplay(id);
310             return;
311         }
312     }
313     rcdMap_[id]->RunHardwareTask(task);
314 }
315 
GetHardwareInfo(NodeId id)316 rs_rcd::RoundCornerHardware RoundCornerDisplayManager::GetHardwareInfo(NodeId id)
317 {
318     std::lock_guard<std::mutex> lock(rcdMapMut_);
319     rs_rcd::RoundCornerHardware rcdHardwareInfo{};
320     if (!CheckExist(id)) {
321         RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module not exist \n", __func__, id);
322         return rcdHardwareInfo;
323     }
324     if (rcdMap_.at(id) == nullptr) {
325         RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module is null \n", __func__, id);
326         return rcdHardwareInfo;
327     }
328     return rcdMap_.at(id)->GetHardwareInfo();
329 }
330 
PrepareHardwareInfo(NodeId id)331 rs_rcd::RoundCornerHardware RoundCornerDisplayManager::PrepareHardwareInfo(NodeId id)
332 {
333     std::lock_guard<std::mutex> lock(rcdMapMut_);
334     rs_rcd::RoundCornerHardware rcdHardwareInfo{};
335     if (!CheckExist(id)) {
336         RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module not exist \n", __func__, id);
337         return rcdHardwareInfo;
338     }
339     if (rcdMap_.at(id) == nullptr) {
340         RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module is null \n", __func__, id);
341         return rcdHardwareInfo;
342     }
343     return rcdMap_.at(id)->PrepareHardwareInfo();
344 }
345 
GetRcdEnable() const346 bool RoundCornerDisplayManager::GetRcdEnable() const
347 {
348     auto &rcdCfg = RSSingleton<rs_rcd::RCDConfig>::GetInstance();
349     // assume support rcd before rcd cfg loaded
350     bool rcdSupport = !rcdCfg.IsDataLoaded();
351     if (!rcdSupport) {
352         auto lcdModel = rcdCfg.GetLcdModel(rs_rcd::ATTR_DEFAULT);
353         if (lcdModel != nullptr) {
354             rcdSupport = lcdModel->surfaceConfig.topSurface.support && lcdModel->surfaceConfig.bottomSurface.support;
355         }
356     }
357     return RSSystemProperties::GetRSScreenRoundCornerEnable() && rcdSupport;
358 }
359 
IsNotchNeedUpdate(NodeId id,bool notchStatus)360 bool RoundCornerDisplayManager::IsNotchNeedUpdate(NodeId id, bool notchStatus)
361 {
362     std::lock_guard<std::mutex> lock(rcdMapMut_);
363     if (!CheckExist(id)) {
364         RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module not exist \n", __func__, id);
365         return false;
366     }
367     if (rcdMap_[id] == nullptr) {
368         RS_LOGE_IF(DEBUG_PIPELINE, "[%{public}s] nodeId:%{public}" PRIu64 " rcd module is null \n", __func__, id);
369         RemoveRoundCornerDisplay(id);
370         return false;
371     }
372     return rcdMap_[id]->IsNotchNeedUpdate(notchStatus);
373 }
374 } // namespace Rosen
375 } // namespace OHOS