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 "hgm_core.h"
19 #include "pipeline/rs_display_render_node.h"
20 #include "pipeline/rs_main_thread.h"
21 #include "pipeline/rs_hardware_thread.h"
22 #include "platform/common/rs_log.h"
23 #include "vsync_sampler.h"
24 #include <parameter.h>
25 #include <parameters.h>
26 #include "param/sys_param.h"
27
28 namespace OHOS {
29 namespace Rosen {
30 #ifdef RS_SUBSCRIBE_SENSOR_ENABLE
31 namespace {
32 constexpr float ANGLE_MIN_VAL = 0.0F;
33 constexpr float ANGLE_MAX_VAL = 180.0F;
34 constexpr int32_t SENSOR_SUCCESS = 0;
35 constexpr int32_t POSTURE_INTERVAL = 4000000;
36 constexpr uint16_t SENSOR_EVENT_FIRST_DATA = 0;
37 constexpr float HALF_FOLDED_MAX_THRESHOLD = 140.0F;
38 constexpr float OPEN_HALF_FOLDED_MIN_THRESHOLD = 25.0F;
39 constexpr uint32_t WAIT_FOR_ACTIVE_SCREEN_ID_TIMEOUT = 1000;
SensorPostureDataCallback(SensorEvent * event)40 void SensorPostureDataCallback(SensorEvent *event)
41 {
42 OHOS::Rosen::CreateOrGetScreenManager()->HandlePostureData(event);
43 }
44 } // namespace
45 #endif
46 using namespace HiviewDFX;
47 namespace impl {
48 std::once_flag RSScreenManager::createFlag_;
49 sptr<OHOS::Rosen::RSScreenManager> RSScreenManager::instance_ = nullptr;
50
GetInstance()51 sptr<OHOS::Rosen::RSScreenManager> RSScreenManager::GetInstance() noexcept
52 {
53 std::call_once(createFlag_, []() {
54 instance_ = new RSScreenManager();
55 });
56
57 return instance_;
58 }
59
RSScreenManager()60 RSScreenManager::RSScreenManager()
61 {
62 }
63
~RSScreenManager()64 RSScreenManager::~RSScreenManager() noexcept
65 {
66 }
67
Init()68 bool RSScreenManager::Init() noexcept
69 {
70 composer_ = HdiBackend::GetInstance();
71 isFoldScreenFlag_ = system::GetParameter("const.window.foldscreen.type", "") != "";
72 if (composer_ == nullptr) {
73 RS_LOGE("RSScreenManager %{public}s: Failed to get composer.", __func__);
74 return false;
75 }
76
77 if (composer_->RegScreenHotplug(&RSScreenManager::OnHotPlug, this) != 0) {
78 RS_LOGE("RSScreenManager %{public}s: Failed to register OnHotPlug Func to composer.", __func__);
79 return false;
80 }
81
82 if (composer_->RegHwcDeadListener(&RSScreenManager::OnHwcDead, this) != 0) {
83 RS_LOGE("RSScreenManager %{public}s: Failed to register OnHwcDead Func to composer.", __func__);
84 return false;
85 }
86
87 // call ProcessScreenHotPlugEvents() for primary screen immediately in main thread.
88 ProcessScreenHotPlugEvents();
89
90 #ifdef RS_SUBSCRIBE_SENSOR_ENABLE
91 if (isFoldScreenFlag_) {
92 RegisterSensorCallback();
93 }
94 #endif
95
96 RS_LOGI("RSScreenManager Init succeed");
97 return true;
98 }
99
100 #ifdef RS_SUBSCRIBE_SENSOR_ENABLE
RegisterSensorCallback()101 void RSScreenManager::RegisterSensorCallback()
102 {
103 user.callback = SensorPostureDataCallback;
104 int32_t subscribeRet;
105 int32_t setBatchRet;
106 int32_t activateRet;
107 int tryCnt = 0;
108 const int tryLimit = 5; // 5 times failure limit
109 do {
110 subscribeRet = SubscribeSensor(SENSOR_TYPE_ID_POSTURE, &user);
111 RS_LOGI("RSScreenManager RegisterSensorCallback, subscribeRet: %{public}d", subscribeRet);
112 setBatchRet = SetBatch(SENSOR_TYPE_ID_POSTURE, &user, POSTURE_INTERVAL, POSTURE_INTERVAL);
113 RS_LOGI("RSScreenManager RegisterSensorCallback, setBatchRet: %{public}d", setBatchRet);
114 activateRet = ActivateSensor(SENSOR_TYPE_ID_POSTURE, &user);
115 RS_LOGI("RSScreenManager RegisterSensorCallback, activateRet: %{public}d", activateRet);
116 if (subscribeRet != SENSOR_SUCCESS || setBatchRet != SENSOR_SUCCESS || activateRet != SENSOR_SUCCESS) {
117 RS_LOGE("RSScreenManager RegisterSensorCallback failed.");
118 usleep(1000); // wait 1000 us for next try
119 tryCnt++;
120 }
121 } while (tryCnt <= tryLimit && (subscribeRet != SENSOR_SUCCESS || setBatchRet != SENSOR_SUCCESS ||
122 activateRet != SENSOR_SUCCESS));
123 if (tryCnt <= tryLimit) {
124 RS_LOGI("RSScreenManager RegisterSensorCallback success.");
125 }
126 }
127
UnRegisterSensorCallback()128 void RSScreenManager::UnRegisterSensorCallback()
129 {
130 int32_t deactivateRet = DeactivateSensor(SENSOR_TYPE_ID_POSTURE, &user);
131 int32_t unsubscribeRet = UnsubscribeSensor(SENSOR_TYPE_ID_POSTURE, &user);
132 if (deactivateRet == SENSOR_SUCCESS && unsubscribeRet == SENSOR_SUCCESS) {
133 RS_LOGI("RSScreenManager UnRegisterSensorCallback success.");
134 }
135 }
136
HandlePostureData(const SensorEvent * const event)137 void RSScreenManager::HandlePostureData(const SensorEvent * const event)
138 {
139 if (event == nullptr) {
140 RS_LOGI("SensorEvent is nullptr.");
141 return;
142 }
143 if (event[SENSOR_EVENT_FIRST_DATA].data == nullptr) {
144 RS_LOGI("SensorEvent[0].data is nullptr.");
145 return;
146 }
147 if (event[SENSOR_EVENT_FIRST_DATA].dataLen < sizeof(PostureData)) {
148 RS_LOGI("SensorEvent dataLen less than posture data size.");
149 return;
150 }
151 PostureData *postureData = reinterpret_cast<PostureData *>(event[SENSOR_EVENT_FIRST_DATA].data);
152 float angle = (*postureData).angle;
153 if (std::isless(angle, ANGLE_MIN_VAL) || std::isgreater(angle, ANGLE_MAX_VAL)) {
154 RS_LOGD("Invalid angle value, angle is %{public}f.", angle);
155 return;
156 }
157 RS_LOGD("angle vlaue in PostureData is: %{public}f.", angle);
158 HandleSensorData(angle);
159 }
160
HandleSensorData(float angle)161 void RSScreenManager::HandleSensorData(float angle)
162 {
163 std::unique_lock<std::mutex> lock(activeScreenIdAssignedMutex_);
164 FoldState foldState = TransferAngleToScreenState(angle);
165 if (foldState == FoldState::FOLDED) {
166 activeScreenId_ = externalScreenId_;
167 } else {
168 activeScreenId_ = innerScreenId_;
169 }
170 isPostureSensorDataHandled_ = true;
171 HgmCore::Instance().SetActiveScreenId(activeScreenId_);
172 activeScreenIdAssignedCV_.notify_one();
173 }
174
TransferAngleToScreenState(float angle)175 FoldState RSScreenManager::TransferAngleToScreenState(float angle)
176 {
177 if (std::isless(angle, ANGLE_MIN_VAL)) {
178 return FoldState::FOLDED;
179 }
180 if (std::isgreaterequal(angle, HALF_FOLDED_MAX_THRESHOLD)) {
181 return FoldState::EXPAND;
182 }
183 FoldState state;
184 if (std::islessequal(angle, OPEN_HALF_FOLDED_MIN_THRESHOLD)) {
185 state = FoldState::FOLDED;
186 } else {
187 state = FoldState::EXPAND;
188 }
189 return state;
190 }
191
GetActiveScreenId()192 ScreenId RSScreenManager::GetActiveScreenId()
193 {
194 std::unique_lock<std::mutex> lock(activeScreenIdAssignedMutex_);
195 if (!isFoldScreenFlag_) {
196 return INVALID_SCREEN_ID;
197 }
198 if (isPostureSensorDataHandled_) {
199 isFirstTimeToGetActiveScreenId_ = false;
200 UnRegisterSensorCallback();
201 RS_LOGI("RSScreenManager activeScreenId: %{public}" PRIu64 " ", activeScreenId_);
202 return activeScreenId_;
203 }
204 activeScreenIdAssignedCV_.wait_until(lock, std::chrono::system_clock::now() +
205 std::chrono::milliseconds(WAIT_FOR_ACTIVE_SCREEN_ID_TIMEOUT), [this]() {
206 return isPostureSensorDataHandled_;
207 });
208 if (isFirstTimeToGetActiveScreenId_) {
209 isFirstTimeToGetActiveScreenId_ = false;
210 UnRegisterSensorCallback();
211 }
212 RS_LOGI("RSScreenManager activeScreenId: %{public}" PRIu64 " ", activeScreenId_);
213 return activeScreenId_;
214 }
215 #endif
216
217 #ifdef USE_VIDEO_PROCESSING_ENGINE
GetScreenBrightnessNits(ScreenId id)218 float RSScreenManager::GetScreenBrightnessNits(ScreenId id)
219 {
220 constexpr float DEFAULT_SCREEN_LIGHT_NITS = 500.0;
221 constexpr float DEFAULT_SCREEN_LIGHT_MAX_NITS = 1200.0;
222 constexpr int32_t DEFAULT_SCREEN_LIGHT_MAX_LEVEL = 255;
223
224 float screenBrightnessNits = DEFAULT_SCREEN_LIGHT_NITS;
225
226 RSScreenType screenType;
227 if (GetScreenType(id, screenType) != SUCCESS) {
228 RS_LOGW("RSScreenManager::GetScreenBrightnessNits GetScreenType fail.");
229 return screenBrightnessNits;
230 }
231
232 if (screenType == VIRTUAL_TYPE_SCREEN) {
233 return screenBrightnessNits;
234 }
235
236 int32_t backLightLevel = GetScreenBacklight(id);
237 if (backLightLevel <= 0) {
238 return screenBrightnessNits;
239 }
240
241 return DEFAULT_SCREEN_LIGHT_MAX_NITS * backLightLevel / DEFAULT_SCREEN_LIGHT_MAX_LEVEL;
242 }
243 #endif
244
OnHotPlug(std::shared_ptr<HdiOutput> & output,bool connected,void * data)245 void RSScreenManager::OnHotPlug(std::shared_ptr<HdiOutput> &output, bool connected, void *data)
246 {
247 if (output == nullptr) {
248 RS_LOGE("RSScreenManager %{public}s: output is nullptr.", __func__);
249 return;
250 }
251
252 RSScreenManager *screenManager = nullptr;
253 if (data != nullptr) {
254 screenManager = static_cast<RSScreenManager *>(data);
255 } else {
256 screenManager = static_cast<RSScreenManager *>(RSScreenManager::GetInstance().GetRefPtr());
257 }
258
259 if (screenManager == nullptr) {
260 RS_LOGE("RSScreenManager %{public}s: Failed to find RSScreenManager instance.", __func__);
261 return;
262 }
263
264 screenManager->OnHotPlugEvent(output, connected);
265 }
266
OnHotPlugEvent(std::shared_ptr<HdiOutput> & output,bool connected)267 void RSScreenManager::OnHotPlugEvent(std::shared_ptr<HdiOutput> &output, bool connected)
268 {
269 {
270 std::lock_guard<std::mutex> lock(mutex_);
271 pendingHotPlugEvents_.emplace_back(ScreenHotPlugEvent{output, connected});
272 }
273
274 // This func would be called in main thread first time immediately after calling composer_->RegScreenHotplug,
275 // but at this time the RSMainThread object would not be ready to handle this, so we need to call
276 // ProcessScreenHotPlugEvents() after this func in RSScreenManager::Init().
277
278 // Normally, this func would be called in hdi's hw-ipc threads(but sometimes in main thread, maybe),
279 // so we should notify the RSMainThread to postTask to call ProcessScreenHotPlugEvents().
280 auto mainThread = RSMainThread::Instance();
281 if (mainThread == nullptr) {
282 return;
283 }
284 mainThread->RequestNextVSync();
285 }
286
OnHwcDead(void * data)287 void RSScreenManager::OnHwcDead(void *data)
288 {
289 RS_LOGW("RSScreenManager %{public}s: The composer_host is already dead.", __func__);
290 RSScreenManager *screenManager = static_cast<RSScreenManager *>(RSScreenManager::GetInstance().GetRefPtr());
291 if (screenManager == nullptr) {
292 RS_LOGE("RSScreenManager %{public}s: Failed to find RSScreenManager instance.", __func__);
293 return;
294 }
295
296 // Automatically recover when composer host dies.
297 screenManager->CleanAndReinit();
298 }
299
OnHwcDeadEvent()300 void RSScreenManager::OnHwcDeadEvent()
301 {
302 std::lock_guard<std::mutex> lock(mutex_);
303 for (const auto &[id, screen] : screens_) {
304 if (screen) {
305 // In sceneboard, we should not notify the WMS to remove node from RSTree
306 if (screen->IsVirtual()) {
307 continue;
308 } else {
309 RSHardwareThread::Instance().ClearFrameBuffers(screen->GetOutput());
310 }
311 }
312 }
313 isHwcDead_ = true;
314 screens_.clear();
315 defaultScreenId_ = INVALID_SCREEN_ID;
316 }
317
CleanAndReinit()318 void RSScreenManager::CleanAndReinit()
319 {
320 RSScreenManager *screenManager = static_cast<RSScreenManager *>(RSScreenManager::GetInstance().GetRefPtr());
321 if (screenManager == nullptr) {
322 RS_LOGE("RSScreenManager %{public}s: Failed to find RSScreenManager instance.", __func__);
323 return;
324 }
325
326 auto renderType = RSUniRenderJudgement::GetUniRenderEnabledType();
327 if (renderType != UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
328 auto mainThread = RSMainThread::Instance();
329 if (mainThread == nullptr) {
330 RS_LOGE("RSScreenManager %{public}s: Reinit failed, get RSMainThread failed.", __func__);
331 return;
332 }
333 mainThread->PostTask([screenManager, this]() {
334 screenManager->OnHwcDeadEvent();
335 composer_->ResetDevice();
336 if (!screenManager->Init()) {
337 RS_LOGE("RSScreenManager %{public}s: Reinit failed, screenManager init failed in mainThread.",
338 __func__);
339 return;
340 }
341 });
342 } else {
343 RSHardwareThread::Instance().PostTask([screenManager, this]() {
344 RS_LOGW("RSScreenManager %{public}s: clean and reinit in hardware thread.", __func__);
345 screenManager->OnHwcDeadEvent();
346 composer_->ResetDevice();
347 if (!screenManager->Init()) {
348 RS_LOGE("RSScreenManager %{public}s: Reinit failed, screenManager init failed in HardwareThread.",
349 __func__);
350 return;
351 }
352 });
353 }
354 }
355
ProcessScreenHotPlugEvents()356 void RSScreenManager::ProcessScreenHotPlugEvents()
357 {
358 std::lock_guard<std::mutex> lock(mutex_);
359 for (auto &event : pendingHotPlugEvents_) {
360 if (event.connected) {
361 ProcessScreenConnectedLocked(event.output);
362 AddScreenToHgm(event.output);
363 } else {
364 ProcessScreenDisConnectedLocked(event.output);
365 RemoveScreenFromHgm(event.output);
366 }
367 }
368 for (auto id : connectedIds_) {
369 for (auto &cb : screenChangeCallbacks_) {
370 if (!isHwcDead_) {
371 cb->OnScreenChanged(id, ScreenEvent::CONNECTED);
372 continue;
373 }
374 if (screens_.count(id) != 0 && screenBacklight_.count(id) != 0 &&
375 (screenPowerStatus_.count(id) == 0 || screenPowerStatus_[id] == ScreenPowerStatus::POWER_STATUS_ON)) {
376 screens_[id]->SetScreenBacklight(screenBacklight_[id]);
377 auto mainThread = RSMainThread::Instance();
378 mainThread->PostTask([mainThread]() {
379 mainThread->SetDirtyFlag();
380 });
381 mainThread->ForceRefreshForUni();
382 }
383 }
384 }
385 isHwcDead_ = false;
386 mipiCheckInFirstHotPlugEvent_ = true;
387 pendingHotPlugEvents_.clear();
388 connectedIds_.clear();
389 }
390
AddScreenToHgm(std::shared_ptr<HdiOutput> & output)391 void RSScreenManager::AddScreenToHgm(std::shared_ptr<HdiOutput> &output)
392 {
393 if (output == nullptr) {
394 RS_LOGE("RSScreenManager %{public}s: output is nullptr.", __func__);
395 return;
396 }
397 RS_LOGI("RSScreenManager AddScreenToHgm");
398 auto &hgmCore = OHOS::Rosen::HgmCore::Instance();
399 ScreenId thisId = ToScreenId(output->GetScreenId());
400 if (screens_.find(thisId) == screens_.end()) {
401 RS_LOGE("RSScreenManager invalid screen id, screen not found : %{public}" PRIu64 "", thisId);
402 return;
403 }
404
405 int32_t initModeId = 0;
406 auto initMode = screens_[thisId]->GetActiveMode();
407 if (!initMode) {
408 RS_LOGE("RSScreenManager failed to get initial mode");
409 } else {
410 initModeId = initMode->id;
411 }
412 const auto &screen = screens_.at(thisId);
413 const auto &capability = screens_.at(thisId)->GetCapability();
414 ScreenSize screenSize = {screen->Width(), screen->Height(), capability.phyWidth, capability.phyHeight};
415 if (hgmCore.AddScreen(thisId, initModeId, screenSize)) {
416 RS_LOGW("RSScreenManager failed to add screen : %{public}" PRIu64 "", thisId);
417 return;
418 }
419 hgmCore.SetActiveScreenId(thisId);
420
421 // for each supported mode, use the index as modeId to add the detailed mode to hgm
422 int32_t modeId = 0;
423 auto supportedModes = screens_[thisId]->GetSupportedModes();
424 for (auto mode = supportedModes.begin(); mode != supportedModes.end(); ++mode) {
425 if (hgmCore.AddScreenInfo(thisId, (*mode).width, (*mode).height,
426 (*mode).freshRate, modeId)) {
427 RS_LOGW("RSScreenManager failed to add a screen profile to the screen : %{public}" PRIu64 "", thisId);
428 }
429 modeId++;
430 }
431 }
432
RemoveScreenFromHgm(std::shared_ptr<HdiOutput> & output)433 void RSScreenManager::RemoveScreenFromHgm(std::shared_ptr<HdiOutput> &output)
434 {
435 if (output == nullptr) {
436 RS_LOGE("RSScreenManager %{public}s: output is nullptr.", __func__);
437 return;
438 }
439
440 RS_LOGI("RSScreenManager RemoveScreenFromHgm");
441 auto &hgmCore = OHOS::Rosen::HgmCore::Instance();
442 ScreenId id = ToScreenId(output->GetScreenId());
443 if (hgmCore.RemoveScreen(id)) {
444 RS_LOGW("RSScreenManager failed to remove screen : %{public}" PRIu64 "", id);
445 }
446 }
447
ProcessScreenConnectedLocked(std::shared_ptr<HdiOutput> & output)448 void RSScreenManager::ProcessScreenConnectedLocked(std::shared_ptr<HdiOutput> &output)
449 {
450 if (output == nullptr) {
451 RS_LOGE("RSScreenManager %{public}s: output is nullptr.", __func__);
452 return;
453 }
454
455 bool isVirtual = false;
456 ScreenId id = ToScreenId(output->GetScreenId());
457 RS_LOGI("RSScreenManager %{public}s The screen for id %{public}" PRIu64 " connected.", __func__, id);
458
459 if (screens_.count(id) == 1) {
460 RS_LOGW("RSScreenManager %{public}s The screen for id %{public}" PRIu64 " already existed.", __func__, id);
461
462 // [PLANNING]: should we erase it and create a new one?
463 for (auto &cb : screenChangeCallbacks_) {
464 cb->OnScreenChanged(id, ScreenEvent::DISCONNECTED);
465 }
466 screens_.erase(id);
467 RS_LOGI("The screen for id %{public}" PRIu64 " already existed, remove the orignal one.", id);
468 }
469
470 screens_[id] = std::make_unique<RSScreen>(id, isVirtual, output, nullptr);
471
472 auto vsyncSampler = CreateVSyncSampler();
473 if (vsyncSampler != nullptr) {
474 auto renderType = RSUniRenderJudgement::GetUniRenderEnabledType();
475 if (renderType != UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
476 vsyncSampler->RegSetScreenVsyncEnabledCallback([this, id](bool enabled) {
477 auto mainThread = RSMainThread::Instance();
478 if (mainThread == nullptr) {
479 RS_LOGE("SetScreenVsyncEnabled:%{public}d failed, get RSMainThread failed", enabled);
480 return;
481 }
482 mainThread->PostTask([this, id, enabled]() {
483 if (screens_[id] == nullptr) {
484 RS_LOGE("SetScreenVsyncEnabled:%{public}d failed, screen %{public}" PRIu64 " not found",
485 enabled, id);
486 return;
487 }
488 screens_[id]->SetScreenVsyncEnabled(enabled);
489 });
490 });
491 } else {
492 vsyncSampler->RegSetScreenVsyncEnabledCallback([this, id](bool enabled) {
493 RSHardwareThread::Instance().PostTask([this, id, enabled]() {
494 if (screens_[id] == nullptr) {
495 RS_LOGE("SetScreenVsyncEnabled:%{public}d failed, screen %{public}" PRIu64 " not found",
496 enabled, id);
497 return;
498 }
499 screens_[id]->SetScreenVsyncEnabled(enabled);
500 });
501 });
502 }
503 } else {
504 RS_LOGE("RegSetScreenVsyncEnabledCallback failed, vsyncSampler is null");
505 }
506
507 if (screens_[id]->GetCapability().type == GraphicInterfaceType::GRAPHIC_DISP_INTF_MIPI) {
508 if (!mipiCheckInFirstHotPlugEvent_) {
509 defaultScreenId_ = id;
510 }
511 mipiCheckInFirstHotPlugEvent_ = true;
512 } else if (defaultScreenId_ == INVALID_SCREEN_ID) {
513 defaultScreenId_ = id;
514 }
515
516 RS_LOGI("RSScreenManager %{public}s: A new screen(id %{public}" PRIu64 ") connected.", __func__, id);
517 connectedIds_.emplace_back(id);
518 if (isFoldScreenFlag_ && id != 0) {
519 externalScreenId_ = id;
520 }
521 }
522
ProcessScreenDisConnectedLocked(std::shared_ptr<HdiOutput> & output)523 void RSScreenManager::ProcessScreenDisConnectedLocked(std::shared_ptr<HdiOutput> &output)
524 {
525 ScreenId id = ToScreenId(output->GetScreenId());
526
527 if (screens_.count(id) == 0) {
528 RS_LOGW("RSScreenManager %{public}s: There is no screen for id %{public}" PRIu64, __func__, id);
529 } else {
530 for (auto &cb : screenChangeCallbacks_) {
531 cb->OnScreenChanged(id, ScreenEvent::DISCONNECTED);
532 }
533 screens_.erase(id);
534 RS_LOGI("RSScreenManager %{public}s: Screen(id %{public}" PRIu64 ") disconnected.", __func__, id);
535 }
536 if (screenPowerStatus_.count(id) != 0) {
537 screenPowerStatus_.erase(id);
538 }
539 if (screenBacklight_.count(id) != 0) {
540 screenBacklight_.erase(id);
541 }
542 if (id == defaultScreenId_) {
543 HandleDefaultScreenDisConnectedLocked();
544 }
545 }
546
547 // If the previous primary screen disconnected, we traversal the left screens
548 // and find the first physical screen to be the default screen.
549 // If there was no physical screen left, we set the first screen as default, no matter what type it is.
550 // At last, if no screen left, we set Default Screen Id to INVALID_SCREEN_ID.
HandleDefaultScreenDisConnectedLocked()551 void RSScreenManager::HandleDefaultScreenDisConnectedLocked()
552 {
553 defaultScreenId_ = INVALID_SCREEN_ID;
554 for (const auto &[id, screen] : screens_) {
555 if (!screen->IsVirtual()) {
556 defaultScreenId_ = id;
557 break;
558 }
559 }
560
561 if (defaultScreenId_ == INVALID_SCREEN_ID) {
562 if (!screens_.empty()) {
563 defaultScreenId_ = screens_.cbegin()->first;
564 }
565 }
566 }
567
SetDefaultScreenId(ScreenId id)568 void RSScreenManager::SetDefaultScreenId(ScreenId id)
569 {
570 std::lock_guard<std::mutex> lock(mutex_);
571 defaultScreenId_ = id;
572 }
573
SetScreenMirror(ScreenId id,ScreenId toMirror)574 void RSScreenManager::SetScreenMirror(ScreenId id, ScreenId toMirror)
575 {
576 std::lock_guard<std::mutex> lock(mutex_);
577
578 if (screens_.count(id) == 0) {
579 RS_LOGW("RSScreenManager %{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
580 return;
581 }
582
583 screens_[id]->SetMirror(toMirror);
584 }
585
GenerateVirtualScreenIdLocked()586 ScreenId RSScreenManager::GenerateVirtualScreenIdLocked()
587 {
588 if (!freeVirtualScreenIds_.empty()) {
589 ScreenId id = freeVirtualScreenIds_.front();
590 freeVirtualScreenIds_.pop();
591 return id;
592 }
593
594 // The left 32 bits is for virtual screen id.
595 return (static_cast<ScreenId>(maxVirtualScreenNum_++) << 32) | 0xffffffffu;
596 }
597
ReuseVirtualScreenIdLocked(ScreenId id)598 void RSScreenManager::ReuseVirtualScreenIdLocked(ScreenId id)
599 {
600 freeVirtualScreenIds_.push(id);
601 }
602
GetVirtualScreenResolutionLocked(ScreenId id,RSVirtualScreenResolution & virtualScreenResolution) const603 void RSScreenManager::GetVirtualScreenResolutionLocked(ScreenId id,
604 RSVirtualScreenResolution& virtualScreenResolution) const
605 {
606 if (screens_.count(id) == 0) {
607 RS_LOGW("RSScreenManager %{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
608 return;
609 }
610
611 virtualScreenResolution.SetVirtualScreenWidth(static_cast<uint32_t>(screens_.at(id)->Width()));
612 virtualScreenResolution.SetVirtualScreenHeight(static_cast<uint32_t>(screens_.at(id)->Height()));
613 }
614
GetScreenActiveModeLocked(ScreenId id,RSScreenModeInfo & screenModeInfo) const615 void RSScreenManager::GetScreenActiveModeLocked(ScreenId id, RSScreenModeInfo& screenModeInfo) const
616 {
617 if (screens_.count(id) == 0) {
618 RS_LOGW("RSScreenManager %{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
619 return;
620 }
621
622 auto modeInfo = screens_.at(id)->GetActiveMode();
623 if (!modeInfo) {
624 RS_LOGE("RSScreenManager %{public}s: Failed to get active mode for screen %{public}" PRIu64 ".", __func__, id);
625 return;
626 }
627
628 screenModeInfo.SetScreenWidth(modeInfo->width);
629 screenModeInfo.SetScreenHeight(modeInfo->height);
630 screenModeInfo.SetScreenRefreshRate(modeInfo->freshRate);
631 screenModeInfo.SetScreenModeId(screens_.at(id)->GetActiveModePosByModeId(modeInfo->id));
632 }
633
GetScreenSupportedModesLocked(ScreenId id) const634 std::vector<RSScreenModeInfo> RSScreenManager::GetScreenSupportedModesLocked(ScreenId id) const
635 {
636 std::vector<RSScreenModeInfo> screenSupportedModes;
637 if (screens_.count(id) == 0) {
638 RS_LOGW("RSScreenManager %{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
639 return screenSupportedModes;
640 }
641
642 const auto& displaySupportedModes = screens_.at(id)->GetSupportedModes();
643 screenSupportedModes.resize(displaySupportedModes.size());
644 for (decltype(displaySupportedModes.size()) idx = 0; idx < displaySupportedModes.size(); ++idx) {
645 screenSupportedModes[idx].SetScreenWidth(displaySupportedModes[idx].width);
646 screenSupportedModes[idx].SetScreenHeight(displaySupportedModes[idx].height);
647 screenSupportedModes[idx].SetScreenRefreshRate(displaySupportedModes[idx].freshRate);
648 screenSupportedModes[idx].SetScreenModeId(displaySupportedModes[idx].id);
649 }
650 return screenSupportedModes;
651 }
652
GetScreenCapabilityLocked(ScreenId id) const653 RSScreenCapability RSScreenManager::GetScreenCapabilityLocked(ScreenId id) const
654 {
655 RSScreenCapability screenCapability;
656 if (screens_.count(id) == 0) {
657 RS_LOGW("RSScreenManager %{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
658 return screenCapability;
659 }
660 if (screens_.at(id)->IsVirtual()) {
661 RS_LOGW("RSScreenManager %{public}s: only name attribute is valid for virtual screen.", __func__);
662 screenCapability.SetName(screens_.at(id)->Name());
663 return screenCapability;
664 }
665
666 const auto& capability = screens_.at(id)->GetCapability();
667 std::vector<RSScreenProps> props;
668 uint32_t propCount = capability.propertyCount;
669 props.resize(propCount);
670 for (uint32_t propIndex = 0; propIndex < propCount; propIndex++) {
671 props[propIndex] = RSScreenProps(capability.props[propIndex].name, capability.props[propIndex].propId,
672 capability.props[propIndex].value);
673 }
674 screenCapability.SetName(capability.name);
675 screenCapability.SetType(static_cast<ScreenInterfaceType>(capability.type));
676 screenCapability.SetPhyWidth(capability.phyWidth);
677 screenCapability.SetPhyHeight(capability.phyHeight);
678 screenCapability.SetSupportLayers(capability.supportLayers);
679 screenCapability.SetVirtualDispCount(capability.virtualDispCount);
680 screenCapability.SetSupportWriteBack(capability.supportWriteBack);
681 screenCapability.SetProps(props);
682 return screenCapability;
683 }
684
GetScreenPowerStatusLocked(ScreenId id) const685 ScreenPowerStatus RSScreenManager::GetScreenPowerStatusLocked(ScreenId id) const
686 {
687 if (screens_.count(id) == 0) {
688 RS_LOGW("RSScreenManager %{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
689 return INVALID_POWER_STATUS;
690 }
691
692 ScreenPowerStatus status = static_cast<ScreenPowerStatus>(screens_.at(id)->GetPowerStatus());
693 return status;
694 }
695
GetScreenCorrectionLocked(ScreenId id) const696 ScreenRotation RSScreenManager::GetScreenCorrectionLocked(ScreenId id) const
697 {
698 if (screens_.count(id) == 0) {
699 RS_LOGW("RSScreenManager %{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
700 return ScreenRotation::INVALID_SCREEN_ROTATION;
701 }
702
703 ScreenRotation screenRotation = screens_.at(id)->GetScreenCorrection();
704 return screenRotation;
705 }
706
GetAllScreenIds()707 std::vector<ScreenId> RSScreenManager::GetAllScreenIds()
708 {
709 std::lock_guard<std::mutex> lock(mutex_);
710 std::vector<ScreenId> ids;
711 for (auto iter = screens_.begin(); iter != screens_.end(); ++iter) {
712 ids.emplace_back(iter->first);
713 }
714 return ids;
715 }
716
CreateVirtualScreen(const std::string & name,uint32_t width,uint32_t height,sptr<Surface> surface,ScreenId mirrorId,int32_t flags,std::vector<NodeId> filteredAppVector)717 ScreenId RSScreenManager::CreateVirtualScreen(
718 const std::string &name,
719 uint32_t width,
720 uint32_t height,
721 sptr<Surface> surface,
722 ScreenId mirrorId,
723 int32_t flags,
724 std::vector<NodeId> filteredAppVector)
725 {
726 std::lock_guard<std::mutex> lock(mutex_);
727
728 if (surface != nullptr) {
729 uint64_t surfaceId = surface->GetUniqueId();
730 for (auto &[_, screen] : screens_) {
731 if (!screen->IsVirtual()) {
732 continue;
733 }
734 auto screenSurface = screen->GetProducerSurface();
735 if (screenSurface == nullptr) {
736 continue;
737 }
738 if (screenSurface->GetUniqueId() == surfaceId) {
739 RS_LOGW("RSScreenManager %{public}s: surface %{public}" PRIu64 " is used, create virtual"
740 " screen failed!", __func__, surfaceId);
741 return INVALID_SCREEN_ID;
742 }
743 }
744 } else {
745 RS_LOGD("RSScreenManager %{public}s: surface is nullptr.", __func__);
746 }
747
748 std::unordered_set<NodeId> filteredAppSet(filteredAppVector.begin(), filteredAppVector.end());
749 VirtualScreenConfigs configs;
750 ScreenId newId = GenerateVirtualScreenIdLocked();
751 configs.id = newId;
752 configs.mirrorId = mirrorId;
753 configs.name = name;
754 configs.width = width;
755 configs.height = height;
756 configs.surface = surface;
757 configs.flags = flags;
758 configs.filteredAppSet= filteredAppSet;
759
760 screens_[newId] = std::make_unique<RSScreen>(configs);
761 RS_LOGD("RSScreenManager %{public}s: create virtual screen(id %{public}" PRIu64 ").", __func__, newId);
762 return newId;
763 }
764
SetVirtualScreenSurface(ScreenId id,sptr<Surface> surface)765 int32_t RSScreenManager::SetVirtualScreenSurface(ScreenId id, sptr<Surface> surface)
766 {
767 std::lock_guard<std::mutex> lock(mutex_);
768 if (screens_.find(id) == screens_.end()) {
769 return SCREEN_NOT_FOUND;
770 }
771 uint64_t surfaceId = surface->GetUniqueId();
772 for (auto &[screenId, screen] : screens_) {
773 if (!screen->IsVirtual() || screenId == id) {
774 continue;
775 }
776 auto screenSurface = screen->GetProducerSurface();
777 if (screenSurface == nullptr) {
778 continue;
779 }
780 if (screenSurface->GetUniqueId() == surface->GetUniqueId()) {
781 RS_LOGE("RSScreenManager %{public}s: surface %{public}" PRIu64 " is used, set surface failed!",
782 __func__, surfaceId);
783 return SURFACE_NOT_UNIQUE;
784 }
785 }
786 screens_.at(id)->SetProducerSurface(surface);
787 RS_LOGD("RSScreenManager %{public}s: set virtual screen surface success!", __func__);
788 // if SetVirtualScreenSurface success, force a refresh of one frame, avoiding prolong black screen
789 auto mainThread = RSMainThread::Instance();
790 if (mainThread != nullptr) {
791 mainThread->PostTask([mainThread]() {
792 mainThread->SetDirtyFlag();
793 });
794 mainThread->ForceRefreshForUni();
795 }
796 return SUCCESS;
797 }
798
RemoveVirtualScreen(ScreenId id)799 void RSScreenManager::RemoveVirtualScreen(ScreenId id)
800 {
801 std::lock_guard<std::mutex> lock(mutex_);
802
803 RemoveVirtualScreenLocked(id);
804 }
805
RemoveVirtualScreenLocked(ScreenId id)806 void RSScreenManager::RemoveVirtualScreenLocked(ScreenId id)
807 {
808 if (screens_.count(id) == 0) {
809 RS_LOGW("RSScreenManager %{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
810 return;
811 }
812
813 screens_.erase(id);
814
815 // Update other screens' mirrorId.
816 for (auto &[id, screen] : screens_) {
817 if (screen->MirrorId() == id) {
818 screen->SetMirror(INVALID_SCREEN_ID);
819 }
820 }
821 RS_LOGD("RSScreenManager %{public}s: remove virtual screen(id %{public}" PRIu64 ").", __func__, id);
822
823 ReuseVirtualScreenIdLocked(id);
824 }
825
SetScreenActiveMode(ScreenId id,uint32_t modeId)826 void RSScreenManager::SetScreenActiveMode(ScreenId id, uint32_t modeId)
827 {
828 std::lock_guard<std::mutex> lock(mutex_);
829
830 if (screens_.count(id) == 0) {
831 RS_LOGW("RSScreenManager %{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
832 return;
833 }
834 screens_.at(id)->SetActiveMode(modeId);
835 }
836
SetVirtualScreenResolution(ScreenId id,uint32_t width,uint32_t height)837 int32_t RSScreenManager::SetVirtualScreenResolution(ScreenId id, uint32_t width, uint32_t height)
838 {
839 std::lock_guard<std::mutex> lock(mutex_);
840
841 if (screens_.count(id) == 0) {
842 RS_LOGW("RSScreenManager %{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
843 return SCREEN_NOT_FOUND;
844 }
845 screens_.at(id)->SetResolution(width, height);
846 RS_LOGD("RSScreenManager %{public}s: set virtual screen resolution success", __func__);
847 return SUCCESS;
848 }
849
SetRogScreenResolution(ScreenId id,uint32_t width,uint32_t height)850 int32_t RSScreenManager::SetRogScreenResolution(ScreenId id, uint32_t width, uint32_t height)
851 {
852 std::lock_guard<std::mutex> lock(mutex_);
853
854 if (screens_.count(id) == 0 || !screens_.at(id)) {
855 RS_LOGW("RSScreenManager %{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
856 return SCREEN_NOT_FOUND;
857 }
858 screens_.at(id)->SetRogResolution(width, height);
859 return SUCCESS;
860 }
861
SetScreenPowerStatus(ScreenId id,ScreenPowerStatus status)862 void RSScreenManager::SetScreenPowerStatus(ScreenId id, ScreenPowerStatus status)
863 {
864 std::lock_guard<std::mutex> lock(mutex_);
865
866 if (screens_.count(id) == 0) {
867 RS_LOGW("RSScreenManager %{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
868 return;
869 }
870 screens_.at(id)->SetPowerStatus(static_cast<uint32_t>(status));
871
872 /*
873 * If app adds the first frame when power on the screen, delete the code
874 */
875 if (status == ScreenPowerStatus::POWER_STATUS_ON) {
876 auto mainThread = RSMainThread::Instance();
877 if (mainThread == nullptr) {
878 return;
879 }
880 mainThread->PostTask([mainThread]() {
881 mainThread->SetDirtyFlag();
882 });
883 if (screenPowerStatus_.count(id) == 0 ||
884 screenPowerStatus_[id] == ScreenPowerStatus::POWER_STATUS_OFF ||
885 screenPowerStatus_[id] == ScreenPowerStatus::POWER_STATUS_OFF_FAKE) {
886 mainThread->ForceRefreshForUni();
887 } else {
888 mainThread->RequestNextVSync();
889 }
890
891 RS_LOGD("RSScreenManager %{public}s: Set system power on, request a frame", __func__);
892 }
893 screenPowerStatus_[id] = status;
894 }
895
SetVirtualMirrorScreenCanvasRotation(ScreenId id,bool canvasRotation)896 bool RSScreenManager::SetVirtualMirrorScreenCanvasRotation(ScreenId id, bool canvasRotation)
897 {
898 std::lock_guard<std::mutex> lock(mutex_);
899
900 if (screens_.count(id) == 0) {
901 RS_LOGW("RSScreenManager %{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
902 return false;
903 }
904
905 RS_LOGD("RSScreenManager %{public}s: canvasRotation: %{public}d", __func__, canvasRotation);
906
907 return screens_.at(id)->SetVirtualMirrorScreenCanvasRotation(canvasRotation);
908 }
909
GetVirtualScreenResolution(ScreenId id,RSVirtualScreenResolution & virtualScreenResolution) const910 void RSScreenManager::GetVirtualScreenResolution(ScreenId id, RSVirtualScreenResolution& virtualScreenResolution) const
911 {
912 std::lock_guard<std::mutex> lock(mutex_);
913
914 GetVirtualScreenResolutionLocked(id, virtualScreenResolution);
915 }
916
GetScreenActiveMode(ScreenId id,RSScreenModeInfo & screenModeInfo) const917 void RSScreenManager::GetScreenActiveMode(ScreenId id, RSScreenModeInfo& screenModeInfo) const
918 {
919 std::lock_guard<std::mutex> lock(mutex_);
920
921 GetScreenActiveModeLocked(id, screenModeInfo);
922 }
923
GetScreenSupportedModes(ScreenId id) const924 std::vector<RSScreenModeInfo> RSScreenManager::GetScreenSupportedModes(ScreenId id) const
925 {
926 std::lock_guard<std::mutex> lock(mutex_);
927
928 return GetScreenSupportedModesLocked(id);
929 }
930
GetScreenCapability(ScreenId id) const931 RSScreenCapability RSScreenManager::GetScreenCapability(ScreenId id) const
932 {
933 std::lock_guard<std::mutex> lock(mutex_);
934
935 return GetScreenCapabilityLocked(id);
936 }
937
GetScreenPowerStatus(ScreenId id) const938 ScreenPowerStatus RSScreenManager::GetScreenPowerStatus(ScreenId id) const
939 {
940 std::lock_guard<std::mutex> lock(mutex_);
941
942 return GetScreenPowerStatusLocked(id);
943 }
944
GetScreenCorrection(ScreenId id) const945 ScreenRotation RSScreenManager::GetScreenCorrection(ScreenId id) const
946 {
947 std::lock_guard<std::mutex> lock(mutex_);
948
949 return GetScreenCorrectionLocked(id);
950 }
951
GetScreenData(ScreenId id) const952 RSScreenData RSScreenManager::GetScreenData(ScreenId id) const
953 {
954 std::lock_guard<std::mutex> lock(mutex_);
955 RSScreenData screenData;
956 if (screens_.count(id) == 0) {
957 RS_LOGW("RSScreenManager %{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
958 return screenData;
959 }
960 RSScreenCapability capability = GetScreenCapabilityLocked(id);
961 RSScreenModeInfo activeMode;
962 GetScreenActiveModeLocked(id, activeMode);
963 std::vector<RSScreenModeInfo> supportModes = GetScreenSupportedModesLocked(id);
964 ScreenPowerStatus powerStatus = GetScreenPowerStatusLocked(id);
965 screenData.SetCapability(capability);
966 screenData.SetActivityModeInfo(activeMode);
967 screenData.SetSupportModeInfo(supportModes);
968 screenData.SetPowerStatus(powerStatus);
969 return screenData;
970 }
971
ResizeVirtualScreen(ScreenId id,uint32_t width,uint32_t height)972 int32_t RSScreenManager::ResizeVirtualScreen(ScreenId id, uint32_t width, uint32_t height)
973 {
974 std::lock_guard<std::mutex> lock(mutex_);
975 if (screens_.count(id) == 0) {
976 RS_LOGW("RSScreenManager %{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
977 return SCREEN_NOT_FOUND;
978 }
979 screens_.at(id)->ResizeVirtualScreen(width, height);
980 RS_LOGD("RSScreenManager %{public}s: resize virtual screen success", __func__);
981
982 return SUCCESS;
983 }
984
GetScreenBacklight(ScreenId id)985 int32_t RSScreenManager::GetScreenBacklight(ScreenId id)
986 {
987 std::lock_guard<std::mutex> lock(mutex_);
988 return GetScreenBacklightLocked(id);
989 }
990
GetScreenBacklightLocked(ScreenId id) const991 int32_t RSScreenManager::GetScreenBacklightLocked(ScreenId id) const
992 {
993 if (screens_.count(id) == 0 || !screens_.at(id)) {
994 RS_LOGW("RSScreenManager %{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
995 return INVALID_BACKLIGHT_VALUE;
996 }
997
998 int32_t level = screens_.at(id)->GetScreenBacklight();
999 return level;
1000 }
1001
SetScreenBacklight(ScreenId id,uint32_t level)1002 void RSScreenManager::SetScreenBacklight(ScreenId id, uint32_t level)
1003 {
1004 std::lock_guard<std::mutex> lock(mutex_);
1005 if (screens_.count(id) == 0) {
1006 RS_LOGW("RSScreenManager %{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
1007 return;
1008 }
1009 screenBacklight_[id] = level;
1010 screens_.at(id)->SetScreenBacklight(level);
1011 }
1012
QueryScreenInfo(ScreenId id) const1013 ScreenInfo RSScreenManager::QueryScreenInfo(ScreenId id) const
1014 {
1015 std::lock_guard<std::mutex> lock(mutex_);
1016
1017 ScreenInfo info;
1018 if (screens_.count(id) == 0) {
1019 RS_LOGW("RSScreenManager %{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
1020 return info;
1021 }
1022
1023 const auto &screen = screens_.at(id);
1024 if (!screen) {
1025 RS_LOGE("RSScreenManager::QueryScreenInfo screen %{public}" PRIu64 " has no info.", id);
1026 return info;
1027 }
1028 info.id = id;
1029 info.width = screen->Width();
1030 info.height = screen->Height();
1031 info.phyWidth = screen->PhyWidth();
1032 info.phyHeight = screen->PhyHeight();
1033 auto ret = screen->GetScreenColorGamut(info.colorGamut);
1034 if (ret != StatusCode::SUCCESS) {
1035 info.colorGamut = COLOR_GAMUT_SRGB;
1036 }
1037
1038 if (!screen->IsEnable()) {
1039 info.state = ScreenState::DISABLED;
1040 } else if (!screen->IsVirtual()) {
1041 info.state = ScreenState::HDI_OUTPUT_ENABLE;
1042 } else {
1043 info.state = ScreenState::PRODUCER_SURFACE_ENABLE;
1044 }
1045 info.skipFrameInterval = screen->GetScreenSkipFrameInterval();
1046 screen->GetPixelFormat(info.pixelFormat);
1047 screen->GetScreenHDRFormat(info.hdrFormat);
1048 info.filteredAppSet = screen->GetFilteredAppSet();
1049 return info;
1050 }
1051
GetCanvasRotation(ScreenId id) const1052 bool RSScreenManager::GetCanvasRotation(ScreenId id) const
1053 {
1054 std::lock_guard<std::mutex> lock(mutex_);
1055
1056 if (screens_.count(id) == 0 || !screens_.at(id)) {
1057 RS_LOGW("RSScreenManager::GetCanvasRotation: There is no screen for id %{public}" PRIu64 ".", id);
1058 return false;
1059 }
1060 return screens_.at(id)->GetCanvasRotation();
1061 }
1062
GetProducerSurface(ScreenId id) const1063 sptr<Surface> RSScreenManager::GetProducerSurface(ScreenId id) const
1064 {
1065 std::lock_guard<std::mutex> lock(mutex_);
1066
1067 // assert screens_.count(id) == 1
1068 if (screens_.count(id) == 0) {
1069 RS_LOGW("RSScreenManager::GetProducerSurface: There is no screen for id %{public}" PRIu64 ".", id);
1070 return nullptr;
1071 }
1072 return screens_.at(id)->GetProducerSurface();
1073 }
1074
GetOutput(ScreenId id) const1075 std::shared_ptr<HdiOutput> RSScreenManager::GetOutput(ScreenId id) const
1076 {
1077 std::lock_guard<std::mutex> lock(mutex_);
1078
1079 // assert screens_.count(id) == 1
1080 if (screens_.count(id) == 0) {
1081 RS_LOGW("RSScreenManager::GetOutput: There is no screen for id %{public}" PRIu64 ".", id);
1082 return nullptr;
1083 }
1084 return screens_.at(id)->GetOutput();
1085 }
1086
AddScreenChangeCallback(const sptr<RSIScreenChangeCallback> & callback)1087 int32_t RSScreenManager::AddScreenChangeCallback(const sptr<RSIScreenChangeCallback> &callback)
1088 {
1089 if (callback == nullptr) {
1090 RS_LOGE("RSScreenManager %{public}s: callback is NULL.", __func__);
1091 return INVALID_ARGUMENTS;
1092 }
1093
1094 std::lock_guard<std::mutex> lock(mutex_);
1095 // when the callback first registered, maybe there were some physical screens already connected,
1096 // so notify to remote immediately.
1097 for (const auto &[id, screen] : screens_) {
1098 if (!screen->IsVirtual()) {
1099 callback->OnScreenChanged(id, ScreenEvent::CONNECTED);
1100 }
1101 }
1102 screenChangeCallbacks_.push_back(callback);
1103 RS_LOGD("RSScreenManager %{public}s: add a remote callback succeed.", __func__);
1104 return SUCCESS;
1105 }
1106
RemoveScreenChangeCallback(const sptr<RSIScreenChangeCallback> & callback)1107 void RSScreenManager::RemoveScreenChangeCallback(const sptr<RSIScreenChangeCallback> &callback)
1108 {
1109 std::lock_guard<std::mutex> lock(mutex_);
1110 for (auto it = screenChangeCallbacks_.begin(); it != screenChangeCallbacks_.end(); it++) {
1111 if (*it == callback) {
1112 screenChangeCallbacks_.erase(it);
1113 RS_LOGD("RSScreenManager %{public}s: remove a remote callback succeed.", __func__);
1114 break;
1115 }
1116 }
1117 }
1118
DisplayDump(std::string & dumpString)1119 void RSScreenManager::DisplayDump(std::string& dumpString)
1120 {
1121 int32_t index = 0;
1122 for (const auto &[id, screen] : screens_) {
1123 screen->DisplayDump(index, dumpString);
1124 index++;
1125 }
1126 }
1127
SurfaceDump(std::string & dumpString)1128 void RSScreenManager::SurfaceDump(std::string& dumpString)
1129 {
1130 int32_t index = 0;
1131 for (const auto &[id, screen] : screens_) {
1132 screen->SurfaceDump(index, dumpString);
1133 index++;
1134 }
1135 }
1136
FpsDump(std::string & dumpString,std::string & arg)1137 void RSScreenManager::FpsDump(std::string& dumpString, std::string& arg)
1138 {
1139 int32_t index = 0;
1140 dumpString += "\n-- The recently fps records info of screens:\n";
1141 for (const auto &[id, screen] : screens_) {
1142 screen->FpsDump(index, dumpString, arg);
1143 index++;
1144 }
1145 }
1146
ClearFpsDump(std::string & dumpString,std::string & arg)1147 void RSScreenManager::ClearFpsDump(std::string& dumpString, std::string& arg)
1148 {
1149 int32_t index = 0;
1150 dumpString += "\n-- Clear fps records info of screens:\n";
1151 for (const auto &[id, screen] : screens_) {
1152 screen->ClearFpsDump(index, dumpString, arg);
1153 index++;
1154 }
1155 }
1156
GetScreenSupportedColorGamutsLocked(ScreenId id,std::vector<ScreenColorGamut> & mode) const1157 int32_t RSScreenManager::GetScreenSupportedColorGamutsLocked(ScreenId id, std::vector<ScreenColorGamut>& mode) const
1158 {
1159 if (screens_.count(id) == 0) {
1160 RS_LOGW("RSScreenManager %{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
1161 return StatusCode::SCREEN_NOT_FOUND;
1162 }
1163 return screens_.at(id)->GetScreenSupportedColorGamuts(mode);
1164 }
1165
GetScreenSupportedMetaDataKeysLocked(ScreenId id,std::vector<ScreenHDRMetadataKey> & keys) const1166 int32_t RSScreenManager::GetScreenSupportedMetaDataKeysLocked(
1167 ScreenId id, std::vector<ScreenHDRMetadataKey>& keys) const
1168 {
1169 if (screens_.count(id) == 0) {
1170 RS_LOGW("RSScreenManager %{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
1171 return StatusCode::SCREEN_NOT_FOUND;
1172 }
1173 return screens_.at(id)->GetScreenSupportedMetaDataKeys(keys);
1174 }
1175
GetScreenColorGamutLocked(ScreenId id,ScreenColorGamut & mode) const1176 int32_t RSScreenManager::GetScreenColorGamutLocked(ScreenId id, ScreenColorGamut& mode) const
1177 {
1178 if (screens_.count(id) == 0 || !screens_.at(id)) {
1179 RS_LOGW("RSScreenManager %{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
1180 return StatusCode::SCREEN_NOT_FOUND;
1181 }
1182 return screens_.at(id)->GetScreenColorGamut(mode);
1183 }
1184
SetScreenColorGamutLocked(ScreenId id,int32_t modeIdx)1185 int32_t RSScreenManager::SetScreenColorGamutLocked(ScreenId id, int32_t modeIdx)
1186 {
1187 if (screens_.count(id) == 0) {
1188 RS_LOGW("RSScreenManager %{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
1189 return StatusCode::SCREEN_NOT_FOUND;
1190 }
1191 return screens_.at(id)->SetScreenColorGamut(modeIdx);
1192 }
1193
SetScreenGamutMapLocked(ScreenId id,ScreenGamutMap mode)1194 int32_t RSScreenManager::SetScreenGamutMapLocked(ScreenId id, ScreenGamutMap mode)
1195 {
1196 if (screens_.count(id) == 0) {
1197 RS_LOGW("RSScreenManager %{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
1198 return StatusCode::SCREEN_NOT_FOUND;
1199 }
1200 return screens_.at(id)->SetScreenGamutMap(mode);
1201 }
1202
SetScreenCorrectionLocked(ScreenId id,ScreenRotation screenRotation)1203 int32_t RSScreenManager::SetScreenCorrectionLocked(ScreenId id, ScreenRotation screenRotation)
1204 {
1205 if (screens_.count(id) == 0) {
1206 RS_LOGW("RSScreenManager %{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
1207 return StatusCode::SCREEN_NOT_FOUND;
1208 }
1209 screens_.at(id)->SetScreenCorrection(screenRotation);
1210 return StatusCode::SUCCESS;
1211 }
1212
GetScreenGamutMapLocked(ScreenId id,ScreenGamutMap & mode) const1213 int32_t RSScreenManager::GetScreenGamutMapLocked(ScreenId id, ScreenGamutMap &mode) const
1214 {
1215 if (screens_.count(id) == 0) {
1216 RS_LOGW("RSScreenManager %{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
1217 return StatusCode::SCREEN_NOT_FOUND;
1218 }
1219 return screens_.at(id)->GetScreenGamutMap(mode);
1220 }
1221
GetScreenHDRCapabilityLocked(ScreenId id,RSScreenHDRCapability & screenHdrCapability) const1222 int32_t RSScreenManager::GetScreenHDRCapabilityLocked(ScreenId id, RSScreenHDRCapability& screenHdrCapability) const
1223 {
1224 if (screens_.count(id) == 0) {
1225 RS_LOGW("RSScreenManager %{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
1226 return StatusCode::SCREEN_NOT_FOUND;
1227 }
1228 GraphicHDRCapability hdrCapability = screens_.at(id)->GetHDRCapability();
1229 std::vector<ScreenHDRFormat> hdrFormats;
1230 uint32_t formatCount = hdrCapability.formatCount;
1231 hdrFormats.resize(formatCount);
1232 for (uint32_t index = 0; index < formatCount; index++) {
1233 hdrFormats[index] = static_cast<ScreenHDRFormat>(hdrCapability.formats[index]);
1234 }
1235 screenHdrCapability.SetMaxLum(hdrCapability.maxLum);
1236 screenHdrCapability.SetMaxAverageLum(hdrCapability.maxAverageLum);
1237 screenHdrCapability.SetMinLum(hdrCapability.minLum);
1238 screenHdrCapability.SetHdrFormats(hdrFormats);
1239 return StatusCode::SUCCESS;
1240 }
1241
GetScreenTypeLocked(ScreenId id,RSScreenType & type) const1242 int32_t RSScreenManager::GetScreenTypeLocked(ScreenId id, RSScreenType& type) const
1243 {
1244 if (screens_.count(id) == 0 || !screens_.at(id)) {
1245 RS_LOGW("RSScreenManager %{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
1246 return StatusCode::SCREEN_NOT_FOUND;
1247 }
1248
1249 type = screens_.at(id)->GetScreenType();
1250 return StatusCode::SUCCESS;
1251 }
1252
SetScreenSkipFrameIntervalLocked(ScreenId id,uint32_t skipFrameInterval)1253 int32_t RSScreenManager::SetScreenSkipFrameIntervalLocked(ScreenId id, uint32_t skipFrameInterval)
1254 {
1255 if (screens_.count(id) == 0) {
1256 RS_LOGW("RSScreenManager %{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
1257 return StatusCode::SCREEN_NOT_FOUND;
1258 }
1259 RSScreenModeInfo screenModeInfo;
1260 // use the refresh rate of the physical screen as the maximum refresh rate
1261 GetScreenActiveModeLocked(defaultScreenId_, screenModeInfo);
1262 // guaranteed screen refresh rate at least 1
1263 if (skipFrameInterval == 0 || (skipFrameInterval > screenModeInfo.GetScreenRefreshRate())) {
1264 return INVALID_ARGUMENTS;
1265 }
1266 screens_.at(id)->SetScreenSkipFrameInterval(skipFrameInterval);
1267 RS_LOGD("RSScreenManager %{public}s: screen(id %" PRIu64 "), skipFrameInterval(%d).",
1268 __func__, id, skipFrameInterval);
1269 return StatusCode::SUCCESS;
1270 }
1271
GetPixelFormatLocked(ScreenId id,GraphicPixelFormat & pixelFormat) const1272 int32_t RSScreenManager::GetPixelFormatLocked(ScreenId id, GraphicPixelFormat& pixelFormat) const
1273 {
1274 if (screens_.count(id) == 0 || !screens_.at(id)) {
1275 RS_LOGW("RSScreenManager %{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
1276 return StatusCode::SCREEN_NOT_FOUND;
1277 }
1278 return screens_.at(id)->GetPixelFormat(pixelFormat);
1279 }
1280
SetPixelFormatLocked(ScreenId id,GraphicPixelFormat pixelFormat)1281 int32_t RSScreenManager::SetPixelFormatLocked(ScreenId id, GraphicPixelFormat pixelFormat)
1282 {
1283 if (screens_.count(id) == 0) {
1284 RS_LOGW("RSScreenManager %{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
1285 return StatusCode::SCREEN_NOT_FOUND;
1286 }
1287 return screens_.at(id)->SetPixelFormat(pixelFormat);
1288 }
1289
GetScreenSupportedHDRFormatsLocked(ScreenId id,std::vector<ScreenHDRFormat> & hdrFormats) const1290 int32_t RSScreenManager::GetScreenSupportedHDRFormatsLocked(ScreenId id, std::vector<ScreenHDRFormat>& hdrFormats) const
1291 {
1292 if (screens_.count(id) == 0) {
1293 RS_LOGW("RSScreenManager %{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
1294 return StatusCode::SCREEN_NOT_FOUND;
1295 }
1296 return screens_.at(id)->GetScreenSupportedHDRFormats(hdrFormats);
1297 }
1298
GetScreenHDRFormatLocked(ScreenId id,ScreenHDRFormat & hdrFormat) const1299 int32_t RSScreenManager::GetScreenHDRFormatLocked(ScreenId id, ScreenHDRFormat& hdrFormat) const
1300 {
1301 if (screens_.count(id) == 0) {
1302 RS_LOGW("RSScreenManager %{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
1303 return StatusCode::SCREEN_NOT_FOUND;
1304 }
1305 return screens_.at(id)->GetScreenHDRFormat(hdrFormat);
1306 }
1307
SetScreenHDRFormatLocked(ScreenId id,int32_t modeIdx)1308 int32_t RSScreenManager::SetScreenHDRFormatLocked(ScreenId id, int32_t modeIdx)
1309 {
1310 if (screens_.count(id) == 0) {
1311 RS_LOGW("RSScreenManager %{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
1312 return StatusCode::SCREEN_NOT_FOUND;
1313 }
1314 return screens_.at(id)->SetScreenHDRFormat(modeIdx);
1315 }
1316
GetScreenSupportedColorSpacesLocked(ScreenId id,std::vector<GraphicCM_ColorSpaceType> & colorSpaces) const1317 int32_t RSScreenManager::GetScreenSupportedColorSpacesLocked(
1318 ScreenId id, std::vector<GraphicCM_ColorSpaceType>& colorSpaces) const
1319 {
1320 if (screens_.count(id) == 0) {
1321 RS_LOGW("RSScreenManager %{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
1322 return StatusCode::SCREEN_NOT_FOUND;
1323 }
1324 return screens_.at(id)->GetScreenSupportedColorSpaces(colorSpaces);
1325 }
1326
GetScreenColorSpaceLocked(ScreenId id,GraphicCM_ColorSpaceType & colorSpace) const1327 int32_t RSScreenManager::GetScreenColorSpaceLocked(ScreenId id, GraphicCM_ColorSpaceType& colorSpace) const
1328 {
1329 if (screens_.count(id) == 0) {
1330 RS_LOGW("RSScreenManager %{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
1331 return StatusCode::SCREEN_NOT_FOUND;
1332 }
1333 return screens_.at(id)->GetScreenColorSpace(colorSpace);
1334 }
1335
SetScreenColorSpaceLocked(ScreenId id,GraphicCM_ColorSpaceType colorSpace)1336 int32_t RSScreenManager::SetScreenColorSpaceLocked(ScreenId id, GraphicCM_ColorSpaceType colorSpace)
1337 {
1338 if (screens_.count(id) == 0) {
1339 RS_LOGW("RSScreenManager %{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
1340 return StatusCode::SCREEN_NOT_FOUND;
1341 }
1342 return screens_.at(id)->SetScreenColorSpace(colorSpace);
1343 }
1344
GetScreenSupportedColorGamuts(ScreenId id,std::vector<ScreenColorGamut> & mode) const1345 int32_t RSScreenManager::GetScreenSupportedColorGamuts(ScreenId id, std::vector<ScreenColorGamut>& mode) const
1346 {
1347 std::lock_guard<std::mutex> lock(mutex_);
1348 return GetScreenSupportedColorGamutsLocked(id, mode);
1349 }
1350
GetScreenSupportedMetaDataKeys(ScreenId id,std::vector<ScreenHDRMetadataKey> & keys) const1351 int32_t RSScreenManager::GetScreenSupportedMetaDataKeys(ScreenId id, std::vector<ScreenHDRMetadataKey>& keys) const
1352 {
1353 std::lock_guard<std::mutex> lock(mutex_);
1354 return GetScreenSupportedMetaDataKeysLocked(id, keys);
1355 }
1356
GetActualScreensNum() const1357 uint32_t RSScreenManager::GetActualScreensNum() const
1358 {
1359 std::lock_guard<std::mutex> lock(mutex_);
1360 uint32_t num = 0;
1361 for (const auto &[id, screen] : screens_) {
1362 if (!screen) {
1363 continue;
1364 }
1365 if (!screen->IsVirtual()) {
1366 num += 1;
1367 } else {
1368 if (screen->GetProducerSurface()) {
1369 num += 1;
1370 }
1371 }
1372 }
1373 return num;
1374 }
1375
GetScreenColorGamut(ScreenId id,ScreenColorGamut & mode) const1376 int32_t RSScreenManager::GetScreenColorGamut(ScreenId id, ScreenColorGamut &mode) const
1377 {
1378 std::lock_guard<std::mutex> lock(mutex_);
1379 return GetScreenColorGamutLocked(id, mode);
1380 }
1381
SetScreenColorGamut(ScreenId id,int32_t modeIdx)1382 int32_t RSScreenManager::SetScreenColorGamut(ScreenId id, int32_t modeIdx)
1383 {
1384 std::lock_guard<std::mutex> lock(mutex_);
1385 return SetScreenColorGamutLocked(id, modeIdx);
1386 }
1387
SetScreenGamutMap(ScreenId id,ScreenGamutMap mode)1388 int32_t RSScreenManager::SetScreenGamutMap(ScreenId id, ScreenGamutMap mode)
1389 {
1390 std::lock_guard<std::mutex> lock(mutex_);
1391 return SetScreenGamutMapLocked(id, mode);
1392 }
1393
SetScreenCorrection(ScreenId id,ScreenRotation screenRotation)1394 int32_t RSScreenManager::SetScreenCorrection(ScreenId id, ScreenRotation screenRotation)
1395 {
1396 std::lock_guard<std::mutex> lock(mutex_);
1397 return SetScreenCorrectionLocked(id, screenRotation);
1398 }
1399
GetScreenGamutMap(ScreenId id,ScreenGamutMap & mode) const1400 int32_t RSScreenManager::GetScreenGamutMap(ScreenId id, ScreenGamutMap &mode) const
1401 {
1402 std::lock_guard<std::mutex> lock(mutex_);
1403 return GetScreenGamutMapLocked(id, mode);
1404 }
1405
GetScreenHDRCapability(ScreenId id,RSScreenHDRCapability & screenHdrCapability) const1406 int32_t RSScreenManager::GetScreenHDRCapability(ScreenId id, RSScreenHDRCapability& screenHdrCapability) const
1407 {
1408 std::lock_guard<std::mutex> lock(mutex_);
1409 return GetScreenHDRCapabilityLocked(id, screenHdrCapability);
1410 }
1411
GetScreenType(ScreenId id,RSScreenType & type) const1412 int32_t RSScreenManager::GetScreenType(ScreenId id, RSScreenType& type) const
1413 {
1414 std::lock_guard<std::mutex> lock(mutex_);
1415 return GetScreenTypeLocked(id, type);
1416 }
1417
SetScreenSkipFrameInterval(ScreenId id,uint32_t skipFrameInterval)1418 int32_t RSScreenManager::SetScreenSkipFrameInterval(ScreenId id, uint32_t skipFrameInterval)
1419 {
1420 std::lock_guard<std::mutex> lock(mutex_);
1421 return SetScreenSkipFrameIntervalLocked(id, skipFrameInterval);
1422 }
1423
GetPixelFormat(ScreenId id,GraphicPixelFormat & pixelFormat) const1424 int32_t RSScreenManager::GetPixelFormat(ScreenId id, GraphicPixelFormat& pixelFormat) const
1425 {
1426 std::lock_guard<std::mutex> lock(mutex_);
1427 return GetPixelFormatLocked(id, pixelFormat);
1428 }
1429
SetPixelFormat(ScreenId id,GraphicPixelFormat pixelFormat)1430 int32_t RSScreenManager::SetPixelFormat(ScreenId id, GraphicPixelFormat pixelFormat)
1431 {
1432 std::lock_guard<std::mutex> lock(mutex_);
1433 return SetPixelFormatLocked(id, pixelFormat);
1434 }
1435
GetScreenSupportedHDRFormats(ScreenId id,std::vector<ScreenHDRFormat> & hdrFormats) const1436 int32_t RSScreenManager::GetScreenSupportedHDRFormats(ScreenId id, std::vector<ScreenHDRFormat>& hdrFormats) const
1437 {
1438 std::lock_guard<std::mutex> lock(mutex_);
1439 return GetScreenSupportedHDRFormatsLocked(id, hdrFormats);
1440 }
1441
GetScreenHDRFormat(ScreenId id,ScreenHDRFormat & hdrFormat) const1442 int32_t RSScreenManager::GetScreenHDRFormat(ScreenId id, ScreenHDRFormat& hdrFormat) const
1443 {
1444 std::lock_guard<std::mutex> lock(mutex_);
1445 return GetScreenHDRFormatLocked(id, hdrFormat);
1446 }
1447
SetScreenHDRFormat(ScreenId id,int32_t modeIdx)1448 int32_t RSScreenManager::SetScreenHDRFormat(ScreenId id, int32_t modeIdx)
1449 {
1450 std::lock_guard<std::mutex> lock(mutex_);
1451 return SetScreenHDRFormatLocked(id, modeIdx);
1452 }
1453
GetScreenSupportedColorSpaces(ScreenId id,std::vector<GraphicCM_ColorSpaceType> & colorSpaces) const1454 int32_t RSScreenManager::GetScreenSupportedColorSpaces(
1455 ScreenId id, std::vector<GraphicCM_ColorSpaceType>& colorSpaces) const
1456 {
1457 std::lock_guard<std::mutex> lock(mutex_);
1458 return GetScreenSupportedColorSpacesLocked(id, colorSpaces);
1459 }
1460
GetScreenColorSpace(ScreenId id,GraphicCM_ColorSpaceType & colorSpace) const1461 int32_t RSScreenManager::GetScreenColorSpace(ScreenId id, GraphicCM_ColorSpaceType& colorSpace) const
1462 {
1463 std::lock_guard<std::mutex> lock(mutex_);
1464 return GetScreenColorSpaceLocked(id, colorSpace);
1465 }
1466
SetScreenColorSpace(ScreenId id,GraphicCM_ColorSpaceType colorSpace)1467 int32_t RSScreenManager::SetScreenColorSpace(ScreenId id, GraphicCM_ColorSpaceType colorSpace)
1468 {
1469 std::lock_guard<std::mutex> lock(mutex_);
1470 return SetScreenColorSpaceLocked(id, colorSpace);
1471 }
1472
1473 } // namespace impl
1474
CreateOrGetScreenManager()1475 sptr<RSScreenManager> CreateOrGetScreenManager()
1476 {
1477 return impl::RSScreenManager::GetInstance();
1478 }
1479 } // namespace Rosen
1480 } // namespace OHOS
1481