• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <unordered_map>
20 #include <unordered_set>
21 #include <vector>
22 
23 #include "animation/rs_frame_rate_range.h"
24 #include "common/rs_common_def.h"
25 #include "hgm_app_page_url_strategy.h"
26 #include "hgm_command.h"
27 #include "hgm_idle_detector.h"
28 #include "hgm_multi_app_strategy.h"
29 #include "hgm_one_shot_timer.h"
30 #include "hgm_screen.h"
31 #include "hgm_task_handle_thread.h"
32 #include "hgm_touch_manager.h"
33 #include "hgm_pointer_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 "pipeline/rs_render_node.h"
38 #include "pipeline/rs_render_node_map.h"
39 #include "screen_manager/screen_types.h"
40 #include "variable_frame_rate/rs_variable_frame_rate.h"
41 
42 namespace OHOS {
43 namespace Rosen {
44 using VoteRange = std::pair<uint32_t, uint32_t>;
45 using FrameRateLinkerMap = std::unordered_map<FrameRateLinkerId, std::shared_ptr<RSRenderFrameRateLinker>>;
46 
47 enum VoteType : bool {
48     REMOVE_VOTE = false,
49     ADD_VOTE = true
50 };
51 
52 enum TouchStatus : uint32_t {
53     TOUCH_CANCEL = 1,
54     TOUCH_DOWN = 2,
55     TOUCH_MOVE = 3,
56     TOUCH_UP = 4,
57     TOUCH_BUTTON_DOWN = 8,
58     TOUCH_BUTTON_UP = 9,
59     TOUCH_PULL_DOWN = 12,
60     TOUCH_PULL_MOVE = 13,
61     TOUCH_PULL_UP = 14,
62 };
63 
64 enum CleanPidCallbackType : uint32_t {
65     LIGHT_FACTOR,
66     PACKAGE_EVENT,
67     TOUCH_EVENT,
68     POINTER_EVENT,
69     GAMES,
70     APP_STRATEGY_CONFIG_EVENT,
71     PAGE_URL,
72 };
73 
74 enum LightFactorStatus : int32_t {
75     // normal level
76     NORMAL_HIGH = 0,
77     NORMAL_LOW,
78     // brightness level
79     LOW_LEVEL = 3,
80     MIDDLE_LEVEL,
81     HIGH_LEVEL,
82 };
83 
84 enum SupportASStatus : int32_t {
85     NOT_SUPPORT = 0,
86     SUPPORT_AS = 1,
87     GAME_SCENE_SKIP = 2,
88 };
89 
90 struct VoteInfo {
91     std::string voterName = "";
92     uint32_t min = OLED_NULL_HZ;
93     uint32_t max = OLED_NULL_HZ;
94     pid_t pid = DEFAULT_PID;
95     std::string extInfo = "";
96     std::string bundleName = "";
97 
MergeVoteInfo98     void Merge(const VoteInfo& other)
99     {
100         this->voterName = other.voterName;
101         this->pid = other.pid;
102         this->extInfo = other.extInfo;
103     }
104 
SetRangeVoteInfo105     void SetRange(uint32_t min, uint32_t max)
106     {
107         this->min = min;
108         this->max = max;
109     }
110 
ToStringVoteInfo111     std::string ToString(uint64_t timestamp) const
112     {
113         char buf[STRING_BUFFER_MAX_SIZE] = {0};
114         int len = ::snprintf_s(buf, sizeof(buf), sizeof(buf) - 1,
115             "VOTER_NAME:%s;PREFERRED:%u;EXT_INFO:%s;PID:%d;BUNDLE_NAME:%s;TIMESTAMP:%lu.",
116             voterName.c_str(), max, extInfo.c_str(), pid, bundleName.c_str(), timestamp);
117         if (len <= 0) {
118             HGM_LOGE("failed to execute snprintf.");
119         }
120         return buf;
121     }
122 
ToSimpleStringVoteInfo123     std::string ToSimpleString() const
124     {
125         char buf[STRING_BUFFER_MAX_SIZE] = {0};
126         int len = ::snprintf_s(buf, sizeof(buf), sizeof(buf) - 1, "VOTER:%s; FPS:%u; EXT:%s; PID:%d.",
127             voterName.c_str(), max, extInfo.c_str(), pid);
128         if (len <= 0) {
129             HGM_LOGE("failed to execute snprintf.");
130         }
131         return buf;
132     }
133 
134     bool operator==(const VoteInfo& other) const
135     {
136         return this->min == other.min && this->max == other.max && this->voterName == other.voterName &&
137             this->extInfo == other.extInfo && this->pid == other.pid && this->bundleName == other.bundleName;
138     }
139 
140     bool operator!=(const VoteInfo& other) const
141     {
142         return !(*this == other);
143     }
144 };
145 
146 class HgmFrameRateManager {
147 public:
148     using ChangeDssRefreshRateCbType = std::function<void(ScreenId, uint32_t, bool)>;
149     HgmFrameRateManager();
150     ~HgmFrameRateManager() = default;
151 
152     void HandleLightFactorStatus(pid_t pid, int32_t state);
153     void HandlePackageEvent(pid_t pid, const std::vector<std::string>& packageList);
154     void HandleRefreshRateEvent(pid_t pid, const EventInfo& eventInfo);
155     void HandleTouchEvent(pid_t pid, int32_t touchStatus, int32_t touchCnt);
156     void HandleDynamicModeEvent(bool enableDynamicModeEvent);
157 
158     void CleanVote(pid_t pid);
GetCurRefreshRateMode()159     int32_t GetCurRefreshRateMode() const { return curRefreshRateMode_; };
GetCurrRefreshRate()160     uint32_t GetCurrRefreshRate() { return currRefreshRate_; }
GetCurScreenId()161     ScreenId GetCurScreenId() const { return curScreenId_.load(); };
GetLastCurScreenId()162     ScreenId GetLastCurScreenId() const { return lastCurScreenId_.load(); };
SetLastCurScreenId(ScreenId screenId)163     void SetLastCurScreenId(ScreenId screenId)
164     {
165         lastCurScreenId_.store(screenId);
166     }
GetCurScreenStrategyId()167     std::string GetCurScreenStrategyId() const { return curScreenStrategyId_; };
168     void HandleRefreshRateMode(int32_t refreshRateMode);
169     void HandleScreenPowerStatus(ScreenId id, ScreenPowerStatus status);
170     void HandleScreenRectFrameRate(ScreenId id, const GraphicIRect& activeRect);
171     void HandleThermalFrameRate(bool status);
172 
173     // called by RSHardwareThread
174     void HandleRsFrame();
IsLtpo()175     bool IsLtpo() const { return isLtpo_; };
AdaptiveStatus()176     int32_t AdaptiveStatus() const { return isAdaptive_.load(); };
177     // called by RSMainThread
IsGameNodeOnTree()178     bool IsGameNodeOnTree() const { return isGameNodeOnTree_.load(); };
179     void UniProcessDataForLtpo(uint64_t timestamp, std::shared_ptr<RSRenderFrameRateLinker> rsFrameRateLinker,
180         const FrameRateLinkerMap& appFrameRateLinkers, const std::map<uint64_t, int>& vRatesMap);
181 
182     int32_t GetExpectedFrameRate(const RSPropertyUnit unit, float velocityPx, int32_t areaPx, int32_t lengthPx) const;
SetForceUpdateCallback(std::function<void (bool,bool)> forceUpdateCallback)183     void SetForceUpdateCallback(std::function<void(bool, bool)> forceUpdateCallback)
184     {
185         forceUpdateCallback_ = forceUpdateCallback;
186     }
187 
188     void Init(sptr<VSyncController> rsController,
189         sptr<VSyncController> appController, sptr<VSyncGenerator> vsyncGenerator);
190     void InitTouchManager();
191     // called by RSMainThread
192     void ProcessPendingRefreshRate(uint64_t timestamp, int64_t vsyncId, uint32_t rsRate, bool isUiDvsyncOn);
GetMultiAppStrategy()193     HgmMultiAppStrategy& GetMultiAppStrategy() { return multiAppStrategy_; }
GetTouchManager()194     HgmTouchManager& GetTouchManager() { return touchManager_; }
GetIdleDetector()195     HgmIdleDetector& GetIdleDetector() { return idleDetector_; }
196     // only called by RSMainThread
197     void UpdateSurfaceTime(const std::string& surfaceName, pid_t pid, UIFWKType uiFwkType);
SetSchedulerPreferredFps(uint32_t schedulePreferredFps)198     void SetSchedulerPreferredFps(uint32_t schedulePreferredFps)
199     {
200         if (schedulePreferredFps_ != schedulePreferredFps) {
201             schedulePreferredFps_ = schedulePreferredFps;
202             schedulePreferredFpsChange_ = true;
203         }
204     }
205 
SetIsNeedUpdateAppOffset(bool isNeedUpdateAppOffset)206     void SetIsNeedUpdateAppOffset(bool isNeedUpdateAppOffset)
207     {
208         isNeedUpdateAppOffset_ = isNeedUpdateAppOffset;
209     }
210 
211     // only called by RSMainThread
212     bool UpdateUIFrameworkDirtyNodes(std::vector<std::weak_ptr<RSRenderNode>>& uiFwkDirtyNodes, uint64_t timestamp);
213     // only called by RSMainThread
214     void HandleGameNode(const RSRenderNodeMap& nodeMap);
215 
216     static std::pair<bool, bool> MergeRangeByPriority(VoteRange& rangeRes, const VoteRange& curVoteRange);
217     void HandleAppStrategyConfigEvent(pid_t pid, const std::string& pkgName,
218         const std::vector<std::pair<std::string, std::string>>& newConfig);
GetRsFrameRateTimer()219     HgmSimpleTimer& GetRsFrameRateTimer() { return rsFrameRateTimer_; };
SetChangeDssRefreshRateCb(ChangeDssRefreshRateCbType changeDssRefreshRateCb)220     void SetChangeDssRefreshRateCb(ChangeDssRefreshRateCbType changeDssRefreshRateCb)
221     {
222         changeDssRefreshRateCb_ = changeDssRefreshRateCb;
223     }
224     void ProcessPageUrlVote(pid_t pid, std::string strategy, const bool isAddVoter);
225     void CleanPageUrlVote(pid_t pid);
226     void HandlePageUrlEvent();
227     void NotifyPageName(pid_t pid, const std::string &packageName, const std::string &pageName, bool isEnter);
228 private:
229     void Reset();
230     void UpdateAppSupportedState();
231     void UpdateGuaranteedPlanVote(uint64_t timestamp);
232 
233     void ProcessLtpoVote(const FrameRateRange& finalRange);
234     void SetAceAnimatorVote(const std::shared_ptr<RSRenderFrameRateLinker>& linker);
235     bool CollectFrameRateChange(FrameRateRange finalRange, std::shared_ptr<RSRenderFrameRateLinker> rsFrameRateLinker,
236         const FrameRateLinkerMap& appFrameRateLinkers);
237     void HandleFrameRateChangeForLTPO(uint64_t timestamp, bool followRs);
238     void UpdateSoftVSync(bool followRs);
239     void SetChangeGeneratorRateValid(bool valid);
240     void FrameRateReport();
241     uint32_t CalcRefreshRate(const ScreenId id, const FrameRateRange& range) const;
242     static uint32_t GetDrawingFrameRate(const uint32_t refreshRate, const FrameRateRange& range);
243     int32_t GetPreferredFps(const std::string& type, float velocityMM, float areaMM, float lengthMM) const;
244     template<typename T>
245     static float PixelToMM(T pixel);
246     template<typename T>
247     static float SqrPixelToSqrMM(T sqrPixel);
248 
249     void HandleIdleEvent(bool isIdle);
250     void HandleSceneEvent(pid_t pid, EventInfo eventInfo);
251     void HandleVirtualDisplayEvent(pid_t pid, EventInfo eventInfo);
252     void HandleGamesEvent(pid_t pid, EventInfo eventInfo);
253     void HandleMultiSelfOwnedScreenEvent(pid_t pid, EventInfo eventInfo);
254     void HandleTouchTask(pid_t pid, int32_t touchStatus, int32_t touchCnt);
255     void HandlePointerTask(pid_t pid, int32_t pointerStatus, int32_t pointerCnt);
256     void HandleScreenFrameRate(std::string curScreenName);
257     void UpdateScreenFrameRate();
258 
259     void GetLowBrightVec(const std::shared_ptr<PolicyConfigData>& configData);
260     void GetStylusVec(const std::shared_ptr<PolicyConfigData>& configData);
261     void DeliverRefreshRateVote(const VoteInfo& voteInfo, bool eventStatus);
262     void MarkVoteChange(const std::string& voter = "");
263     static bool IsCurrentScreenSupportAS();
264     void ProcessAdaptiveSync(const std::string& voterName);
265     // merge [VOTER_LTPO, VOTER_IDLE)
266     bool MergeLtpo2IdleVote(
267         std::vector<std::string>::iterator& voterIter, VoteInfo& resultVoteInfo, VoteRange& mergedVoteRange);
268     void CheckAncoVoter(const std::string& voter, VoteInfo& curVoteInfo);
269     bool ProcessRefreshRateVote(std::vector<std::string>::iterator& voterIter, VoteInfo& resultVoteInfo,
270         VoteRange& voteRange, bool &voterGamesEffective);
271     VoteInfo ProcessRefreshRateVote();
272     void ChangePriority(uint32_t curScenePriority);
273     void UpdateVoteRule();
274     void ReportHiSysEvent(const VoteInfo& frameRateVoteInfo);
275     void SetResultVoteInfo(VoteInfo& voteInfo, uint32_t min, uint32_t max);
276     void UpdateEnergyConsumptionConfig();
277     static void ProcessVoteLog(const VoteInfo& curVoteInfo, bool isSkip);
278     void RegisterCoreCallbacksAndInitController(sptr<VSyncController> rsController,
279         sptr<VSyncController> appController, sptr<VSyncGenerator> vsyncGenerator);
280     // vrate voting to hgm linkerId means that frameLinkerid, appFrameRate means that vrate
281     void CollectVRateChange(uint64_t linkerId, FrameRateRange& appFrameRate);
GetGameNodeName()282     std::string GetGameNodeName() const
283     {
284         std::lock_guard<std::mutex> lock(pendingMutex_);
285         return curGameNodeName_;
286     }
287     void CheckRefreshRateChange(bool followRs, bool frameRateChanged, uint32_t refreshRate);
SetGameNodeName(std::string nodeName)288     void SetGameNodeName(std::string nodeName)
289     {
290         std::lock_guard<std::mutex> lock(pendingMutex_);
291         curGameNodeName_ = nodeName;
292     }
293     void FrameRateReportTask(uint32_t leftRetryTimes);
294 
295     std::atomic<uint32_t> currRefreshRate_ = 0;
296     uint32_t controllerRate_ = 0;
297 
298     // concurrency protection >>>
299     mutable std::mutex pendingMutex_;
300     std::shared_ptr<uint32_t> pendingRefreshRate_ = nullptr;
301     uint64_t pendingConstraintRelativeTime_ = 0;
302     uint64_t lastPendingConstraintRelativeTime_ = 0;
303     uint32_t lastPendingRefreshRate_ = 0;
304     int64_t vsyncCountOfChangeGeneratorRate_ = -1; // default vsyncCount
305     std::atomic<bool> changeGeneratorRateValid_{ true };
306     HgmSimpleTimer changeGeneratorRateValidTimer_;
307     // if current game's self drawing node is on tree,default false
308     std::atomic<bool> isGameNodeOnTree_ = false;
309     // current game app's self drawing node name
310     std::string curGameNodeName_;
311     // concurrency protection <<<
312 
313     std::shared_ptr<HgmVSyncGeneratorController> controller_ = nullptr;
314     std::vector<std::pair<FrameRateLinkerId, uint32_t>> appChangeData_;
315     std::vector<uint32_t> lowBrightVec_;
316     std::vector<uint32_t> stylusVec_;
317 
318     std::function<void(bool, bool)> forceUpdateCallback_ = nullptr;
319     HgmSimpleTimer rsFrameRateTimer_;
320 
321     std::vector<std::string> voters_;
322     // FORMAT: <sceneName, pid>
323     std::vector<std::pair<std::string, pid_t>> sceneStack_;
324     // FORMAT: "voterName, <<pid, <min, max>>, effective>"
325     std::unordered_map<std::string, std::pair<std::vector<VoteInfo>, bool>> voteRecord_;
326     // Used to record your votes, and clear your votes after you die
327     std::unordered_set<pid_t> pidRecord_;
328     std::unordered_set<std::string> gameScenes_;
329     std::unordered_set<std::string> ancoScenes_;
330     std::unordered_map<pid_t, std::unordered_set<CleanPidCallbackType>> cleanPidCallback_;
331     // FORMAT: <timestamp, VoteInfo>
332     std::vector<std::pair<int64_t, VoteInfo>> frameRateVoteInfoVec_;
333 
334     int32_t curRefreshRateMode_ = HGM_REFRESHRATE_MODE_AUTO;
335     std::atomic<ScreenId> curScreenId_ = 0;
336     std::atomic<ScreenId> lastCurScreenId_ = 0;
337     std::string curScreenStrategyId_ = "LTPO-DEFAULT";
338     bool isLtpo_ = true;
339     bool isEnableThermalStrategy_ = false;
340     int32_t isAmbientStatus_ = 0;
341     bool isAmbientEffect_ = false;
342     int32_t stylusMode_ = -1;
343     int32_t idleFps_ = OLED_60_HZ;
344     VoteInfo lastVoteInfo_;
345     HgmMultiAppStrategy multiAppStrategy_;
346     HgmTouchManager touchManager_;
347     HgmPointerManager pointerManager_;
348     std::atomic<bool> voterTouchEffective_ = false;
349     std::atomic<bool> voterGamesEffective_ = false;
350     // For the power consumption module, only monitor touch up 3s and 600ms without flashing frames
351     std::atomic<bool> startCheck_ = false;
352     HgmIdleDetector idleDetector_;
353     // only called by RSMainThread
354     // exp. <"AceAnimato", pid, FROM_SURFACE>
355     std::vector<std::tuple<std::string, pid_t, UIFWKType>> surfaceData_;
356     uint64_t lastPostIdleDetectorTaskTimestamp_ = 0; // only called by RSMainThread
357     int32_t lastTouchUpExpectFps_ = 0;
358     bool isNeedUpdateAppOffset_ = false;
359     uint32_t schedulePreferredFps_ = 60;
360     int32_t schedulePreferredFpsChange_ = false;
361     std::atomic<int32_t> isAdaptive_ = SupportASStatus::NOT_SUPPORT;
362     // Does current game require Adaptive Sync
363     int32_t isGameSupportAS_ = SupportASStatus::NOT_SUPPORT;
364 
365     std::atomic<uint64_t> timestamp_ = 0;
366     std::shared_ptr<RSRenderFrameRateLinker> rsFrameRateLinker_ = nullptr;
367     FrameRateLinkerMap appFrameRateLinkers_;
368     // linkerid is key, vrate is value
369     std::map<uint64_t, int> vRatesMap_;
370     ChangeDssRefreshRateCbType changeDssRefreshRateCb_;
371     HgmAppPageUrlStrategy appPageUrlStrategy_;
372 };
373 } // namespace Rosen
374 } // namespace OHOS
375 #endif // HGM_FRAME_RATE_MANAGER_H
376