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