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