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 #include "hgm_task_handle_thread.h"
21
22 namespace OHOS::Rosen {
HgmScreen()23 HgmScreen::HgmScreen() {}
24
HgmScreen(ScreenId id,int32_t mode,ScreenSize & screenSize)25 HgmScreen::HgmScreen(ScreenId id, int32_t mode, ScreenSize& screenSize)
26 : id_(id), activeModeId_(mode), width_(screenSize.width), height_(screenSize.height),
27 phyWidth_(screenSize.phyWidth), phyHeight_(screenSize.phyHeight)
28 {
29 auto screenLength = sqrt(pow(screenSize.width, 2) + pow(screenSize.height, 2));
30 auto phyScreenLength = sqrt(pow(screenSize.phyWidth, 2) + pow(screenSize.phyHeight, 2));
31 if (phyScreenLength != 0) {
32 ppi_ = screenLength / (phyScreenLength / INCH_2_MM);
33 }
34 if (screenSize.phyWidth != 0) {
35 xDpi_ = screenSize.width / (screenSize.phyWidth / INCH_2_MM);
36 }
37 if (screenSize.phyHeight != 0) {
38 yDpi_ = screenSize.height / (screenSize.phyHeight / INCH_2_MM);
39 }
40 }
41
~HgmScreen()42 HgmScreen::~HgmScreen() {}
43
GetActiveRefreshRate() const44 uint32_t HgmScreen::GetActiveRefreshRate() const
45 {
46 auto profilePtr = GetModeViaId(activeModeId_);
47 if (!profilePtr) {
48 HGM_LOGI("HgmScreen current mode is not supported, failed to get refreshrate");
49 return RATE_NOT_SUPPORTED;
50 }
51
52 return profilePtr->GetRate();
53 }
54
SetActiveRefreshRate(int32_t sceneId,uint32_t rate)55 int32_t HgmScreen::SetActiveRefreshRate(int32_t sceneId, uint32_t rate)
56 {
57 // check if this screen supports the requested rate
58 if (supportedRefreshRates_.find(rate) == supportedRefreshRates_.end()) {
59 HGM_LOGE("HgmScreen refreshrate %{public}u is not supported, abandoned", rate);
60 return HGM_ERROR;
61 }
62
63 // decide if this rate should be accepted
64 if (!IfSwitchToRate(sceneId, rate)) {
65 return HGM_ERROR;
66 }
67
68 int32_t modeIdToApply = GetModeIdViaRate(rate);
69 if (modeIdToApply >= 0) {
70 SetActiveModeId(modeIdToApply);
71 }
72 return modeIdToApply;
73 }
74
SetRateAndResolution(int32_t sceneId,uint32_t rate,int32_t width,int32_t height)75 int32_t HgmScreen::SetRateAndResolution(int32_t sceneId, uint32_t rate, int32_t width, int32_t height)
76 {
77 if (!IfSwitchToRate(sceneId, rate)) {
78 return HGM_ERROR;
79 }
80
81 int32_t modeIdToApply = GetModeIdViaResolutionAndRate(width, height, rate);
82 if (modeIdToApply >= 0) {
83 SetActiveModeId(modeIdToApply);
84 }
85 return modeIdToApply;
86 }
87
SetRefreshRateRange(uint32_t minRate,uint32_t maxRate)88 int32_t HgmScreen::SetRefreshRateRange(uint32_t minRate, uint32_t maxRate)
89 {
90 minRefreshRateRange_ = minRate;
91 maxRefreshRateRange_ = maxRate;
92 return EXEC_SUCCESS;
93 }
94
AddScreenModeInfo(int32_t width,int32_t height,uint32_t rate,int32_t modeId)95 int32_t HgmScreen::AddScreenModeInfo(int32_t width, int32_t height, uint32_t rate, int32_t modeId)
96 {
97 HgmTaskHandleThread::Instance().DetectMultiThreadingCalls();
98 if (supportedModeIds_.find(modeId) == supportedModeIds_.end()) {
99 supportedModeIds_.emplace(modeId);
100 } else {
101 return HGM_SCREEN_MODE_EXIST;
102 }
103
104 if (supportedRefreshRates_.find(rate) == supportedRefreshRates_.end()) {
105 supportedRefreshRates_.emplace(rate);
106 }
107
108 auto newProfile = std::make_shared<ScreenProfile>(width, height, rate, modeId);
109 screenModeInfos_.emplace_back(newProfile);
110 return EXEC_SUCCESS;
111 }
112
SetActiveModeId(int32_t modeId)113 void HgmScreen::SetActiveModeId(int32_t modeId)
114 {
115 HGM_LOGD("HgmScreen setting activeModeId to %{public}d", modeId);
116 activeModeId_ = modeId;
117 }
118
GetModeViaId(int32_t id) const119 std::shared_ptr<HgmScreen::ScreenProfile> HgmScreen::GetModeViaId(int32_t id) const
120 {
121 for (auto mode : screenModeInfos_) {
122 if (mode->GetModeId() != id) {
123 continue;
124 }
125 return mode;
126 }
127
128 HGM_LOGW("HgmScreen failed to get activeMode via modeId : %{public}d", id);
129 return nullptr;
130 }
131
IfSwitchToRate(int32_t sceneId,uint32_t rate) const132 bool HgmScreen::IfSwitchToRate(int32_t sceneId, uint32_t rate) const
133 {
134 // decides if a refreshrate switch will be accepted or not
135 auto profilePtr = GetModeViaId(activeModeId_);
136 bool ifSwitch = false;
137
138 if (!profilePtr) {
139 return ifSwitch;
140 }
141
142 if (rate == profilePtr->GetRate() || sceneId < 0) {
143 HGM_LOGI("HgmScreen Set framerate to %{public}u is rejected!!!", rate);
144 return ifSwitch;
145 }
146
147 ifSwitch = true;
148 HGM_LOGD("HgmScreen Set framerate to %{public}u is accepted", rate);
149 return ifSwitch;
150 }
151
GetModeIdViaRate(uint32_t rate) const152 int32_t HgmScreen::GetModeIdViaRate(uint32_t rate) const
153 {
154 // get the corresponding mode id with the given refreshrate, using the current resolution
155 auto supportedRates = supportedRefreshRates_.find(rate);
156 if (supportedRates == supportedRefreshRates_.end()) {
157 HGM_LOGE("HgmScreen freshrate %{public}u is not supported by any modeId", rate);
158 return HGM_ERROR;
159 }
160
161 auto profilePtr = GetModeViaId(activeModeId_);
162 if (!profilePtr) {
163 HGM_LOGW("HgmScreen activeMode is not among supported modes");
164 return HGM_ERROR;
165 }
166
167 HGM_LOGD("HgmScreen getting a new mode with the resolution of current mode : %{public}d", activeModeId_);
168 int32_t mode = GetModeIdViaResolutionAndRate(profilePtr->GetWidth(), profilePtr->GetHeight(), rate);
169 return mode;
170 }
171
GetModeIdViaResolutionAndRate(int32_t width,int32_t height,uint32_t rate) const172 int32_t HgmScreen::GetModeIdViaResolutionAndRate(int32_t width, int32_t height, uint32_t rate) const
173 {
174 // get the corresponding mode id with the given resolution and refreshrate
175 for (const auto& mode : screenModeInfos_) {
176 if (mode->GetRate() != rate || mode->GetWidth() != width || mode->GetHeight() != height) {
177 continue;
178 }
179 int32_t modeIdFound = mode->GetModeId();
180 HGM_LOGD("HgmScreen mode : %{public}d is found for w : %{public}d, h : %{public}d, rate : %{public}u",
181 modeIdFound, width, height, rate);
182 return modeIdFound;
183 }
184
185 HGM_LOGW("HgmScreen NO mode is found for w : %{public}d, h : %{public}d, rate : %{public}u",
186 width, height, rate);
187 return HGM_ERROR;
188 }
189 } // namespace OHOS::Rosen