• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "rs_screen_manager.h"
17 
18 #include "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