1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "hgm_screen.h"
17
18 #include <cmath>
19 #include "hgm_log.h"
20
21 namespace OHOS::Rosen {
HgmScreen()22 HgmScreen::HgmScreen() {}
23
HgmScreen(ScreenId id,int32_t mode,ScreenSize & screenSize)24 HgmScreen::HgmScreen(ScreenId id, int32_t mode, ScreenSize& screenSize)
25 : id_(id), activeModeId_(mode), width_(screenSize.width), height_(screenSize.height),
26 phyWidth_(screenSize.phyWidth), phyHeight_(screenSize.phyHeight)
27 {
28 auto screenLength = sqrt(pow(screenSize.width, 2) + pow(screenSize.height, 2));
29 auto phyScreenLength = sqrt(pow(screenSize.phyWidth, 2) + pow(screenSize.phyHeight, 2));
30 if (phyScreenLength != 0) {
31 ppi_ = screenLength / (phyScreenLength / INCH_2_MM);
32 }
33 if (screenSize.phyWidth != 0) {
34 xDpi_ = screenSize.width / (screenSize.phyWidth / INCH_2_MM);
35 }
36 if (screenSize.phyHeight != 0) {
37 yDpi_ = screenSize.height / (screenSize.phyHeight / INCH_2_MM);
38 }
39 }
40
~HgmScreen()41 HgmScreen::~HgmScreen() {}
42
GetActiveRefreshRate() const43 uint32_t HgmScreen::GetActiveRefreshRate() const
44 {
45 auto profilePtr = GetModeViaId(activeModeId_);
46 if (!profilePtr) {
47 HGM_LOGI("HgmScreen current mode is not supported, failed to get refreshrate");
48 return RATE_NOT_SUPPORTED;
49 }
50
51 return profilePtr->GetRate();
52 }
53
SetActiveRefreshRate(int32_t sceneId,uint32_t rate)54 int32_t HgmScreen::SetActiveRefreshRate(int32_t sceneId, uint32_t rate)
55 {
56 // check if this screen supports the requested rate
57 if (supportedRefreshRates_.find(rate) == supportedRefreshRates_.end()) {
58 HGM_LOGE("HgmScreen refreshrate %{public}u is not supported, abandoned", rate);
59 return HGM_ERROR;
60 }
61
62 // decide if this rate should be accepted
63 if (!IfSwitchToRate(sceneId, rate)) {
64 return HGM_ERROR;
65 }
66
67 int32_t modeIdToApply = GetModeIdViaRate(rate);
68 if (modeIdToApply >= 0) {
69 SetActiveModeId(modeIdToApply);
70 }
71 return modeIdToApply;
72 }
73
SetRateAndResolution(int32_t sceneId,uint32_t rate,int32_t width,int32_t height)74 int32_t HgmScreen::SetRateAndResolution(int32_t sceneId, uint32_t rate, int32_t width, int32_t height)
75 {
76 if (!IfSwitchToRate(sceneId, rate)) {
77 return HGM_ERROR;
78 }
79
80 int32_t modeIdToApply = GetModeIdViaResolutionAndRate(width, height, rate);
81 if (modeIdToApply >= 0) {
82 SetActiveModeId(modeIdToApply);
83 }
84 return modeIdToApply;
85 }
86
SetRefreshRateRange(uint32_t minRate,uint32_t maxRate)87 int32_t HgmScreen::SetRefreshRateRange(uint32_t minRate, uint32_t maxRate)
88 {
89 minRefreshRateRange_ = minRate;
90 maxRefreshRateRange_ = maxRate;
91 return EXEC_SUCCESS;
92 }
93
AddScreenModeInfo(int32_t width,int32_t height,uint32_t rate,int32_t modeId)94 int32_t HgmScreen::AddScreenModeInfo(int32_t width, int32_t height, uint32_t rate, int32_t modeId)
95 {
96 if (supportedModeIds_.find(modeId) == supportedModeIds_.end()) {
97 supportedModeIds_.emplace(modeId);
98 } else {
99 return HGM_SCREEN_MODE_EXIST;
100 }
101
102 if (supportedRefreshRates_.find(rate) == supportedRefreshRates_.end()) {
103 supportedRefreshRates_.emplace(rate);
104 }
105
106 auto newProfile = std::make_shared<ScreenProfile>(width, height, rate, modeId);
107 screenModeInfos_.emplace_back(newProfile);
108 return EXEC_SUCCESS;
109 }
110
SetActiveModeId(int32_t modeId)111 void HgmScreen::SetActiveModeId(int32_t modeId)
112 {
113 HGM_LOGD("HgmScreen setting activeModeId to %{public}d", modeId);
114 activeModeId_ = modeId;
115 }
116
GetModeViaId(int32_t id) const117 std::shared_ptr<HgmScreen::ScreenProfile> HgmScreen::GetModeViaId(int32_t id) const
118 {
119 for (auto mode : screenModeInfos_) {
120 if (mode->GetModeId() != id) {
121 continue;
122 }
123 return mode;
124 }
125
126 HGM_LOGW("HgmScreen failed to get activeMode via modeId : %{public}d", id);
127 return nullptr;
128 }
129
IfSwitchToRate(int32_t sceneId,uint32_t rate) const130 bool HgmScreen::IfSwitchToRate(int32_t sceneId, uint32_t rate) const
131 {
132 // decides if a refreshrate switch will be accepted or not
133 auto profilePtr = GetModeViaId(activeModeId_);
134 bool ifSwitch = false;
135
136 if (!profilePtr) {
137 return ifSwitch;
138 }
139
140 if (rate == profilePtr->GetRate() || sceneId < 0) {
141 HGM_LOGI("HgmScreen Set framerate to %{public}u is rejected!!!", rate);
142 return ifSwitch;
143 }
144
145 ifSwitch = true;
146 HGM_LOGD("HgmScreen Set framerate to %{public}u is accepted", rate);
147 return ifSwitch;
148 }
149
GetModeIdViaRate(uint32_t rate) const150 int32_t HgmScreen::GetModeIdViaRate(uint32_t rate) const
151 {
152 // get the corresponding mode id with the given refreshrate, using the current resolution
153 auto supportedRates = supportedRefreshRates_.find(rate);
154 if (supportedRates == supportedRefreshRates_.end()) {
155 HGM_LOGE("HgmScreen freshrate %{public}u is not supported by any modeId", rate);
156 return HGM_ERROR;
157 }
158
159 auto profilePtr = GetModeViaId(activeModeId_);
160 if (!profilePtr) {
161 HGM_LOGW("HgmScreen activeMode is not among supported modes");
162 return HGM_ERROR;
163 }
164
165 HGM_LOGD("HgmScreen getting a new mode with the resolution of current mode : %{public}d", activeModeId_);
166 int32_t mode = GetModeIdViaResolutionAndRate(profilePtr->GetWidth(), profilePtr->GetHeight(), rate);
167 return mode;
168 }
169
GetModeIdViaResolutionAndRate(int32_t width,int32_t height,uint32_t rate) const170 int32_t HgmScreen::GetModeIdViaResolutionAndRate(int32_t width, int32_t height, uint32_t rate) const
171 {
172 // get the corresponding mode id with the given resolution and refreshrate
173 for (const auto& mode : screenModeInfos_) {
174 if (mode->GetRate() != rate || mode->GetWidth() != width || mode->GetHeight() != height) {
175 continue;
176 }
177 int32_t modeIdFound = mode->GetModeId();
178 HGM_LOGD("HgmScreen mode : %{public}d is found for w : %{public}d, h : %{public}d, rate : %{public}u",
179 modeIdFound, width, height, rate);
180 return modeIdFound;
181 }
182
183 HGM_LOGW("HgmScreen NO mode is found for w : %{public}d, h : %{public}d, rate : %{public}u",
184 width, height, rate);
185 return HGM_ERROR;
186 }
187 } // namespace OHOS::Rosen