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 FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_MANAGER_UI_DISPLAY_SYNC_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_MANAGER_UI_DISPLAY_SYNC_H
18 
19 #include <unordered_map>
20 #include <string>
21 #include <functional>
22 #include <mutex>
23 #include <iostream>
24 #include <atomic>
25 #include <set>
26 
27 #include "base/memory/ace_type.h"
28 #include "base/utils/utils.h"
29 #include "base/log/log.h"
30 #include "base/utils/base_id.h"
31 #include "base/log/ace_trace.h"
32 
33 namespace OHOS::Ace {
34 enum class RefreshRateMode : int32_t {
35     REFRESHRATE_MODE_AUTO = -1,
36 };
37 enum class UIObjectType : int32_t {
38     DISPLAYSYNC_OTHERS = -1,
39     DISPLAYSYNC_ANIMATOR = 0,
40     DISPLAYSYNC_XCOMPONENT = 1,
41 };
42 constexpr int32_t INVALID_ANIMATOR_EXPECTED_RATE = -1;
43 
44 class PipelineBase;
45 
46 class FrameRateRange : public AceType {
DECLARE_ACE_TYPE(FrameRateRange,AceType)47     DECLARE_ACE_TYPE(FrameRateRange, AceType)
48 public:
49     FrameRateRange() : min_(0), max_(0), preferred_(0), componentScene_(0) {}
50 
FrameRateRange(int min,int max,int preferred)51     FrameRateRange(int min, int max, int preferred) : min_(min), max_(max), preferred_(preferred) {}
52 
FrameRateRange(int min,int max,int preferred,int componentScene)53     FrameRateRange(int min, int max, int preferred, int componentScene)
54         : min_(min), max_(max), preferred_(preferred), componentScene_(componentScene) {}
55 
IsZero()56     bool IsZero() const
57     {
58         return this->preferred_ == 0;
59     }
60 
IsValid()61     bool IsValid() const
62     {
63         return !this->IsZero() && this->min_ <= this->preferred_ && this->preferred_ <= this->max_ &&
64             this->min_ >= 0 && this->max_ <= rangeMaxRefreshrate;
65     }
66 
IsDynamic()67     bool IsDynamic() const
68     {
69         return IsValid() && this->min_ != this->max_;
70     }
71 
Reset()72     void Reset()
73     {
74         this->min_ = 0;
75         this->max_ = 0;
76         this->preferred_ = 0;
77         this->componentScene_ = 0;
78     }
79 
Set(int min,int max,int preferred)80     void Set(int min, int max, int preferred)
81     {
82         this->min_ = min;
83         this->max_ = max;
84         this->preferred_ = preferred;
85     }
86 
Merge(const FrameRateRange & other)87     void Merge(const FrameRateRange& other)
88     {
89         if (this->preferred_ < other.preferred_) {
90             this->Set(other.min_, other.max_, other.preferred_);
91         }
92     }
93 
94     bool operator==(const FrameRateRange& other)
95     {
96         return this->min_ == other.min_ && this->max_ == other.max_ &&
97             this->preferred_ == other.preferred_;
98     }
99 
100     bool operator!=(const FrameRateRange& other)
101     {
102         return this->min_ != other.min_ || this->max_ != other.max_ ||
103             this->preferred_ != other.preferred_;
104     }
105 
106     int min_ = 0;
107     int max_ = 0;
108     int preferred_ = 0;
109     int componentScene_ = 0;
110     const int32_t rangeMaxRefreshrate = 144;
111 };
112 
113 class DisplaySyncData;
114 using OnFrameCallBack = std::function<void()>;
115 using OnFrameCallBackWithData = std::function<void(const RefPtr<DisplaySyncData>&)>;
116 using OnFrameCallBackWithTimestamp = std::function<void(uint64_t)>;
117 
118 class DisplaySyncData : public AceType {
DECLARE_ACE_TYPE(DisplaySyncData,AceType)119     DECLARE_ACE_TYPE(DisplaySyncData, AceType)
120 public:
121     void SetTimestamp(int64_t timestamp)
122     {
123         timestamp_ = timestamp;
124     }
125 
GetTimestamp()126     int64_t GetTimestamp() const
127     {
128         return timestamp_;
129     }
130 
SetTargetTimestamp(int64_t targetTimestamp)131     void SetTargetTimestamp(int64_t targetTimestamp)
132     {
133         targetTimestamp_ = targetTimestamp;
134     }
135 
GetTargetTimestamp()136     int64_t GetTargetTimestamp() const
137     {
138         return targetTimestamp_;
139     }
140 
141     OnFrameCallBack onFrame_ = nullptr;
142     OnFrameCallBackWithData onFrameWithData_ = nullptr;
143     OnFrameCallBackWithTimestamp onFrameWithTimestamp_ = nullptr;
144 
145     int64_t timestamp_ = 0;
146     int64_t targetTimestamp_ = 0;
147 
148     int32_t rate_ = 1;
149     bool noSkip_ = true;
150     int32_t count_ = 0;
151     RefPtr<FrameRateRange> rateRange_ = AceType::MakeRefPtr<FrameRateRange>();
152 };
153 
154 class ACE_FORCE_EXPORT UIDisplaySync : public AceType, public BaseId {
155     DECLARE_ACE_TYPE(UIDisplaySync, AceType)
156 public:
157     void AddToPipeline(WeakPtr<PipelineBase>& pipelineContext);
158     void DelFromPipeline(WeakPtr<PipelineBase>& pipelineContext);
159     void AddToPipelineOnContainer();
160     void DelFromPipelineOnContainer();
161     bool IsAddToPipeline(WeakPtr<PipelineBase>& pipelineContext);
162     bool IsOnPipeline();
163     void RequestFrame();
164     void JudgeWhetherRequestFrame();
165 
166     void RegisterOnFrame(OnFrameCallBack&& onFrameCallBack);
167     void RegisterOnFrameWithData(OnFrameCallBackWithData&& onFrameCallBack);
168     void RegisterOnFrameWithTimestamp(OnFrameCallBackWithTimestamp&& onFrameCallBack);
169 
170     void UnregisterOnFrame();
171 
172     void CheckRate(int32_t vsyncRate, int32_t refreshRateMode);
173     void UpdateData(int64_t nanoTimestamp, int32_t vsyncPeriod);
174     void JudgeWhetherSkip();
175     void OnFrame();
176 
177     void SetExpectedFrameRateRange(const FrameRateRange& frameRateRange);
178     bool SetVsyncRate(int32_t vsyncRate);
179     bool IsCommonDivisor(int32_t expectedRate, int32_t vsyncRate);
180 
181     void SetTimestampData(int64_t timestamp);
182     int64_t GetTimestampData() const;
183     void SetTargetTimestampData(int64_t targetTimestamp);
184     int64_t GetTargetTimestampData() const;
185 
186     RefPtr<DisplaySyncData> GetDisplaySyncData() const;
187     int32_t GetAnimatorExpectedRate();
188 
189     void SetRefreshRateMode(int32_t refreshRateMode);
190     int32_t GetRefreshRateMode() const;
191     bool IsAutoRefreshRateMode() const;
192     bool IsNonAutoRefreshRateMode() const;
193 
194     std::vector<int32_t> FindRefreshRateFactors(int32_t refreshRate);
195     int32_t FindMatchedRefreshRate(int32_t vsyncRate, int32_t targetRate);
196     int32_t SearchMatchedRate(int32_t vsyncRate, int32_t iterCount = 1);
197     RefPtr<PipelineBase> GetCurrentContext();
198 
199     UIDisplaySync();
200     UIDisplaySync(UIObjectType uiObjectType);
201     ~UIDisplaySync() noexcept override;
202 
203 private:
204     UIObjectType uiObjectType_ = UIObjectType::DISPLAYSYNC_OTHERS;
205     RefPtr<DisplaySyncData> data_ = AceType::MakeRefPtr<DisplaySyncData>();
206     int32_t sourceVsyncRate_ = 0;
207     bool rateChanged_ = true;
208     int32_t refreshRateMode_ = 0;
209     WeakPtr<PipelineBase> context_;
210     int32_t drawFPS_ = 0;
211     std::unordered_map<int32_t, std::vector<int32_t>> refreshRateToFactorsMap_;
212 };
213 } // namespace OHOS::Ace
214 
215 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_MANAGER_UI_DISPLAY_SYNC_H
216