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 #include "core/pipeline/pipeline_base.h"
16 #include "core/components_ng/manager/display_sync/ui_display_sync.h"
17
18 namespace OHOS::Ace {
CheckRate(int32_t vsyncRate,int32_t refreshRateMode)19 void UIDisplaySync::CheckRate(int32_t vsyncRate, int32_t refreshRateMode)
20 {
21 SetVsyncRate(vsyncRate);
22 SetRefreshRateMode(refreshRateMode);
23
24 if (IsCommonDivisor(data_->rateRange_->preferred_, vsyncRate)) {
25 int32_t curRate = vsyncRate / data_->rateRange_->preferred_;
26 if (data_->rate_ != curRate) {
27 data_->rate_ = curRate;
28 rateChanged_ = true;
29 ACE_SCOPED_TRACE("[%s] Id[%" PRIu64 "] RateChangedTo: %d", __func__, GetId(), data_->rate_);
30 }
31 }
32 return;
33 }
34
UpdateData(uint64_t nanoTimestamp,int32_t vsyncPeriod)35 void UIDisplaySync::UpdateData(uint64_t nanoTimestamp, int32_t vsyncPeriod)
36 {
37 SetTimestampData(nanoTimestamp);
38 uint64_t targetTimestamp = nanoTimestamp + static_cast<uint64_t>(vsyncPeriod * data_->rate_);
39 SetTargetTimestampData(targetTimestamp);
40 }
41
JudgeWhetherSkip()42 void UIDisplaySync::JudgeWhetherSkip()
43 {
44 if (rateChanged_) {
45 data_->count_ = 0;
46 rateChanged_ = false;
47 }
48
49 data_->count_++;
50 if (data_->count_ % data_->rate_ == 0) {
51 data_->noSkip_ = true;
52 data_->count_ = 0;
53 } else {
54 data_->noSkip_ = false;
55 }
56 }
57
OnFrame()58 void UIDisplaySync::OnFrame()
59 {
60 ACE_SCOPED_TRACE("DisplaySyncId[%" PRIu64 "] Timestamp[%" PRIu64 "] TargetTimestamp[%" PRIu64 "]"
61 "Preferred[%d] VSyncRate[%d] Rate[%d] noSkip[%d]",
62 GetId(), data_->timestamp_, data_->targetTimestamp_,
63 data_->rateRange_->preferred_, sourceVsyncRate_, data_->rate_, data_->noSkip_);
64 if (data_->noSkip_ && data_->onFrame_) {
65 data_->onFrame_();
66 }
67
68 if (data_->noSkip_ && data_->onFrameWithData_) {
69 data_->onFrameWithData_(data_);
70 }
71
72 if (data_->noSkip_ && data_->onFrameWithTimestamp_) {
73 data_->onFrameWithTimestamp_(data_->timestamp_);
74 }
75
76 JudgeWhetherRequestFrame();
77 }
78
AddToPipeline(WeakPtr<PipelineBase> & pipelineContext)79 void UIDisplaySync::AddToPipeline(WeakPtr<PipelineBase>& pipelineContext)
80 {
81 auto context = pipelineContext.Upgrade();
82 if (!context) {
83 return;
84 }
85
86 RefPtr<UIDisplaySyncManager> dsm = context->GetOrCreateUIDisplaySyncManager();
87 if (!dsm) {
88 return;
89 }
90 dsm->AddDisplaySync(AceType::Claim(this));
91 }
92
DelFromPipeline(WeakPtr<PipelineBase> & pipelineContext)93 void UIDisplaySync::DelFromPipeline(WeakPtr<PipelineBase>& pipelineContext)
94 {
95 auto context = pipelineContext.Upgrade();
96 if (!context) {
97 return;
98 }
99
100 RefPtr<UIDisplaySyncManager> dsm = context->GetOrCreateUIDisplaySyncManager();
101 if (!dsm) {
102 return;
103 }
104 dsm->RemoveDisplaySync(AceType::Claim(this));
105 }
106
IsAddToPipeline(WeakPtr<PipelineBase> & pipelineContext)107 bool UIDisplaySync::IsAddToPipeline(WeakPtr<PipelineBase>& pipelineContext)
108 {
109 auto context = pipelineContext.Upgrade();
110 if (!context) {
111 return false;
112 }
113
114 RefPtr<UIDisplaySyncManager> dsm = context->GetOrCreateUIDisplaySyncManager();
115 if (!dsm) {
116 return false;
117 }
118 return dsm->HasDisplaySync(AceType::Claim(this));
119 }
120
AddToPipelineOnContainer()121 void UIDisplaySync::AddToPipelineOnContainer()
122 {
123 WeakPtr<PipelineBase> pipeline = PipelineBase::GetCurrentContext();
124 AddToPipeline(pipeline);
125 return;
126 }
127
DelFromPipelineOnContainer()128 void UIDisplaySync::DelFromPipelineOnContainer()
129 {
130 WeakPtr<PipelineBase> pipeline = PipelineBase::GetCurrentContext();
131 DelFromPipeline(pipeline);
132 return;
133 }
134
IsOnPipeline()135 bool UIDisplaySync::IsOnPipeline()
136 {
137 WeakPtr<PipelineBase> pipeline = PipelineBase::GetCurrentContext();
138 return IsAddToPipeline(pipeline);
139 }
140
RequestFrame()141 void UIDisplaySync::RequestFrame()
142 {
143 WeakPtr<PipelineBase> pipeline = PipelineBase::GetCurrentContext();
144 auto context = pipeline.Upgrade();
145 if (!context) {
146 return;
147 }
148 context->RequestFrame();
149 }
150
JudgeWhetherRequestFrame()151 void UIDisplaySync::JudgeWhetherRequestFrame()
152 {
153 bool isNeedRequest = data_->onFrame_ || data_->onFrameWithData_ || data_->onFrameWithTimestamp_;
154 if (isNeedRequest) {
155 RequestFrame();
156 }
157 }
158
RegisterOnFrame(OnFrameCallBack && onFrameCallBack)159 void UIDisplaySync::RegisterOnFrame(OnFrameCallBack&& onFrameCallBack)
160 {
161 data_->onFrame_ = std::move(onFrameCallBack);
162 }
163
RegisterOnFrameWithData(OnFrameCallBackWithData && onFrameCallBack)164 void UIDisplaySync::RegisterOnFrameWithData(OnFrameCallBackWithData&& onFrameCallBack)
165 {
166 data_->onFrameWithData_ = std::move(onFrameCallBack);
167 }
168
RegisterOnFrameWithTimestamp(OnFrameCallBackWithTimestamp && onFrameCallBack)169 void UIDisplaySync::RegisterOnFrameWithTimestamp(OnFrameCallBackWithTimestamp&& onFrameCallBack)
170 {
171 data_->onFrameWithTimestamp_ = std::move(onFrameCallBack);
172 }
173
UnRegisterOnFrame()174 void UIDisplaySync::UnRegisterOnFrame()
175 {
176 data_->onFrame_ = nullptr;
177 data_->onFrameWithData_ = nullptr;
178 data_->onFrameWithTimestamp_ = nullptr;
179 }
180
SetTimestampData(uint64_t timestamp)181 void UIDisplaySync::SetTimestampData(uint64_t timestamp)
182 {
183 data_->SetTimestamp(timestamp);
184 }
185
GetTimestampData() const186 uint64_t UIDisplaySync::GetTimestampData() const
187 {
188 return data_->GetTimestamp();
189 }
190
SetTargetTimestampData(uint64_t targetTimestamp)191 void UIDisplaySync::SetTargetTimestampData(uint64_t targetTimestamp)
192 {
193 data_->SetTargetTimestamp(targetTimestamp);
194 }
195
GetTargetTimestampData() const196 uint64_t UIDisplaySync::GetTargetTimestampData() const
197 {
198 return data_->GetTargetTimestamp();
199 }
200
SetRefreshRateMode(int32_t refreshRateMode)201 void UIDisplaySync::SetRefreshRateMode(int32_t refreshRateMode)
202 {
203 refreshRateMode_ = refreshRateMode;
204 }
205
GetRefreshRateMode() const206 int32_t UIDisplaySync::GetRefreshRateMode() const
207 {
208 return refreshRateMode_;
209 }
210
IsAutoRefreshRateMode() const211 bool UIDisplaySync::IsAutoRefreshRateMode() const
212 {
213 return refreshRateMode_ == static_cast<int32_t>(RefreshRateMode::REFRESHRATE_MODE_AUTO);
214 }
215
IsNonAutoRefreshRateMode() const216 bool UIDisplaySync::IsNonAutoRefreshRateMode() const
217 {
218 return refreshRateMode_ != static_cast<int32_t>(RefreshRateMode::REFRESHRATE_MODE_AUTO);
219 }
220
UIDisplaySync()221 UIDisplaySync::UIDisplaySync() {}
222
~UIDisplaySync()223 UIDisplaySync::~UIDisplaySync() noexcept {}
224
SetExpectedFrameRateRange(FrameRateRange && range)225 void UIDisplaySync::SetExpectedFrameRateRange(FrameRateRange&& range)
226 {
227 data_->rateRange_->Set(range.min_, range.max_, range.preferred_);
228 }
229
SetVsyncRate(int32_t vsyncRate)230 bool UIDisplaySync::SetVsyncRate(int32_t vsyncRate)
231 {
232 if (sourceVsyncRate_ == vsyncRate) {
233 return false;
234 }
235 sourceVsyncRate_ = vsyncRate;
236 return true;
237 }
238
GetDisplaySyncData() const239 RefPtr<DisplaySyncData> UIDisplaySync::GetDisplaySyncData() const
240 {
241 return data_;
242 }
243
IsCommonDivisor(int32_t expectedRate,int32_t vsyncRate)244 bool UIDisplaySync::IsCommonDivisor(int32_t expectedRate, int32_t vsyncRate)
245 {
246 if (expectedRate == 0 || vsyncRate == 0) {
247 return false;
248 }
249
250 int32_t n = vsyncRate / expectedRate;
251 if (vsyncRate % n == 0) {
252 return true;
253 }
254 return false;
255 }
256 } // namespace OHOS::Ace
257