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_idle_detector.h"
17 #include "rs_trace.h"
18 #include "hgm_task_handle_thread.h"
19
20 namespace OHOS {
21 namespace Rosen {
22 namespace {
23 constexpr uint32_t ACE_ANIMATOR_OFFSET = 16;
24 constexpr uint64_t BUFFER_IDLE_TIME_OUT = 200000000; // 200ms
25 constexpr uint64_t MAX_CACHED_VALID_SURFACE_NAME_COUNT = 60;
26 constexpr int32_t ANIMATOR_NO_EXPECTED_FRAME_RATE = 0;
27 const std::string ACE_ANIMATOR_NAME = "AceAnimato";
28 const std::string OTHER_SURFACE = "Other_SF";
29 }
30
SetAppSupportedState(bool appSupported)31 void HgmIdleDetector::SetAppSupportedState(bool appSupported)
32 {
33 appSupported_ = appSupported;
34 if (!appSupported_) {
35 aceAnimatorIdleState_ = true;
36 aceAnimatorExpectedFrameRate_ = ANIMATOR_NOT_RUNNING;
37 surfaceTimeMap_.clear();
38 bufferFpsMap_.clear();
39 }
40 }
41
SetAceAnimatorIdleState(bool aceAnimatorIdleState)42 void HgmIdleDetector::SetAceAnimatorIdleState(bool aceAnimatorIdleState)
43 {
44 if (!appSupported_ || bufferFpsMap_.find(ACE_ANIMATOR_NAME) == bufferFpsMap_.end() ||
45 bufferFpsMap_[ACE_ANIMATOR_NAME] == 0) {
46 // only if bufferFpsMap_ contains ACE_ANIMATOR_NAME, aceAnimatorIdleState_ can be set to false
47 aceAnimatorIdleState_ = true;
48 return;
49 }
50
51 aceAnimatorIdleState_ = aceAnimatorIdleState;
52 }
53
UpdateSurfaceTime(const std::string & surfaceName,uint64_t timestamp,pid_t pid,UIFWKType uiFwkType)54 void HgmIdleDetector::UpdateSurfaceTime(const std::string& surfaceName, uint64_t timestamp,
55 pid_t pid, UIFWKType uiFwkType)
56 {
57 if (surfaceName.empty()) {
58 return;
59 }
60
61 if (!GetAppSupportedState() || surfaceTimeMap_.size() > MAX_CACHED_VALID_SURFACE_NAME_COUNT) {
62 surfaceTimeMap_.clear();
63 return;
64 }
65
66 std::string validSurfaceType = "";
67 bool hasValidFramework = false;
68 switch (uiFwkType) {
69 case UIFWKType::FROM_UNKNOWN:
70 hasValidFramework = GetUnknownFrameworkState(surfaceName, validSurfaceType);
71 break;
72 case UIFWKType::FROM_SURFACE:
73 hasValidFramework = GetSurfaceFrameworkState(surfaceName, validSurfaceType);
74 break;
75 default:
76 break;
77 }
78 if (!hasValidFramework) {
79 return;
80 }
81
82 RS_TRACE_NAME_FMT("UpdateSurfaceTime:: Not Idle SurFace Name = [%s] From Pid = [%d]",
83 surfaceName.c_str(), pid);
84 // only types contained by bufferFpsMap_ can be add to surfaceTimeMap_
85 surfaceTimeMap_[validSurfaceType] = timestamp;
86 }
87
GetUnknownFrameworkState(const std::string & surfaceName,std::string & uiFwkType)88 bool HgmIdleDetector::GetUnknownFrameworkState(const std::string& surfaceName,
89 std::string& uiFwkType)
90 {
91 for (const auto& [supportedAppBuffer, fps] : bufferFpsMap_) {
92 if (surfaceName.rfind(supportedAppBuffer, 0) == 0) {
93 if (fps > 0) {
94 uiFwkType = supportedAppBuffer;
95 return true;
96 } else {
97 return false;
98 }
99 }
100 }
101 return false;
102 }
103
GetSurfaceFrameworkState(const std::string & surfaceName,std::string & validSurfaceName)104 bool HgmIdleDetector::GetSurfaceFrameworkState(const std::string& surfaceName,
105 std::string& validSurfaceName)
106 {
107 for (const auto& [supportedAppBuffer, fps] : bufferFpsMap_) {
108 if (surfaceName.rfind(supportedAppBuffer, 0) == 0) {
109 if (fps > 0) {
110 validSurfaceName = supportedAppBuffer;
111 return true;
112 } else {
113 return false;
114 }
115 }
116 }
117 if (bufferFpsMap_.find(OTHER_SURFACE) != bufferFpsMap_.end() &&
118 bufferFpsMap_[OTHER_SURFACE] > 0) {
119 validSurfaceName = OTHER_SURFACE;
120 return true;
121 }
122 return false;
123 }
124
UpdateSurfaceState(uint64_t timestamp)125 void HgmIdleDetector::UpdateSurfaceState(uint64_t timestamp)
126 {
127 for (auto iter = surfaceTimeMap_.begin(); iter != surfaceTimeMap_.end();) {
128 if (timestamp > iter->second && (timestamp - iter->second) > BUFFER_IDLE_TIME_OUT) {
129 iter = surfaceTimeMap_.erase(iter);
130 } else {
131 ++iter;
132 }
133 }
134 }
135
GetTouchUpExpectedFPS()136 int32_t HgmIdleDetector::GetTouchUpExpectedFPS()
137 {
138 if (aceAnimatorIdleState_ && surfaceTimeMap_.empty()) {
139 return 0;
140 }
141
142 int32_t aceAnimatorVote = 0;
143 if (!aceAnimatorIdleState_) {
144 // only if bufferFpsMap_ contains ACE_ANIMATOR_NAME, aceAnimatorIdleState_ can be set to false
145 aceAnimatorVote = aceAnimatorExpectedFrameRate_ > ANIMATOR_NO_EXPECTED_FRAME_RATE
146 ? std::min(aceAnimatorExpectedFrameRate_, bufferFpsMap_[ACE_ANIMATOR_NAME])
147 : bufferFpsMap_[ACE_ANIMATOR_NAME];
148 }
149
150 int32_t surfaceVote = 0;
151 for (const auto& [surfaceName, _] : surfaceTimeMap_) {
152 // only types contained by bufferFpsMap_ can be add to surfaceTimeMap_
153 surfaceVote = std::max(surfaceVote, bufferFpsMap_[surfaceName]);
154 }
155
156 RS_TRACE_NAME_FMT("GetTouchUpExpectedFPS: aceAnimatorVote:[%d], surfaceVote:[%d]", aceAnimatorVote, surfaceVote);
157 return std::max(aceAnimatorVote, surfaceVote);
158 }
159
UpdateAceAnimatorExpectedFrameRate(int32_t aceAnimatorExpectedFrameRate)160 void HgmIdleDetector::UpdateAceAnimatorExpectedFrameRate(int32_t aceAnimatorExpectedFrameRate)
161 {
162 // aceAnimatorExpectedFrameRate int32_t example: 0x003c0001
163 // [0, 16) is existAnimatorNoExpectdRate = 1
164 // [16, 32) is aceAnimatorExpectedFrameRate = 60
165 if (aceAnimatorExpectedFrameRate < 0) {
166 return;
167 }
168 bool existAnimatorNoExpectdRate = aceAnimatorExpectedFrameRate & 1;
169 auto iter = bufferFpsMap_.find(ACE_ANIMATOR_NAME);
170 if (iter != bufferFpsMap_.end() && iter->second > 0 && existAnimatorNoExpectdRate) {
171 aceAnimatorExpectedFrameRate = 0;
172 } else {
173 aceAnimatorExpectedFrameRate = aceAnimatorExpectedFrameRate >> ACE_ANIMATOR_OFFSET;
174 }
175
176 if (aceAnimatorExpectedFrameRate_ != 0 &&
177 (aceAnimatorExpectedFrameRate == 0 || aceAnimatorExpectedFrameRate > aceAnimatorExpectedFrameRate_)) {
178 aceAnimatorExpectedFrameRate_ = aceAnimatorExpectedFrameRate;
179 }
180 }
181 } // namespace Rosen
182 } // namespace OHOS