• 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_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