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_screen.h" 31 #include "vsync_type.h" 32 #include "vsync_generator.h" 33 #include "xml_parser.h" 34 35 namespace OHOS::Rosen { 36 class HgmFrameRateManager; 37 using RefreshRateModeChangeCallback = std::function<void(int32_t)>; 38 using RefreshRateUpdateCallback = std::function<void(int32_t)>; 39 class HgmCore final { 40 public: 41 static HgmCore& Instance(); 42 GetScreenIds()43 std::vector<ScreenId> GetScreenIds() const 44 { 45 return screenIds_; 46 } 47 IsEnabled()48 bool IsEnabled() const 49 { 50 return isEnabled_; 51 } 52 IsInit()53 bool IsInit() const 54 { 55 return isInit_.load(); 56 } 57 GetScreenListSize()58 int32_t GetScreenListSize() const 59 { 60 return screenList_.size(); 61 } 62 GetActiveScreenId()63 ScreenId GetActiveScreenId() const 64 { 65 return activeScreenId_; 66 } 67 GetPolicyConfigData()68 const std::shared_ptr<PolicyConfigData>& GetPolicyConfigData() const 69 { 70 return mPolicyConfigData_; 71 } 72 SetPendingScreenRefreshRate(uint32_t rate)73 void SetPendingScreenRefreshRate(uint32_t rate) 74 { 75 pendingScreenRefreshRate_ = rate; 76 } 77 GetPendingScreenRefreshRate()78 uint32_t GetPendingScreenRefreshRate() const 79 { 80 return pendingScreenRefreshRate_; 81 } 82 83 // called by HgmThread 84 // the rate takes effect at the latest hardware timing SetScreenRefreshRateImme(uint32_t rate)85 void SetScreenRefreshRateImme(uint32_t rate) 86 { 87 screenRefreshRateImme_.store(rate); 88 } 89 90 // called by HardwareThread GetScreenRefreshRateImme()91 uint32_t GetScreenRefreshRateImme() 92 { 93 // 0 means disenable 94 return screenRefreshRateImme_.exchange(0); 95 } 96 SetPendingConstraintRelativeTime(uint64_t relativeTime)97 void SetPendingConstraintRelativeTime(uint64_t relativeTime) 98 { 99 pendingConstraintRelativeTime_ = relativeTime; 100 } 101 GetPendingConstraintRelativeTime()102 uint64_t GetPendingConstraintRelativeTime() const 103 { 104 return pendingConstraintRelativeTime_; 105 } 106 SetTimestamp(uint64_t timestamp)107 void SetTimestamp(uint64_t timestamp) 108 { 109 timestamp_ = timestamp; 110 } 111 GetCurrentTimestamp()112 uint64_t GetCurrentTimestamp() const 113 { 114 return timestamp_; 115 } 116 117 // called by RSMainThread SetActualTimestamp(int64_t timestamp)118 void SetActualTimestamp(int64_t timestamp) 119 { 120 actualTimestamp_.store(timestamp); 121 } 122 123 // called by RSMainThread/RSUniRenderThread GetActualTimestamp()124 int64_t GetActualTimestamp() const 125 { 126 return actualTimestamp_.load(); 127 } 128 129 // called by RSMainThread SetVsyncId(uint64_t vsyncId)130 void SetVsyncId(uint64_t vsyncId) 131 { 132 vsyncId_.store(vsyncId); 133 } 134 135 // called by RSMainThread/RSUniRenderThread GetVsyncId()136 uint64_t GetVsyncId() const 137 { 138 return vsyncId_.load(); 139 } 140 141 // called by RSMainThread SetForceRefreshFlag(bool isForceRefresh)142 void SetForceRefreshFlag(bool isForceRefresh) 143 { 144 isForceRefresh_.store(isForceRefresh); 145 } 146 147 // called by RSMainThread/RSUniRenderThread GetForceRefreshFlag()148 bool GetForceRefreshFlag() const 149 { 150 return isForceRefresh_.load(); 151 } 152 GetLtpoEnabled()153 bool GetLtpoEnabled() const 154 { 155 return ltpoEnabled_ && (customFrameRateMode_ == HGM_REFRESHRATE_MODE_AUTO) && 156 (maxTE_ == VSYNC_MAX_REFRESHRATE); 157 } 158 IsVBlankIdleCorrectEnabled()159 bool IsVBlankIdleCorrectEnabled() const 160 { 161 return vBlankIdleCorrectSwitch_; 162 } 163 IsLowRateToHighQuickEnabled()164 bool IsLowRateToHighQuickEnabled() const 165 { 166 return lowRateToHighQuickSwitch_; 167 } 168 IsLTPOSwitchOn()169 bool IsLTPOSwitchOn() const 170 { 171 return ltpoEnabled_; 172 } 173 SetLtpoEnabled(bool ltpoEnabled)174 void SetLtpoEnabled(bool ltpoEnabled) 175 { 176 ltpoEnabled_ = ltpoEnabled; 177 } 178 GetAlignRate()179 uint32_t GetAlignRate() const 180 { 181 return alignRate_; 182 } 183 GetPipelineOffset()184 int64_t GetPipelineOffset() const 185 { 186 auto pulse = CreateVSyncGenerator()->GetVSyncPulse(); 187 return pipelineOffsetPulseNum_ * pulse; 188 } 189 GetSupportedMaxTE()190 uint32_t GetSupportedMaxTE() const 191 { 192 return maxTE_; 193 } 194 SetSupportedMaxTE(uint32_t maxTE)195 void SetSupportedMaxTE(uint32_t maxTE) 196 { 197 maxTE_ = maxTE; 198 } 199 GetDirectCompositionFlag()200 bool GetDirectCompositionFlag() const 201 { 202 return doDirectComposition_; 203 } 204 SetDirectCompositionFlag(bool doDirectComposition)205 void SetDirectCompositionFlag(bool doDirectComposition) 206 { 207 doDirectComposition_ = doDirectComposition; 208 } 209 210 // set refresh rates 211 int32_t SetScreenRefreshRate(ScreenId id, int32_t sceneId, int32_t rate); 212 static int32_t SetRateAndResolution(ScreenId id, int32_t sceneId, int32_t rate, int32_t width, int32_t height); 213 int32_t SetRefreshRateMode(int32_t refreshRateMode); 214 215 void NotifyScreenPowerStatus(ScreenId id, ScreenPowerStatus status); 216 217 // screen interface 218 int32_t AddScreen(ScreenId id, int32_t defaultMode, ScreenSize& screenSize); 219 int32_t RemoveScreen(ScreenId id); 220 int32_t AddScreenInfo(ScreenId id, int32_t width, int32_t height, uint32_t rate, int32_t mode); 221 int32_t RefreshBundleName(const std::string& name); 222 uint32_t GetScreenCurrentRefreshRate(ScreenId id) const; 223 int32_t GetCurrentRefreshRateMode() const; 224 int32_t GetCurrentRefreshRateModeName() const; 225 sptr<HgmScreen> GetScreen(ScreenId id) const; 226 sptr<HgmScreen> GetActiveScreen() const; 227 std::vector<uint32_t> GetScreenSupportedRefreshRates(ScreenId id); 228 std::vector<int32_t> GetScreenComponentRefreshRates(ScreenId id); 229 std::unique_ptr<std::unordered_map<ScreenId, int32_t>> GetModesToApply(); 230 void SetActiveScreenId(ScreenId id); GetFrameRateMgr()231 std::shared_ptr<HgmFrameRateManager> GetFrameRateMgr() { return hgmFrameRateMgr_; }; 232 233 // for LTPO 234 void SetLtpoConfig(); 235 void SetScreenConstraintConfig(); 236 int64_t GetIdealPeriod(uint32_t rate); 237 void RegisterRefreshRateModeChangeCallback(const RefreshRateModeChangeCallback& callback); 238 void RegisterRefreshRateUpdateCallback(const RefreshRateUpdateCallback& callback); GetRefreshRateModeChangeCallback()239 RefreshRateModeChangeCallback GetRefreshRateModeChangeCallback() const 240 { 241 return refreshRateModeChangeCallback_; 242 } 243 GetRefreshRateUpdate()244 RefreshRateUpdateCallback GetRefreshRateUpdate() const 245 { 246 return refreshRateUpdateCallback_; 247 } 248 SetEnableDynamicMode(bool enableDynamicMode)249 void SetEnableDynamicMode(bool enableDynamicMode) 250 { 251 enableDynamicMode_ = enableDynamicMode; 252 } 253 GetEnableDynamicMode()254 bool GetEnableDynamicMode() const 255 { 256 return enableDynamicMode_; 257 } 258 IsDelayMode()259 bool IsDelayMode() const 260 { 261 return isDelayMode_; 262 } 263 private: 264 HgmCore(); 265 ~HgmCore() = default; 266 HgmCore(const HgmCore&) = delete; 267 HgmCore(const HgmCore&&) = delete; 268 HgmCore& operator=(const HgmCore&) = delete; 269 HgmCore& operator=(const HgmCore&&) = delete; 270 271 bool Init(); 272 void CheckCustomFrameRateModeValid(); 273 int32_t InitXmlConfig(); 274 int32_t SetCustomRateMode(int32_t mode); 275 276 bool isEnabled_ = true; 277 std::atomic<bool> isInit_{false}; 278 static constexpr char configFileProduct[] = "/sys_prod/etc/graphic/hgm_policy_config.xml"; 279 std::unique_ptr<XMLParser> mParser_ = nullptr; 280 std::shared_ptr<PolicyConfigData> mPolicyConfigData_ = nullptr; 281 282 int32_t customFrameRateMode_ = HGM_REFRESHRATE_MODE_AUTO; 283 std::vector<ScreenId> screenIds_; 284 std::vector<sptr<HgmScreen>> screenList_; 285 mutable std::mutex listMutex_; 286 287 mutable std::mutex modeListMutex_; 288 std::unique_ptr<std::unordered_map<ScreenId, int32_t>> modeListToApply_ = nullptr; 289 290 std::string currentBundleName_; 291 ScreenId activeScreenId_ = INVALID_SCREEN_ID; 292 std::unordered_set<SceneType> screenSceneSet_; 293 std::shared_ptr<HgmFrameRateManager> hgmFrameRateMgr_ = nullptr; 294 295 // for LTPO 296 uint32_t pendingScreenRefreshRate_ = 0; 297 std::atomic<uint32_t> screenRefreshRateImme_{ 0 }; 298 uint64_t pendingConstraintRelativeTime_ = 0; 299 uint64_t timestamp_ = 0; 300 std::atomic<int64_t> actualTimestamp_{ 0 }; 301 std::atomic<uint64_t> vsyncId_{ 0 }; 302 std::atomic<bool> isForceRefresh_{ false }; 303 bool isDelayMode_ = false; 304 bool ltpoEnabled_ = false; 305 uint32_t maxTE_ = 0; 306 uint32_t alignRate_ = 0; 307 int32_t pipelineOffsetPulseNum_ = 8; 308 bool vBlankIdleCorrectSwitch_ = false; 309 bool lowRateToHighQuickSwitch_ = false; 310 RefreshRateModeChangeCallback refreshRateModeChangeCallback_ = nullptr; 311 RefreshRateUpdateCallback refreshRateUpdateCallback_ = nullptr; 312 bool doDirectComposition_ = false; 313 bool enableDynamicMode_ = true; 314 }; 315 } // namespace OHOS::Rosen 316 #endif // HGM_CORE_H 317