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 <parameter.h>
19 #include <parameters.h>
20 #include "param/sys_param.h"
21
22 #include "common/rs_optional_trace.h"
23 #include "common/rs_switching_thread.h"
24 #include "display_engine/rs_color_temperature.h"
25 #include "gfx/first_frame_notifier/rs_first_frame_notifier.h"
26 #include "graphic_feature_param_manager.h"
27 #include "hgm_core.h"
28 #include "pipeline/hardware_thread/rs_hardware_thread.h"
29 #include "pipeline/main_thread/rs_main_thread.h"
30 #include "pipeline/rs_screen_render_node.h"
31 #include "platform/common/rs_log.h"
32 #include "platform/common/rs_system_properties.h"
33 #include "rs_screen.h"
34 #include "rs_trace.h"
35 #include "screen_manager/rs_screen_node_listener.h"
36 #include "vsync_sampler.h"
37
38 #undef LOG_TAG
39 #define LOG_TAG "RSScreenManager"
40
41 namespace OHOS {
42 namespace Rosen {
43 #ifdef RS_SUBSCRIBE_SENSOR_ENABLE
44 namespace {
45 constexpr float ANGLE_MIN_VAL = 0.0F;
46 constexpr float ANGLE_MAX_VAL = 180.0F;
47 constexpr int32_t SENSOR_SUCCESS = 0;
48 constexpr int32_t POSTURE_INTERVAL = 4000000;
49 constexpr uint16_t SENSOR_EVENT_FIRST_DATA = 0;
50 constexpr float HALF_FOLDED_MAX_THRESHOLD = 140.0F;
51 constexpr float OPEN_HALF_FOLDED_MIN_THRESHOLD = 25.0F;
52 constexpr uint32_t WAIT_FOR_ACTIVE_SCREEN_ID_TIMEOUT = 1000;
53 constexpr uint32_t WAIT_FOR_STATUS_TASK_TIMEOUT = 1000; // 1000ms
54 constexpr uint32_t MAX_VIRTUAL_SCREEN_NUM = 64;
55 constexpr uint32_t MAX_VIRTUAL_SCREEN_WIDTH = 65536;
56 constexpr uint32_t MAX_VIRTUAL_SCREEN_HEIGHT = 65536;
57 constexpr uint32_t MAX_VIRTUAL_SCREEN_REFRESH_RATE = 120;
58 constexpr uint32_t ORIGINAL_FOLD_SCREEN_AMOUNT = 2;
59 constexpr uint32_t MAX_BLACK_LIST_NUM = 1024;
60 const std::string FORCE_REFRESH_ONE_FRAME_TASK_NAME = "ForceRefreshOneFrameIfNoRNV";
SensorPostureDataCallback(SensorEvent * event)61 void SensorPostureDataCallback(SensorEvent* event)
62 {
63 CreateOrGetScreenManager()->HandlePostureData(event);
64 }
65 } // namespace
66 #endif
67 using namespace HiviewDFX;
68 namespace impl {
69 std::once_flag RSScreenManager::createFlag_;
70 sptr<OHOS::Rosen::RSScreenManager> RSScreenManager::instance_ = nullptr;
71
GetInstance()72 sptr<OHOS::Rosen::RSScreenManager> RSScreenManager::GetInstance() noexcept
73 {
74 std::call_once(createFlag_, []() {
75 instance_ = new RSScreenManager();
76 });
77
78 return instance_;
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(screenMapMutex_, 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 return false;
271 }
272 }
273 return true;
274 }
275
PostForceRefreshTask()276 void RSScreenManager::PostForceRefreshTask()
277 {
278 auto mainThread = RSMainThread::Instance();
279 if (mainThread != nullptr && !mainThread->IsRequestedNextVSync()) {
280 mainThread->PostTask([mainThread]() {
281 RS_TRACE_NAME("No RNV, ForceRefreshOneFrame");
282 mainThread->SetDirtyFlag();
283 mainThread->RequestNextVSync();
284 }, FORCE_REFRESH_ONE_FRAME_TASK_NAME, 20); // delay 20ms
285 }
286 }
287
RemoveForceRefreshTask()288 void RSScreenManager::RemoveForceRefreshTask()
289 {
290 auto mainThread = RSMainThread::Instance();
291 if (mainThread != nullptr) {
292 mainThread->RemoveTask(FORCE_REFRESH_ONE_FRAME_TASK_NAME);
293 }
294 }
295
OnHotPlug(std::shared_ptr<HdiOutput> & output,bool connected,void * data)296 void RSScreenManager::OnHotPlug(std::shared_ptr<HdiOutput>& output, bool connected, void* data)
297 {
298 if (output == nullptr) {
299 RS_LOGE("%{public}s: output is nullptr.", __func__);
300 return;
301 }
302
303 RSScreenManager* screenManager = nullptr;
304 if (data != nullptr) {
305 RS_LOGI("%{public}s: data is not nullptr.", __func__);
306 screenManager = static_cast<RSScreenManager*>(data);
307 } else {
308 RS_LOGI("%{public}s: data is nullptr.", __func__);
309 screenManager = static_cast<RSScreenManager*>(RSScreenManager::GetInstance().GetRefPtr());
310 }
311
312 if (screenManager == nullptr) {
313 RS_LOGE("%{public}s: Failed to find RSScreenManager instance.", __func__);
314 return;
315 }
316
317 screenManager->OnHotPlugEvent(output, connected);
318 }
319
OnHotPlugEvent(std::shared_ptr<HdiOutput> & output,bool connected)320 void RSScreenManager::OnHotPlugEvent(std::shared_ptr<HdiOutput>& output, bool connected)
321 {
322 {
323 std::lock_guard<std::mutex> lock(hotPlugAndConnectMutex_);
324
325 ScreenId id = ToScreenId(output->GetScreenId());
326 if (pendingHotPlugEvents_.find(id) != pendingHotPlugEvents_.end()) {
327 RS_LOGE("%{public}s: screen %{public}" PRIu64 "is covered.", __func__, id);
328 }
329 pendingHotPlugEvents_[id] = ScreenHotPlugEvent{output, connected};
330 RS_LOGI("%{public}s: screen %{public}" PRIu64 "is %{public}s, event has been saved", __func__, id,
331 connected ? "connected" : "disconnected");
332 }
333
334 // This func would be called in main thread first time immediately after calling composer_->RegScreenHotplug,
335 // but at this time the RSMainThread object would not be ready to handle this, so we need to call
336 // ProcessScreenHotPlugEvents() after this func in RSScreenManager::Init().
337
338 // Normally, this func would be called in hdi's hw-ipc threads(but sometimes in main thread, maybe),
339 // so we should notify the RSMainThread to postTask to call ProcessScreenHotPlugEvents().
340 auto mainThread = RSMainThread::Instance();
341 if (mainThread == nullptr) {
342 RS_LOGE("%{public}s: mainThread is nullptr.", __func__);
343 return;
344 }
345 RS_LOGI("%{public}s: mainThread->RequestNextVSync()", __func__);
346 mainThread->RequestNextVSync();
347 }
348
OnRefresh(ScreenId id,void * data)349 void RSScreenManager::OnRefresh(ScreenId id, void* data)
350 {
351 RSScreenManager* screenManager = nullptr;
352 if (data != nullptr) {
353 screenManager = static_cast<RSScreenManager*>(data);
354 } else {
355 RS_LOGI("%{public}s: data is nullptr.", __func__);
356 screenManager = static_cast<RSScreenManager*>(RSScreenManager::GetInstance().GetRefPtr());
357 }
358
359 if (screenManager == nullptr) {
360 RS_LOGE("%{public}s: Failed to find RSScreenManager instance.", __func__);
361 return;
362 }
363 screenManager->OnRefreshEvent(id);
364 }
365
OnRefreshEvent(ScreenId id)366 void RSScreenManager::OnRefreshEvent(ScreenId id)
367 {
368 auto mainThread = RSMainThread::Instance();
369 if (mainThread == nullptr) {
370 RS_LOGE("%{public}s: mainThread is nullptr.", __func__);
371 return;
372 }
373 mainThread->PostTask([mainThread]() {
374 mainThread->SetForceUpdateUniRenderFlag(true);
375 mainThread->RequestNextVSync();
376 });
377 }
378
OnHwcDead(void * data)379 void RSScreenManager::OnHwcDead(void* data)
380 {
381 RS_LOGW("%{public}s: The composer_host is already dead.", __func__);
382 RSScreenManager* screenManager = static_cast<RSScreenManager*>(RSScreenManager::GetInstance().GetRefPtr());
383 if (screenManager == nullptr) {
384 RS_LOGE("%{public}s: Failed to find RSScreenManager instance.", __func__);
385 return;
386 }
387
388 // Automatically recover when composer host dies.
389 screenManager->CleanAndReinit();
390 }
391
OnHwcDeadEvent()392 void RSScreenManager::OnHwcDeadEvent()
393 {
394 // Only clean the physical screen when hwc dead
395 std::map<ScreenId, std::shared_ptr<OHOS::Rosen::RSScreen>> screens;
396 {
397 std::lock_guard<std::mutex> lock(screenMapMutex_);
398 for (auto it = screens_.begin(); it != screens_.end();) {
399 if (it->second && !it->second->IsVirtual()) {
400 auto node = screens_.extract(it++);
401 screens.insert(std::move(node));
402 } else {
403 ++it;
404 }
405 }
406 }
407 #ifdef RS_ENABLE_GPU
408 for (const auto& [_, screen] : screens) {
409 RSHardwareThread::Instance().ClearFrameBuffers(screen->GetOutput());
410 }
411 #endif
412 isHwcDead_ = true;
413 defaultScreenId_ = INVALID_SCREEN_ID;
414 }
415
OnScreenVBlankIdle(uint32_t devId,uint64_t ns,void * data)416 void RSScreenManager::OnScreenVBlankIdle(uint32_t devId, uint64_t ns, void* data)
417 {
418 RS_LOGI("%{public}s: devId:%{public}u, ns:" RSPUBU64, __func__, devId, ns);
419 RS_TRACE_NAME_FMT("OnScreenVBlankIdle devId:%u, ns:%lu", devId, ns);
420 CreateVSyncSampler()->StartSample(true);
421 RSScreenManager* screenManager = static_cast<RSScreenManager*>(RSScreenManager::GetInstance().GetRefPtr());
422 if (screenManager == nullptr) {
423 RS_LOGE("%{public}s: Failed to find RSScreenManager instance.", __func__);
424 return;
425 }
426 screenManager->OnScreenVBlankIdleEvent(devId, ns);
427 }
428
OnScreenVBlankIdleEvent(uint32_t devId,uint64_t ns)429 void RSScreenManager::OnScreenVBlankIdleEvent(uint32_t devId, uint64_t ns)
430 {
431 ScreenId screenId = ToScreenId(devId);
432 if (GetScreen(screenId) == nullptr) {
433 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, screenId);
434 return;
435 }
436 #ifdef RS_ENABLE_GPU
437 RSHardwareThread::Instance().PostTask([screenId, ns]() {
438 RSHardwareThread::Instance().OnScreenVBlankIdleCallback(screenId, ns);
439 });
440 #endif
441 }
442
CleanAndReinit()443 void RSScreenManager::CleanAndReinit()
444 {
445 auto task = [this]() {
446 OnHwcDeadEvent();
447 if (!composer_) {
448 RS_LOGE("CleanAndReinit: Failed to get composer.");
449 return;
450 }
451 composer_->ResetDevice();
452 if (!Init()) {
453 RS_LOGE("CleanAndReinit: Reinit failed");
454 return;
455 }
456 };
457
458 auto renderType = RSUniRenderJudgement::GetUniRenderEnabledType();
459 if (renderType != UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
460 RSMainThread::Instance()->PostTask(std::move(task));
461 } else {
462 #ifdef RS_ENABLE_GPU
463 RSHardwareThread::Instance().PostTask(std::move(task));
464 #endif
465 }
466 }
467
TrySimpleProcessHotPlugEvents()468 bool RSScreenManager::TrySimpleProcessHotPlugEvents()
469 {
470 std::lock_guard<std::mutex> lock(hotPlugAndConnectMutex_);
471 if (!isHwcDead_ && pendingHotPlugEvents_.empty() && pendingConnectedIds_.empty()) {
472 mipiCheckInFirstHotPlugEvent_ = true;
473 return true;
474 }
475 RS_LOGI("%{public}s: isHwcDead_:%{public}d, pendingHotPlugEventsSize:%{public}zu, "
476 "pendingConnectedIdsSize:%{public}zu",
477 __func__, isHwcDead_.load(), pendingHotPlugEvents_.size(), pendingConnectedIds_.size());
478 return false;
479 }
480
ProcessScreenHotPlugEvents()481 void RSScreenManager::ProcessScreenHotPlugEvents()
482 {
483 std::map<ScreenId, ScreenHotPlugEvent> pendingHotPlugEvents;
484 {
485 std::lock_guard<std::mutex> lock(hotPlugAndConnectMutex_);
486 pendingHotPlugEvents.swap(pendingHotPlugEvents_);
487 }
488 for (auto& [_, event] : pendingHotPlugEvents) {
489 if (event.output == nullptr) {
490 RS_LOGE("%{public}s: output is nullptr.", __func__);
491 continue;
492 }
493 if (event.connected) {
494 ProcessScreenConnected(event.output);
495 AddScreenToHgm(event.output);
496 } else {
497 ProcessScreenDisConnected(event.output);
498 RemoveScreenFromHgm(event.output);
499 }
500 }
501 ProcessPendingConnections();
502 isHwcDead_ = false;
503 mipiCheckInFirstHotPlugEvent_ = true;
504 }
505
ProcessPendingConnections()506 void RSScreenManager::ProcessPendingConnections()
507 {
508 std::vector<ScreenId> pendingConnectedIds;
509 {
510 std::lock_guard<std::mutex> lock(hotPlugAndConnectMutex_);
511 pendingConnectedIds.swap(pendingConnectedIds_);
512 }
513 for (auto id : pendingConnectedIds) {
514 NotifyScreenNodeChange(id, true);
515 if (!isHwcDead_) {
516 TriggerCallbacks(id, ScreenEvent::CONNECTED);
517 } else if (id != 0 && MultiScreenParam::IsRsReportHwcDead()) {
518 TriggerCallbacks(id, ScreenEvent::CONNECTED, ScreenChangeReason::HWCDEAD);
519 }
520 auto screen = GetScreen(id);
521 if (screen == nullptr) {
522 continue;
523 }
524
525 ScreenRotation rotation = ScreenRotation::INVALID_SCREEN_ROTATION;
526 int32_t backLightLevel = INVALID_BACKLIGHT_VALUE;
527 {
528 std::shared_lock<std::shared_mutex> lock(backLightAndCorrectionMutex_);
529 if (auto iter = screenCorrection_.find(id); iter != screenCorrection_.end()) {
530 rotation = iter->second;
531 }
532 if (auto iter = screenBacklight_.find(id); iter != screenBacklight_.end()) {
533 backLightLevel = static_cast<int32_t>(iter->second);
534 }
535 }
536 if (rotation != ScreenRotation::INVALID_SCREEN_ROTATION) {
537 screen->SetScreenCorrection(rotation);
538 }
539
540 bool screenPowerOn = false;
541 {
542 std::shared_lock<std::shared_mutex> lock(powerStatusMutex_);
543 auto iter = screenPowerStatus_.find(id);
544 screenPowerOn = (iter == screenPowerStatus_.end() || iter->second == ScreenPowerStatus::POWER_STATUS_ON);
545 }
546 if (backLightLevel != INVALID_BACKLIGHT_VALUE && screenPowerOn) {
547 screen->SetScreenBacklight(static_cast<uint32_t>(backLightLevel));
548 auto mainThread = RSMainThread::Instance();
549 mainThread->PostTask([mainThread]() {
550 mainThread->SetDirtyFlag();
551 });
552 mainThread->ForceRefreshForUni();
553 }
554 }
555 }
556
AddScreenToHgm(std::shared_ptr<HdiOutput> & output)557 void RSScreenManager::AddScreenToHgm(std::shared_ptr<HdiOutput>& output)
558 {
559 RS_LOGI("%{public}s in", __func__);
560 HgmTaskHandleThread::Instance().PostSyncTask([this, &output] () {
561 auto& hgmCore = OHOS::Rosen::HgmCore::Instance();
562 ScreenId thisId = ToScreenId(output->GetScreenId());
563 auto screen = GetScreen(thisId);
564 if (screen == nullptr) {
565 RS_LOGE("invalid screen id, screen not found : %{public}" PRIu64, thisId);
566 return;
567 }
568
569 int32_t initModeId = 0;
570 auto initMode = screen->GetActiveMode();
571 if (!initMode) {
572 RS_LOGE("%{public}s failed to get initial mode", __func__);
573 } else {
574 initModeId = initMode->id;
575 }
576 const auto& capability = screen->GetCapability();
577 ScreenSize screenSize = {screen->Width(), screen->Height(), capability.phyWidth, capability.phyHeight};
578 RS_LOGI("%{public}s: add screen: w * h: [%{public}u * %{public}u], capability w * h: "
579 "[%{public}u * %{public}u]", __func__, screen->Width(), screen->Height(),
580 capability.phyWidth, capability.phyHeight);
581 if (hgmCore.AddScreen(thisId, initModeId, screenSize)) {
582 RS_LOGE("%{public}s failed to add screen : %{public}" PRIu64, __func__, thisId);
583 return;
584 }
585
586 // for each supported mode, use the index as modeId to add the detailed mode to hgm
587 int32_t modeId = 0;
588 auto supportedModes = screen->GetSupportedModes();
589 for (const auto& mode : supportedModes) {
590 if (hgmCore.AddScreenInfo(thisId, mode.width, mode.height, mode.freshRate, modeId)) {
591 RS_LOGW("failed to add a screen profile to the screen : %{public}" PRIu64, thisId);
592 }
593 modeId++;
594 }
595 });
596 }
597
RemoveScreenFromHgm(std::shared_ptr<HdiOutput> & output)598 void RSScreenManager::RemoveScreenFromHgm(std::shared_ptr<HdiOutput>& output)
599 {
600 RS_LOGI("%{public}s in", __func__);
601 HgmTaskHandleThread::Instance().PostTask([id = ToScreenId(output->GetScreenId())] () {
602 auto& hgmCore = OHOS::Rosen::HgmCore::Instance();
603 RS_LOGI("remove screen, id: %{public}" PRIu64, id);
604 if (hgmCore.RemoveScreen(id)) {
605 RS_LOGW("failed to remove screen : %{public}" PRIu64, id);
606 }
607 });
608 }
609
ProcessScreenConnected(std::shared_ptr<HdiOutput> & output)610 void RSScreenManager::ProcessScreenConnected(std::shared_ptr<HdiOutput>& output)
611 {
612 ScreenId id = ToScreenId(output->GetScreenId());
613 RS_LOGI("%{public}s The screen for id %{public}" PRIu64 " connected.", __func__, id);
614
615 if (GetScreen(id)) {
616 TriggerCallbacks(id, ScreenEvent::DISCONNECTED);
617 RS_LOGW("%{public}s The screen for id %{public}" PRIu64 " already existed.", __func__, id);
618 }
619 auto screen = std::make_shared<RSScreen>(id, false, output, nullptr);
620
621 std::unique_lock<std::mutex> lock(screenMapMutex_);
622 screens_[id] = screen;
623 if (isFoldScreenFlag_ && foldScreenIds_.size() < ORIGINAL_FOLD_SCREEN_AMOUNT) {
624 foldScreenIds_[id] = {true, false};
625 }
626 lock.unlock();
627
628 ScreenId defaultScreenId = defaultScreenId_;
629 if (screen->GetCapability().type == GraphicInterfaceType::GRAPHIC_DISP_INTF_MIPI) {
630 if (!mipiCheckInFirstHotPlugEvent_.exchange(true)) {
631 defaultScreenId = id;
632 }
633 } else if (defaultScreenId == INVALID_SCREEN_ID) {
634 RS_LOGI("%{public}s The screen id %{public}" PRIu64
635 " is set to defaultScreenId. last defaultScreenId is %{public}" PRIu64 ".",
636 __func__, id, defaultScreenId);
637 defaultScreenId = id;
638 }
639 defaultScreenId_ = defaultScreenId;
640
641 uint64_t vsyncEnabledScreenId = JudgeVSyncEnabledScreenWhileHotPlug(id, true);
642 UpdateVsyncEnabledScreenId(vsyncEnabledScreenId);
643 if (vsyncEnabledScreenId == id) {
644 screen->SetScreenVsyncEnabled(true);
645 }
646
647 #ifdef RS_SUBSCRIBE_SENSOR_ENABLE
648 if (isFoldScreenFlag_ && id != 0) {
649 RS_LOGI("%{public}s The externalScreenId_ is set %{public}" PRIu64 ".", __func__, id);
650 externalScreenId_ = id;
651 }
652 #endif
653 std::lock_guard<std::mutex> connectLock(hotPlugAndConnectMutex_);
654 pendingConnectedIds_.emplace_back(id);
655 }
656
ProcessScreenDisConnected(std::shared_ptr<HdiOutput> & output)657 void RSScreenManager::ProcessScreenDisConnected(std::shared_ptr<HdiOutput>& output)
658 {
659 ScreenId id = ToScreenId(output->GetScreenId());
660 RS_LOGW("%{public}s process screen disconnected, id: %{public}" PRIu64, __func__, id);
661 if (auto screen = GetScreen(id)) {
662 TriggerCallbacks(id, ScreenEvent::DISCONNECTED);
663 NotifyScreenNodeChange(id, false);
664 std::lock_guard<std::mutex> lock(screenMapMutex_);
665 screens_.erase(id);
666 RS_LOGI("%{public}s: Screen(id %{public}" PRIu64 ") disconnected.", __func__, id);
667 } else {
668 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
669 }
670 {
671 std::lock_guard<std::shared_mutex> lock(powerStatusMutex_);
672 screenPowerStatus_.erase(id);
673 }
674 {
675 std::lock_guard<std::shared_mutex> lock(backLightAndCorrectionMutex_);
676 screenBacklight_.erase(id);
677 screenCorrection_.erase(id);
678 }
679 if (id == defaultScreenId_) {
680 HandleDefaultScreenDisConnected();
681 }
682
683 uint64_t vsyncEnabledScreenId = JudgeVSyncEnabledScreenWhileHotPlug(id, false);
684 UpdateVsyncEnabledScreenId(vsyncEnabledScreenId);
685 }
686
UpdateVsyncEnabledScreenId(ScreenId screenId)687 void RSScreenManager::UpdateVsyncEnabledScreenId(ScreenId screenId)
688 {
689 std::unique_lock<std::mutex> lock(screenMapMutex_);
690 if (isFoldScreenFlag_ && foldScreenIds_.size() == ORIGINAL_FOLD_SCREEN_AMOUNT) {
691 bool isAllFoldScreenDisconnected = true;
692 for (const auto& [foldScreenId, foldScreenStatus] : foldScreenIds_) {
693 if (foldScreenStatus.isConnected) {
694 isAllFoldScreenDisconnected = false;
695 break;
696 }
697 }
698 auto it = foldScreenIds_.find(screenId);
699 if (it == foldScreenIds_.end() && !isAllFoldScreenDisconnected) {
700 return;
701 }
702 }
703 lock.unlock();
704
705 auto renderType = RSUniRenderJudgement::GetUniRenderEnabledType();
706 if (renderType != UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
707 RegSetScreenVsyncEnabledCallbackForMainThread(screenId);
708 } else {
709 RegSetScreenVsyncEnabledCallbackForHardwareThread(screenId);
710 }
711 }
712
RegSetScreenVsyncEnabledCallbackForMainThread(ScreenId vsyncEnabledScreenId)713 void RSScreenManager::RegSetScreenVsyncEnabledCallbackForMainThread(ScreenId vsyncEnabledScreenId)
714 {
715 auto vsyncSampler = CreateVSyncSampler();
716 if (vsyncSampler == nullptr) {
717 RS_LOGE("%{public}s failed, vsyncSampler is null", __func__);
718 return;
719 }
720 vsyncSampler->SetVsyncEnabledScreenId(vsyncEnabledScreenId);
721 vsyncSampler->RegSetScreenVsyncEnabledCallback([this](uint64_t screenId, bool enabled) {
722 auto mainThread = RSMainThread::Instance();
723 if (mainThread == nullptr) {
724 RS_LOGE("%{public}s screenVsyncEnabled:%{public}d set failed, "
725 "get RSMainThread failed", __func__, enabled);
726 return;
727 }
728 mainThread->PostTask([this, screenId, enabled]() {
729 auto screen = GetScreen(screenId);
730 if (screen == nullptr) {
731 RS_LOGE("SetScreenVsyncEnabled:%{public}d failed, screen %{public}" PRIu64 " not found",
732 enabled, screenId);
733 return;
734 }
735 screen->SetScreenVsyncEnabled(enabled);
736 });
737 });
738 }
739
RegSetScreenVsyncEnabledCallbackForHardwareThread(ScreenId vsyncEnabledScreenId)740 void RSScreenManager::RegSetScreenVsyncEnabledCallbackForHardwareThread(ScreenId vsyncEnabledScreenId)
741 {
742 auto vsyncSampler = CreateVSyncSampler();
743 if (vsyncSampler == nullptr) {
744 RS_LOGE("%{public}s failed, vsyncSampler is null", __func__);
745 return;
746 }
747 vsyncSampler->SetVsyncEnabledScreenId(vsyncEnabledScreenId);
748 #ifdef RS_ENABLE_GPU
749 vsyncSampler->RegSetScreenVsyncEnabledCallback([this](uint64_t screenId, bool enabled) {
750 RSHardwareThread::Instance().PostTask([this, screenId, enabled]() {
751 auto screen = GetScreen(screenId);
752 if (screen == nullptr) {
753 RS_LOGE("SetScreenVsyncEnabled:%{public}d failed, screen %{public}" PRIu64 " not found",
754 enabled, screenId);
755 return;
756 }
757 screen->SetScreenVsyncEnabled(enabled);
758 });
759 });
760 #endif
761 }
762
763 // If the previous primary screen disconnected, we traversal the left screens
764 // and find the first physical screen to be the default screen.
765 // If there was no physical screen left, we set the first screen as default, no matter what type it is.
766 // At last, if no screen left, we set Default Screen Id to INVALID_SCREEN_ID.
HandleDefaultScreenDisConnected()767 void RSScreenManager::HandleDefaultScreenDisConnected()
768 {
769 ScreenId defaultScreenId = INVALID_SCREEN_ID;
770 std::lock_guard<std::mutex> lock(screenMapMutex_);
771 auto iter = std::find_if(screens_.cbegin(), screens_.cend(), [](const auto& node) {
772 const auto& screen = node.second;
773 return screen && !screen->IsVirtual();
774 });
775 if (iter != screens_.cend()) {
776 defaultScreenId = iter->first;
777 }
778
779 if (defaultScreenId == INVALID_SCREEN_ID && !screens_.empty()) {
780 defaultScreenId = screens_.cbegin()->first;
781 }
782 defaultScreenId_ = defaultScreenId;
783 }
784
UpdateFoldScreenConnectStatusLocked(ScreenId screenId,bool connected)785 void RSScreenManager::UpdateFoldScreenConnectStatusLocked(ScreenId screenId, bool connected)
786 {
787 if (isFoldScreenFlag_) {
788 auto it = foldScreenIds_.find(screenId);
789 if (it != foldScreenIds_.end()) {
790 it->second.isConnected = connected;
791 }
792 }
793 }
794
JudgeVSyncEnabledScreenWhileHotPlug(ScreenId screenId,bool connected)795 uint64_t RSScreenManager::JudgeVSyncEnabledScreenWhileHotPlug(ScreenId screenId, bool connected)
796 {
797 std::unique_lock<std::mutex> lock(screenMapMutex_);
798 UpdateFoldScreenConnectStatusLocked(screenId, connected);
799
800 auto vsyncSampler = CreateVSyncSampler();
801 if (vsyncSampler == nullptr) {
802 RS_LOGE("%{public}s failed, vsyncSampler is null", __func__);
803 return screenId;
804 }
805 uint64_t vsyncEnabledScreenId = vsyncSampler->GetVsyncEnabledScreenId();
806 if (connected) { // screen connected
807 if (vsyncEnabledScreenId == INVALID_SCREEN_ID) {
808 return screenId;
809 }
810 } else { // screen disconnected
811 if (vsyncEnabledScreenId != screenId) {
812 return vsyncEnabledScreenId;
813 }
814 vsyncEnabledScreenId = INVALID_SCREEN_ID;
815 auto iter = std::find_if(screens_.cbegin(), screens_.cend(), [](const auto& node) {
816 const auto& screen = node.second;
817 return screen && !screen->IsVirtual();
818 });
819 if (iter != screens_.end()) {
820 vsyncEnabledScreenId = iter->first;
821 }
822 }
823 return vsyncEnabledScreenId;
824 }
825
JudgeVSyncEnabledScreenWhilePowerStatusChanged(ScreenId screenId,ScreenPowerStatus status)826 uint64_t RSScreenManager::JudgeVSyncEnabledScreenWhilePowerStatusChanged(ScreenId screenId, ScreenPowerStatus status)
827 {
828 std::unique_lock<std::mutex> lock(screenMapMutex_);
829 uint64_t vsyncEnabledScreenId = CreateVSyncSampler()->GetVsyncEnabledScreenId();
830 auto it = foldScreenIds_.find(screenId);
831 if (it == foldScreenIds_.end()) {
832 return vsyncEnabledScreenId;
833 }
834
835 if (status == ScreenPowerStatus::POWER_STATUS_ON) {
836 it->second.isPowerOn = true;
837 auto vsyncScreenIt = foldScreenIds_.find(vsyncEnabledScreenId);
838 if (vsyncScreenIt == foldScreenIds_.end() || vsyncScreenIt->second.isPowerOn == false) {
839 return screenId;
840 }
841 } else if (status == ScreenPowerStatus::POWER_STATUS_OFF) {
842 it->second.isPowerOn = false;
843 if (screenId != vsyncEnabledScreenId) {
844 return vsyncEnabledScreenId;
845 }
846 for (auto& [foldScreenId, status] : foldScreenIds_) {
847 if (status.isConnected && status.isPowerOn) {
848 return foldScreenId;
849 }
850 }
851 }
852 return vsyncEnabledScreenId;
853 }
854
855 // if SetVirtualScreenSurface success, force a refresh of one frame, avoiding prolong black screen
ForceRefreshOneFrame() const856 void RSScreenManager::ForceRefreshOneFrame() const
857 {
858 auto mainThread = RSMainThread::Instance();
859 if (mainThread != nullptr) {
860 mainThread->PostTask([mainThread]() {
861 mainThread->SetDirtyFlag();
862 });
863 mainThread->ForceRefreshForUni();
864 }
865 }
866
SetDefaultScreenId(ScreenId id)867 void RSScreenManager::SetDefaultScreenId(ScreenId id)
868 {
869 defaultScreenId_ = id;
870 }
871
GenerateVirtualScreenId()872 ScreenId RSScreenManager::GenerateVirtualScreenId()
873 {
874 std::lock_guard<std::mutex> lock(virtualScreenIdMutex_);
875 if (!freeVirtualScreenIds_.empty()) {
876 ScreenId id = freeVirtualScreenIds_.front();
877 freeVirtualScreenIds_.pop();
878 RS_LOGI("%{public}s: VirtualScreenId is %{public}" PRIu64, __func__, id);
879 return id;
880 }
881
882 RS_LOGI("%{public}s: freeVirtualScreenIds_ is empty.", __func__);
883 // The left 32 bits is for virtual screen id.
884 return (static_cast<ScreenId>(virtualScreenCount_++) << 32) | 0xffffffffu;
885 }
886
GetVirtualScreenResolution(ScreenId id,RSVirtualScreenResolution & virtualScreenResolution) const887 void RSScreenManager::GetVirtualScreenResolution(ScreenId id, RSVirtualScreenResolution& virtualScreenResolution) const
888 {
889 auto screen = GetScreen(id);
890 if (screen == nullptr) {
891 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
892 return;
893 }
894
895 virtualScreenResolution.SetVirtualScreenWidth(static_cast<uint32_t>(screen->Width()));
896 virtualScreenResolution.SetVirtualScreenHeight(static_cast<uint32_t>(screen->Height()));
897 }
898
GetScreenActiveMode(ScreenId id,RSScreenModeInfo & screenModeInfo) const899 void RSScreenManager::GetScreenActiveMode(ScreenId id, RSScreenModeInfo& screenModeInfo) const
900 {
901 auto screen = GetScreen(id);
902 if (screen == nullptr) {
903 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
904 return;
905 }
906 auto modeInfo = screen->GetActiveMode();
907 if (!modeInfo) {
908 RS_LOGE("%{public}s: Failed to get active mode for screen %{public}" PRIu64, __func__, id);
909 return;
910 }
911
912 RS_LOGI("%{public}s: screen[%{public}" PRIu64 "] pixel[%{public}d * %{public}d],"
913 "freshRate[%{public}d]", __func__, id, modeInfo->width, modeInfo->height, modeInfo->freshRate);
914 screenModeInfo.SetScreenWidth(modeInfo->width);
915 screenModeInfo.SetScreenHeight(modeInfo->height);
916 screenModeInfo.SetScreenRefreshRate(modeInfo->freshRate);
917 screenModeInfo.SetScreenModeId(screen->GetActiveModePosByModeId(modeInfo->id));
918 }
919
GetScreenSupportedModes(ScreenId id) const920 std::vector<RSScreenModeInfo> RSScreenManager::GetScreenSupportedModes(ScreenId id) const
921 {
922 auto screen = GetScreen(id);
923 if (screen == nullptr) {
924 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
925 return {};
926 }
927
928 const auto& displaySupportedModes = screen->GetSupportedModes();
929 std::vector<RSScreenModeInfo> screenSupportedModes(displaySupportedModes.size());
930 std::transform(displaySupportedModes.cbegin(), displaySupportedModes.cend(), screenSupportedModes.begin(),
931 [](const auto& node) { return RSScreenModeInfo(node.width, node.height, node.freshRate, node.id); });
932 return screenSupportedModes;
933 }
934
GetScreenCapability(ScreenId id) const935 RSScreenCapability RSScreenManager::GetScreenCapability(ScreenId id) const
936 {
937 RSScreenCapability screenCapability;
938 auto screen = GetScreen(id);
939 if (screen == nullptr) {
940 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
941 return screenCapability;
942 }
943
944 if (screen->IsVirtual()) {
945 RS_LOGW("%{public}s: only name attribute is valid for virtual screen.", __func__);
946 screenCapability.SetName(screen->Name());
947 return screenCapability;
948 }
949
950 const auto& capability = screen->GetCapability();
951 std::vector<RSScreenProps> props(capability.props.size());
952 std::transform(capability.props.cbegin(), capability.props.cend(), props.begin(), [](const auto& node) {
953 return RSScreenProps(node.name, node.propId, node.value);
954 });
955 screenCapability.SetName(capability.name);
956 screenCapability.SetType(static_cast<ScreenInterfaceType>(capability.type));
957 screenCapability.SetPhyWidth(capability.phyWidth);
958 screenCapability.SetPhyHeight(capability.phyHeight);
959 screenCapability.SetSupportLayers(capability.supportLayers);
960 screenCapability.SetVirtualDispCount(capability.virtualDispCount);
961 screenCapability.SetSupportWriteBack(capability.supportWriteBack);
962 screenCapability.SetProps(std::move(props));
963 return screenCapability;
964 }
965
GetScreenPowerStatus(ScreenId id) const966 ScreenPowerStatus RSScreenManager::GetScreenPowerStatus(ScreenId id) const
967 {
968 if (!RSSystemProperties::IsSmallFoldDevice()) {
969 auto screen = GetScreen(id);
970 if (screen == nullptr) {
971 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
972 return INVALID_POWER_STATUS;
973 }
974
975 ScreenPowerStatus status = static_cast<ScreenPowerStatus>(screen->GetPowerStatus());
976 return status;
977 }
978
979 ScreenPowerStatus status = ScreenPowerStatus::INVALID_POWER_STATUS;
980 RSSwitchingThread::Instance().PostSyncTask([id, &status, this]() {
981 auto screen = GetScreen(id);
982 if (screen == nullptr) {
983 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
984 status = INVALID_POWER_STATUS;
985 return;
986 }
987
988 status = static_cast<ScreenPowerStatus>(screen->GetPowerStatus());
989 });
990
991 return status;
992 }
993
GetScreenCorrection(ScreenId id) const994 ScreenRotation RSScreenManager::GetScreenCorrection(ScreenId id) const
995 {
996 auto screen = GetScreen(id);
997 if (screen == nullptr) {
998 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
999 return ScreenRotation::INVALID_SCREEN_ROTATION;
1000 }
1001
1002 return screen->GetScreenCorrection();
1003 }
1004
GetDefaultScreenId() const1005 ScreenId RSScreenManager::GetDefaultScreenId() const
1006 {
1007 return defaultScreenId_;
1008 }
1009
GetAllScreenIds() const1010 std::vector<ScreenId> RSScreenManager::GetAllScreenIds() const
1011 {
1012 std::lock_guard<std::mutex> lock(screenMapMutex_);
1013 std::vector<ScreenId> ids;
1014 for (auto iter = screens_.begin(); iter != screens_.end(); ++iter) {
1015 ids.emplace_back(iter->first);
1016 }
1017 return ids;
1018 }
1019
CreateVirtualScreen(const std::string & name,uint32_t width,uint32_t height,sptr<Surface> surface,ScreenId mirrorId,int32_t flags,std::vector<NodeId> whiteList)1020 ScreenId RSScreenManager::CreateVirtualScreen(
1021 const std::string& name,
1022 uint32_t width,
1023 uint32_t height,
1024 sptr<Surface> surface,
1025 ScreenId mirrorId,
1026 int32_t flags,
1027 std::vector<NodeId> whiteList)
1028 {
1029 if (currentVirtualScreenNum_ >= MAX_VIRTUAL_SCREEN_NUM) {
1030 RS_LOGW("%{public}s: virtual screens num %{public}" PRIu32 " has reached the maximum limit!",
1031 __func__, currentVirtualScreenNum_.load());
1032 return INVALID_SCREEN_ID;
1033 }
1034 if (width > MAX_VIRTUAL_SCREEN_WIDTH || height > MAX_VIRTUAL_SCREEN_HEIGHT) {
1035 RS_LOGW("%{public}s: width %{public}" PRIu32 " or height %{public}" PRIu32 " has reached"
1036 " the maximum limit!", __func__, width, height);
1037 return INVALID_SCREEN_ID;
1038 }
1039 if (surface != nullptr) {
1040 uint64_t surfaceId = surface->GetUniqueId();
1041 auto func = [surfaceId](const ScreenNode& node) {
1042 const auto& screen = node.second;
1043 return screen && screen->IsVirtual() && screen->GetProducerSurface() &&
1044 screen->GetProducerSurface()->GetUniqueId() == surfaceId;
1045 };
1046 if (AnyScreenFits(func)) {
1047 RS_LOGW("%{public}s: surface %{public}" PRIu64 " is used, create virtual"
1048 " screen failed!", __func__, surfaceId);
1049 return INVALID_SCREEN_ID;
1050 }
1051 } else {
1052 RS_LOGW("%{public}s: surface is nullptr.", __func__);
1053 }
1054
1055 VirtualScreenConfigs configs;
1056 ScreenId newId = GenerateVirtualScreenId();
1057 configs.id = newId;
1058 configs.mirrorId = mirrorId;
1059 configs.name = name;
1060 configs.width = width;
1061 configs.height = height;
1062 configs.surface = surface;
1063 configs.flags = flags;
1064 configs.whiteList = std::unordered_set<NodeId>(whiteList.begin(), whiteList.end());
1065
1066 {
1067 std::lock_guard<std::mutex> lock(screenMapMutex_);
1068 screens_[newId] = std::make_shared<RSScreen>(configs);
1069 }
1070 ++currentVirtualScreenNum_;
1071 NotifyScreenNodeChange(newId, true);
1072 RS_LOGI("%{public}s: create virtual screen(id %{public}" PRIu64 "), width %{public}u, height %{public}u.",
1073 __func__, newId, width, height);
1074 return newId;
1075 }
1076
GetBlackListVirtualScreenByNode(uint64_t nodeId)1077 std::unordered_set<uint64_t> RSScreenManager::GetBlackListVirtualScreenByNode(uint64_t nodeId)
1078 {
1079 std::unordered_set<uint64_t> virtualScreens = {};
1080 std::scoped_lock lock(screenMapMutex_, blackListMutex_);
1081 if (blackListInVirtualScreen_.find(nodeId) != blackListInVirtualScreen_.end()) {
1082 virtualScreens = blackListInVirtualScreen_[nodeId];
1083 }
1084 if (castScreenBlackList_.find(nodeId) != castScreenBlackList_.end()) {
1085 // nodeId in castScreenBlackList, return its cast virtual screen
1086 for (const auto& [screenId, screen] : screens_) {
1087 if (screen && screen->IsVirtual() && screen->GetCastScreenEnableSkipWindow()) {
1088 virtualScreens.insert(screenId);
1089 }
1090 }
1091 }
1092 return virtualScreens;
1093 }
1094
SetVirtualScreenBlackList(ScreenId id,const std::vector<uint64_t> & blackList)1095 int32_t RSScreenManager::SetVirtualScreenBlackList(ScreenId id, const std::vector<uint64_t>& blackList)
1096 {
1097 std::unordered_set<NodeId> screenBlackList(blackList.begin(), blackList.end());
1098 if (id == INVALID_SCREEN_ID) {
1099 RS_LOGI("%{public}s: Cast screen blacklists for id %{public}" PRIu64, __func__, id);
1100 std::lock_guard<std::mutex> lock(blackListMutex_);
1101 castScreenBlackList_ = std::move(screenBlackList);
1102 return SUCCESS;
1103 }
1104 auto virtualScreen = GetScreen(id);
1105 if (virtualScreen == nullptr) {
1106 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1107 return SCREEN_NOT_FOUND;
1108 }
1109 RS_LOGI("%{public}s: Record screen blacklists for id %{public}" PRIu64, __func__, id);
1110 virtualScreen->SetBlackList(screenBlackList);
1111 {
1112 std::lock_guard<std::mutex> lock(blackListMutex_);
1113 for (const auto& [nodeId, screenIdSet] : blackListInVirtualScreen_) {
1114 if (screenIdSet.find(id) != screenIdSet.end()) {
1115 blackListInVirtualScreen_[nodeId].erase(id);
1116 }
1117 }
1118 for (const auto& nodeId : screenBlackList) {
1119 blackListInVirtualScreen_[nodeId].insert(id);
1120 }
1121 }
1122
1123 ScreenId mainId = GetDefaultScreenId();
1124 if (mainId != id) {
1125 auto mainScreen = GetScreen(mainId);
1126 if (mainScreen == nullptr) {
1127 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, mainId);
1128 return SCREEN_NOT_FOUND;
1129 }
1130 mainScreen->SetBlackList(screenBlackList);
1131 }
1132 return SUCCESS;
1133 }
1134
SetVirtualScreenTypeBlackList(ScreenId id,const std::vector<uint8_t> & typeBlackList)1135 int32_t RSScreenManager::SetVirtualScreenTypeBlackList(ScreenId id, const std::vector<uint8_t>& typeBlackList)
1136 {
1137 std::unordered_set<NodeType> screenTypeBlackList(typeBlackList.begin(), typeBlackList.end());
1138 if (id == INVALID_SCREEN_ID) {
1139 RS_LOGI("%{public}s: Cast screen typeblacklists for id %{public}" PRIu64, __func__, id);
1140 std::lock_guard<std::mutex> lock(typeBlackListMutex_);
1141 castScreenTypeBlackList_ = std::move(screenTypeBlackList);
1142 return SUCCESS;
1143 }
1144 auto virtualScreen = GetScreen(id);
1145 if (virtualScreen == nullptr) {
1146 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1147 return SCREEN_NOT_FOUND;
1148 }
1149 RS_LOGI("%{public}s: Record screen typeblacklists for id %{public}" PRIu64, __func__, id);
1150 virtualScreen->SetTypeBlackList(screenTypeBlackList);
1151 return SUCCESS;
1152 }
1153
IsBlackListExceeded(const std::vector<uint64_t> & blackList,const std::unordered_set<uint64_t> & screenBlacklist)1154 static inline bool IsBlackListExceeded(const std::vector<uint64_t>& blackList,
1155 const std::unordered_set<uint64_t>& screenBlacklist)
1156 {
1157 return blackList.size() + screenBlacklist.size() > MAX_BLACK_LIST_NUM;
1158 }
1159
AddVirtualScreenBlackList(ScreenId id,const std::vector<uint64_t> & blackList)1160 int32_t RSScreenManager::AddVirtualScreenBlackList(ScreenId id, const std::vector<uint64_t>& blackList)
1161 {
1162 if (id == INVALID_SCREEN_ID) {
1163 std::lock_guard<std::mutex> lock(blackListMutex_);
1164 if (IsBlackListExceeded(blackList, castScreenBlackList_)) {
1165 RS_LOGW("%{public}s: blacklist is over max size!", __func__);
1166 return INVALID_ARGUMENTS;
1167 }
1168 RS_LOGI("%{public}s: Cast screen blacklists", __func__);
1169 castScreenBlackList_.insert(blackList.cbegin(), blackList.cend());
1170 return SUCCESS;
1171 }
1172 auto virtualScreen = GetScreen(id);
1173 if (virtualScreen == nullptr) {
1174 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1175 return SCREEN_NOT_FOUND;
1176 }
1177 if (IsBlackListExceeded(blackList, virtualScreen->GetBlackList())) {
1178 RS_LOGW("%{public}s: blacklist is over max size!", __func__);
1179 return INVALID_ARGUMENTS;
1180 }
1181 RS_LOGI("%{public}s: Record screen blacklists for id %{public}" PRIu64, __func__, id);
1182 virtualScreen->AddBlackList(blackList);
1183 {
1184 std::lock_guard<std::mutex> lock(blackListMutex_);
1185 for (const auto& nodeId : blackList) {
1186 blackListInVirtualScreen_[nodeId].insert(id);
1187 }
1188 }
1189
1190 ScreenId mainId = GetDefaultScreenId();
1191 if (mainId != id) {
1192 auto mainScreen = GetScreen(mainId);
1193 if (mainScreen == nullptr) {
1194 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, mainId);
1195 return SCREEN_NOT_FOUND;
1196 }
1197 if (IsBlackListExceeded(blackList, mainScreen->GetBlackList())) {
1198 RS_LOGW("%{public}s: blacklist is over max size!", __func__);
1199 return INVALID_ARGUMENTS;
1200 }
1201 mainScreen->AddBlackList(blackList);
1202 }
1203 return SUCCESS;
1204 }
1205
RemoveVirtualScreenBlackList(ScreenId id,const std::vector<uint64_t> & blackList)1206 int32_t RSScreenManager::RemoveVirtualScreenBlackList(ScreenId id, const std::vector<uint64_t>& blackList)
1207 {
1208 if (id == INVALID_SCREEN_ID) {
1209 RS_LOGI("%{public}s: Cast screen blacklists", __func__);
1210 std::lock_guard<std::mutex> lock(blackListMutex_);
1211 for (const auto& list : blackList) {
1212 castScreenBlackList_.erase(list);
1213 }
1214 return SUCCESS;
1215 }
1216 auto virtualScreen = GetScreen(id);
1217 if (virtualScreen == nullptr) {
1218 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1219 return SCREEN_NOT_FOUND;
1220 }
1221 RS_LOGI("%{public}s: Record screen blacklists for id %{public}" PRIu64, __func__, id);
1222 virtualScreen->RemoveBlackList(blackList);
1223 {
1224 std::lock_guard<std::mutex> lock(blackListMutex_);
1225 for (const auto& nodeId : blackList) {
1226 blackListInVirtualScreen_[nodeId].erase(id);
1227 }
1228 }
1229
1230 ScreenId mainId = GetDefaultScreenId();
1231 if (mainId != id) {
1232 auto mainScreen = GetScreen(mainId);
1233 if (mainScreen == nullptr) {
1234 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, mainId);
1235 return SCREEN_NOT_FOUND;
1236 }
1237 mainScreen->RemoveBlackList(blackList);
1238 }
1239 return SUCCESS;
1240 }
1241
SetVirtualScreenSecurityExemptionList(ScreenId id,const std::vector<uint64_t> & securityExemptionList)1242 int32_t RSScreenManager::SetVirtualScreenSecurityExemptionList(
1243 ScreenId id,
1244 const std::vector<uint64_t>& securityExemptionList)
1245 {
1246 if (id == INVALID_SCREEN_ID) {
1247 RS_LOGW("%{public}s: INVALID_SCREEN_ID.", __func__);
1248 return INVALID_ARGUMENTS;
1249 }
1250 auto virtualScreen = GetScreen(id);
1251 if (virtualScreen == nullptr) {
1252 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1253 return SCREEN_NOT_FOUND;
1254 }
1255
1256 if (!virtualScreen->IsVirtual()) {
1257 RS_LOGW("%{public}s: not virtual screen for id %{public}" PRIu64, __func__, id);
1258 return INVALID_ARGUMENTS;
1259 }
1260 virtualScreen->SetSecurityExemptionList(securityExemptionList);
1261 for (const auto& exemption : securityExemptionList) {
1262 RS_LOGW("%{public}s: virtual screen(id %{public}" PRIu64 "), nodeId %{public}" PRIu64,
1263 __func__, id, exemption);
1264 }
1265 return SUCCESS;
1266 }
1267
GetVirtualScreenSecurityExemptionList(ScreenId id) const1268 const std::vector<uint64_t> RSScreenManager::GetVirtualScreenSecurityExemptionList(ScreenId id) const
1269 {
1270 auto virtualScreen = GetScreen(id);
1271 if (virtualScreen == nullptr) {
1272 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1273 return {};
1274 }
1275
1276 return virtualScreen->GetSecurityExemptionList();
1277 }
1278
SetScreenSecurityMask(ScreenId id,std::shared_ptr<Media::PixelMap> securityMask)1279 int32_t RSScreenManager::SetScreenSecurityMask(ScreenId id, std::shared_ptr<Media::PixelMap> securityMask)
1280 {
1281 if (id == INVALID_SCREEN_ID) {
1282 RS_LOGW("%{public}s: INVALID_SCREEN_ID.", __func__);
1283 return INVALID_ARGUMENTS;
1284 }
1285 auto screen = GetScreen(id);
1286 if (screen == nullptr) {
1287 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1288 return SCREEN_NOT_FOUND;
1289 }
1290
1291 return screen->SetSecurityMask(securityMask);
1292 }
1293
GetScreenSecurityMask(ScreenId id) const1294 std::shared_ptr<Media::PixelMap> RSScreenManager::GetScreenSecurityMask(ScreenId id) const
1295 {
1296 auto screen = GetScreen(id);
1297 if (screen == nullptr) {
1298 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1299 return nullptr;
1300 }
1301 return screen->GetSecurityMask();
1302 }
1303
GetVirtualScreenSecLayerOption(ScreenId id) const1304 int32_t RSScreenManager::GetVirtualScreenSecLayerOption(ScreenId id) const
1305 {
1306 if (id == INVALID_SCREEN_ID) {
1307 RS_LOGW("%{public}s: INVALID_SCREEN_ID.", __func__);
1308 return INVALID_ARGUMENTS;
1309 }
1310 auto virtualScreen = GetScreen(id);
1311 if (virtualScreen == nullptr || !virtualScreen->IsVirtual()) {
1312 RS_LOGW("%{public}s: There is no virtual screen for id %{public}" PRIu64, __func__, id);
1313 return SCREEN_NOT_FOUND;
1314 }
1315 return virtualScreen->GetVirtualSecLayerOption();
1316 }
1317
SetMirrorScreenVisibleRect(ScreenId id,const Rect & mainScreenRect,bool supportRotation)1318 int32_t RSScreenManager::SetMirrorScreenVisibleRect(ScreenId id, const Rect& mainScreenRect, bool supportRotation)
1319 {
1320 if (id == INVALID_SCREEN_ID) {
1321 RS_LOGW("%{public}s: INVALID_SCREEN_ID.", __func__);
1322 return INVALID_ARGUMENTS;
1323 }
1324 auto mainScreen = GetScreen(id);
1325 if (mainScreen == nullptr) {
1326 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1327 return SCREEN_NOT_FOUND;
1328 }
1329
1330 // zero Rect means disable visible rect
1331 static Rect ZERO = {0, 0, 0, 0};
1332 mainScreen->SetEnableVisibleRect(mainScreenRect != ZERO);
1333 mainScreen->SetMainScreenVisibleRect(mainScreenRect);
1334 mainScreen->SetVisibleRectSupportRotation(supportRotation);
1335 RS_LOGI("%{public}s: mirror screen(id %{public}" PRIu64 "), "
1336 "visible rect[%{public}d, %{public}d, %{public}d, %{public}d], supportRotation: %{public}d",
1337 __func__, id, mainScreenRect.x, mainScreenRect.y, mainScreenRect.w, mainScreenRect.h, supportRotation);
1338 return SUCCESS;
1339 }
1340
GetMirrorScreenVisibleRect(ScreenId id) const1341 Rect RSScreenManager::GetMirrorScreenVisibleRect(ScreenId id) const
1342 {
1343 auto mirrorScreen = GetScreen(id);
1344 if (mirrorScreen == nullptr) {
1345 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1346 return {};
1347 }
1348
1349 return mirrorScreen->GetMainScreenVisibleRect();
1350 }
1351
SetCastScreenEnableSkipWindow(ScreenId id,bool enable)1352 int32_t RSScreenManager::SetCastScreenEnableSkipWindow(ScreenId id, bool enable)
1353 {
1354 auto virtualScreen = GetScreen(id);
1355 if (virtualScreen == nullptr) {
1356 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1357 return SCREEN_NOT_FOUND;
1358 }
1359 virtualScreen->SetCastScreenEnableSkipWindow(enable);
1360 RS_LOGW("%{public}s: screen id %{public}" PRIu64 " set %{public}d success.", __func__, id, enable);
1361 return SUCCESS;
1362 }
1363
GetVirtualScreenBlackList(ScreenId id) const1364 const std::unordered_set<NodeId> RSScreenManager::GetVirtualScreenBlackList(ScreenId id) const
1365 {
1366 auto virtualScreen = GetScreen(id);
1367 if (virtualScreen == nullptr) {
1368 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1369 return {};
1370 }
1371 std::unordered_set<uint64_t> virtualScreenBlackList = virtualScreen->GetBlackList();
1372 // if the skipWindow flag is enabled, the global blacklist takes effect in addition
1373 if (virtualScreen->GetCastScreenEnableSkipWindow()) {
1374 RS_LOGD("%{public}s: Cast screen blacklists for id %{public}" PRIu64, __func__, id);
1375 std::lock_guard<std::mutex> lock(blackListMutex_);
1376 virtualScreenBlackList.insert(castScreenBlackList_.begin(), castScreenBlackList_.end());
1377 }
1378 RS_LOGD("%{public}s: Record screen blacklists for id %{public}" PRIu64, __func__, id);
1379 return virtualScreenBlackList;
1380 }
1381
GetVirtualScreenTypeBlackList(ScreenId id) const1382 const std::unordered_set<NodeType> RSScreenManager::GetVirtualScreenTypeBlackList(ScreenId id) const
1383 {
1384 auto virtualScreen = GetScreen(id);
1385 if (virtualScreen == nullptr) {
1386 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1387 return {};
1388 }
1389 if (virtualScreen->GetCastScreenEnableSkipWindow()) {
1390 RS_LOGD("%{public}s: Cast screen typeblacklists for id %{public}" PRIu64, __func__, id);
1391 std::lock_guard<std::mutex> lock(typeBlackListMutex_);
1392 return castScreenTypeBlackList_;
1393 }
1394 RS_LOGD("%{public}s: Record screen typeblacklists for id %{public}" PRIu64, __func__, id);
1395 return virtualScreen->GetTypeBlackList();
1396 }
1397
GetAllBlackList() const1398 std::unordered_set<uint64_t> RSScreenManager::GetAllBlackList() const
1399 {
1400 std::unordered_set<uint64_t> allBlackList;
1401 std::scoped_lock lock(screenMapMutex_, blackListMutex_);
1402 for (const auto& [_, screen] : screens_) {
1403 if (screen == nullptr) {
1404 continue;
1405 }
1406 if (screen->GetCastScreenEnableSkipWindow()) {
1407 allBlackList.insert(castScreenBlackList_.cbegin(), castScreenBlackList_.cend());
1408 } else {
1409 const auto blackList = screen->GetBlackList();
1410 allBlackList.insert(blackList.cbegin(), blackList.cend());
1411 }
1412 }
1413 return allBlackList;
1414 }
1415
GetAllWhiteList()1416 std::unordered_set<uint64_t> RSScreenManager::GetAllWhiteList()
1417 {
1418 std::lock_guard<std::mutex> lock(screenMapMutex_);
1419 std::unordered_set<uint64_t> allWhiteList;
1420 for (const auto& [id, screen] : screens_) {
1421 if (screen == nullptr) {
1422 continue;
1423 }
1424 const auto& whiteList = screen->GetWhiteList();
1425 if (!whiteList.empty()) {
1426 allWhiteList.insert(whiteList.begin(), whiteList.end());
1427 std::lock_guard<std::mutex> lock(whiteListMutex_);
1428 screenWhiteList_[id] = whiteList;
1429 }
1430 }
1431 return allWhiteList;
1432 }
1433
GetScreenWhiteList() const1434 std::unordered_map<ScreenId, std::unordered_set<uint64_t>> RSScreenManager::GetScreenWhiteList() const
1435 {
1436 std::lock_guard<std::mutex> lock(whiteListMutex_);
1437 return screenWhiteList_;
1438 }
1439
SetVirtualScreenSurface(ScreenId id,sptr<Surface> surface)1440 int32_t RSScreenManager::SetVirtualScreenSurface(ScreenId id, sptr<Surface> surface)
1441 {
1442 if (surface == nullptr) {
1443 RS_LOGW("%{public}s: screenId:%{public}" PRIu64 " surface is null.", __func__, id);
1444 return INVALID_ARGUMENTS;
1445 }
1446 auto screen = GetScreen(id);
1447 if (screen == nullptr) {
1448 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1449 return SCREEN_NOT_FOUND;
1450 }
1451 if (!screen->IsVirtual()) {
1452 RS_LOGW("%{public}s: The screen is not virtual, id %{public}" PRIu64, __func__, id);
1453 return INVALID_ARGUMENTS;
1454 }
1455 uint64_t surfaceId = surface->GetUniqueId();
1456
1457 auto func = [id, surfaceId](const ScreenNode& node) -> bool {
1458 const auto& [screenId, screen] = node;
1459 return screen && screen->IsVirtual() && screenId != id && screen->GetProducerSurface() &&
1460 screen->GetProducerSurface()->GetUniqueId() == surfaceId;
1461 };
1462 if (AnyScreenFits(func)) {
1463 RS_LOGE("%{public}s: surface %{public}" PRIu64 " is used, set surface failed!", __func__, surfaceId);
1464 return SURFACE_NOT_UNIQUE;
1465 }
1466
1467 screen->SetProducerSurface(surface);
1468 RS_LOGI("%{public}s: set virtual screen surface success!", __func__);
1469 RS_TRACE_NAME("RSScreenManager::SetVirtualScreenSurface, ForceRefreshOneFrame.");
1470 ForceRefreshOneFrame();
1471 screen->SetPSurfaceChange(true);
1472 return SUCCESS;
1473 }
1474
1475 // only used in dirtyRegion
CheckPSurfaceChanged(ScreenId id)1476 bool RSScreenManager::CheckPSurfaceChanged(ScreenId id)
1477 {
1478 auto screen = GetScreen(id);
1479 if (screen == nullptr) {
1480 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1481 return false;
1482 }
1483 if (!screen->IsVirtual()) {
1484 return false;
1485 }
1486 return screen->GetAndResetPSurfaceChange();
1487 }
1488
GetAndResetVirtualSurfaceUpdateFlag(ScreenId id) const1489 bool RSScreenManager::GetAndResetVirtualSurfaceUpdateFlag(ScreenId id) const
1490 {
1491 auto virtualScreen = GetScreen(id);
1492 if (virtualScreen == nullptr) {
1493 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1494 return false;
1495 }
1496 return virtualScreen->GetAndResetVirtualSurfaceUpdateFlag();
1497 }
1498
RemoveVirtualScreen(ScreenId id)1499 void RSScreenManager::RemoveVirtualScreen(ScreenId id)
1500 {
1501 {
1502 std::lock_guard<std::mutex> lock(screenMapMutex_);
1503 auto iter = screens_.find(id);
1504 if (iter == screens_.end() || iter->second == nullptr) {
1505 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1506 return;
1507 }
1508 if (!iter->second->IsVirtual()) {
1509 RS_LOGW("%{public}s: The screen is not virtual, id %{public}" PRIu64, __func__, id);
1510 return;
1511 }
1512
1513 screens_.erase(iter);
1514 --currentVirtualScreenNum_;
1515 RS_LOGI("%{public}s: remove virtual screen(id %{public}" PRIu64 ").", __func__, id);
1516 }
1517 {
1518 std::lock_guard<std::mutex> lock(virtualScreenIdMutex_);
1519 freeVirtualScreenIds_.push(id);
1520 }
1521 NotifyScreenNodeChange(id, false);
1522
1523 // when virtual screen doesn't exist no more, render control can be recovered.
1524 {
1525 std::lock_guard<std::mutex> lock(renderControlMutex_);
1526 disableRenderControlScreens_.erase(id);
1527 }
1528 }
1529
GetCurrentVirtualScreenNum()1530 uint32_t RSScreenManager::GetCurrentVirtualScreenNum()
1531 {
1532 return currentVirtualScreenNum_;
1533 }
1534
SetScreenActiveMode(ScreenId id,uint32_t modeId)1535 uint32_t RSScreenManager::SetScreenActiveMode(ScreenId id, uint32_t modeId)
1536 {
1537 auto screen = GetScreen(id);
1538 if (screen == nullptr) {
1539 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1540 return StatusCode::SCREEN_NOT_FOUND;
1541 }
1542 return screen->SetActiveMode(modeId);
1543 }
1544
SetScreenActiveRect(ScreenId id,const GraphicIRect & activeRect)1545 uint32_t RSScreenManager::SetScreenActiveRect(ScreenId id, const GraphicIRect& activeRect)
1546 {
1547 auto screen = GetScreen(id);
1548 if (screen == nullptr) {
1549 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1550 return StatusCode::SCREEN_NOT_FOUND;
1551 }
1552
1553 RSHardwareThread::Instance().ScheduleTask([screen, activeRect, id]() {
1554 if (screen->SetScreenActiveRect(activeRect) != StatusCode::SUCCESS) {
1555 RS_LOGW("%{public}s: Invalid param", __func__);
1556 return;
1557 }
1558
1559 if (auto output = screen->GetOutput()) {
1560 output->SetActiveRectSwitchStatus(true);
1561 }
1562 }).wait();
1563 return StatusCode::SUCCESS;
1564 }
1565
SetPhysicalScreenResolution(ScreenId id,uint32_t width,uint32_t height)1566 int32_t RSScreenManager::SetPhysicalScreenResolution(ScreenId id, uint32_t width, uint32_t height)
1567 {
1568 auto screen = GetScreen(id);
1569 if (screen == nullptr) {
1570 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1571 return SCREEN_NOT_FOUND;
1572 }
1573 return screen->SetResolution(width, height);
1574 }
1575
SetVirtualScreenResolution(ScreenId id,uint32_t width,uint32_t height)1576 int32_t RSScreenManager::SetVirtualScreenResolution(ScreenId id, uint32_t width, uint32_t height)
1577 {
1578 if (width > MAX_VIRTUAL_SCREEN_WIDTH || height > MAX_VIRTUAL_SCREEN_HEIGHT) {
1579 RS_LOGW("%{public}s: width %{public}" PRIu32 " or height %{public}" PRIu32 " has reached "
1580 "the maximum limit!", __func__, width, height);
1581 return INVALID_ARGUMENTS;
1582 }
1583 auto screen = GetScreen(id);
1584 if (screen == nullptr) {
1585 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1586 return SCREEN_NOT_FOUND;
1587 }
1588 screen->SetResolution(width, height);
1589 RS_LOGI("%{public}s: set virtual screen resolution success", __func__);
1590 RS_OPTIONAL_TRACE_NAME("RSScreenManager::SetVirtualScreenResolution, ForceRefreshOneFrame.");
1591 ForceRefreshOneFrame();
1592 return SUCCESS;
1593 }
1594
SetRogScreenResolution(ScreenId id,uint32_t width,uint32_t height)1595 int32_t RSScreenManager::SetRogScreenResolution(ScreenId id, uint32_t width, uint32_t height)
1596 {
1597 auto screen = GetScreen(id);
1598 if (screen == nullptr) {
1599 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1600 return SCREEN_NOT_FOUND;
1601 }
1602 screen->SetRogResolution(width, height);
1603 return SUCCESS;
1604 }
1605
ProcessVSyncScreenIdWhilePowerStatusChanged(ScreenId id,ScreenPowerStatus status)1606 void RSScreenManager::ProcessVSyncScreenIdWhilePowerStatusChanged(ScreenId id, ScreenPowerStatus status)
1607 {
1608 auto vsyncSampler = CreateVSyncSampler();
1609 if (vsyncSampler == nullptr) {
1610 RS_LOGE("%{public}s failed, vsyncSampler is null.", __func__);
1611 return;
1612 }
1613 RS_TRACE_NAME_FMT("%s, id:%lu, status:%d, isPowerOff:%d, isSuspend:%d", __func__, id, status,
1614 (status == ScreenPowerStatus::POWER_STATUS_OFF), (status == ScreenPowerStatus::POWER_STATUS_SUSPEND));
1615 if (status == ScreenPowerStatus::POWER_STATUS_OFF || status == ScreenPowerStatus::POWER_STATUS_SUSPEND) {
1616 vsyncSampler->SetScreenVsyncEnabledInRSMainThread(id, false);
1617 }
1618 if (isFoldScreenFlag_) {
1619 uint64_t vsyncEnabledScreenId = JudgeVSyncEnabledScreenWhilePowerStatusChanged(id, status);
1620 uint64_t lastVsyncEnabledScreenId = vsyncSampler->GetVsyncEnabledScreenId();
1621 if (vsyncEnabledScreenId != lastVsyncEnabledScreenId) {
1622 RS_TRACE_NAME_FMT("vsyncEnabledScreenId has changed, need disable lastVsyncEnabledScreenId vsync, "
1623 "vsyncEnabledScreenId:%lu, lastVsyncEnabledScreenId:%lu",
1624 vsyncEnabledScreenId, lastVsyncEnabledScreenId);
1625 vsyncSampler->SetScreenVsyncEnabledInRSMainThread(lastVsyncEnabledScreenId, false);
1626 }
1627 UpdateVsyncEnabledScreenId(vsyncEnabledScreenId);
1628 }
1629 }
1630
UpdateScreenPowerStatus(ScreenId id,ScreenPowerStatus status)1631 void RSScreenManager::UpdateScreenPowerStatus(ScreenId id, ScreenPowerStatus status)
1632 {
1633 auto screen = GetScreen(id);
1634 if (screen == nullptr) {
1635 RS_LOGW("[UL_POWER] %{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1636 return;
1637 }
1638
1639 isScreenPoweringOn_ =
1640 (status == ScreenPowerStatus::POWER_STATUS_ON || status == ScreenPowerStatus::POWER_STATUS_ON_ADVANCED);
1641 auto ret = screen->SetPowerStatus(static_cast<uint32_t>(status));
1642 isScreenPoweringOn_ = false;
1643 if (ret != static_cast<int32_t>(StatusCode::SUCCESS)) {
1644 RS_LOGE("[UL_POWER] %{public}s: Failed to set power status of id %{public}" PRIu64, __func__, id);
1645 return;
1646 }
1647
1648 ProcessVSyncScreenIdWhilePowerStatusChanged(id, status);
1649
1650 /*
1651 * If app adds the first frame when power on the screen, delete the code
1652 */
1653 if (status == ScreenPowerStatus::POWER_STATUS_ON ||
1654 status == ScreenPowerStatus::POWER_STATUS_ON_ADVANCED) {
1655 RSFirstFrameNotifier::GetInstance().AddFirstFrameCommitScreen(id);
1656 auto mainThread = RSMainThread::Instance();
1657 if (mainThread == nullptr) {
1658 RS_LOGE("[UL_POWER] %{public}s: mainThread is nullptr", __func__);
1659 return;
1660 }
1661 mainThread->PostTask([mainThread]() {
1662 mainThread->SetDirtyFlag();
1663 mainThread->SetScreenPowerOnChanged(true);
1664 });
1665 std::shared_lock<std::shared_mutex> lock(powerStatusMutex_);
1666 if (screenPowerStatus_.count(id) == 0 ||
1667 screenPowerStatus_[id] == ScreenPowerStatus::POWER_STATUS_OFF ||
1668 screenPowerStatus_[id] == ScreenPowerStatus::POWER_STATUS_OFF_FAKE ||
1669 screenPowerStatus_[id] == ScreenPowerStatus::POWER_STATUS_OFF_ADVANCED) {
1670 mainThread->ForceRefreshForUni();
1671 } else {
1672 mainThread->RequestNextVSync();
1673 }
1674
1675 RS_LOGI("[UL_POWER] %{public}s: PowerStatus %{public}d, request a frame", __func__, status);
1676 }
1677 RSColorTemperature::Get().UpdateScreenStatus(id, status);
1678 std::lock_guard<std::shared_mutex> lock(powerStatusMutex_);
1679 screenPowerStatus_[id] = status;
1680 }
1681
SetScreenPowerStatus(ScreenId id,ScreenPowerStatus status)1682 void RSScreenManager::SetScreenPowerStatus(ScreenId id, ScreenPowerStatus status)
1683 {
1684 if (!RSSystemProperties::IsSmallFoldDevice()) {
1685 UpdateScreenPowerStatus(id, status);
1686 return;
1687 }
1688
1689 ResetScreenPowerStatusTask();
1690 RSSwitchingThread::Instance().PostTask([id, status, this]() {
1691 if (status == ScreenPowerStatus::POWER_STATUS_OFF) {
1692 std::lock_guard<std::shared_mutex> lock(powerStatusMutex_);
1693 isScreenPoweringOff_.insert(id);
1694 }
1695
1696 UpdateScreenPowerStatus(id, status);
1697
1698 {
1699 std::lock_guard<std::shared_mutex> lock(powerStatusMutex_);
1700 isScreenPoweringOff_.erase(id);
1701 }
1702
1703 std::unique_lock<std::mutex> taskLock(syncTaskMutex_);
1704 statusTaskEndFlag_ = true;
1705 statusTaskCV_.notify_all();
1706 });
1707 }
1708
ResetScreenPowerStatusTask()1709 void RSScreenManager::ResetScreenPowerStatusTask()
1710 {
1711 if (!RSSystemProperties::IsSmallFoldDevice()) {
1712 return;
1713 }
1714
1715 std::unique_lock<std::mutex> taskLock(syncTaskMutex_);
1716 statusTaskEndFlag_ = false;
1717 }
1718
WaitScreenPowerStatusTask()1719 void RSScreenManager::WaitScreenPowerStatusTask()
1720 {
1721 if (!RSSystemProperties::IsSmallFoldDevice()) {
1722 return;
1723 }
1724
1725 std::unique_lock<std::mutex> taskLock(syncTaskMutex_);
1726 if (!statusTaskCV_.wait_for(taskLock, std::chrono::milliseconds(WAIT_FOR_STATUS_TASK_TIMEOUT), [this]() {
1727 return statusTaskEndFlag_;
1728 })) {
1729 RS_LOGW("[UL_POWER] %{public}s: wait screen power status task timeout", __func__);
1730 }
1731 }
1732
IsScreenPoweringOn() const1733 bool RSScreenManager::IsScreenPoweringOn() const
1734 {
1735 return isScreenPoweringOn_;
1736 }
1737
IsScreenPoweringOff(ScreenId id) const1738 bool RSScreenManager::IsScreenPoweringOff(ScreenId id) const
1739 {
1740 std::shared_lock<std::shared_mutex> lock(powerStatusMutex_);
1741 return isScreenPoweringOff_.count(id) != 0;
1742 }
1743
SetVirtualMirrorScreenCanvasRotation(ScreenId id,bool canvasRotation)1744 bool RSScreenManager::SetVirtualMirrorScreenCanvasRotation(ScreenId id, bool canvasRotation)
1745 {
1746 auto screen = GetScreen(id);
1747 if (screen == nullptr) {
1748 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1749 return false;
1750 }
1751
1752 RS_LOGI("%{public}s: canvasRotation: %{public}d", __func__, canvasRotation);
1753 return screen->SetVirtualMirrorScreenCanvasRotation(canvasRotation);
1754 }
1755
SetVirtualScreenAutoRotation(ScreenId id,bool isAutoRotation)1756 int32_t RSScreenManager::SetVirtualScreenAutoRotation(ScreenId id, bool isAutoRotation)
1757 {
1758 auto screen = GetScreen(id);
1759 if (screen == nullptr) {
1760 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1761 return StatusCode::SCREEN_NOT_FOUND;
1762 }
1763
1764 RS_LOGI("%{public}s: screenId: %{public}" PRIu64 " isAutoRotation: %{public}d", __func__, id, isAutoRotation);
1765 return screen->SetVirtualScreenAutoRotation(isAutoRotation);
1766 }
1767
SetVirtualMirrorScreenScaleMode(ScreenId id,ScreenScaleMode scaleMode)1768 bool RSScreenManager::SetVirtualMirrorScreenScaleMode(ScreenId id, ScreenScaleMode scaleMode)
1769 {
1770 auto screen = GetScreen(id);
1771 if (screen == nullptr) {
1772 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1773 return false;
1774 }
1775
1776 RS_LOGI("%{public}s: scaleMode: %{public}d", __func__, scaleMode);
1777 return screen->SetVirtualMirrorScreenScaleMode(scaleMode);
1778 }
1779
GetDefaultScreenActiveMode(RSScreenModeInfo & screenModeInfo) const1780 void RSScreenManager::GetDefaultScreenActiveMode(RSScreenModeInfo& screenModeInfo) const
1781 {
1782 GetScreenActiveMode(defaultScreenId_, screenModeInfo);
1783 }
1784
ReleaseScreenDmaBuffer(ScreenId screenId)1785 void RSScreenManager::ReleaseScreenDmaBuffer(ScreenId screenId)
1786 {
1787 #ifdef RS_ENABLE_GPU
1788 RSHardwareThread::Instance().PostTask([this, screenId]() {
1789 RS_TRACE_NAME("RSScreenManager ReleaseScreenDmaBuffer");
1790 auto output = GetOutput(screenId);
1791 if (output == nullptr) {
1792 RS_LOGE("ReleaseScreenDmaBuffer: HdiOutput is nullptr!");
1793 return;
1794 }
1795 std::vector<LayerInfoPtr> layer;
1796 output->SetLayerInfo(layer);
1797 });
1798 #endif
1799 }
1800
1801 /* only used for mock tests */
MockHdiScreenConnected(std::shared_ptr<OHOS::Rosen::RSScreen> rsScreen)1802 void RSScreenManager::MockHdiScreenConnected(std::shared_ptr<OHOS::Rosen::RSScreen> rsScreen)
1803 {
1804 if (rsScreen == nullptr) {
1805 return;
1806 }
1807 screens_[rsScreen->Id()] = rsScreen;
1808 }
1809
GetScreenData(ScreenId id) const1810 RSScreenData RSScreenManager::GetScreenData(ScreenId id) const
1811 {
1812 RSScreenData screenData;
1813 if (GetScreen(id) == nullptr) {
1814 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1815 return screenData;
1816 }
1817 RSScreenCapability capability = GetScreenCapability(id);
1818 RSScreenModeInfo activeMode;
1819 GetScreenActiveMode(id, activeMode);
1820 std::vector<RSScreenModeInfo> supportModes = GetScreenSupportedModes(id);
1821 ScreenPowerStatus powerStatus = GetScreenPowerStatus(id);
1822 screenData.SetCapability(capability);
1823 screenData.SetActivityModeInfo(activeMode);
1824 screenData.SetSupportModeInfo(supportModes);
1825 screenData.SetPowerStatus(powerStatus);
1826 return screenData;
1827 }
1828
ResizeVirtualScreen(ScreenId id,uint32_t width,uint32_t height)1829 int32_t RSScreenManager::ResizeVirtualScreen(ScreenId id, uint32_t width, uint32_t height)
1830 {
1831 if (width > MAX_VIRTUAL_SCREEN_WIDTH || height > MAX_VIRTUAL_SCREEN_HEIGHT) {
1832 RS_LOGW("%{public}s: width %{public}" PRIu32 " or height %{public}" PRIu32 " has reached"
1833 " the maximum limit!", __func__, width, height);
1834 return INVALID_ARGUMENTS;
1835 }
1836 auto screen = GetScreen(id);
1837 if (screen == nullptr) {
1838 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1839 return SCREEN_NOT_FOUND;
1840 }
1841 screen->ResizeVirtualScreen(width, height);
1842 RS_LOGI("%{public}s: resize virtual screen success, width:%{public}u, height:%{public}u",
1843 __func__, width, height);
1844
1845 return SUCCESS;
1846 }
1847
GetScreenBacklight(ScreenId id) const1848 int32_t RSScreenManager::GetScreenBacklight(ScreenId id) const
1849 {
1850 auto screen = GetScreen(id);
1851 if (screen == nullptr) {
1852 RS_LOGE("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1853 return INVALID_BACKLIGHT_VALUE;
1854 }
1855 return screen->GetScreenBacklight();
1856 }
1857
SetScreenBacklight(ScreenId id,uint32_t level)1858 void RSScreenManager::SetScreenBacklight(ScreenId id, uint32_t level)
1859 {
1860 auto screen = GetScreen(id);
1861 if (screen == nullptr) {
1862 RS_LOGE("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1863 return;
1864 }
1865 screen->SetScreenBacklight(level);
1866
1867 std::lock_guard<std::shared_mutex> lock(backLightAndCorrectionMutex_);
1868 if (screenBacklight_[id] == level) {
1869 RS_LOGD("%{public}s: repeat backlight screenId: %{public}" PRIu64 " newLevel: %d", __func__, id, level);
1870 return;
1871 }
1872 screenBacklight_[id] = level;
1873 }
1874
QueryDefaultScreenInfo() const1875 ScreenInfo RSScreenManager::QueryDefaultScreenInfo() const
1876 {
1877 return QueryScreenInfo(defaultScreenId_);
1878 }
1879
QueryScreenInfo(ScreenId id) const1880 ScreenInfo RSScreenManager::QueryScreenInfo(ScreenId id) const
1881 {
1882 ScreenInfo info;
1883 auto screen = GetScreen(id);
1884 if (screen == nullptr) {
1885 RS_LOGE("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1886 return info;
1887 }
1888
1889 info.id = id;
1890 info.width = screen->Width();
1891 info.height = screen->Height();
1892 info.phyWidth = screen->PhyWidth() ? screen->PhyWidth() : screen->Width();
1893 info.phyHeight = screen->PhyHeight() ? screen->PhyHeight() : screen->Height();
1894 info.offsetX = screen->GetOffsetX();
1895 info.offsetY = screen->GetOffsetY();
1896 info.isSamplingOn = screen->IsSamplingOn();
1897 info.samplingTranslateX = screen->GetSamplingTranslateX();
1898 info.samplingTranslateY = screen->GetSamplingTranslateY();
1899 info.samplingScale = screen->GetSamplingScale();
1900 auto ret = screen->GetScreenColorGamut(info.colorGamut);
1901 if (ret != StatusCode::SUCCESS) {
1902 info.colorGamut = COLOR_GAMUT_SRGB;
1903 }
1904
1905 if (!screen->IsEnable()) {
1906 info.state = ScreenState::DISABLED;
1907 } else if (!screen->IsVirtual()) {
1908 info.state = ScreenState::HDI_OUTPUT_ENABLE;
1909 } else {
1910 info.state = ScreenState::SOFTWARE_OUTPUT_ENABLE;
1911 }
1912 info.skipFrameInterval = screen->GetScreenSkipFrameInterval();
1913 info.expectedRefreshRate = screen->GetScreenExpectedRefreshRate();
1914 info.skipFrameStrategy = screen->GetScreenSkipFrameStrategy();
1915 info.isEqualVsyncPeriod = screen->GetEqualVsyncPeriod();
1916 screen->GetPixelFormat(info.pixelFormat);
1917 screen->GetScreenHDRFormat(info.hdrFormat);
1918 info.whiteList = screen->GetWhiteList();
1919 info.enableVisibleRect = screen->GetEnableVisibleRect();
1920 info.activeRect = screen->GetActiveRect();
1921 info.maskRect = screen->GetMaskRect();
1922 info.reviseRect = screen->GetReviseRect();
1923 return info;
1924 }
1925
GetCanvasRotation(ScreenId id) const1926 bool RSScreenManager::GetCanvasRotation(ScreenId id) const
1927 {
1928 auto screen = GetScreen(id);
1929 if (screen == nullptr) {
1930 RS_LOGE("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1931 return false;
1932 }
1933 return screen->GetCanvasRotation();
1934 }
1935
GetVirtualScreenAutoRotation(ScreenId id) const1936 bool RSScreenManager::GetVirtualScreenAutoRotation(ScreenId id) const
1937 {
1938 auto screen = GetScreen(id);
1939 if (screen == nullptr) {
1940 RS_LOGE("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1941 return false;
1942 }
1943 return screen->GetVirtualScreenAutoRotation();
1944 }
1945
GetScaleMode(ScreenId id) const1946 ScreenScaleMode RSScreenManager::GetScaleMode(ScreenId id) const
1947 {
1948 auto screen = GetScreen(id);
1949 if (screen == nullptr) {
1950 RS_LOGE("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1951 return ScreenScaleMode::INVALID_MODE;
1952 }
1953 auto scaleModeDFX = static_cast<ScreenScaleMode>(
1954 RSSystemProperties::GetVirtualScreenScaleModeDFX());
1955 // Support mode can be configured for maintenance and testing before
1956 // upper layer application adaptation
1957 return (scaleModeDFX == ScreenScaleMode::INVALID_MODE) ? screen->GetScaleMode() : scaleModeDFX;
1958 }
1959
GetProducerSurface(ScreenId id) const1960 sptr<Surface> RSScreenManager::GetProducerSurface(ScreenId id) const
1961 {
1962 auto screen = GetScreen(id);
1963 if (screen == nullptr) {
1964 RS_LOGE("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1965 return nullptr;
1966 }
1967 return screen->GetProducerSurface();
1968 }
1969
GetOutput(ScreenId id) const1970 std::shared_ptr<HdiOutput> RSScreenManager::GetOutput(ScreenId id) const
1971 {
1972 auto screen = GetScreen(id);
1973 if (screen == nullptr) {
1974 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
1975 return nullptr;
1976 }
1977 return screen->GetOutput();
1978 }
1979
AddScreenChangeCallback(const sptr<RSIScreenChangeCallback> & callback)1980 int32_t RSScreenManager::AddScreenChangeCallback(const sptr<RSIScreenChangeCallback>& callback)
1981 {
1982 if (callback == nullptr) {
1983 RS_LOGE("%{public}s: callback is NULL.", __func__);
1984 return INVALID_ARGUMENTS;
1985 }
1986
1987 {
1988 std::lock_guard<std::mutex> lock(screenMapMutex_);
1989 // when the callback first registered, maybe there were some physical screens already connected,
1990 // so notify to remote immediately.
1991 for (const auto& [id, screen] : screens_) {
1992 if (screen == nullptr) {
1993 RS_LOGW("%{public}s: screen %{public}" PRIu64 " not found", __func__, id);
1994 continue;
1995 }
1996 if (!screen->IsVirtual()) {
1997 callback->OnScreenChanged(id, ScreenEvent::CONNECTED);
1998 }
1999 }
2000 }
2001
2002 std::lock_guard<std::shared_mutex> lock(screenChangeCallbackMutex_);
2003 screenChangeCallbacks_.push_back(callback);
2004 RS_LOGI("%{public}s: add a remote callback succeed.", __func__);
2005 return SUCCESS;
2006 }
2007
RemoveScreenChangeCallback(const sptr<RSIScreenChangeCallback> & callback)2008 void RSScreenManager::RemoveScreenChangeCallback(const sptr<RSIScreenChangeCallback>& callback)
2009 {
2010 std::lock_guard<std::shared_mutex> lock(screenChangeCallbackMutex_);
2011 auto iter = std::find(screenChangeCallbacks_.cbegin(), screenChangeCallbacks_.cend(), callback);
2012 if (iter == screenChangeCallbacks_.cend()) {
2013 RS_LOGW("%{public}s: The remote callback is not in screenChangeCallbacks_", __func__);
2014 return;
2015 }
2016 screenChangeCallbacks_.erase(iter);
2017 RS_LOGI("%{public}s: remove a remote callback succeed.", __func__);
2018 }
2019
SetScreenSwitchingNotifyCallback(const sptr<RSIScreenSwitchingNotifyCallback> & callback)2020 int32_t RSScreenManager::SetScreenSwitchingNotifyCallback(const sptr<RSIScreenSwitchingNotifyCallback>& callback)
2021 {
2022 std::lock_guard<std::shared_mutex> lock(screenSwitchingNotifyCallbackMutex_);
2023 screenSwitchingNotifyCallback_ = callback;
2024 RS_LOGI("%{public}s: set screen switching notify callback succeed.", __func__);
2025 return SUCCESS;
2026 }
2027
RegisterScreenNodeListener(std::shared_ptr<RSIScreenNodeListener> listener)2028 void RSScreenManager::RegisterScreenNodeListener(std::shared_ptr<RSIScreenNodeListener> listener)
2029 {
2030 if (listener == nullptr) {
2031 RS_LOGE("%{public}s: callback is null", __func__);
2032 return;
2033 }
2034
2035 {
2036 std::lock_guard<std::mutex> lock(screenMapMutex_);
2037 for (const auto& [id, screen] : screens_) {
2038 if (screen == nullptr) {
2039 RS_LOGW("%{public}s: screen %{public}" PRIu64 " not found", __func__, id);
2040 continue;
2041 }
2042 listener->OnScreenConnect(id);
2043 }
2044 }
2045
2046 std::lock_guard<std::shared_mutex> lock(screenChangeCallbackMutex_);
2047 screenNodeListener_ = listener;
2048 }
2049
DisplayDump(std::string & dumpString)2050 void RSScreenManager::DisplayDump(std::string& dumpString)
2051 {
2052 std::lock_guard<std::mutex> lock(screenMapMutex_);
2053 int32_t index = 0;
2054 for (const auto& [id, screen] : screens_) {
2055 if (screen == nullptr) {
2056 RS_LOGE("%{public}s: screen %{public}" PRIu64 " not found.", __func__, id);
2057 continue;
2058 }
2059 screen->DisplayDump(index, dumpString);
2060 index++;
2061 }
2062 if (isFoldScreenFlag_) {
2063 dumpString += "===================\n";
2064 dumpString += "foldScreenIds_ size is " + std::to_string(foldScreenIds_.size()) + "\n";
2065 for (auto& [screenId, status] : foldScreenIds_) {
2066 dumpString += "foldScreenId:" + std::to_string(screenId) +
2067 ", isConnected:" + std::to_string(status.isConnected) +
2068 ", isPowerOn:" + std::to_string(status.isPowerOn) + "\n";
2069 }
2070 }
2071 }
2072
SurfaceDump(std::string & dumpString)2073 void RSScreenManager::SurfaceDump(std::string& dumpString)
2074 {
2075 std::lock_guard<std::mutex> lock(screenMapMutex_);
2076 int32_t index = 0;
2077 for (const auto& [id, screen] : screens_) {
2078 if (screen == nullptr) {
2079 RS_LOGE("%{public}s: screen %{public}" PRIu64 " not found.", __func__, id);
2080 continue;
2081 }
2082 screen->SurfaceDump(index, dumpString);
2083 index++;
2084 }
2085 }
2086
DumpCurrentFrameLayers()2087 void RSScreenManager::DumpCurrentFrameLayers()
2088 {
2089 std::lock_guard<std::mutex> lock(screenMapMutex_);
2090 for (const auto &[id, screen] : screens_) {
2091 if (screen == nullptr) {
2092 RS_LOGE("RSScreenManager %{public}s: screen %{public}" PRIu64 " not found.", __func__, id);
2093 continue;
2094 }
2095 screen->DumpCurrentFrameLayers();
2096 }
2097 }
2098
FpsDump(std::string & dumpString,std::string & arg)2099 void RSScreenManager::FpsDump(std::string& dumpString, std::string& arg)
2100 {
2101 std::lock_guard<std::mutex> lock(screenMapMutex_);
2102 int32_t index = 0;
2103 dumpString += "\n-- The recently fps records info of screens:\n";
2104 for (const auto& [id, screen] : screens_) {
2105 if (screen == nullptr) {
2106 RS_LOGE("%{public}s: screen %{public}" PRIu64 " not found.", __func__, id);
2107 continue;
2108 }
2109 screen->FpsDump(index, dumpString, arg);
2110 index++;
2111 }
2112 }
2113
ClearFpsDump(std::string & dumpString,std::string & arg)2114 void RSScreenManager::ClearFpsDump(std::string& dumpString, std::string& arg)
2115 {
2116 std::lock_guard<std::mutex> lock(screenMapMutex_);
2117 int32_t index = 0;
2118 dumpString += "\n-- Clear fps records info of screens:\n";
2119 for (const auto& [id, screen] : screens_) {
2120 if (screen == nullptr) {
2121 RS_LOGE("%{public}s: screen %{public}" PRIu64 " not found.", __func__, id);
2122 continue;
2123 }
2124 screen->ClearFpsDump(index, dumpString, arg);
2125 index++;
2126 }
2127 }
2128
ClearFrameBufferIfNeed()2129 void RSScreenManager::ClearFrameBufferIfNeed()
2130 {
2131 #ifdef RS_ENABLE_GPU
2132 RSHardwareThread::Instance().PostTask([this]() {
2133 std::lock_guard<std::mutex> lock(screenMapMutex_);
2134 for (const auto& [id, screen] : screens_) {
2135 if (!screen || !screen->GetOutput()) {
2136 RS_LOGE("%{public}s: screen %{public}" PRIu64 " not found.", __func__, id);
2137 continue;
2138 }
2139 if (screen->GetHasProtectedLayer()) {
2140 RS_TRACE_NAME_FMT("screen Id:%lu has protected layer.", id);
2141 continue;
2142 }
2143 if (screen->GetOutput()->GetBufferCacheSize() > 0) {
2144 RS_LOGI("%{public}s: screen %{public}" PRIu64 " ClearFrameBuffers.", __func__, id);
2145 RSHardwareThread::Instance().ClearFrameBuffers(screen->GetOutput());
2146 }
2147 }
2148 });
2149 #endif
2150 }
2151
SetScreenConstraint(ScreenId id,uint64_t timestamp,ScreenConstraintType type)2152 int32_t RSScreenManager::SetScreenConstraint(ScreenId id, uint64_t timestamp, ScreenConstraintType type)
2153 {
2154 frameId_++;
2155 auto screen = GetScreen(id);
2156 if (screen == nullptr) {
2157 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2158 return StatusCode::SCREEN_NOT_FOUND;
2159 }
2160 RS_TRACE_NAME_FMT("SetScreenConstraint frameId:%lu timestamp:%lu type:%d", frameId_, timestamp, type);
2161 return screen->SetScreenConstraint(frameId_, timestamp, type);
2162 }
2163
HitchsDump(std::string & dumpString,std::string & arg)2164 void RSScreenManager::HitchsDump(std::string& dumpString, std::string& arg)
2165 {
2166 std::lock_guard<std::mutex> lock(screenMapMutex_);
2167 int32_t index = 0;
2168 dumpString += "\n-- The recently window hitchs records info of screens:\n";
2169 for (const auto& [id, screen] : screens_) {
2170 if (screen == nullptr) {
2171 RS_LOGE("%{public}s: screen %{public}" PRIu64 " not found.", __func__, id);
2172 continue;
2173 }
2174 screen->HitchsDump(index, dumpString, arg);
2175 index++;
2176 }
2177 }
2178
GetScreenSupportedColorGamuts(ScreenId id,std::vector<ScreenColorGamut> & mode) const2179 int32_t RSScreenManager::GetScreenSupportedColorGamuts(ScreenId id, std::vector<ScreenColorGamut>& mode) const
2180 {
2181 auto screen = GetScreen(id);
2182 if (screen == nullptr) {
2183 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2184 return StatusCode::SCREEN_NOT_FOUND;
2185 }
2186 return screen->GetScreenSupportedColorGamuts(mode);
2187 }
2188
GetScreenSupportedMetaDataKeys(ScreenId id,std::vector<ScreenHDRMetadataKey> & keys) const2189 int32_t RSScreenManager::GetScreenSupportedMetaDataKeys(ScreenId id, std::vector<ScreenHDRMetadataKey>& keys) const
2190 {
2191 auto screen = GetScreen(id);
2192 if (screen == nullptr) {
2193 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2194 return StatusCode::SCREEN_NOT_FOUND;
2195 }
2196 return screen->GetScreenSupportedMetaDataKeys(keys);
2197 }
2198
GetScreenColorGamut(ScreenId id,ScreenColorGamut & mode) const2199 int32_t RSScreenManager::GetScreenColorGamut(ScreenId id, ScreenColorGamut& mode) const
2200 {
2201 auto screen = GetScreen(id);
2202 if (screen == nullptr) {
2203 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2204 return StatusCode::SCREEN_NOT_FOUND;
2205 }
2206 return screen->GetScreenColorGamut(mode);
2207 }
2208
SetScreenColorGamut(ScreenId id,int32_t modeIdx)2209 int32_t RSScreenManager::SetScreenColorGamut(ScreenId id, int32_t modeIdx)
2210 {
2211 auto screen = GetScreen(id);
2212 if (screen == nullptr) {
2213 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2214 return StatusCode::SCREEN_NOT_FOUND;
2215 }
2216 return screen->SetScreenColorGamut(modeIdx);
2217 }
2218
SetScreenGamutMap(ScreenId id,ScreenGamutMap mode)2219 int32_t RSScreenManager::SetScreenGamutMap(ScreenId id, ScreenGamutMap mode)
2220 {
2221 auto screen = GetScreen(id);
2222 if (screen == nullptr) {
2223 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2224 return StatusCode::SCREEN_NOT_FOUND;
2225 }
2226 RS_OPTIONAL_TRACE_NAME("RSScreenManager::SetScreenGamutMapLocked, ForceRefreshOneFrame.");
2227 ForceRefreshOneFrame();
2228 return screen->SetScreenGamutMap(mode);
2229 }
2230
SetScreenCorrection(ScreenId id,ScreenRotation screenRotation)2231 int32_t RSScreenManager::SetScreenCorrection(ScreenId id, ScreenRotation screenRotation)
2232 {
2233 auto screen = GetScreen(id);
2234 if (screen == nullptr) {
2235 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2236 return StatusCode::SCREEN_NOT_FOUND;
2237 }
2238 screen->SetScreenCorrection(screenRotation);
2239
2240 std::lock_guard<std::shared_mutex> lock(backLightAndCorrectionMutex_);
2241 screenCorrection_[id] = screenRotation;
2242 return StatusCode::SUCCESS;
2243 }
2244
GetScreenGamutMap(ScreenId id,ScreenGamutMap & mode) const2245 int32_t RSScreenManager::GetScreenGamutMap(ScreenId id, ScreenGamutMap& mode) const
2246 {
2247 auto screen = GetScreen(id);
2248 if (screen == nullptr) {
2249 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2250 return StatusCode::SCREEN_NOT_FOUND;
2251 }
2252 return screen->GetScreenGamutMap(mode);
2253 }
2254
GetScreenHDRCapability(ScreenId id,RSScreenHDRCapability & screenHdrCapability) const2255 int32_t RSScreenManager::GetScreenHDRCapability(ScreenId id, RSScreenHDRCapability& screenHdrCapability) const
2256 {
2257 auto screen = GetScreen(id);
2258 if (screen == nullptr) {
2259 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2260 return StatusCode::SCREEN_NOT_FOUND;
2261 }
2262
2263 GraphicHDRCapability hdrCapability = screen->GetHDRCapability();
2264 std::vector<ScreenHDRFormat> hdrFormats(hdrCapability.formats.size());
2265 std::transform(hdrCapability.formats.cbegin(), hdrCapability.formats.cend(), hdrFormats.begin(),
2266 [](const auto& node) { return static_cast<ScreenHDRFormat>(node); }
2267 );
2268
2269 screenHdrCapability.SetMaxLum(hdrCapability.maxLum);
2270 screenHdrCapability.SetMaxAverageLum(hdrCapability.maxAverageLum);
2271 screenHdrCapability.SetMinLum(hdrCapability.minLum);
2272 screenHdrCapability.SetHdrFormats(std::move(hdrFormats));
2273 return StatusCode::SUCCESS;
2274 }
2275
GetScreenType(ScreenId id,RSScreenType & type) const2276 int32_t RSScreenManager::GetScreenType(ScreenId id, RSScreenType& type) const
2277 {
2278 auto screen = GetScreen(id);
2279 if (screen == nullptr) {
2280 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2281 return StatusCode::SCREEN_NOT_FOUND;
2282 }
2283
2284 type = screen->GetScreenType();
2285 return StatusCode::SUCCESS;
2286 }
2287
SetScreenSkipFrameInterval(ScreenId id,uint32_t skipFrameInterval)2288 int32_t RSScreenManager::SetScreenSkipFrameInterval(ScreenId id, uint32_t skipFrameInterval)
2289 {
2290 auto screen = GetScreen(id);
2291 if (screen == nullptr) {
2292 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2293 return StatusCode::SCREEN_NOT_FOUND;
2294 }
2295 RSScreenModeInfo screenModeInfo;
2296 // use the refresh rate of the physical screen as the maximum refresh rate
2297 GetDefaultScreenActiveMode(screenModeInfo);
2298 // guaranteed screen refresh rate at least 1
2299 if (skipFrameInterval == 0 || (skipFrameInterval > screenModeInfo.GetScreenRefreshRate())) {
2300 RS_LOGE("%{public}s: screen %{public}" PRIu64 " is INVALID_ARGUMENTS.", __func__, id);
2301 return INVALID_ARGUMENTS;
2302 }
2303 screen->SetScreenSkipFrameInterval(skipFrameInterval);
2304 screen->SetEqualVsyncPeriod(skipFrameInterval == 1);
2305 RS_LOGI("%{public}s: screen(id %{public}" PRIu64 "), skipFrameInterval(%{public}d).",
2306 __func__, id, skipFrameInterval);
2307 return StatusCode::SUCCESS;
2308 }
2309
SetVirtualScreenRefreshRate(ScreenId id,uint32_t maxRefreshRate,uint32_t & actualRefreshRate)2310 int32_t RSScreenManager::SetVirtualScreenRefreshRate(ScreenId id, uint32_t maxRefreshRate, uint32_t& actualRefreshRate)
2311 {
2312 auto screen = GetScreen(id);
2313 if (screen == nullptr) {
2314 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2315 return StatusCode::SCREEN_NOT_FOUND;
2316 }
2317 if (!screen->IsVirtual()) {
2318 RS_LOGW("%{public}s: Not Support for screen:%{public}" PRIu64, __func__, id);
2319 return StatusCode::SCREEN_NOT_FOUND;
2320 }
2321 if (maxRefreshRate == 0) {
2322 RS_LOGW("%{public}s: Invalid maxRefreshRate:%{public}u.", __func__, maxRefreshRate);
2323 return StatusCode::INVALID_ARGUMENTS;
2324 }
2325 if (maxRefreshRate > MAX_VIRTUAL_SCREEN_REFRESH_RATE) {
2326 maxRefreshRate = MAX_VIRTUAL_SCREEN_REFRESH_RATE;
2327 }
2328 screen->SetScreenExpectedRefreshRate(maxRefreshRate);
2329 RS_LOGI("%{public}s: screen(id %{public}" PRIu64 "), maxRefreshRate(%{public}d).",
2330 __func__, id, maxRefreshRate);
2331 actualRefreshRate = maxRefreshRate;
2332 return StatusCode::SUCCESS;
2333 }
2334
SetEqualVsyncPeriod(ScreenId id,bool isEqualVsyncPeriod)2335 void RSScreenManager::SetEqualVsyncPeriod(ScreenId id, bool isEqualVsyncPeriod)
2336 {
2337 auto screen = GetScreen(id);
2338 if (screen == nullptr) {
2339 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2340 return;
2341 }
2342 screen->SetEqualVsyncPeriod(isEqualVsyncPeriod);
2343 return;
2344 }
2345
GetDisplayIdentificationData(ScreenId id,uint8_t & outPort,std::vector<uint8_t> & edidData) const2346 int32_t RSScreenManager::GetDisplayIdentificationData(ScreenId id, uint8_t& outPort,
2347 std::vector<uint8_t>& edidData) const
2348 {
2349 auto screen = GetScreen(id);
2350 if (screen == nullptr) {
2351 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2352 return SCREEN_NOT_FOUND;
2353 }
2354
2355 return screen->GetDisplayIdentificationData(outPort, edidData);
2356 }
2357
GetPixelFormat(ScreenId id,GraphicPixelFormat & pixelFormat) const2358 int32_t RSScreenManager::GetPixelFormat(ScreenId id, GraphicPixelFormat& pixelFormat) const
2359 {
2360 auto screen = GetScreen(id);
2361 if (screen == nullptr) {
2362 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2363 return StatusCode::SCREEN_NOT_FOUND;
2364 }
2365 return screen->GetPixelFormat(pixelFormat);
2366 }
2367
SetPixelFormat(ScreenId id,GraphicPixelFormat pixelFormat)2368 int32_t RSScreenManager::SetPixelFormat(ScreenId id, GraphicPixelFormat pixelFormat)
2369 {
2370 auto screen = GetScreen(id);
2371 if (screen == nullptr) {
2372 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2373 return StatusCode::SCREEN_NOT_FOUND;
2374 }
2375 return screen->SetPixelFormat(pixelFormat);
2376 }
2377
GetScreenSupportedHDRFormats(ScreenId id,std::vector<ScreenHDRFormat> & hdrFormats) const2378 int32_t RSScreenManager::GetScreenSupportedHDRFormats(ScreenId id, std::vector<ScreenHDRFormat>& hdrFormats) const
2379 {
2380 auto screen = GetScreen(id);
2381 if (screen == nullptr) {
2382 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2383 return StatusCode::SCREEN_NOT_FOUND;
2384 }
2385 return screen->GetScreenSupportedHDRFormats(hdrFormats);
2386 }
2387
GetScreenHDRFormat(ScreenId id,ScreenHDRFormat & hdrFormat) const2388 int32_t RSScreenManager::GetScreenHDRFormat(ScreenId id, ScreenHDRFormat& hdrFormat) const
2389 {
2390 auto screen = GetScreen(id);
2391 if (screen == nullptr) {
2392 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2393 return StatusCode::SCREEN_NOT_FOUND;
2394 }
2395 return screen->GetScreenHDRFormat(hdrFormat);
2396 }
2397
SetScreenHDRFormat(ScreenId id,int32_t modeIdx)2398 int32_t RSScreenManager::SetScreenHDRFormat(ScreenId id, int32_t modeIdx)
2399 {
2400 auto screen = GetScreen(id);
2401 if (screen == nullptr) {
2402 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2403 return StatusCode::SCREEN_NOT_FOUND;
2404 }
2405 return screen->SetScreenHDRFormat(modeIdx);
2406 }
2407
GetScreenSupportedColorSpaces(ScreenId id,std::vector<GraphicCM_ColorSpaceType> & colorSpaces) const2408 int32_t RSScreenManager::GetScreenSupportedColorSpaces(
2409 ScreenId id, std::vector<GraphicCM_ColorSpaceType>& colorSpaces) const
2410 {
2411 auto screen = GetScreen(id);
2412 if (screen == nullptr) {
2413 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2414 return StatusCode::SCREEN_NOT_FOUND;
2415 }
2416 return screen->GetScreenSupportedColorSpaces(colorSpaces);
2417 }
2418
GetScreenColorSpace(ScreenId id,GraphicCM_ColorSpaceType & colorSpace) const2419 int32_t RSScreenManager::GetScreenColorSpace(ScreenId id, GraphicCM_ColorSpaceType& colorSpace) const
2420 {
2421 auto screen = GetScreen(id);
2422 if (screen == nullptr) {
2423 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2424 return StatusCode::SCREEN_NOT_FOUND;
2425 }
2426 return screen->GetScreenColorSpace(colorSpace);
2427 }
2428
SetScreenColorSpace(ScreenId id,GraphicCM_ColorSpaceType colorSpace)2429 int32_t RSScreenManager::SetScreenColorSpace(ScreenId id, GraphicCM_ColorSpaceType colorSpace)
2430 {
2431 auto screen = GetScreen(id);
2432 if (screen == nullptr) {
2433 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2434 return StatusCode::SCREEN_NOT_FOUND;
2435 }
2436 return screen->SetScreenColorSpace(colorSpace);
2437 }
2438
GetActualScreenMaxResolution() const2439 ScreenInfo RSScreenManager::GetActualScreenMaxResolution() const
2440 {
2441 ScreenId maxScreenId = INVALID_SCREEN_ID;
2442 {
2443 std::lock_guard<std::mutex> lock(screenMapMutex_);
2444 uint32_t maxResolution = 0;
2445 for (const auto& [id, screen] : screens_) {
2446 if (!screen || screen->IsVirtual()) {
2447 RS_LOGE("%{public}s: screen %{public}" PRIu64 " not found.", __func__, id);
2448 continue;
2449 }
2450 uint32_t resolution = screen->PhyWidth() * screen->PhyHeight();
2451 if (resolution > maxResolution) {
2452 maxScreenId = id;
2453 maxResolution = resolution;
2454 }
2455 }
2456 }
2457
2458 return QueryScreenInfo(maxScreenId);
2459 }
2460
MarkPowerOffNeedProcessOneFrame()2461 void RSScreenManager::MarkPowerOffNeedProcessOneFrame()
2462 {
2463 powerOffNeedProcessOneFrame_ = true;
2464 }
2465
ResetPowerOffNeedProcessOneFrame()2466 void RSScreenManager::ResetPowerOffNeedProcessOneFrame()
2467 {
2468 powerOffNeedProcessOneFrame_ = false;
2469 }
2470
GetPowerOffNeedProcessOneFrame() const2471 bool RSScreenManager::GetPowerOffNeedProcessOneFrame() const
2472 {
2473 return powerOffNeedProcessOneFrame_;
2474 }
2475
IsScreenPowerOff(ScreenId id) const2476 bool RSScreenManager::IsScreenPowerOff(ScreenId id) const
2477 {
2478 std::shared_lock<std::shared_mutex> lock(powerStatusMutex_);
2479 if (screenPowerStatus_.count(id) == 0) {
2480 RS_LOGD("%{public}s: screen %{public}" PRIu64 " not found.", __func__, id);
2481 return false;
2482 }
2483 return screenPowerStatus_.at(id) == GraphicDispPowerStatus::GRAPHIC_POWER_STATUS_SUSPEND ||
2484 screenPowerStatus_.at(id) == GraphicDispPowerStatus::GRAPHIC_POWER_STATUS_OFF;
2485 }
2486
DisablePowerOffRenderControl(ScreenId id)2487 void RSScreenManager::DisablePowerOffRenderControl(ScreenId id)
2488 {
2489 auto screen = GetScreen(id);
2490 if (screen == nullptr) {
2491 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2492 return;
2493 }
2494 std::lock_guard<std::mutex> lock(renderControlMutex_);
2495 RS_LOGI("%{public}s: Add Screen_%{public}" PRIu64 " for disable power-off render control.", __func__, id);
2496 disableRenderControlScreens_.insert(id);
2497 }
2498
GetDisableRenderControlScreensCount() const2499 int RSScreenManager::GetDisableRenderControlScreensCount() const
2500 {
2501 std::lock_guard<std::mutex> lock(renderControlMutex_);
2502 return disableRenderControlScreens_.size();
2503 }
2504
SetVirtualScreenStatus(ScreenId id,VirtualScreenStatus screenStatus)2505 bool RSScreenManager::SetVirtualScreenStatus(ScreenId id, VirtualScreenStatus screenStatus)
2506 {
2507 auto screen = GetScreen(id);
2508 if (screen == nullptr) {
2509 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2510 return false;
2511 }
2512 RS_LOGW("%{public}s: id %{public}" PRIu64 " status:%{public}d", __func__, id, screenStatus);
2513 return screen->SetVirtualScreenStatus(screenStatus);
2514 }
2515
GetVirtualScreenStatus(ScreenId id) const2516 VirtualScreenStatus RSScreenManager::GetVirtualScreenStatus(ScreenId id) const
2517 {
2518 auto screen = GetScreen(id);
2519 if (screen == nullptr) {
2520 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2521 return VirtualScreenStatus::VIRTUAL_SCREEN_INVALID_STATUS;
2522 }
2523 return screen->GetVirtualScreenStatus();
2524 }
2525
GetDisplayPropertyForHardCursor(uint32_t screenId)2526 bool RSScreenManager::GetDisplayPropertyForHardCursor(uint32_t screenId)
2527 {
2528 auto screen = GetScreen(screenId);
2529 if (screen == nullptr) {
2530 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu32, __func__, screenId);
2531 return false;
2532 }
2533 return screen->GetDisplayPropertyForHardCursor();
2534 }
2535
SetScreenHasProtectedLayer(ScreenId id,bool hasProtectedLayer)2536 void RSScreenManager::SetScreenHasProtectedLayer(ScreenId id, bool hasProtectedLayer)
2537 {
2538 auto screen = GetScreen(id);
2539 if (screen == nullptr) {
2540 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2541 return;
2542 }
2543 screen->SetHasProtectedLayer(hasProtectedLayer);
2544 }
2545
SetScreenSwitchStatus(bool flag)2546 void RSScreenManager::SetScreenSwitchStatus(bool flag)
2547 {
2548 RS_LOGI("%{public}s: set isScreenSwitching_ = %{public}d", __func__, flag);
2549 isScreenSwitching_ = flag;
2550 if (!flag) {
2551 NotifySwitchingCallback(flag);
2552 }
2553 }
2554
IsScreenSwitching() const2555 bool RSScreenManager::IsScreenSwitching() const
2556 {
2557 return isScreenSwitching_;
2558 }
2559
SetScreenLinearMatrix(ScreenId id,const std::vector<float> & matrix)2560 int32_t RSScreenManager::SetScreenLinearMatrix(ScreenId id, const std::vector<float>& matrix)
2561 {
2562 auto task = [this, id, matrix]() -> void {
2563 auto screen = GetScreen(id);
2564 if (screen == nullptr) {
2565 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2566 return;
2567 }
2568 screen->SetScreenLinearMatrix(matrix);
2569 };
2570 // SetScreenLinearMatrix is SMQ API, which can only be executed in RSHardwareThread.
2571 RSHardwareThread::Instance().PostTask(task);
2572 return StatusCode::SUCCESS;
2573 }
2574
IsVisibleRectSupportRotation(ScreenId id)2575 bool RSScreenManager::IsVisibleRectSupportRotation(ScreenId id)
2576 {
2577 auto screen = GetScreen(id);
2578 if (screen == nullptr) {
2579 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2580 return false;
2581 }
2582
2583 return screen->GetVisibleRectSupportRotation();
2584 }
2585
SetScreenOffset(ScreenId id,int32_t offsetX,int32_t offsetY)2586 void RSScreenManager::SetScreenOffset(ScreenId id, int32_t offsetX, int32_t offsetY)
2587 {
2588 auto screen = GetScreen(id);
2589 if (screen == nullptr) {
2590 RS_LOGW("%{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
2591 return;
2592 }
2593 screen->SetScreenOffset(offsetX, offsetY);
2594 }
2595
AnyScreenFits(std::function<bool (const ScreenNode &)> func) const2596 bool RSScreenManager::AnyScreenFits(std::function<bool(const ScreenNode&)> func) const
2597 {
2598 std::lock_guard<std::mutex> lock(screenMapMutex_);
2599 return std::any_of(screens_.cbegin(), screens_.cend(), func);
2600 }
2601
TriggerCallbacks(ScreenId id,ScreenEvent event,ScreenChangeReason reason) const2602 void RSScreenManager::TriggerCallbacks(ScreenId id, ScreenEvent event, ScreenChangeReason reason) const
2603 {
2604 std::shared_lock<std::shared_mutex> lock(screenChangeCallbackMutex_);
2605 RS_LOGI("%{public}s: id %{public}" PRIu64
2606 "event %{public}u reason %{public}u screenChangeCallbacks_.size() %{public}zu",
2607 __func__, id, static_cast<uint8_t>(event), static_cast<uint8_t>(reason), screenChangeCallbacks_.size());
2608 for (const auto& cb : screenChangeCallbacks_) {
2609 cb->OnScreenChanged(id, event, reason);
2610 }
2611 }
2612
NotifyScreenNodeChange(ScreenId id,bool connected) const2613 void RSScreenManager::NotifyScreenNodeChange(ScreenId id, bool connected) const
2614 {
2615 std::shared_lock<std::shared_mutex> lock(screenChangeCallbackMutex_);
2616 if (screenNodeListener_ == nullptr) {
2617 RS_LOGE("%{public}s: screenNodeListener_ is nullptr!", __func__);
2618 return;
2619 }
2620
2621 if (connected) {
2622 screenNodeListener_->OnScreenConnect(id);
2623 } else {
2624 screenNodeListener_->OnScreenDisconnect(id);
2625 }
2626 }
2627
NotifySwitchingCallback(bool status) const2628 void RSScreenManager::NotifySwitchingCallback(bool status) const
2629 {
2630 std::shared_lock<std::shared_mutex> lock(screenSwitchingNotifyCallbackMutex_);
2631 if (screenSwitchingNotifyCallback_ == nullptr) {
2632 RS_LOGE("%{public}s: screenSwitchingNotifyCallback_ is nullptr! status: %{public}d", __func__, status);
2633 return;
2634 }
2635
2636 RS_LOGI("%{public}s: status: %{public}d", __func__, status);
2637 screenSwitchingNotifyCallback_->OnScreenSwitchingNotify(status);
2638 }
2639
GetScreen(ScreenId id) const2640 std::shared_ptr<OHOS::Rosen::RSScreen> RSScreenManager::GetScreen(ScreenId id) const
2641 {
2642 std::lock_guard<std::mutex> lock(screenMapMutex_);
2643 auto iter = screens_.find(id);
2644 if (iter == screens_.end() || iter->second == nullptr) {
2645 return nullptr;
2646 }
2647 return iter->second;
2648 }
2649 } // namespace impl
2650
CreateOrGetScreenManager()2651 sptr<RSScreenManager> CreateOrGetScreenManager()
2652 {
2653 return impl::RSScreenManager::GetInstance();
2654 }
2655 } // namespace Rosen
2656 } // namespace OHOS
2657