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