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