1 /*
2 * Copyright (c) 2021-2022 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.h"
17
18 #include <algorithm>
19 #include <cinttypes>
20
21 #include "graphic_feature_param_manager.h"
22 #include "hgm_core.h"
23 #include "pipeline/main_thread/rs_main_thread.h"
24 #include "platform/common/rs_hisysevent.h"
25 #include "platform/common/rs_log.h"
26 #include "platform/common/rs_system_properties.h"
27 #include "rs_trace.h"
28 #include "string_utils.h"
29
30 #undef LOG_TAG
31 #define LOG_TAG "RSScreen"
32
33 namespace OHOS {
34 namespace Rosen {
35 using namespace HiviewDFX;
36
37 namespace impl {
38 std::map<GraphicColorGamut, GraphicCM_ColorSpaceType> RSScreen::RS_TO_COMMON_COLOR_SPACE_TYPE_MAP {
39 {GRAPHIC_COLOR_GAMUT_STANDARD_BT601, GRAPHIC_CM_BT601_EBU_FULL},
40 {GRAPHIC_COLOR_GAMUT_STANDARD_BT709, GRAPHIC_CM_BT709_FULL},
41 {GRAPHIC_COLOR_GAMUT_SRGB, GRAPHIC_CM_SRGB_FULL},
42 {GRAPHIC_COLOR_GAMUT_ADOBE_RGB, GRAPHIC_CM_ADOBERGB_FULL},
43 {GRAPHIC_COLOR_GAMUT_DISPLAY_P3, GRAPHIC_CM_P3_FULL},
44 {GRAPHIC_COLOR_GAMUT_BT2020, GRAPHIC_CM_DISPLAY_BT2020_SRGB},
45 {GRAPHIC_COLOR_GAMUT_BT2100_PQ, GRAPHIC_CM_BT2020_PQ_FULL},
46 {GRAPHIC_COLOR_GAMUT_BT2100_HLG, GRAPHIC_CM_BT2020_HLG_FULL},
47 {GRAPHIC_COLOR_GAMUT_DISPLAY_BT2020, GRAPHIC_CM_DISPLAY_BT2020_SRGB},
48 };
49 std::map<GraphicCM_ColorSpaceType, GraphicColorGamut> RSScreen::COMMON_COLOR_SPACE_TYPE_TO_RS_MAP {
50 {GRAPHIC_CM_BT601_EBU_FULL, GRAPHIC_COLOR_GAMUT_STANDARD_BT601},
51 {GRAPHIC_CM_BT709_FULL, GRAPHIC_COLOR_GAMUT_STANDARD_BT709},
52 {GRAPHIC_CM_SRGB_FULL, GRAPHIC_COLOR_GAMUT_SRGB},
53 {GRAPHIC_CM_ADOBERGB_FULL, GRAPHIC_COLOR_GAMUT_ADOBE_RGB},
54 {GRAPHIC_CM_P3_FULL, GRAPHIC_COLOR_GAMUT_DISPLAY_P3},
55 {GRAPHIC_CM_DISPLAY_BT2020_SRGB, GRAPHIC_COLOR_GAMUT_BT2020},
56 {GRAPHIC_CM_BT2020_PQ_FULL, GRAPHIC_COLOR_GAMUT_BT2100_PQ},
57 {GRAPHIC_CM_BT2020_HLG_FULL, GRAPHIC_COLOR_GAMUT_BT2100_HLG},
58 {GRAPHIC_CM_DISPLAY_BT2020_SRGB, GRAPHIC_COLOR_GAMUT_DISPLAY_BT2020},
59 };
60 std::map<GraphicHDRFormat, ScreenHDRFormat> RSScreen::HDI_HDR_FORMAT_TO_RS_MAP {
61 {GRAPHIC_NOT_SUPPORT_HDR, NOT_SUPPORT_HDR},
62 {GRAPHIC_DOLBY_VISION, NOT_SUPPORT_HDR},
63 {GRAPHIC_HDR10, VIDEO_HDR10},
64 {GRAPHIC_HLG, VIDEO_HLG},
65 {GRAPHIC_HDR10_PLUS, NOT_SUPPORT_HDR},
66 {GRAPHIC_HDR_VIVID, VIDEO_HDR_VIVID},
67 };
68 std::map<ScreenHDRFormat, GraphicHDRFormat> RSScreen::RS_TO_HDI_HDR_FORMAT_MAP {
69 {NOT_SUPPORT_HDR, GRAPHIC_NOT_SUPPORT_HDR},
70 {VIDEO_HLG, GRAPHIC_HLG},
71 {VIDEO_HDR10, GRAPHIC_HDR10},
72 {VIDEO_HDR_VIVID, GRAPHIC_HDR_VIVID},
73 {IMAGE_HDR_VIVID_DUAL, GRAPHIC_HDR_VIVID},
74 {IMAGE_HDR_VIVID_SINGLE, GRAPHIC_HDR_VIVID},
75 {IMAGE_HDR_ISO_DUAL, GRAPHIC_NOT_SUPPORT_HDR},
76 {IMAGE_HDR_ISO_SINGLE, GRAPHIC_NOT_SUPPORT_HDR},
77 };
78
79 constexpr int MAX_LUM = 1000;
80
RSScreen(ScreenId id,bool isVirtual,std::shared_ptr<HdiOutput> output,sptr<Surface> surface)81 RSScreen::RSScreen(ScreenId id,
82 bool isVirtual,
83 std::shared_ptr<HdiOutput> output,
84 sptr<Surface> surface)
85 : id_(id),
86 isVirtual_(isVirtual),
87 hdiOutput_(std::move(output)),
88 producerSurface_(std::move(surface))
89 {
90 if (!IsVirtual()) {
91 hdrCapability_.formatCount = 0;
92 name_ = "Screen_" + std::to_string(id_);
93 PhysicalScreenInit();
94 RS_LOGW("init physical: {id: %{public}" PRIu64 ", w * h: [%{public}u * %{public}u], "
95 "screenType: %{public}u}", id_, width_, height_, screenType_);
96 }
97 capability_.props.clear();
98 }
99
RSScreen(const VirtualScreenConfigs & configs)100 RSScreen::RSScreen(const VirtualScreenConfigs &configs)
101 : id_(configs.id),
102 mirroredId_(configs.mirrorId),
103 name_(configs.name),
104 width_(configs.width),
105 height_(configs.height),
106 isVirtual_(true),
107 virtualSecLayerOption_(configs.flags),
108 producerSurface_(configs.surface),
109 pixelFormat_(configs.pixelFormat),
110 screenType_(RSScreenType::VIRTUAL_TYPE_SCREEN),
111 whiteList_(configs.whiteList)
112 {
113 VirtualScreenInit();
114 RS_LOGW("init virtual screen: {id: %{public}" PRIu64 ", mirroredId: %{public}" PRIu64
115 ", w * h: [%{public}u * %{public}u], name: %{public}s, screenType: %{public}u, whiteList size: %{public}zu}",
116 id_, mirroredId_, width_, height_, name_.c_str(), screenType_, whiteList_.size());
117 }
118
VirtualScreenInit()119 void RSScreen::VirtualScreenInit() noexcept
120 {
121 hdrCapability_.formatCount = 0;
122 for (auto item : supportedVirtualHDRFormats_) {
123 hdrCapability_.formats.emplace_back(RS_TO_HDI_HDR_FORMAT_MAP[item]);
124 ++hdrCapability_.formatCount;
125 }
126 }
127
PhysicalScreenInit()128 void RSScreen::PhysicalScreenInit() noexcept
129 {
130 hdiScreen_ = HdiScreen::CreateHdiScreen(ScreenPhysicalId(id_));
131 if (hdiScreen_ == nullptr) {
132 RS_LOGE("%{public}s: RSScreen(id %{public}" PRIu64 ") failed to CreateHdiScreens.",
133 __func__, id_);
134 return;
135 }
136
137 hdiScreen_->Init();
138 if (hdiScreen_->GetScreenSupportedModes(supportedModes_) < 0) {
139 RS_LOGE("%{public}s: RSScreen(id %{public}" PRIu64 ") failed to GetScreenSupportedModes.",
140 __func__, id_);
141 }
142
143 if (hdiScreen_->GetHDRCapabilityInfos(hdrCapability_) < 0) {
144 RS_LOGE("%{public}s: RSScreen(id %{public}" PRIu64 ") failed to GetHDRCapabilityInfos.",
145 __func__, id_);
146 }
147 std::transform(hdrCapability_.formats.begin(), hdrCapability_.formats.end(),
148 back_inserter(supportedPhysicalHDRFormats_),
149 [](GraphicHDRFormat item) -> ScreenHDRFormat { return HDI_HDR_FORMAT_TO_RS_MAP[item]; });
150 auto status = GraphicDispPowerStatus::GRAPHIC_POWER_STATUS_ON;
151 if (MultiScreenParam::IsRsSetScreenPowerStatus() || id_ == 0) {
152 RS_LOGI("%{public}s: RSScreen(id %{public}" PRIu64 ") start SetScreenPowerStatus to On",
153 __func__, id_);
154 if (hdiScreen_->SetScreenPowerStatus(status) < 0) {
155 RS_LOGE("%{public}s: RSScreen(id %{public}" PRIu64 ") failed to SetScreenPowerStatus.",
156 __func__, id_);
157 } else {
158 RS_LOGI("%{public}s: RSScreen(id %{public}" PRIu64 ") end SetScreenPowerStatus to On",
159 __func__, id_);
160 }
161 }
162 auto activeMode = GetActiveMode();
163 if (activeMode) {
164 phyWidth_ = activeMode->width;
165 phyHeight_ = activeMode->height;
166 width_ = phyWidth_;
167 height_ = phyHeight_;
168 }
169 if (hdiScreen_->GetScreenPowerStatus(status) < 0) {
170 RS_LOGE("%{public}s: RSScreen(id %{public}" PRIu64 ") failed to GetScreenPowerStatus.",
171 __func__, id_);
172 powerStatus_ = ScreenPowerStatus::INVALID_POWER_STATUS;
173 } else {
174 powerStatus_ = static_cast<ScreenPowerStatus>(status);
175 }
176 if (capability_.type == GraphicInterfaceType::GRAPHIC_DISP_INTF_MIPI) {
177 screenType_ = RSScreenType::BUILT_IN_TYPE_SCREEN;
178 } else {
179 screenType_ = RSScreenType::EXTERNAL_TYPE_SCREEN;
180 }
181 ScreenCapabilityInit();
182
183 std::vector<GraphicColorGamut> supportedColorGamuts;
184 if (hdiScreen_->GetScreenSupportedColorGamuts(supportedColorGamuts) != GRAPHIC_DISPLAY_SUCCESS) {
185 RS_LOGE("%{public}s: RSScreen(id %{public}" PRIu64 ") failed to GetScreenSupportedColorGamuts.",
186 __func__, id_);
187 } else {
188 int index = 0;
189 for (auto item : supportedColorGamuts) {
190 supportedPhysicalColorGamuts_.push_back(static_cast<ScreenColorGamut>(item));
191 if (item == GraphicColorGamut::GRAPHIC_COLOR_GAMUT_SRGB) {
192 currentPhysicalColorGamutIdx_ = index;
193 }
194 ++index;
195 }
196 }
197 screenBacklightLevel_ = GetScreenBacklight();
198 }
199
ScreenCapabilityInit()200 void RSScreen::ScreenCapabilityInit() noexcept
201 {
202 if (!hdiScreen_) {
203 RS_LOGE("%{public}s failed, hdiScreen_ is nullptr", __func__);
204 return;
205 }
206 int32_t ret = hdiScreen_->GetScreenCapability(capability_);
207 if (ret != GRAPHIC_DISPLAY_SUCCESS) {
208 RS_LOGE("%{public}s: get display capability failed, ret is %{public}d, use the default"
209 " display capability.", __func__, ret);
210 capability_ = {
211 .name = "test1",
212 .type = GRAPHIC_DISP_INTF_HDMI,
213 .phyWidth = 1921,
214 .phyHeight = 1081,
215 .supportLayers = 0,
216 .virtualDispCount = 0,
217 .supportWriteBack = true,
218 .propertyCount = 0
219 };
220 }
221 }
222
Id() const223 ScreenId RSScreen::Id() const
224 {
225 return id_;
226 }
227
MirroredId() const228 ScreenId RSScreen::MirroredId() const
229 {
230 return mirroredId_;
231 }
232
SetMirror(ScreenId mirroredId)233 void RSScreen::SetMirror(ScreenId mirroredId)
234 {
235 mirroredId_ = mirroredId;
236 }
237
Name() const238 const std::string& RSScreen::Name() const
239 {
240 return name_;
241 }
242
Width() const243 uint32_t RSScreen::Width() const
244 {
245 std::shared_lock<std::shared_mutex> lock(screenMutex_);
246 return width_;
247 }
248
Height() const249 uint32_t RSScreen::Height() const
250 {
251 std::shared_lock<std::shared_mutex> lock(screenMutex_);
252 return height_;
253 }
254
PhyWidth() const255 uint32_t RSScreen::PhyWidth() const
256 {
257 std::shared_lock<std::shared_mutex> lock(screenMutex_);
258 return phyWidth_;
259 }
260
PhyHeight() const261 uint32_t RSScreen::PhyHeight() const
262 {
263 std::shared_lock<std::shared_mutex> lock(screenMutex_);
264 return phyHeight_;
265 }
266
SetScreenOffset(int32_t offsetX,int32_t offsetY)267 void RSScreen::SetScreenOffset(int32_t offsetX, int32_t offsetY)
268 {
269 std::lock_guard<std::shared_mutex> lock(screenMutex_);
270 offsetX_ = offsetX;
271 offsetY_ = offsetY;
272 }
273
GetOffsetX() const274 int32_t RSScreen::GetOffsetX() const
275 {
276 std::shared_lock<std::shared_mutex> lock(screenMutex_);
277 return offsetX_;
278 }
279
GetOffsetY() const280 int32_t RSScreen::GetOffsetY() const
281 {
282 std::shared_lock<std::shared_mutex> lock(screenMutex_);
283 return offsetY_;
284 }
285
IsSamplingOn() const286 bool RSScreen::IsSamplingOn() const
287 {
288 std::shared_lock<std::shared_mutex> lock(screenMutex_);
289 return isSamplingOn_;
290 }
291
GetSamplingTranslateX() const292 float RSScreen::GetSamplingTranslateX() const
293 {
294 std::shared_lock<std::shared_mutex> lock(screenMutex_);
295 return samplingTranslateX_;
296 }
297
GetSamplingTranslateY() const298 float RSScreen::GetSamplingTranslateY() const
299 {
300 std::shared_lock<std::shared_mutex> lock(screenMutex_);
301 return samplingTranslateY_;
302 }
303
GetSamplingScale() const304 float RSScreen::GetSamplingScale() const
305 {
306 std::shared_lock<std::shared_mutex> lock(screenMutex_);
307 return samplingScale_;
308 }
309
GetActiveRect() const310 RectI RSScreen::GetActiveRect() const
311 {
312 std::shared_lock<std::shared_mutex> lock(screenMutex_);
313 return activeRect_;
314 }
315
GetMaskRect() const316 RectI RSScreen::GetMaskRect() const
317 {
318 std::shared_lock<std::shared_mutex> lock(screenMutex_);
319 return maskRect_;
320 }
321
GetReviseRect() const322 RectI RSScreen::GetReviseRect() const
323 {
324 std::shared_lock<std::shared_mutex> lock(screenMutex_);
325 return reviseRect_;
326 }
327
IsEnable() const328 bool RSScreen::IsEnable() const
329 {
330 if (id_ == INVALID_SCREEN_ID) {
331 return false;
332 }
333
334 std::lock_guard<std::mutex> lock(producerSurfaceMutex_);
335 if (!hdiOutput_ && !producerSurface_) {
336 return false;
337 }
338
339 // [PLANNING]: maybe need more information to judge whether this screen is enable.
340 return true;
341 }
342
IsVirtual() const343 bool RSScreen::IsVirtual() const
344 {
345 return isVirtual_;
346 }
347
WriteHisyseventEpsLcdInfo(GraphicDisplayModeInfo & activeMode)348 void RSScreen::WriteHisyseventEpsLcdInfo(GraphicDisplayModeInfo& activeMode)
349 {
350 auto frameRateMgr = HgmCore::Instance().GetFrameRateMgr();
351 if (frameRateMgr != nullptr && frameRateMgr->IsLtpo()) {
352 RS_LOGW_IF(DEBUG_SCREEN, "RSScreen LTPO mode");
353 return;
354 }
355 static GraphicDisplayModeInfo modeInfo;
356 if ((modeInfo.freshRate != activeMode.freshRate)
357 || modeInfo.width != activeMode.width || modeInfo.height != activeMode.height) {
358 RS_TRACE_NAME("RSScreen::WriteHisyseventEpsLcdInfo HiSysEventWrite");
359 RSHiSysEvent::EventWrite(RSEventName::EPS_LCD_FREQ, RSEventType::RS_STATISTIC,
360 "SOURCERATE", modeInfo.freshRate, "TARGETRATE", activeMode.freshRate, "WIDTH", activeMode.width,
361 "HEIGHT", activeMode.height);
362 modeInfo = activeMode;
363 }
364 }
365
SetActiveMode(uint32_t modeId)366 uint32_t RSScreen::SetActiveMode(uint32_t modeId)
367 {
368 if (IsVirtual()) {
369 RS_LOGW("%{public}s: virtual screen not support SetActiveMode.", __func__);
370 return StatusCode::VIRTUAL_SCREEN;
371 }
372 if (!hdiScreen_) {
373 RS_LOGE("%{public}s failed, hdiScreen_ is nullptr", __func__);
374 return StatusCode::SCREEN_NOT_FOUND;
375 }
376
377 if (modeId >= supportedModes_.size()) {
378 RS_LOGE("%{public}s: set fails because the index is out of bounds.", __func__);
379 return StatusCode::INVALID_ARGUMENTS;
380 }
381 RS_LOGW_IF(DEBUG_SCREEN, "RSScreen set active mode: %{public}u", modeId);
382 int32_t selectModeId = supportedModes_[modeId].id;
383 if (hdiScreen_->SetScreenMode(static_cast<uint32_t>(selectModeId)) < 0) {
384 RS_LOGE("%{public}s: Hdi SetScreenMode fails.", __func__);
385 return StatusCode::SET_RATE_ERROR;
386 }
387 auto activeMode = GetActiveMode();
388 if (activeMode) {
389 std::unique_lock<std::shared_mutex> lock(screenMutex_);
390 phyWidth_ = activeMode->width;
391 phyHeight_ = activeMode->height;
392 lock.unlock();
393 WriteHisyseventEpsLcdInfo(activeMode.value());
394 }
395 return StatusCode::SUCCESS;
396 }
397
SetScreenActiveRect(const GraphicIRect & activeRect)398 uint32_t RSScreen::SetScreenActiveRect(const GraphicIRect& activeRect)
399 {
400 if (IsVirtual()) {
401 RS_LOGW("%{public}s failed: virtual screen not support", __func__);
402 return StatusCode::HDI_ERROR;
403 }
404 if (hdiScreen_ == nullptr) {
405 RS_LOGE("%{public}s failed: hdiScreen_ is nullptr", __func__);
406 return StatusCode::HDI_ERROR;
407 }
408 if (activeRect.x < 0 || activeRect.y < 0 || activeRect.w <= 0 || activeRect.h <= 0 ||
409 static_cast<uint32_t>(activeRect.x + activeRect.w) > width_ ||
410 static_cast<uint32_t>(activeRect.y + activeRect.h) > height_) {
411 RS_LOGW("%{public}s failed:, for activeRect: "
412 "(%{public}" PRId32 ", %{public}" PRId32 ", %{public}" PRId32 ", %{public}" PRId32 ")",
413 __func__, activeRect.x, activeRect.y, activeRect.w, activeRect.h);
414 return StatusCode::INVALID_ARGUMENTS;
415 }
416
417 std::unique_lock<std::shared_mutex> lock(screenMutex_);
418 activeRect_ = RectI(activeRect.x, activeRect.y, activeRect.w, activeRect.h);
419 RS_LOGI("%{public}s success, activeRect: (%{public}" PRId32 ", %{public}" PRId32 ", "
420 "%{public}" PRId32 ", %{public}" PRId32 ")", __func__, activeRect.x, activeRect.y, activeRect.w, activeRect.h);
421 GraphicIRect reviseRect = activeRect;
422 if (!CalculateMaskRectAndReviseRect(activeRect, reviseRect)) {
423 RS_LOGW("CalculateMaskRect failed or not need");
424 }
425 reviseRect_ = RectI(reviseRect.x, reviseRect.y, reviseRect.w, reviseRect.h);
426 lock.unlock();
427
428 if (hdiScreen_->SetScreenActiveRect(reviseRect) < 0) {
429 RS_LOGE("%{public}s failed: hdi SetScreenActiveRect failed, activeRect with revise:"
430 "(%{public}" PRId32 ", %{public}" PRId32 ", %{public}" PRId32 ", %{public}" PRId32 ")",
431 __func__, reviseRect.x, reviseRect.y, reviseRect.w, reviseRect.h);
432 return StatusCode::HDI_ERROR;
433 }
434 RS_LOGI("%{public}s success, reviseRect: (%{public}" PRId32 ", %{public}" PRId32 ", "
435 "%{public}" PRId32 ", %{public}" PRId32 ")", __func__, reviseRect.x, reviseRect.y, reviseRect.w, reviseRect.h);
436 return StatusCode::SUCCESS;
437 }
438
CalculateMaskRectAndReviseRect(const GraphicIRect & activeRect,GraphicIRect & reviseRect)439 bool RSScreen::CalculateMaskRectAndReviseRect(const GraphicIRect& activeRect, GraphicIRect& reviseRect)
440 {
441 #ifdef ROSEN_EMULATOR
442 RS_LOGD("%{public}s emulator device do not revise rect", __func__);
443 return false;
444 #endif
445 if (!RSSystemProperties::IsSuperFoldDisplay()) {
446 RS_LOGE("device is not super fold display");
447 return false;
448 }
449 if (activeRect.w > 0 && activeRect.h > 0) {
450 // neet tobe configuration item
451 static RectI rect[2] = {{0, 0, 0, 0}, {0, 1008, 2232, 128}};
452 maskRect_ = (static_cast<uint32_t>(activeRect.h) == height_) ? rect[0] : rect[1];
453 // Take the minimum rectangular area containing two rectangles
454 reviseRect.x = std::clamp(activeRect.x, 0, std::min(activeRect.x, maskRect_.left_));
455 reviseRect.y = std::clamp(activeRect.y, 0, std::min(activeRect.y, maskRect_.top_));
456 reviseRect.w = std::max(activeRect.x + activeRect.w, maskRect_.left_ + maskRect_.width_) - reviseRect.x;
457 reviseRect.h = std::max(activeRect.y + activeRect.h, maskRect_.top_ + maskRect_.height_) - reviseRect.y;
458 RS_LOGI("%{public}s success, maskRect: %{public}s", __func__, maskRect_.ToString().c_str());
459 return true;
460 }
461 return false;
462 }
463
SetRogResolution(uint32_t width,uint32_t height)464 void RSScreen::SetRogResolution(uint32_t width, uint32_t height)
465 {
466 if (!hdiScreen_) {
467 RS_LOGE("%{public}s failed, hdiScreen_ is nullptr", __func__);
468 return;
469 }
470
471 std::shared_lock<std::shared_mutex> sharedLock(screenMutex_);
472 if ((width == 0 || height == 0) ||
473 (width == width_ && height == height_) ||
474 (width > phyWidth_ || height > phyHeight_)) {
475 RS_LOGD("%{public}s: width: %{public}d, height: %{public}d.", __func__, width, height);
476 return;
477 }
478 sharedLock.unlock();
479
480 if (hdiScreen_->SetScreenOverlayResolution(width, height) < 0) {
481 RS_LOGE("%{public}s: hdi set screen rog resolution failed.", __func__);
482 }
483 std::lock_guard<std::shared_mutex> lock(screenMutex_);
484 width_ = width;
485 height_ = height;
486 RS_LOGI("%{public}s: RSScreen(id %{public}" PRIu64 "), width: %{public}d,"
487 " height: %{public}d, phywidth: %{public}d, phyHeight: %{public}d.",
488 __func__, id_, width_, height_, phyWidth_, phyHeight_);
489 }
490
SetResolution(uint32_t width,uint32_t height)491 int32_t RSScreen::SetResolution(uint32_t width, uint32_t height)
492 {
493 RS_LOGI("%{public}s screenId:%{public}" PRIu64 " width: %{public}u height: %{public}u", __func__, id_, width,
494 height);
495 std::lock_guard<std::shared_mutex> lock(screenMutex_);
496 if (IsVirtual()) {
497 width_ = width;
498 height_ = height;
499 return StatusCode::SUCCESS;
500 }
501 if (width < phyWidth_ || height < phyHeight_) {
502 RS_LOGE("%{public}s phyWidth: %{public}u phyHeight: %{public}u", __func__, phyWidth_, phyHeight_);
503 return StatusCode::INVALID_ARGUMENTS;
504 }
505 width_ = width;
506 height_ = height;
507 isSamplingOn_ = width > phyWidth_ || height > phyHeight_;
508 if (isSamplingOn_ && width_ > 0 && height_ > 0) {
509 samplingScale_ = std::min(static_cast<float>(phyWidth_) / width_,
510 static_cast<float>(phyHeight_) / height_);
511 samplingTranslateX_ = (phyWidth_ - width_ * samplingScale_) / 2.f;
512 samplingTranslateY_ = (phyHeight_ - height_ * samplingScale_) / 2.f;
513 RS_LOGI("%{public}s: sampling is enabled. "
514 "scale: %{public}f, translateX: %{public}f, translateY: %{public}f",
515 __func__, samplingScale_, samplingTranslateX_, samplingTranslateY_);
516 }
517 return StatusCode::SUCCESS;
518 }
519
GetActiveModePosByModeId(int32_t modeId) const520 int32_t RSScreen::GetActiveModePosByModeId(int32_t modeId) const
521 {
522 decltype(supportedModes_.size()) modeIndex = 0;
523 for (; modeIndex < supportedModes_.size(); ++modeIndex) {
524 if (supportedModes_[modeIndex].id == modeId) {
525 return static_cast<int32_t>(modeIndex);
526 }
527 }
528 return -1;
529 }
530
SetPowerStatus(uint32_t powerStatus)531 int32_t RSScreen::SetPowerStatus(uint32_t powerStatus)
532 {
533 if (!hdiScreen_) {
534 RS_LOGE("[UL_POWER] %{public}s failed, hdiScreen_ is nullptr", __func__);
535 return StatusCode::HDI_ERROR;
536 }
537 if (IsVirtual()) {
538 RS_LOGW("[UL_POWER] %{public}s: virtual screen not support SetPowerStatus.", __func__);
539 return StatusCode::HDI_ERROR;
540 }
541
542 RS_LOGW("[UL_POWER]RSScreen_%{public}" PRIu64 " SetPowerStatus: %{public}u.", id_, powerStatus);
543 RS_TRACE_NAME_FMT("[UL_POWER]Screen_%llu SetPowerStatus %u", id_, powerStatus);
544 hasLogBackLightAfterPowerStatusChanged_ = false;
545 if (hdiScreen_->SetScreenPowerStatus(static_cast<GraphicDispPowerStatus>(powerStatus)) < 0) {
546 RS_LOGW("[UL_POWER] %{public}s failed to set power status", __func__);
547 powerStatus_ = ScreenPowerStatus::INVALID_POWER_STATUS;
548 return StatusCode::HDI_ERROR;
549 }
550 powerStatus_ = static_cast<ScreenPowerStatus>(powerStatus);
551
552 RS_LOGW("[UL_POWER]RSScreen_%{public}" PRIu64 " SetPowerStatus: %{public}u done.", id_, powerStatus);
553 return StatusCode::SUCCESS;
554 }
555
GetActiveMode() const556 std::optional<GraphicDisplayModeInfo> RSScreen::GetActiveMode() const
557 {
558 if (IsVirtual()) {
559 RS_LOGW("%{public}s: virtual screen not support GetActiveMode.", __func__);
560 return {};
561 }
562
563 uint32_t modeId = 0;
564
565 if (hdiScreen_ == nullptr) {
566 RS_LOGE("%{public}s: id: %{public}" PRIu64 " hdiScreen is null.", __func__, id_);
567 return {};
568 }
569
570 if (hdiScreen_->GetScreenMode(modeId) < 0) {
571 RS_LOGE("%{public}s: id: %{public}" PRIu64 " GetScreenMode failed.", __func__, id_);
572 return {};
573 }
574
575 auto iter = std::find_if(supportedModes_.cbegin(), supportedModes_.cend(),
576 [modeId](const auto &mode) { return static_cast<uint32_t>(mode.id) == modeId; });
577 if (iter == supportedModes_.cend()) {
578 return {};
579 }
580
581 return *iter;
582 }
583
GetSupportedModes() const584 const std::vector<GraphicDisplayModeInfo>& RSScreen::GetSupportedModes() const
585 {
586 return supportedModes_;
587 }
588
GetCapability() const589 const GraphicDisplayCapability& RSScreen::GetCapability() const
590 {
591 return capability_;
592 }
593
GetPowerStatus()594 uint32_t RSScreen::GetPowerStatus()
595 {
596 if (IsVirtual()) {
597 RS_LOGW("%{public}s: virtual screen not support GetPowerStatus.", __func__);
598 return ScreenPowerStatus::INVALID_POWER_STATUS;
599 }
600
601 if (!hdiScreen_) {
602 RS_LOGE("%{public}s failed, hdiScreen_ is nullptr", __func__);
603 return INVALID_POWER_STATUS;
604 }
605
606 if (powerStatus_ != ScreenPowerStatus::INVALID_POWER_STATUS) {
607 return static_cast<uint32_t>(powerStatus_);
608 }
609
610 auto status = GraphicDispPowerStatus::GRAPHIC_POWER_STATUS_ON;
611 if (hdiScreen_->GetScreenPowerStatus(status) < 0) {
612 powerStatus_ = ScreenPowerStatus::INVALID_POWER_STATUS;
613 RS_LOGE("%{public}s failed to get screen powerStatus", __func__);
614 return INVALID_POWER_STATUS;
615 }
616 powerStatus_ = static_cast<ScreenPowerStatus>(status);
617 RS_LOGW("%{public}s cached powerStatus is INVALID_POWER_STATUS and GetScreenPowerStatus %{public}d",
618 __func__, static_cast<uint32_t>(status));
619 return static_cast<uint32_t>(status);
620 }
621
GetOutput() const622 std::shared_ptr<HdiOutput> RSScreen::GetOutput() const
623 {
624 return hdiOutput_;
625 }
626
GetProducerSurface() const627 sptr<Surface> RSScreen::GetProducerSurface() const
628 {
629 std::lock_guard<std::mutex> lock(producerSurfaceMutex_);
630 return producerSurface_;
631 }
632
SetProducerSurface(sptr<Surface> producerSurface)633 void RSScreen::SetProducerSurface(sptr<Surface> producerSurface)
634 {
635 std::lock_guard<std::mutex> lock(producerSurfaceMutex_);
636 producerSurface_ = producerSurface;
637 isVirtualSurfaceUpdateFlag_ = true;
638 }
639
GetAndResetVirtualSurfaceUpdateFlag()640 bool RSScreen::GetAndResetVirtualSurfaceUpdateFlag()
641 {
642 return isVirtualSurfaceUpdateFlag_.exchange(false);
643 }
644
ModeInfoDump(std::string & dumpString)645 void RSScreen::ModeInfoDump(std::string& dumpString)
646 {
647 decltype(supportedModes_.size()) modeIndex = 0;
648 for (; modeIndex < supportedModes_.size(); ++modeIndex) {
649 AppendFormat(dumpString, "supportedMode[%d]: %dx%d, refreshRate=%d\n",
650 modeIndex, supportedModes_[modeIndex].width,
651 supportedModes_[modeIndex].height, supportedModes_[modeIndex].freshRate);
652 }
653 std::optional<GraphicDisplayModeInfo> activeMode = GetActiveMode();
654 if (activeMode) {
655 AppendFormat(dumpString, "activeMode: %dx%d, refreshRate=%d\n",
656 activeMode->width, activeMode->height, activeMode->freshRate);
657 }
658 }
659
CapabilityTypeDump(GraphicInterfaceType capabilityType,std::string & dumpString)660 void RSScreen::CapabilityTypeDump(GraphicInterfaceType capabilityType, std::string& dumpString)
661 {
662 dumpString += "type=";
663 switch (capabilityType) {
664 case GRAPHIC_DISP_INTF_HDMI: {
665 dumpString += "DISP_INTF_HDMI, ";
666 break;
667 }
668 case GRAPHIC_DISP_INTF_LCD: {
669 dumpString += "DISP_INTF_LCD, ";
670 break;
671 }
672 case GRAPHIC_DISP_INTF_BT1120: {
673 dumpString += "DISP_INTF_BT1120, ";
674 break;
675 }
676 case GRAPHIC_DISP_INTF_BT656: {
677 dumpString += "DISP_INTF_BT656, ";
678 break;
679 }
680 default:
681 dumpString += "INVALID_DISP_INTF, ";
682 break;
683 }
684 }
685
CapabilityDump(std::string & dumpString)686 void RSScreen::CapabilityDump(std::string& dumpString)
687 {
688 AppendFormat(dumpString, "name=%s, phyWidth=%d, phyHeight=%d, "
689 "supportLayers=%d, virtualDispCount=%d, propertyCount=%d, ",
690 capability_.name.c_str(), capability_.phyWidth, capability_.phyHeight,
691 capability_.supportLayers, capability_.virtualDispCount, capability_.propertyCount);
692 CapabilityTypeDump(capability_.type, dumpString);
693 dumpString += "supportWriteBack=";
694 dumpString += (capability_.supportWriteBack) ? "true" : "false";
695 dumpString += "\n";
696 PropDump(dumpString);
697 }
698
PropDump(std::string & dumpString)699 void RSScreen::PropDump(std::string& dumpString)
700 {
701 decltype(capability_.propertyCount) propIndex = 0;
702 for (; propIndex < capability_.propertyCount; ++propIndex) {
703 AppendFormat(dumpString, "prop[%u]: name=%s, propid=%d, value=%d\n",
704 propIndex, capability_.props[propIndex].name.c_str(), capability_.props[propIndex].propId,
705 capability_.props[propIndex].value);
706 }
707 }
708
PowerStatusDump(std::string & dumpString)709 void RSScreen::PowerStatusDump(std::string& dumpString)
710 {
711 dumpString += "powerStatus=";
712 switch (GetPowerStatus()) {
713 case GRAPHIC_POWER_STATUS_ON: {
714 dumpString += "POWER_STATUS_ON";
715 break;
716 }
717 case GRAPHIC_POWER_STATUS_STANDBY: {
718 dumpString += "POWER_STATUS_STANDBY";
719 break;
720 }
721 case GRAPHIC_POWER_STATUS_SUSPEND: {
722 dumpString += "POWER_STATUS_SUSPEND";
723 break;
724 }
725 case GRAPHIC_POWER_STATUS_OFF: {
726 dumpString += "POWER_STATUS_OFF";
727 break;
728 }
729 case GRAPHIC_POWER_STATUS_OFF_FAKE: {
730 dumpString += "POWER_STATUS_OFF_FAKE";
731 break;
732 }
733 case GRAPHIC_POWER_STATUS_BUTT: {
734 dumpString += "POWER_STATUS_BUTT";
735 break;
736 }
737 case GRAPHIC_POWER_STATUS_ON_ADVANCED: {
738 dumpString += "POWER_STATUS_ON_ADVANCED";
739 break;
740 }
741 case GRAPHIC_POWER_STATUS_OFF_ADVANCED: {
742 dumpString += "POWER_STATUS_OFF_ADVANCED";
743 break;
744 }
745 default: {
746 dumpString += "INVALID_POWER_STATUS";
747 break;
748 }
749 }
750 }
751
DisplayDump(int32_t screenIndex,std::string & dumpString)752 void RSScreen::DisplayDump(int32_t screenIndex, std::string& dumpString)
753 {
754 dumpString += "-- ScreenInfo\n";
755 if (IsVirtual()) {
756 dumpString += "screen[" + std::to_string(screenIndex) + "]: ";
757 dumpString += "id=";
758 dumpString += (id_ == INVALID_SCREEN_ID) ? "INVALID_SCREEN_ID" : std::to_string(id_);
759 dumpString += ", ";
760 dumpString += "mirroredId=";
761 dumpString += (mirroredId_ == INVALID_SCREEN_ID) ? "INVALID_SCREEN_ID" : std::to_string(mirroredId_);
762 dumpString += ", ";
763 std::shared_lock<std::shared_mutex> screenLock(screenMutex_, std::defer_lock);
764 std::shared_lock<std::shared_mutex> skipFrameLock(skipFrameMutex_, std::defer_lock);
765 std::lock(screenLock, skipFrameLock);
766 AppendFormat(dumpString, ", render resolution=%dx%d, isVirtual=true, skipFrameInterval=%d"
767 ", expectedRefreshRate=%d, skipFrameStrategy=%d\n",
768 width_, height_, skipFrameInterval_, expectedRefreshRate_, skipFrameStrategy_);
769 } else {
770 dumpString += "screen[" + std::to_string(screenIndex) + "]: ";
771 dumpString += "id=";
772 dumpString += (id_ == INVALID_SCREEN_ID) ? "INVALID_SCREEN_ID" : std::to_string(id_);
773 dumpString += ", ";
774 PowerStatusDump(dumpString);
775 dumpString += ", ";
776 dumpString += "backlight=" + std::to_string(GetScreenBacklight());
777 dumpString += ", ";
778 ScreenTypeDump(dumpString);
779 std::shared_lock<std::shared_mutex> screenLock(screenMutex_, std::defer_lock);
780 std::shared_lock<std::shared_mutex> skipFrameLock(skipFrameMutex_, std::defer_lock);
781 std::lock(screenLock, skipFrameLock);
782 AppendFormat(dumpString,
783 ", render resolution=%dx%d, physical resolution=%dx%d, isVirtual=false, skipFrameInterval=%d"
784 ", expectedRefreshRate=%d, skipFrameStrategy=%d\n",
785 width_, height_, phyWidth_, phyHeight_, skipFrameInterval_, expectedRefreshRate_, skipFrameStrategy_);
786 screenLock.unlock();
787 skipFrameLock.unlock();
788 ModeInfoDump(dumpString);
789 CapabilityDump(dumpString);
790 AppendFormat(dumpString,
791 "isSamplingOn=%d, samplingScale=%.2f, samplingTranslateX=%.2f, samplingTranslateY=%.2f\n",
792 isSamplingOn_, samplingScale_, samplingTranslateX_, samplingTranslateY_);
793 AppendFormat(dumpString, "enableVisibleRect=%d, mainScreenVisibleRect_=[%d,%d,%d,%d]\n",
794 enableVisibleRect_.load(), mainScreenVisibleRect_.x, mainScreenVisibleRect_.y,
795 mainScreenVisibleRect_.w, mainScreenVisibleRect_.h);
796 }
797 }
798
ScreenTypeDump(std::string & dumpString)799 void RSScreen::ScreenTypeDump(std::string& dumpString)
800 {
801 dumpString += "screenType=";
802 switch (screenType_) {
803 case RSScreenType::BUILT_IN_TYPE_SCREEN: {
804 dumpString += "BUILT_IN_TYPE";
805 break;
806 }
807 case RSScreenType::EXTERNAL_TYPE_SCREEN: {
808 dumpString += "EXTERNAL_TYPE";
809 break;
810 }
811 case RSScreenType::VIRTUAL_TYPE_SCREEN: {
812 dumpString += "VIRTUAL_TYPE";
813 break;
814 }
815 default: {
816 dumpString += "UNKNOWN_TYPE";
817 break;
818 }
819 }
820 }
821
SurfaceDump(int32_t screenIndex,std::string & dumpString)822 void RSScreen::SurfaceDump(int32_t screenIndex, std::string& dumpString)
823 {
824 if (hdiOutput_ == nullptr) {
825 RS_LOGW("%{public}s: hdiOutput_ is nullptr.", __func__);
826 return;
827 }
828 hdiOutput_->Dump(dumpString);
829 }
830
DumpCurrentFrameLayers()831 void RSScreen::DumpCurrentFrameLayers()
832 {
833 if (hdiOutput_ == nullptr) {
834 RS_LOGW("RSScreen %{public}s: hdiOutput_ is nullptr.", __func__);
835 return;
836 }
837 hdiOutput_->DumpCurrentFrameLayers();
838 }
839
FpsDump(int32_t screenIndex,std::string & dumpString,std::string & arg)840 void RSScreen::FpsDump(int32_t screenIndex, std::string& dumpString, std::string& arg)
841 {
842 if (hdiOutput_ == nullptr) {
843 RS_LOGW("%{public}s: hdiOutput_ is nullptr.", __func__);
844 return;
845 }
846 hdiOutput_->DumpFps(dumpString, arg);
847 }
848
ClearFpsDump(int32_t screenIndex,std::string & dumpString,std::string & arg)849 void RSScreen::ClearFpsDump(int32_t screenIndex, std::string& dumpString, std::string& arg)
850 {
851 if (hdiOutput_ == nullptr) {
852 RS_LOGW("%{public}s: hdiOutput_ is nullptr.", __func__);
853 return;
854 }
855 hdiOutput_->ClearFpsDump(dumpString, arg);
856 }
857
HitchsDump(int32_t screenIndex,std::string & dumpString,std::string & arg)858 void RSScreen::HitchsDump(int32_t screenIndex, std::string& dumpString, std::string& arg)
859 {
860 if (hdiOutput_ == nullptr) {
861 RS_LOGW("%{public}s: hdiOutput_ is nullptr.", __func__);
862 return;
863 }
864 hdiOutput_->DumpHitchs(dumpString, arg);
865 }
866
ResizeVirtualScreen(uint32_t width,uint32_t height)867 void RSScreen::ResizeVirtualScreen(uint32_t width, uint32_t height)
868 {
869 if (!IsVirtual()) {
870 RS_LOGW("%{public}s: physical screen not support ResizeVirtualScreen.", __func__);
871 return;
872 }
873 std::lock_guard<std::shared_mutex> lock(screenMutex_);
874 width_ = width;
875 height_ = height;
876 }
877
SetScreenBacklight(uint32_t level)878 void RSScreen::SetScreenBacklight(uint32_t level)
879 {
880 if (!hdiScreen_) {
881 RS_LOGE("%{public}s failed, hdiScreen_ is nullptr", __func__);
882 return;
883 }
884 if (IsVirtual()) {
885 RS_LOGW("%{public}s: virtual screen not support SetScreenBacklight.", __func__);
886 return;
887 }
888 if (!hasLogBackLightAfterPowerStatusChanged_) {
889 RS_LOGI("%{public}s id: %{public}" PRIu64 ", level is %{public}u, current level is %{public}d", __func__, id_,
890 level, screenBacklightLevel_);
891 }
892
893 RS_LOGD("%{public}s id: %{public}" PRIu64 ", level is %{public}u", __func__, id_, level);
894 if (hdiScreen_->SetScreenBacklight(level) < 0) {
895 RS_LOGE("RSScreen_%{public}" PRIu64 " SetScreenBacklight error.", id_);
896 return;
897 }
898 if (!hasLogBackLightAfterPowerStatusChanged_) {
899 RS_LOGI("%{public}s id: %{public}" PRIu64 ", level is %{public}u done, last level is %{public}d", __func__, id_,
900 level, screenBacklightLevel_);
901 hasLogBackLightAfterPowerStatusChanged_ = true;
902 }
903 std::lock_guard<std::shared_mutex> lock(screenMutex_);
904 screenBacklightLevel_ = static_cast<int32_t>(level);
905 }
906
GetScreenBacklight() const907 int32_t RSScreen::GetScreenBacklight() const
908 {
909 if (IsVirtual()) {
910 RS_LOGW("%{public}s: virtual screen not support GetScreenBacklight.", __func__);
911 return INVALID_BACKLIGHT_VALUE;
912 }
913 uint32_t level = 0;
914 if (std::shared_lock<std::shared_mutex> lock(screenMutex_);
915 screenBacklightLevel_ != INVALID_BACKLIGHT_VALUE) {
916 return screenBacklightLevel_;
917 }
918 if (!hdiScreen_) {
919 RS_LOGE("%{public}s failed, hdiScreen_ is nullptr", __func__);
920 return INVALID_BACKLIGHT_VALUE;
921 }
922 if (hdiScreen_->GetScreenBacklight(level) < 0) {
923 RS_LOGE("%{public}s failed, level is invalid", __func__);
924 return INVALID_BACKLIGHT_VALUE;
925 }
926 return static_cast<int32_t>(level);
927 }
928
GetScreenSupportedColorGamuts(std::vector<ScreenColorGamut> & mode) const929 int32_t RSScreen::GetScreenSupportedColorGamuts(std::vector<ScreenColorGamut> &mode) const
930 {
931 mode.clear();
932 if (IsVirtual()) {
933 mode = supportedVirtualColorGamuts_;
934 } else {
935 mode = supportedPhysicalColorGamuts_;
936 }
937 if (mode.size() == 0) {
938 return StatusCode::HDI_ERROR;
939 }
940 return StatusCode::SUCCESS;
941 }
942
GetScreenSupportedMetaDataKeys(std::vector<ScreenHDRMetadataKey> & keys) const943 int32_t RSScreen::GetScreenSupportedMetaDataKeys(std::vector<ScreenHDRMetadataKey> &keys) const
944 {
945 if (IsVirtual()) {
946 RS_LOGW("%{public}s: virtual screen not support GetScreenSupportedMetaDataKeys.", __func__);
947 return INVALID_BACKLIGHT_VALUE;
948 }
949
950 // ScreenHDRMetadataKey now is mock data.
951 keys.push_back(ScreenHDRMetadataKey::MATAKEY_RED_PRIMARY_X);
952 keys.push_back(ScreenHDRMetadataKey::MATAKEY_RED_PRIMARY_Y);
953 keys.push_back(ScreenHDRMetadataKey::MATAKEY_GREEN_PRIMARY_X);
954 keys.push_back(ScreenHDRMetadataKey::MATAKEY_GREEN_PRIMARY_Y);
955 keys.push_back(ScreenHDRMetadataKey::MATAKEY_BLUE_PRIMARY_X);
956 keys.push_back(ScreenHDRMetadataKey::MATAKEY_BLUE_PRIMARY_Y);
957 keys.push_back(ScreenHDRMetadataKey::MATAKEY_WHITE_PRIMARY_X);
958 keys.push_back(ScreenHDRMetadataKey::MATAKEY_WHITE_PRIMARY_Y);
959 keys.push_back(ScreenHDRMetadataKey::MATAKEY_MAX_LUMINANCE);
960 keys.push_back(ScreenHDRMetadataKey::MATAKEY_MIN_LUMINANCE);
961 keys.push_back(ScreenHDRMetadataKey::MATAKEY_MAX_CONTENT_LIGHT_LEVEL);
962 keys.push_back(ScreenHDRMetadataKey::MATAKEY_MAX_FRAME_AVERAGE_LIGHT_LEVEL);
963 keys.push_back(ScreenHDRMetadataKey::MATAKEY_HDR10_PLUS);
964 keys.push_back(ScreenHDRMetadataKey::MATAKEY_HDR_VIVID);
965 return StatusCode::SUCCESS;
966 }
967
GetScreenColorGamut(ScreenColorGamut & mode) const968 int32_t RSScreen::GetScreenColorGamut(ScreenColorGamut &mode) const
969 {
970 if (IsVirtual()) {
971 mode = supportedVirtualColorGamuts_[currentVirtualColorGamutIdx_];
972 return StatusCode::SUCCESS;
973 }
974 if (supportedPhysicalColorGamuts_.size() == 0) {
975 RS_LOGE("%{public}s failed", __func__);
976 return StatusCode::HDI_ERROR;
977 }
978 mode = supportedPhysicalColorGamuts_[currentPhysicalColorGamutIdx_];
979 return StatusCode::SUCCESS;
980 }
981
SetScreenColorGamut(int32_t modeIdx)982 int32_t RSScreen::SetScreenColorGamut(int32_t modeIdx)
983 {
984 if (modeIdx < 0) {
985 return StatusCode::INVALID_ARGUMENTS;
986 }
987 if (IsVirtual()) {
988 if (modeIdx >= static_cast<int32_t>(supportedVirtualColorGamuts_.size())) {
989 return StatusCode::INVALID_ARGUMENTS;
990 }
991 currentVirtualColorGamutIdx_ = modeIdx;
992 return StatusCode::SUCCESS;
993 }
994 if (!hdiScreen_) {
995 RS_LOGE("%{public}s failed, hdiScreen_ is nullptr", __func__);
996 return StatusCode::HDI_ERROR;
997 }
998 std::vector<GraphicColorGamut> hdiMode;
999 if (hdiScreen_->GetScreenSupportedColorGamuts(hdiMode) != GRAPHIC_DISPLAY_SUCCESS) {
1000 return StatusCode::HDI_ERROR;
1001 }
1002 if (modeIdx >= static_cast<int32_t>(hdiMode.size())) {
1003 return StatusCode::INVALID_ARGUMENTS;
1004 }
1005 int32_t result = hdiScreen_->SetScreenColorGamut(hdiMode[modeIdx]);
1006 if (result == GRAPHIC_DISPLAY_SUCCESS) {
1007 currentPhysicalColorGamutIdx_ = modeIdx;
1008 return StatusCode::SUCCESS;
1009 }
1010 return StatusCode::HDI_ERROR;
1011 }
1012
SetScreenGamutMap(ScreenGamutMap mode)1013 int32_t RSScreen::SetScreenGamutMap(ScreenGamutMap mode)
1014 {
1015 if (IsVirtual()) {
1016 currentVirtualGamutMap_ = mode;
1017 return StatusCode::SUCCESS;
1018 }
1019 if (!hdiScreen_) {
1020 RS_LOGE("%{public}s failed, hdiScreen_ is nullptr", __func__);
1021 return StatusCode::HDI_ERROR;
1022 }
1023 int32_t result = hdiScreen_->SetScreenGamutMap(static_cast<GraphicGamutMap>(mode));
1024 if (result == GRAPHIC_DISPLAY_SUCCESS) {
1025 return StatusCode::SUCCESS;
1026 }
1027 return StatusCode::HDI_ERROR;
1028 }
1029
SetScreenCorrection(ScreenRotation screenRotation)1030 void RSScreen::SetScreenCorrection(ScreenRotation screenRotation)
1031 {
1032 RS_LOGI("%{public}s: RSScreen(id %{public}" PRIu64 ") ,ScreenRotation: %{public}d.", __func__,
1033 id_, static_cast<uint32_t>(screenRotation));
1034 screenRotation_ = screenRotation;
1035 }
1036
GetScreenCorrection() const1037 ScreenRotation RSScreen::GetScreenCorrection() const
1038 {
1039 return screenRotation_;
1040 }
1041
GetScreenGamutMap(ScreenGamutMap & mode) const1042 int32_t RSScreen::GetScreenGamutMap(ScreenGamutMap &mode) const
1043 {
1044 if (IsVirtual()) {
1045 mode = currentVirtualGamutMap_;
1046 return StatusCode::SUCCESS;
1047 }
1048 if (!hdiScreen_) {
1049 RS_LOGE("%{public}s failed, hdiScreen_ is nullptr", __func__);
1050 return StatusCode::HDI_ERROR;
1051 }
1052 GraphicGamutMap hdiMode;
1053 int32_t result = hdiScreen_->GetScreenGamutMap(hdiMode);
1054 if (result == GRAPHIC_DISPLAY_SUCCESS) {
1055 mode = static_cast<ScreenGamutMap>(hdiMode);
1056 return StatusCode::SUCCESS;
1057 }
1058 return StatusCode::HDI_ERROR;
1059 }
1060
GetHDRCapability()1061 const GraphicHDRCapability& RSScreen::GetHDRCapability()
1062 {
1063 hdrCapability_.maxLum = MAX_LUM; // mock data
1064 return hdrCapability_;
1065 }
1066
GetScreenType() const1067 const RSScreenType& RSScreen::GetScreenType() const
1068 {
1069 return screenType_;
1070 }
1071
SetScreenSkipFrameInterval(uint32_t skipFrameInterval)1072 void RSScreen::SetScreenSkipFrameInterval(uint32_t skipFrameInterval)
1073 {
1074 std::lock_guard<std::shared_mutex> lock(skipFrameMutex_);
1075 skipFrameInterval_ = skipFrameInterval;
1076 skipFrameStrategy_ = SKIP_FRAME_BY_INTERVAL;
1077 }
1078
SetScreenExpectedRefreshRate(uint32_t expectedRefreshRate)1079 void RSScreen::SetScreenExpectedRefreshRate(uint32_t expectedRefreshRate)
1080 {
1081 std::lock_guard<std::shared_mutex> lock(skipFrameMutex_);
1082 expectedRefreshRate_ = expectedRefreshRate;
1083 skipFrameStrategy_ = SKIP_FRAME_BY_REFRESH_RATE;
1084 }
1085
SetEqualVsyncPeriod(bool isEqualVsyncPeriod)1086 void RSScreen::SetEqualVsyncPeriod(bool isEqualVsyncPeriod)
1087 {
1088 std::lock_guard<std::shared_mutex> lock(skipFrameMutex_);
1089 isEqualVsyncPeriod_ = isEqualVsyncPeriod;
1090 }
1091
GetScreenSkipFrameInterval() const1092 uint32_t RSScreen::GetScreenSkipFrameInterval() const
1093 {
1094 std::shared_lock<std::shared_mutex> lock(skipFrameMutex_);
1095 return skipFrameInterval_;
1096 }
1097
GetScreenExpectedRefreshRate() const1098 uint32_t RSScreen::GetScreenExpectedRefreshRate() const
1099 {
1100 std::shared_lock<std::shared_mutex> lock(skipFrameMutex_);
1101 return expectedRefreshRate_;
1102 }
1103
GetScreenSkipFrameStrategy() const1104 SkipFrameStrategy RSScreen::GetScreenSkipFrameStrategy() const
1105 {
1106 std::shared_lock<std::shared_mutex> lock(skipFrameMutex_);
1107 return skipFrameStrategy_;
1108 }
1109
GetEqualVsyncPeriod() const1110 bool RSScreen::GetEqualVsyncPeriod() const
1111 {
1112 std::shared_lock<std::shared_mutex> lock(skipFrameMutex_);
1113 return isEqualVsyncPeriod_;
1114 }
1115
SetScreenVsyncEnabled(bool enabled) const1116 void RSScreen::SetScreenVsyncEnabled(bool enabled) const
1117 {
1118 if (IsVirtual()) {
1119 return;
1120 }
1121 if (hdiScreen_ != nullptr) {
1122 hdiScreen_->SetScreenVsyncEnabled(enabled);
1123 }
1124 }
1125
SetVirtualMirrorScreenCanvasRotation(bool canvasRotation)1126 bool RSScreen::SetVirtualMirrorScreenCanvasRotation(bool canvasRotation)
1127 {
1128 if (IsVirtual()) {
1129 canvasRotation_ = canvasRotation;
1130 return true;
1131 }
1132 return false;
1133 }
1134
GetCanvasRotation() const1135 bool RSScreen::GetCanvasRotation() const
1136 {
1137 return canvasRotation_;
1138 }
1139
SetVirtualScreenAutoRotation(bool isAutoRotation)1140 int32_t RSScreen::SetVirtualScreenAutoRotation(bool isAutoRotation)
1141 {
1142 if (IsVirtual()) {
1143 autoBufferRotation_ = isAutoRotation;
1144 return StatusCode::SUCCESS;
1145 }
1146 return StatusCode::INVALID_ARGUMENTS;
1147 }
1148
GetVirtualScreenAutoRotation() const1149 bool RSScreen::GetVirtualScreenAutoRotation() const
1150 {
1151 return autoBufferRotation_;
1152 }
1153
SetVirtualMirrorScreenScaleMode(ScreenScaleMode scaleMode)1154 bool RSScreen::SetVirtualMirrorScreenScaleMode(ScreenScaleMode scaleMode)
1155 {
1156 if (IsVirtual()) {
1157 scaleMode_ = scaleMode;
1158 return true;
1159 }
1160 return false;
1161 }
1162
GetScaleMode() const1163 ScreenScaleMode RSScreen::GetScaleMode() const
1164 {
1165 return scaleMode_;
1166 }
1167
GetScreenSupportedHDRFormats(std::vector<ScreenHDRFormat> & hdrFormats) const1168 int32_t RSScreen::GetScreenSupportedHDRFormats(std::vector<ScreenHDRFormat>& hdrFormats) const
1169 {
1170 hdrFormats.clear();
1171 if (IsVirtual()) {
1172 hdrFormats = supportedVirtualHDRFormats_;
1173 } else {
1174 hdrFormats = supportedPhysicalHDRFormats_;
1175 }
1176 if (hdrFormats.size() == 0) {
1177 return StatusCode::HDI_ERROR;
1178 }
1179 return StatusCode::SUCCESS;
1180 }
1181
GetScreenHDRFormat(ScreenHDRFormat & hdrFormat) const1182 int32_t RSScreen::GetScreenHDRFormat(ScreenHDRFormat& hdrFormat) const
1183 {
1184 if (IsVirtual()) {
1185 hdrFormat = supportedVirtualHDRFormats_[currentVirtualHDRFormatIdx_];
1186 return StatusCode::SUCCESS;
1187 } else {
1188 if (supportedPhysicalHDRFormats_.size() == 0) {
1189 return StatusCode::HDI_ERROR;
1190 }
1191 hdrFormat = supportedPhysicalHDRFormats_[currentPhysicalHDRFormatIdx_];
1192 return StatusCode::SUCCESS;
1193 }
1194 return StatusCode::HDI_ERROR;
1195 }
1196
SetScreenHDRFormat(int32_t modeIdx)1197 int32_t RSScreen::SetScreenHDRFormat(int32_t modeIdx)
1198 {
1199 if (modeIdx < 0) {
1200 return StatusCode::INVALID_ARGUMENTS;
1201 }
1202 if (IsVirtual()) {
1203 if (modeIdx >= static_cast<int32_t>(supportedVirtualHDRFormats_.size())) {
1204 return StatusCode::INVALID_ARGUMENTS;
1205 }
1206 currentVirtualHDRFormatIdx_ = modeIdx;
1207 return StatusCode::SUCCESS;
1208 } else {
1209 // There should be some hdi operation
1210 if (modeIdx >= static_cast<int32_t>(hdrCapability_.formats.size())) {
1211 return StatusCode::INVALID_ARGUMENTS;
1212 }
1213 currentPhysicalHDRFormatIdx_ = modeIdx;
1214 return StatusCode::SUCCESS;
1215 }
1216 return StatusCode::HDI_ERROR;
1217 }
1218
GetPixelFormat(GraphicPixelFormat & pixelFormat) const1219 int32_t RSScreen::GetPixelFormat(GraphicPixelFormat& pixelFormat) const
1220 {
1221 pixelFormat = pixelFormat_;
1222 return StatusCode::SUCCESS;
1223 }
1224
SetPixelFormat(GraphicPixelFormat pixelFormat)1225 int32_t RSScreen::SetPixelFormat(GraphicPixelFormat pixelFormat)
1226 {
1227 pixelFormat_ = pixelFormat;
1228 return StatusCode::SUCCESS;
1229 }
1230
GetScreenSupportedColorSpaces(std::vector<GraphicCM_ColorSpaceType> & colorSpaces) const1231 int32_t RSScreen::GetScreenSupportedColorSpaces(std::vector<GraphicCM_ColorSpaceType>& colorSpaces) const
1232 {
1233 colorSpaces.clear();
1234 if (IsVirtual()) {
1235 std::transform(supportedVirtualColorGamuts_.begin(), supportedVirtualColorGamuts_.end(),
1236 back_inserter(colorSpaces),
1237 [](ScreenColorGamut item) -> GraphicCM_ColorSpaceType {
1238 return RS_TO_COMMON_COLOR_SPACE_TYPE_MAP[static_cast<GraphicColorGamut>(item)];
1239 });
1240 } else {
1241 std::transform(supportedPhysicalColorGamuts_.begin(), supportedPhysicalColorGamuts_.end(),
1242 back_inserter(colorSpaces),
1243 [](ScreenColorGamut item) -> GraphicCM_ColorSpaceType {
1244 return RS_TO_COMMON_COLOR_SPACE_TYPE_MAP[static_cast<GraphicColorGamut>(item)];
1245 });
1246 }
1247 if (colorSpaces.size() == 0) {
1248 return StatusCode::HDI_ERROR;
1249 }
1250 return StatusCode::SUCCESS;
1251 }
1252
GetScreenColorSpace(GraphicCM_ColorSpaceType & colorSpace) const1253 int32_t RSScreen::GetScreenColorSpace(GraphicCM_ColorSpaceType& colorSpace) const
1254 {
1255 ScreenColorGamut curGamut;
1256 int32_t result = GetScreenColorGamut(curGamut);
1257 colorSpace = RS_TO_COMMON_COLOR_SPACE_TYPE_MAP[static_cast<GraphicColorGamut>(curGamut)];
1258 return result;
1259 }
1260
SetScreenColorSpace(GraphicCM_ColorSpaceType colorSpace)1261 int32_t RSScreen::SetScreenColorSpace(GraphicCM_ColorSpaceType colorSpace)
1262 {
1263 auto iter = COMMON_COLOR_SPACE_TYPE_TO_RS_MAP.find(colorSpace);
1264 if (iter == COMMON_COLOR_SPACE_TYPE_TO_RS_MAP.end()) {
1265 return StatusCode::INVALID_ARGUMENTS;
1266 }
1267 ScreenColorGamut dstColorGamut = static_cast<ScreenColorGamut>(iter->second);
1268 int32_t curIdx;
1269 if (IsVirtual()) {
1270 auto it = std::find(supportedVirtualColorGamuts_.begin(), supportedVirtualColorGamuts_.end(), dstColorGamut);
1271 if (it == supportedVirtualColorGamuts_.end()) {
1272 return StatusCode::INVALID_ARGUMENTS;
1273 }
1274 curIdx = std::distance(supportedVirtualColorGamuts_.begin(), it);
1275 currentVirtualColorGamutIdx_ = curIdx;
1276 return StatusCode::SUCCESS;
1277 }
1278 if (!hdiScreen_) {
1279 RS_LOGE("%{public}s failed, hdiScreen_ is nullptr", __func__);
1280 return StatusCode::HDI_ERROR;
1281 }
1282 std::vector<GraphicColorGamut> hdiMode;
1283 if (hdiScreen_->GetScreenSupportedColorGamuts(hdiMode) != GRAPHIC_DISPLAY_SUCCESS) {
1284 return StatusCode::HDI_ERROR;
1285 }
1286 auto it = std::find(hdiMode.begin(), hdiMode.end(), static_cast<GraphicColorGamut>(dstColorGamut));
1287 if (it == hdiMode.end()) {
1288 return StatusCode::INVALID_ARGUMENTS;
1289 }
1290 curIdx = std::distance(hdiMode.begin(), it);
1291 int32_t result = hdiScreen_->SetScreenColorGamut(hdiMode[curIdx]);
1292 if (result == GRAPHIC_DISPLAY_SUCCESS) {
1293 currentPhysicalColorGamutIdx_ = curIdx;
1294 return StatusCode::SUCCESS;
1295 }
1296 return StatusCode::HDI_ERROR;
1297 }
1298
GetWhiteList() const1299 const std::unordered_set<uint64_t>& RSScreen::GetWhiteList() const
1300 {
1301 return whiteList_;
1302 }
1303
SetBlackList(const std::unordered_set<uint64_t> & blackList)1304 void RSScreen::SetBlackList(const std::unordered_set<uint64_t>& blackList)
1305 {
1306 std::lock_guard<std::mutex> lock(blackListMutex_);
1307 blackList_ = blackList;
1308 }
1309
SetTypeBlackList(const std::unordered_set<uint8_t> & typeBlackList)1310 void RSScreen::SetTypeBlackList(const std::unordered_set<uint8_t>& typeBlackList)
1311 {
1312 std::lock_guard<std::mutex> lock(typeBlackListMutex_);
1313 typeBlackList_ = typeBlackList;
1314 }
1315
AddBlackList(const std::vector<uint64_t> & blackList)1316 void RSScreen::AddBlackList(const std::vector<uint64_t>& blackList)
1317 {
1318 std::lock_guard<std::mutex> lock(blackListMutex_);
1319 blackList_.insert(blackList.cbegin(), blackList.cend());
1320 }
1321
RemoveBlackList(const std::vector<uint64_t> & blackList)1322 void RSScreen::RemoveBlackList(const std::vector<uint64_t>& blackList)
1323 {
1324 std::lock_guard<std::mutex> lock(blackListMutex_);
1325 for (const auto& list : blackList) {
1326 blackList_.erase(list);
1327 }
1328 }
1329
SetCastScreenEnableSkipWindow(bool enable)1330 void RSScreen::SetCastScreenEnableSkipWindow(bool enable)
1331 {
1332 skipWindow_ = enable;
1333 }
1334
GetCastScreenEnableSkipWindow()1335 bool RSScreen::GetCastScreenEnableSkipWindow()
1336 {
1337 return skipWindow_;
1338 }
1339
GetBlackList() const1340 const std::unordered_set<uint64_t> RSScreen::GetBlackList() const
1341 {
1342 std::lock_guard<std::mutex> lock(blackListMutex_);
1343 return blackList_;
1344 }
1345
GetTypeBlackList() const1346 const std::unordered_set<uint8_t> RSScreen::GetTypeBlackList() const
1347 {
1348 std::lock_guard<std::mutex> lock(typeBlackListMutex_);
1349 return typeBlackList_;
1350 }
1351
SetScreenConstraint(uint64_t frameId,uint64_t timestamp,ScreenConstraintType type)1352 int32_t RSScreen::SetScreenConstraint(uint64_t frameId, uint64_t timestamp, ScreenConstraintType type)
1353 {
1354 if (IsVirtual()) {
1355 return StatusCode::SUCCESS;
1356 }
1357 if (hdiScreen_ != nullptr) {
1358 int32_t result = hdiScreen_->SetScreenConstraint(frameId, timestamp, static_cast<uint32_t>(type));
1359 if (result == GRAPHIC_DISPLAY_SUCCESS) {
1360 return StatusCode::SUCCESS;
1361 }
1362 }
1363 return StatusCode::HDI_ERROR;
1364 }
1365
SetSecurityExemptionList(const std::vector<uint64_t> & securityExemptionList)1366 void RSScreen::SetSecurityExemptionList(const std::vector<uint64_t>& securityExemptionList)
1367 {
1368 std::lock_guard<std::mutex> lock(securityExemptionMutex_);
1369 securityExemptionList_ = securityExemptionList;
1370 }
1371
GetSecurityExemptionList() const1372 const std::vector<uint64_t> RSScreen::GetSecurityExemptionList() const
1373 {
1374 std::lock_guard<std::mutex> lock(securityExemptionMutex_);
1375 return securityExemptionList_;
1376 }
1377
SetSecurityMask(std::shared_ptr<Media::PixelMap> securityMask)1378 int32_t RSScreen::SetSecurityMask(std::shared_ptr<Media::PixelMap> securityMask)
1379 {
1380 std::lock_guard<std::mutex> lock(securityMaskMutex_);
1381 securityMask_ = securityMask;
1382 return SUCCESS;
1383 }
1384
GetSecurityMask() const1385 std::shared_ptr<Media::PixelMap> RSScreen::GetSecurityMask() const
1386 {
1387 std::lock_guard<std::mutex> lock(securityMaskMutex_);
1388 return securityMask_;
1389 }
1390
SetEnableVisibleRect(bool enable)1391 void RSScreen::SetEnableVisibleRect(bool enable)
1392 {
1393 enableVisibleRect_ = enable;
1394 }
1395
GetEnableVisibleRect() const1396 bool RSScreen::GetEnableVisibleRect() const
1397 {
1398 return enableVisibleRect_;
1399 }
1400
SetMainScreenVisibleRect(const Rect & mainScreenRect)1401 void RSScreen::SetMainScreenVisibleRect(const Rect& mainScreenRect)
1402 {
1403 std::lock_guard<std::mutex> lock(visibleRectMutex_);
1404 mainScreenVisibleRect_ = mainScreenRect;
1405 }
1406
GetMainScreenVisibleRect() const1407 Rect RSScreen::GetMainScreenVisibleRect() const
1408 {
1409 std::lock_guard<std::mutex> lock(visibleRectMutex_);
1410 return mainScreenVisibleRect_;
1411 }
1412
GetVisibleRectSupportRotation() const1413 bool RSScreen::GetVisibleRectSupportRotation() const
1414 {
1415 return isSupportRotation_;
1416 }
1417
SetVisibleRectSupportRotation(bool supportRotation)1418 void RSScreen::SetVisibleRectSupportRotation(bool supportRotation)
1419 {
1420 isSupportRotation_ = supportRotation;
1421 }
1422
SetVirtualScreenStatus(VirtualScreenStatus screenStatus)1423 bool RSScreen::SetVirtualScreenStatus(VirtualScreenStatus screenStatus)
1424 {
1425 if (IsVirtual()) {
1426 screenStatus_ = screenStatus;
1427 return true;
1428 }
1429 return false;
1430 }
1431
GetVirtualScreenStatus() const1432 VirtualScreenStatus RSScreen::GetVirtualScreenStatus() const
1433 {
1434 return screenStatus_;
1435 }
1436
GetDisplayPropertyForHardCursor()1437 bool RSScreen::GetDisplayPropertyForHardCursor()
1438 {
1439 std::call_once(hardCursorSupportedFlag_, [this]() {
1440 if (hdiScreen_) {
1441 isHardCursorSupport_ = hdiScreen_->GetDisplayPropertyForHardCursor(id_);
1442 }
1443 RS_LOGI("%{public}s, RSScreen(id %{public}" PRIu64 ", isHardCursorSupport:%{public}d)",
1444 __func__, id_, isHardCursorSupport_);
1445 });
1446 return isHardCursorSupport_;
1447 }
1448
SetHasProtectedLayer(bool hasProtectedLayer)1449 void RSScreen::SetHasProtectedLayer(bool hasProtectedLayer)
1450 {
1451 hasProtectedLayer_ = hasProtectedLayer;
1452 }
1453
GetHasProtectedLayer()1454 bool RSScreen::GetHasProtectedLayer()
1455 {
1456 return hasProtectedLayer_;
1457 }
1458
GetDisplayIdentificationData(uint8_t & outPort,std::vector<uint8_t> & edidData) const1459 int32_t RSScreen::GetDisplayIdentificationData(uint8_t& outPort, std::vector<uint8_t>& edidData) const
1460 {
1461 if (hdiScreen_ == nullptr) {
1462 RS_LOGE("%{public}s: id: %{public}" PRIu64 " is not physical display", __func__, id_);
1463 return HDI_ERROR;
1464 }
1465
1466 int32_t ret = hdiScreen_->GetDisplayIdentificationData(outPort, edidData);
1467 if (ret != GRAPHIC_DISPLAY_SUCCESS) {
1468 RS_LOGE("%{public}s: id %{public}" PRIu64 " call hid interface failed(%{public}d)",
1469 __func__, id_, ret);
1470 return HDI_ERROR;
1471 }
1472 RS_LOGD("%{public}s:: EdidSize: %{public}zu", __func__, edidData.size());
1473 return SUCCESS;
1474 }
1475
SetScreenLinearMatrix(const std::vector<float> & matrix)1476 int32_t RSScreen::SetScreenLinearMatrix(const std::vector<float> &matrix)
1477 {
1478 if (IsVirtual()) {
1479 RS_LOGW("%{public}s: virtual screen not support SetScreenLinearMatrix.", __func__);
1480 return StatusCode::VIRTUAL_SCREEN;
1481 }
1482 if (!hdiScreen_) {
1483 RS_LOGE("%{public}s failed, hdiScreen_ is nullptr", __func__);
1484 return StatusCode::HDI_ERROR;
1485 }
1486 if (linearMatrix_ == matrix) {
1487 return StatusCode::SUCCESS;
1488 }
1489 if (hdiScreen_->SetScreenLinearMatrix(matrix) < 0) {
1490 RS_LOGI("%{public}s failed, matrix is invalid", __func__);
1491 return StatusCode::INVALID_ARGUMENTS;
1492 }
1493
1494 linearMatrix_ = matrix;
1495 return StatusCode::SUCCESS;
1496 }
1497
GetVirtualSecLayerOption() const1498 int32_t RSScreen::GetVirtualSecLayerOption() const
1499 {
1500 return virtualSecLayerOption_;
1501 }
1502
GetAndResetPSurfaceChange()1503 bool RSScreen::GetAndResetPSurfaceChange()
1504 {
1505 bool expected = true;
1506 return pSurfaceChange_.compare_exchange_strong(expected, false);
1507 }
1508
1509 // only used in virtual screen
SetPSurfaceChange(bool pSurfaceChange)1510 void RSScreen::SetPSurfaceChange(bool pSurfaceChange)
1511 {
1512 pSurfaceChange_ = pSurfaceChange;
1513 }
1514 } // namespace impl
1515 } // namespace Rosen
1516 } // namespace OHOS
1517