• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "rs_screen_manager.h"
17 
18 #include "graphic_feature_param_manager.h"
19 #include "display_engine/rs_color_temperature.h"
20 #include "hgm_core.h"
21 #include "pipeline/rs_display_render_node.h"
22 #include "pipeline/main_thread/rs_main_thread.h"
23 #include "pipeline/hardware_thread/rs_hardware_thread.h"
24 #include "platform/common/rs_log.h"
25 #include "vsync_sampler.h"
26 #include <parameter.h>
27 #include <parameters.h>
28 #include "param/sys_param.h"
29 #include "common/rs_optional_trace.h"
30 #include "rs_trace.h"
31 
32 #undef LOG_TAG
33 #define LOG_TAG "RSScreenManager"
34 
35 namespace OHOS {
36 namespace Rosen {
37 #ifdef RS_SUBSCRIBE_SENSOR_ENABLE
38 namespace {
39     constexpr float ANGLE_MIN_VAL = 0.0F;
40     constexpr float ANGLE_MAX_VAL = 180.0F;
41     constexpr int32_t SENSOR_SUCCESS = 0;
42     constexpr int32_t POSTURE_INTERVAL = 4000000;
43     constexpr uint16_t SENSOR_EVENT_FIRST_DATA = 0;
44     constexpr float HALF_FOLDED_MAX_THRESHOLD = 140.0F;
45     constexpr float OPEN_HALF_FOLDED_MIN_THRESHOLD = 25.0F;
46     constexpr uint32_t WAIT_FOR_ACTIVE_SCREEN_ID_TIMEOUT = 1000;
47     constexpr uint32_t MAX_VIRTUAL_SCREEN_NUM = 64;
48     constexpr uint32_t MAX_VIRTUAL_SCREEN_WIDTH = 65536;
49     constexpr uint32_t MAX_VIRTUAL_SCREEN_HEIGHT = 65536;
50     constexpr uint32_t MAX_VIRTUAL_SCREEN_REFRESH_RATE = 120;
51     constexpr uint32_t ORIGINAL_FOLD_SCREEN_AMOUNT = 2;
52     const std::string FORCE_REFRESH_ONE_FRAME_TASK_NAME = "ForceRefreshOneFrameIfNoRNV";
SensorPostureDataCallback(SensorEvent * event)53     void SensorPostureDataCallback(SensorEvent* event)
54     {
55         OHOS::Rosen::CreateOrGetScreenManager()->HandlePostureData(event);
56     }
57 } // namespace
58 #endif
59 using namespace HiviewDFX;
60 namespace impl {
61 std::once_flag RSScreenManager::createFlag_;
62 sptr<OHOS::Rosen::RSScreenManager> RSScreenManager::instance_ = nullptr;
63 
GetInstance()64 sptr<OHOS::Rosen::RSScreenManager> RSScreenManager::GetInstance() noexcept
65 {
66     std::call_once(createFlag_, []() {
67         instance_ = new RSScreenManager();
68     });
69 
70     return instance_;
71 }
72 
RSScreenManager()73 RSScreenManager::RSScreenManager()
74 {
75 }
76 
~RSScreenManager()77 RSScreenManager::~RSScreenManager() noexcept
78 {
79 }
80 
Init()81 bool RSScreenManager::Init() noexcept
82 {
83     composer_ = HdiBackend::GetInstance();
84 #ifdef RS_SUBSCRIBE_SENSOR_ENABLE
85     isFoldScreenFlag_ = system::GetParameter("const.window.foldscreen.type", "") != "";
86 #endif
87     if (composer_ == nullptr) {
88         RS_LOGE("%{public}s: Failed to get composer.", __func__);
89         return false;
90     }
91 
92     if (composer_->RegScreenHotplug(&RSScreenManager::OnHotPlug, this) != 0) {
93         RS_LOGE("%{public}s: Failed to register OnHotPlug Func to composer.", __func__);
94         return false;
95     }
96 
97     if (composer_->RegScreenRefresh(&RSScreenManager::OnRefresh, this) != 0) {
98         RS_LOGE("%{public}s: Failed to register OnRefresh Func to composer.", __func__);
99     }
100 
101     if (composer_->RegHwcDeadListener(&RSScreenManager::OnHwcDead, this) != 0) {
102         RS_LOGE("%{public}s: Failed to register OnHwcDead Func to composer.", __func__);
103         return false;
104     }
105 
106     if (composer_->RegScreenVBlankIdleCallback(&RSScreenManager::OnScreenVBlankIdle, this) != 0) {
107         RS_LOGW("%{public}s: Not support register OnScreenVBlankIdle Func to composer.", __func__);
108     }
109 
110     // call ProcessScreenHotPlugEvents() for primary screen immediately in main thread.
111     ProcessScreenHotPlugEvents();
112 
113 #ifdef RS_SUBSCRIBE_SENSOR_ENABLE
114     if (isFoldScreenFlag_) {
115         RS_LOGI("%{public}s: FoldScreen need to RegisterSensorCallback.", __func__);
116         RegisterSensorCallback();
117     }
118 #endif
119     RS_LOGI("Init succeed");
120     return true;
121 }
122 
123 #ifdef RS_SUBSCRIBE_SENSOR_ENABLE
RegisterSensorCallback()124 void RSScreenManager::RegisterSensorCallback()
125 {
126     user.callback = SensorPostureDataCallback;
127     int32_t subscribeRet;
128     int32_t setBatchRet;
129     int32_t activateRet;
130     int tryCnt = 0;
131     constexpr int tryLimit = 5; // 5 times failure limit
132     do {
133         subscribeRet = SubscribeSensor(SENSOR_TYPE_ID_POSTURE, &user);
134         RS_LOGI("%{public}s, subscribeRet: %{public}d", __func__, subscribeRet);
135         setBatchRet = SetBatch(SENSOR_TYPE_ID_POSTURE, &user, POSTURE_INTERVAL, POSTURE_INTERVAL);
136         RS_LOGI("%{public}s, setBatchRet: %{public}d", __func__, setBatchRet);
137         activateRet = ActivateSensor(SENSOR_TYPE_ID_POSTURE, &user);
138         RS_LOGI("%{public}s, activateRet: %{public}d", __func__, activateRet);
139         if (subscribeRet != SENSOR_SUCCESS || setBatchRet != SENSOR_SUCCESS || activateRet != SENSOR_SUCCESS) {
140             RS_LOGE("%{public}s failed.", __func__);
141             usleep(1000); // wait 1000 us for next try
142             tryCnt++;
143         }
144     } while (tryCnt <= tryLimit && (subscribeRet != SENSOR_SUCCESS || setBatchRet != SENSOR_SUCCESS ||
145         activateRet != SENSOR_SUCCESS));
146     if (tryCnt <= tryLimit) {
147         RS_LOGI("%{public}s success.", __func__);
148     }
149 }
150 
UnRegisterSensorCallback()151 void RSScreenManager::UnRegisterSensorCallback()
152 {
153     int32_t deactivateRet = DeactivateSensor(SENSOR_TYPE_ID_POSTURE, &user);
154     int32_t unsubscribeRet = UnsubscribeSensor(SENSOR_TYPE_ID_POSTURE, &user);
155     if (deactivateRet == SENSOR_SUCCESS && unsubscribeRet == SENSOR_SUCCESS) {
156         RS_LOGI("%{public}s success.", __func__);
157     }
158 }
159 
HandlePostureData(const SensorEvent * const event)160 void RSScreenManager::HandlePostureData(const SensorEvent* const event)
161 {
162     if (event == nullptr) {
163         RS_LOGW("SensorEvent is nullptr.");
164         return;
165     }
166     if (event[SENSOR_EVENT_FIRST_DATA].data == nullptr) {
167         RS_LOGW("SensorEvent[0].data is nullptr.");
168         return;
169     }
170     if (event[SENSOR_EVENT_FIRST_DATA].dataLen < sizeof(PostureData)) {
171         RS_LOGW("SensorEvent dataLen less than posture data size.");
172         return;
173     }
174     PostureData* postureData = reinterpret_cast<PostureData*>(event[SENSOR_EVENT_FIRST_DATA].data);
175     float angle = (*postureData).angle;
176     if (std::isless(angle, ANGLE_MIN_VAL) || std::isgreater(angle, ANGLE_MAX_VAL)) {
177         RS_LOGW("Invalid angle value, angle is %{public}f.", angle);
178         return;
179     }
180     RS_LOGI("angle vlaue in PostureData is: %{public}f.", angle);
181     HandleSensorData(angle);
182 }
183 
HandleSensorData(float angle)184 void RSScreenManager::HandleSensorData(float angle)
185 {
186     std::unique_lock<std::mutex> lock(activeScreenIdAssignedMutex_);
187     FoldState foldState = TransferAngleToScreenState(angle);
188     if (foldState == FoldState::FOLDED) {
189         if (activeScreenId_ != externalScreenId_) {
190             activeScreenId_ = externalScreenId_;
191             RS_LOGI("%{public}s: foldState is FoldState::FOLDED.", __func__);
192         }
193     } else if (activeScreenId_ != innerScreenId_) {
194         activeScreenId_ = innerScreenId_;
195         RS_LOGI("%{public}s: foldState is not FoldState::FOLDED.", __func__);
196     }
197     isPostureSensorDataHandled_ = true;
198     HgmCore::Instance().SetActiveScreenId(activeScreenId_);
199     activeScreenIdAssignedCV_.notify_one();
200 }
201 
TransferAngleToScreenState(float angle)202 FoldState RSScreenManager::TransferAngleToScreenState(float angle)
203 {
204     if (std::isless(angle, ANGLE_MIN_VAL)) {
205         RS_LOGI("%{public}s: angle isless ANGLE_MIN_VAL.", __func__);
206         return FoldState::FOLDED;
207     }
208     if (std::isgreaterequal(angle, HALF_FOLDED_MAX_THRESHOLD)) {
209         RS_LOGI("%{public}s: angle isgreaterequal HALF_FOLDED_MAX_THRESHOLD.", __func__);
210         return FoldState::EXPAND;
211     }
212     FoldState state;
213     if (std::islessequal(angle, OPEN_HALF_FOLDED_MIN_THRESHOLD)) {
214         RS_LOGI("%{public}s: angle islessequal OPEN_HALF_FOLDED_MIN_THRESHOLD.", __func__);
215         state = FoldState::FOLDED;
216     } else {
217         RS_LOGI("%{public}s: angle isgreater HALF_FOLDED_MAX_THRESHOLD.", __func__);
218         state = FoldState::EXPAND;
219     }
220     return state;
221 }
222 
GetActiveScreenId()223 ScreenId RSScreenManager::GetActiveScreenId()
224 {
225     std::unique_lock<std::mutex> lock(activeScreenIdAssignedMutex_);
226     if (!isFoldScreenFlag_) {
227         RS_LOGW("%{public}s: !isFoldScreenFlag_.", __func__);
228         return INVALID_SCREEN_ID;
229     }
230     if (isPostureSensorDataHandled_) {
231         isFirstTimeToGetActiveScreenId_ = false;
232         UnRegisterSensorCallback();
233         RS_LOGW("%{public}s: activeScreenId: %{public}" PRIu64, __func__, activeScreenId_);
234         return activeScreenId_;
235     }
236     activeScreenIdAssignedCV_.wait_until(lock, std::chrono::system_clock::now() +
237         std::chrono::milliseconds(WAIT_FOR_ACTIVE_SCREEN_ID_TIMEOUT), [this]() {
238             return isPostureSensorDataHandled_;
239         });
240     if (isFirstTimeToGetActiveScreenId_) {
241         RS_LOGI("%{public}s: isFirstTimeToGetActiveScreenId_.", __func__);
242         isFirstTimeToGetActiveScreenId_ = false;
243         UnRegisterSensorCallback();
244     }
245     RS_LOGI("%{public}s: activeScreenId: %{public}" PRIu64, __func__, activeScreenId_);
246     return activeScreenId_;
247 }
248 #else
GetActiveScreenId()249 ScreenId RSScreenManager::GetActiveScreenId()
250 {
251     return INVALID_SCREEN_ID;
252 }
253 #endif
254 
IsAllScreensPowerOff() const255 bool RSScreenManager::IsAllScreensPowerOff() const
256 {
257     std::scoped_lock lock(mutex_, powerStatusMutex_);
258     if (screenPowerStatus_.empty()) {
259         RS_LOGE("%{public}s: screenPowerStatus_ is empty.", __func__);
260         return false;
261     }
262     for (const auto& [id, powerStatus] : screenPowerStatus_) {
263         auto iter = screens_.find(id);
264         if (iter != screens_.end() && iter->second != nullptr && iter->second->IsVirtual()) {
265             continue;
266         }
267         // we also need to consider the AOD mode(POWER_STATUS_SUSPEND)
268         if (powerStatus != ScreenPowerStatus::POWER_STATUS_OFF &&
269             powerStatus != ScreenPowerStatus::POWER_STATUS_SUSPEND) {
270             RS_LOGE("%{public}s: powerStatus is not off or suspend.", __func__);
271             return false;
272         }
273     }
274     return true;
275 }
276 
277 #ifdef USE_VIDEO_PROCESSING_ENGINE
GetScreenBrightnessNits(ScreenId id) const278 float RSScreenManager::GetScreenBrightnessNits(ScreenId id) const
279 {
280     constexpr float DEFAULT_SCREEN_LIGHT_NITS = 500.0;
281     constexpr float DEFAULT_SCREEN_LIGHT_MAX_NITS = 1200.0;
282     constexpr int32_t DEFAULT_SCREEN_LIGHT_MAX_LEVEL = 255;
283 
284     float screenBrightnessNits = DEFAULT_SCREEN_LIGHT_NITS;
285 
286     RSScreenType screenType;
287     if (GetScreenType(id, screenType) != SUCCESS) {
288         RS_LOGW("%{public}s: GetScreenType fail.", __func__);
289         return screenBrightnessNits;
290     }
291 
292     if (screenType == VIRTUAL_TYPE_SCREEN) {
293         RS_LOGE("%{public}s: screenType is VIRTUAL_TYPE_SCREEN.", __func__);
294         return screenBrightnessNits;
295     }
296 
297     int32_t backLightLevel = GetScreenBacklight(id);
298     if (backLightLevel <= 0) {
299         RS_LOGE("%{public}s: backLightLevel <= zero.", __func__);
300         return screenBrightnessNits;
301     }
302 
303     return DEFAULT_SCREEN_LIGHT_MAX_NITS * backLightLevel / DEFAULT_SCREEN_LIGHT_MAX_LEVEL;
304 }
305 #endif
306 
PostForceRefreshTask()307 void RSScreenManager::PostForceRefreshTask()
308 {
309     auto mainThread = RSMainThread::Instance();
310     if (mainThread != nullptr && !mainThread->IsRequestedNextVSync()) {
311         mainThread->PostTask([mainThread]() {
312             RS_TRACE_NAME("No RNV, ForceRefreshOneFrame");
313             mainThread->SetDirtyFlag();
314             mainThread->RequestNextVSync();
315         }, FORCE_REFRESH_ONE_FRAME_TASK_NAME, 20); // delay 20ms
316     }
317 }
318 
RemoveForceRefreshTask()319 void RSScreenManager::RemoveForceRefreshTask()
320 {
321     auto mainThread = RSMainThread::Instance();
322     if (mainThread != nullptr) {
323         mainThread->RemoveTask(FORCE_REFRESH_ONE_FRAME_TASK_NAME);
324     }
325 }
326 
OnHotPlug(std::shared_ptr<HdiOutput> & output,bool connected,void * data)327 void RSScreenManager::OnHotPlug(std::shared_ptr<HdiOutput>& output, bool connected, void* data)
328 {
329     if (output == nullptr) {
330         RS_LOGE("%{public}s: output is nullptr.", __func__);
331         return;
332     }
333 
334     RSScreenManager* screenManager = nullptr;
335     if (data != nullptr) {
336         RS_LOGI("%{public}s: data is not nullptr.", __func__);
337         screenManager = static_cast<RSScreenManager*>(data);
338     } else {
339         RS_LOGI("%{public}s: data is nullptr.", __func__);
340         screenManager = static_cast<RSScreenManager*>(RSScreenManager::GetInstance().GetRefPtr());
341     }
342 
343     if (screenManager == nullptr) {
344         RS_LOGE("%{public}s: Failed to find RSScreenManager instance.", __func__);
345         return;
346     }
347 
348     screenManager->OnHotPlugEvent(output, connected);
349 }
350 
OnHotPlugEvent(std::shared_ptr<HdiOutput> & output,bool connected)351 void RSScreenManager::OnHotPlugEvent(std::shared_ptr<HdiOutput>& output, bool connected)
352 {
353     {
354         std::lock_guard<std::mutex> lock(hotPlugAndConnectMutex_);
355 
356         ScreenId id = ToScreenId(output->GetScreenId());
357         if (pendingHotPlugEvents_.find(id) != pendingHotPlugEvents_.end()) {
358             RS_LOGE("%{public}s: screen %{public}" PRIu64 "is covered.", __func__, id);
359         }
360         pendingHotPlugEvents_[id] = ScreenHotPlugEvent{output, connected};
361     }
362 
363     // This func would be called in main thread first time immediately after calling composer_->RegScreenHotplug,
364     // but at this time the RSMainThread object would not be ready to handle this, so we need to call
365     // ProcessScreenHotPlugEvents() after this func in RSScreenManager::Init().
366 
367     // Normally, this func would be called in hdi's hw-ipc threads(but sometimes in main thread, maybe),
368     // so we should notify the RSMainThread to postTask to call ProcessScreenHotPlugEvents().
369     auto mainThread = RSMainThread::Instance();
370     if (mainThread == nullptr) {
371         RS_LOGE("%{public}s: mainThread is nullptr.", __func__);
372         return;
373     }
374     mainThread->RequestNextVSync();
375 }
376 
OnRefresh(ScreenId id,void * data)377 void RSScreenManager::OnRefresh(ScreenId id, void* data)
378 {
379     RSScreenManager* screenManager = nullptr;
380     if (data != nullptr) {
381         screenManager = static_cast<RSScreenManager*>(data);
382     } else {
383         RS_LOGI("%{public}s: data is nullptr.", __func__);
384         screenManager = static_cast<RSScreenManager*>(RSScreenManager::GetInstance().GetRefPtr());
385     }
386 
387     if (screenManager == nullptr) {
388         RS_LOGE("%{public}s: Failed to find RSScreenManager instance.", __func__);
389         return;
390     }
391     screenManager->OnRefreshEvent(id);
392 }
393 
OnRefreshEvent(ScreenId id)394 void RSScreenManager::OnRefreshEvent(ScreenId id)
395 {
396     auto mainThread = RSMainThread::Instance();
397     if (mainThread == nullptr) {
398         RS_LOGE("%{public}s: mainThread is nullptr.", __func__);
399         return;
400     }
401     mainThread->PostTask([mainThread]() {
402         mainThread->SetForceUpdateUniRenderFlag(true);
403         mainThread->RequestNextVSync();
404     });
405 }
406 
OnHwcDead(void * data)407 void RSScreenManager::OnHwcDead(void* data)
408 {
409     RS_LOGW("%{public}s: The composer_host is already dead.", __func__);
410     RSScreenManager* screenManager = static_cast<RSScreenManager*>(RSScreenManager::GetInstance().GetRefPtr());
411     if (screenManager == nullptr) {
412         RS_LOGE("%{public}s: Failed to find RSScreenManager instance.", __func__);
413         return;
414     }
415 
416     // Automatically recover when composer host dies.
417     screenManager->CleanAndReinit();
418 }
419 
OnHwcDeadEvent()420 void RSScreenManager::OnHwcDeadEvent()
421 {
422     std::map<ScreenId, std::shared_ptr<OHOS::Rosen::RSScreen>> screens;
423     {
424         std::lock_guard<std::mutex> lock(mutex_);
425         screens = std::move(screens_);
426     }
427     for (const auto& [id, screen] : screens) {
428         if (screen) {
429             // In sceneboard, we should not notify the WMS to remove node from RSTree
430             if (screen->IsVirtual()) {
431                 continue;
432             } else {
433 #ifdef RS_ENABLE_GPU
434                 RSHardwareThread::Instance().ClearFrameBuffers(screen->GetOutput());
435 #endif
436             }
437         }
438     }
439     isHwcDead_ = true;
440     defaultScreenId_ = INVALID_SCREEN_ID;
441 }
442 
OnScreenVBlankIdle(uint32_t devId,uint64_t ns,void * data)443 void RSScreenManager::OnScreenVBlankIdle(uint32_t devId, uint64_t ns, void* data)
444 {
445     RS_LOGI("RSScreenManager::OnScreenVBlankIdle devId:%{public}u, ns:" RSPUBU64, devId, ns);
446     RS_TRACE_NAME_FMT("OnScreenVBlankIdle devId:%u, ns:%lu", devId, ns);
447     CreateVSyncSampler()->StartSample(true);
448     RSScreenManager* screenManager = static_cast<RSScreenManager*>(RSScreenManager::GetInstance().GetRefPtr());
449     if (screenManager == nullptr) {
450         RS_LOGE("%{public}s: Failed to find RSScreenManager instance.", __func__);
451         return;
452     }
453     screenManager->OnScreenVBlankIdleEvent(devId, ns);
454 }
455 
OnScreenVBlankIdleEvent(uint32_t devId,uint64_t ns)456 void RSScreenManager::OnScreenVBlankIdleEvent(uint32_t devId, uint64_t ns)
457 {
458     ScreenId screenId = ToScreenId(devId);
459     if (GetScreen(screenId) == nullptr) {
460         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, screenId);
461         return;
462     }
463 #ifdef RS_ENABLE_GPU
464     RSHardwareThread::Instance().PostTask([screenId, ns]() {
465         RSHardwareThread::Instance().OnScreenVBlankIdleCallback(screenId, ns);
466     });
467 #endif
468 }
469 
CleanAndReinit()470 void RSScreenManager::CleanAndReinit()
471 {
472     RSScreenManager* screenManager = static_cast<RSScreenManager*>(RSScreenManager::GetInstance().GetRefPtr());
473     if (screenManager == nullptr) {
474         RS_LOGE("%{public}s: Failed to find RSScreenManager instance.", __func__);
475         return;
476     }
477 
478     auto renderType = RSUniRenderJudgement::GetUniRenderEnabledType();
479     if (renderType != UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
480         auto mainThread = RSMainThread::Instance();
481         if (mainThread == nullptr) {
482             RS_LOGE("%{public}s: Reinit failed, get RSMainThread failed.", __func__);
483             return;
484         }
485         mainThread->PostTask([screenManager, this]() {
486             screenManager->OnHwcDeadEvent();
487             if (!composer_) {
488                 RS_LOGE("%{public}s: Failed to get composer.", __func__);
489                 return;
490             }
491             composer_->ResetDevice();
492             if (!screenManager->Init()) {
493                 RS_LOGE("%{public}s: Reinit failed, screenManager init failed in mainThread.", __func__);
494                 return;
495             }
496         });
497     } else {
498 #ifdef RS_ENABLE_GPU
499         RSHardwareThread::Instance().PostTask([screenManager, this]() {
500             RS_LOGW("%{public}s: clean and reinit in hardware thread.", __func__);
501             screenManager->OnHwcDeadEvent();
502             if (!composer_) {
503                 RS_LOGE("%{public}s: Failed to get composer.", __func__);
504                 return;
505             }
506             composer_->ResetDevice();
507             if (!screenManager->Init()) {
508                 RS_LOGE("%{public}s: Reinit failed, screenManager init failed in HardwareThread.", __func__);
509                 return;
510             }
511         });
512 #endif
513     }
514 }
515 
TrySimpleProcessHotPlugEvents()516 bool RSScreenManager::TrySimpleProcessHotPlugEvents()
517 {
518     std::lock_guard<std::mutex> lock(hotPlugAndConnectMutex_);
519     if (!isHwcDead_ && pendingHotPlugEvents_.empty() && pendingConnectedIds_.empty()) {
520         mipiCheckInFirstHotPlugEvent_ = true;
521         return true;
522     }
523     return false;
524 }
525 
ProcessScreenHotPlugEvents()526 void RSScreenManager::ProcessScreenHotPlugEvents()
527 {
528     std::map<ScreenId, ScreenHotPlugEvent> pendingHotPlugEvents;
529     {
530         std::lock_guard<std::mutex> lock(hotPlugAndConnectMutex_);
531         pendingHotPlugEvents = std::move(pendingHotPlugEvents_);
532     }
533     for (auto& [_, event] : pendingHotPlugEvents) {
534         if (event.output == nullptr) {
535             RS_LOGE("%{public}s: output is nullptr.", __func__);
536             continue;
537         }
538         if (event.connected) {
539             ProcessScreenConnected(event.output);
540             AddScreenToHgm(event.output);
541         } else {
542             ProcessScreenDisConnected(event.output);
543             RemoveScreenFromHgm(event.output);
544         }
545     }
546 
547     ProcessPendingConnections();
548     isHwcDead_ = false;
549     mipiCheckInFirstHotPlugEvent_ = true;
550 }
551 
ProcessPendingConnections()552 void RSScreenManager::ProcessPendingConnections()
553 {
554     std::vector<ScreenId> pendingConnectedIds;
555     {
556         std::lock_guard<std::mutex> lock(hotPlugAndConnectMutex_);
557         pendingConnectedIds = std::move(pendingConnectedIds_);
558     }
559     auto multiScreenFeatureParam = std::static_pointer_cast<MultiScreenParam>(
560         GraphicFeatureParamManager::GetInstance().GetFeatureParam(FEATURE_CONFIGS[MULTISCREEN]));
561     if (!multiScreenFeatureParam) {
562         RS_LOGE("%{public}s multiScreenFeatureParam is null", __func__);
563         return;
564     }
565     for (auto id : pendingConnectedIds) {
566         if (!isHwcDead_) {
567             TriggerCallbacks(id, ScreenEvent::CONNECTED);
568         } else if (id != 0 && multiScreenFeatureParam->IsRsReportHwcDead()) {
569             TriggerCallbacks(id, ScreenEvent::CONNECTED, ScreenChangeReason::HWCDEAD);
570         }
571         auto screen = GetScreen(id);
572         if (screen == nullptr) {
573             continue;
574         }
575         ScreenRotation rotation = ScreenRotation::INVALID_SCREEN_ROTATION;
576         int32_t backLightLevel = INVALID_BACKLIGHT_VALUE;
577         {
578             std::shared_lock<std::shared_mutex> lock(backLightAndCorrectionMutex_);
579             if (auto iter = screenCorrection_.find(id); iter != screenCorrection_.end()) {
580                 rotation = iter->second;
581             }
582             if (auto iter = screenBacklight_.find(id); iter != screenBacklight_.end()) {
583                 backLightLevel = static_cast<int32_t>(iter->second);
584             }
585         }
586         if (rotation != ScreenRotation::INVALID_SCREEN_ROTATION) {
587             screen->SetScreenCorrection(rotation);
588         }
589         bool screenPowerOn = false;
590         {
591             std::shared_lock<std::shared_mutex> lock(powerStatusMutex_);
592             auto iter = screenPowerStatus_.find(id);
593             screenPowerOn = (iter == screenPowerStatus_.end() || iter->second == ScreenPowerStatus::POWER_STATUS_ON);
594         }
595         if (backLightLevel != INVALID_BACKLIGHT_VALUE && screenPowerOn) {
596             screen->SetScreenBacklight(static_cast<uint32_t>(backLightLevel));
597             auto mainThread = RSMainThread::Instance();
598             mainThread->PostTask([mainThread]() {
599                 mainThread->SetDirtyFlag();
600             });
601             mainThread->ForceRefreshForUni();
602         }
603     }
604 }
605 
AddScreenToHgm(std::shared_ptr<HdiOutput> & output)606 void RSScreenManager::AddScreenToHgm(std::shared_ptr<HdiOutput>& output)
607 {
608     RS_LOGI("%{public}s in", __func__);
609     HgmTaskHandleThread::Instance().PostSyncTask([this, &output] () {
610         auto& hgmCore = OHOS::Rosen::HgmCore::Instance();
611         ScreenId thisId = ToScreenId(output->GetScreenId());
612         auto screen = GetScreen(thisId);
613         if (screen == nullptr) {
614             RS_LOGE("%{public}s invalid screen id, screen not found : %{public}" PRIu64, __func__, thisId);
615             return;
616         }
617 
618         int32_t initModeId = 0;
619         auto initMode = screen->GetActiveMode();
620         if (!initMode) {
621             RS_LOGE("%{public}s failed to get initial mode", __func__);
622         } else {
623             initModeId = initMode->id;
624         }
625         const auto& capability = screen->GetCapability();
626         ScreenSize screenSize = {screen->Width(), screen->Height(), capability.phyWidth, capability.phyHeight};
627         RS_LOGI("%{public}s: add screen: w * h: [%{public}u * %{public}u], capability w * h: "
628             "[%{public}u * %{public}u]", __func__, screen->Width(), screen->Height(),
629             capability.phyWidth, capability.phyHeight);
630         if (hgmCore.AddScreen(thisId, initModeId, screenSize)) {
631             RS_LOGE("%{public}s failed to add screen : %{public}" PRIu64, __func__, thisId);
632             return;
633         }
634 
635         // for each supported mode, use the index as modeId to add the detailed mode to hgm
636         int32_t modeId = 0;
637         auto supportedModes = screen->GetSupportedModes();
638         for (auto mode = supportedModes.begin(); mode != supportedModes.end(); ++mode) {
639             if (hgmCore.AddScreenInfo(thisId, (*mode).width, (*mode).height,
640                 (*mode).freshRate, modeId)) {
641                 RS_LOGW("failed to add a screen profile to the screen : %{public}" PRIu64, thisId);
642             }
643             modeId++;
644         }
645     });
646 }
647 
RemoveScreenFromHgm(std::shared_ptr<HdiOutput> & output)648 void RSScreenManager::RemoveScreenFromHgm(std::shared_ptr<HdiOutput>& output)
649 {
650     RS_LOGI("%{public}s in", __func__);
651     HgmTaskHandleThread::Instance().PostTask([id = ToScreenId(output->GetScreenId())] () {
652         auto& hgmCore = OHOS::Rosen::HgmCore::Instance();
653         RS_LOGI("%{public}s remove screen, id: %{public}" PRIu64, __func__, id);
654         if (hgmCore.RemoveScreen(id)) {
655             RS_LOGW("%{public}s failed to remove screen : %{public}" PRIu64, __func__, id);
656         }
657     });
658 }
659 
ProcessScreenConnected(std::shared_ptr<HdiOutput> & output)660 void RSScreenManager::ProcessScreenConnected(std::shared_ptr<HdiOutput>& output)
661 {
662     bool isVirtual = false;
663     ScreenId id = ToScreenId(output->GetScreenId());
664     RS_LOGI("%{public}s The screen for id %{public}" PRIu64 " connected.", __func__, id);
665 
666     if (GetScreen(id)) {
667         TriggerCallbacks(id, ScreenEvent::DISCONNECTED);
668         RS_LOGW("%{public}s The screen for id %{public}" PRIu64 " already existed.", __func__, id);
669     }
670     auto screen = std::make_shared<RSScreen>(id, isVirtual, output, nullptr);
671 
672     std::unique_lock<std::mutex> lock(mutex_);
673     screens_[id] = screen;
674     if (isFoldScreenFlag_ && foldScreenIds_.size() < ORIGINAL_FOLD_SCREEN_AMOUNT) {
675         foldScreenIds_[id] = {true, false};
676     }
677     lock.unlock();
678 
679     ScreenId defaultScreenId = defaultScreenId_;
680     if (screen->GetCapability().type == GraphicInterfaceType::GRAPHIC_DISP_INTF_MIPI) {
681         if (!mipiCheckInFirstHotPlugEvent_.exchange(true)) {
682             defaultScreenId = id;
683         }
684     } else if (defaultScreenId == INVALID_SCREEN_ID) {
685         defaultScreenId = id;
686     }
687     defaultScreenId_ = defaultScreenId;
688 
689     uint64_t vsyncEnabledScreenId = JudgeVSyncEnabledScreenWhileHotPlug(id, true);
690     UpdateVsyncEnabledScreenId(vsyncEnabledScreenId);
691     if (vsyncEnabledScreenId == id) {
692         screen->SetScreenVsyncEnabled(true);
693     }
694 
695 #ifdef RS_SUBSCRIBE_SENSOR_ENABLE
696     if (isFoldScreenFlag_ && id != 0) {
697         externalScreenId_ = id;
698     }
699 #endif
700     std::lock_guard<std::mutex> connectLock(hotPlugAndConnectMutex_);
701     pendingConnectedIds_.emplace_back(id);
702 }
703 
ProcessScreenDisConnected(std::shared_ptr<HdiOutput> & output)704 void RSScreenManager::ProcessScreenDisConnected(std::shared_ptr<HdiOutput>& output)
705 {
706     ScreenId id = ToScreenId(output->GetScreenId());
707     RS_LOGI("%{public}s process screen disconnected, id: %{public}" PRIu64, __func__, id);
708     if (GetScreen(id) == nullptr) {
709         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
710     } else {
711         TriggerCallbacks(id, ScreenEvent::DISCONNECTED);
712         std::lock_guard<std::mutex> lock(mutex_);
713         screens_.erase(id);
714         RS_LOGI("%{public}s: Screen(id %{public}" PRIu64 ") disconnected.", __func__, id);
715     }
716     {
717         std::lock_guard<std::shared_mutex> lock(powerStatusMutex_);
718         screenPowerStatus_.erase(id);
719     }
720     {
721         std::lock_guard<std::shared_mutex> lock(backLightAndCorrectionMutex_);
722         screenBacklight_.erase(id);
723         screenCorrection_.erase(id);
724     }
725     if (id == defaultScreenId_) {
726         HandleDefaultScreenDisConnected();
727     }
728 
729     uint64_t vsyncEnabledScreenId = JudgeVSyncEnabledScreenWhileHotPlug(id, false);
730     UpdateVsyncEnabledScreenId(vsyncEnabledScreenId);
731 }
732 
UpdateVsyncEnabledScreenId(ScreenId screenId)733 void RSScreenManager::UpdateVsyncEnabledScreenId(ScreenId screenId)
734 {
735     std::unique_lock<std::mutex> lock(mutex_);
736     if (isFoldScreenFlag_ && foldScreenIds_.size() == ORIGINAL_FOLD_SCREEN_AMOUNT) {
737         bool isAllFoldScreenDisconnected = true;
738         for (const auto &[foldScreenId, foldScreenStatus] : foldScreenIds_) {
739             if (foldScreenStatus.isConnected) {
740                 isAllFoldScreenDisconnected = false;
741                 break;
742             }
743         }
744         auto it = foldScreenIds_.find(screenId);
745         if (it == foldScreenIds_.end() && !isAllFoldScreenDisconnected) {
746             return;
747         }
748     }
749     lock.unlock();
750 
751     auto renderType = RSUniRenderJudgement::GetUniRenderEnabledType();
752     if (renderType != UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
753         RegSetScreenVsyncEnabledCallbackForMainThread(screenId);
754     } else {
755         RegSetScreenVsyncEnabledCallbackForHardwareThread(screenId);
756     }
757 }
758 
RegSetScreenVsyncEnabledCallbackForMainThread(ScreenId vsyncEnabledScreenId)759 void RSScreenManager::RegSetScreenVsyncEnabledCallbackForMainThread(ScreenId vsyncEnabledScreenId)
760 {
761     auto vsyncSampler = CreateVSyncSampler();
762     if (vsyncSampler == nullptr) {
763         RS_LOGE("%{public}s failed, vsyncSampler is null", __func__);
764         return;
765     }
766     vsyncSampler->SetVsyncEnabledScreenId(vsyncEnabledScreenId);
767     vsyncSampler->RegSetScreenVsyncEnabledCallback([this, vsyncEnabledScreenId](bool enabled) {
768         auto mainThread = RSMainThread::Instance();
769         if (mainThread == nullptr) {
770             RS_LOGE("%{public}s screenVsyncEnabled:%{public}d set failed, "
771                 "get RSMainThread failed", __func__, enabled);
772             return;
773         }
774         mainThread->PostTask([this, vsyncEnabledScreenId, enabled]() {
775             auto screen = GetScreen(vsyncEnabledScreenId);
776             if (screen == nullptr) {
777                 RS_LOGE("%{public}s screenVsyncEnabled:%{public}d set failed, "
778                     "screen %{public}" PRIu64 " not found", __func__, enabled, vsyncEnabledScreenId);
779                 return;
780             }
781             screen->SetScreenVsyncEnabled(enabled);
782         });
783     });
784 }
785 
RegSetScreenVsyncEnabledCallbackForHardwareThread(ScreenId vsyncEnabledScreenId)786 void RSScreenManager::RegSetScreenVsyncEnabledCallbackForHardwareThread(ScreenId vsyncEnabledScreenId)
787 {
788     auto vsyncSampler = CreateVSyncSampler();
789     if (vsyncSampler == nullptr) {
790         RS_LOGE("%{public}s failed, vsyncSampler is null", __func__);
791         return;
792     }
793     vsyncSampler->SetVsyncEnabledScreenId(vsyncEnabledScreenId);
794 #ifdef RS_ENABLE_GPU
795     vsyncSampler->RegSetScreenVsyncEnabledCallback([this, vsyncEnabledScreenId](bool enabled) {
796         RSHardwareThread::Instance().PostTask([this, vsyncEnabledScreenId, enabled]() {
797             auto screen = GetScreen(vsyncEnabledScreenId);
798             if (screen == nullptr) {
799                 RS_LOGE("%{public}s screenVsyncEnabled:%{public}d set failed, "
800                     "screen %{public}" PRIu64 " not found", __func__, enabled, vsyncEnabledScreenId);
801                 return;
802             }
803             screen->SetScreenVsyncEnabled(enabled);
804         });
805     });
806 #endif
807 }
808 
809 // If the previous primary screen disconnected, we traversal the left screens
810 // and find the first physical screen to be the default screen.
811 // If there was no physical screen left, we set the first screen as default, no matter what type it is.
812 // At last, if no screen left, we set Default Screen Id to INVALID_SCREEN_ID.
HandleDefaultScreenDisConnected()813 void RSScreenManager::HandleDefaultScreenDisConnected()
814 {
815     ScreenId defaultScreenId = INVALID_SCREEN_ID;
816     std::lock_guard<std::mutex> lock(mutex_);
817     for (const auto& [id, screen] : screens_) {
818         if (screen == nullptr) {
819             RS_LOGW("%{public}s: screen %{public}" PRIu64 " not found", __func__, id);
820             continue;
821         }
822         if (!screen->IsVirtual()) {
823             defaultScreenId = id;
824             break;
825         }
826     }
827 
828     if (defaultScreenId == INVALID_SCREEN_ID && !screens_.empty()) {
829         defaultScreenId = screens_.cbegin()->first;
830     }
831     defaultScreenId_ = defaultScreenId;
832 }
833 
UpdateFoldScreenConnectStatusLocked(ScreenId screenId,bool connected)834 void RSScreenManager::UpdateFoldScreenConnectStatusLocked(ScreenId screenId, bool connected)
835 {
836     if (isFoldScreenFlag_) {
837         auto it = foldScreenIds_.find(screenId);
838         if (it != foldScreenIds_.end()) {
839             it->second.isConnected = connected;
840         }
841     }
842 }
843 
JudgeVSyncEnabledScreenWhileHotPlug(ScreenId screenId,bool connected)844 uint64_t RSScreenManager::JudgeVSyncEnabledScreenWhileHotPlug(ScreenId screenId, bool connected)
845 {
846     std::unique_lock<std::mutex> lock(mutex_);
847     UpdateFoldScreenConnectStatusLocked(screenId, connected);
848 
849     auto vsyncSampler = CreateVSyncSampler();
850     if (vsyncSampler == nullptr) {
851         RS_LOGE("%{public}s failed, vsyncSampler is null", __func__);
852         return screenId;
853     }
854     uint64_t vsyncEnabledScreenId = vsyncSampler->GetVsyncEnabledScreenId();
855     if (connected) { // screen connected
856         if (vsyncEnabledScreenId == UINT64_MAX) {
857             return screenId;
858         }
859     } else { // screen disconnected
860         if (vsyncEnabledScreenId != screenId) {
861             return vsyncEnabledScreenId;
862         }
863         vsyncEnabledScreenId = UINT64_MAX;
864         for (const auto &[id, screen] : screens_) {
865             if (screen == nullptr) {
866                 RS_LOGW("%{public}s: screen %{public}" PRIu64 " not found", __func__, id);
867                 continue;
868             }
869             if (!screen->IsVirtual()) {
870                 vsyncEnabledScreenId = id;
871                 break;
872             }
873         }
874     }
875     return vsyncEnabledScreenId;
876 }
877 
JudgeVSyncEnabledScreenWhilePowerStatusChanged(ScreenId screenId,ScreenPowerStatus status)878 uint64_t RSScreenManager::JudgeVSyncEnabledScreenWhilePowerStatusChanged(ScreenId screenId, ScreenPowerStatus status)
879 {
880     std::unique_lock<std::mutex> lock(mutex_);
881     uint64_t vsyncEnabledScreenId = CreateVSyncSampler()->GetVsyncEnabledScreenId();
882     auto it = foldScreenIds_.find(screenId);
883     if (it == foldScreenIds_.end()) {
884         return vsyncEnabledScreenId;
885     }
886 
887     if (status == ScreenPowerStatus::POWER_STATUS_ON) {
888         it->second.isPowerOn = true;
889         auto vsyncScreenIt = foldScreenIds_.find(vsyncEnabledScreenId);
890         if (vsyncScreenIt == foldScreenIds_.end() || vsyncScreenIt->second.isPowerOn == false) {
891             return screenId;
892         }
893     } else if (status == ScreenPowerStatus::POWER_STATUS_OFF) {
894         it->second.isPowerOn = false;
895         if (screenId != vsyncEnabledScreenId) {
896             return vsyncEnabledScreenId;
897         }
898         for (auto &[foldScreenId, status] : foldScreenIds_) {
899             if (status.isConnected && status.isPowerOn) {
900                 return foldScreenId;
901             }
902         }
903     }
904     return vsyncEnabledScreenId;
905 }
906 
907 // if SetVirtualScreenSurface success, force a refresh of one frame, avoiding prolong black screen
ForceRefreshOneFrame() const908 void RSScreenManager::ForceRefreshOneFrame() const
909 {
910     auto mainThread = RSMainThread::Instance();
911     if (mainThread != nullptr) {
912         mainThread->PostTask([mainThread]() {
913             mainThread->SetDirtyFlag();
914         });
915         mainThread->ForceRefreshForUni();
916     }
917 }
918 
SetDefaultScreenId(ScreenId id)919 void RSScreenManager::SetDefaultScreenId(ScreenId id)
920 {
921     defaultScreenId_ = id;
922 }
923 
SetScreenMirror(ScreenId id,ScreenId toMirror)924 void RSScreenManager::SetScreenMirror(ScreenId id, ScreenId toMirror)
925 {
926     std::lock_guard<std::mutex> lock(mutex_);
927 
928     auto screensIt = screens_.find(id);
929     if (screensIt == screens_.end() || screensIt->second == nullptr) {
930         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
931         return;
932     }
933 
934     screensIt->second->SetMirror(toMirror);
935 }
936 
GenerateVirtualScreenIdLocked()937 ScreenId RSScreenManager::GenerateVirtualScreenIdLocked()
938 {
939     if (!freeVirtualScreenIds_.empty()) {
940         ScreenId id = freeVirtualScreenIds_.front();
941         freeVirtualScreenIds_.pop();
942         RS_LOGI("%{public}s: VirtualScreenId is %{public}" PRIu64, __func__, id);
943         return id;
944     }
945 
946     RS_LOGI("%{public}s: freeVirtualScreenIds_ is empty.", __func__);
947     // The left 32 bits is for virtual screen id.
948     return (static_cast<ScreenId>(virtualScreenCount_++) << 32) | 0xffffffffu;
949 }
950 
ReuseVirtualScreenIdLocked(ScreenId id)951 void RSScreenManager::ReuseVirtualScreenIdLocked(ScreenId id)
952 {
953     freeVirtualScreenIds_.push(id);
954 }
955 
GetVirtualScreenResolutionLocked(ScreenId id,RSVirtualScreenResolution & virtualScreenResolution) const956 void RSScreenManager::GetVirtualScreenResolutionLocked(ScreenId id,
957     RSVirtualScreenResolution& virtualScreenResolution) const
958 {
959     auto screensIt = screens_.find(id);
960     if (screensIt == screens_.end() || screensIt->second == nullptr) {
961         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
962         return;
963     }
964     const auto& screen = screensIt->second;
965     virtualScreenResolution.SetVirtualScreenWidth(static_cast<uint32_t>(screen->Width()));
966     virtualScreenResolution.SetVirtualScreenHeight(static_cast<uint32_t>(screen->Height()));
967 }
968 
GetScreenActiveMode(ScreenId id,RSScreenModeInfo & screenModeInfo) const969 void RSScreenManager::GetScreenActiveMode(ScreenId id, RSScreenModeInfo& screenModeInfo) const
970 {
971     auto screen = GetScreen(id);
972     if (screen == nullptr) {
973         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
974         return;
975     }
976     auto modeInfo = screen->GetActiveMode();
977     if (!modeInfo) {
978         RS_LOGE("%{public}s: Failed to get active mode for screen %{public}" PRIu64, __func__, id);
979         return;
980     }
981 
982     RS_LOGI("%{public}s: screen[%{public}" PRIu64 "] pixel[%{public}d * %{public}d],"
983         "freshRate[%{public}d]", __func__, id, modeInfo->width, modeInfo->height, modeInfo->freshRate);
984     screenModeInfo.SetScreenWidth(modeInfo->width);
985     screenModeInfo.SetScreenHeight(modeInfo->height);
986     screenModeInfo.SetScreenRefreshRate(modeInfo->freshRate);
987     screenModeInfo.SetScreenModeId(screen->GetActiveModePosByModeId(modeInfo->id));
988 }
989 
GetScreenSupportedModes(ScreenId id) const990 std::vector<RSScreenModeInfo> RSScreenManager::GetScreenSupportedModes(ScreenId id) const
991 {
992     auto screen = GetScreen(id);
993     if (screen == nullptr) {
994         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
995         return {};
996     }
997 
998     const auto& displaySupportedModes = screen->GetSupportedModes();
999     std::vector<RSScreenModeInfo> screenSupportedModes(displaySupportedModes.size());
1000     for (decltype(displaySupportedModes.size()) idx = 0; idx < displaySupportedModes.size(); ++idx) {
1001         screenSupportedModes[idx].SetScreenWidth(displaySupportedModes[idx].width);
1002         screenSupportedModes[idx].SetScreenHeight(displaySupportedModes[idx].height);
1003         screenSupportedModes[idx].SetScreenRefreshRate(displaySupportedModes[idx].freshRate);
1004         screenSupportedModes[idx].SetScreenModeId(displaySupportedModes[idx].id);
1005     }
1006     return screenSupportedModes;
1007 }
1008 
GetScreenCapabilityLocked(ScreenId id) const1009 RSScreenCapability RSScreenManager::GetScreenCapabilityLocked(ScreenId id) const
1010 {
1011     RSScreenCapability screenCapability;
1012     auto screensIt = screens_.find(id);
1013     if (screensIt == screens_.end() || screensIt->second == nullptr) {
1014         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1015         return screenCapability;
1016     }
1017     const auto& screen = screensIt->second;
1018     if (screen->IsVirtual()) {
1019         RS_LOGW("%{public}s: only name attribute is valid for virtual screen.", __func__);
1020         screenCapability.SetName(screen->Name());
1021         return screenCapability;
1022     }
1023 
1024     const auto& capability = screen->GetCapability();
1025     std::vector<RSScreenProps> props;
1026     uint32_t propCount = capability.propertyCount;
1027     props.resize(propCount);
1028     for (uint32_t propIndex = 0; propIndex < propCount; propIndex++) {
1029         props[propIndex] = RSScreenProps(capability.props[propIndex].name, capability.props[propIndex].propId,
1030             capability.props[propIndex].value);
1031     }
1032     screenCapability.SetName(capability.name);
1033     screenCapability.SetType(static_cast<ScreenInterfaceType>(capability.type));
1034     screenCapability.SetPhyWidth(capability.phyWidth);
1035     screenCapability.SetPhyHeight(capability.phyHeight);
1036     screenCapability.SetSupportLayers(capability.supportLayers);
1037     screenCapability.SetVirtualDispCount(capability.virtualDispCount);
1038     screenCapability.SetSupportWriteBack(capability.supportWriteBack);
1039     screenCapability.SetProps(props);
1040     return screenCapability;
1041 }
1042 
GetScreenPowerStatus(ScreenId id) const1043 ScreenPowerStatus RSScreenManager::GetScreenPowerStatus(ScreenId id) const
1044 {
1045     auto screen = GetScreen(id);
1046     if (screen == nullptr) {
1047         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1048         return INVALID_POWER_STATUS;
1049     }
1050 
1051     ScreenPowerStatus status = static_cast<ScreenPowerStatus>(screen->GetPowerStatus());
1052     return status;
1053 }
1054 
GetScreenCorrectionLocked(ScreenId id) const1055 ScreenRotation RSScreenManager::GetScreenCorrectionLocked(ScreenId id) const
1056 {
1057     auto screensIt = screens_.find(id);
1058     if (screensIt == screens_.end() || screensIt->second == nullptr) {
1059         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1060         return ScreenRotation::INVALID_SCREEN_ROTATION;
1061     }
1062 
1063     ScreenRotation screenRotation = screensIt->second->GetScreenCorrection();
1064     return screenRotation;
1065 }
1066 
GetDefaultScreenId() const1067 ScreenId RSScreenManager::GetDefaultScreenId() const
1068 {
1069     return defaultScreenId_;
1070 }
1071 
GetAllScreenIds() const1072 std::vector<ScreenId> RSScreenManager::GetAllScreenIds() const
1073 {
1074     std::lock_guard<std::mutex> lock(mutex_);
1075     std::vector<ScreenId> ids;
1076     for (auto iter = screens_.begin(); iter != screens_.end(); ++iter) {
1077         ids.emplace_back(iter->first);
1078     }
1079     return ids;
1080 }
1081 
CreateVirtualScreen(const std::string & name,uint32_t width,uint32_t height,sptr<Surface> surface,ScreenId mirrorId,int32_t flags,std::vector<NodeId> whiteList)1082 ScreenId RSScreenManager::CreateVirtualScreen(
1083     const std::string& name,
1084     uint32_t width,
1085     uint32_t height,
1086     sptr<Surface> surface,
1087     ScreenId mirrorId,
1088     int32_t flags,
1089     std::vector<NodeId> whiteList)
1090 {
1091     std::lock_guard<std::mutex> lock(mutex_);
1092 
1093     if (currentVirtualScreenNum_ >= MAX_VIRTUAL_SCREEN_NUM) {
1094         RS_LOGW("%{public}s: virtual screens num %{public}" PRIu32" has reached the maximum limit!",
1095             __func__, currentVirtualScreenNum_);
1096         return INVALID_SCREEN_ID;
1097     }
1098     if (width > MAX_VIRTUAL_SCREEN_WIDTH || height > MAX_VIRTUAL_SCREEN_HEIGHT) {
1099         RS_LOGW("%{public}s: width %{public}" PRIu32" or height %{public}" PRIu32" has reached"
1100             " the maximum limit!", __func__, width, height);
1101         return INVALID_SCREEN_ID;
1102     }
1103     if (surface != nullptr) {
1104         uint64_t surfaceId = surface->GetUniqueId();
1105         for (auto& [_, screen] : screens_) {
1106             if (screen == nullptr || !screen->IsVirtual()) {
1107                 continue;
1108             }
1109             auto screenSurface = screen->GetProducerSurface();
1110             if (screenSurface == nullptr) {
1111                 continue;
1112             }
1113             if (screenSurface->GetUniqueId() == surfaceId) {
1114                 RS_LOGW("%{public}s: surface %{public}" PRIu64 " is used, create virtual"
1115                     " screen failed!", __func__, surfaceId);
1116                 return INVALID_SCREEN_ID;
1117             }
1118         }
1119     } else {
1120         RS_LOGW("%{public}s: surface is nullptr.", __func__);
1121     }
1122 
1123     VirtualScreenConfigs configs;
1124     ScreenId newId = GenerateVirtualScreenIdLocked();
1125     configs.id = newId;
1126     configs.mirrorId = mirrorId;
1127     configs.name = name;
1128     configs.width = width;
1129     configs.height = height;
1130     configs.surface = surface;
1131     configs.flags = flags;
1132     configs.whiteList = std::unordered_set<NodeId>(whiteList.begin(), whiteList.end());
1133 
1134     screens_[newId] = std::make_shared<RSScreen>(configs);
1135     ++currentVirtualScreenNum_;
1136     RS_LOGD("%{public}s: create virtual screen(id %{public}" PRIu64 ").", __func__, newId);
1137     return newId;
1138 }
1139 
SetVirtualScreenBlackList(ScreenId id,const std::vector<uint64_t> & blackList)1140 int32_t RSScreenManager::SetVirtualScreenBlackList(ScreenId id, const std::vector<uint64_t>& blackList)
1141 {
1142     std::lock_guard<std::mutex> lock(mutex_);
1143     std::unordered_set<NodeId> screenBlackList(blackList.begin(), blackList.end());
1144     if (id == INVALID_SCREEN_ID) {
1145         RS_LOGI("%{public}s: Cast screen blacklists for id %{public}" PRIu64, __func__, id);
1146         castScreenBlackList_ = screenBlackList;
1147         return SUCCESS;
1148     }
1149     auto virtualScreen = screens_.find(id);
1150     if (virtualScreen == screens_.end() || virtualScreen->second == nullptr) {
1151         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1152         return SCREEN_NOT_FOUND;
1153     }
1154     RS_LOGI("%{public}s: Record screen blacklists for id %{public}" PRIu64, __func__, id);
1155     virtualScreen->second->SetBlackList(screenBlackList);
1156     ScreenId mainId = GetDefaultScreenId();
1157     if (mainId != id) {
1158         auto mainScreen = screens_.find(mainId);
1159         if (mainScreen == screens_.end() || mainScreen->second == nullptr) {
1160             RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, mainId);
1161             return SCREEN_NOT_FOUND;
1162         }
1163         mainScreen->second->SetBlackList(screenBlackList);
1164     }
1165     return SUCCESS;
1166 }
1167 
AddVirtualScreenBlackList(ScreenId id,const std::vector<uint64_t> & blackList)1168 int32_t RSScreenManager::AddVirtualScreenBlackList(ScreenId id, const std::vector<uint64_t>& blackList)
1169 {
1170     std::lock_guard<std::mutex> lock(mutex_);
1171     if (id == INVALID_SCREEN_ID) {
1172         RS_LOGI("%{public}s: Cast screen blacklists", __func__);
1173         for (auto& list : blackList) {
1174             castScreenBlackList_.emplace(list);
1175         }
1176         return SUCCESS;
1177     }
1178     auto virtualScreen = screens_.find(id);
1179     if (virtualScreen == screens_.end() || virtualScreen->second == nullptr) {
1180         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1181         return SCREEN_NOT_FOUND;
1182     }
1183     RS_LOGI("%{public}s: Record screen blacklists for id %{public}" PRIu64, __func__, id);
1184     virtualScreen->second->AddBlackList(blackList);
1185 
1186     ScreenId mainId = GetDefaultScreenId();
1187     if (mainId != id) {
1188         auto mainScreen = screens_.find(mainId);
1189         if (mainScreen == screens_.end() || mainScreen->second == nullptr) {
1190             RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, mainId);
1191             return SCREEN_NOT_FOUND;
1192         }
1193         mainScreen->second->AddBlackList(blackList);
1194     }
1195     return SUCCESS;
1196 }
1197 
RemoveVirtualScreenBlackList(ScreenId id,const std::vector<uint64_t> & blackList)1198 int32_t RSScreenManager::RemoveVirtualScreenBlackList(ScreenId id, const std::vector<uint64_t>& blackList)
1199 {
1200     std::lock_guard<std::mutex> lock(mutex_);
1201     if (id == INVALID_SCREEN_ID) {
1202         RS_LOGI("%{public}s: Cast screen blacklists", __func__);
1203         for (auto& list : blackList) {
1204             auto it = castScreenBlackList_.find(list);
1205             if (it == castScreenBlackList_.end()) {
1206                 continue;
1207             }
1208             castScreenBlackList_.erase(it);
1209         }
1210         return SUCCESS;
1211     }
1212     auto virtualScreen = screens_.find(id);
1213     if (virtualScreen == screens_.end() || virtualScreen->second == nullptr) {
1214         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1215         return SCREEN_NOT_FOUND;
1216     }
1217     RS_LOGI("%{public}s: Record screen blacklists for id %{public}" PRIu64, __func__, id);
1218     virtualScreen->second->RemoveBlackList(blackList);
1219 
1220     ScreenId mainId = GetDefaultScreenId();
1221     if (mainId != id) {
1222         auto mainScreen = screens_.find(mainId);
1223         if (mainScreen == screens_.end() || mainScreen->second == nullptr) {
1224             RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, mainId);
1225             return SCREEN_NOT_FOUND;
1226         }
1227         mainScreen->second->RemoveBlackList(blackList);
1228     }
1229     return SUCCESS;
1230 }
1231 
SetVirtualScreenSecurityExemptionList(ScreenId id,const std::vector<uint64_t> & securityExemptionList)1232 int32_t RSScreenManager::SetVirtualScreenSecurityExemptionList(
1233     ScreenId id,
1234     const std::vector<uint64_t>& securityExemptionList)
1235 {
1236     if (id == INVALID_SCREEN_ID) {
1237         RS_LOGW("%{public}s: INVALID_SCREEN_ID.", __func__);
1238         return INVALID_ARGUMENTS;
1239     }
1240     std::lock_guard<std::mutex> lock(mutex_);
1241     auto virtualScreen = screens_.find(id);
1242     if (virtualScreen == screens_.end() || virtualScreen->second == nullptr) {
1243         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1244         return SCREEN_NOT_FOUND;
1245     }
1246 
1247     if (!(virtualScreen->second->IsVirtual())) {
1248         RS_LOGW("%{public}s: not virtual screen for id %{public}" PRIu64, __func__, id);
1249         return INVALID_ARGUMENTS;
1250     }
1251     virtualScreen->second->SetSecurityExemptionList(securityExemptionList);
1252     for (const auto& exemption : securityExemptionList) {
1253         RS_LOGW("%{public}s: virtual screen(id %{public}" PRIu64 "), nodeId %{public}" PRIu64,
1254             __func__, id, exemption);
1255     }
1256     return SUCCESS;
1257 }
1258 
GetVirtualScreenSecurityExemptionList(ScreenId id) const1259 const std::vector<uint64_t> RSScreenManager::GetVirtualScreenSecurityExemptionList(ScreenId id) const
1260 {
1261     std::lock_guard<std::mutex> lock(mutex_);
1262     auto virtualScreen = screens_.find(id);
1263     if (virtualScreen == screens_.end() || virtualScreen->second == nullptr) {
1264         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1265         return {};
1266     }
1267 
1268     return virtualScreen->second->GetSecurityExemptionList();
1269 }
1270 
SetScreenSecurityMask(ScreenId id,std::shared_ptr<Media::PixelMap> securityMask)1271 int32_t RSScreenManager::SetScreenSecurityMask(ScreenId id,
1272     std::shared_ptr<Media::PixelMap> securityMask)
1273 {
1274     if (id == INVALID_SCREEN_ID) {
1275         RS_LOGW("%{public}s: INVALID_SCREEN_ID.", __func__);
1276         return INVALID_ARGUMENTS;
1277     }
1278     std::lock_guard<std::mutex> lock(mutex_);
1279     auto iter = screens_.find(id);
1280     if (iter == screens_.end() || iter->second == nullptr) {
1281         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1282         return SCREEN_NOT_FOUND;
1283     }
1284 
1285     return iter->second->SetSecurityMask(std::move(securityMask));
1286 }
1287 
GetScreenSecurityMask(ScreenId id) const1288 std::shared_ptr<Media::PixelMap> RSScreenManager::GetScreenSecurityMask(ScreenId id) const
1289 {
1290     std::lock_guard<std::mutex> lock(mutex_);
1291     auto iter = screens_.find(id);
1292     if (iter == screens_.end() || iter->second == nullptr) {
1293         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1294         return nullptr;
1295     }
1296     return iter->second->GetSecurityMask();
1297 }
1298 
SetMirrorScreenVisibleRect(ScreenId id,const Rect & mainScreenRect,bool supportRotation)1299 int32_t RSScreenManager::SetMirrorScreenVisibleRect(ScreenId id, const Rect& mainScreenRect, bool supportRotation)
1300 {
1301     if (id == INVALID_SCREEN_ID) {
1302         RS_LOGW("%{public}s: INVALID_SCREEN_ID.", __func__);
1303         return INVALID_ARGUMENTS;
1304     }
1305     std::lock_guard<std::mutex> lock(mutex_);
1306     auto mainScreen = screens_.find(id);
1307     if (mainScreen == screens_.end() || mainScreen->second == nullptr) {
1308         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1309         return SCREEN_NOT_FOUND;
1310     }
1311 
1312     // zero Rect means disable visible rect
1313     static Rect ZERO = {0, 0, 0, 0};
1314     mainScreen->second->SetEnableVisibleRect(mainScreenRect != ZERO);
1315     mainScreen->second->SetMainScreenVisibleRect(mainScreenRect);
1316     mainScreen->second->SetVisibleRectSupportRotation(supportRotation);
1317     RS_LOGI("%{public}s: mirror screen(id %{public}" PRIu64 "), visible rect[%{public}d, %{public}d, "
1318         "%{public}d, %{public}d]. supportRotation: %{public}d", __func__, id, mainScreenRect.x, mainScreenRect.y,
1319          mainScreenRect.w, mainScreenRect.h, supportRotation);
1320     return SUCCESS;
1321 }
1322 
GetMirrorScreenVisibleRect(ScreenId id) const1323 Rect RSScreenManager::GetMirrorScreenVisibleRect(ScreenId id) const
1324 {
1325     std::lock_guard<std::mutex> lock(mutex_);
1326     auto mirrorScreen = screens_.find(id);
1327     if (mirrorScreen == screens_.end() || mirrorScreen->second == nullptr) {
1328         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1329         return {};
1330     }
1331 
1332     return mirrorScreen->second->GetMainScreenVisibleRect();
1333 }
1334 
GetVirtualScreenBlackList(ScreenId id) const1335 const std::unordered_set<NodeId> RSScreenManager::GetVirtualScreenBlackList(ScreenId id) const
1336 {
1337     std::lock_guard<std::mutex> lock(mutex_);
1338     auto virtualScreen = screens_.find(id);
1339     if (virtualScreen == screens_.end() || virtualScreen->second == nullptr) {
1340         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1341         return {};
1342     }
1343     if (GetCastScreenEnableSkipWindow(id)) {
1344         RS_LOGW("%{public}s: Cast screen blacklists for id %{public}" PRIu64, __func__, id);
1345         return castScreenBlackList_;
1346     }
1347     RS_LOGD("%{public}s: Record screen blacklists for id %{public}" PRIu64, __func__, id);
1348     return virtualScreen->second->GetBlackList();
1349 }
1350 
GetAllBlackList() const1351 std::unordered_set<uint64_t> RSScreenManager::GetAllBlackList() const
1352 {
1353     std::lock_guard<std::mutex> lock(mutex_);
1354     std::unordered_set<uint64_t> allBlackList;
1355     for (const auto& screen : screens_) {
1356         if (screen.second == nullptr) {
1357             continue;
1358         }
1359         if (screen.second->GetCastScreenEnableSkipWindow()) {
1360             allBlackList.insert(castScreenBlackList_.begin(), castScreenBlackList_.end());
1361         } else {
1362             const auto& blackList = screen.second->GetBlackList();
1363             allBlackList.insert(blackList.begin(), blackList.end());
1364         }
1365     }
1366     return allBlackList;
1367 }
1368 
GetAllWhiteList() const1369 std::unordered_set<uint64_t> RSScreenManager::GetAllWhiteList() const
1370 {
1371     std::lock_guard<std::mutex> lock(mutex_);
1372     std::unordered_set<uint64_t> allWhiteList;
1373     for (const auto& screen : screens_) {
1374         if (screen.second != nullptr) {
1375             const auto& whiteList = screen.second->GetWhiteList();
1376             allWhiteList.insert(whiteList.begin(), whiteList.end());
1377         }
1378     }
1379     return allWhiteList;
1380 }
1381 
SetCastScreenEnableSkipWindow(ScreenId id,bool enable)1382 int32_t RSScreenManager::SetCastScreenEnableSkipWindow(ScreenId id, bool enable)
1383 {
1384     std::lock_guard<std::mutex> lock(mutex_);
1385     auto virtualScreen = screens_.find(id);
1386     if (virtualScreen == screens_.end() || virtualScreen->second == nullptr) {
1387         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1388         return SCREEN_NOT_FOUND;
1389     }
1390     virtualScreen->second->SetCastScreenEnableSkipWindow(enable);
1391     RS_LOGW("%{public}s: screen id %{public}" PRIu64 " set %{public}d success.", __func__, id, enable);
1392     return SUCCESS;
1393 }
1394 
GetCastScreenEnableSkipWindow(ScreenId id) const1395 bool RSScreenManager::GetCastScreenEnableSkipWindow(ScreenId id) const
1396 {
1397     auto virtualScreen = screens_.find(id);
1398     if (virtualScreen == screens_.end() || virtualScreen->second == nullptr) {
1399         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1400         return false;
1401     }
1402     return virtualScreen->second->GetCastScreenEnableSkipWindow();
1403 }
1404 
SetVirtualScreenSurface(ScreenId id,sptr<Surface> surface)1405 int32_t RSScreenManager::SetVirtualScreenSurface(ScreenId id, sptr<Surface> surface)
1406 {
1407     if (surface == nullptr) {
1408         RS_LOGW("%{public}s: screenId:%{public}" PRIu64 " surface is null.", __func__, id);
1409         return INVALID_ARGUMENTS;
1410     }
1411     std::lock_guard<std::mutex> lock(mutex_);
1412     auto screensIt = screens_.find(id);
1413     if (screensIt == screens_.end()) {
1414         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1415         return SCREEN_NOT_FOUND;
1416     }
1417     if (screensIt->second != nullptr && !screensIt->second->IsVirtual()) {
1418         RS_LOGW("%{public}s: The screen is not virtual, id %{public}" PRIu64, __func__, id);
1419         return INVALID_ARGUMENTS;
1420     }
1421     uint64_t surfaceId = surface->GetUniqueId();
1422     for (auto& [screenId, screen] : screens_) {
1423         if (screen == nullptr) {
1424             RS_LOGW("%{public}s: screen %{public}" PRIu64 " not found", __func__, screenId);
1425             continue;
1426         }
1427         if (!screen->IsVirtual() || screenId == id) {
1428             RS_LOGW("%{public}s: screen %{public}" PRIu64 " is not virtual or is the same screen.",
1429                 __func__, screenId);
1430             continue;
1431         }
1432         auto screenSurface = screen->GetProducerSurface();
1433         if (screenSurface == nullptr) {
1434             RS_LOGW("%{public}s: screen %{public}" PRIu64 " is nullptr.",
1435                 __func__, screenId);
1436             continue;
1437         }
1438         if (screenSurface->GetUniqueId() == surface->GetUniqueId()) {
1439             RS_LOGE("%{public}s: surface %{public}" PRIu64 " is used, set surface failed!",
1440                 __func__, surfaceId);
1441             return SURFACE_NOT_UNIQUE;
1442         }
1443     }
1444     screensIt->second->SetProducerSurface(surface);
1445     RS_LOGI("%{public}s: set virtual screen surface success!", __func__);
1446     RS_TRACE_NAME("RSScreenManager::SetVirtualScreenSurface, ForceRefreshOneFrame.");
1447     ForceRefreshOneFrame();
1448     return SUCCESS;
1449 }
1450 
GetAndResetVirtualSurfaceUpdateFlag(ScreenId id) const1451 bool RSScreenManager::GetAndResetVirtualSurfaceUpdateFlag(ScreenId id) const
1452 {
1453     std::lock_guard<std::mutex> lock(mutex_);
1454     auto virtualScreen = screens_.find(id);
1455     if (virtualScreen == screens_.end() || virtualScreen->second == nullptr) {
1456         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1457         return false;
1458     }
1459     return virtualScreen->second->GetAndResetVirtualSurfaceUpdateFlag();
1460 }
1461 
RemoveVirtualScreen(ScreenId id)1462 void RSScreenManager::RemoveVirtualScreen(ScreenId id)
1463 {
1464     {
1465         std::lock_guard<std::mutex> lock(mutex_);
1466         RemoveVirtualScreenLocked(id);
1467     }
1468     // when virtual screen doesn't exist no more, render control can be recovered.
1469     {
1470         std::lock_guard<std::mutex> lock(renderControlMutex_);
1471         disableRenderControlScreens_.erase(id);
1472     }
1473 }
1474 
RemoveVirtualScreenLocked(ScreenId id)1475 void RSScreenManager::RemoveVirtualScreenLocked(ScreenId id)
1476 {
1477     auto screensIt = screens_.find(id);
1478     if (screensIt == screens_.end() || screensIt->second == nullptr) {
1479         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1480         return;
1481     }
1482     if (!screensIt->second->IsVirtual()) {
1483         RS_LOGW("%{public}s: The screen is not virtual, id %{public}" PRIu64, __func__, id);
1484         return;
1485     }
1486 
1487     screens_.erase(screensIt);
1488     --currentVirtualScreenNum_;
1489 
1490     // Update other screens' mirrorId.
1491     for (auto& [id, screen] : screens_) {
1492         if (screen == nullptr) {
1493             RS_LOGW("%{public}s: screen %{public}" PRIu64 " not found", __func__, id);
1494             continue;
1495         }
1496         if (screen->MirrorId() == id) {
1497             screen->SetMirror(INVALID_SCREEN_ID);
1498         }
1499     }
1500     RS_LOGI("%{public}s: remove virtual screen(id %{public}" PRIu64 ").", __func__, id);
1501 
1502     ReuseVirtualScreenIdLocked(id);
1503 }
1504 
SetScreenActiveMode(ScreenId id,uint32_t modeId)1505 uint32_t RSScreenManager::SetScreenActiveMode(ScreenId id, uint32_t modeId)
1506 {
1507     auto screen = GetScreen(id);
1508     if (screen == nullptr) {
1509         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1510         return StatusCode::SCREEN_NOT_FOUND;
1511     }
1512     return screen->SetActiveMode(modeId);
1513 }
1514 
SetScreenActiveRect(ScreenId id,const GraphicIRect & activeRect)1515 uint32_t RSScreenManager::SetScreenActiveRect(ScreenId id, const GraphicIRect& activeRect)
1516 {
1517     auto screen = GetScreen(id);
1518     if (screen == nullptr) {
1519         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1520         return StatusCode::SCREEN_NOT_FOUND;
1521     }
1522 
1523     RSHardwareThread::Instance().ScheduleTask([screen, activeRect]() {
1524         if (screen->SetScreenActiveRect(activeRect) != StatusCode::SUCCESS) {
1525             RS_LOGW("%{public}s: Invalid param", __func__);
1526         }
1527     }).wait();
1528     return StatusCode::SUCCESS;
1529 }
1530 
SetPhysicalScreenResolution(ScreenId id,uint32_t width,uint32_t height)1531 int32_t RSScreenManager::SetPhysicalScreenResolution(ScreenId id, uint32_t width, uint32_t height)
1532 {
1533     std::lock_guard<std::mutex> lock(mutex_);
1534 
1535     auto screensIt = screens_.find(id);
1536     if (screensIt == screens_.end() || screensIt->second == nullptr) {
1537         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1538         return SCREEN_NOT_FOUND;
1539     }
1540     return screensIt->second->SetResolution(width, height);
1541 }
1542 
SetVirtualScreenResolution(ScreenId id,uint32_t width,uint32_t height)1543 int32_t RSScreenManager::SetVirtualScreenResolution(ScreenId id, uint32_t width, uint32_t height)
1544 {
1545     std::lock_guard<std::mutex> lock(mutex_);
1546 
1547     if (width > MAX_VIRTUAL_SCREEN_WIDTH || height > MAX_VIRTUAL_SCREEN_HEIGHT) {
1548         RS_LOGW("%{public}s: width %{public}" PRIu32" or height %{public}" PRIu32" has reached "
1549             "the maximum limit!", __func__, width, height);
1550         return INVALID_ARGUMENTS;
1551     }
1552     auto screensIt = screens_.find(id);
1553     if (screensIt == screens_.end() || screensIt->second == nullptr) {
1554         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1555         return SCREEN_NOT_FOUND;
1556     }
1557     screensIt->second->SetResolution(width, height);
1558     RS_LOGI("%{public}s: set virtual screen resolution success", __func__);
1559     RS_OPTIONAL_TRACE_NAME("RSScreenManager::SetVirtualScreenResolution, ForceRefreshOneFrame.");
1560     ForceRefreshOneFrame();
1561     return SUCCESS;
1562 }
1563 
SetRogScreenResolution(ScreenId id,uint32_t width,uint32_t height)1564 int32_t RSScreenManager::SetRogScreenResolution(ScreenId id, uint32_t width, uint32_t height)
1565 {
1566     auto screen = GetScreen(id);
1567     if (screen == nullptr) {
1568         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1569         return StatusCode::SCREEN_NOT_FOUND;
1570     }
1571     screen->SetRogResolution(width, height);
1572     return SUCCESS;
1573 }
1574 
SetScreenPowerStatus(ScreenId id,ScreenPowerStatus status)1575 void RSScreenManager::SetScreenPowerStatus(ScreenId id, ScreenPowerStatus status)
1576 {
1577     auto screen = GetScreen(id);
1578     if (screen == nullptr) {
1579         RS_LOGW("[UL_POWER] %{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1580         return;
1581     }
1582 
1583     isScreenPoweringOn_ =
1584         (status == ScreenPowerStatus::POWER_STATUS_ON || status == ScreenPowerStatus::POWER_STATUS_ON_ADVANCED);
1585     auto ret = screen->SetPowerStatus(static_cast<uint32_t>(status));
1586     isScreenPoweringOn_ = false;
1587     if (ret != static_cast<int32_t>(StatusCode::SUCCESS)) {
1588         RS_LOGE("[UL_POWER] %{public}s: Failed to set power status of id %{public}" PRIu64, __func__, id);
1589         return;
1590     }
1591 
1592     if (isFoldScreenFlag_) {
1593         uint64_t vsyncEnabledScreenId = JudgeVSyncEnabledScreenWhilePowerStatusChanged(id, status);
1594         UpdateVsyncEnabledScreenId(vsyncEnabledScreenId);
1595     }
1596 
1597     /*
1598      * If app adds the first frame when power on the screen, delete the code
1599      */
1600     if (status == ScreenPowerStatus::POWER_STATUS_ON ||
1601         status == ScreenPowerStatus::POWER_STATUS_ON_ADVANCED) {
1602         auto mainThread = RSMainThread::Instance();
1603         if (mainThread == nullptr) {
1604             RS_LOGE("[UL_POWER] %{public}s: mainThread is nullptr", __func__);
1605             return;
1606         }
1607         mainThread->PostTask([mainThread]() {
1608             mainThread->SetDirtyFlag();
1609             mainThread->SetScreenPowerOnChanged(true);
1610         });
1611         std::shared_lock<std::shared_mutex> lock(powerStatusMutex_);
1612         if (screenPowerStatus_.count(id) == 0 ||
1613             screenPowerStatus_[id] == ScreenPowerStatus::POWER_STATUS_OFF ||
1614             screenPowerStatus_[id] == ScreenPowerStatus::POWER_STATUS_OFF_FAKE ||
1615             screenPowerStatus_[id] == ScreenPowerStatus::POWER_STATUS_OFF_ADVANCED) {
1616             mainThread->ForceRefreshForUni();
1617         } else {
1618             mainThread->RequestNextVSync();
1619         }
1620 
1621         RS_LOGI("[UL_POWER] %{public}s: PowerStatus %{public}d, request a frame", __func__, status);
1622     }
1623     RSColorTemperature::Get().UpdateScreenStatus(id, status);
1624     std::lock_guard<std::shared_mutex> lock(powerStatusMutex_);
1625     screenPowerStatus_[id] = status;
1626 }
1627 
SetVirtualMirrorScreenCanvasRotation(ScreenId id,bool canvasRotation)1628 bool RSScreenManager::SetVirtualMirrorScreenCanvasRotation(ScreenId id, bool canvasRotation)
1629 {
1630     std::lock_guard<std::mutex> lock(mutex_);
1631 
1632     auto screensIt = screens_.find(id);
1633     if (screensIt == screens_.end() || screensIt->second == nullptr) {
1634         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1635         return false;
1636     }
1637 
1638     RS_LOGI("%{public}s: canvasRotation: %{public}d", __func__, canvasRotation);
1639 
1640     return screensIt->second->SetVirtualMirrorScreenCanvasRotation(canvasRotation);
1641 }
1642 
SetVirtualMirrorScreenScaleMode(ScreenId id,ScreenScaleMode scaleMode)1643 bool RSScreenManager::SetVirtualMirrorScreenScaleMode(ScreenId id, ScreenScaleMode scaleMode)
1644 {
1645     std::lock_guard<std::mutex> lock(mutex_);
1646 
1647     auto screensIt = screens_.find(id);
1648     if (screensIt == screens_.end() || screensIt->second == nullptr) {
1649         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1650         return false;
1651     }
1652 
1653     RS_LOGI("%{public}s: scaleMode: %{public}d", __func__, scaleMode);
1654 
1655     return screensIt->second->SetVirtualMirrorScreenScaleMode(scaleMode);
1656 }
1657 
GetVirtualScreenResolution(ScreenId id,RSVirtualScreenResolution & virtualScreenResolution) const1658 void RSScreenManager::GetVirtualScreenResolution(ScreenId id, RSVirtualScreenResolution& virtualScreenResolution) const
1659 {
1660     std::lock_guard<std::mutex> lock(mutex_);
1661 
1662     GetVirtualScreenResolutionLocked(id, virtualScreenResolution);
1663 }
1664 
GetDefaultScreenActiveMode(RSScreenModeInfo & screenModeInfo) const1665 void RSScreenManager::GetDefaultScreenActiveMode(RSScreenModeInfo& screenModeInfo) const
1666 {
1667     GetScreenActiveMode(defaultScreenId_, screenModeInfo);
1668 }
1669 
ReleaseScreenDmaBuffer(uint64_t screenId)1670 void RSScreenManager::ReleaseScreenDmaBuffer(uint64_t screenId)
1671 {
1672 #ifdef RS_ENABLE_GPU
1673     RSHardwareThread::Instance().PostTask([screenId]() {
1674         RS_TRACE_NAME("RSScreenManager ReleaseScreenDmaBuffer");
1675         auto screenManager = CreateOrGetScreenManager();
1676         if (screenManager == nullptr) {
1677             RS_LOGE("%{public}s RSScreenManager is nullptr!", __func__);
1678             return;
1679         }
1680         auto output = screenManager->GetOutput(screenId);
1681         if (output == nullptr) {
1682             RS_LOGE("%{public}s HdiOutput is nullptr!", __func__);
1683             return;
1684         }
1685         std::vector<LayerInfoPtr> layer;
1686         output->SetLayerInfo(layer);
1687     });
1688 #endif
1689 }
1690 
GetScreenCapability(ScreenId id) const1691 RSScreenCapability RSScreenManager::GetScreenCapability(ScreenId id) const
1692 {
1693     std::lock_guard<std::mutex> lock(mutex_);
1694 
1695     return GetScreenCapabilityLocked(id);
1696 }
1697 
GetScreenCorrection(ScreenId id) const1698 ScreenRotation RSScreenManager::GetScreenCorrection(ScreenId id) const
1699 {
1700     std::lock_guard<std::mutex> lock(mutex_);
1701 
1702     return GetScreenCorrectionLocked(id);
1703 }
1704 
GetScreenData(ScreenId id) const1705 RSScreenData RSScreenManager::GetScreenData(ScreenId id) const
1706 {
1707     RSScreenData screenData;
1708     if (GetScreen(id) == nullptr) {
1709         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1710         return screenData;
1711     }
1712     RSScreenCapability capability = GetScreenCapability(id);
1713     RSScreenModeInfo activeMode;
1714     GetScreenActiveMode(id, activeMode);
1715     std::vector<RSScreenModeInfo> supportModes = GetScreenSupportedModes(id);
1716     ScreenPowerStatus powerStatus = GetScreenPowerStatus(id);
1717     screenData.SetCapability(capability);
1718     screenData.SetActivityModeInfo(activeMode);
1719     screenData.SetSupportModeInfo(supportModes);
1720     screenData.SetPowerStatus(powerStatus);
1721     return screenData;
1722 }
1723 
ResizeVirtualScreen(ScreenId id,uint32_t width,uint32_t height)1724 int32_t RSScreenManager::ResizeVirtualScreen(ScreenId id, uint32_t width, uint32_t height)
1725 {
1726     std::lock_guard<std::mutex> lock(mutex_);
1727 
1728     if (width > MAX_VIRTUAL_SCREEN_WIDTH || height > MAX_VIRTUAL_SCREEN_HEIGHT) {
1729         RS_LOGW("%{public}s: width %{public}" PRIu32" or height %{public}" PRIu32" has reached"
1730             " the maximum limit!", __func__, width, height);
1731         return INVALID_ARGUMENTS;
1732     }
1733     auto screensIt = screens_.find(id);
1734     if (screensIt == screens_.end() || screensIt->second == nullptr) {
1735         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1736         return SCREEN_NOT_FOUND;
1737     }
1738     screensIt->second->ResizeVirtualScreen(width, height);
1739     RS_LOGI("%{public}s: resize virtual screen success, width:%{public}u, height:%{public}u",
1740         __func__, width, height);
1741 
1742     return SUCCESS;
1743 }
1744 
GetScreenBacklight(ScreenId id) const1745 int32_t RSScreenManager::GetScreenBacklight(ScreenId id) const
1746 {
1747     auto screen = GetScreen(id);
1748     if (screen == nullptr) {
1749         RS_LOGE("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1750         return INVALID_BACKLIGHT_VALUE;
1751     }
1752     return screen->GetScreenBacklight();
1753 }
1754 
SetScreenBacklight(ScreenId id,uint32_t level)1755 void RSScreenManager::SetScreenBacklight(ScreenId id, uint32_t level)
1756 {
1757     auto screen = GetScreen(id);
1758     if (screen == nullptr) {
1759         RS_LOGE("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1760         return;
1761     }
1762     {
1763         std::lock_guard<std::shared_mutex> lock(backLightAndCorrectionMutex_);
1764         if (screenBacklight_[id] == level) {
1765             RS_LOGD("%{public}s: repeat backlight screenId: %{public}" PRIu64 " newLevel: %d",
1766                 __func__, id, level);
1767         }
1768         screenBacklight_[id] = level;
1769     }
1770     screen->SetScreenBacklight(level);
1771 }
1772 
QueryDefaultScreenInfo() const1773 ScreenInfo RSScreenManager::QueryDefaultScreenInfo() const
1774 {
1775     std::lock_guard<std::mutex> lock(mutex_);
1776     return QueryScreenInfoLocked(defaultScreenId_);
1777 }
1778 
QueryScreenInfo(ScreenId id) const1779 ScreenInfo RSScreenManager::QueryScreenInfo(ScreenId id) const
1780 {
1781     std::lock_guard<std::mutex> lock(mutex_);
1782     return QueryScreenInfoLocked(id);
1783 }
1784 
QueryScreenInfoLocked(ScreenId id) const1785 ScreenInfo RSScreenManager::QueryScreenInfoLocked(ScreenId id) const
1786 {
1787     ScreenInfo info;
1788     auto screensIt = screens_.find(id);
1789     if (screensIt == screens_.end()) {
1790         RS_LOGE("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1791         return info;
1792     }
1793 
1794     const auto& screen = screensIt->second;
1795     if (!screen) {
1796         RS_LOGE("%{public}s: screen %{public}" PRIu64 " has no info.", __func__, id);
1797         return info;
1798     }
1799     info.id = id;
1800     info.width = screen->Width();
1801     info.height = screen->Height();
1802     info.phyWidth = screen->PhyWidth() ? screen->PhyWidth() : screen->Width();
1803     info.phyHeight = screen->PhyHeight() ? screen->PhyHeight() : screen->Height();
1804     info.isSamplingOn = screen->IsSamplingOn();
1805     info.samplingTranslateX = screen->GetSamplingTranslateX();
1806     info.samplingTranslateY = screen->GetSamplingTranslateY();
1807     info.samplingScale = screen->GetSamplingScale();
1808     auto ret = screen->GetScreenColorGamut(info.colorGamut);
1809     if (ret != StatusCode::SUCCESS) {
1810         info.colorGamut = COLOR_GAMUT_SRGB;
1811     }
1812 
1813     if (!screen->IsEnable()) {
1814         info.state = ScreenState::DISABLED;
1815     } else if (!screen->IsVirtual()) {
1816         info.state = ScreenState::HDI_OUTPUT_ENABLE;
1817     } else {
1818         info.state = ScreenState::SOFTWARE_OUTPUT_ENABLE;
1819     }
1820     info.skipFrameInterval = screen->GetScreenSkipFrameInterval();
1821     info.expectedRefreshRate = screen->GetScreenExpectedRefreshRate();
1822     info.skipFrameStrategy = screen->GetScreenSkipFrameStrategy();
1823     info.isEqualVsyncPeriod = screen->GetEqualVsyncPeriod();
1824     screen->GetPixelFormat(info.pixelFormat);
1825     screen->GetScreenHDRFormat(info.hdrFormat);
1826     info.whiteList = screen->GetWhiteList();
1827     info.enableVisibleRect = screen->GetEnableVisibleRect();
1828     info.activeRect = screen->GetActiveRect();
1829     info.maskRect = screen->GetMaskRect();
1830     info.reviseRect = screen->GetReviseRect();
1831     return info;
1832 }
1833 
GetCanvasRotation(ScreenId id) const1834 bool RSScreenManager::GetCanvasRotation(ScreenId id) const
1835 {
1836     std::lock_guard<std::mutex> lock(mutex_);
1837 
1838     auto screensIt = screens_.find(id);
1839     if (screensIt == screens_.end() || screensIt->second == nullptr) {
1840         RS_LOGE("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1841         return false;
1842     }
1843     return screensIt->second->GetCanvasRotation();
1844 }
1845 
GetScaleMode(ScreenId id) const1846 ScreenScaleMode RSScreenManager::GetScaleMode(ScreenId id) const
1847 {
1848     std::lock_guard<std::mutex> lock(mutex_);
1849 
1850     auto screensIt = screens_.find(id);
1851     if (screensIt == screens_.end() || screensIt->second == nullptr) {
1852         RS_LOGE("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1853         return ScreenScaleMode::INVALID_MODE;
1854     }
1855     auto scaleModeDFX = static_cast<ScreenScaleMode>(
1856         RSSystemProperties::GetVirtualScreenScaleModeDFX());
1857     // Support mode can be configured for maintenance and testing before
1858     // upper layer application adaptation
1859     const auto& scaleMode = (scaleModeDFX == ScreenScaleMode::INVALID_MODE) ?
1860         screensIt->second->GetScaleMode() : scaleModeDFX;
1861     return scaleMode;
1862 }
1863 
GetProducerSurface(ScreenId id) const1864 sptr<Surface> RSScreenManager::GetProducerSurface(ScreenId id) const
1865 {
1866     std::lock_guard<std::mutex> lock(mutex_);
1867 
1868     auto screensIt = screens_.find(id);
1869     if (screensIt == screens_.end() || screensIt->second == nullptr) {
1870         RS_LOGE("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1871         return nullptr;
1872     }
1873     return screensIt->second->GetProducerSurface();
1874 }
1875 
GetOutput(ScreenId id) const1876 std::shared_ptr<HdiOutput> RSScreenManager::GetOutput(ScreenId id) const
1877 {
1878     std::lock_guard<std::mutex> lock(mutex_);
1879 
1880     auto screensIt = screens_.find(id);
1881     if (screensIt == screens_.end() || screensIt->second == nullptr) {
1882         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1883         return nullptr;
1884     }
1885     return screensIt->second->GetOutput();
1886 }
1887 
AddScreenChangeCallback(const sptr<RSIScreenChangeCallback> & callback)1888 int32_t RSScreenManager::AddScreenChangeCallback(const sptr<RSIScreenChangeCallback>& callback)
1889 {
1890     if (callback == nullptr) {
1891         RS_LOGE("%{public}s: callback is NULL.", __func__);
1892         return INVALID_ARGUMENTS;
1893     }
1894 
1895     {
1896         std::lock_guard<std::mutex> lock(mutex_);
1897         // when the callback first registered, maybe there were some physical screens already connected,
1898         // so notify to remote immediately.
1899         for (const auto& [id, screen] : screens_) {
1900             if (screen == nullptr) {
1901                 RS_LOGW("%{public}s: screen %{public}" PRIu64 " not found", __func__, id);
1902                 continue;
1903             }
1904             if (!screen->IsVirtual()) {
1905                 callback->OnScreenChanged(id, ScreenEvent::CONNECTED);
1906             }
1907         }
1908     }
1909 
1910     std::lock_guard<std::shared_mutex> lock(screenChangeCallbackMutex_);
1911     screenChangeCallbacks_.push_back(callback);
1912     RS_LOGI("%{public}s: add a remote callback succeed.", __func__);
1913     return SUCCESS;
1914 }
1915 
RemoveScreenChangeCallback(const sptr<RSIScreenChangeCallback> & callback)1916 void RSScreenManager::RemoveScreenChangeCallback(const sptr<RSIScreenChangeCallback>& callback)
1917 {
1918     std::lock_guard<std::shared_mutex> lock(screenChangeCallbackMutex_);
1919     for (auto it = screenChangeCallbacks_.begin(); it != screenChangeCallbacks_.end(); it++) {
1920         if (*it == callback) {
1921             screenChangeCallbacks_.erase(it);
1922             RS_LOGI("%{public}s: remove a remote callback succeed.", __func__);
1923             break;
1924         }
1925     }
1926 }
1927 
DisplayDump(std::string & dumpString)1928 void RSScreenManager::DisplayDump(std::string& dumpString)
1929 {
1930     std::lock_guard<std::mutex> lock(mutex_);
1931     int32_t index = 0;
1932     for (const auto& [id, screen] : screens_) {
1933         if (screen == nullptr) {
1934             RS_LOGE("%{public}s: screen %{public}" PRIu64 " not found.", __func__, id);
1935             continue;
1936         }
1937         screen->DisplayDump(index, dumpString);
1938         index++;
1939     }
1940     if (isFoldScreenFlag_) {
1941         dumpString += "===================\n";
1942         dumpString += "foldScreenIds_ size is " + std::to_string(foldScreenIds_.size()) + "\n";
1943         for (auto &[screenId, status] : foldScreenIds_) {
1944             dumpString += "foldScreenId:" + std::to_string(screenId) +
1945                 ", isConnected:" + std::to_string(status.isConnected) +
1946                 ", isPowerOn:" + std::to_string(status.isPowerOn) + "\n";
1947         }
1948     }
1949 }
1950 
SurfaceDump(std::string & dumpString)1951 void RSScreenManager::SurfaceDump(std::string& dumpString)
1952 {
1953     std::lock_guard<std::mutex> lock(mutex_);
1954     int32_t index = 0;
1955     for (const auto& [id, screen] : screens_) {
1956         if (screen == nullptr) {
1957             RS_LOGE("%{public}s: screen %{public}" PRIu64 " not found.", __func__, id);
1958             continue;
1959         }
1960         screen->SurfaceDump(index, dumpString);
1961         index++;
1962     }
1963 }
1964 
FpsDump(std::string & dumpString,std::string & arg)1965 void RSScreenManager::FpsDump(std::string& dumpString, std::string& arg)
1966 {
1967     std::lock_guard<std::mutex> lock(mutex_);
1968     int32_t index = 0;
1969     dumpString += "\n-- The recently fps records info of screens:\n";
1970     for (const auto& [id, screen] : screens_) {
1971         if (screen == nullptr) {
1972             RS_LOGE("%{public}s: screen %{public}" PRIu64 " not found.", __func__, id);
1973             continue;
1974         }
1975         screen->FpsDump(index, dumpString, arg);
1976         index++;
1977     }
1978 }
1979 
ClearFpsDump(std::string & dumpString,std::string & arg)1980 void RSScreenManager::ClearFpsDump(std::string& dumpString, std::string& arg)
1981 {
1982     std::lock_guard<std::mutex> lock(mutex_);
1983     int32_t index = 0;
1984     dumpString += "\n-- Clear fps records info of screens:\n";
1985     for (const auto& [id, screen] : screens_) {
1986         if (screen == nullptr) {
1987             RS_LOGE("%{public}s: screen %{public}" PRIu64 " not found.", __func__, id);
1988             continue;
1989         }
1990         screen->ClearFpsDump(index, dumpString, arg);
1991         index++;
1992     }
1993 }
1994 
ClearFrameBufferIfNeed()1995 void RSScreenManager::ClearFrameBufferIfNeed()
1996 {
1997 #ifdef RS_ENABLE_GPU
1998     RSHardwareThread::Instance().PostTask([this]() {
1999         std::lock_guard<std::mutex> lock(mutex_);
2000         for (const auto& [id, screen] : screens_) {
2001             if (!screen || !screen->GetOutput()) {
2002                 RS_LOGE("%{public}s: screen %{public}" PRIu64 " not found.", __func__, id);
2003                 continue;
2004             }
2005             if (screen->GetHasProtectedLayer()) {
2006                 RS_TRACE_NAME_FMT("screen Id:%lu has protected layer.", id);
2007                 continue;
2008             }
2009             if (screen->GetOutput()->GetBufferCacheSize() > 0) {
2010                 RS_LOGI("%{public}s: screen %{public}" PRIu64 " ClearFrameBuffers.", __func__, id);
2011                 RSHardwareThread::Instance().ClearFrameBuffers(screen->GetOutput());
2012             }
2013         }
2014     });
2015 #endif
2016 }
2017 
SetScreenConstraint(ScreenId id,uint64_t timestamp,ScreenConstraintType type)2018 int32_t RSScreenManager::SetScreenConstraint(ScreenId id, uint64_t timestamp, ScreenConstraintType type)
2019 {
2020     frameId_++;
2021     auto screen = GetScreen(id);
2022     if (screen == nullptr) {
2023         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2024         return StatusCode::SCREEN_NOT_FOUND;
2025     }
2026     RS_TRACE_NAME_FMT("SetScreenConstraint frameId:%lu timestamp:%lu type:%d", frameId_, timestamp, type);
2027     return screen->SetScreenConstraint(frameId_, timestamp, type);
2028 }
2029 
HitchsDump(std::string & dumpString,std::string & arg)2030 void RSScreenManager::HitchsDump(std::string& dumpString, std::string& arg)
2031 {
2032     std::lock_guard<std::mutex> lock(mutex_);
2033     int32_t index = 0;
2034     dumpString += "\n-- The recently window hitchs records info of screens:\n";
2035     for (const auto& [id, screen] : screens_) {
2036         if (screen == nullptr) {
2037             RS_LOGE("%{public}s: screen %{public}" PRIu64 " not found.", __func__, id);
2038             continue;
2039         }
2040         screen->HitchsDump(index, dumpString, arg);
2041         index++;
2042     }
2043 }
2044 
GetScreenSupportedColorGamutsLocked(ScreenId id,std::vector<ScreenColorGamut> & mode) const2045 int32_t RSScreenManager::GetScreenSupportedColorGamutsLocked(ScreenId id, std::vector<ScreenColorGamut>& mode) const
2046 {
2047     auto screensIt = screens_.find(id);
2048     if (screensIt == screens_.end() || screensIt->second == nullptr) {
2049         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2050         return StatusCode::SCREEN_NOT_FOUND;
2051     }
2052     return screensIt->second->GetScreenSupportedColorGamuts(mode);
2053 }
2054 
GetScreenSupportedMetaDataKeysLocked(ScreenId id,std::vector<ScreenHDRMetadataKey> & keys) const2055 int32_t RSScreenManager::GetScreenSupportedMetaDataKeysLocked(
2056     ScreenId id, std::vector<ScreenHDRMetadataKey>& keys) const
2057 {
2058     auto screensIt = screens_.find(id);
2059     if (screensIt == screens_.end() || screensIt->second == nullptr) {
2060         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2061         return StatusCode::SCREEN_NOT_FOUND;
2062     }
2063     return screensIt->second->GetScreenSupportedMetaDataKeys(keys);
2064 }
2065 
GetScreenColorGamutLocked(ScreenId id,ScreenColorGamut & mode) const2066 int32_t RSScreenManager::GetScreenColorGamutLocked(ScreenId id, ScreenColorGamut& mode) const
2067 {
2068     auto screensIt = screens_.find(id);
2069     if (screensIt == screens_.end() || screensIt->second == nullptr) {
2070         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2071         return StatusCode::SCREEN_NOT_FOUND;
2072     }
2073     return screensIt->second->GetScreenColorGamut(mode);
2074 }
2075 
SetScreenColorGamut(ScreenId id,int32_t modeIdx)2076 int32_t RSScreenManager::SetScreenColorGamut(ScreenId id, int32_t modeIdx)
2077 {
2078     auto screen = GetScreen(id);
2079     if (screen == nullptr) {
2080         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2081         return StatusCode::SCREEN_NOT_FOUND;
2082     }
2083     return screen->SetScreenColorGamut(modeIdx);
2084 }
2085 
SetScreenGamutMap(ScreenId id,ScreenGamutMap mode)2086 int32_t RSScreenManager::SetScreenGamutMap(ScreenId id, ScreenGamutMap mode)
2087 {
2088     auto screen = GetScreen(id);
2089     if (screen == nullptr) {
2090         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2091         return StatusCode::SCREEN_NOT_FOUND;
2092     }
2093     RS_OPTIONAL_TRACE_NAME("RSScreenManager::SetScreenGamutMapLocked, ForceRefreshOneFrame.");
2094     ForceRefreshOneFrame();
2095     return screen->SetScreenGamutMap(mode);
2096 }
2097 
SetScreenCorrection(ScreenId id,ScreenRotation screenRotation)2098 int32_t RSScreenManager::SetScreenCorrection(ScreenId id, ScreenRotation screenRotation)
2099 {
2100     auto screen = GetScreen(id);
2101     if (screen == nullptr) {
2102         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2103         return StatusCode::SCREEN_NOT_FOUND;
2104     }
2105     screen->SetScreenCorrection(screenRotation);
2106 
2107     std::lock_guard<std::shared_mutex> lock(backLightAndCorrectionMutex_);
2108     screenCorrection_[id] = screenRotation;
2109     return StatusCode::SUCCESS;
2110 }
2111 
GetScreenGamutMapLocked(ScreenId id,ScreenGamutMap & mode) const2112 int32_t RSScreenManager::GetScreenGamutMapLocked(ScreenId id, ScreenGamutMap& mode) const
2113 {
2114     auto screensIt = screens_.find(id);
2115     if (screensIt == screens_.end() || screensIt->second == nullptr) {
2116         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2117         return StatusCode::SCREEN_NOT_FOUND;
2118     }
2119     return screensIt->second->GetScreenGamutMap(mode);
2120 }
2121 
GetScreenHDRCapabilityLocked(ScreenId id,RSScreenHDRCapability & screenHdrCapability) const2122 int32_t RSScreenManager::GetScreenHDRCapabilityLocked(ScreenId id, RSScreenHDRCapability& screenHdrCapability) const
2123 {
2124     auto screensIt = screens_.find(id);
2125     if (screensIt == screens_.end() || screensIt->second == nullptr) {
2126         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2127         return StatusCode::SCREEN_NOT_FOUND;
2128     }
2129     GraphicHDRCapability hdrCapability = screensIt->second->GetHDRCapability();
2130     std::vector<ScreenHDRFormat> hdrFormats;
2131     uint32_t formatCount = hdrCapability.formatCount;
2132     hdrFormats.resize(formatCount);
2133     for (uint32_t index = 0; index < formatCount; index++) {
2134         hdrFormats[index] = static_cast<ScreenHDRFormat>(hdrCapability.formats[index]);
2135     }
2136     screenHdrCapability.SetMaxLum(hdrCapability.maxLum);
2137     screenHdrCapability.SetMaxAverageLum(hdrCapability.maxAverageLum);
2138     screenHdrCapability.SetMinLum(hdrCapability.minLum);
2139     screenHdrCapability.SetHdrFormats(hdrFormats);
2140     return StatusCode::SUCCESS;
2141 }
2142 
GetScreenTypeLocked(ScreenId id,RSScreenType & type) const2143 int32_t RSScreenManager::GetScreenTypeLocked(ScreenId id, RSScreenType& type) const
2144 {
2145     auto screensIt = screens_.find(id);
2146     if (screensIt == screens_.end() || screensIt->second == nullptr) {
2147         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2148         return StatusCode::SCREEN_NOT_FOUND;
2149     }
2150 
2151     type = screensIt->second->GetScreenType();
2152     return StatusCode::SUCCESS;
2153 }
2154 
SetScreenSkipFrameInterval(ScreenId id,uint32_t skipFrameInterval)2155 int32_t RSScreenManager::SetScreenSkipFrameInterval(ScreenId id, uint32_t skipFrameInterval)
2156 {
2157     auto screen = GetScreen(id);
2158     if (screen == nullptr) {
2159         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2160         return StatusCode::SCREEN_NOT_FOUND;
2161     }
2162     RSScreenModeInfo screenModeInfo;
2163     // use the refresh rate of the physical screen as the maximum refresh rate
2164     GetDefaultScreenActiveMode(screenModeInfo);
2165     // guaranteed screen refresh rate at least 1
2166     if (skipFrameInterval == 0 || (skipFrameInterval > screenModeInfo.GetScreenRefreshRate())) {
2167         RS_LOGE("%{public}s: screen %{public}" PRIu64 " is INVALID_ARGUMENTS.", __func__, id);
2168         return INVALID_ARGUMENTS;
2169     }
2170     screen->SetScreenSkipFrameInterval(skipFrameInterval);
2171     screen->SetEqualVsyncPeriod(skipFrameInterval == 1);
2172     RS_LOGI("%{public}s: screen(id %" PRIu64 "), skipFrameInterval(%d).",
2173         __func__, id, skipFrameInterval);
2174     return StatusCode::SUCCESS;
2175 }
2176 
SetVirtualScreenRefreshRate(ScreenId id,uint32_t maxRefreshRate,uint32_t & actualRefreshRate)2177 int32_t RSScreenManager::SetVirtualScreenRefreshRate(ScreenId id, uint32_t maxRefreshRate, uint32_t& actualRefreshRate)
2178 {
2179     std::lock_guard<std::mutex> lock(mutex_);
2180     auto screensIt = screens_.find(id);
2181     if (screensIt == screens_.end() || screensIt->second == nullptr) {
2182         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2183         return StatusCode::SCREEN_NOT_FOUND;
2184     }
2185     if (!screensIt->second->IsVirtual()) {
2186         RS_LOGW("%{public}s: Not Support for screen:%{public}" PRIu64, __func__, id);
2187         return StatusCode::SCREEN_NOT_FOUND;
2188     }
2189     if (maxRefreshRate == 0) {
2190         RS_LOGW("%{public}s: Invalid maxRefreshRate:%{public}u.", __func__, maxRefreshRate);
2191         return StatusCode::INVALID_ARGUMENTS;
2192     }
2193     if (maxRefreshRate > MAX_VIRTUAL_SCREEN_REFRESH_RATE) {
2194         maxRefreshRate = MAX_VIRTUAL_SCREEN_REFRESH_RATE;
2195     }
2196     screensIt->second->SetScreenExpectedRefreshRate(maxRefreshRate);
2197     RS_LOGI("%{public}s: screen(id %" PRIu64 "), maxRefreshRate(%d).",
2198         __func__, id, maxRefreshRate);
2199     actualRefreshRate = maxRefreshRate;
2200     return StatusCode::SUCCESS;
2201 }
2202 
SetEqualVsyncPeriod(ScreenId id,bool isEqualVsyncPeriod)2203 void RSScreenManager::SetEqualVsyncPeriod(ScreenId id, bool isEqualVsyncPeriod)
2204 {
2205     std::lock_guard<std::mutex> lock(mutex_);
2206     auto screensIt = screens_.find(id);
2207     if (screensIt == screens_.end() || screensIt->second == nullptr) {
2208         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2209         return;
2210     }
2211     screensIt->second->SetEqualVsyncPeriod(isEqualVsyncPeriod);
2212     return;
2213 }
2214 
GetDisplayIdentificationData(ScreenId id,uint8_t & outPort,std::vector<uint8_t> & edidData) const2215 int32_t RSScreenManager::GetDisplayIdentificationData(ScreenId id, uint8_t& outPort,
2216     std::vector<uint8_t>& edidData) const
2217 {
2218     auto screen = GetScreen(id);
2219     if (screen == nullptr) {
2220         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2221         return SCREEN_NOT_FOUND;
2222     }
2223 
2224     return screen->GetDisplayIdentificationData(outPort, edidData);
2225 }
2226 
GetPixelFormatLocked(ScreenId id,GraphicPixelFormat & pixelFormat) const2227 int32_t RSScreenManager::GetPixelFormatLocked(ScreenId id, GraphicPixelFormat& pixelFormat) const
2228 {
2229     auto screensIt = screens_.find(id);
2230     if (screensIt == screens_.end() || screensIt->second == nullptr) {
2231         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2232         return StatusCode::SCREEN_NOT_FOUND;
2233     }
2234     return screensIt->second->GetPixelFormat(pixelFormat);
2235 }
2236 
SetPixelFormatLocked(ScreenId id,GraphicPixelFormat pixelFormat)2237 int32_t RSScreenManager::SetPixelFormatLocked(ScreenId id, GraphicPixelFormat pixelFormat)
2238 {
2239     auto screensIt = screens_.find(id);
2240     if (screensIt == screens_.end() || screensIt->second == nullptr) {
2241         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2242         return StatusCode::SCREEN_NOT_FOUND;
2243     }
2244     return screensIt->second->SetPixelFormat(pixelFormat);
2245 }
2246 
GetScreenSupportedHDRFormatsLocked(ScreenId id,std::vector<ScreenHDRFormat> & hdrFormats) const2247 int32_t RSScreenManager::GetScreenSupportedHDRFormatsLocked(ScreenId id, std::vector<ScreenHDRFormat>& hdrFormats) const
2248 {
2249     auto screensIt = screens_.find(id);
2250     if (screensIt == screens_.end() || screensIt->second == nullptr) {
2251         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2252         return StatusCode::SCREEN_NOT_FOUND;
2253     }
2254     return screensIt->second->GetScreenSupportedHDRFormats(hdrFormats);
2255 }
2256 
GetScreenHDRFormatLocked(ScreenId id,ScreenHDRFormat & hdrFormat) const2257 int32_t RSScreenManager::GetScreenHDRFormatLocked(ScreenId id, ScreenHDRFormat& hdrFormat) const
2258 {
2259     auto screensIt = screens_.find(id);
2260     if (screensIt == screens_.end() || screensIt->second == nullptr) {
2261         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2262         return StatusCode::SCREEN_NOT_FOUND;
2263     }
2264     return screensIt->second->GetScreenHDRFormat(hdrFormat);
2265 }
2266 
SetScreenHDRFormatLocked(ScreenId id,int32_t modeIdx)2267 int32_t RSScreenManager::SetScreenHDRFormatLocked(ScreenId id, int32_t modeIdx)
2268 {
2269     auto screensIt = screens_.find(id);
2270     if (screensIt == screens_.end() || screensIt->second == nullptr) {
2271         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2272         return StatusCode::SCREEN_NOT_FOUND;
2273     }
2274     return screensIt->second->SetScreenHDRFormat(modeIdx);
2275 }
2276 
GetScreenSupportedColorSpacesLocked(ScreenId id,std::vector<GraphicCM_ColorSpaceType> & colorSpaces) const2277 int32_t RSScreenManager::GetScreenSupportedColorSpacesLocked(
2278     ScreenId id, std::vector<GraphicCM_ColorSpaceType>& colorSpaces) const
2279 {
2280     auto screensIt = screens_.find(id);
2281     if (screensIt == screens_.end() || screensIt->second == nullptr) {
2282         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2283         return StatusCode::SCREEN_NOT_FOUND;
2284     }
2285     return screensIt->second->GetScreenSupportedColorSpaces(colorSpaces);
2286 }
2287 
GetScreenColorSpaceLocked(ScreenId id,GraphicCM_ColorSpaceType & colorSpace) const2288 int32_t RSScreenManager::GetScreenColorSpaceLocked(ScreenId id, GraphicCM_ColorSpaceType& colorSpace) const
2289 {
2290     auto screensIt = screens_.find(id);
2291     if (screensIt == screens_.end() || screensIt->second == nullptr) {
2292         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2293         return StatusCode::SCREEN_NOT_FOUND;
2294     }
2295     return screensIt->second->GetScreenColorSpace(colorSpace);
2296 }
2297 
SetScreenColorSpace(ScreenId id,GraphicCM_ColorSpaceType colorSpace)2298 int32_t RSScreenManager::SetScreenColorSpace(ScreenId id, GraphicCM_ColorSpaceType colorSpace)
2299 {
2300     auto screen = GetScreen(id);
2301     if (screen == nullptr) {
2302         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2303         return StatusCode::SCREEN_NOT_FOUND;
2304     }
2305     return screen->SetScreenColorSpace(colorSpace);
2306 }
2307 
GetScreenSupportedColorGamuts(ScreenId id,std::vector<ScreenColorGamut> & mode) const2308 int32_t RSScreenManager::GetScreenSupportedColorGamuts(ScreenId id, std::vector<ScreenColorGamut>& mode) const
2309 {
2310     std::lock_guard<std::mutex> lock(mutex_);
2311     return GetScreenSupportedColorGamutsLocked(id, mode);
2312 }
2313 
GetScreenSupportedMetaDataKeys(ScreenId id,std::vector<ScreenHDRMetadataKey> & keys) const2314 int32_t RSScreenManager::GetScreenSupportedMetaDataKeys(ScreenId id, std::vector<ScreenHDRMetadataKey>& keys) const
2315 {
2316     std::lock_guard<std::mutex> lock(mutex_);
2317     return GetScreenSupportedMetaDataKeysLocked(id, keys);
2318 }
2319 
GetActualScreensNum() const2320 uint32_t RSScreenManager::GetActualScreensNum() const
2321 {
2322     std::lock_guard<std::mutex> lock(mutex_);
2323     uint32_t num = 0;
2324     for (const auto& [id, screen] : screens_) {
2325         if (!screen) {
2326             RS_LOGE("%{public}s: screen %{public}" PRIu64 " not found.", __func__, id);
2327             continue;
2328         }
2329         if (!screen->IsVirtual()) {
2330             num += 1;
2331         } else {
2332             if (screen->GetProducerSurface()) {
2333                 num += 1;
2334             }
2335         }
2336     }
2337     return num;
2338 }
2339 
GetActualScreenMaxResolution() const2340 ScreenInfo RSScreenManager::GetActualScreenMaxResolution() const
2341 {
2342     std::lock_guard<std::mutex> lock(mutex_);
2343     uint32_t maxResolution = 0;
2344     ScreenId maxScreenId = INVALID_SCREEN_ID;
2345     for (const auto& [id, screen] : screens_) {
2346         if (!screen || screen->IsVirtual()) {
2347             RS_LOGE("%{public}s: screen %{public}" PRIu64 " not found.", __func__, id);
2348             continue;
2349         }
2350         uint32_t resolution = screen->PhyWidth() * screen->PhyHeight();
2351         if (resolution > maxResolution) {
2352             maxScreenId = id;
2353             maxResolution = resolution;
2354         }
2355     }
2356     return QueryScreenInfoLocked(maxScreenId);
2357 }
2358 
GetScreenColorGamut(ScreenId id,ScreenColorGamut & mode) const2359 int32_t RSScreenManager::GetScreenColorGamut(ScreenId id, ScreenColorGamut& mode) const
2360 {
2361     std::lock_guard<std::mutex> lock(mutex_);
2362     return GetScreenColorGamutLocked(id, mode);
2363 }
2364 
GetScreenGamutMap(ScreenId id,ScreenGamutMap & mode) const2365 int32_t RSScreenManager::GetScreenGamutMap(ScreenId id, ScreenGamutMap& mode) const
2366 {
2367     std::lock_guard<std::mutex> lock(mutex_);
2368     return GetScreenGamutMapLocked(id, mode);
2369 }
2370 
GetScreenHDRCapability(ScreenId id,RSScreenHDRCapability & screenHdrCapability) const2371 int32_t RSScreenManager::GetScreenHDRCapability(ScreenId id, RSScreenHDRCapability& screenHdrCapability) const
2372 {
2373     std::lock_guard<std::mutex> lock(mutex_);
2374     return GetScreenHDRCapabilityLocked(id, screenHdrCapability);
2375 }
2376 
GetScreenType(ScreenId id,RSScreenType & type) const2377 int32_t RSScreenManager::GetScreenType(ScreenId id, RSScreenType& type) const
2378 {
2379     std::lock_guard<std::mutex> lock(mutex_);
2380     return GetScreenTypeLocked(id, type);
2381 }
2382 
GetPixelFormat(ScreenId id,GraphicPixelFormat & pixelFormat) const2383 int32_t RSScreenManager::GetPixelFormat(ScreenId id, GraphicPixelFormat& pixelFormat) const
2384 {
2385     std::lock_guard<std::mutex> lock(mutex_);
2386     return GetPixelFormatLocked(id, pixelFormat);
2387 }
2388 
SetPixelFormat(ScreenId id,GraphicPixelFormat pixelFormat)2389 int32_t RSScreenManager::SetPixelFormat(ScreenId id, GraphicPixelFormat pixelFormat)
2390 {
2391     std::lock_guard<std::mutex> lock(mutex_);
2392     return SetPixelFormatLocked(id, pixelFormat);
2393 }
2394 
GetScreenSupportedHDRFormats(ScreenId id,std::vector<ScreenHDRFormat> & hdrFormats) const2395 int32_t RSScreenManager::GetScreenSupportedHDRFormats(ScreenId id, std::vector<ScreenHDRFormat>& hdrFormats) const
2396 {
2397     std::lock_guard<std::mutex> lock(mutex_);
2398     return GetScreenSupportedHDRFormatsLocked(id, hdrFormats);
2399 }
2400 
GetScreenHDRFormat(ScreenId id,ScreenHDRFormat & hdrFormat) const2401 int32_t RSScreenManager::GetScreenHDRFormat(ScreenId id, ScreenHDRFormat& hdrFormat) const
2402 {
2403     std::lock_guard<std::mutex> lock(mutex_);
2404     return GetScreenHDRFormatLocked(id, hdrFormat);
2405 }
2406 
SetScreenHDRFormat(ScreenId id,int32_t modeIdx)2407 int32_t RSScreenManager::SetScreenHDRFormat(ScreenId id, int32_t modeIdx)
2408 {
2409     std::lock_guard<std::mutex> lock(mutex_);
2410     return SetScreenHDRFormatLocked(id, modeIdx);
2411 }
2412 
GetScreenSupportedColorSpaces(ScreenId id,std::vector<GraphicCM_ColorSpaceType> & colorSpaces) const2413 int32_t RSScreenManager::GetScreenSupportedColorSpaces(
2414     ScreenId id, std::vector<GraphicCM_ColorSpaceType>& colorSpaces) const
2415 {
2416     std::lock_guard<std::mutex> lock(mutex_);
2417     return GetScreenSupportedColorSpacesLocked(id, colorSpaces);
2418 }
2419 
GetScreenColorSpace(ScreenId id,GraphicCM_ColorSpaceType & colorSpace) const2420 int32_t RSScreenManager::GetScreenColorSpace(ScreenId id, GraphicCM_ColorSpaceType& colorSpace) const
2421 {
2422     std::lock_guard<std::mutex> lock(mutex_);
2423     return GetScreenColorSpaceLocked(id, colorSpace);
2424 }
2425 
MarkPowerOffNeedProcessOneFrame()2426 void RSScreenManager::MarkPowerOffNeedProcessOneFrame()
2427 {
2428     powerOffNeedProcessOneFrame_ = true;
2429 }
2430 
ResetPowerOffNeedProcessOneFrame()2431 void RSScreenManager::ResetPowerOffNeedProcessOneFrame()
2432 {
2433     powerOffNeedProcessOneFrame_ = false;
2434 }
2435 
GetPowerOffNeedProcessOneFrame() const2436 bool RSScreenManager::GetPowerOffNeedProcessOneFrame() const
2437 {
2438     return powerOffNeedProcessOneFrame_;
2439 }
2440 
IsScreenPowerOff(ScreenId id) const2441 bool RSScreenManager::IsScreenPowerOff(ScreenId id) const
2442 {
2443     std::shared_lock<std::shared_mutex> lock(powerStatusMutex_);
2444     if (screenPowerStatus_.count(id) == 0) {
2445         RS_LOGD("%{public}s: screen %{public}" PRIu64 " not found.", __func__, id);
2446         return false;
2447     }
2448     return screenPowerStatus_.at(id) == GraphicDispPowerStatus::GRAPHIC_POWER_STATUS_SUSPEND ||
2449         screenPowerStatus_.at(id) == GraphicDispPowerStatus::GRAPHIC_POWER_STATUS_OFF;
2450 }
2451 
DisablePowerOffRenderControl(ScreenId id)2452 void RSScreenManager::DisablePowerOffRenderControl(ScreenId id)
2453 {
2454     std::lock_guard<std::mutex> lock(renderControlMutex_);
2455     RS_LOGI("%{public}s: Add Screen_%{public}" PRIu64 " for"
2456         "disable power-off render control.", __func__, id);
2457     disableRenderControlScreens_.insert(id);
2458 }
2459 
GetDisableRenderControlScreensCount() const2460 int RSScreenManager::GetDisableRenderControlScreensCount() const
2461 {
2462     std::lock_guard<std::mutex> lock(renderControlMutex_);
2463     return disableRenderControlScreens_.size();
2464 }
2465 
SetVirtualScreenStatus(ScreenId id,VirtualScreenStatus screenStatus)2466 bool RSScreenManager::SetVirtualScreenStatus(ScreenId id, VirtualScreenStatus screenStatus)
2467 {
2468     std::lock_guard<std::mutex> lock(mutex_);
2469     auto screensIt = screens_.find(id);
2470     if (screensIt == screens_.end() || screensIt->second == nullptr) {
2471         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2472         return false;
2473     }
2474     RS_LOGW("RSScreenManager::%{public}s: id %{public}" PRIu64 " status:%{public}d",
2475         __func__, id, screenStatus);
2476     return screensIt->second->SetVirtualScreenStatus(screenStatus);
2477 }
2478 
GetVirtualScreenStatus(ScreenId id) const2479 VirtualScreenStatus RSScreenManager::GetVirtualScreenStatus(ScreenId id) const
2480 {
2481     std::lock_guard<std::mutex> lock(mutex_);
2482     auto screensIt = screens_.find(id);
2483     if (screensIt == screens_.end() || screensIt->second == nullptr) {
2484         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2485         return VirtualScreenStatus::VIRTUAL_SCREEN_INVALID_STATUS;
2486     }
2487     return screensIt->second->GetVirtualScreenStatus();
2488 }
2489 
GetDisplayPropertyForHardCursor(uint32_t screenId)2490 bool RSScreenManager::GetDisplayPropertyForHardCursor(uint32_t screenId)
2491 {
2492     auto screen = GetScreen(screenId);
2493     if (screen == nullptr) {
2494         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu32 ".", __func__, screenId);
2495         return false;
2496     }
2497     return screen->GetDisplayPropertyForHardCursor();
2498 }
2499 
SetScreenHasProtectedLayer(ScreenId id,bool hasProtectedLayer)2500 void RSScreenManager::SetScreenHasProtectedLayer(ScreenId id, bool hasProtectedLayer)
2501 {
2502     std::lock_guard<std::mutex> lock(mutex_);
2503     auto screensIt = screens_.find(id);
2504     if (screensIt == screens_.end() || screensIt->second == nullptr) {
2505         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2506         return;
2507     }
2508     screensIt->second->SetHasProtectedLayer(hasProtectedLayer);
2509 }
2510 
IsVisibleRectSupportRotation(ScreenId id) const2511 bool RSScreenManager::IsVisibleRectSupportRotation(ScreenId id) const
2512 {
2513     std::lock_guard<std::mutex> lock(mutex_);
2514     auto mirrorScreen = screens_.find(id);
2515     if (mirrorScreen == screens_.end() || mirrorScreen->second == nullptr) {
2516         RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2517         return false;
2518     }
2519 
2520     return mirrorScreen->second->GetVisibleRectSupportRotation();
2521 }
2522 
SetScreenSwitchStatus(bool flag)2523 void RSScreenManager::SetScreenSwitchStatus(bool flag)
2524 {
2525     isScreenSwitching_ = flag;
2526 }
2527 
IsScreenSwitching() const2528 bool RSScreenManager::IsScreenSwitching() const
2529 {
2530     return isScreenSwitching_;
2531 }
2532 
SetScreenLinearMatrix(ScreenId id,const std::vector<float> & matrix)2533 int32_t RSScreenManager::SetScreenLinearMatrix(ScreenId id, const std::vector<float>& matrix)
2534 {
2535     auto task = [this, id, matrix]() -> void {
2536         auto screen = GetScreen(id);
2537         if (screen == nullptr) {
2538             RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2539             return;
2540         }
2541         screen->SetScreenLinearMatrix(matrix);
2542     };
2543 	// SetScreenLinearMatrix is SMQ API, which can only be executed in RSHardwareThread.
2544     RSHardwareThread::Instance().PostTask(task);
2545     return StatusCode::SUCCESS;
2546 }
2547 
TriggerCallbacks(ScreenId id,ScreenEvent event,ScreenChangeReason reason) const2548 void RSScreenManager::TriggerCallbacks(ScreenId id, ScreenEvent event, ScreenChangeReason reason) const
2549 {
2550     std::shared_lock<std::shared_mutex> lock(screenChangeCallbackMutex_);
2551     for (const auto& cb : screenChangeCallbacks_) {
2552         cb->OnScreenChanged(id, event, reason);
2553     }
2554 }
2555 
GetScreen(ScreenId id) const2556 std::shared_ptr<OHOS::Rosen::RSScreen> RSScreenManager::GetScreen(ScreenId id) const
2557 {
2558     std::lock_guard<std::mutex> lock(mutex_);
2559     auto iter = screens_.find(id);
2560     if (iter == screens_.end() || iter->second == nullptr) {
2561         return nullptr;
2562     }
2563     return iter->second;
2564 }
2565 } // namespace impl
2566 
CreateOrGetScreenManager()2567 sptr<RSScreenManager> CreateOrGetScreenManager()
2568 {
2569     return impl::RSScreenManager::GetInstance();
2570 }
2571 } // namespace Rosen
2572 } // namespace OHOS
2573