• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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