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