1 /*
2  * Copyright (c) 2023 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 #ifndef HGM_FRAME_RATE_MANAGER_H
17 #define HGM_FRAME_RATE_MANAGER_H
18 
19 #include <mutex>
20 #include <sstream>
21 #include <unordered_map>
22 #include <unordered_set>
23 #include <vector>
24 
25 #include "animation/rs_frame_rate_range.h"
26 #include "common/rs_common_def.h"
27 #include "hgm_command.h"
28 #include "hgm_idle_detector.h"
29 #include "hgm_multi_app_strategy.h"
30 #include "hgm_one_shot_timer.h"
31 #include "hgm_screen.h"
32 #include "hgm_task_handle_thread.h"
33 #include "hgm_touch_manager.h"
34 #include "hgm_vsync_generator_controller.h"
35 #include "modifier/rs_modifier_type.h"
36 #include "pipeline/rs_render_frame_rate_linker.h"
37 #include "screen_manager/screen_types.h"
38 #include "variable_frame_rate/rs_variable_frame_rate.h"
39 
40 namespace OHOS {
41 namespace Rosen {
42 using VoteRange = std::pair<uint32_t, uint32_t>;
43 using FrameRateLinkerMap = std::unordered_map<FrameRateLinkerId, std::shared_ptr<RSRenderFrameRateLinker>>;
44 
45 enum VoteType : bool {
46     REMOVE_VOTE = false,
47     ADD_VOTE = true
48 };
49 
50 enum TouchStatus : uint32_t {
51     TOUCH_CANCEL = 1,
52     TOUCH_DOWN = 2,
53     TOUCH_MOVE = 3,
54     TOUCH_UP = 4,
55     TOUCH_PULL_DOWN = 12,
56     TOUCH_PULL_UP = 14,
57 };
58 
59 enum CleanPidCallbackType : uint32_t {
60     LIGHT_FACTOR,
61     PACKAGE_EVENT,
62     TOUCH_EVENT,
63     GAMES,
64 };
65 
66 struct DvsyncInfo {
67     bool isRsDvsyncOn = false;
68     bool isUiDvsyncOn = false;
69 };
70 
71 struct VoteInfo {
72     std::string voterName = "";
73     uint32_t min = OLED_NULL_HZ;
74     uint32_t max = OLED_NULL_HZ;
75     pid_t pid = DEFAULT_PID;
76     std::string extInfo = "";
77     std::string bundleName = "";
78 
MergeVoteInfo79     void Merge(const VoteInfo& other)
80     {
81         this->voterName = other.voterName;
82         this->pid = other.pid;
83         this->extInfo = other.extInfo;
84     }
85 
SetRangeVoteInfo86     void SetRange(uint32_t min, uint32_t max)
87     {
88         this->min = min;
89         this->max = max;
90     }
91 
ToStringVoteInfo92     std::string ToString(uint64_t timestamp) const
93     {
94         std::stringstream str;
95         str << "VOTER_NAME:" << voterName << ";";
96         str << "PREFERRED:" << max << ";";
97         str << "EXT_INFO:" << extInfo << ";";
98         str << "PID:" << pid << ";";
99         str << "BUNDLE_NAME:" << bundleName << ";";
100         str << "TIMESTAMP:" << timestamp << ".";
101         return str.str();
102     }
103 
104     bool operator==(const VoteInfo& other) const
105     {
106         return this->max == other.max && this->voterName == other.voterName &&
107             this->extInfo == other.extInfo && this->pid == other.pid && this->bundleName == other.bundleName;
108     }
109 
110     bool operator!=(const VoteInfo& other) const
111     {
112         return !(*this == other);
113     }
114 };
115 
116 class HgmFrameRateManager {
117 public:
118     HgmFrameRateManager() = default;
119     ~HgmFrameRateManager() = default;
120 
121     void HandleLightFactorStatus(pid_t pid, bool isSafe);
122     void HandlePackageEvent(pid_t pid, const std::vector<std::string>& packageList);
123     void HandleRefreshRateEvent(pid_t pid, const EventInfo& eventInfo);
124     void HandleTouchEvent(pid_t pid, int32_t touchStatus, int32_t touchCnt);
125     void HandleDynamicModeEvent(bool enableDynamicModeEvent);
126 
127     void CleanVote(pid_t pid);
GetCurRefreshRateMode()128     int32_t GetCurRefreshRateMode() const { return curRefreshRateMode_; };
GetCurScreenId()129     ScreenId GetCurScreenId() const { return curScreenId_; };
GetCurScreenStrategyId()130     std::string GetCurScreenStrategyId() const { return curScreenStrategyId_; };
131     void HandleRefreshRateMode(int32_t refreshRateMode);
132     void HandleScreenPowerStatus(ScreenId id, ScreenPowerStatus status);
IsLtpo()133     bool IsLtpo() const { return isLtpo_; };
134     void UniProcessDataForLtpo(uint64_t timestamp, std::shared_ptr<RSRenderFrameRateLinker> rsFrameRateLinker,
135         const FrameRateLinkerMap& appFrameRateLinkers, bool idleTimerExpired, const DvsyncInfo& dvsyncInfo);
136     void UniProcessDataForLtps(bool idleTimerExpired);
137 
138     int32_t GetExpectedFrameRate(const RSPropertyUnit unit, float velocity) const;
139     std::shared_ptr<HgmOneShotTimer> GetScreenTimer(ScreenId screenId) const;
140     void ResetScreenTimer(ScreenId screenId) const;
141     void StartScreenTimer(ScreenId screenId, int32_t interval,
142         std::function<void()> resetCallback, std::function<void()> expiredCallback);
143     void StopScreenTimer(ScreenId screenId);
SetForceUpdateCallback(std::function<void (bool,bool)> forceUpdateCallback)144     void SetForceUpdateCallback(std::function<void(bool, bool)> forceUpdateCallback)
145     {
146         forceUpdateCallback_ = forceUpdateCallback;
147     }
148 
149     void Init(sptr<VSyncController> rsController,
150         sptr<VSyncController> appController, sptr<VSyncGenerator> vsyncGenerator);
151     void InitTouchManager();
152     std::shared_ptr<uint32_t> GetPendingRefreshRate();
153     void ResetPendingRefreshRate();
154     void ProcessPendingRefreshRate(uint64_t timestamp, uint32_t rsRate, const DvsyncInfo& dvsyncInfo);
GetMultiAppStrategy()155     HgmMultiAppStrategy& GetMultiAppStrategy() { return multiAppStrategy_; }
GetTouchManager()156     HgmTouchManager& GetTouchManager() { return touchManager_; }
157     void UpdateSurfaceTime(const std::string& surfaceName, uint64_t timestamp, pid_t pid);
SetSchedulerPreferredFps(uint32_t schedulePreferredFps)158     void SetSchedulerPreferredFps(uint32_t schedulePreferredFps)
159     {
160         if (schedulePreferredFps_ != schedulePreferredFps) {
161             schedulePreferredFps_ = schedulePreferredFps;
162             schedulePreferredFpsChange_ = true;
163         }
164     }
165 
SetIsNeedUpdateAppOffset(bool isNeedUpdateAppOffset)166     void SetIsNeedUpdateAppOffset(bool isNeedUpdateAppOffset)
167     {
168         isNeedUpdateAppOffset_ = isNeedUpdateAppOffset;
169     }
170 
171     static std::pair<bool, bool> MergeRangeByPriority(VoteRange& rangeRes, const VoteRange& curVoteRange);
172 private:
173     void Reset();
174     void UpdateAppSupportedState();
175     void UpdateGuaranteedPlanVote(uint64_t timestamp);
176 
177     void ProcessLtpoVote(const FrameRateRange& finalRange, bool idleTimerExpired);
178     void SetAceAnimatorVote(const std::shared_ptr<RSRenderFrameRateLinker>& linker, bool& needCheckAceAnimatorStatus);
179     bool CollectFrameRateChange(FrameRateRange finalRange, std::shared_ptr<RSRenderFrameRateLinker> rsFrameRateLinker,
180         const FrameRateLinkerMap& appFrameRateLinkers);
181     void HandleFrameRateChangeForLTPO(uint64_t timestamp);
182     void FrameRateReport();
183     void CalcRefreshRate(const ScreenId id, const FrameRateRange& range);
184     uint32_t GetDrawingFrameRate(const uint32_t refreshRate, const FrameRateRange& range);
185     int32_t GetPreferredFps(const std::string& type, float velocity) const;
186     static float PixelToMM(float velocity);
187 
188     void HandleIdleEvent(bool isIdle);
189     void HandleSceneEvent(pid_t pid, EventInfo eventInfo);
190     void HandleVirtualDisplayEvent(pid_t pid, EventInfo eventInfo);
191     void HandleGamesEvent(pid_t pid, EventInfo eventInfo);
192 
193     void DeliverRefreshRateVote(const VoteInfo& voteInfo, bool eventStatus);
194     void MarkVoteChange();
195     // merge [VOTER_LTPO, VOTER_IDLE)
196     bool MergeLtpo2IdleVote(
197         std::vector<std::string>::iterator& voterIter, VoteInfo& resultVoteInfo, VoteRange& mergedVoteRange);
198     bool CheckRefreshNeed();
199     VoteInfo ProcessRefreshRateVote();
200     void UpdateVoteRule();
201     void ReportHiSysEvent(const VoteInfo& frameRateVoteInfo);
202     void SetResultVoteInfo(VoteInfo& voteInfo, uint32_t min, uint32_t max);
203     void UpdateEnergyConsumptionConfig();
204     void EnterEnergyConsumptionAssuranceMode();
205     void ExitEnergyConsumptionAssuranceMode();
206     static void ProcessVoteLog(const VoteInfo& curVoteInfo, bool isSkip);
207     void RegisterCoreCallbacksAndInitController(sptr<VSyncController> rsController,
208         sptr<VSyncController> appController, sptr<VSyncGenerator> vsyncGenerator);
209     void ProcessAncoRefreshRateVote(const std::string& voter, VoteInfo& curVoteInfo);
210 
211     uint32_t currRefreshRate_ = 0;
212     uint32_t controllerRate_ = 0;
213     std::shared_ptr<uint32_t> pendingRefreshRate_ = nullptr;
214     uint64_t pendingConstraintRelativeTime_ = 0;
215     std::shared_ptr<HgmVSyncGeneratorController> controller_ = nullptr;
216     std::mutex appChangeDataMutex_;
217     std::vector<std::pair<FrameRateLinkerId, uint32_t>> appChangeData_;
218 
219     std::function<void(bool, bool)> forceUpdateCallback_ = nullptr;
220     std::unordered_map<ScreenId, std::shared_ptr<HgmOneShotTimer>> screenTimerMap_;
221 
222     std::mutex pkgSceneMutex_;
223     std::mutex voteMutex_;
224     std::mutex voteNameMutex_;
225     std::vector<std::string> voters_;
226     // FORMAT: <sceneName, pid>
227     std::vector<std::pair<std::string, pid_t>> sceneStack_;
228     // FORMAT: "voterName, <pid, <min, max>>"
229     std::unordered_map<std::string, std::vector<VoteInfo>> voteRecord_;
230     // Used to record your votes, and clear your votes after you die
231     std::unordered_set<pid_t> pidRecord_;
232     std::unordered_set<std::string> gameScenes_;
233     std::unordered_set<std::string> ancoScenes_;
234     std::mutex cleanPidCallbackMutex_;
235     std::unordered_map<pid_t, std::unordered_set<CleanPidCallbackType>> cleanPidCallback_;
236     std::mutex frameRateVoteInfoMutex_;
237     // FORMAT: <timestamp, VoteInfo>
238     std::vector<std::pair<int64_t, VoteInfo>> frameRateVoteInfoVec_;
239 
240     int32_t curRefreshRateMode_ = HGM_REFRESHRATE_MODE_AUTO;
241     ScreenId curScreenId_ = 0;
242     std::string curScreenStrategyId_ = "LTPO-DEFAULT";
243     bool isLtpo_ = true;
244     bool isRefreshNeed_ = true;
245     int32_t idleFps_ = 60;
246     VoteInfo lastVoteInfo_;
247     HgmMultiAppStrategy multiAppStrategy_;
248     HgmTouchManager touchManager_;
249     std::atomic<bool> startCheck_ = false;
250     HgmIdleDetector idleDetector_;
251     bool needHighRefresh_ = false;
252     int32_t lastTouchUpExpectFps_ = 0;
253     bool isNeedUpdateAppOffset_ = false;
254     uint32_t schedulePreferredFps_ = 60;
255     int32_t schedulePreferredFpsChange_ = false;
256 };
257 } // namespace Rosen
258 } // namespace OHOS
259 #endif // HGM_FRAME_RATE_MANAGER_H