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/components_ng/manager/display_sync/ui_display_sync_manager.h"
16
17 namespace OHOS::Ace {
18 const std::vector<int32_t> UIDisplaySyncManager::REFRESH_RATE_LIST = { 90, 120, 144 };
19
DispatchFunc(int64_t nanoTimestamp)20 void UIDisplaySyncManager::DispatchFunc(int64_t nanoTimestamp)
21 {
22 CheckSkipEnableProperty();
23 displaySyncRange_->Reset();
24
25 if (uiDisplaySyncMap_.empty()) {
26 return;
27 }
28
29 IdToDisplaySyncMap backupedMap(uiDisplaySyncMap_);
30
31 int32_t VSyncPeriod = GetVsyncPeriod();
32 for (const auto& [Id, weakDisplaySync] : backupedMap) {
33 auto displaySync = weakDisplaySync.Upgrade();
34 if (displaySync) {
35 displaySync->CheckRate(sourceVsyncRate_, refreshRateMode_);
36 displaySync->UpdateData(nanoTimestamp, VSyncPeriod);
37 if (IsAutoRefreshRateMode() ||
38 (IsNonAutoRefreshRateMode() && IsSupportSkip())) {
39 displaySync->JudgeWhetherSkip();
40 }
41 displaySync->OnFrame();
42
43 auto rateRange = displaySync->GetDisplaySyncData()->rateRange_;
44 if (rateRange->IsValid()) {
45 displaySyncRange_->Merge(*rateRange);
46 }
47 TAG_LOGD(AceLogTag::ACE_DISPLAY_SYNC, "UIDisplaySyncMapSize:%{public}d Id:%{public}d"
48 "FrameRateRange: {%{public}d, %{public}d, %{public}d}",
49 static_cast<int32_t>(uiDisplaySyncMap_.size()), static_cast<int32_t>(displaySync->GetId()),
50 rateRange->min_, rateRange->max_, rateRange->preferred_);
51 } else {
52 uiDisplaySyncMap_.erase(Id);
53 }
54 }
55
56 return;
57 }
58
HasDisplaySync(const RefPtr<UIDisplaySync> & displaySync)59 bool UIDisplaySyncManager::HasDisplaySync(const RefPtr<UIDisplaySync>& displaySync)
60 {
61 if (displaySync && uiDisplaySyncMap_.count(displaySync->GetId())) {
62 return true;
63 }
64 return false;
65 }
66
AddDisplaySync(const RefPtr<UIDisplaySync> & displaySync)67 bool UIDisplaySyncManager::AddDisplaySync(const RefPtr<UIDisplaySync>& displaySync)
68 {
69 if (HasDisplaySync(displaySync)) {
70 TAG_LOGD(AceLogTag::ACE_DISPLAY_SYNC, "DisplaySyncId[%{public}d] is existed.",
71 static_cast<int32_t>(displaySync->GetId()));
72 return false;
73 }
74 ACE_SCOPED_TRACE("AddDisplaySync Id:%d", static_cast<int32_t>(displaySync->GetId()));
75 uiDisplaySyncMap_[displaySync->GetId()] = displaySync;
76 TAG_LOGD(AceLogTag::ACE_DISPLAY_SYNC, "AddDisplaySync MapSize: %{public}d expected: %{public}d.",
77 static_cast<int32_t>(uiDisplaySyncMap_.size()), displaySync->GetDisplaySyncData()->rateRange_->preferred_);
78 displaySync->JudgeWhetherRequestFrame();
79 return true;
80 }
81
RemoveDisplaySync(const RefPtr<UIDisplaySync> & displaySync)82 bool UIDisplaySyncManager::RemoveDisplaySync(const RefPtr<UIDisplaySync>& displaySync)
83 {
84 if (HasDisplaySync(displaySync)) {
85 ACE_SCOPED_TRACE("RemoveDisplaySync Id:%d", static_cast<int32_t>(displaySync->GetId()));
86 uiDisplaySyncMap_.erase(displaySync->GetId());
87 TAG_LOGD(AceLogTag::ACE_DISPLAY_SYNC, "RemoveDisplaySync MapSize: %{public}d expected: %{public}d.",
88 static_cast<int32_t>(uiDisplaySyncMap_.size()),
89 displaySync->GetDisplaySyncData()->rateRange_->preferred_);
90 return true;
91 }
92 return false;
93 }
94
SetVsyncRate(int32_t vsyncRate)95 bool UIDisplaySyncManager::SetVsyncRate(int32_t vsyncRate)
96 {
97 if (vsyncRate < 0) {
98 return false;
99 }
100
101 if (sourceVsyncRate_ == vsyncRate) {
102 return false;
103 }
104 sourceVsyncRate_ = vsyncRate;
105 return true;
106 }
107
GetVsyncRate() const108 int32_t UIDisplaySyncManager::GetVsyncRate() const
109 {
110 return sourceVsyncRate_;
111 }
112
SetVsyncPeriod(int64_t vsyncPeriod)113 bool UIDisplaySyncManager::SetVsyncPeriod(int64_t vsyncPeriod)
114 {
115 if (vsyncPeriod < 0) {
116 return false;
117 }
118
119 if (vsyncPeriod_ == vsyncPeriod) {
120 return false;
121 }
122 vsyncPeriod_ = vsyncPeriod;
123
124 int32_t rate = static_cast<int32_t>(std::ceil(SECOND_IN_NANO / vsyncPeriod_));
125 std::call_once(computeFactorsFlag_, [this]() { FindAllRefreshRateFactors(); });
126 int32_t refreshRate = FindMatchedRefreshRate(rate);
127 SetVsyncRate(refreshRate);
128
129 return true;
130 }
131
GetVsyncPeriod() const132 int64_t UIDisplaySyncManager::GetVsyncPeriod() const
133 {
134 return vsyncPeriod_;
135 }
136
SetRefreshRateMode(int32_t refreshRateMode)137 bool UIDisplaySyncManager::SetRefreshRateMode(int32_t refreshRateMode)
138 {
139 if (refreshRateMode < -1) {
140 return false;
141 }
142
143 if (refreshRateMode_ == refreshRateMode) {
144 return false;
145 }
146
147 refreshRateMode_ = refreshRateMode;
148 return true;
149 }
150
GetRefreshRateMode() const151 int32_t UIDisplaySyncManager::GetRefreshRateMode() const
152 {
153 return refreshRateMode_;
154 }
155
GetDisplaySyncRate() const156 int32_t UIDisplaySyncManager::GetDisplaySyncRate() const
157 {
158 int32_t displaySyncRate = displaySyncRange_->preferred_;
159 return displaySyncRate;
160 }
161
GetUIDisplaySyncMap() const162 IdToDisplaySyncMap UIDisplaySyncManager::GetUIDisplaySyncMap() const
163 {
164 return uiDisplaySyncMap_;
165 }
166
CheckSkipEnableProperty()167 void UIDisplaySyncManager::CheckSkipEnableProperty()
168 {
169 std::call_once(isEnablePropertyFlag_, [this] () {
170 supportSkipEnabled_ = SystemProperties::GetDisplaySyncSkipEnabled();
171 });
172 }
173
IsSupportSkip() const174 bool UIDisplaySyncManager::IsSupportSkip() const
175 {
176 return supportSkipEnabled_;
177 }
178
IsAutoRefreshRateMode() const179 bool UIDisplaySyncManager::IsAutoRefreshRateMode() const
180 {
181 return refreshRateMode_ == static_cast<int32_t>(RefreshRateMode::REFRESHRATE_MODE_AUTO);
182 }
183
IsNonAutoRefreshRateMode() const184 bool UIDisplaySyncManager::IsNonAutoRefreshRateMode() const
185 {
186 return refreshRateMode_ != static_cast<int32_t>(RefreshRateMode::REFRESHRATE_MODE_AUTO);
187 }
188
FindRefreshRateFactors(int32_t refreshRate)189 std::set<int32_t> UIDisplaySyncManager::FindRefreshRateFactors(int32_t refreshRate)
190 {
191 std::set<int32_t> refreshRateFactors;
192 for (int32_t i = 1; i * i <= refreshRate; ++i) {
193 if (refreshRate % i == 0) {
194 refreshRateFactors.insert(i);
195 if (i != refreshRate / i) {
196 refreshRateFactors.insert(refreshRate / i);
197 }
198 }
199 }
200 return refreshRateFactors;
201 }
202
FindMatchedRefreshRate(int32_t target)203 int32_t UIDisplaySyncManager::FindMatchedRefreshRate(int32_t target)
204 {
205 auto it = std::lower_bound(refreshRateFactors_.begin(), refreshRateFactors_.end(), target);
206 if (it == refreshRateFactors_.begin()) {
207 return *it;
208 } else if (it == refreshRateFactors_.end()) {
209 return *(it - 1);
210 }
211 return std::abs(*it - target) < std::abs(*(it - 1) - target) ? *it : *(it - 1);
212 }
213
FindAllRefreshRateFactors()214 void UIDisplaySyncManager::FindAllRefreshRateFactors()
215 {
216 std::set<int32_t> allFactors;
217 for (const auto& refreshRate : REFRESH_RATE_LIST) {
218 std::set<int32_t> factors = FindRefreshRateFactors(refreshRate);
219 allFactors.insert(factors.begin(), factors.end());
220 }
221 refreshRateFactors_.clear();
222 std::copy(allFactors.begin(), allFactors.end(), std::back_inserter(refreshRateFactors_));
223 return;
224 }
225
GetAnimatorRate()226 int32_t UIDisplaySyncManager::GetAnimatorRate()
227 {
228 std::priority_queue<int32_t> emptyQue;
229 std::swap(maxAnimatorRateHap_, emptyQue);
230
231 if (uiDisplaySyncMap_.empty()) {
232 return INVALID_ANIMATOR_EXPECTED_RATE;
233 }
234
235 IdToDisplaySyncMap backupedMap(uiDisplaySyncMap_);
236 for (const auto& [Id, weakDisplaySync] : backupedMap) {
237 auto displaySync = weakDisplaySync.Upgrade();
238 if (displaySync) {
239 maxAnimatorRateHap_.push(displaySync->GetAnimatorExpectedRate());
240 } else {
241 uiDisplaySyncMap_.erase(Id);
242 }
243 }
244
245 if (maxAnimatorRateHap_.empty()) {
246 return INVALID_ANIMATOR_EXPECTED_RATE;
247 }
248 int32_t currMaxAnimatorExpectedRate = maxAnimatorRateHap_.top();
249 return currMaxAnimatorExpectedRate;
250 }
251
IsAnimatorStopped()252 bool UIDisplaySyncManager::IsAnimatorStopped()
253 {
254 if (GetAnimatorRate() == INVALID_ANIMATOR_EXPECTED_RATE) {
255 return true;
256 }
257 return false;
258 }
259
UIDisplaySyncManager()260 UIDisplaySyncManager::UIDisplaySyncManager() {}
261
~UIDisplaySyncManager()262 UIDisplaySyncManager::~UIDisplaySyncManager() noexcept
263 {
264 uiDisplaySyncMap_.clear();
265 }
266 } // namespace OHOS::Ace
267