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_CORE_H 17 #define HGM_CORE_H 18 19 #include <cstdint> 20 #include <functional> 21 #include <cinttypes> 22 #include <memory> 23 #include <thread> 24 #include <unordered_map> 25 #include <vector> 26 #include <unordered_set> 27 28 #include <event_handler.h> 29 30 #include "hgm_frame_rate_manager.h" 31 #include "hgm_hfbc_config.h" 32 #include "hgm_screen.h" 33 #include "hgm_task_handle_thread.h" 34 #include "vsync_type.h" 35 #include "vsync_generator.h" 36 #include "xml_parser.h" 37 38 namespace OHOS::Rosen { 39 class HgmFrameRateManager; 40 using RefreshRateModeChangeCallback = std::function<void(int32_t)>; 41 using RefreshRateUpdateCallback = std::function<void(int32_t)>; 42 class HgmCore final { 43 public: 44 static HgmCore& Instance(); 45 GetScreenIds()46 std::vector<ScreenId> GetScreenIds() const 47 { 48 return screenIds_; 49 } 50 GetScreenListSize()51 int32_t GetScreenListSize() const 52 { 53 return screenList_.size(); 54 } 55 GetActiveScreenId()56 ScreenId GetActiveScreenId() const 57 { 58 if (hgmFrameRateMgr_ != nullptr) { 59 return hgmFrameRateMgr_->GetCurScreenId(); 60 } 61 return activeScreenId_.load(); 62 } 63 GetPolicyConfigData()64 const std::shared_ptr<PolicyConfigData>& GetPolicyConfigData() const 65 { 66 return mPolicyConfigData_; 67 } 68 GetPolicyConfigVisitor()69 std::shared_ptr<PolicyConfigVisitor> GetPolicyConfigVisitor() const 70 { 71 return mPolicyConfigVisitor_; 72 } 73 74 // called by RSMainThread SetPendingScreenRefreshRate(uint32_t rate)75 void SetPendingScreenRefreshRate(uint32_t rate) 76 { 77 pendingScreenRefreshRate_.store(rate); 78 } 79 80 // called by RSMainThread/RSUniRenderThread GetPendingScreenRefreshRate()81 uint32_t GetPendingScreenRefreshRate() const 82 { 83 return pendingScreenRefreshRate_.load(); 84 } 85 86 // called by HgmThread 87 // the rate takes effect at the latest hardware timing SetScreenRefreshRateImme(uint32_t rate)88 void SetScreenRefreshRateImme(uint32_t rate) 89 { 90 screenRefreshRateImme_.store(rate); 91 } 92 93 // called by HardwareThread GetScreenRefreshRateImme()94 uint32_t GetScreenRefreshRateImme() 95 { 96 // 0 means disenable 97 return screenRefreshRateImme_.exchange(0); 98 } 99 100 // called by RSMainThread SetPendingConstraintRelativeTime(uint64_t relativeTime)101 void SetPendingConstraintRelativeTime(uint64_t relativeTime) 102 { 103 pendingConstraintRelativeTime_.store(relativeTime); 104 } 105 106 // called by RSMainThread/RSUniRenderThread GetPendingConstraintRelativeTime()107 uint64_t GetPendingConstraintRelativeTime() const 108 { 109 return pendingConstraintRelativeTime_.load(); 110 } 111 112 // called by RSMainThread SetTimestamp(uint64_t timestamp)113 void SetTimestamp(uint64_t timestamp) 114 { 115 timestamp_.store(timestamp); 116 } 117 118 // called by RSMainThread/RSUniRenderThread GetCurrentTimestamp()119 uint64_t GetCurrentTimestamp() const 120 { 121 return timestamp_.load(); 122 } 123 124 // called by RSMainThread SetActualTimestamp(int64_t timestamp)125 void SetActualTimestamp(int64_t timestamp) 126 { 127 actualTimestamp_.store(timestamp); 128 } 129 130 // called by RSMainThread/RSUniRenderThread GetActualTimestamp()131 int64_t GetActualTimestamp() const 132 { 133 return actualTimestamp_.load(); 134 } 135 136 // called by RSMainThread SetVsyncId(uint64_t vsyncId)137 void SetVsyncId(uint64_t vsyncId) 138 { 139 vsyncId_.store(vsyncId); 140 } 141 142 // called by RSMainThread/RSUniRenderThread GetVsyncId()143 uint64_t GetVsyncId() const 144 { 145 return vsyncId_.load(); 146 } 147 148 // called by RSMainThread SetForceRefreshFlag(bool isForceRefresh)149 void SetForceRefreshFlag(bool isForceRefresh) 150 { 151 isForceRefresh_.store(isForceRefresh); 152 } 153 154 // called by RSMainThread/RSUniRenderThread GetForceRefreshFlag()155 bool GetForceRefreshFlag() const 156 { 157 return isForceRefresh_.load(); 158 } 159 160 // called by RSMainThread SetFastComposeTimeStampDiff(uint64_t fastComposeTimeStampDiff)161 void SetFastComposeTimeStampDiff(uint64_t fastComposeTimeStampDiff) 162 { 163 fastComposeTimeStampDiff_.store(fastComposeTimeStampDiff); 164 } 165 166 // called by RSMainThread/RSUniRenderThread GetFastComposeTimeStampDiff()167 uint64_t GetFastComposeTimeStampDiff() const 168 { 169 return fastComposeTimeStampDiff_.load(); 170 } 171 172 // called by RSMainThread SetHgmTaskFlag(bool value)173 bool SetHgmTaskFlag(bool value) 174 { 175 return postHgmTaskFlag_.exchange(value); 176 } 177 GetLtpoEnabled()178 bool GetLtpoEnabled() const 179 { 180 return ltpoEnabled_ && (maxTE_ == CreateVSyncGenerator()->GetVSyncMaxRefreshRate()); 181 } 182 GetAdaptiveSyncEnabled()183 bool GetAdaptiveSyncEnabled() const 184 { 185 return GetLtpoEnabled() && adaptiveSync_ == ADAPTIVE_SYNC_ENABLED; 186 } 187 188 // called by RSHardwareTHread IsVBlankIdleCorrectEnabled()189 bool IsVBlankIdleCorrectEnabled() const 190 { 191 return vBlankIdleCorrectSwitch_.load(); 192 } 193 IsLowRateToHighQuickEnabled()194 bool IsLowRateToHighQuickEnabled() const 195 { 196 return lowRateToHighQuickSwitch_.load(); 197 } 198 IsLTPOSwitchOn()199 bool IsLTPOSwitchOn() const 200 { 201 return ltpoEnabled_; 202 } 203 SetLtpoEnabled(bool ltpoEnabled)204 void SetLtpoEnabled(bool ltpoEnabled) 205 { 206 ltpoEnabled_ = ltpoEnabled; 207 } 208 GetAlignRate()209 uint32_t GetAlignRate() const 210 { 211 return alignRate_; 212 } 213 SetIdealPipelineOffset(int32_t pipelineOffsetPulseNum)214 void SetIdealPipelineOffset(int32_t pipelineOffsetPulseNum) 215 { 216 idealPipelineOffset_ = pipelineOffsetPulseNum * IDEAL_PULSE; 217 } 218 GetIdealPipelineOffset()219 int64_t GetIdealPipelineOffset() const 220 { 221 return idealPipelineOffset_; 222 } 223 GetPipelineOffset()224 int64_t GetPipelineOffset() const 225 { 226 auto pulse = CreateVSyncGenerator()->GetVSyncPulse(); 227 return pipelineOffsetPulseNum_ * pulse; 228 } 229 GetSupportedMaxTE()230 uint32_t GetSupportedMaxTE() const 231 { 232 return maxTE_; 233 } 234 SetSupportedMaxTE(uint32_t maxTE)235 void SetSupportedMaxTE(uint32_t maxTE) 236 { 237 maxTE_ = maxTE; 238 } 239 GetPluseNum()240 int32_t GetPluseNum() const 241 { 242 return pluseNum_; 243 } 244 245 // called by RSMainThread/RSUniRenderThread GetDirectCompositionFlag()246 bool GetDirectCompositionFlag() const 247 { 248 return doDirectComposition_.load(); 249 } 250 251 // called by RSMainThread SetDirectCompositionFlag(bool doDirectComposition)252 void SetDirectCompositionFlag(bool doDirectComposition) 253 { 254 doDirectComposition_.store(doDirectComposition); 255 } 256 257 // set refresh rates 258 int32_t SetScreenRefreshRate(ScreenId id, int32_t sceneId, int32_t rate, bool shouldSendCallback = true); 259 static int32_t SetRateAndResolution(ScreenId id, int32_t sceneId, int32_t rate, int32_t width, int32_t height); 260 int32_t SetRefreshRateMode(int32_t refreshRateMode); 261 262 void NotifyScreenPowerStatus(ScreenId id, ScreenPowerStatus status); 263 void NotifyScreenRectFrameRateChange(ScreenId id, const GraphicIRect& activeRect); 264 265 // screen interface 266 int32_t AddScreen(ScreenId id, int32_t defaultMode, ScreenSize& screenSize); 267 int32_t RemoveScreen(ScreenId id); 268 int32_t AddScreenInfo(ScreenId id, int32_t width, int32_t height, uint32_t rate, int32_t mode); 269 uint32_t GetScreenCurrentRefreshRate(ScreenId id) const; 270 int32_t GetCurrentRefreshRateMode() const; 271 int32_t GetCurrentRefreshRateModeName() const; 272 sptr<HgmScreen> GetScreen(ScreenId id) const; 273 sptr<HgmScreen> GetActiveScreen() const; 274 std::vector<uint32_t> GetScreenSupportedRefreshRates(ScreenId id); 275 std::vector<int32_t> GetScreenComponentRefreshRates(ScreenId id); 276 // called by RSHardwareTHread 277 std::unique_ptr<std::unordered_map<ScreenId, int32_t>> GetModesToApply(); 278 void SetActiveScreenId(ScreenId id); GetFrameRateMgr()279 std::shared_ptr<HgmFrameRateManager> GetFrameRateMgr() { return hgmFrameRateMgr_; }; 280 281 // for LTPO 282 void SetLtpoConfig(); 283 void SetScreenConstraintConfig(); 284 void SetPerformanceConfig(); 285 int64_t GetIdealPeriod(uint32_t rate); 286 void RegisterRefreshRateModeChangeCallback(const RefreshRateModeChangeCallback& callback); 287 void RegisterRefreshRateUpdateCallback(const RefreshRateUpdateCallback& callback); GetRefreshRateModeChangeCallback()288 RefreshRateModeChangeCallback GetRefreshRateModeChangeCallback() const 289 { 290 return refreshRateModeChangeCallback_; 291 } 292 GetRefreshRateUpdate()293 RefreshRateUpdateCallback GetRefreshRateUpdate() const 294 { 295 return refreshRateUpdateCallback_; 296 } 297 SetEnableDynamicMode(bool enableDynamicMode)298 void SetEnableDynamicMode(bool enableDynamicMode) 299 { 300 enableDynamicMode_ = enableDynamicMode; 301 } 302 GetEnableDynamicMode()303 bool GetEnableDynamicMode() const 304 { 305 return enableDynamicMode_; 306 } 307 IsDelayMode()308 bool IsDelayMode() const 309 { 310 return isDelayMode_; 311 } 312 SetMultiSelfOwnedScreenEnable(bool multiSelfOwnedScreenEnable)313 void SetMultiSelfOwnedScreenEnable(bool multiSelfOwnedScreenEnable) 314 { 315 multiSelfOwnedScreenEnable_.store(multiSelfOwnedScreenEnable); 316 } 317 GetMultiSelfOwnedScreenEnable()318 bool GetMultiSelfOwnedScreenEnable() const 319 { 320 return multiSelfOwnedScreenEnable_.load(); 321 } 322 GetHfbcConfig()323 HgmHfbcConfig& GetHfbcConfig() 324 { 325 return hfbcConfig_; 326 } 327 static void SysModeChangeProcess(const char* key, const char* value, void* context); 328 private: 329 HgmCore(); 330 ~HgmCore() = default; 331 HgmCore(const HgmCore&) = delete; 332 HgmCore(const HgmCore&&) = delete; 333 HgmCore& operator=(const HgmCore&) = delete; 334 HgmCore& operator=(const HgmCore&&) = delete; 335 friend class HgmUserDefineImpl; 336 337 void Init(); 338 int AddParamWatcher() const; 339 void CheckCustomFrameRateModeValid(); 340 int32_t InitXmlConfig(); 341 int32_t SetCustomRateMode(int32_t mode); 342 void SetASConfig(const PolicyConfigData::ScreenSetting& curScreenSetting); 343 IsEnabled()344 bool IsEnabled() const 345 { 346 return mPolicyConfigData_ != nullptr && !mPolicyConfigData_->refreshRateForSettings_.empty(); 347 } 348 349 static constexpr char CONFIG_FILE_PRODUCT[] = "/sys_prod/etc/graphic/hgm_policy_config.xml"; 350 std::unique_ptr<XMLParser> mParser_ = nullptr; 351 std::shared_ptr<PolicyConfigData> mPolicyConfigData_ = nullptr; 352 std::shared_ptr<PolicyConfigVisitor> mPolicyConfigVisitor_ = nullptr; 353 354 int32_t customFrameRateMode_ = HGM_REFRESHRATE_MODE_AUTO; 355 std::vector<ScreenId> screenIds_; 356 std::vector<sptr<HgmScreen>> screenList_; 357 mutable std::mutex listMutex_; 358 359 mutable std::mutex modeListMutex_; 360 std::unique_ptr<std::unordered_map<ScreenId, int32_t>> modeListToApply_ = nullptr; 361 362 std::atomic<ScreenId> activeScreenId_{ INVALID_SCREEN_ID }; 363 std::shared_ptr<HgmFrameRateManager> hgmFrameRateMgr_ = nullptr; 364 365 // for LTPO 366 std::atomic<uint32_t> pendingScreenRefreshRate_{ 0 }; 367 std::atomic<uint32_t> screenRefreshRateImme_{ 0 }; 368 std::atomic<uint64_t> pendingConstraintRelativeTime_{ 0 }; 369 std::atomic<uint64_t> timestamp_{ 0 }; 370 std::atomic<int64_t> actualTimestamp_{ 0 }; 371 std::atomic<uint64_t> vsyncId_{ 0 }; 372 std::atomic<bool> isForceRefresh_{ false }; 373 std::atomic<uint64_t> fastComposeTimeStampDiff_{ 0 }; 374 bool isDelayMode_ = true; 375 bool ltpoEnabled_ = false; 376 uint32_t maxTE_ = 0; 377 uint32_t alignRate_ = 0; 378 int64_t idealPipelineOffset_ = 0; 379 int32_t pluseNum_ = -1; 380 int adaptiveSync_ = 0; 381 int32_t pipelineOffsetPulseNum_ = 8; 382 std::atomic<bool> vBlankIdleCorrectSwitch_{ false }; 383 std::atomic<bool> lowRateToHighQuickSwitch_{ false }; 384 RefreshRateModeChangeCallback refreshRateModeChangeCallback_ = nullptr; 385 RefreshRateUpdateCallback refreshRateUpdateCallback_ = nullptr; 386 std::atomic<bool> doDirectComposition_{ false }; 387 bool enableDynamicMode_ = true; 388 std::atomic<bool> multiSelfOwnedScreenEnable_{ false }; 389 std::atomic<bool> postHgmTaskFlag_{ true }; 390 HgmHfbcConfig hfbcConfig_; 391 392 friend class HWCParam; 393 }; 394 } // namespace OHOS::Rosen 395 #endif // HGM_CORE_H 396