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