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