• 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_frame_voter.h"
28 #include "hgm_idle_detector.h"
29 #include "hgm_multi_app_strategy.h"
30 #include "hgm_soft_vsync_manager.h"
31 #include "hgm_one_shot_timer.h"
32 #include "hgm_screen.h"
33 #include "hgm_task_handle_thread.h"
34 #include "hgm_touch_manager.h"
35 #include "hgm_pointer_manager.h"
36 #include "hgm_voter.h"
37 #include "hgm_vsync_generator_controller.h"
38 #include "hgm_user_define.h"
39 #include "vsync_distributor.h"
40 #include "pipeline/rs_render_frame_rate_linker.h"
41 #include "pipeline/rs_render_node.h"
42 #include "pipeline/rs_render_node_map.h"
43 #include "screen_manager/screen_types.h"
44 #include "variable_frame_rate/rs_variable_frame_rate.h"
45 
46 namespace OHOS {
47 namespace Rosen {
48 using FrameRateLinkerMap = std::unordered_map<FrameRateLinkerId, std::shared_ptr<RSRenderFrameRateLinker>>;
49 
50 enum VoteType : bool {
51     REMOVE_VOTE = false,
52     ADD_VOTE = true
53 };
54 
55 enum TouchStatus : uint32_t {
56     TOUCH_CANCEL = 1,
57     TOUCH_DOWN = 2,
58     TOUCH_MOVE = 3,
59     TOUCH_UP = 4,
60     AXIS_BEGIN = 5,
61     AXIS_UPDATE = 6,
62     AXIS_END = 7,
63     TOUCH_BUTTON_DOWN = 8,
64     TOUCH_BUTTON_UP = 9,
65     TOUCH_PULL_DOWN = 12,
66     TOUCH_PULL_MOVE = 13,
67     TOUCH_PULL_UP = 14,
68 };
69 
70 enum CleanPidCallbackType : uint32_t {
71     LIGHT_FACTOR,
72     PACKAGE_EVENT,
73     TOUCH_EVENT,
74     POINTER_EVENT,
75     GAMES,
76     PAGE_URL,
77     APP_STRATEGY_CONFIG_EVENT,
78 };
79 
80 enum LightFactorStatus : int32_t {
81     // normal level
82     NORMAL_HIGH = 0,
83     NORMAL_LOW,
84     // brightness level
85     LOW_LEVEL = 3,
86     MIDDLE_LEVEL,
87     HIGH_LEVEL,
88 };
89 
90 enum SupportASStatus : int32_t {
91     NOT_SUPPORT = 0,
92     SUPPORT_AS = 1,
93     GAME_SCENE_SKIP = 2,
94 };
95 
96 class HgmFrameRateManager {
97 public:
98     HgmFrameRateManager();
99     ~HgmFrameRateManager() = default;
100 
101     void HandleLightFactorStatus(pid_t pid, int32_t state);
102     void HandlePackageEvent(pid_t pid, const std::vector<std::string>& packageList);
103     void HandleRefreshRateEvent(pid_t pid, const EventInfo& eventInfo);
104     void HandleTouchEvent(pid_t pid, int32_t touchStatus, int32_t touchCnt);
105     void HandleDynamicModeEvent(bool enableDynamicModeEvent);
106 
107     void CleanVote(pid_t pid);
GetCurRefreshRateMode()108     int32_t GetCurRefreshRateMode() const { return curRefreshRateMode_; };
GetCurrRefreshRate()109     uint32_t GetCurrRefreshRate() { return currRefreshRate_; }
GetCurScreenId()110     ScreenId GetCurScreenId() const { return curScreenId_.load(); };
GetLastCurScreenId()111     ScreenId GetLastCurScreenId() const { return lastCurScreenId_.load(); };
SetLastCurScreenId(ScreenId screenId)112     void SetLastCurScreenId(ScreenId screenId)
113     {
114         lastCurScreenId_.store(screenId);
115     }
GetCurScreenStrategyId()116     std::string GetCurScreenStrategyId() const { return curScreenStrategyId_; };
117     void HandleRefreshRateMode(int32_t refreshRateMode);
118     void HandleScreenPowerStatus(ScreenId id, ScreenPowerStatus status);
119     void HandleScreenRectFrameRate(ScreenId id, const GraphicIRect& activeRect);
120     void HandleScreenExtStrategyChange(bool status, const std::string& suffix);
121     std::string GetCurScreenExtStrategyId();
122     void UpdateScreenExtStrategyConfig(const PolicyConfigData::ScreenConfigMap& screenConfigs);
123 
124     // called by RSHardwareThread
125     void HandleRsFrame();
IsLtpo()126     bool IsLtpo() const { return isLtpo_; };
AdaptiveStatus()127     int32_t AdaptiveStatus() const { return isAdaptive_.load(); };
128     // called by RSHardwareThread
IsGameNodeOnTree()129     bool IsGameNodeOnTree() const { return isGameNodeOnTree_.load(); };
130     void UniProcessDataForLtpo(uint64_t timestamp, std::shared_ptr<RSRenderFrameRateLinker> rsFrameRateLinker,
131         const FrameRateLinkerMap& appFrameRateLinkers, const std::map<uint64_t, int>& vRatesMap);
132 
133     int32_t GetExpectedFrameRate(const RSPropertyUnit unit, float velocityPx, int32_t areaPx, int32_t lengthPx) const;
SetForceUpdateCallback(std::function<void (bool,bool)> forceUpdateCallback)134     void SetForceUpdateCallback(std::function<void(bool, bool)> forceUpdateCallback)
135     {
136         forceUpdateCallback_ = forceUpdateCallback;
137     }
138 
139     void Init(sptr<VSyncController> rsController, sptr<VSyncController> appController,
140         sptr<VSyncGenerator> vsyncGenerator, sptr<VSyncDistributor> appDistributor);
141     void SetTimeoutParamsFromConfig(const std::shared_ptr<PolicyConfigData>& configData);
142     // called by RSMainThread
143     void ProcessPendingRefreshRate(uint64_t timestamp, int64_t vsyncId, uint32_t rsRate, bool isUiDvsyncOn);
GetMultiAppStrategy()144     HgmMultiAppStrategy& GetMultiAppStrategy() { return multiAppStrategy_; }
GetTouchManager()145     HgmTouchManager& GetTouchManager() { return touchManager_; }
GetIdleDetector()146     HgmIdleDetector& GetIdleDetector() { return idleDetector_; }
147     // only called by RSMainThread
148     void UpdateSurfaceTime(const std::string& surfaceName, pid_t pid, UIFWKType uiFwkType);
SetSchedulerPreferredFps(uint32_t schedulePreferredFps)149     void SetSchedulerPreferredFps(uint32_t schedulePreferredFps)
150     {
151         if (schedulePreferredFps_ != schedulePreferredFps) {
152             schedulePreferredFps_ = schedulePreferredFps;
153             schedulePreferredFpsChange_ = true;
154         }
155     }
156 
SetIsNeedUpdateAppOffset(bool isNeedUpdateAppOffset)157     void SetIsNeedUpdateAppOffset(bool isNeedUpdateAppOffset)
158     {
159         isNeedUpdateAppOffset_ = isNeedUpdateAppOffset;
160     }
161 
162     // only called by RSMainThread
163     bool UpdateUIFrameworkDirtyNodes(std::vector<std::weak_ptr<RSRenderNode>>& uiFwkDirtyNodes, uint64_t timestamp);
164     // only called by RSMainThread
165     bool HandleGameNode(const RSRenderNodeMap& nodeMap);
166 
GetRsFrameRateTimer()167     HgmSimpleTimer& GetRsFrameRateTimer() { return rsFrameRateTimer_; };
168 
169     void ProcessPageUrlVote(pid_t pid, std::string strategy, const bool isAddVoter);
170     void CleanPageUrlVote(pid_t pid);
171     void HandlePageUrlEvent();
172     void NotifyPageName(pid_t pid, const std::string& packageName, const std::string& pageName, bool isEnter);
173     // called by OS_IPC thread
174     bool SetVsyncRateDiscountLTPO(const std::vector<uint64_t>& linkerIds, uint32_t rateDiscount);
SoftVSyncMgrRef()175     HgmSoftVSyncManager& SoftVSyncMgrRef() { return softVSyncManager_; };
176     void HandleAppStrategyConfigEvent(pid_t pid, const std::string& pkgName,
177         const std::vector<std::pair<std::string, std::string>>& newConfig);
FrameVoterRef()178     HgmFrameVoter& FrameVoterRef() { return frameVoter_; }
179 private:
180     friend class HgmUserDefineImpl;
181 
182     void InitTouchManager();
183     void InitConfig();
184     void Reset();
185     void UpdateAppSupportedState();
186     void UpdateGuaranteedPlanVote(uint64_t timestamp);
187 
188     void ProcessLtpoVote(const FrameRateRange& finalRange);
189     void SetAceAnimatorVote(const std::shared_ptr<RSRenderFrameRateLinker>& linker);
190     void HandleFrameRateChangeForLTPO(uint64_t timestamp, bool followRs, bool frameRateChange);
191     void DVSyncTaskProcessor(int64_t delayTime, uint64_t targetTime,
192         std::vector<std::pair<FrameRateLinkerId, uint32_t>> appChangeData, int64_t controllerRate);
193     void UpdateSoftVSync(bool followRs);
194     void SetChangeGeneratorRateValid(bool valid);
195     void FrameRateReport();
196     uint32_t CalcRefreshRate(const ScreenId id, const FrameRateRange& range) const;
197     int32_t GetPreferredFps(const std::string& type, float velocityMM, float areaSqrMM, float lengthMM) const;
198     template<typename T>
199     static float PixelToMM(T pixel);
200     template<typename T>
201     static float SqrPixelToSqrMM(T sqrPixel);
202 
203     void HandleIdleEvent(bool isIdle);
204     void HandleStylusSceneEvent(const std::string& sceneName);
205     void HandleSceneEvent(pid_t pid, const EventInfo& eventInfo);
206     void HandleVirtualDisplayEvent(pid_t pid, EventInfo eventInfo);
207     void HandleGamesEvent(pid_t pid, EventInfo eventInfo);
208     void HandleMultiSelfOwnedScreenEvent(pid_t pid, EventInfo eventInfo);
209     void HandleTouchTask(pid_t pid, int32_t touchStatus, int32_t touchCnt);
210     void HandlePointerTask(pid_t pid, int32_t pointerStatus, int32_t pointerCnt);
211     void HandleScreenFrameRate(std::string curScreenName);
212     void UpdateScreenFrameRate();
213     void RegisterUpTimeoutAndDownEvent();
214 
215     void GetSupportedRefreshRates(const std::shared_ptr<PolicyConfigData>& configData,
216         const std::string& modeKey, std::vector<uint32_t>& targetVec, bool handleAmbientEffect);
217     void GetLowBrightVec(const std::shared_ptr<PolicyConfigData>& configData);
218     void GetAncoLowBrightVec(const std::shared_ptr<PolicyConfigData>& configData);
219     void GetStylusVec(const std::shared_ptr<PolicyConfigData>& configData);
220     void DeliverRefreshRateVote(const VoteInfo& voteInfo, bool eventStatus);
221     void MarkVoteChange(const std::string& voter = "");
222     static bool IsCurrentScreenSupportAS();
223     void ProcessAdaptiveSync(const std::string& voterName);
224     bool CheckAncoVoterStatus() const;
225     VoteInfo ProcessRefreshRateVote();
226     void ReportHiSysEvent(const VoteInfo& frameRateVoteInfo);
227     void SetResultVoteInfo(VoteInfo& voteInfo, uint32_t min, uint32_t max);
228     void UpdateEnergyConsumptionConfig();
229     void RegisterCoreCallbacksAndInitController(sptr<VSyncController> rsController,
230         sptr<VSyncController> appController,
231         sptr<VSyncGenerator> vsyncGenerator, sptr<VSyncDistributor> appDistributor);
232     void CheckRefreshRateChange(
233         bool followRs, bool frameRateChanged, uint32_t refreshRate, bool needChangeDssRefreshRate);
234     uint32_t UpdateFrameRateWithDelay(uint32_t refreshRate);
GetGameNodeName()235     std::string GetGameNodeName() const
236     {
237         std::lock_guard<std::mutex> lock(pendingMutex_);
238         return curGameNodeName_;
239     }
SetGameNodeName(std::string nodeName)240     void SetGameNodeName(std::string nodeName)
241     {
242         std::lock_guard<std::mutex> lock(pendingMutex_);
243         curGameNodeName_ = nodeName;
244     }
245     void FrameRateReportTask(uint32_t leftRetryTimes);
246     void CheckNeedUpdateAppOffset(uint32_t refreshRate, uint32_t controllerRate);
CheckForceUpdateCallback(uint32_t refreshRate)247     void CheckForceUpdateCallback(uint32_t refreshRate)
248     {
249         if (needForceUpdateUniRender_ && refreshRate != currRefreshRate_.load() && forceUpdateCallback_) {
250             forceUpdateCallback_(false, true);
251         }
252     }
253 
254     std::atomic<uint32_t> currRefreshRate_ = 0;
255 
256     // concurrency protection >>>
257     mutable std::mutex pendingMutex_;
258     std::shared_ptr<uint32_t> pendingRefreshRate_ = nullptr;
259     uint64_t pendingConstraintRelativeTime_ = 0;
260     uint64_t lastPendingConstraintRelativeTime_ = 0;
261     uint32_t lastPendingRefreshRate_ = 0;
262     int64_t vsyncCountOfChangeGeneratorRate_ = -1; // default vsyncCount
263     std::atomic<bool> changeGeneratorRateValid_{ true };
264     HgmSimpleTimer changeGeneratorRateValidTimer_;
265     // if current game's self drawing node is on tree,default false
266     std::atomic<bool> isGameNodeOnTree_ = false;
267     // current game app's self drawing node name
268     std::string curGameNodeName_;
269     // concurrency protection <<<
270 
271     std::shared_ptr<HgmVSyncGeneratorController> controller_ = nullptr;
272     std::vector<uint32_t> lowBrightVec_;
273     std::vector<uint32_t> ancoLowBrightVec_;
274     std::vector<uint32_t> stylusVec_;
275 
276     std::function<void(bool, bool)> forceUpdateCallback_ = nullptr;
277     HgmSimpleTimer rsFrameRateTimer_;
278 
279     std::unordered_map<pid_t, std::unordered_set<CleanPidCallbackType>> cleanPidCallback_;
280     // FORMAT: <timestamp, VoteInfo>
281     std::vector<std::pair<int64_t, VoteInfo>> frameRateVoteInfoVec_;
282 
283     int32_t curRefreshRateMode_ = HGM_REFRESHRATE_MODE_AUTO;
284     std::atomic<ScreenId> curScreenId_ = 0;
285     std::atomic<ScreenId> lastCurScreenId_ = 0;
286     std::string curScreenStrategyId_ = "LTPO-DEFAULT";
287     std::string curScreenDefaultStrategyId_ = "LTPO-DEFAULT";
288     bool isLtpo_ = true;
289     int32_t idleFps_ = OLED_60_HZ;
290     std::unordered_map<std::string, std::pair<int32_t, bool>> screenExtStrategyMap_ = HGM_CONFIG_SCREENEXT_STRATEGY_MAP;
291     int32_t isAmbientStatus_ = 0;
292     bool isAmbientEffect_ = false;
293     bool isStylusWakeUp_ = false;
294     VoteInfo lastVoteInfo_;
295     HgmMultiAppStrategy multiAppStrategy_;
296     HgmTouchManager touchManager_;
297     HgmPointerManager pointerManager_;
298     HgmSoftVSyncManager softVSyncManager_;
299     HgmFrameVoter frameVoter_;
300     HgmUserDefine userDefine_;
301     std::atomic<bool> voterTouchEffective_ = false;
302     // For the power consumption module, only monitor touch up 3s and 600ms without flashing frames
303     std::atomic<bool> startCheck_ = false;
304     HgmIdleDetector idleDetector_;
305     // only called by RSMainThread
306     // exp. <"AceAnimato", pid, FROM_SURFACE>
307     std::vector<std::tuple<std::string, pid_t, UIFWKType>> surfaceData_;
308     uint64_t lastPostIdleDetectorTaskTimestamp_ = 0; // only called by RSMainThread
309     int32_t lastTouchUpExpectFps_ = 0;
310     bool isNeedUpdateAppOffset_ = false;
311     uint32_t schedulePreferredFps_ = 60;
312     int32_t schedulePreferredFpsChange_ = false;
313     std::atomic<int32_t> isAdaptive_ = SupportASStatus::NOT_SUPPORT;
314     // Does current game require Adaptive Sync
315     int32_t isGameSupportAS_ = SupportASStatus::NOT_SUPPORT;
316 
317     std::atomic<uint64_t> timestamp_ = 0;
318     std::shared_ptr<RSRenderFrameRateLinker> rsFrameRateLinker_ = nullptr;
319     FrameRateLinkerMap appFrameRateLinkers_;
320     HgmAppPageUrlStrategy appPageUrlStrategy_;
321 
322     uint32_t lastLTPORefreshRate_ = 0;
323     long lastLTPOVoteTime_ = 0;
324 
325     bool needForceUpdateUniRender_ = false;
326 };
327 } // namespace Rosen
328 } // namespace OHOS
329 #endif // HGM_FRAME_RATE_MANAGER_H
330