1 /*
2 * Copyright (c) 2024 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
16 #include "ui/rs_ui_display_soloist.h"
17 #include "platform/common/rs_log.h"
18 #include "rs_trace.h"
19
20 namespace OHOS {
21 namespace Rosen {
22
23 // class RSC_EXPORT SoloistId
24
Create()25 std::shared_ptr<SoloistId> SoloistId::Create()
26 {
27 std::shared_ptr<SoloistId> soloistId = std::make_shared<SoloistId>();
28 return soloistId;
29 }
30
GenerateId()31 SoloistIdType SoloistId::GenerateId()
32 {
33 static std::atomic<SoloistIdType> currentId_ = 0;
34 auto currentId = currentId_.fetch_add(1, std::memory_order_relaxed);
35 return currentId;
36 }
37
GetId() const38 SoloistIdType SoloistId::GetId() const
39 {
40 return id_;
41 }
42
SoloistId()43 SoloistId::SoloistId() : id_(GenerateId()) {}
44
~SoloistId()45 SoloistId::~SoloistId() {}
46
47 // class RSC_EXPORT RSDisplaySoloist
48
RSDisplaySoloist(SoloistIdType instanceId)49 RSDisplaySoloist::RSDisplaySoloist(SoloistIdType instanceId)
50 : instanceId_(instanceId)
51 {
52 vsyncTimeoutTaskName_ = TIME_OUT_TASK + std::to_string(instanceId_);
53 }
54
OnVsync(TimestampType timestamp,void * client)55 void RSDisplaySoloist::OnVsync(TimestampType timestamp, void* client)
56 {
57 auto soloist = static_cast<RSDisplaySoloist*>(client);
58 if (soloist && soloist->useExclusiveThread_) {
59 soloist->VsyncCallbackInner(timestamp);
60 }
61 }
62
VsyncCallbackInner(TimestampType timestamp)63 void RSDisplaySoloist::VsyncCallbackInner(TimestampType timestamp)
64 {
65 {
66 std::lock_guard<std::mutex> lock(mtx_);
67 hasRequestedVsync_ = false;
68 subVsyncHandler_->RemoveTask(vsyncTimeoutTaskName_);
69 }
70 if (subStatus_ != ActiveStatus::ACTIVE) {
71 SetSubFrameRateLinkerEnable(false);
72 return;
73 }
74
75 if (JudgeWhetherSkip(timestamp)) {
76 if (callback_.first) {
77 RS_TRACE_NAME_FMT("SubDisplaySoloistId: %d, RefreshRate: %d, FrameRateRange: {%d, %d, %d}, "
78 "drawFPS: %d, rate: %d, count: %d", instanceId_, GetVSyncRate(),
79 frameRateRange_.min_, frameRateRange_.max_, frameRateRange_.preferred_, drawFPS_,
80 currRate_, currCnt_);
81 ROSEN_LOGD("SubDisplaySoloistId: %{public}d, RefreshRate: %{public}d, "
82 "FrameRateRange: {%{public}d, %{public}d, %{public}d}, "
83 "drawFPS: %{public}d, rate: %{public}d, count: %{public}d", instanceId_, GetVSyncRate(),
84 frameRateRange_.min_, frameRateRange_.max_, frameRateRange_.preferred_, drawFPS_,
85 currRate_, currCnt_);
86 callback_.first(timestamp_, targetTimestamp_, callback_.second);
87 }
88 }
89
90 if (callback_.first) {
91 RequestNextVSync();
92 }
93 FlushFrameRate(frameRateRange_.preferred_);
94 }
95
Init()96 void RSDisplaySoloist::Init()
97 {
98 if (useExclusiveThread_ && (!subReceiver_ || !hasInitVsyncReceiver_)) {
99 if (!subVsyncHandler_) {
100 subVsyncHandler_ = std::make_shared<AppExecFwk::EventHandler>(
101 AppExecFwk::EventRunner::Create("OS_" + std::to_string(instanceId_) + "_SubDisplaySoloist"));
102 }
103 auto& rsClient = OHOS::Rosen::RSInterfaces::GetInstance();
104 frameRateLinker_ = OHOS::Rosen::RSFrameRateLinker::Create();
105 while (!subReceiver_) {
106 subReceiver_ = rsClient.CreateVSyncReceiver(std::to_string(instanceId_)+"_SubDisplaySoloist",
107 frameRateLinker_->GetId(), subVsyncHandler_);
108 }
109 subReceiver_->Init();
110 subStatus_ = ActiveStatus::ACTIVE;
111 hasInitVsyncReceiver_ = true;
112 }
113 }
114
RequestNextVSync()115 void RSDisplaySoloist::RequestNextVSync()
116 {
117 {
118 std::lock_guard<std::mutex> lock(mtx_);
119 if (destroyed_) {
120 return;
121 }
122 Init();
123 if (hasRequestedVsync_) {
124 return;
125 }
126 if (subVsyncHandler_) {
127 subVsyncHandler_->RemoveTask(vsyncTimeoutTaskName_);
128 ROSEN_LOGD("%{public}s SubDisplaySoloistId: %{public}d PostTimeoutTask", __func__, instanceId_);
129 subVsyncHandler_->PostTask(vsyncTimeoutCallback_, vsyncTimeoutTaskName_, TIME_OUT_MILLISECONDS);
130 }
131 }
132
133 if (subReceiver_ && useExclusiveThread_) {
134 subReceiver_->RequestNextVSync(subFrameCallback_);
135 hasRequestedVsync_ = true;
136 }
137 }
138
OnVsyncTimeOut()139 void RSDisplaySoloist::OnVsyncTimeOut()
140 {
141 ROSEN_LOGD("%{public}s SubDisplaySoloistId: %{public}d Vsync time out", __func__, instanceId_);
142 std::lock_guard<std::mutex> lock(mtx_);
143 hasRequestedVsync_ = false;
144 }
145
FlushFrameRate(int32_t rate)146 void RSDisplaySoloist::FlushFrameRate(int32_t rate)
147 {
148 if (frameRateLinker_ && frameRateLinker_->IsEnable()) {
149 FrameRateRange range = {0, RANGE_MAX_REFRESHRATE, rate, DISPLAY_SOLOIST_FRAME_RATE_TYPE};
150 frameRateLinker_->UpdateFrameRateRangeImme(range);
151 }
152 }
153
SetSubFrameRateLinkerEnable(bool enabled)154 void RSDisplaySoloist::SetSubFrameRateLinkerEnable(bool enabled)
155 {
156 if (frameRateLinker_) {
157 if (!enabled) {
158 FrameRateRange range = {0, RANGE_MAX_REFRESHRATE, FRAME_RATE_0};
159 frameRateLinker_->UpdateFrameRateRangeImme(range);
160 }
161 frameRateLinker_->SetEnable(enabled);
162 }
163 }
164
JudgeWhetherSkip(TimestampType timestamp)165 bool RSDisplaySoloist::JudgeWhetherSkip(TimestampType timestamp)
166 {
167 int32_t vsyncRate = GetVSyncRate();
168 drawFPS_ = FindMatchedRefreshRate(vsyncRate, frameRateRange_.preferred_);
169 if (drawFPS_ < frameRateRange_.min_ || drawFPS_ > frameRateRange_.max_) {
170 drawFPS_ = SearchMatchedRate(frameRateRange_, vsyncRate);
171 }
172
173 if (drawFPS_ == 0) {
174 return false;
175 }
176
177 int32_t currRate = vsyncRate / drawFPS_;
178 int64_t currVsyncPeriod = GetVSyncPeriod();
179 timestamp_ = timestamp;
180 targetTimestamp_ = timestamp + currRate * currVsyncPeriod;
181
182 if (currRate != currRate_) {
183 currCnt_ = 0;
184 }
185 currRate_ = currRate;
186
187 bool isSkip = false;
188 if (currCnt_ == 0) {
189 isSkip = true;
190 }
191
192 if ((currRate_ > 0) && (currRate_ - currCnt_) == 1) {
193 currCnt_ = -1;
194 }
195 currCnt_++;
196
197 return isSkip;
198 }
199
IsCommonDivisor(int32_t expectedRate,int32_t vsyncRate)200 bool RSDisplaySoloist::IsCommonDivisor(int32_t expectedRate, int32_t vsyncRate)
201 {
202 if (expectedRate == 0 || vsyncRate == 0) {
203 return false;
204 }
205
206 int32_t n = vsyncRate / expectedRate;
207 if (expectedRate * n == vsyncRate) {
208 return true;
209 }
210 return false;
211 }
212
FindRefreshRateFactors(int32_t refreshRate)213 std::vector<int32_t> RSDisplaySoloist::FindRefreshRateFactors(int32_t refreshRate)
214 {
215 std::vector<int32_t> refreshRateFactors;
216 for (int32_t i = 1; i * i <= refreshRate; ++i) {
217 if (refreshRate % i == 0) {
218 refreshRateFactors.emplace_back(i);
219 if (i != refreshRate / i) {
220 refreshRateFactors.emplace_back(refreshRate / i);
221 }
222 }
223 }
224 sort(refreshRateFactors.begin(), refreshRateFactors.end());
225 return refreshRateFactors;
226 }
227
FindAllRefreshRateFactors()228 void RSDisplaySoloist::FindAllRefreshRateFactors()
229 {
230 std::set<int32_t> allFactors;
231 for (const auto& refreshRate : REFRESH_RATE_LIST) {
232 std::vector<int32_t> factors = FindRefreshRateFactors(refreshRate);
233 allFactors.insert(factors.begin(), factors.end());
234 }
235 REFRESH_RATE_FACTORS.clear();
236 std::copy(allFactors.begin(), allFactors.end(), std::back_inserter(REFRESH_RATE_FACTORS));
237 return;
238 }
239
FindAccurateRefreshRate(int32_t approximateRate)240 int32_t RSDisplaySoloist::FindAccurateRefreshRate(int32_t approximateRate)
241 {
242 if (REFRESH_RATE_FACTORS.empty()) {
243 ROSEN_LOGE("%{public}s REFRESH_RATE_FACTORS is Empty.", __func__);
244 return 0;
245 }
246 auto it = std::lower_bound(REFRESH_RATE_FACTORS.begin(), REFRESH_RATE_FACTORS.end(), approximateRate);
247 if (it == REFRESH_RATE_FACTORS.begin()) {
248 return *it;
249 } else if (it == REFRESH_RATE_FACTORS.end()) {
250 // Indicate the end element of vector.
251 return *(it - 1);
252 }
253 return std::abs(*it - approximateRate) < std::abs(*(it - 1) - approximateRate) ? *it : *(it - 1);
254 }
255
FindMatchedRefreshRate(int32_t vsyncRate,int32_t targetRate)256 int32_t RSDisplaySoloist::FindMatchedRefreshRate(int32_t vsyncRate, int32_t targetRate)
257 {
258 if (targetRate == 0 || targetRate > vsyncRate) {
259 return vsyncRate;
260 }
261
262 if (IsCommonDivisor(targetRate, vsyncRate)) {
263 return targetRate;
264 }
265
266 if (!RATE_TO_FACTORS.count(vsyncRate)) {
267 RATE_TO_FACTORS[vsyncRate] = FindRefreshRateFactors(vsyncRate);
268 }
269
270 std::vector<int32_t> refreshRateFactors = RATE_TO_FACTORS[vsyncRate];
271 if (refreshRateFactors.empty()) {
272 return 0;
273 }
274 auto it = std::lower_bound(refreshRateFactors.begin(), refreshRateFactors.end(), targetRate);
275 if (it == refreshRateFactors.begin()) {
276 return *it;
277 } else if (it == refreshRateFactors.end()) {
278 // Indicate the end element of vector.
279 return *(it - 1);
280 }
281 return std::abs(*it - targetRate) < std::abs(*(it - 1) - targetRate) ? *it : *(it - 1);
282 }
283
SearchMatchedRate(const FrameRateRange & frameRateRange,int32_t vsyncRate,int32_t iterCount)284 int32_t RSDisplaySoloist::SearchMatchedRate(const FrameRateRange& frameRateRange,
285 int32_t vsyncRate, int32_t iterCount)
286 {
287 if (vsyncRate != 0 && iterCount >= vsyncRate) {
288 return FindMatchedRefreshRate(vsyncRate, frameRateRange.preferred_);
289 }
290
291 if (iterCount == 0 || vsyncRate == 0) {
292 return vsyncRate;
293 }
294
295 int32_t expectedRate = vsyncRate / iterCount;
296 if (frameRateRange.min_ <= expectedRate &&
297 frameRateRange.max_ >= expectedRate) {
298 return FindMatchedRefreshRate(vsyncRate, expectedRate);
299 }
300
301 return SearchMatchedRate(frameRateRange, vsyncRate, ++iterCount);
302 }
303
GetVSyncPeriod()304 int64_t RSDisplaySoloist::GetVSyncPeriod()
305 {
306 {
307 std::lock_guard<std::mutex> lock(mtx_);
308 Init();
309 }
310 int64_t period = 0;
311 if (subReceiver_) {
312 #ifdef __OHOS__
313 subReceiver_->GetVSyncPeriod(period);
314 #endif
315 }
316
317 if (period == 0 && !useExclusiveThread_) {
318 RSDisplaySoloistManager& soloistManager = RSDisplaySoloistManager::GetInstance();
319 period = soloistManager.GetVSyncPeriod();
320 }
321
322 return period;
323 }
324
GetVSyncRate()325 int32_t RSDisplaySoloist::GetVSyncRate()
326 {
327 int64_t vsyncPeriod = GetVSyncPeriod();
328 if (vsyncPeriod == 0 && !useExclusiveThread_) {
329 RSDisplaySoloistManager& soloistManager = RSDisplaySoloistManager::GetInstance();
330 vsyncPeriod = soloistManager.GetVSyncPeriod();
331 }
332 int32_t approximateRate = static_cast<int32_t>(std::ceil(SECOND_IN_NANO / vsyncPeriod));
333 std::call_once(COMPUTE_FACTORS_FLAG, [this] () { FindAllRefreshRateFactors(); });
334 int32_t rate = FindAccurateRefreshRate(approximateRate);
335 SetVSyncRate(rate);
336 if (!useExclusiveThread_) {
337 RSDisplaySoloistManager& soloistManager = RSDisplaySoloistManager::GetInstance();
338 soloistManager.SetVSyncRate(rate);
339 }
340 return rate;
341 }
342
SetVSyncRate(int32_t vsyncRate)343 bool RSDisplaySoloist::SetVSyncRate(int32_t vsyncRate)
344 {
345 if (vsyncRate < 0) {
346 return false;
347 }
348
349 if (sourceVsyncRate_ == vsyncRate) {
350 return false;
351 }
352 sourceVsyncRate_ = vsyncRate;
353 return true;
354 }
355
356 // RSDisplaySoloistManager
357
GetInstance()358 RSDisplaySoloistManager& RSDisplaySoloistManager::GetInstance() noexcept
359 {
360 static RSDisplaySoloistManager soloistManager;
361 soloistManager.InitVsyncReceiver();
362 return soloistManager;
363 }
364
~RSDisplaySoloistManager()365 RSDisplaySoloistManager::~RSDisplaySoloistManager() noexcept {}
366
InitVsyncReceiver()367 bool RSDisplaySoloistManager::InitVsyncReceiver()
368 {
369 if (hasInitVsyncReceiver_) {
370 return false;
371 }
372
373 if (!vsyncHandler_) {
374 vsyncHandler_ = std::make_shared<AppExecFwk::EventHandler>(
375 AppExecFwk::EventRunner::Create("OS_MainDisplaySoloist"));
376 }
377 auto& rsClient = OHOS::Rosen::RSInterfaces::GetInstance();
378 frameRateLinker_ = OHOS::Rosen::RSFrameRateLinker::Create();
379 while (!receiver_) {
380 receiver_ = rsClient.CreateVSyncReceiver("MainDisplaySoloist",
381 frameRateLinker_->GetId(), vsyncHandler_);
382 }
383
384 receiver_->Init();
385 hasInitVsyncReceiver_ = true;
386 managerStatus_ = ActiveStatus::ACTIVE;
387
388 return true;
389 }
390
RequestNextVSync()391 void RSDisplaySoloistManager::RequestNextVSync()
392 {
393 if (receiver_ == nullptr) {
394 ROSEN_LOGE("%{public}s, VSyncReceiver is null.", __func__);
395 return;
396 }
397
398 {
399 std::lock_guard<std::mutex> lock(mtx_);
400 if (managerStatus_ != ActiveStatus::ACTIVE) {
401 return;
402 }
403 InitVsyncReceiver();
404 if (vsyncHandler_) {
405 vsyncHandler_->RemoveTask(vsyncTimeoutTaskName_);
406 ROSEN_LOGD("%{public}s MainDisplaySoloistManager PostTimeoutTask", __func__);
407 vsyncHandler_->PostTask(vsyncTimeoutCallback_, vsyncTimeoutTaskName_, TIME_OUT_MILLISECONDS);
408 }
409 }
410
411 receiver_->RequestNextVSync(managerFrameCallback_);
412 }
413
OnVsync(TimestampType timestamp,void * client)414 void RSDisplaySoloistManager::OnVsync(TimestampType timestamp, void* client)
415 {
416 auto soloistManager = static_cast<RSDisplaySoloistManager*>(client);
417 if (soloistManager == nullptr) {
418 ROSEN_LOGE("%{public}s, soloistManager is null.", __func__);
419 return;
420 }
421 soloistManager->VsyncCallbackInner(timestamp);
422 }
423
VsyncCallbackInner(TimestampType timestamp)424 void RSDisplaySoloistManager::VsyncCallbackInner(TimestampType timestamp)
425 {
426 if (managerStatus_ != ActiveStatus::ACTIVE) {
427 SetMainFrameRateLinkerEnable(false);
428 return;
429 }
430
431 std::unique_lock<std::mutex> lock(dataUpdateMtx_);
432 for (auto it = idToSoloistMap_.begin(); it != idToSoloistMap_.end();) {
433 if (it->second && it->second->subStatus_ == ActiveStatus::NEED_REMOVE) {
434 it = idToSoloistMap_.erase(it);
435 } else {
436 ++it;
437 }
438 }
439 lock.unlock();
440
441 DispatchSoloistCallback(timestamp);
442 }
443
DispatchSoloistCallback(TimestampType timestamp)444 void RSDisplaySoloistManager::DispatchSoloistCallback(TimestampType timestamp)
445 {
446 bool isNeedRequestVSync = false;
447 frameRateRange_.Reset();
448
449 std::unique_lock<std::mutex> lock(dataUpdateMtx_);
450 IdToSoloistMapType idToSoloistMapBackup(idToSoloistMap_);
451 lock.unlock();
452
453 for (const auto& [id, displaySoloist] : idToSoloistMapBackup) {
454 if (displaySoloist && displaySoloist->useExclusiveThread_) {
455 displaySoloist->RequestNextVSync();
456 continue;
457 }
458
459 if (displaySoloist && displaySoloist->JudgeWhetherSkip(timestamp) &&
460 displaySoloist->subStatus_ == ActiveStatus::ACTIVE) {
461 if (displaySoloist->callback_.first) {
462 RS_TRACE_NAME_FMT("DisplaySoloistId: %d, RefreshRate: %d, FrameRateRange: {%d, %d, %d}, "
463 "drawFPS: %d, rate: %d, count: %d",
464 displaySoloist->instanceId_, displaySoloist->GetVSyncRate(), displaySoloist->frameRateRange_.min_,
465 displaySoloist->frameRateRange_.max_, displaySoloist->frameRateRange_.preferred_,
466 displaySoloist->drawFPS_, displaySoloist->currRate_, displaySoloist->currCnt_);
467 ROSEN_LOGD("DisplaySoloistId: %{public}d, RefreshRate: %{public}d, "
468 "FrameRateRange: {%{public}d, %{public}d, %{public}d}, "
469 "drawFPS: %{public}d, rate: %{public}d, count: %{public}d",
470 displaySoloist->instanceId_, displaySoloist->GetVSyncRate(), displaySoloist->frameRateRange_.min_,
471 displaySoloist->frameRateRange_.max_, displaySoloist->frameRateRange_.preferred_,
472 displaySoloist->drawFPS_, displaySoloist->currRate_, displaySoloist->currCnt_);
473 displaySoloist->callback_.first(displaySoloist->timestamp_, displaySoloist->targetTimestamp_,
474 displaySoloist->callback_.second);
475 }
476 if (displaySoloist->frameRateRange_.IsValid()) {
477 frameRateRange_.Merge(displaySoloist->frameRateRange_);
478 }
479 }
480 bool isActiveSoloist = false;
481 if (displaySoloist && displaySoloist->subStatus_ == ActiveStatus::ACTIVE) {
482 isActiveSoloist = true;
483 }
484 isNeedRequestVSync = isNeedRequestVSync || isActiveSoloist;
485 }
486
487 if (isNeedRequestVSync && managerStatus_ == ActiveStatus::ACTIVE) {
488 RequestNextVSync();
489 FlushFrameRate(frameRateRange_.preferred_);
490 } else {
491 FlushFrameRate(FRAME_RATE_0);
492 }
493 }
494
Start(SoloistIdType id)495 void RSDisplaySoloistManager::Start(SoloistIdType id)
496 {
497 std::unique_lock<std::mutex> lock(dataUpdateMtx_);
498 if (!idToSoloistMap_.count(id)) {
499 idToSoloistMap_[id] = std::make_shared<RSDisplaySoloist>(id);
500 }
501 managerStatus_ = ActiveStatus::ACTIVE;
502 idToSoloistMap_[id]->subStatus_ = ActiveStatus::ACTIVE;
503 idToSoloistMap_[id]->SetSubFrameRateLinkerEnable(true);
504 idToSoloistMap_[id]->RequestNextVSync();
505 lock.unlock();
506 RequestNextVSync();
507 ROSEN_LOGD("%{public}s, SoloistId:%{public}d.", __func__, id);
508 return;
509 }
510
Stop(SoloistIdType id)511 void RSDisplaySoloistManager::Stop(SoloistIdType id)
512 {
513 std::unique_lock<std::mutex> lock(dataUpdateMtx_);
514 if (!idToSoloistMap_.count(id)) {
515 return;
516 }
517 idToSoloistMap_[id]->subStatus_ = ActiveStatus::INACTIVE;
518 idToSoloistMap_[id]->SetSubFrameRateLinkerEnable(false);
519 idToSoloistMap_[id]->RequestNextVSync();
520 lock.unlock();
521 RequestNextVSync();
522 ROSEN_LOGD("%{public}s, SoloistId:%{public}d.", __func__, id);
523 return;
524 }
525
RemoveSoloist(SoloistIdType id)526 void RSDisplaySoloistManager::RemoveSoloist(SoloistIdType id)
527 {
528 std::unique_lock<std::mutex> lock(dataUpdateMtx_);
529 if (idToSoloistMap_.count(id)) {
530 idToSoloistMap_[id]->subStatus_ = ActiveStatus::NEED_REMOVE;
531 idToSoloistMap_[id]->SetSubFrameRateLinkerEnable(false);
532 idToSoloistMap_[id]->RequestNextVSync();
533 RequestNextVSync();
534 }
535 lock.unlock();
536 ROSEN_LOGD("%{public}s, SoloistId:%{public}d.", __func__, id);
537 return;
538 }
539
InsertOnVsyncCallback(SoloistIdType id,DisplaySoloistOnFrameCallback cb,void * data)540 void RSDisplaySoloistManager::InsertOnVsyncCallback(SoloistIdType id, DisplaySoloistOnFrameCallback cb, void* data)
541 {
542 std::unique_lock<std::mutex> lock(dataUpdateMtx_);
543 if (!idToSoloistMap_.count(id)) {
544 idToSoloistMap_[id] = std::make_shared<RSDisplaySoloist>(id);
545 }
546 idToSoloistMap_[id]->callback_ = { cb, data };
547 lock.unlock();
548 ROSEN_LOGD("%{public}s, SoloistId:%{public}d.", __func__, id);
549 return;
550 }
551
InsertFrameRateRange(SoloistIdType id,FrameRateRange frameRateRange)552 void RSDisplaySoloistManager::InsertFrameRateRange(SoloistIdType id, FrameRateRange frameRateRange)
553 {
554 std::unique_lock<std::mutex> lock(dataUpdateMtx_);
555 if (!idToSoloistMap_.count(id)) {
556 idToSoloistMap_[id] = std::make_shared<RSDisplaySoloist>(id);
557 }
558 idToSoloistMap_[id]->frameRateRange_ = frameRateRange;
559 lock.unlock();
560 ROSEN_LOGD("%{public}s, SoloistId:%{public}d expected:%{public}d.", __func__, id, frameRateRange_.preferred_);
561 return;
562 }
563
InsertUseExclusiveThreadFlag(SoloistIdType id,bool useExclusiveThread)564 void RSDisplaySoloistManager::InsertUseExclusiveThreadFlag(SoloistIdType id, bool useExclusiveThread)
565 {
566 if (!idToSoloistMap_.count(id)) {
567 idToSoloistMap_[id] = std::make_shared<RSDisplaySoloist>(id);
568 }
569 idToSoloistMap_[id]->useExclusiveThread_ = useExclusiveThread;
570 ROSEN_LOGD("%{public}s, SoloistId:%{public}d useExclusiveThread:%{public}d.", __func__, id, useExclusiveThread);
571 return;
572 }
573
FlushFrameRate(int32_t rate)574 void RSDisplaySoloistManager::FlushFrameRate(int32_t rate)
575 {
576 if (frameRateLinker_ && frameRateLinker_->IsEnable()) {
577 FrameRateRange range = {0, RANGE_MAX_REFRESHRATE, rate, DISPLAY_SOLOIST_FRAME_RATE_TYPE};
578 frameRateLinker_->UpdateFrameRateRangeImme(range);
579 }
580 }
581
SetMainFrameRateLinkerEnable(bool enabled)582 void RSDisplaySoloistManager::SetMainFrameRateLinkerEnable(bool enabled)
583 {
584 if (frameRateLinker_) {
585 if (!enabled) {
586 FrameRateRange range = {0, RANGE_MAX_REFRESHRATE, FRAME_RATE_0};
587 frameRateLinker_->UpdateFrameRateRangeImme(range);
588 managerStatus_ = ActiveStatus::INACTIVE;
589 } else {
590 managerStatus_ = ActiveStatus::ACTIVE;
591 }
592 frameRateLinker_->SetEnable(enabled);
593 }
594
595 for (const auto& [id, displaySoloist] : idToSoloistMap_) {
596 displaySoloist->SetSubFrameRateLinkerEnable(enabled);
597 }
598
599 RequestNextVSync();
600 }
601
GetFrameRateRange()602 FrameRateRange RSDisplaySoloistManager::GetFrameRateRange()
603 {
604 return frameRateRange_;
605 }
606
GetIdToSoloistMap()607 IdToSoloistMapType RSDisplaySoloistManager::GetIdToSoloistMap()
608 {
609 return idToSoloistMap_;
610 }
611
GetFrameRateLinker()612 std::shared_ptr<RSFrameRateLinker> RSDisplaySoloistManager::GetFrameRateLinker()
613 {
614 return frameRateLinker_;
615 }
616
GetManagerStatus()617 enum ActiveStatus RSDisplaySoloistManager::GetManagerStatus()
618 {
619 return managerStatus_;
620 }
621
GetVSyncPeriod() const622 int64_t RSDisplaySoloistManager::GetVSyncPeriod() const
623 {
624 int64_t period = 0;
625 if (receiver_ == nullptr) {
626 ROSEN_LOGE("%{public}s, VSyncReceiver is null.", __func__);
627 return period;
628 }
629
630 #ifdef __OHOS__
631 receiver_->GetVSyncPeriod(period);
632 #endif
633 return period;
634 }
635
SetVSyncRate(int32_t vsyncRate)636 bool RSDisplaySoloistManager::SetVSyncRate(int32_t vsyncRate)
637 {
638 if (vsyncRate < 0) {
639 return false;
640 }
641
642 if (sourceVsyncRate_ == vsyncRate) {
643 return false;
644 }
645 sourceVsyncRate_ = vsyncRate;
646 return true;
647 }
648
GetVSyncRate() const649 int32_t RSDisplaySoloistManager::GetVSyncRate() const
650 {
651 return sourceVsyncRate_;
652 }
653
OnVsyncTimeOut()654 void RSDisplaySoloistManager::OnVsyncTimeOut()
655 {
656 ROSEN_LOGD("%{public}s MainDisplaySoloistManager: Vsync time out", __func__);
657 }
658
659 } // namespace Rosen
660 } // namespace OHOS
661