• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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