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
19 namespace OHOS {
20 namespace Rosen {
21 namespace {
22 constexpr uint64_t BUFFER_IDLE_TIME_OUT = 200000000; // 200ms
23 constexpr uint64_t MAX_BUFFER_COUNT = 10;
24 constexpr uint32_t MAX_BUFFER_LENGTH = 10;
25 constexpr uint32_t FPS_MAX = 120;
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
UpdateSurfaceTime(const std::string & surfaceName,uint64_t timestamp,pid_t pid)31 void HgmIdleDetector::UpdateSurfaceTime(const std::string& surfaceName, uint64_t timestamp, pid_t pid)
32 {
33 if (!GetAppSupportedState() || frameTimeMap_.size() > MAX_BUFFER_COUNT || surfaceName.empty()) {
34 if (!frameTimeMap_.empty()) {
35 frameTimeMap_.clear();
36 }
37 return;
38 }
39
40 auto validSurfaceName = surfaceName.size() > MAX_BUFFER_LENGTH ?
41 surfaceName.substr(0, MAX_BUFFER_LENGTH) : surfaceName;
42 if (!std::count(supportAppBufferList_.begin(), supportAppBufferList_.end(), OTHER_SURFACE) &&
43 !std::count(supportAppBufferList_.begin(), supportAppBufferList_.end(), validSurfaceName)) {
44 return;
45 }
46
47 RS_TRACE_NAME_FMT("UpdateSurfaceTime:: Not Idle SurFace Name = [%s] From Pid = [%d]",
48 surfaceName.c_str(), pid);
49 frameTimeMap_[validSurfaceName] = timestamp;
50 }
51
GetSurfaceIdleState(uint64_t timestamp)52 bool HgmIdleDetector::GetSurfaceIdleState(uint64_t timestamp)
53 {
54 if (frameTimeMap_.empty()) {
55 return true;
56 }
57
58 bool idle = true;
59 for (auto iter = frameTimeMap_.begin(); iter != frameTimeMap_.end();) {
60 if ((timestamp - iter->second) > BUFFER_IDLE_TIME_OUT) {
61 iter = frameTimeMap_.erase(iter);
62 } else {
63 idle = false;
64 ++iter;
65 }
66 }
67
68 return idle;
69 }
70
ThirdFrameNeedHighRefresh()71 bool HgmIdleDetector::ThirdFrameNeedHighRefresh()
72 {
73 std::lock_guard<std::mutex> lock(appBufferBlackListMutex_);
74 if (appBufferBlackList_.empty() || (!aceAnimatorIdleState_ &&
75 !std::count(appBufferBlackList_.begin(), appBufferBlackList_.end(), ACE_ANIMATOR_NAME))) {
76 return true;
77 }
78
79 if (frameTimeMap_.empty() ||
80 std::count(appBufferBlackList_.begin(), appBufferBlackList_.end(), OTHER_SURFACE)) {
81 return false;
82 }
83
84 for (auto &[surfaceName, _] : frameTimeMap_) {
85 if (!std::count(appBufferBlackList_.begin(), appBufferBlackList_.end(), surfaceName)) {
86 return true;
87 }
88 }
89 return false;
90 }
91
GetTouchUpExpectedFPS()92 int32_t HgmIdleDetector::GetTouchUpExpectedFPS()
93 {
94 std::lock_guard<std::mutex> lock(appBufferListMutex_);
95 if (appBufferList_.empty()) {
96 return GetAceAnimatorExpectedFrameRate() > ANIMATOR_NO_EXPECTED_FRAME_RATE ? GetAceAnimatorExpectedFrameRate()
97 : FPS_MAX;
98 }
99 if (!aceAnimatorIdleState_) {
100 auto iter = std::find_if(appBufferList_.begin(), appBufferList_.end(),
101 [&](const auto& appBuffer) {
102 return appBuffer.first == ACE_ANIMATOR_NAME;
103 });
104 if (iter != appBufferList_.end() && frameTimeMap_.empty()) {
105 return GetAceAnimatorExpectedFrameRate() > ANIMATOR_NO_EXPECTED_FRAME_RATE
106 ? std::min(GetAceAnimatorExpectedFrameRate(), iter->second)
107 : iter->second;
108 }
109 }
110
111 for (auto &[surfaceName, _] : frameTimeMap_) {
112 auto iter = std::find_if(appBufferList_.begin(), appBufferList_.end(),
113 [&surfaceName = surfaceName](const std::pair<std::string, int32_t>& appBuffer) {
114 return appBuffer.first == surfaceName;
115 });
116 if (iter == appBufferList_.end()) {
117 return FPS_MAX;
118 }
119 }
120
121 for (auto &[surfaceName, touchUpExpectedFPS] : appBufferList_) {
122 if ((surfaceName == ACE_ANIMATOR_NAME && !aceAnimatorIdleState_) ||
123 frameTimeMap_.count(surfaceName)) {
124 return touchUpExpectedFPS;
125 }
126 }
127
128 return FPS_MAX;
129 }
130
131 } // namespace Rosen
132 } // namespace OHOS