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