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