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