• 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 
25 namespace OHOS {
26 namespace Rosen {
27 using namespace HiviewDFX;
28 namespace impl {
29 std::once_flag RSScreenManager::createFlag_;
30 sptr<OHOS::Rosen::RSScreenManager> RSScreenManager::instance_ = nullptr;
31 
GetInstance()32 sptr<OHOS::Rosen::RSScreenManager> RSScreenManager::GetInstance() noexcept
33 {
34     std::call_once(createFlag_, []() {
35         instance_ = new RSScreenManager();
36     });
37 
38     return instance_;
39 }
40 
RSScreenManager()41 RSScreenManager::RSScreenManager()
42 {
43 }
44 
~RSScreenManager()45 RSScreenManager::~RSScreenManager() noexcept
46 {
47 }
48 
Init()49 bool RSScreenManager::Init() noexcept
50 {
51     composer_ = HdiBackend::GetInstance();
52     if (composer_ == nullptr) {
53         RS_LOGE("RSScreenManager %s: Failed to get composer.", __func__);
54         return false;
55     }
56 
57     if (composer_->RegScreenHotplug(&RSScreenManager::OnHotPlug, this) != 0) {
58         RS_LOGE("RSScreenManager %s: Failed to register OnHotPlug Func to composer.", __func__);
59         return false;
60     }
61 
62     if (composer_->RegHwcDeadListener(&RSScreenManager::OnHwcDead, this) != 0) {
63         RS_LOGE("RSScreenManager %s: Failed to register OnHwcDead Func to composer.", __func__);
64         return false;
65     }
66 
67     // call ProcessScreenHotPlugEvents() for primary screen immediately in main thread.
68     ProcessScreenHotPlugEvents();
69     RS_LOGI("RSScreenManager Init succeed");
70     return true;
71 }
72 
OnHotPlug(std::shared_ptr<HdiOutput> & output,bool connected,void * data)73 void RSScreenManager::OnHotPlug(std::shared_ptr<HdiOutput> &output, bool connected, void *data)
74 {
75     if (output == nullptr) {
76         RS_LOGE("RSScreenManager %s: output is nullptr.", __func__);
77         return;
78     }
79 
80     RSScreenManager *screenManager = nullptr;
81     if (data != nullptr) {
82         screenManager = static_cast<RSScreenManager *>(data);
83     } else {
84         screenManager = static_cast<RSScreenManager *>(RSScreenManager::GetInstance().GetRefPtr());
85     }
86 
87     if (screenManager == nullptr) {
88         RS_LOGE("RSScreenManager %s: Failed to find RSScreenManager instance.", __func__);
89         return;
90     }
91 
92     screenManager->OnHotPlugEvent(output, connected);
93 }
94 
OnHotPlugEvent(std::shared_ptr<HdiOutput> & output,bool connected)95 void RSScreenManager::OnHotPlugEvent(std::shared_ptr<HdiOutput> &output, bool connected)
96 {
97     {
98         std::lock_guard<std::mutex> lock(mutex_);
99         pendingHotPlugEvents_.emplace_back(ScreenHotPlugEvent{output, connected});
100     }
101 
102     // This func would be called in main thread first time immediately after calling composer_->RegScreenHotplug,
103     // but at this time the RSMainThread object would not be ready to handle this, so we need to call
104     // ProcessScreenHotPlugEvents() after this func in RSScreenManager::Init().
105 
106     // Normally, this func would be called in hdi's hw-ipc threads(but sometimes in main thread, maybe),
107     // so we should notify the RSMainThread to postTask to call ProcessScreenHotPlugEvents().
108     auto mainThread = RSMainThread::Instance();
109     if (mainThread == nullptr) {
110         return;
111     }
112     mainThread->RequestNextVSync();
113 }
114 
OnHwcDead(void * data)115 void RSScreenManager::OnHwcDead(void *data)
116 {
117     RS_LOGD("RSScreenManager %s: The composer_host is already dead.", __func__);
118     RSScreenManager *screenManager = static_cast<RSScreenManager *>(RSScreenManager::GetInstance().GetRefPtr());
119     if (screenManager == nullptr) {
120         RS_LOGE("RSScreenManager %s: Failed to find RSScreenManager instance.", __func__);
121         return;
122     }
123 
124     screenManager->OnHwcDeadEvent();
125 
126     // Automatically recover when composer host dies.
127     screenManager->Reinit();
128 }
129 
OnHwcDeadEvent()130 void RSScreenManager::OnHwcDeadEvent()
131 {
132     std::lock_guard<std::mutex> lock(mutex_);
133     for (const auto &[id, screen] : screens_) {
134         if (screen) {
135             for (auto &cb : screenChangeCallbacks_) {
136                 cb->OnScreenChanged(id, ScreenEvent::DISCONNECTED);
137                 RS_LOGD("RSScreenManager %s: The screen callback has been invoked.", __func__);
138             }
139             if (screenPowerStatus_.count(id) != 0) {
140                 screenPowerStatus_.erase(id);
141             }
142             if (screen->IsVirtual()) {
143                 continue;
144             } else {
145                 auto surfaceId = screen->GetOutput()->GetFrameBufferSurface()->GetUniqueId();
146                 screen->GetOutput()->GetFrameBufferSurface()->CleanCache();
147                 RSHardwareThread::Instance().CleanRenderFrame(surfaceId);
148             }
149         }
150     }
151     screens_.clear();
152     defaultScreenId_ = INVALID_SCREEN_ID;
153 }
154 
Reinit()155 void RSScreenManager::Reinit()
156 {
157     RSScreenManager *screenManager = static_cast<RSScreenManager *>(RSScreenManager::GetInstance().GetRefPtr());
158     if (screenManager == nullptr) {
159         RS_LOGE("RSScreenManager %s: Failed to find RSScreenManager instance.", __func__);
160         return;
161     }
162 
163     auto renderType = RSUniRenderJudgement::GetUniRenderEnabledType();
164     if (renderType != UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
165         auto mainThread = RSMainThread::Instance();
166         if (mainThread == nullptr) {
167             RS_LOGE("RSScreenManager %s: Reinit failed, get RSMainThread failed.", __func__);
168             return;
169         }
170         mainThread->PostTask([screenManager, this]() {
171             composer_->ResetDevice();
172             if (!screenManager->Init()) {
173                 RS_LOGE("RSScreenManager %s: Reinit failed, screenManager init failed in mainThread.", __func__);
174                 return;
175             }
176         });
177     } else {
178         RSHardwareThread::Instance().PostTask([screenManager, this]() {
179             composer_->ResetDevice();
180             if (!screenManager->Init()) {
181                 RS_LOGE("RSScreenManager %s: Reinit failed, screenManager init failed in HardwareThread.", __func__);
182                 return;
183             }
184         });
185     }
186 }
187 
ProcessScreenHotPlugEvents()188 void RSScreenManager::ProcessScreenHotPlugEvents()
189 {
190     std::lock_guard<std::mutex> lock(mutex_);
191     for (auto &event : pendingHotPlugEvents_) {
192         if (event.connected) {
193             ProcessScreenConnectedLocked(event.output);
194             AddScreenToHgm(event.output);
195         } else {
196             ProcessScreenDisConnectedLocked(event.output);
197             RemoveScreenFromHgm(event.output);
198         }
199     }
200     for (auto id : connectedIds_) {
201         for (auto &cb : screenChangeCallbacks_) {
202             cb->OnScreenChanged(id, ScreenEvent::CONNECTED);
203         }
204     }
205     mipiCheckInFirstHotPlugEvent_ = true;
206     pendingHotPlugEvents_.clear();
207     connectedIds_.clear();
208 }
209 
AddScreenToHgm(std::shared_ptr<HdiOutput> & output)210 void RSScreenManager::AddScreenToHgm(std::shared_ptr<HdiOutput> &output)
211 {
212     if (output == nullptr) {
213         RS_LOGE("RSScreenManager %s: output is nullptr.", __func__);
214         return;
215     }
216     RS_LOGI("RSScreenManager AddScreenToHgm");
217     auto &hgmCore = OHOS::Rosen::HgmCore::Instance();
218     ScreenId thisId = ToScreenId(output->GetScreenId());
219     if (screens_.find(thisId) == screens_.end()) {
220         RS_LOGE("RSScreenManager invalid screen id, screen not found : %" PRIu64 "", thisId);
221         return;
222     }
223 
224     int32_t initModeId = 0;
225     auto initMode = screens_[thisId]->GetActiveMode();
226     if (!initMode) {
227         RS_LOGE("RSScreenManager failed to get initial mode");
228     } else {
229         initModeId = initMode->id;
230     }
231     if (hgmCore.AddScreen(thisId, initModeId)) {
232         RS_LOGW("RSScreenManager failed to add screen : %" PRIu64 "", thisId);
233         return;
234     }
235 
236     // for each supported mode, use the index as modeId to add the detailed mode to hgm
237     int32_t modeId = 0;
238     auto supportedModes = screens_[thisId]->GetSupportedModes();
239     for (auto mode = supportedModes.begin(); mode != supportedModes.end(); ++mode) {
240         if (!hgmCore.AddScreenInfo(thisId, (*mode).width, (*mode).height,
241             (*mode).freshRate, modeId)) {
242             RS_LOGW("RSScreenManager failed to add a screen profile to the screen : %" PRIu64 "", thisId);
243         }
244         modeId++;
245     }
246     const auto &screen = screens_.at(thisId);
247     const auto &capability = screens_.at(thisId)->GetCapability();
248     hgmCore.AddScreenProfile(thisId, screen->Width(), screen->Height(), capability.phyWidth, capability.phyHeight);
249 }
250 
RemoveScreenFromHgm(std::shared_ptr<HdiOutput> & output)251 void RSScreenManager::RemoveScreenFromHgm(std::shared_ptr<HdiOutput> &output)
252 {
253     if (output == nullptr) {
254         RS_LOGE("RSScreenManager %s: output is nullptr.", __func__);
255         return;
256     }
257 
258     RS_LOGI("RSScreenManager RemoveScreenFromHgm");
259     auto &hgmCore = OHOS::Rosen::HgmCore::Instance();
260     ScreenId id = ToScreenId(output->GetScreenId());
261     if (hgmCore.RemoveScreen(id)) {
262         RS_LOGW("RSScreenManager failed to remove screen : %" PRIu64 "", id);
263     }
264     hgmCore.RemoveScreenProfile(id);
265 }
266 
ProcessScreenConnectedLocked(std::shared_ptr<HdiOutput> & output)267 void RSScreenManager::ProcessScreenConnectedLocked(std::shared_ptr<HdiOutput> &output)
268 {
269     if (output == nullptr) {
270         RS_LOGE("RSScreenManager %s: output is nullptr.", __func__);
271         return;
272     }
273 
274     bool isVirtual = false;
275     ScreenId id = ToScreenId(output->GetScreenId());
276 
277     if (screens_.count(id) == 1) {
278         RS_LOGW("RSScreenManager %s The screen for id %" PRIu64 " already existed.", __func__, id);
279 
280         // [PLANNING]: should we erase it and create a new one?
281         for (auto &cb : screenChangeCallbacks_) {
282             cb->OnScreenChanged(id, ScreenEvent::DISCONNECTED);
283         }
284         screens_.erase(id);
285     }
286 
287     screens_[id] = std::make_unique<RSScreen>(id, isVirtual, output, nullptr);
288 
289     auto vsyncSampler = CreateVSyncSampler();
290     if (vsyncSampler != nullptr) {
291         auto renderType = RSUniRenderJudgement::GetUniRenderEnabledType();
292         if (renderType != UniRenderEnabledType::UNI_RENDER_ENABLED_FOR_ALL) {
293             vsyncSampler->RegSetScreenVsyncEnabledCallback([this, id](bool enabled) {
294                 auto mainThread = RSMainThread::Instance();
295                 if (mainThread == nullptr) {
296                     RS_LOGE("SetScreenVsyncEnabled:%{public}d failed, get RSMainThread failed", enabled);
297                     return;
298                 }
299                 mainThread->PostTask([this, id, enabled]() {
300                     if (screens_[id] == nullptr) {
301                         RS_LOGE("SetScreenVsyncEnabled:%{public}d failed, screen %{public}ld not found", enabled, id);
302                         return;
303                     }
304                     screens_[id]->SetScreenVsyncEnabled(enabled);
305                 });
306             });
307         } else {
308             vsyncSampler->RegSetScreenVsyncEnabledCallback([this, id](bool enabled) {
309                 RSHardwareThread::Instance().PostTask([this, id, enabled]() {
310                     if (screens_[id] == nullptr) {
311                         RS_LOGE("SetScreenVsyncEnabled:%{public}d failed, screen %{public}ld not found", enabled, id);
312                         return;
313                     }
314                     screens_[id]->SetScreenVsyncEnabled(enabled);
315                 });
316             });
317         }
318     } else {
319         RS_LOGE("RegSetScreenVsyncEnabledCallback failed, vsyncSampler is null");
320     }
321 
322     if (screens_[id]->GetCapability().type == GraphicInterfaceType::GRAPHIC_DISP_INTF_MIPI) {
323         if (!mipiCheckInFirstHotPlugEvent_) {
324             defaultScreenId_ = id;
325         }
326         mipiCheckInFirstHotPlugEvent_ = true;
327     } else if (defaultScreenId_ == INVALID_SCREEN_ID) {
328         defaultScreenId_ = id;
329     }
330 
331     RS_LOGI("RSScreenManager %s: A new screen(id %" PRIu64 ") connected.", __func__, id);
332     connectedIds_.emplace_back(id);
333 }
334 
ProcessScreenDisConnectedLocked(std::shared_ptr<HdiOutput> & output)335 void RSScreenManager::ProcessScreenDisConnectedLocked(std::shared_ptr<HdiOutput> &output)
336 {
337     ScreenId id = ToScreenId(output->GetScreenId());
338 
339     if (screens_.count(id) == 0) {
340         RS_LOGW("RSScreenManager %s: There is no screen for id %" PRIu64, __func__, id);
341     } else {
342         for (auto &cb : screenChangeCallbacks_) {
343             cb->OnScreenChanged(id, ScreenEvent::DISCONNECTED);
344         }
345         screens_.erase(id);
346         RS_LOGI("RSScreenManager %s: Screen(id %" PRIu64 ") disconnected.", __func__, id);
347     }
348     if (screenPowerStatus_.count(id) != 0) {
349         screenPowerStatus_.erase(id);
350     }
351     if (id == defaultScreenId_) {
352         HandleDefaultScreenDisConnectedLocked();
353     }
354 }
355 
356 // If the previous primary screen disconnected, we traversal the left screens
357 // and find the first physical screen to be the default screen.
358 // If there was no physical screen left, we set the first screen as default, no matter what type it is.
359 // At last, if no screen left, we set Default Screen Id to INVALID_SCREEN_ID.
HandleDefaultScreenDisConnectedLocked()360 void RSScreenManager::HandleDefaultScreenDisConnectedLocked()
361 {
362     defaultScreenId_ = INVALID_SCREEN_ID;
363     for (const auto &[id, screen] : screens_) {
364         if (!screen->IsVirtual()) {
365             defaultScreenId_ = id;
366             break;
367         }
368     }
369 
370     if (defaultScreenId_ == INVALID_SCREEN_ID) {
371         if (!screens_.empty()) {
372             defaultScreenId_ = screens_.cbegin()->first;
373         }
374     }
375 }
376 
SetDefaultScreenId(ScreenId id)377 void RSScreenManager::SetDefaultScreenId(ScreenId id)
378 {
379     std::lock_guard<std::mutex> lock(mutex_);
380     defaultScreenId_ = id;
381 }
382 
SetScreenMirror(ScreenId id,ScreenId toMirror)383 void RSScreenManager::SetScreenMirror(ScreenId id, ScreenId toMirror)
384 {
385     std::lock_guard<std::mutex> lock(mutex_);
386 
387     if (screens_.count(id) == 0) {
388         RS_LOGW("RSScreenManager %s: There is no screen for id %" PRIu64 ".", __func__, id);
389         return;
390     }
391 
392     screens_[id]->SetMirror(toMirror);
393 }
394 
GenerateVirtualScreenIdLocked()395 ScreenId RSScreenManager::GenerateVirtualScreenIdLocked()
396 {
397     if (!freeVirtualScreenIds_.empty()) {
398         ScreenId id = freeVirtualScreenIds_.front();
399         freeVirtualScreenIds_.pop();
400         return id;
401     }
402 
403     // The left 32 bits is for virtual screen id.
404     return (static_cast<ScreenId>(maxVirtualScreenNum_++) << 32) | 0xffffffffu;
405 }
406 
ReuseVirtualScreenIdLocked(ScreenId id)407 void RSScreenManager::ReuseVirtualScreenIdLocked(ScreenId id)
408 {
409     freeVirtualScreenIds_.push(id);
410 }
411 
GetMirrorScreenId(ScreenId id)412 ScreenId RSScreenManager::GetMirrorScreenId(ScreenId id)
413 {
414     ScreenId mirroredId = INVALID_SCREEN_ID;
415     auto mainThread = RSMainThread::Instance();
416     if (mainThread == nullptr) {
417         return mirroredId;
418     }
419 
420     const auto& nodeMap = mainThread->GetContext().GetNodeMap();
421     nodeMap.TraversalNodes([&id, &mirroredId](const std::shared_ptr<RSBaseRenderNode>& node) {
422         if (node == nullptr || !node->IsInstanceOf<RSDisplayRenderNode>()) {
423             return;
424         }
425         RSDisplayRenderNode& displayNode = *(RSBaseRenderNode::ReinterpretCast<RSDisplayRenderNode>(node));
426         if (displayNode.GetScreenId() != id) {
427             return;
428         }
429         std::shared_ptr<RSDisplayRenderNode> mirroredNode = displayNode.GetMirrorSource().lock();
430         if (mirroredNode != nullptr) {
431             mirroredId = mirroredNode->GetScreenId();
432         }
433     });
434     return mirroredId;
435 }
436 
437 // The main screen resolution can be changed by the mirrored screen.
MirrorChangeDefaultScreenResolution(ScreenId id,uint32_t width,uint32_t height)438 void RSScreenManager::MirrorChangeDefaultScreenResolution(ScreenId id, uint32_t width, uint32_t height)
439 {
440     if (screens_.count(id) == 0) {
441         RS_LOGD("RSScreenManager %s: set fails because no screen access is currently available!", __func__);
442         return;
443     }
444 
445     ScreenId mirroredId = GetMirrorScreenId(id);
446     if (mirroredId == INVALID_SCREEN_ID) {
447         RS_LOGD("RSScreenManager %s: mirror screen is invalid.", __func__);
448         return;
449     }
450     ScreenId mainId = GetDefaultScreenId();
451     if (mirroredId == mainId) {
452         bool resolutionSetSuccess = false;
453         std::vector<GraphicDisplayModeInfo> mainMode = screens_.at(mainId)->GetSupportedModes();
454         for (uint32_t i = 0; i < mainMode.size(); i++) {
455             if (static_cast<uint32_t>(mainMode[i].width) == width &&
456                 static_cast<uint32_t>(mainMode[i].height) == height) {
457                 screens_.at(mainId)->SetActiveMode(i);
458                 resolutionSetSuccess = true;
459                 break;
460             }
461         }
462         if (!resolutionSetSuccess) {
463             RS_LOGD("RSScreenManager %s: not support the current resolution!", __func__);
464         }
465     }
466 }
467 
GetVirtualScreenResolutionLocked(ScreenId id,RSVirtualScreenResolution & virtualScreenResolution) const468 void RSScreenManager::GetVirtualScreenResolutionLocked(ScreenId id,
469     RSVirtualScreenResolution& virtualScreenResolution) const
470 {
471     if (screens_.count(id) == 0) {
472         RS_LOGW("RSScreenManager %s: There is no screen for id %" PRIu64 ".", __func__, id);
473         return;
474     }
475 
476     virtualScreenResolution.SetVirtualScreenWidth(static_cast<uint32_t>(screens_.at(id)->Width()));
477     virtualScreenResolution.SetVirtualScreenHeight(static_cast<uint32_t>(screens_.at(id)->Height()));
478 }
479 
GetScreenActiveModeLocked(ScreenId id,RSScreenModeInfo & screenModeInfo) const480 void RSScreenManager::GetScreenActiveModeLocked(ScreenId id, RSScreenModeInfo& screenModeInfo) const
481 {
482     if (screens_.count(id) == 0) {
483         RS_LOGW("RSScreenManager %s: There is no screen for id %" PRIu64 ".", __func__, id);
484         return;
485     }
486 
487     auto modeInfo = screens_.at(id)->GetActiveMode();
488     if (!modeInfo) {
489         RS_LOGE("RSScreenManager %s: Failed to get active mode for screen %" PRIu64 ".", __func__, id);
490         return;
491     }
492 
493     screenModeInfo.SetScreenWidth(modeInfo->width);
494     screenModeInfo.SetScreenHeight(modeInfo->height);
495     screenModeInfo.SetScreenRefreshRate(modeInfo->freshRate);
496     screenModeInfo.SetScreenModeId(screens_.at(id)->GetActiveModePosByModeId(modeInfo->id));
497 }
498 
GetScreenSupportedModesLocked(ScreenId id) const499 std::vector<RSScreenModeInfo> RSScreenManager::GetScreenSupportedModesLocked(ScreenId id) const
500 {
501     std::vector<RSScreenModeInfo> screenSupportedModes;
502     if (screens_.count(id) == 0) {
503         RS_LOGW("RSScreenManager %s: There is no screen for id %" PRIu64 ".", __func__, id);
504         return screenSupportedModes;
505     }
506 
507     const auto& displaySupportedModes = screens_.at(id)->GetSupportedModes();
508     screenSupportedModes.resize(displaySupportedModes.size());
509     for (decltype(displaySupportedModes.size()) idx = 0; idx < displaySupportedModes.size(); ++idx) {
510         screenSupportedModes[idx].SetScreenWidth(displaySupportedModes[idx].width);
511         screenSupportedModes[idx].SetScreenHeight(displaySupportedModes[idx].height);
512         screenSupportedModes[idx].SetScreenRefreshRate(displaySupportedModes[idx].freshRate);
513         screenSupportedModes[idx].SetScreenModeId(displaySupportedModes[idx].id);
514     }
515     return screenSupportedModes;
516 }
517 
GetScreenCapabilityLocked(ScreenId id) const518 RSScreenCapability RSScreenManager::GetScreenCapabilityLocked(ScreenId id) const
519 {
520     RSScreenCapability screenCapability;
521     if (screens_.count(id) == 0) {
522         RS_LOGW("RSScreenManager %s: There is no screen for id %" PRIu64 ".", __func__, id);
523         return screenCapability;
524     }
525     if (screens_.at(id)->IsVirtual()) {
526         RS_LOGW("RSScreenManager %s: only name attribute is valid for virtual screen.", __func__);
527         screenCapability.SetName(screens_.at(id)->Name());
528         return screenCapability;
529     }
530 
531     const auto& capability = screens_.at(id)->GetCapability();
532     std::vector<RSScreenProps> props;
533     uint32_t propCount = capability.propertyCount;
534     props.resize(propCount);
535     for (uint32_t propIndex = 0; propIndex < propCount; propIndex++) {
536         props[propIndex] = RSScreenProps(capability.props[propIndex].name, capability.props[propIndex].propId,
537             capability.props[propIndex].value);
538     }
539     screenCapability.SetName(capability.name);
540     screenCapability.SetType(static_cast<ScreenInterfaceType>(capability.type));
541     screenCapability.SetPhyWidth(capability.phyWidth);
542     screenCapability.SetPhyHeight(capability.phyHeight);
543     screenCapability.SetSupportLayers(capability.supportLayers);
544     screenCapability.SetVirtualDispCount(capability.virtualDispCount);
545     screenCapability.SetSupportWriteBack(capability.supportWriteBack);
546     screenCapability.SetProps(props);
547     return screenCapability;
548 }
549 
GetScreenPowerStatusLocked(ScreenId id) const550 ScreenPowerStatus RSScreenManager::GetScreenPowerStatusLocked(ScreenId id) const
551 {
552     if (screens_.count(id) == 0) {
553         RS_LOGW("RSScreenManager %s: There is no screen for id %" PRIu64 ".", __func__, id);
554         return INVALID_POWER_STATUS;
555     }
556 
557     ScreenPowerStatus status = static_cast<ScreenPowerStatus>(screens_.at(id)->GetPowerStatus());
558     return status;
559 }
560 
GetAllScreenIds()561 std::vector<ScreenId> RSScreenManager::GetAllScreenIds()
562 {
563     std::vector<ScreenId> ids;
564     for (auto iter = screens_.begin(); iter != screens_.end(); ++iter) {
565         ids.emplace_back(iter->first);
566     }
567     return ids;
568 }
569 
CreateVirtualScreen(const std::string & name,uint32_t width,uint32_t height,sptr<Surface> surface,ScreenId mirrorId,int32_t flags)570 ScreenId RSScreenManager::CreateVirtualScreen(
571     const std::string &name,
572     uint32_t width,
573     uint32_t height,
574     sptr<Surface> surface,
575     ScreenId mirrorId,
576     int32_t flags
577     )
578 {
579     std::lock_guard<std::mutex> lock(mutex_);
580 
581     if (surface != nullptr) {
582         uint64_t surfaceId = surface->GetUniqueId();
583         for (auto &[_, screen] : screens_) {
584             if (!screen->IsVirtual()) {
585                 continue;
586             }
587             auto screenSurface = screen->GetProducerSurface();
588             if (screenSurface == nullptr) {
589                 continue;
590             }
591             if (screenSurface->GetUniqueId() == surfaceId) {
592                 RS_LOGW("RSScreenManager %s: surface %" PRIu64 " is used, create virtual screen failed!", __func__,
593                     surfaceId);
594                 return INVALID_SCREEN_ID;
595             }
596         }
597     } else {
598         RS_LOGD("RSScreenManager %s: surface is nullptr.", __func__);
599     }
600 
601     VirtualScreenConfigs configs;
602     ScreenId newId = GenerateVirtualScreenIdLocked();
603     configs.id = newId;
604     configs.mirrorId = mirrorId;
605     configs.name = name;
606     configs.width = width;
607     configs.height = height;
608     configs.surface = surface;
609     configs.flags = flags;
610 
611     screens_[newId] = std::make_unique<RSScreen>(configs);
612     RS_LOGD("RSScreenManager %s: create virtual screen(id %" PRIu64 ").", __func__, newId);
613     return newId;
614 }
615 
SetVirtualScreenSurface(ScreenId id,sptr<Surface> surface)616 int32_t RSScreenManager::SetVirtualScreenSurface(ScreenId id, sptr<Surface> surface)
617 {
618     std::lock_guard<std::mutex> lock(mutex_);
619     if (screens_.find(id) == screens_.end()) {
620         return SCREEN_NOT_FOUND;
621     }
622     uint64_t surfaceId = surface->GetUniqueId();
623     for (auto &[screenId, screen] : screens_) {
624         if (!screen->IsVirtual() || screenId == id) {
625             continue;
626         }
627         auto screenSurface = screen->GetProducerSurface();
628         if (screenSurface == nullptr) {
629             continue;
630         }
631         if (screenSurface->GetUniqueId() == surface->GetUniqueId()) {
632             RS_LOGE("RSScreenManager %s: surface %" PRIu64 " is used, set surface failed!", __func__, surfaceId);
633             return SURFACE_NOT_UNIQUE;
634         }
635     }
636     screens_.at(id)->SetProducerSurface(surface);
637     RS_LOGD("RSScreenManager %s: set virtual screen surface success!", __func__);
638     // if SetVirtualScreenSurface success, better to request the next vsync, avoiding prolong black screen
639     auto mainThread = RSMainThread::Instance();
640     if (mainThread != nullptr) {
641         mainThread->RequestNextVSync();
642     }
643     return SUCCESS;
644 }
645 
RemoveVirtualScreen(ScreenId id)646 void RSScreenManager::RemoveVirtualScreen(ScreenId id)
647 {
648     std::lock_guard<std::mutex> lock(mutex_);
649 
650     RemoveVirtualScreenLocked(id);
651 }
652 
RemoveVirtualScreenLocked(ScreenId id)653 void RSScreenManager::RemoveVirtualScreenLocked(ScreenId id)
654 {
655     if (screens_.count(id) == 0) {
656         RS_LOGW("RSScreenManager %s: There is no screen for id %" PRIu64 ".", __func__, id);
657         return;
658     }
659 
660     screens_.erase(id);
661 
662     // Update other screens' mirrorId.
663     for (auto &[id, screen] : screens_) {
664         if (screen->MirrorId() == id) {
665             screen->SetMirror(INVALID_SCREEN_ID);
666         }
667     }
668     RS_LOGD("RSScreenManager %s: remove virtual screen(id %" PRIu64 ").", __func__, id);
669 
670     ReuseVirtualScreenIdLocked(id);
671 }
672 
SetScreenActiveMode(ScreenId id,uint32_t modeId)673 void RSScreenManager::SetScreenActiveMode(ScreenId id, uint32_t modeId)
674 {
675     std::lock_guard<std::mutex> lock(mutex_);
676 
677     if (screens_.count(id) == 0) {
678         RS_LOGW("RSScreenManager %s: There is no screen for id %" PRIu64 ".", __func__, id);
679         return;
680     }
681     screens_.at(id)->SetActiveMode(modeId);
682 
683     // The main screen resolution can be changed on the mirrored physical screen.
684     auto supportedModes = screens_.at(id)->GetSupportedModes();
685     if (modeId >= supportedModes.size()) {
686         RS_LOGE("RSScreenManager %s: set fails because the index is out of bounds.", __func__);
687         return;
688     }
689     uint32_t width = supportedModes[modeId].width;
690     uint32_t height = supportedModes[modeId].height;
691     MirrorChangeDefaultScreenResolution(id, width, height);
692 }
693 
SetVirtualScreenResolution(ScreenId id,uint32_t width,uint32_t height)694 int32_t RSScreenManager::SetVirtualScreenResolution(ScreenId id, uint32_t width, uint32_t height)
695 {
696     std::lock_guard<std::mutex> lock(mutex_);
697 
698     if (screens_.count(id) == 0) {
699         RS_LOGW("RSScreenManager %s: There is no screen for id %" PRIu64 ".", __func__, id);
700         return SCREEN_NOT_FOUND;
701     }
702     screens_.at(id)->SetResolution(width, height);
703     RS_LOGD("RSScreenManager %s: set virtual screen resolution success", __func__);
704 
705     // The main screen resolution can be changed by the mirrored virtual screen.
706     MirrorChangeDefaultScreenResolution(id, width, height);
707 
708     return SUCCESS;
709 }
710 
SetScreenPowerStatus(ScreenId id,ScreenPowerStatus status)711 void RSScreenManager::SetScreenPowerStatus(ScreenId id, ScreenPowerStatus status)
712 {
713     std::lock_guard<std::mutex> lock(mutex_);
714 
715     if (screens_.count(id) == 0) {
716         RS_LOGW("RSScreenManager %s: There is no screen for id %" PRIu64 ".", __func__, id);
717         return;
718     }
719     screens_.at(id)->SetPowerStatus(static_cast<uint32_t>(status));
720 
721     /*
722      * If app adds the first frame when power on the screen, delete the code
723      */
724     if (status == ScreenPowerStatus::POWER_STATUS_ON) {
725         auto mainThread = RSMainThread::Instance();
726         if (mainThread == nullptr) {
727             return;
728         }
729         mainThread->SetDirtyFlag();
730         if (screenPowerStatus_.count(id) == 0 || screenPowerStatus_[id] == ScreenPowerStatus::POWER_STATUS_OFF) {
731             mainThread->ForceRefreshForUni();
732         } else {
733             mainThread->RequestNextVSync();
734         }
735 
736         RS_LOGI("RSScreenManager %s: Set system power on, request a frame", __func__);
737     }
738     screenPowerStatus_[id] = status;
739 }
740 
GetVirtualScreenResolution(ScreenId id,RSVirtualScreenResolution & virtualScreenResolution) const741 void RSScreenManager::GetVirtualScreenResolution(ScreenId id, RSVirtualScreenResolution& virtualScreenResolution) const
742 {
743     std::lock_guard<std::mutex> lock(mutex_);
744 
745     GetVirtualScreenResolutionLocked(id, virtualScreenResolution);
746 }
747 
GetScreenActiveMode(ScreenId id,RSScreenModeInfo & screenModeInfo) const748 void RSScreenManager::GetScreenActiveMode(ScreenId id, RSScreenModeInfo& screenModeInfo) const
749 {
750     std::lock_guard<std::mutex> lock(mutex_);
751 
752     GetScreenActiveModeLocked(id, screenModeInfo);
753 }
754 
GetScreenSupportedModes(ScreenId id) const755 std::vector<RSScreenModeInfo> RSScreenManager::GetScreenSupportedModes(ScreenId id) const
756 {
757     std::lock_guard<std::mutex> lock(mutex_);
758 
759     return GetScreenSupportedModesLocked(id);
760 }
761 
GetScreenCapability(ScreenId id) const762 RSScreenCapability RSScreenManager::GetScreenCapability(ScreenId id) const
763 {
764     std::lock_guard<std::mutex> lock(mutex_);
765 
766     return GetScreenCapabilityLocked(id);
767 }
768 
GetScreenPowerStatus(ScreenId id) const769 ScreenPowerStatus RSScreenManager::GetScreenPowerStatus(ScreenId id) const
770 {
771     std::lock_guard<std::mutex> lock(mutex_);
772 
773     return GetScreenPowerStatusLocked(id);
774 }
775 
GetScreenData(ScreenId id) const776 RSScreenData RSScreenManager::GetScreenData(ScreenId id) const
777 {
778     std::lock_guard<std::mutex> lock(mutex_);
779     RSScreenData screenData;
780     if (screens_.count(id) == 0) {
781         RS_LOGW("RSScreenManager %s: There is no screen for id %" PRIu64 ".", __func__, id);
782         return screenData;
783     }
784     RSScreenCapability capability = GetScreenCapabilityLocked(id);
785     RSScreenModeInfo activeMode;
786     GetScreenActiveModeLocked(id, activeMode);
787     std::vector<RSScreenModeInfo> supportModes = GetScreenSupportedModesLocked(id);
788     ScreenPowerStatus powerStatus = GetScreenPowerStatusLocked(id);
789     screenData.SetCapability(capability);
790     screenData.SetActivityModeInfo(activeMode);
791     screenData.SetSupportModeInfo(supportModes);
792     screenData.SetPowerStatus(powerStatus);
793     return screenData;
794 }
795 
GetScreenBacklight(ScreenId id)796 int32_t RSScreenManager::GetScreenBacklight(ScreenId id)
797 {
798     std::lock_guard<std::mutex> lock(mutex_);
799     return GetScreenBacklightLocked(id);
800 }
801 
GetScreenBacklightLocked(ScreenId id) const802 int32_t RSScreenManager::GetScreenBacklightLocked(ScreenId id) const
803 {
804     if (screens_.count(id) == 0) {
805         RS_LOGW("RSScreenManager %s: There is no screen for id %" PRIu64 ".", __func__, id);
806         return INVALID_BACKLIGHT_VALUE;
807     }
808 
809     int32_t level = screens_.at(id)->GetScreenBacklight();
810     return level;
811 }
812 
SetScreenBacklight(ScreenId id,uint32_t level)813 void RSScreenManager::SetScreenBacklight(ScreenId id, uint32_t level)
814 {
815     std::lock_guard<std::mutex> lock(mutex_);
816     if (screens_.count(id) == 0) {
817         RS_LOGW("RSScreenManager %s: There is no screen for id %" PRIu64 ".", __func__, id);
818         return;
819     }
820     screens_.at(id)->SetScreenBacklight(level);
821 }
822 
QueryScreenInfo(ScreenId id) const823 ScreenInfo RSScreenManager::QueryScreenInfo(ScreenId id) const
824 {
825     std::lock_guard<std::mutex> lock(mutex_);
826 
827     ScreenInfo info;
828     if (screens_.count(id) == 0) {
829         RS_LOGW("RSScreenManager %s: There is no screen for id %" PRIu64 ".", __func__, id);
830         return info;
831     }
832 
833     const auto &screen = screens_.at(id);
834     info.id = id;
835     info.width = screen->Width();
836     info.height = screen->Height();
837     auto ret = screen->GetScreenColorGamut(info.colorGamut);
838     if (ret != StatusCode::SUCCESS) {
839         info.colorGamut = COLOR_GAMUT_SRGB;
840     }
841 
842     if (!screen->IsEnable()) {
843         info.state = ScreenState::DISABLED;
844     } else if (!screen->IsVirtual()) {
845         info.state = ScreenState::HDI_OUTPUT_ENABLE;
846     } else {
847         info.state = ScreenState::PRODUCER_SURFACE_ENABLE;
848     }
849     info.skipFrameInterval = screen->GetScreenSkipFrameInterval();
850 
851     return info;
852 }
853 
GetProducerSurface(ScreenId id) const854 sptr<Surface> RSScreenManager::GetProducerSurface(ScreenId id) const
855 {
856     std::lock_guard<std::mutex> lock(mutex_);
857 
858     // assert screens_.count(id) == 1
859     if (screens_.count(id) == 0) {
860         RS_LOGW("RSScreenManager::GetProducerSurface: There is no screen for id %" PRIu64 ".", id);
861         return nullptr;
862     }
863     return screens_.at(id)->GetProducerSurface();
864 }
865 
GetOutput(ScreenId id) const866 std::shared_ptr<HdiOutput> RSScreenManager::GetOutput(ScreenId id) const
867 {
868     std::lock_guard<std::mutex> lock(mutex_);
869 
870     // assert screens_.count(id) == 1
871     if (screens_.count(id) == 0) {
872         RS_LOGW("RSScreenManager::GetOutput: There is no screen for id %" PRIu64 ".", id);
873         return nullptr;
874     }
875     return screens_.at(id)->GetOutput();
876 }
877 
AddScreenChangeCallback(const sptr<RSIScreenChangeCallback> & callback)878 int32_t RSScreenManager::AddScreenChangeCallback(const sptr<RSIScreenChangeCallback> &callback)
879 {
880     if (callback == nullptr) {
881         RS_LOGE("RSScreenManager %s: callback is NULL.", __func__);
882         return INVALID_ARGUMENTS;
883     }
884 
885     std::lock_guard<std::mutex> lock(mutex_);
886     // when the callback first registered, maybe there were some physical screens already connected,
887     // so notify to remote immediately.
888     for (const auto &[id, screen] : screens_) {
889         if (!screen->IsVirtual()) {
890             callback->OnScreenChanged(id, ScreenEvent::CONNECTED);
891         }
892     }
893     screenChangeCallbacks_.push_back(callback);
894     RS_LOGD("RSScreenManager %s: add a remote callback succeed.", __func__);
895     return SUCCESS;
896 }
897 
RemoveScreenChangeCallback(const sptr<RSIScreenChangeCallback> & callback)898 void RSScreenManager::RemoveScreenChangeCallback(const sptr<RSIScreenChangeCallback> &callback)
899 {
900     std::lock_guard<std::mutex> lock(mutex_);
901     for (auto it = screenChangeCallbacks_.begin(); it != screenChangeCallbacks_.end(); it++) {
902         if (*it == callback) {
903             screenChangeCallbacks_.erase(it);
904             RS_LOGD("RSScreenManager %s: remove a remote callback succeed.", __func__);
905             break;
906         }
907     }
908 }
909 
DisplayDump(std::string & dumpString)910 void RSScreenManager::DisplayDump(std::string& dumpString)
911 {
912     int32_t index = 0;
913     for (const auto &[id, screen] : screens_) {
914         screen->DisplayDump(index, dumpString);
915         index++;
916     }
917 }
918 
SurfaceDump(std::string & dumpString)919 void RSScreenManager::SurfaceDump(std::string& dumpString)
920 {
921     int32_t index = 0;
922     for (const auto &[id, screen] : screens_) {
923         screen->SurfaceDump(index, dumpString);
924         index++;
925     }
926 }
927 
FpsDump(std::string & dumpString,std::string & arg)928 void RSScreenManager::FpsDump(std::string& dumpString, std::string& arg)
929 {
930     int32_t index = 0;
931     dumpString += "\n-- The recently fps records info of screens:\n";
932     for (const auto &[id, screen] : screens_) {
933         screen->FpsDump(index, dumpString, arg);
934         index++;
935     }
936 }
937 
ClearFpsDump(std::string & dumpString,std::string & arg)938 void RSScreenManager::ClearFpsDump(std::string& dumpString, std::string& arg)
939 {
940     int32_t index = 0;
941     dumpString += "\n-- Clear fps records info of screens:\n";
942     for (const auto &[id, screen] : screens_) {
943         screen->ClearFpsDump(index, dumpString, arg);
944         index++;
945     }
946 }
947 
GetScreenSupportedColorGamutsLocked(ScreenId id,std::vector<ScreenColorGamut> & mode) const948 int32_t RSScreenManager::GetScreenSupportedColorGamutsLocked(ScreenId id, std::vector<ScreenColorGamut>& mode) const
949 {
950     if (screens_.count(id) == 0) {
951         RS_LOGW("RSScreenManager %s: There is no screen for id %" PRIu64 ".", __func__, id);
952         return StatusCode::SCREEN_NOT_FOUND;
953     }
954     return screens_.at(id)->GetScreenSupportedColorGamuts(mode);
955 }
956 
GetScreenSupportedMetaDataKeysLocked(ScreenId id,std::vector<ScreenHDRMetadataKey> & keys) const957 int32_t RSScreenManager::GetScreenSupportedMetaDataKeysLocked(
958     ScreenId id, std::vector<ScreenHDRMetadataKey>& keys) const
959 {
960     if (screens_.count(id) == 0) {
961         RS_LOGW("RSScreenManager %s: There is no screen for id %" PRIu64 ".", __func__, id);
962         return StatusCode::SCREEN_NOT_FOUND;
963     }
964     return screens_.at(id)->GetScreenSupportedMetaDataKeys(keys);
965 }
966 
GetScreenColorGamutLocked(ScreenId id,ScreenColorGamut & mode) const967 int32_t RSScreenManager::GetScreenColorGamutLocked(ScreenId id, ScreenColorGamut& mode) const
968 {
969     if (screens_.count(id) == 0) {
970         RS_LOGW("RSScreenManager %s: There is no screen for id %" PRIu64 ".", __func__, id);
971         return StatusCode::SCREEN_NOT_FOUND;
972     }
973     return screens_.at(id)->GetScreenColorGamut(mode);
974 }
975 
SetScreenColorGamutLocked(ScreenId id,int32_t modeIdx)976 int32_t RSScreenManager::SetScreenColorGamutLocked(ScreenId id, int32_t modeIdx)
977 {
978     if (screens_.count(id) == 0) {
979         RS_LOGW("RSScreenManager %s: There is no screen for id %" PRIu64 ".", __func__, id);
980         return StatusCode::SCREEN_NOT_FOUND;
981     }
982     return screens_.at(id)->SetScreenColorGamut(modeIdx);
983 }
984 
SetScreenGamutMapLocked(ScreenId id,ScreenGamutMap mode)985 int32_t RSScreenManager::SetScreenGamutMapLocked(ScreenId id, ScreenGamutMap mode)
986 {
987     if (screens_.count(id) == 0) {
988         RS_LOGW("RSScreenManager %s: There is no screen for id %" PRIu64 ".", __func__, id);
989         return StatusCode::SCREEN_NOT_FOUND;
990     }
991     return screens_.at(id)->SetScreenGamutMap(mode);
992 }
993 
GetScreenGamutMapLocked(ScreenId id,ScreenGamutMap & mode) const994 int32_t RSScreenManager::GetScreenGamutMapLocked(ScreenId id, ScreenGamutMap &mode) const
995 {
996     if (screens_.count(id) == 0) {
997         RS_LOGW("RSScreenManager %s: There is no screen for id %" PRIu64 ".", __func__, id);
998         return StatusCode::SCREEN_NOT_FOUND;
999     }
1000     return screens_.at(id)->GetScreenGamutMap(mode);
1001 }
1002 
GetScreenHDRCapabilityLocked(ScreenId id,RSScreenHDRCapability & screenHdrCapability) const1003 int32_t RSScreenManager::GetScreenHDRCapabilityLocked(ScreenId id, RSScreenHDRCapability& screenHdrCapability) const
1004 {
1005     if (screens_.count(id) == 0) {
1006         RS_LOGW("RSScreenManager %s: There is no screen for id %" PRIu64 ".", __func__, id);
1007         return StatusCode::SCREEN_NOT_FOUND;
1008     }
1009     GraphicHDRCapability hdrCapability = screens_.at(id)->GetHDRCapability();
1010     std::vector<ScreenHDRFormat> hdrFormats;
1011     uint32_t formatCount = hdrCapability.formatCount;
1012     hdrFormats.resize(formatCount);
1013     for (uint32_t index = 0; index < formatCount; index++) {
1014         hdrFormats[index] = static_cast<ScreenHDRFormat>(hdrCapability.formats[index]);
1015     }
1016     screenHdrCapability.SetMaxLum(hdrCapability.maxLum);
1017     screenHdrCapability.SetMaxAverageLum(hdrCapability.maxAverageLum);
1018     screenHdrCapability.SetMinLum(hdrCapability.minLum);
1019     screenHdrCapability.SetHdrFormats(hdrFormats);
1020     return StatusCode::SUCCESS;
1021 }
1022 
GetScreenTypeLocked(ScreenId id,RSScreenType & type) const1023 int32_t RSScreenManager::GetScreenTypeLocked(ScreenId id, RSScreenType& type) const
1024 {
1025     if (screens_.count(id) == 0) {
1026         RS_LOGW("RSScreenManager %s: There is no screen for id %" PRIu64 ".", __func__, id);
1027         return StatusCode::SCREEN_NOT_FOUND;
1028     }
1029 
1030     type = screens_.at(id)->GetScreenType();
1031     return StatusCode::SUCCESS;
1032 }
1033 
SetScreenSkipFrameIntervalLocked(ScreenId id,uint32_t skipFrameInterval)1034 int32_t RSScreenManager::SetScreenSkipFrameIntervalLocked(ScreenId id, uint32_t skipFrameInterval)
1035 {
1036     if (screens_.count(id) == 0) {
1037         RS_LOGW("RSScreenManager %s: There is no screen for id %" PRIu64 ".", __func__, id);
1038         return StatusCode::SCREEN_NOT_FOUND;
1039     }
1040     RSScreenModeInfo screenModeInfo;
1041     // use the refresh rate of the physical screen as the maximum refresh rate
1042     GetScreenActiveModeLocked(defaultScreenId_, screenModeInfo);
1043     // guaranteed screen refresh rate at least 1
1044     if (skipFrameInterval == 0 || (skipFrameInterval > screenModeInfo.GetScreenRefreshRate())) {
1045         return INVALID_ARGUMENTS;
1046     }
1047     screens_.at(id)->SetScreenSkipFrameInterval(skipFrameInterval);
1048     RS_LOGD("RSScreenManager %s: screen(id %" PRIu64 "), skipFrameInterval(%d).",
1049         __func__, id, skipFrameInterval);
1050     return StatusCode::SUCCESS;
1051 }
1052 
GetScreenSupportedColorGamuts(ScreenId id,std::vector<ScreenColorGamut> & mode) const1053 int32_t RSScreenManager::GetScreenSupportedColorGamuts(ScreenId id, std::vector<ScreenColorGamut>& mode) const
1054 {
1055     std::lock_guard<std::mutex> lock(mutex_);
1056     return GetScreenSupportedColorGamutsLocked(id, mode);
1057 }
1058 
GetScreenSupportedMetaDataKeys(ScreenId id,std::vector<ScreenHDRMetadataKey> & keys) const1059 int32_t RSScreenManager::GetScreenSupportedMetaDataKeys(ScreenId id, std::vector<ScreenHDRMetadataKey>& keys) const
1060 {
1061     std::lock_guard<std::mutex> lock(mutex_);
1062     return GetScreenSupportedMetaDataKeysLocked(id, keys);
1063 }
1064 
GetScreenColorGamut(ScreenId id,ScreenColorGamut & mode) const1065 int32_t RSScreenManager::GetScreenColorGamut(ScreenId id, ScreenColorGamut &mode) const
1066 {
1067     std::lock_guard<std::mutex> lock(mutex_);
1068     return GetScreenColorGamutLocked(id, mode);
1069 }
1070 
SetScreenColorGamut(ScreenId id,int32_t modeIdx)1071 int32_t RSScreenManager::SetScreenColorGamut(ScreenId id, int32_t modeIdx)
1072 {
1073     std::lock_guard<std::mutex> lock(mutex_);
1074     return SetScreenColorGamutLocked(id, modeIdx);
1075 }
1076 
SetScreenGamutMap(ScreenId id,ScreenGamutMap mode)1077 int32_t RSScreenManager::SetScreenGamutMap(ScreenId id, ScreenGamutMap mode)
1078 {
1079     std::lock_guard<std::mutex> lock(mutex_);
1080     return SetScreenGamutMapLocked(id, mode);
1081 }
1082 
GetScreenGamutMap(ScreenId id,ScreenGamutMap & mode) const1083 int32_t RSScreenManager::GetScreenGamutMap(ScreenId id, ScreenGamutMap &mode) const
1084 {
1085     std::lock_guard<std::mutex> lock(mutex_);
1086     return GetScreenGamutMapLocked(id, mode);
1087 }
1088 
GetScreenHDRCapability(ScreenId id,RSScreenHDRCapability & screenHdrCapability) const1089 int32_t RSScreenManager::GetScreenHDRCapability(ScreenId id, RSScreenHDRCapability& screenHdrCapability) const
1090 {
1091     std::lock_guard<std::mutex> lock(mutex_);
1092     return GetScreenHDRCapabilityLocked(id, screenHdrCapability);
1093 }
1094 
GetScreenType(ScreenId id,RSScreenType & type) const1095 int32_t RSScreenManager::GetScreenType(ScreenId id, RSScreenType& type) const
1096 {
1097     std::lock_guard<std::mutex> lock(mutex_);
1098     return GetScreenTypeLocked(id, type);
1099 }
1100 
SetScreenSkipFrameInterval(ScreenId id,uint32_t skipFrameInterval)1101 int32_t RSScreenManager::SetScreenSkipFrameInterval(ScreenId id, uint32_t skipFrameInterval)
1102 {
1103     std::lock_guard<std::mutex> lock(mutex_);
1104     return SetScreenSkipFrameIntervalLocked(id, skipFrameInterval);
1105 }
1106 } // namespace impl
1107 
CreateOrGetScreenManager()1108 sptr<RSScreenManager> CreateOrGetScreenManager()
1109 {
1110     return impl::RSScreenManager::GetInstance();
1111 }
1112 } // namespace Rosen
1113 } // namespace OHOS
1114