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