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