• 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 "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