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