1 /*
2 * Copyright (c) 2021 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 #include "pipeline/rs_main_thread.h"
18
19 namespace OHOS {
20 namespace Rosen {
21 using namespace HiviewDFX;
22 namespace impl {
23 std::once_flag RSScreenManager::createFlag_;
24 sptr<OHOS::Rosen::RSScreenManager> RSScreenManager::instance_ = nullptr;
25
GetInstance()26 sptr<OHOS::Rosen::RSScreenManager> RSScreenManager::GetInstance() noexcept
27 {
28 std::call_once(createFlag_, []() {
29 instance_ = new RSScreenManager();
30 });
31
32 return instance_;
33 }
34
RSScreenManager()35 RSScreenManager::RSScreenManager()
36 {
37 }
38
~RSScreenManager()39 RSScreenManager::~RSScreenManager() noexcept
40 {
41 }
42
Init()43 bool RSScreenManager::Init() noexcept
44 {
45 composer_ = HdiBackend::GetInstance();
46 if (composer_ == nullptr) {
47 HiLog::Error(LOG_LABEL, "%{public}s: Failed to get composer.", __func__);
48 return false;
49 }
50
51 if (composer_->RegScreenHotplug(&RSScreenManager::OnHotPlug, this) == -1) {
52 HiLog::Error(LOG_LABEL, "%{public}s: Failed to register OnHotPlug Func to composer.", __func__);
53 return false;
54 }
55
56 // call ProcessScreenHotPlugEvents() for primary screen immediately in main thread.
57 ProcessScreenHotPlugEvents();
58
59 return true;
60 }
61
OnHotPlug(std::shared_ptr<HdiOutput> & output,bool connected,void * data)62 void RSScreenManager::OnHotPlug(std::shared_ptr<HdiOutput> &output, bool connected, void *data)
63 {
64 if (output == nullptr) {
65 HiLog::Error(LOG_LABEL, "%{public}s: output is nullptr.", __func__);
66 return;
67 }
68
69 RSScreenManager *screenManager = nullptr;
70 if (data != nullptr) {
71 screenManager = static_cast<RSScreenManager *>(data);
72 } else {
73 screenManager = static_cast<RSScreenManager *>(RSScreenManager::GetInstance().GetRefPtr());
74 }
75
76 if (screenManager == nullptr) {
77 HiLog::Error(LOG_LABEL, "%{public}s: Failed to find RSScreenManager instance.", __func__);
78 return;
79 }
80
81 screenManager->OnHotPlugEvent(output, connected);
82 }
83
OnHotPlugEvent(std::shared_ptr<HdiOutput> & output,bool connected)84 void RSScreenManager::OnHotPlugEvent(std::shared_ptr<HdiOutput> &output, bool connected)
85 {
86 {
87 std::lock_guard<std::mutex> lock(mutex_);
88 pendingHotPlugEvents_.emplace_back(ScreenHotPlugEvent{output, connected});
89 }
90
91 // This func would be called in main thread first time immediately after calling composer_->RegScreenHotplug,
92 // but at this time the RSMainThread object would not be ready to handle this, so we need to call
93 // ProcessScreenHotPlugEvents() after this func in RSScreenManager::Init().
94
95 // Normally, this func would be called in hdi's hw-ipc threads(but sometimes in main thread, maybe),
96 // so we should notify the RSMainThread to postTask to call ProcessScreenHotPlugEvents().
97 auto mainThread = RSMainThread::Instance();
98 if (mainThread == nullptr) {
99 return;
100 }
101 mainThread->RequestNextVSync();
102 }
103
ProcessScreenHotPlugEvents()104 void RSScreenManager::ProcessScreenHotPlugEvents()
105 {
106 std::lock_guard<std::mutex> lock(mutex_);
107 for (auto &event : pendingHotPlugEvents_) {
108 if (event.connected) {
109 ProcessScreenConnectedLocked(event.output);
110 } else {
111 ProcessScreenDisConnectedLocked(event.output);
112 }
113 }
114
115 pendingHotPlugEvents_.clear();
116 }
117
ProcessScreenConnectedLocked(std::shared_ptr<HdiOutput> & output)118 void RSScreenManager::ProcessScreenConnectedLocked(std::shared_ptr<HdiOutput> &output)
119 {
120 if (output == nullptr) {
121 HiLog::Error(LOG_LABEL, "%{public}s: output is nullptr.", __func__);
122 return;
123 }
124
125 bool isVirtual = false;
126 ScreenId id = ToScreenId(output->GetScreenId());
127 if (defaultScreenId_ == INVALID_SCREEN_ID) {
128 defaultScreenId_ = id;
129 }
130
131 if (screens_.count(id) == 1) {
132 HiLog::Warn(LOG_LABEL, "%{public}s: The screen for id %{public}" PRIu64 " already existed.", __func__, id);
133
134 // [PLANNING]: should we erase it and create a new one?
135 for (auto &cb : screenChangeCallbacks_) {
136 cb->OnScreenChanged(id, ScreenEvent::DISCONNECTED);
137 }
138 screens_.erase(id);
139 }
140
141 screens_[id] = std::make_unique<RSScreen>(id, isVirtual, output, nullptr);
142 HiLog::Info(LOG_LABEL, "%{public}s: A new screen(id %{public}" PRIu64 ") connected.", __func__, id);
143 for (auto &cb : screenChangeCallbacks_) {
144 cb->OnScreenChanged(id, ScreenEvent::CONNECTED);
145 }
146 }
147
ProcessScreenDisConnectedLocked(std::shared_ptr<HdiOutput> & output)148 void RSScreenManager::ProcessScreenDisConnectedLocked(std::shared_ptr<HdiOutput> &output)
149 {
150 ScreenId id = ToScreenId(output->GetScreenId());
151
152 if (screens_.count(id) == 0) {
153 HiLog::Warn(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
154 } else {
155 for (auto &cb : screenChangeCallbacks_) {
156 cb->OnScreenChanged(id, ScreenEvent::DISCONNECTED);
157 }
158 screens_.erase(id);
159 HiLog::Info(LOG_LABEL, "%{public}s: Screen(id %{public}" PRIu64 ") disconnected.", __func__, id);
160 }
161
162 if (id == defaultScreenId_) {
163 HandleDefaultScreenDisConnectedLocked();
164 }
165 }
166
167 // If the previous primary screen disconnected, we traversal the left screens
168 // and find the first physical screen to be the default screen.
169 // If there was no physical screen left, we set the first screen as default, no matter what type it is.
170 // At last, if no screen left, we set Default Screen Id to INVALID_SCREEN_ID.
HandleDefaultScreenDisConnectedLocked()171 void RSScreenManager::HandleDefaultScreenDisConnectedLocked()
172 {
173 defaultScreenId_ = INVALID_SCREEN_ID;
174 for (const auto &[id, screen] : screens_) {
175 if (!screen->IsVirtual()) {
176 defaultScreenId_ = id;
177 break;
178 }
179 }
180
181 if (defaultScreenId_ == INVALID_SCREEN_ID) {
182 if (!screens_.empty()) {
183 defaultScreenId_ = screens_.cbegin()->first;
184 }
185 }
186 }
187
SetDefaultScreenId(ScreenId id)188 void RSScreenManager::SetDefaultScreenId(ScreenId id)
189 {
190 std::lock_guard<std::mutex> lock(mutex_);
191 defaultScreenId_ = id;
192 }
193
SetScreenMirror(ScreenId id,ScreenId toMirror)194 void RSScreenManager::SetScreenMirror(ScreenId id, ScreenId toMirror)
195 {
196 std::lock_guard<std::mutex> lock(mutex_);
197
198 if (screens_.count(id) == 0) {
199 HiLog::Warn(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
200 return;
201 }
202
203 screens_[id]->SetMirror(toMirror);
204 }
205
GenerateVirtualScreenIdLocked()206 ScreenId RSScreenManager::GenerateVirtualScreenIdLocked()
207 {
208 if (!freeVirtualScreenIds_.empty()) {
209 ScreenId id = freeVirtualScreenIds_.front();
210 freeVirtualScreenIds_.pop();
211 return id;
212 }
213
214 // The left 32 bits is for virtual screen id.
215 return (static_cast<ScreenId>(maxVirtualScreenNum_++) << 32) | 0xffffffffu;
216 }
217
ReuseVirtualScreenIdLocked(ScreenId id)218 void RSScreenManager::ReuseVirtualScreenIdLocked(ScreenId id)
219 {
220 freeVirtualScreenIds_.push(id);
221 }
222
GetScreenActiveModeLocked(ScreenId id,RSScreenModeInfo & screenModeInfo) const223 void RSScreenManager::GetScreenActiveModeLocked(ScreenId id, RSScreenModeInfo& screenModeInfo) const
224 {
225 if (screens_.count(id) == 0) {
226 HiLog::Error(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
227 return;
228 }
229
230 auto modeInfo = screens_.at(id)->GetActiveMode();
231 if (!modeInfo) {
232 HiLog::Error(LOG_LABEL, "%{public}s: Failed to get active mode for screen %{public}" PRIu64 ".", __func__, id);
233 return;
234 }
235
236 screenModeInfo.SetScreenWidth(modeInfo->width);
237 screenModeInfo.SetScreenHeight(modeInfo->height);
238 screenModeInfo.SetScreenRefreshRate(modeInfo->freshRate);
239 screenModeInfo.SetScreenModeId(screens_.at(id)->GetActiveModePosByModeId(modeInfo->id));
240 }
241
GetScreenSupportedModesLocked(ScreenId id) const242 std::vector<RSScreenModeInfo> RSScreenManager::GetScreenSupportedModesLocked(ScreenId id) const
243 {
244 std::vector<RSScreenModeInfo> screenSupportedModes;
245 if (screens_.count(id) == 0) {
246 HiLog::Error(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
247 return screenSupportedModes;
248 }
249
250 const auto& displaySupportedModes = screens_.at(id)->GetSupportedModes();
251 screenSupportedModes.resize(displaySupportedModes.size());
252 for (decltype(displaySupportedModes.size()) idx = 0; idx < displaySupportedModes.size(); ++idx) {
253 screenSupportedModes[idx].SetScreenWidth(displaySupportedModes[idx].width);
254 screenSupportedModes[idx].SetScreenHeight(displaySupportedModes[idx].height);
255 screenSupportedModes[idx].SetScreenRefreshRate(displaySupportedModes[idx].freshRate);
256 screenSupportedModes[idx].SetScreenModeId(displaySupportedModes[idx].id);
257 }
258 return screenSupportedModes;
259 }
260
GetScreenCapabilityLocked(ScreenId id) const261 RSScreenCapability RSScreenManager::GetScreenCapabilityLocked(ScreenId id) const
262 {
263 RSScreenCapability screenCapability;
264 if (screens_.count(id) == 0) {
265 HiLog::Error(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".\n", __func__, id);
266 return screenCapability;
267 }
268 if (screens_.at(id)->IsVirtual()) {
269 HiLog::Warn(LOG_LABEL, "%{public}s: only name attribute is valid for virtual screen.\n", __func__);
270 screenCapability.SetName(screens_.at(id)->Name());
271 return screenCapability;
272 }
273
274 const auto& capability = screens_.at(id)->GetCapability();
275 std::vector<RSScreenProps> props;
276 uint32_t propCount = capability.propertyCount;
277 props.resize(propCount);
278 for (uint32_t propIndex = 0; propIndex < propCount; propIndex++) {
279 props[propIndex] = RSScreenProps(capability.props[propIndex].name, capability.props[propIndex].propId,
280 capability.props[propIndex].value);
281 }
282 screenCapability.SetName(capability.name);
283 screenCapability.SetType(static_cast<ScreenInterfaceType>(capability.type));
284 screenCapability.SetPhyWidth(capability.phyWidth);
285 screenCapability.SetPhyHeight(capability.phyHeight);
286 screenCapability.SetSupportLayers(capability.supportLayers);
287 screenCapability.SetVirtualDispCount(capability.virtualDispCount);
288 screenCapability.SetSupportWriteback(capability.supportWriteBack);
289 screenCapability.SetProps(props);
290 return screenCapability;
291 }
292
GetScreenPowerStatuslocked(ScreenId id) const293 ScreenPowerStatus RSScreenManager::GetScreenPowerStatuslocked(ScreenId id) const
294 {
295 if (screens_.count(id) == 0) {
296 HiLog::Error(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".\n", __func__, id);
297 return INVALID_POWER_STATUS;
298 }
299
300 ScreenPowerStatus status = static_cast<ScreenPowerStatus>(screens_.at(id)->GetPowerStatus());
301 return status;
302 }
303
CreateVirtualScreen(const std::string & name,uint32_t width,uint32_t height,sptr<Surface> surface,ScreenId mirrorId,int32_t flags)304 ScreenId RSScreenManager::CreateVirtualScreen(
305 const std::string &name,
306 uint32_t width,
307 uint32_t height,
308 sptr<Surface> surface,
309 ScreenId mirrorId,
310 int32_t flags
311 )
312 {
313 std::lock_guard<std::mutex> lock(mutex_);
314
315 if (surface != nullptr) {
316 uint64_t surfaceId = surface->GetUniqueId();
317 for (auto &[_, screen] : screens_) {
318 if (!screen->IsVirtual()) {
319 continue;
320 }
321 auto screenSurface = screen->GetProducerSurface();
322 if (screenSurface == nullptr) {
323 continue;
324 }
325 if (screenSurface->GetUniqueId() == surfaceId) {
326 HiLog::Error(LOG_LABEL, "surface %{public}" PRIu64 " is used, create virtualscreen failed!", surfaceId);
327 return INVALID_SCREEN_ID;
328 }
329 }
330 } else {
331 HiLog::Debug(LOG_LABEL, "%{public}s: surface is nullptr.\n", __func__);
332 }
333
334 VirtualScreenConfigs configs;
335 ScreenId newId = GenerateVirtualScreenIdLocked();
336 configs.id = newId;
337 configs.mirrorId = mirrorId;
338 configs.name = name;
339 configs.width = width;
340 configs.height = height;
341 configs.surface = surface;
342 configs.flags = flags;
343
344 screens_[newId] = std::make_unique<RSScreen>(configs);
345 HiLog::Debug(LOG_LABEL, "%{public}s: create virtual screen(id %{public}" PRIu64 ").\n", __func__, newId);
346 return newId;
347 }
348
SetVirtualScreenSurface(ScreenId id,sptr<Surface> surface)349 int32_t RSScreenManager::SetVirtualScreenSurface(ScreenId id, sptr<Surface> surface)
350 {
351 uint64_t surfaceId = surface->GetUniqueId();
352 for (auto &[screenId, screen] : screens_) {
353 if (!screen->IsVirtual() || screenId == id) {
354 continue;
355 }
356 auto screenSurface = screen->GetProducerSurface();
357 if (screenSurface == nullptr) {
358 continue;
359 }
360 if (screenSurface->GetUniqueId() == surface->GetUniqueId()) {
361 HiLog::Error(LOG_LABEL, "surface %{public}" PRIu64 " is used, set surface failed!", surfaceId);
362 return SURFACE_NOT_UNIQUE;
363 }
364 }
365 screens_.at(id)->SetProducerSurface(surface);
366 HiLog::Debug(LOG_LABEL, "%{public}s: set virtual screen surface success! \n", __func__);
367 return SUCCESS;
368 }
369
RemoveVirtualScreen(ScreenId id)370 void RSScreenManager::RemoveVirtualScreen(ScreenId id)
371 {
372 std::lock_guard<std::mutex> lock(mutex_);
373
374 RemoveVirtualScreenLocked(id);
375 }
376
RemoveVirtualScreenLocked(ScreenId id)377 void RSScreenManager::RemoveVirtualScreenLocked(ScreenId id)
378 {
379 if (screens_.count(id) == 0) {
380 HiLog::Warn(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
381 return;
382 }
383
384 screens_.erase(id);
385
386 // Update other screens' mirrorId.
387 for (auto &[id, screen] : screens_) {
388 if (screen->MirrorId() == id) {
389 screen->SetMirror(INVALID_SCREEN_ID);
390 }
391 }
392 HiLog::Debug(LOG_LABEL, "%{public}s: remove virtual screen(id %{public}" PRIu64 ").\n", __func__, id);
393
394 ReuseVirtualScreenIdLocked(id);
395 }
396
SetScreenActiveMode(ScreenId id,uint32_t modeId)397 void RSScreenManager::SetScreenActiveMode(ScreenId id, uint32_t modeId)
398 {
399 std::lock_guard<std::mutex> lock(mutex_);
400
401 if (screens_.count(id) == 0) {
402 HiLog::Error(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".\n", __func__, id);
403 return;
404 }
405 screens_.at(id)->SetActiveMode(modeId);
406 }
407
SetScreenPowerStatus(ScreenId id,ScreenPowerStatus status)408 void RSScreenManager::SetScreenPowerStatus(ScreenId id, ScreenPowerStatus status)
409 {
410 std::lock_guard<std::mutex> lock(mutex_);
411
412 if (screens_.count(id) == 0) {
413 HiLog::Error(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".\n", __func__, id);
414 return;
415 }
416 screens_.at(id)->SetPowerStatus(static_cast<uint32_t>(status));
417
418 /*
419 * If app adds the first frame when power on the screen, delete the code
420 */
421 if (status == ScreenPowerStatus::POWER_STATUS_ON) {
422 auto mainThread = RSMainThread::Instance();
423 if (mainThread == nullptr) {
424 return;
425 }
426 mainThread->RequestNextVSync();
427 HiLog::Info(LOG_LABEL, "Set system power on, request a frame");
428 }
429 }
430
GetScreenActiveMode(ScreenId id,RSScreenModeInfo & screenModeInfo) const431 void RSScreenManager::GetScreenActiveMode(ScreenId id, RSScreenModeInfo& screenModeInfo) const
432 {
433 std::lock_guard<std::mutex> lock(mutex_);
434
435 GetScreenActiveModeLocked(id, screenModeInfo);
436 }
437
GetScreenSupportedModes(ScreenId id) const438 std::vector<RSScreenModeInfo> RSScreenManager::GetScreenSupportedModes(ScreenId id) const
439 {
440 std::lock_guard<std::mutex> lock(mutex_);
441
442 return GetScreenSupportedModesLocked(id);
443 }
444
GetScreenCapability(ScreenId id) const445 RSScreenCapability RSScreenManager::GetScreenCapability(ScreenId id) const
446 {
447 std::lock_guard<std::mutex> lock(mutex_);
448
449 return GetScreenCapabilityLocked(id);
450 }
451
GetScreenPowerStatus(ScreenId id) const452 ScreenPowerStatus RSScreenManager::GetScreenPowerStatus(ScreenId id) const
453 {
454 std::lock_guard<std::mutex> lock(mutex_);
455
456 return GetScreenPowerStatuslocked(id);
457 }
458
GetScreenData(ScreenId id) const459 RSScreenData RSScreenManager::GetScreenData(ScreenId id) const
460 {
461 std::lock_guard<std::mutex> lock(mutex_);
462 RSScreenData screenData;
463 if (screens_.count(id) == 0) {
464 HiLog::Error(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".\n", __func__, id);
465 return screenData;
466 }
467 RSScreenCapability capability = GetScreenCapabilityLocked(id);
468 RSScreenModeInfo activeMode;
469 GetScreenActiveModeLocked(id, activeMode);
470 std::vector<RSScreenModeInfo> supportModes = GetScreenSupportedModesLocked(id);
471 ScreenPowerStatus powerStatus = GetScreenPowerStatuslocked(id);
472 screenData.SetCapability(capability);
473 screenData.SetActivityModeInfo(activeMode);
474 screenData.SetSupportModeInfo(supportModes);
475 screenData.SetPowerStatus(powerStatus);
476 return screenData;
477 }
478
GetScreenBacklight(ScreenId id)479 int32_t RSScreenManager::GetScreenBacklight(ScreenId id)
480 {
481 std::lock_guard<std::mutex> lock(mutex_);
482 return GetScreenBacklightlocked(id);
483 }
484
GetScreenBacklightlocked(ScreenId id) const485 int32_t RSScreenManager::GetScreenBacklightlocked(ScreenId id) const
486 {
487 if (screens_.count(id) == 0) {
488 HiLog::Error(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".\n", __func__, id);
489 return INVALID_BACKLIGHT_VALUE;
490 }
491
492 int32_t level = screens_.at(id)->GetScreenBacklight();
493 return level;
494 }
495
SetScreenBacklight(ScreenId id,uint32_t level)496 void RSScreenManager::SetScreenBacklight(ScreenId id, uint32_t level)
497 {
498 std::lock_guard<std::mutex> lock(mutex_);
499 if (screens_.count(id) == 0) {
500 HiLog::Error(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".\n", __func__, id);
501 return;
502 }
503 screens_.at(id)->SetScreenBacklight(level);
504 }
505
QueryScreenInfo(ScreenId id) const506 ScreenInfo RSScreenManager::QueryScreenInfo(ScreenId id) const
507 {
508 std::lock_guard<std::mutex> lock(mutex_);
509
510 ScreenInfo info;
511 if (screens_.count(id) == 0) {
512 HiLog::Error(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".", __func__, id);
513 return info;
514 }
515
516 const auto &screen = screens_.at(id);
517
518 info.width = screen->Width();
519 info.height = screen->Height();
520 (void)screen->GetScreenColorGamut(info.colorGamut);
521
522 if (!screen->IsEnable()) {
523 info.state = ScreenState::DISABLED;
524 } else if (!screen->IsVirtual()) {
525 info.state = ScreenState::HDI_OUTPUT_ENABLE;
526 } else {
527 info.state = ScreenState::PRODUCER_SURFACE_ENABLE;
528 }
529 info.rotationMatrix = screen->GetRotationMatrix();
530
531 return info;
532 }
533
GetProducerSurface(ScreenId id) const534 sptr<Surface> RSScreenManager::GetProducerSurface(ScreenId id) const
535 {
536 std::lock_guard<std::mutex> lock(mutex_);
537
538 // assert screens_.count(id) == 1
539 return screens_.at(id)->GetProducerSurface();
540 }
541
GetOutput(ScreenId id) const542 std::shared_ptr<HdiOutput> RSScreenManager::GetOutput(ScreenId id) const
543 {
544 std::lock_guard<std::mutex> lock(mutex_);
545
546 // assert screens_.count(id) == 1
547 return screens_.at(id)->GetOutput();
548 }
549
AddScreenChangeCallback(const sptr<RSIScreenChangeCallback> & callback)550 int32_t RSScreenManager::AddScreenChangeCallback(const sptr<RSIScreenChangeCallback> &callback)
551 {
552 if (callback == nullptr) {
553 HiLog::Error(LOG_LABEL, "%{public}s: callback is NULL.", __func__);
554 return INVALID_ARGUMENTS;
555 }
556
557 std::lock_guard<std::mutex> lock(mutex_);
558 // when the callback first registered, maybe there were some physical screens already connected,
559 // so notify to remote immediately.
560 for (const auto &[id, screen] : screens_) {
561 if (!screen->IsVirtual()) {
562 callback->OnScreenChanged(id, ScreenEvent::CONNECTED);
563 }
564 }
565 screenChangeCallbacks_.push_back(callback);
566 HiLog::Debug(LOG_LABEL, "%{public}s: add a remote callback succeed.", __func__);
567 return SUCCESS;
568 }
569
RemoveScreenChangeCallback(const sptr<RSIScreenChangeCallback> & callback)570 void RSScreenManager::RemoveScreenChangeCallback(const sptr<RSIScreenChangeCallback> &callback)
571 {
572 std::lock_guard<std::mutex> lock(mutex_);
573 for (auto it = screenChangeCallbacks_.begin(); it != screenChangeCallbacks_.end(); it++) {
574 if (*it == callback) {
575 screenChangeCallbacks_.erase(it);
576 HiLog::Debug(LOG_LABEL, "%{public}s: remove a remote callback succeed.", __func__);
577 break;
578 }
579 }
580 }
581
DisplayDump(std::string & dumpString)582 void RSScreenManager::DisplayDump(std::string& dumpString)
583 {
584 int32_t index = 0;
585 for (const auto &[id, screen] : screens_) {
586 screen->DisplayDump(index, dumpString);
587 index++;
588 }
589 }
590
SurfaceDump(std::string & dumpString)591 void RSScreenManager::SurfaceDump(std::string& dumpString)
592 {
593 int32_t index = 0;
594 for (const auto &[id, screen] : screens_) {
595 screen->SurfaceDump(index, dumpString);
596 index++;
597 }
598 }
599
FpsDump(std::string & dumpString,std::string & arg)600 void RSScreenManager::FpsDump(std::string& dumpString, std::string& arg)
601 {
602 int32_t index = 0;
603 for (const auto &[id, screen] : screens_) {
604 screen->FpsDump(index, dumpString, arg);
605 index++;
606 }
607 }
608
GetScreenSupportedColorGamutsLocked(ScreenId id,std::vector<ScreenColorGamut> & mode) const609 int32_t RSScreenManager::GetScreenSupportedColorGamutsLocked(ScreenId id, std::vector<ScreenColorGamut>& mode) const
610 {
611 if (screens_.count(id) == 0) {
612 HiLog::Error(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".\n", __func__, id);
613 return StatusCode::SCREEN_NOT_FOUND;
614 }
615 return screens_.at(id)->GetScreenSupportedColorGamuts(mode);
616 }
617
GetScreenColorGamutLocked(ScreenId id,ScreenColorGamut & mode) const618 int32_t RSScreenManager::GetScreenColorGamutLocked(ScreenId id, ScreenColorGamut& mode) const
619 {
620 if (screens_.count(id) == 0) {
621 HiLog::Error(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".\n", __func__, id);
622 return StatusCode::SCREEN_NOT_FOUND;
623 }
624 return screens_.at(id)->GetScreenColorGamut(mode);
625 }
626
SetScreenColorGamutLocked(ScreenId id,int32_t modeIdx)627 int32_t RSScreenManager::SetScreenColorGamutLocked(ScreenId id, int32_t modeIdx)
628 {
629 if (screens_.count(id) == 0) {
630 HiLog::Error(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".\n", __func__, id);
631 return StatusCode::SCREEN_NOT_FOUND;
632 }
633 return screens_.at(id)->SetScreenColorGamut(modeIdx);
634 }
635
SetScreenGamutMapLocked(ScreenId id,ScreenGamutMap mode)636 int32_t RSScreenManager::SetScreenGamutMapLocked(ScreenId id, ScreenGamutMap mode)
637 {
638 if (screens_.count(id) == 0) {
639 HiLog::Error(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".\n", __func__, id);
640 return StatusCode::SCREEN_NOT_FOUND;
641 }
642 return screens_.at(id)->SetScreenGamutMap(mode);
643 }
644
GetScreenGamutMapLocked(ScreenId id,ScreenGamutMap & mode) const645 int32_t RSScreenManager::GetScreenGamutMapLocked(ScreenId id, ScreenGamutMap &mode) const
646 {
647 if (screens_.count(id) == 0) {
648 HiLog::Error(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".\n", __func__, id);
649 return StatusCode::SCREEN_NOT_FOUND;
650 }
651 return screens_.at(id)->GetScreenGamutMap(mode);
652 }
653
RequestRotationLocked(ScreenId id,ScreenRotation rotation)654 bool RSScreenManager::RequestRotationLocked(ScreenId id, ScreenRotation rotation)
655 {
656 auto iter = screens_.find(id);
657 if (iter == screens_.end()) {
658 HiLog::Error(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".\n", __func__, id);
659 return false;
660 }
661 return iter->second->SetRotation(rotation);
662 }
663
GetRotationLocked(ScreenId id) const664 ScreenRotation RSScreenManager::GetRotationLocked(ScreenId id) const
665 {
666 auto iter = screens_.find(id);
667 if (iter == screens_.end()) {
668 HiLog::Error(LOG_LABEL, "%{public}s: There is no screen for id %{public}" PRIu64 ".\n", __func__, id);
669 return ScreenRotation::INVALID_SCREEN_ROTATION;
670 }
671 return iter->second->GetRotation();
672 }
673
GetScreenSupportedColorGamuts(ScreenId id,std::vector<ScreenColorGamut> & mode) const674 int32_t RSScreenManager::GetScreenSupportedColorGamuts(ScreenId id, std::vector<ScreenColorGamut>& mode) const
675 {
676 std::lock_guard<std::mutex> lock(mutex_);
677 return GetScreenSupportedColorGamutsLocked(id, mode);
678 }
679
GetScreenColorGamut(ScreenId id,ScreenColorGamut & mode) const680 int32_t RSScreenManager::GetScreenColorGamut(ScreenId id, ScreenColorGamut &mode) const
681 {
682 std::lock_guard<std::mutex> lock(mutex_);
683 return GetScreenColorGamutLocked(id, mode);
684 }
685
SetScreenColorGamut(ScreenId id,int32_t modeIdx)686 int32_t RSScreenManager::SetScreenColorGamut(ScreenId id, int32_t modeIdx)
687 {
688 std::lock_guard<std::mutex> lock(mutex_);
689 return SetScreenColorGamutLocked(id, modeIdx);
690 }
691
SetScreenGamutMap(ScreenId id,ScreenGamutMap mode)692 int32_t RSScreenManager::SetScreenGamutMap(ScreenId id, ScreenGamutMap mode)
693 {
694 std::lock_guard<std::mutex> lock(mutex_);
695 return SetScreenGamutMapLocked(id, mode);
696 }
697
GetScreenGamutMap(ScreenId id,ScreenGamutMap & mode) const698 int32_t RSScreenManager::GetScreenGamutMap(ScreenId id, ScreenGamutMap &mode) const
699 {
700 std::lock_guard<std::mutex> lock(mutex_);
701 return GetScreenGamutMapLocked(id, mode);
702 }
703
RequestRotation(ScreenId id,ScreenRotation rotation)704 bool RSScreenManager::RequestRotation(ScreenId id, ScreenRotation rotation)
705 {
706 std::lock_guard<std::mutex> lock(mutex_);
707 return RequestRotationLocked(id, rotation);
708 }
709
GetRotation(ScreenId id) const710 ScreenRotation RSScreenManager::GetRotation(ScreenId id) const
711 {
712 std::lock_guard<std::mutex> lock(mutex_);
713 return GetRotationLocked(id);
714 }
715 } // namespace impl
716
CreateOrGetScreenManager()717 sptr<RSScreenManager> CreateOrGetScreenManager()
718 {
719 return impl::RSScreenManager::GetInstance();
720 }
721 } // namespace Rosen
722 } // namespace OHOS
723