1 /*
2 * Copyright (c) 2024 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_energy_consumption_policy.h"
17
18 #include <functional>
19
20 #include "hgm_core.h"
21 #include "hgm_log.h"
22 #include "rs_trace.h"
23 #include "xml_parser.h"
24
25 #include "common/rs_common_def.h"
26 #include "common/rs_common_hook.h"
27
28 namespace OHOS::Rosen {
29 static const std::string IS_ANIMATION_ENERGY_ASSURANCE_ENABLE = "animation_energy_assurance_enable";
30 static const std::string ANIMATION_IDLE_FPS = "animation_idle_fps";
31 static const std::string ANIMATION_IDLE_DURATION = "animation_idle_duration";
32 static const std::unordered_map<std::string, int32_t> UI_RATE_TYPE_NAME_MAP = {
33 {"ui_animation", UI_ANIMATION_FRAME_RATE_TYPE },
34 {"display_sync", DISPLAY_SYNC_FRAME_RATE_TYPE },
35 {"ace_component", ACE_COMPONENT_FRAME_RATE_TYPE },
36 {"display_soloist", DISPLAY_SOLOIST_FRAME_RATE_TYPE },
37 };
38 constexpr int DEFAULT_ENERGY_ASSURANCE_IDLE_FPS = 60;
39 constexpr int DEFAULT_ANIMATION_IDLE_DURATION = 2000;
40
HgmEnergyConsumptionPolicy()41 HgmEnergyConsumptionPolicy::HgmEnergyConsumptionPolicy()
42 {
43 RsCommonHook::Instance().RegisterStartNewAnimationListener(
44 std::bind(&HgmEnergyConsumptionPolicy::StartNewAnimation, this));
45 }
46
Instance()47 HgmEnergyConsumptionPolicy& HgmEnergyConsumptionPolicy::Instance()
48 {
49 static HgmEnergyConsumptionPolicy hlpp;
50 return hlpp;
51 }
52
ConverStrToInt(int & targetNum,std::string sourceStr,int defaultValue)53 void HgmEnergyConsumptionPolicy::ConverStrToInt(int& targetNum, std::string sourceStr, int defaultValue)
54 {
55 if (!XMLParser::IsNumber(sourceStr)) {
56 targetNum = defaultValue;
57 return;
58 }
59 targetNum = std::stoi(sourceStr.c_str());
60 }
61
SetEnergyConsumptionConfig(std::unordered_map<std::string,std::string> animationPowerConfig)62 void HgmEnergyConsumptionPolicy::SetEnergyConsumptionConfig(
63 std::unordered_map<std::string, std::string> animationPowerConfig)
64 {
65 std::lock_guard<std::recursive_mutex> lock(mutex_);
66 if (animationPowerConfig.count(IS_ANIMATION_ENERGY_ASSURANCE_ENABLE) == 0) {
67 isAnimationEnergyAssuranceEnable_ = false;
68 } else {
69 isAnimationEnergyAssuranceEnable_ =
70 animationPowerConfig[IS_ANIMATION_ENERGY_ASSURANCE_ENABLE] == "true" ? true : false;
71 }
72 if (!isAnimationEnergyAssuranceEnable_) {
73 HGM_LOGD("HgmEnergyConsumptionPolicy::SetEnergyConsumptionConfig isAnimationLtpoPowerEnable is false");
74 return;
75 }
76
77 if (animationPowerConfig.count(ANIMATION_IDLE_FPS) == 0) {
78 animationIdleFps_ = DEFAULT_ENERGY_ASSURANCE_IDLE_FPS;
79 } else {
80 ConverStrToInt(animationIdleFps_, animationPowerConfig[ANIMATION_IDLE_FPS], DEFAULT_ENERGY_ASSURANCE_IDLE_FPS);
81 }
82
83 if (animationPowerConfig.count(ANIMATION_IDLE_DURATION) == 0) {
84 animationIdleDuration_ = DEFAULT_ANIMATION_IDLE_DURATION;
85 } else {
86 ConverStrToInt(
87 animationIdleDuration_, animationPowerConfig[ANIMATION_IDLE_DURATION], DEFAULT_ANIMATION_IDLE_DURATION);
88 }
89 HGM_LOGD("HgmEnergyConsumptionPolicy::SetEnergyConsumptionConfig update config success");
90 }
91
SetUiEnergyConsumptionConfig(std::unordered_map<std::string,std::string> uiPowerConfig)92 void HgmEnergyConsumptionPolicy::SetUiEnergyConsumptionConfig(
93 std::unordered_map<std::string, std::string> uiPowerConfig)
94 {
95 std::lock_guard<std::recursive_mutex> lock(mutex_);
96 uiEnergyAssuranceMap_.clear();
97 for (auto config : uiPowerConfig) {
98 std::string rateTypeName = config.first;
99 auto it = UI_RATE_TYPE_NAME_MAP.find(rateTypeName);
100 if (it == UI_RATE_TYPE_NAME_MAP.end()) {
101 HGM_LOGD("HgmEnergyConsumptionPolicy::SetUiEnergyConsumptionConfig the rateType is invalid");
102 continue;
103 }
104 int idleFps = 60;
105 ConverStrToInt(idleFps, config.second, DEFAULT_ENERGY_ASSURANCE_IDLE_FPS);
106 uiEnergyAssuranceMap_[it->second] = std::make_pair(true, idleFps);
107 }
108 }
109
SetAnimationEnergyConsumptionAssuranceMode(bool isEnergyConsumptionAssuranceMode)110 void HgmEnergyConsumptionPolicy::SetAnimationEnergyConsumptionAssuranceMode(bool isEnergyConsumptionAssuranceMode)
111 {
112 std::lock_guard<std::recursive_mutex> lock(mutex_);
113 if (!isAnimationEnergyAssuranceEnable_ ||
114 isAnimationEnergyConsumptionAssuranceMode_ == isEnergyConsumptionAssuranceMode) {
115 return;
116 }
117 isAnimationEnergyConsumptionAssuranceMode_ = isEnergyConsumptionAssuranceMode;
118 firstAnimationTimestamp_ = HgmCore::Instance().GetCurrentTimestamp() / NS_PER_MS;
119 lastAnimationTimestamp_ = firstAnimationTimestamp_;
120 }
121
SetUiEnergyConsumptionAssuranceMode(bool isEnergyConsumptionAssuranceMode)122 void HgmEnergyConsumptionPolicy::SetUiEnergyConsumptionAssuranceMode(bool isEnergyConsumptionAssuranceMode)
123 {
124 std::lock_guard<std::recursive_mutex> lock(mutex_);
125 isUiEnergyConsumptionAssuranceMode_ = isEnergyConsumptionAssuranceMode;
126 }
127
StatisticAnimationTime(uint64_t timestamp)128 void HgmEnergyConsumptionPolicy::StatisticAnimationTime(uint64_t timestamp)
129 {
130 std::lock_guard<std::recursive_mutex> lock(mutex_);
131 if (!isAnimationEnergyAssuranceEnable_ || !isAnimationEnergyConsumptionAssuranceMode_) {
132 return;
133 }
134 lastAnimationTimestamp_ = timestamp;
135 }
136
StartNewAnimation()137 void HgmEnergyConsumptionPolicy::StartNewAnimation()
138 {
139 std::lock_guard<std::recursive_mutex> lock(mutex_);
140 if (!isAnimationEnergyAssuranceEnable_ || !isAnimationEnergyConsumptionAssuranceMode_) {
141 return;
142 }
143 firstAnimationTimestamp_ = HgmCore::Instance().GetCurrentTimestamp() / NS_PER_MS;
144 lastAnimationTimestamp_ = firstAnimationTimestamp_;
145 }
146
GetAnimationIdleFps(FrameRateRange & rsRange)147 void HgmEnergyConsumptionPolicy::GetAnimationIdleFps(FrameRateRange& rsRange)
148 {
149 std::lock_guard<std::recursive_mutex> lock(mutex_);
150 if (!isAnimationEnergyAssuranceEnable_ || !isAnimationEnergyConsumptionAssuranceMode_) {
151 return;
152 }
153 if (lastAnimationTimestamp_ > firstAnimationTimestamp_ &&
154 (lastAnimationTimestamp_ - firstAnimationTimestamp_) < static_cast<uint64_t>(animationIdleDuration_)) {
155 return;
156 }
157 SetEnergyConsumptionRateRange(rsRange, animationIdleFps_);
158 }
159
GetUiIdleFps(FrameRateRange & rsRange)160 void HgmEnergyConsumptionPolicy::GetUiIdleFps(FrameRateRange& rsRange)
161 {
162 std::lock_guard<std::recursive_mutex> lock(mutex_);
163 if (!isUiEnergyConsumptionAssuranceMode_) {
164 return;
165 }
166 auto it = uiEnergyAssuranceMap_.find(rsRange.type_);
167 if (it == uiEnergyAssuranceMap_.end()) {
168 HGM_LOGD("HgmEnergyConsumptionPolicy::GetUiIdleFps the rateType = %{public}d is invalid", rsRange.type_);
169 return;
170 }
171 bool isEnergyAssuranceEnable = it->second.first;
172 int idleFps = it->second.second;
173 if (isEnergyAssuranceEnable) {
174 SetEnergyConsumptionRateRange(rsRange, idleFps);
175 }
176 }
177
SetEnergyConsumptionRateRange(FrameRateRange & rsRange,int idleFps)178 void HgmEnergyConsumptionPolicy::SetEnergyConsumptionRateRange(FrameRateRange& rsRange, int idleFps)
179 {
180 RS_TRACE_NAME_FMT("SetEnergyConsumptionRateRange rateType:%s, maxFps:%d", rsRange.GetExtInfo().c_str(), idleFps);
181 rsRange.max_ = std::min(rsRange.max_, idleFps);
182 rsRange.min_ = std::min(rsRange.min_, idleFps);
183 rsRange.preferred_ = std::min(rsRange.preferred_, idleFps);
184 }
185 } // namespace OHOS::Rosen