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