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