• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "vsync_distributor.h"
17 #include <chrono>
18 #include <condition_variable>
19 #include <algorithm>
20 #include <cinttypes>
21 #include <cstdint>
22 #include <mutex>
23 #include <sched.h>
24 #include <sys/resource.h>
25 #include <scoped_bytrace.h>
26 #include <hitrace_meter.h>
27 #include "vsync_log.h"
28 #include "vsync_type.h"
29 #include "vsync_generator.h"
30 #include <rs_trace.h>
31 #include "scoped_trace_fmt.h"
32 
33 #ifdef COMPOSER_SCHED_ENABLE
34 #include "if_system_ability_manager.h"
35 #include <iservice_registry.h>
36 #include "system_ability_definition.h"
37 #endif
38 
39 #if defined(RS_ENABLE_DVSYNC_2)
40 #include "dvsync.h"
41 #include "dvsync_controller.h"
42 #endif
43 
44 namespace OHOS {
45 namespace Rosen {
46 namespace {
47 constexpr int32_t SOFT_VSYNC_PERIOD = 16;
48 constexpr int32_t ERRNO_EAGAIN = -1;
49 constexpr int32_t ERRNO_OTHER = -2;
50 constexpr int32_t THREAD_PRIORTY = -6;
51 constexpr int32_t SCHED_PRIORITY = 2;
52 constexpr int32_t DEFAULT_VSYNC_RATE = 1;
53 constexpr uint32_t SOCKET_CHANNEL_SIZE = 1024;
54 constexpr int32_t VSYNC_CONNECTION_MAX_SIZE = 256;
55 }
56 
VSyncConnectionDeathRecipient(wptr<VSyncConnection> conn)57 VSyncConnection::VSyncConnectionDeathRecipient::VSyncConnectionDeathRecipient(
58     wptr<VSyncConnection> conn) : conn_(conn)
59 {
60 }
61 
OnRemoteDied(const wptr<IRemoteObject> & token)62 void VSyncConnection::VSyncConnectionDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& token)
63 {
64     auto tokenSptr = token.promote();
65     if (tokenSptr == nullptr) {
66         VLOGW("%{public}s: can't promote remote object.", __func__);
67         return;
68     }
69     auto vsyncConn = conn_.promote();
70     if (vsyncConn == nullptr) {
71         VLOGW("%{public}s: VSyncConnection was dead, do nothing.", __func__);
72         return;
73     }
74     if (vsyncConn->token_ != tokenSptr) {
75         VLOGI("%{public}s: token doesn't match, ignore it.", __func__);
76         return;
77     }
78     VLOGD("%{public}s: clear socketPair, conn name:%{public}s.", __func__, vsyncConn->info_.name_.c_str());
79     VsyncError ret = vsyncConn->Destroy();
80     if (ret != VSYNC_ERROR_OK) {
81         VLOGE("vsync connection clearAll failed!");
82     }
83 }
84 
VSyncConnection(const sptr<VSyncDistributor> & distributor,std::string name,const sptr<IRemoteObject> & token,uint64_t id,uint64_t windowNodeId)85 VSyncConnection::VSyncConnection(
86     const sptr<VSyncDistributor>& distributor,
87     std::string name,
88     const sptr<IRemoteObject>& token,
89     uint64_t id,
90     uint64_t windowNodeId)
91     : rate_(-1),
92       info_(name),
93       id_(id),
94       windowNodeId_(windowNodeId),
95       vsyncConnDeathRecipient_(new VSyncConnectionDeathRecipient(this)),
96       token_(token),
97       distributor_(distributor)
98 {
99     socketPair_ = new LocalSocketPair();
100     int32_t err = socketPair_->CreateChannel(SOCKET_CHANNEL_SIZE, SOCKET_CHANNEL_SIZE);
101     if (err != 0) {
102         RS_TRACE_NAME_FMT("Create socket channel failed, errno = %d", errno);
103     }
104     proxyPid_ = GetCallingPid();
105     isDead_ = false;
106 }
107 
RegisterDeathRecipient()108 void VSyncConnection::RegisterDeathRecipient()
109 {
110     if (token_ != nullptr) {
111         token_->AddDeathRecipient(vsyncConnDeathRecipient_);
112     }
113 }
114 
~VSyncConnection()115 VSyncConnection::~VSyncConnection()
116 {
117     if ((token_ != nullptr) && (vsyncConnDeathRecipient_ != nullptr)) {
118         token_->RemoveDeathRecipient(vsyncConnDeathRecipient_);
119     }
120 }
121 
RequestNextVSync()122 VsyncError VSyncConnection::RequestNextVSync()
123 {
124     static const std::string DEFAULT_REQUEST = "unknown";
125     return RequestNextVSync(DEFAULT_REQUEST, 0);
126 }
127 
RequestNextVSync(const std::string & fromWhom,int64_t lastVSyncTS)128 VsyncError VSyncConnection::RequestNextVSync(const std::string &fromWhom, int64_t lastVSyncTS)
129 {
130     sptr<VSyncDistributor> distributor;
131     {
132         std::unique_lock<std::mutex> locker(mutex_);
133         if (isDead_) {
134             VLOGE("%{public}s VSync Client Connection is dead, name:%{public}s.", __func__, info_.name_.c_str());
135             return VSYNC_ERROR_API_FAILED;
136         }
137         if (distributor_ == nullptr) {
138             VLOGE("%{public}s distributor_ is null, name:%{public}s.", __func__, info_.name_.c_str());
139             return VSYNC_ERROR_NULLPTR;
140         }
141         distributor = distributor_.promote();
142         if (distributor == nullptr) {
143             VLOGE("%{public}s distributor is null, name:%{public}s.", __func__, info_.name_.c_str());
144             return VSYNC_ERROR_NULLPTR;
145         }
146         if (isFirstRequestVsync_) {
147             isFirstRequestVsync_ = false;
148             distributor->FirstRequestVsync();
149             VLOGI("First vsync is requested, name: %{public}s", info_.name_.c_str());
150         }
151     }
152     return distributor->RequestNextVSync(this, fromWhom, lastVSyncTS);
153 }
154 
GetReceiveFd(int32_t & fd)155 VsyncError VSyncConnection::GetReceiveFd(int32_t &fd)
156 {
157     std::unique_lock<std::mutex> locker(mutex_);
158     if (isDead_ || socketPair_ == nullptr) {
159         VLOGE("%{public}s VSync Client Connection is dead, name:%{public}s.", __func__, info_.name_.c_str());
160         return VSYNC_ERROR_API_FAILED;
161     }
162     fd = socketPair_->GetReceiveDataFd();
163     if (fd < 0) {
164         VLOGE("%{public}s socketPair invalid fd:%{public}d.", __func__, fd);
165         return VSYNC_ERROR_API_FAILED;
166     }
167     return VSYNC_ERROR_OK;
168 }
169 
PostEvent(int64_t now,int64_t period,int64_t vsyncCount)170 int32_t VSyncConnection::PostEvent(int64_t now, int64_t period, int64_t vsyncCount)
171 {
172     sptr<LocalSocketPair> socketPair;
173     {
174         std::unique_lock<std::mutex> locker(mutex_);
175         if (isDead_) {
176             RS_TRACE_NAME_FMT("Vsync Client Connection is dead, conn: %s", info_.name_.c_str());
177             VLOGE("%{public}s VSync Client Connection is dead, name:%{public}s.", __func__, info_.name_.c_str());
178             return ERRNO_OTHER;
179         }
180         socketPair = socketPair_;
181     }
182     if (socketPair == nullptr) {
183         RS_TRACE_NAME_FMT("socketPair is null, conn: %s", info_.name_.c_str());
184         return ERRNO_OTHER;
185     }
186 
187     std::unique_lock<std::mutex> lockerPostEvent(postEventMutex_);
188     RS_TRACE_NAME_FMT("SendVsyncTo conn: %s, now:%ld, refreshRate:%d", info_.name_.c_str(), now, refreshRate_);
189     // 3 is array size.
190     int64_t data[3];
191     data[0] = now;
192     // 1, 2: index of array data.
193     data[1] = period;
194     data[2] = vsyncCount;
195     if (isFirstSendVsync_) {
196         isFirstSendVsync_ = false;
197         VLOGI("First vsync has send to : %{public}s", info_.name_.c_str());
198     }
199     int32_t ret = socketPair->SendData(data, sizeof(data));
200     if (ret == ERRNO_EAGAIN) {
201         RS_TRACE_NAME("remove the earlies data and SendData again.");
202         int64_t receiveData[3];
203         socketPair->ReceiveData(receiveData, sizeof(receiveData));
204         ret = socketPair->SendData(data, sizeof(data));
205         VLOGW("vsync signal is not processed in time, please check pid:%{public}d, ret:%{public}d", proxyPid_, ret);
206     }
207     if (ret > -1) {
208         ScopedDebugTrace successful("successful");
209         info_.postVSyncCount_++;
210         if (gcNotifyTask_ != nullptr) {
211             gcNotifyTask_(false);
212         }
213     } else {
214         ScopedBytrace failed("failed");
215     }
216     return ret;
217 }
218 
SetVSyncRate(int32_t rate)219 VsyncError VSyncConnection::SetVSyncRate(int32_t rate)
220 {
221     std::unique_lock<std::mutex> locker(mutex_);
222     if (isDead_) {
223         VLOGE("%{public}s VSync Client Connection is dead, name:%{public}s.", __func__, info_.name_.c_str());
224         return VSYNC_ERROR_API_FAILED;
225     }
226     if (distributor_ == nullptr) {
227         return VSYNC_ERROR_NULLPTR;
228     }
229     const sptr<VSyncDistributor> distributor = distributor_.promote();
230     if (distributor == nullptr) {
231         return VSYNC_ERROR_NULLPTR;
232     }
233     return distributor->SetVSyncRate(rate, this);
234 }
235 
CleanAllLocked()236 VsyncError VSyncConnection::CleanAllLocked()
237 {
238     socketPair_ = nullptr;
239     const sptr<VSyncDistributor> distributor = distributor_.promote();
240     if (distributor == nullptr) {
241         return VSYNC_ERROR_OK;
242     }
243     VsyncError ret = distributor->RemoveConnection(this);
244     isDead_ = true;
245     return ret;
246 }
247 
Destroy()248 VsyncError VSyncConnection::Destroy()
249 {
250     std::unique_lock<std::mutex> locker(mutex_);
251     return CleanAllLocked();
252 }
253 
SetUiDvsyncSwitch(bool dvsyncSwitch)254 VsyncError VSyncConnection::SetUiDvsyncSwitch(bool dvsyncSwitch)
255 {
256     sptr<VSyncDistributor> distributor;
257     {
258         std::unique_lock<std::mutex> locker(mutex_);
259         if (isDead_) {
260             VLOGE("%{public}s VSync Client Connection is dead, name:%{public}s.", __func__, info_.name_.c_str());
261             return VSYNC_ERROR_API_FAILED;
262         }
263         if (distributor_ == nullptr) {
264             return VSYNC_ERROR_NULLPTR;
265         }
266         distributor = distributor_.promote();
267         if (distributor == nullptr) {
268             return VSYNC_ERROR_NULLPTR;
269         }
270     }
271     return distributor->SetUiDvsyncSwitch(dvsyncSwitch, this);
272 }
273 
SetNativeDVSyncSwitch(bool dvsyncSwitch)274 VsyncError VSyncConnection::SetNativeDVSyncSwitch(bool dvsyncSwitch)
275 {
276     sptr<VSyncDistributor> distributor;
277     {
278         std::unique_lock<std::mutex> locker(mutex_);
279         if (isDead_) {
280             VLOGE("%{public}s VSync Client Connection is dead, name:%{public}s.", __func__, info_.name_.c_str());
281             return VSYNC_ERROR_API_FAILED;
282         }
283         if (distributor_ == nullptr) {
284             return VSYNC_ERROR_NULLPTR;
285         }
286         distributor = distributor_.promote();
287         if (distributor == nullptr) {
288             return VSYNC_ERROR_NULLPTR;
289         }
290     }
291     return distributor->SetNativeDVSyncSwitch(dvsyncSwitch, this);
292 }
293 
SetUiDvsyncConfig(int32_t bufferCount)294 VsyncError VSyncConnection::SetUiDvsyncConfig(int32_t bufferCount)
295 {
296     sptr<VSyncDistributor> distributor;
297     {
298         std::unique_lock<std::mutex> locker(mutex_);
299         if (isDead_) {
300             VLOGE("%{public}s VSync Client Connection is dead, name:%{public}s.", __func__, info_.name_.c_str());
301             return VSYNC_ERROR_API_FAILED;
302         }
303         if (distributor_ == nullptr) {
304             return VSYNC_ERROR_NULLPTR;
305         }
306         distributor = distributor_.promote();
307         if (distributor == nullptr) {
308             return VSYNC_ERROR_NULLPTR;
309         }
310     }
311     return distributor->SetUiDvsyncConfig(bufferCount);
312 }
313 
VSyncDistributor(sptr<VSyncController> controller,std::string name,DVSyncFeatureParam dvsyncParam)314 VSyncDistributor::VSyncDistributor(sptr<VSyncController> controller, std::string name, DVSyncFeatureParam dvsyncParam)
315     : controller_(controller), mutex_(), con_(), connections_(),
316     event_(), vsyncEnabled_(false), name_(name)
317 {
318     static const std::string DEFAULT_RS_NAME = "rs";
319     if (name == DEFAULT_RS_NAME) {
320         isRs_ = true;
321     }
322 #if defined(RS_ENABLE_DVSYNC)
323     dvsync_ = new DVsync(isRs_);
324     if (dvsync_->IsFeatureEnabled()) {
325         vsyncThreadRunning_ = true;
326         threadLoop_ = std::thread([this] { this->ThreadMain(); });
327         std::string threadName = "DVSync-" + name;
328         pthread_setname_np(threadLoop_.native_handle(), threadName.c_str());
329     }
330 #endif
331     // Start of DVSync
332     InitDVSync(dvsyncParam);
333     // End of DVSync
334 }
335 
~VSyncDistributor()336 VSyncDistributor::~VSyncDistributor()
337 {
338 #if defined(RS_ENABLE_DVSYNC)
339     if (dvsync_->IsFeatureEnabled()) {
340         {
341             std::unique_lock<std::mutex> locker(mutex_);
342             vsyncThreadRunning_ = false;
343         }
344         if (threadLoop_.joinable()) {
345             {
346                 std::unique_lock<std::mutex> locker(mutex_);
347                 dvsync_->RNVNotify();
348             }
349             con_.notify_all();
350             threadLoop_.join();
351         }
352     }
353 #endif
354 }
355 
AddConnection(const sptr<VSyncConnection> & connection,uint64_t windowNodeId)356 VsyncError VSyncDistributor::AddConnection(const sptr<VSyncConnection>& connection, uint64_t windowNodeId)
357 {
358     if (connection == nullptr) {
359         return VSYNC_ERROR_NULLPTR;
360     }
361     std::lock_guard<std::mutex> locker(mutex_);
362     int32_t proxyPid = connection->proxyPid_;
363     if (connectionCounter_[proxyPid] > VSYNC_CONNECTION_MAX_SIZE) {
364         VLOGE("You [%{public}d] have created too many vsync connection, please check!!!", proxyPid);
365         return VSYNC_ERROR_API_FAILED;
366     }
367     auto it = std::find(connections_.begin(), connections_.end(), connection);
368     if (it != connections_.end()) {
369         return VSYNC_ERROR_INVALID_ARGUMENTS;
370     }
371     RS_TRACE_NAME_FMT("Add VSyncConnection: %s", connection->info_.name_.c_str());
372     connections_.push_back(connection);
373     // Start of DVSync
374     DVSyncAddConnection(connection);
375     // End of DVSync
376     connectionCounter_[proxyPid]++;
377     if (windowNodeId != 0) {
378         connectionsMap_[windowNodeId].push_back(connection);
379         uint32_t tmpPid;
380         if (QosGetPidByName(connection->info_.name_, tmpPid) == VSYNC_ERROR_OK) {
381             std::vector<uint64_t> tmpVec = pidWindowIdMap_[tmpPid];
382             if (std::find(tmpVec.begin(), tmpVec.end(), windowNodeId) == tmpVec.end()) {
383                 pidWindowIdMap_[tmpPid].push_back(windowNodeId);
384             }
385         }
386     } else {
387         uint32_t tmpPid;
388         if (QosGetPidByName(connection->info_.name_, tmpPid) == VSYNC_ERROR_OK) {
389             connectionsMap_[tmpPid].push_back(connection);
390         }
391     }
392     connection->RegisterDeathRecipient();
393     return VSYNC_ERROR_OK;
394 }
395 
RemoveConnection(const sptr<VSyncConnection> & connection)396 VsyncError VSyncDistributor::RemoveConnection(const sptr<VSyncConnection>& connection)
397 {
398     if (connection == nullptr) {
399         return VSYNC_ERROR_NULLPTR;
400     }
401     std::lock_guard<std::mutex> locker(mutex_);
402     int32_t proxyPid = connection->proxyPid_;
403     auto it = std::find(connections_.begin(), connections_.end(), connection);
404     if (it == connections_.end()) {
405         return VSYNC_ERROR_INVALID_ARGUMENTS;
406     }
407     RS_TRACE_NAME_FMT("Remove VSyncConnection: %s", connection->info_.name_.c_str());
408     connections_.erase(it);
409     connectionCounter_[proxyPid]--;
410     if (connectionCounter_[proxyPid] == 0) {
411         connectionCounter_.erase(proxyPid);
412     }
413     connectionsMap_.erase(connection->windowNodeId_);
414     uint32_t tmpPid;
415     if (QosGetPidByName(connection->info_.name_, tmpPid) == VSYNC_ERROR_OK) {
416         pidWindowIdMap_.erase(tmpPid);
417         auto iter = connectionsMap_.find(tmpPid);
418         if (iter == connectionsMap_.end()) {
419             return VSYNC_ERROR_OK;
420         }
421         auto connIter = find(iter->second.begin(), iter->second.end(), connection);
422         if (connIter != iter->second.end()) {
423             iter->second.erase(connIter);
424         }
425         if (iter->second.empty()) {
426             connectionsMap_.erase(iter);
427         }
428     }
429     return VSYNC_ERROR_OK;
430 }
431 
WaitForVsyncOrRequest(std::unique_lock<std::mutex> & locker)432 void VSyncDistributor::WaitForVsyncOrRequest(std::unique_lock<std::mutex> &locker)
433 {
434     if (!vsyncThreadRunning_) {
435         return;
436     }
437 
438     // before con_ wait, notify the rnv_con.
439 #if defined(RS_ENABLE_DVSYNC)
440     beforeWaitRnvTime_ = Now();
441     dvsync_->RNVNotify();
442     if (!isRs_ && IsDVsyncOn()) {
443         con_.wait_for(locker, std::chrono::nanoseconds(dvsync_->WaitTime()), [this] { return dvsync_->WaitCond(); });
444     } else {
445         if (!(hasVsync_.load() && isRs_)) {
446             con_.wait(locker);
447         }
448         hasVsync_.store(false);
449     }
450     afterWaitRnvTime_ = Now();
451     if (pendingRNVInVsync_) {
452         return;
453     }
454     if (IsDVsyncOn()) {
455         std::pair<bool, int64_t> result = dvsync_->DoPreExecute(locker, con_);
456         if (result.first) {
457             event_.timestamp = result.second;
458             lastDVsyncTS_.store(result.second);
459             event_.vsyncCount++;
460             if (vsyncEnabled_ == false) {
461                 ScopedBytrace func(name_ + "_EnableVsync");
462                 EnableVSync();
463             }
464         }
465     }
466 #else
467     con_.wait(locker);
468 #endif
469 }
470 
Now()471 int64_t Now()
472 {
473     const auto &now = std::chrono::steady_clock::now().time_since_epoch();
474     return std::chrono::duration_cast<std::chrono::nanoseconds>(now).count();
475 }
476 
WaitForVsyncOrTimeOut(std::unique_lock<std::mutex> & locker)477 void VSyncDistributor::WaitForVsyncOrTimeOut(std::unique_lock<std::mutex> &locker)
478 {
479 #if defined(RS_ENABLE_DVSYNC)
480     dvsync_->RNVNotify();
481 #endif
482     beforeWaitRnvTime_ = Now();
483     if (con_.wait_for(locker, std::chrono::milliseconds(SOFT_VSYNC_PERIOD)) ==
484         std::cv_status::timeout) {
485         event_.timestamp = Now();
486         event_.vsyncCount++;
487     }
488     afterWaitRnvTime_ = Now();
489 }
490 
ThreadMain()491 void VSyncDistributor::ThreadMain()
492 {
493     // set thread priorty
494     setpriority(PRIO_PROCESS, 0, THREAD_PRIORTY);
495     struct sched_param param = {0};
496     param.sched_priority = SCHED_PRIORITY;
497     sched_setscheduler(0, SCHED_FIFO, &param);
498 
499 #ifdef COMPOSER_SCHED_ENABLE
500     std::string threadName = "VSync-" + name_;
501     SubScribeSystemAbility(threadName);
502 #endif
503 
504     int64_t timestamp;
505     while (vsyncThreadRunning_ == true) {
506         std::vector<sptr<VSyncConnection>> conns;
507         {
508             bool waitForVSync = false;
509             std::unique_lock<std::mutex> locker(mutex_);
510             CollectConns(waitForVSync, timestamp, conns, true);
511             // no vsync signal
512             if (timestamp == 0) {
513                 // there is some connections request next vsync, enable vsync if vsync disable and
514                 // and start the software vsync with wait_for function
515                 if (waitForVSync == true && vsyncEnabled_ == false) {
516                     EnableVSync();
517                     WaitForVsyncOrTimeOut(locker);
518                 } else {
519                     // just wait request or vsync signal
520                     WaitForVsyncOrRequest(locker);
521                 }
522                 RS_TRACE_NAME_FMT("%s_continue: waitForVSync %d, vsyncEnabled %d, dvsyncOn %d",
523                     name_.c_str(), waitForVSync, vsyncEnabled_, IsDVsyncOn());
524                 if ((isRs_ && event_.timestamp == 0) || !IsDVsyncOn()) {
525                     continue;
526                 } else {
527                     timestamp = event_.timestamp;
528                 }
529             } else if ((timestamp > 0) && (waitForVSync == false) && (isRs_ || !IsDVsyncOn())) {
530                 // if there is a vsync signal but no vaild connections, we should disable vsync
531                 RS_TRACE_NAME_FMT("%s_DisableVSync, there is no valid connections", name_.c_str());
532                 VLOGI("%s_DisableVSync, there is no valid connections", name_.c_str());
533                 DisableVSync();
534                 continue;
535             }
536         }
537         if (!PostVSyncEventPreProcess(timestamp, conns)) {
538             continue;
539         } else {
540             // IMPORTANT: ScopedDebugTrace here will cause frame loss.
541             RS_TRACE_NAME_FMT("%s_SendVsync", name_.c_str());
542         }
543         PostVSyncEvent(conns, timestamp, true);
544     }
545 }
546 
CollectConns(bool & waitForVSync,int64_t & timestamp,std::vector<sptr<VSyncConnection>> & conns,bool isDvsyncThread)547 void VSyncDistributor::CollectConns(bool &waitForVSync, int64_t &timestamp,
548     std::vector<sptr<VSyncConnection>> &conns, bool isDvsyncThread)
549 {
550     if (isDvsyncThread) {
551         timestamp = event_.timestamp;
552         event_.timestamp = 0;
553     }
554     if (vsyncMode_ == VSYNC_MODE_LTPO) {
555         CollectConnectionsLTPO(waitForVSync, timestamp, conns, event_.vsyncPulseCount, isDvsyncThread);
556     } else {
557         CollectConnections(waitForVSync, timestamp, conns, event_.vsyncCount, isDvsyncThread);
558     }
559 }
560 
PostVSyncEventPreProcess(int64_t & timestamp,std::vector<sptr<VSyncConnection>> & conns)561 bool VSyncDistributor::PostVSyncEventPreProcess(int64_t &timestamp, std::vector<sptr<VSyncConnection>> &conns)
562 {
563 #if defined(RS_ENABLE_DVSYNC)
564     bool waitForVSync = false;
565     // ensure the preexecution only gets ahead for at most one period(i.e., 3 buffer rotation)
566     if (IsDVsyncOn()) {
567         {
568             std::unique_lock<std::mutex> locker(mutex_);
569             dvsync_->MarkDistributorSleep(true);
570             dvsync_->RNVNotify();
571             dvsync_->DelayBeforePostEvent(event_.timestamp, locker);
572             dvsync_->MarkDistributorSleep(false);
573             CollectConns(waitForVSync, timestamp, conns, true);
574             hasVsync_.store(false);
575         }
576         // if getting switched into vsync mode after sleep
577         if (!IsDVsyncOn()) {
578             ScopedBytrace func("NoAccumulateInVsync");
579             lastDVsyncTS_.store(0);  // ensure further OnVSyncEvent do not skip
580             for (auto conn : conns) {
581                 RequestNextVSync(conn);
582             }  // resend RNV for vsync
583             if (isRs_) {
584                 VLOGW("DVSync is close");
585             }
586             return false;  // do not accumulate frame;
587         }
588     } else {
589         std::unique_lock<std::mutex> locker(mutex_);
590         hasVsync_.store(false);
591     }
592     {
593         std::unique_lock<std::mutex> locker(mutex_);
594         pendingRNVInVsync_ = false;
595         if (IsUiDvsyncOn()) {
596             event_.period = dvsync_->GetPeriod();
597         }
598     }
599 #endif
600     return true;
601 }
602 
EnableVSync()603 void VSyncDistributor::EnableVSync()
604 {
605     if (controller_ != nullptr && vsyncEnabled_ == false) {
606         controller_->SetCallback(this);
607         controller_->SetEnable(true, vsyncEnabled_);
608         // Start of DVSync
609         RecordEnableVsync();
610     }
611     if (dvsyncController_!= nullptr && dvsyncControllerEnabled_ == false) {
612         ScopedBytrace func("dvsyncController enable");
613         dvsyncController_->SetCallback(this);
614         dvsyncController_->SetEnable(true, dvsyncControllerEnabled_);
615     }
616     // End of DVSync
617 #if defined(RS_ENABLE_DVSYNC)
618     dvsync_->RecordEnableVsync();
619 #endif
620 }
621 
DisableVSync()622 void VSyncDistributor::DisableVSync()
623 {
624     if (controller_ != nullptr && vsyncEnabled_ == true) {
625         controller_->SetEnable(false, vsyncEnabled_);
626     }
627     // Start of DVSync
628     DVSyncDisableVSync();
629     // End of DVSync
630 }
631 
632 #if defined(RS_ENABLE_DVSYNC)
OnDVSyncTrigger(int64_t now,int64_t period,uint32_t refreshRate,VSyncMode vsyncMode,uint32_t vsyncMaxRefreshRate)633 void VSyncDistributor::OnDVSyncTrigger(int64_t now, int64_t period,
634     uint32_t refreshRate, VSyncMode vsyncMode, uint32_t vsyncMaxRefreshRate)
635 {
636     std::unique_lock<std::mutex> locker(mutex_);
637     if (isFirstSend_) {
638         isFirstSend_ = false;
639         VLOGI("First vsync OnDVSyncTrigger");
640     }
641     vsyncMode_ = vsyncMode;
642     dvsync_->RuntimeSwitch();
643     if (IsDVsyncOn()) {
644         RS_TRACE_NAME_FMT("VSyncD onVSyncEvent, now:%ld", now);
645     } else {
646         RS_TRACE_NAME_FMT("VSync onVSyncEvent, now:%ld", now);
647     }
648     event_.period = period;
649 
650     dvsync_->RecordVSync(now, period, refreshRate);
651     dvsync_->NotifyPreexecuteWait();
652 
653     SendConnectionsToVSyncWindow(now, period, refreshRate, vsyncMode, locker);
654     // when dvsync switch to vsync, skip all vsync events within one period from the pre-rendered timestamp
655     if (dvsync_->NeedSkipDVsyncPrerenderedFrame()) {
656         return;
657     }
658 
659     // When vsync switches to dvsync, need to handle pending RNVs during vsync
660     if (!IsDVsyncOn() || pendingRNVInVsync_) {
661         event_.timestamp = now;
662         event_.vsyncCount++;
663     }
664 
665     if (refreshRate > 0) {
666         event_.vsyncPulseCount += static_cast<int64_t>(vsyncMaxRefreshRate / refreshRate);
667         generatorRefreshRate_ = refreshRate;
668     }
669 
670     ChangeConnsRateLocked(vsyncMaxRefreshRate);
671     RS_TRACE_NAME_FMT("pendingRNVInVsync: %d DVSyncOn: %d isRS:%d", pendingRNVInVsync_, IsDVsyncOn(), isRs_);
672     if (dvsync_->WaitCond() || pendingRNVInVsync_) {
673         con_.notify_all();
674     } else {
675         CheckNeedDisableDvsync(now, period);
676     }
677 }
678 #endif
679 
OnVSyncTrigger(int64_t now,int64_t period,uint32_t refreshRate,VSyncMode vsyncMode,uint32_t vsyncMaxRefreshRate)680 void VSyncDistributor::OnVSyncTrigger(int64_t now, int64_t period,
681     uint32_t refreshRate, VSyncMode vsyncMode, uint32_t vsyncMaxRefreshRate)
682 {
683     std::vector<sptr<VSyncConnection>> conns;
684     uint32_t generatorRefreshRate;
685     int64_t vsyncCount;
686 
687     {
688         bool waitForVSync = false;
689         std::lock_guard<std::mutex> locker(mutex_);
690         if (isFirstSend_) {
691             isFirstSend_ = false;
692             VLOGI("First vsync OnVSyncTrigger");
693         }
694         // Start of DVSync
695         DVSyncRecordVSync(now, period, refreshRate, false);
696         // End of DVSync
697         event_.vsyncCount++;
698         vsyncCount = event_.vsyncCount;
699 #if defined(RS_ENABLE_DVSYNC)
700         if (dvsync_->IsFeatureEnabled()) {
701             dvsync_->RecordVSync(now, period, refreshRate);
702         }
703 #endif
704         if (refreshRate > 0) {
705             event_.vsyncPulseCount += static_cast<int64_t>(vsyncMaxRefreshRate / refreshRate);
706             generatorRefreshRate_ = refreshRate;
707         }
708         vsyncMode_ = vsyncMode;
709         ChangeConnsRateLocked(vsyncMaxRefreshRate);
710 
711         if (vsyncMode_ == VSYNC_MODE_LTPO) {
712             CollectConnectionsLTPO(waitForVSync, now, conns, event_.vsyncPulseCount);
713         } else {
714             CollectConnections(waitForVSync, now, conns, event_.vsyncCount);
715         }
716 #if defined(RS_ENABLE_DVSYNC_2)
717         bool canDisableVsync = isRs_ || !DVSync::Instance().IsAppDVSyncOn();
718 #else
719         bool canDisableVsync = true;
720 #endif
721         if (!waitForVSync && canDisableVsync) {
722             DisableVSync();
723             return;
724         }
725 
726         countTraceValue_ = (countTraceValue_ + 1) % 2;  // 2 : change num
727         CountTrace(HITRACE_TAG_GRAPHIC_AGP, "VSync-" + name_, countTraceValue_);
728 
729         generatorRefreshRate = generatorRefreshRate_;
730 #if defined(RS_ENABLE_DVSYNC)
731         if (dvsync_->IsFeatureEnabled()) {
732             dvsync_->RecordPostEvent(conns, now);
733         }
734 #endif
735     }
736     ConnectionsPostEvent(conns, now, period, generatorRefreshRate, vsyncCount, false);
737 }
738 
TriggerNext(sptr<VSyncConnection> con)739 void VSyncDistributor::TriggerNext(sptr<VSyncConnection> con)
740 {
741     std::lock_guard<std::mutex> locker(mutex_);
742     // Trigger VSync Again for LTPO
743     con->triggerThisTime_ = true;
744     // Exclude SetVSyncRate for LTPS
745     if (con->rate_ < 0) {
746         con->rate_ = 0;
747     }
748 }
749 
ConnPostEvent(sptr<VSyncConnection> con,int64_t now,int64_t period,int64_t vsyncCount)750 void VSyncDistributor::ConnPostEvent(sptr<VSyncConnection> con, int64_t now, int64_t period, int64_t vsyncCount)
751 {
752     int32_t ret = con->PostEvent(now, period, vsyncCount);
753     VLOGD("Distributor name: %{public}s, Conn name: %{public}s, ret: %{public}d",
754         name_.c_str(), con->info_.name.c_str(), ret);
755     if (ret == 0 || ret == ERRNO_OTHER) {
756         RemoveConnection(con);
757     } else if (ret == ERRNO_EAGAIN) {
758         TriggerNext(con);
759     }
760 }
761 
ConnectionsPostEvent(std::vector<sptr<VSyncConnection>> & conns,int64_t now,int64_t period,uint32_t generatorRefreshRate,int64_t vsyncCount,bool isDvsyncController)762 void VSyncDistributor::ConnectionsPostEvent(std::vector<sptr<VSyncConnection>> &conns, int64_t now, int64_t period,
763     uint32_t generatorRefreshRate, int64_t vsyncCount, bool isDvsyncController)
764 {
765     for (uint32_t i = 0; i < conns.size(); i++) {
766         int64_t actualPeriod = period;
767         int64_t timestamp = now;
768         if ((generatorRefreshRate > 0) && (conns[i]->refreshRate_ > 0) &&
769             (generatorRefreshRate % conns[i]->refreshRate_ == 0)
770             && !isDvsyncController) {
771             actualPeriod = period * static_cast<int64_t>(generatorRefreshRate / conns[i]->refreshRate_);
772         }
773         // Start of DVSync
774         if (DVSyncCheckSkipAndUpdateTs(conns[i], timestamp)) {
775             TriggerNext(conns[i]);
776             continue;
777         }
778         // End of DVSync
779         ConnPostEvent(conns[i], timestamp, actualPeriod, vsyncCount);
780     }
781 }
782 
OnVSyncEvent(int64_t now,int64_t period,uint32_t refreshRate,VSyncMode vsyncMode,uint32_t vsyncMaxRefreshRate)783 void VSyncDistributor::OnVSyncEvent(int64_t now, int64_t period,
784     uint32_t refreshRate, VSyncMode vsyncMode, uint32_t vsyncMaxRefreshRate)
785 {
786 #if defined(RS_ENABLE_DVSYNC)
787     bool needDVSyncTrigger = true;
788     if (dvsync_->IsFeatureEnabled()) {
789         std::unique_lock<std::mutex> locker(mutex_);
790         dvsync_->ChangeState(now);
791         needDVSyncTrigger = dvsync_->NeedDVSyncTrigger();
792     }
793     if (dvsync_->IsFeatureEnabled() && needDVSyncTrigger) {
794         OnDVSyncTrigger(now, period, refreshRate, vsyncMode, vsyncMaxRefreshRate);
795     } else
796 #endif
797     {
798         OnVSyncTrigger(now, period, refreshRate, vsyncMode, vsyncMaxRefreshRate);
799     }
800 }
801 
802 #if defined(RS_ENABLE_DVSYNC)
SendConnectionsToVSyncWindow(int64_t now,int64_t period,uint32_t refreshRate,VSyncMode vsyncMode,std::unique_lock<std::mutex> & locker)803 void VSyncDistributor::SendConnectionsToVSyncWindow(int64_t now, int64_t period, uint32_t refreshRate,
804                                                     VSyncMode vsyncMode, std::unique_lock<std::mutex> &locker)
805 {
806     std::vector<sptr<VSyncConnection>> conns;
807     bool waitForVSync = false;
808     if (isRs_ || GetUIDVsyncPid() == 0) {
809         return;
810     }
811     CollectConns(waitForVSync, now, conns, false);
812     locker.unlock();
813     PostVSyncEvent(conns, now, false);
814     locker.lock();
815 }
816 
GetUIDVsyncPid()817 int32_t VSyncDistributor::GetUIDVsyncPid()
818 {
819     int32_t pid = 0;
820     if (!isRs_) {
821         pid = dvsync_->GetProxyPid();
822     }
823     return pid;
824 }
825 #endif
826 
CheckNeedDisableDvsync(int64_t now,int64_t period)827 void VSyncDistributor::CheckNeedDisableDvsync(int64_t now, int64_t period)
828 {
829 #if defined(RS_ENABLE_DVSYNC)
830     if (!isRs_ && IsDVsyncOn()) {
831         return;
832     }
833     // When Dvsync on, if the RequestNextVsync is not invoked within three period and SetVSyncRate
834     // is not invoked either, execute DisableVSync.
835     for (uint32_t i = 0; i < connections_.size(); i++) {
836         if (connections_[i]->triggerThisTime_ || connections_[i]->rate_ >= 0) {
837             return;
838         }
839     }
840     if (now - dvsync_->GetLastRnvTS() > 3 * period) {  // 3 period
841         ScopedBytrace func(name_ + "_DisableVsync");
842         DisableVSync();
843     }
844 #endif
845 }
846 
847 /* std::pair<id, refresh rate> */
OnConnsRefreshRateChanged(const std::vector<std::pair<uint64_t,uint32_t>> & refreshRates)848 void VSyncDistributor::OnConnsRefreshRateChanged(const std::vector<std::pair<uint64_t, uint32_t>> &refreshRates)
849 {
850     std::lock_guard<std::mutex> locker(changingConnsRefreshRatesMtx_);
851     for (auto refreshRate : refreshRates) {
852         changingConnsRefreshRates_[refreshRate.first] = refreshRate.second;
853     }
854 }
855 
SubScribeSystemAbility(const std::string & threadName)856 void VSyncDistributor::SubScribeSystemAbility(const std::string& threadName)
857 {
858     VLOGI("%{public}s", __func__);
859     sptr<ISystemAbilityManager> systemAbilityManager =
860         SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
861     if (!systemAbilityManager) {
862         VLOGE("%{public}s failed to get system ability manager client", __func__);
863         return;
864     }
865     std::string strUid = std::to_string(getuid());
866     std::string strPid = std::to_string(getpid());
867     std::string strTid = std::to_string(gettid());
868 
869     saStatusChangeListener_ = new VSyncSystemAbilityListener(threadName, strUid, strPid, strTid);
870     int32_t ret = systemAbilityManager->SubscribeSystemAbility(RES_SCHED_SYS_ABILITY_ID, saStatusChangeListener_);
871     if (ret != ERR_OK) {
872         VLOGE("%{public}s subscribe system ability %{public}d failed.", __func__, RES_SCHED_SYS_ABILITY_ID);
873         saStatusChangeListener_ = nullptr;
874     }
875 }
876 
CollectConnections(bool & waitForVSync,int64_t timestamp,std::vector<sptr<VSyncConnection>> & conns,int64_t vsyncCount,bool isDvsyncThread)877 void VSyncDistributor::CollectConnections(bool &waitForVSync, int64_t timestamp,
878     std::vector<sptr<VSyncConnection>> &conns, int64_t vsyncCount, bool isDvsyncThread)
879 {
880 #if defined(RS_ENABLE_DVSYNC)
881     auto uiDVsyncPid = GetUIDVsyncPid();
882 #endif
883     for (uint32_t i = 0; i < connections_.size(); i++) {
884 #if defined(RS_ENABLE_DVSYNC)
885     if (uiDVsyncPid != 0 && ((!isDvsyncThread && connections_[i]->proxyPid_ == uiDVsyncPid) ||
886         (isDvsyncThread && connections_[i]->proxyPid_ != uiDVsyncPid))) {
887             continue;
888         }
889 #endif
890         int32_t rate = connections_[i]->highPriorityState_ ? connections_[i]->highPriorityRate_ :
891                                                              connections_[i]->rate_;
892 
893         if (rate < 0) {
894             continue;
895         }
896 
897         if (rate == 0) {  // for RequestNextVSync
898             waitForVSync = true;
899             if (timestamp > 0) {
900                 connections_[i]->rate_ = -1;
901                 connections_[i]->triggerThisTime_ = false;
902                 conns.push_back(connections_[i]);
903             }
904             continue;
905         }
906 
907         RS_TRACE_NAME_FMT("CollectConnections name:%s, proxyPid:%d, highPriorityState_:%d, highPriorityRate_:%d"
908             ", rate_:%d, timestamp:%ld, vsyncCount:%ld", connections_[i]->info_.name_.c_str(),
909             connections_[i]->proxyPid_, connections_[i]->highPriorityState_,
910             connections_[i]->highPriorityRate_, connections_[i]->rate_, timestamp, vsyncCount);
911 
912         if (connections_[i]->rate_ == 0) {  // for SetHighPriorityVSyncRate with RequestNextVSync
913             waitForVSync = true;
914             if (timestamp > 0 && (vsyncCount % rate == 0)) {
915                 connections_[i]->rate_ = -1;
916                 connections_[i]->triggerThisTime_ = false;
917                 conns.push_back(connections_[i]);
918             }
919         } else if (connections_[i]->rate_ > 0) {  // for SetVSyncRate
920             waitForVSync = true;
921             if (timestamp > 0 && (vsyncCount % rate == 0)) {
922                 conns.push_back(connections_[i]);
923             }
924         }
925     }
926 }
927 
CollectConnectionsLTPO(bool & waitForVSync,int64_t timestamp,std::vector<sptr<VSyncConnection>> & conns,int64_t vsyncCount,bool isDvsyncThread)928 void VSyncDistributor::CollectConnectionsLTPO(bool &waitForVSync, int64_t timestamp,
929     std::vector<sptr<VSyncConnection>> &conns, int64_t vsyncCount, bool isDvsyncThread)
930 {
931 #if defined(RS_ENABLE_DVSYNC)
932     auto uiDVsyncPid = GetUIDVsyncPid();
933 #endif
934     for (uint32_t i = 0; i < connections_.size(); i++) {
935 #if defined(RS_ENABLE_DVSYNC)
936     if (uiDVsyncPid != 0 && ((!isDvsyncThread && connections_[i]->proxyPid_ == uiDVsyncPid) ||
937         (isDvsyncThread && connections_[i]->proxyPid_ != uiDVsyncPid))) {
938             continue;
939         }
940 #endif
941         SCOPED_DEBUG_TRACE_FMT("CollectConnectionsLTPO, i:%d, name:%s, rate:%d, vsyncPulseFreq:%u"
942             ", referencePulseCount:%ld, vsyncCount:%d, highPriorityRate_:%d", i, connections_[i]->info_.name_.c_str(),
943             connections_[i]->rate_, connections_[i]->vsyncPulseFreq_, connections_[i]->referencePulseCount_,
944             vsyncCount, connections_[i]->highPriorityRate_);
945         // Start of DVSync
946         if (DVSyncNeedSkipUi(connections_[i])) {
947             waitForVSync = true;
948             continue;
949         }
950         // End of DVSync
951         if (!connections_[i]->triggerThisTime_ && connections_[i]->rate_ <= 0) {
952             continue;
953         }
954         waitForVSync = true;
955         if (timestamp <= 0) {
956             break;
957         }
958         int64_t vsyncPulseFreq = static_cast<int64_t>(connections_[i]->vsyncPulseFreq_);
959         if (vsyncPulseFreq == 0) {
960             continue;
961         }
962         if ((vsyncCount - connections_[i]->referencePulseCount_) % vsyncPulseFreq == 0) {
963             connections_[i]->triggerThisTime_ = false;
964             if (connections_[i]->rate_ == 0) {
965                 connections_[i]->rate_ = -1;
966             }
967             conns.push_back(connections_[i]);
968         }
969     }
970 }
971 
PostVSyncEvent(const std::vector<sptr<VSyncConnection>> & conns,int64_t timestamp,bool isDvsyncThread)972 void VSyncDistributor::PostVSyncEvent(const std::vector<sptr<VSyncConnection>> &conns,
973                                       int64_t timestamp, bool isDvsyncThread)
974 {
975     beforePostEvent_.store(Now());
976 #if defined(RS_ENABLE_DVSYNC)
977     if (isDvsyncThread) {
978         std::unique_lock<std::mutex> locker(mutex_);
979         dvsync_->RecordPostEvent(conns, timestamp);
980     }
981 #endif
982     uint32_t generatorRefreshRate = 0;
983     int64_t eventPeriod = 0;
984     int64_t vsyncCount = 0;
985     {
986         std::unique_lock<std::mutex> locker(mutex_);
987         generatorRefreshRate = generatorRefreshRate_;
988         eventPeriod = event_.period;
989         vsyncCount = event_.vsyncCount;
990     }
991     for (uint32_t i = 0; i < conns.size(); i++) {
992         int64_t period = eventPeriod;
993         if ((generatorRefreshRate > 0) && (conns[i]->refreshRate_ > 0) &&
994             (generatorRefreshRate % conns[i]->refreshRate_ == 0)) {
995             period = eventPeriod * static_cast<int64_t>(generatorRefreshRate / conns[i]->refreshRate_);
996         }
997         startPostEvent_.store(Now());
998         int32_t ret = conns[i]->PostEvent(timestamp, period, vsyncCount);
999         VLOGD("Distributor name:%{public}s, connection name:%{public}s, ret:%{public}d",
1000             name_.c_str(), conns[i]->info_.name_.c_str(), ret);
1001         if (ret == 0 || ret == ERRNO_OTHER) {
1002             RemoveConnection(conns[i]);
1003         } else if (ret == ERRNO_EAGAIN) {
1004             std::unique_lock<std::mutex> locker(mutex_);
1005             // Trigger VSync Again for LTPO
1006             conns[i]->triggerThisTime_ = true;
1007 #if defined(RS_ENABLE_DVSYNC)
1008             if (isDvsyncThread) {
1009                 hasVsync_.store(true);
1010             }
1011 #endif
1012             // Exclude SetVSyncRate for LTPS
1013             if (conns[i]->rate_ < 0) {
1014                 conns[i]->rate_ = 0;
1015             }
1016         }
1017     }
1018 }
1019 
RequestNextVSync(const sptr<VSyncConnection> & connection,const std::string & fromWhom,int64_t lastVSyncTS)1020 VsyncError VSyncDistributor::RequestNextVSync(const sptr<VSyncConnection> &connection, const std::string &fromWhom,
1021                                               int64_t lastVSyncTS)
1022 {
1023     if (connection == nullptr) {
1024         VLOGE("connection is nullptr");
1025         return VSYNC_ERROR_NULLPTR;
1026     }
1027 
1028     RS_TRACE_NAME_FMT("%s_RequestNextVSync", connection->info_.name_.c_str());
1029     bool NeedPreexecute = false;
1030     int64_t timestamp = 0;
1031     int64_t period = 0;
1032     int64_t vsyncCount = 0;
1033     {
1034         std::unique_lock<std::mutex> locker(mutex_);
1035         auto it = find(connections_.begin(), connections_.end(), connection);
1036         if (it == connections_.end()) {
1037             VLOGE("connection is invalid arguments");
1038             return VSYNC_ERROR_INVALID_ARGUMENTS;
1039         }
1040         if (connection->rate_ < 0) {
1041             connection->rate_ = 0;
1042         }
1043         connection->triggerThisTime_ = true;
1044         EnableVSync();
1045         // Start of DVSync
1046         DVSyncRecordRNV(connection, fromWhom, lastVSyncTS);
1047         NeedPreexecute = DVSyncCheckPreexecuteAndUpdateTs(connection, timestamp, period, vsyncCount);
1048         lastNotifyTime_ = Now();
1049     }
1050     if (NeedPreexecute) {
1051         ConnPostEvent(connection, timestamp, period, vsyncCount);
1052     }
1053     // End of DVSync
1054     if (isFirstRequest_) {
1055         isFirstRequest_ = false;
1056         isFirstSend_ = true;
1057         VLOGI("First vsync RequestNextVSync conn:%{public}s, rate:%{public}d, highPriorityRate:%{public}d",
1058             connection->info_.name_.c_str(), connection->rate_, connection->highPriorityRate_);
1059     }
1060     VLOGD("conn name:%{public}s, rate:%{public}d", connection->info_.name_.c_str(), connection->rate_);
1061     return VSYNC_ERROR_OK;
1062 }
1063 
SetVSyncRate(int32_t rate,const sptr<VSyncConnection> & connection)1064 VsyncError VSyncDistributor::SetVSyncRate(int32_t rate, const sptr<VSyncConnection>& connection)
1065 {
1066     if (rate < -1 || connection == nullptr) {
1067         return VSYNC_ERROR_INVALID_ARGUMENTS;
1068     }
1069     std::lock_guard<std::mutex> locker(mutex_);
1070     auto it = find(connections_.begin(), connections_.end(), connection);
1071     if (it == connections_.end()) {
1072         return VSYNC_ERROR_INVALID_ARGUMENTS;
1073     }
1074     if (connection->rate_ == rate) {
1075         return VSYNC_ERROR_INVALID_ARGUMENTS;
1076     }
1077     connection->rate_ = rate;
1078     VLOGD("conn name:%{public}s", connection->info_.name_.c_str());
1079 #if defined(RS_ENABLE_DVSYNC)
1080     if (dvsync_->IsFeatureEnabled()) {
1081         con_.notify_all();
1082     } else
1083 #endif
1084     {
1085         EnableVSync();
1086     }
1087     return VSYNC_ERROR_OK;
1088 }
1089 
SetHighPriorityVSyncRate(int32_t highPriorityRate,const sptr<VSyncConnection> & connection)1090 VsyncError VSyncDistributor::SetHighPriorityVSyncRate(int32_t highPriorityRate, const sptr<VSyncConnection>& connection)
1091 {
1092     if (highPriorityRate <= 0 || connection == nullptr) {
1093         return VSYNC_ERROR_INVALID_ARGUMENTS;
1094     }
1095 
1096     std::lock_guard<std::mutex> locker(mutex_);
1097     auto it = find(connections_.begin(), connections_.end(), connection);
1098     if (it == connections_.end()) {
1099         return VSYNC_ERROR_INVALID_ARGUMENTS;
1100     }
1101     if (connection->highPriorityRate_ == highPriorityRate) {
1102         return VSYNC_ERROR_INVALID_ARGUMENTS;
1103     }
1104     connection->highPriorityRate_ = highPriorityRate;
1105     connection->highPriorityState_ = true;
1106     VLOGD("in, conn name:%{public}s, highPriorityRate:%{public}d", connection->info_.name_.c_str(),
1107           connection->highPriorityRate_);
1108 #if defined(RS_ENABLE_DVSYNC)
1109     if (dvsync_->IsFeatureEnabled()) {
1110         con_.notify_all();
1111     } else
1112 #endif
1113     {
1114         EnableVSync();
1115     }
1116     return VSYNC_ERROR_OK;
1117 }
1118 
QosGetPidByName(const std::string & name,uint32_t & pid)1119 VsyncError VSyncDistributor::QosGetPidByName(const std::string& name, uint32_t& pid)
1120 {
1121     if (name.find("WM") == std::string::npos) {
1122         return VSYNC_ERROR_INVALID_ARGUMENTS;
1123     }
1124     // exclude names like NWeb_WM or ArkWebCore_WM
1125     if ((name.find("NWeb") != std::string::npos) || (name.find("ArkWebCore") != std::string::npos)) {
1126         return VSYNC_ERROR_INVALID_ARGUMENTS;
1127     }
1128     std::string::size_type pos = name.find("_");
1129     if (pos == std::string::npos || (pos + 1) >= name.size()) {
1130         return VSYNC_ERROR_INVALID_ARGUMENTS;
1131     }
1132     pid = static_cast<uint32_t>(stoi(name.substr(pos + 1)));
1133     return VSYNC_ERROR_OK;
1134 }
1135 
SetQosVSyncRateByPid(uint32_t pid,int32_t rate,bool isSystemAnimateScene)1136 VsyncError VSyncDistributor::SetQosVSyncRateByPid(uint32_t pid, int32_t rate, bool isSystemAnimateScene)
1137 {
1138     // only set vsync rate by pid in SystemAnimateSecne
1139     if (!isSystemAnimateScene && rate != DEFAULT_VSYNC_RATE) {
1140         return VSYNC_ERROR_OK;
1141     }
1142     auto iter = connectionsMap_.find(pid);
1143     if (iter == connectionsMap_.end()) {
1144         VLOGD("%{public}s:%{public}d pid[%{public}u] can not found", __func__, __LINE__, pid);
1145         return VSYNC_ERROR_INVALID_ARGUMENTS;
1146     }
1147     bool isNeedNotify = false;
1148     for (auto connection : iter->second) {
1149         uint32_t tmpPid;
1150         if (QosGetPidByName(connection->info_.name_, tmpPid) != VSYNC_ERROR_OK || tmpPid != pid) {
1151             continue;
1152         }
1153         if (connection->highPriorityRate_ != rate) {
1154             connection->highPriorityRate_ = rate;
1155             connection->highPriorityState_ = true;
1156             VLOGD("in, conn name:%{public}s, highPriorityRate:%{public}d", connection->info_.name_.c_str(),
1157                 connection->highPriorityRate_);
1158             isNeedNotify = true;
1159         }
1160     }
1161 
1162     if (isNeedNotify) {
1163 #if defined(RS_ENABLE_DVSYNC)
1164         if (dvsync_->IsFeatureEnabled()) {
1165             con_.notify_all();
1166         } else
1167 #endif
1168         {
1169             EnableVSync();
1170         }
1171     }
1172 
1173     return VSYNC_ERROR_OK;
1174 }
1175 
SetQosVSyncRateByPidPublic(uint32_t pid,uint32_t rate,bool isSystemAnimateScene)1176 VsyncError VSyncDistributor::SetQosVSyncRateByPidPublic(uint32_t pid, uint32_t rate, bool isSystemAnimateScene)
1177 {
1178     std::vector<uint64_t> tmpVec = pidWindowIdMap_[pid];
1179     for (const auto& windowId : tmpVec) {
1180         VsyncError ret = SetQosVSyncRate(windowId, rate, isSystemAnimateScene);
1181         if (ret != VSYNC_ERROR_OK) {
1182             VLOGD("windowId:%{public}" PRUint " is not exit", windowId);
1183             return VSYNC_ERROR_INVALID_ARGUMENTS;
1184         }
1185     }
1186     return VSYNC_ERROR_OK;
1187 }
1188 
ExtractPid(uint64_t id)1189 constexpr pid_t VSyncDistributor::ExtractPid(uint64_t id)
1190 {
1191     constexpr uint32_t bits = 32u;
1192     return static_cast<pid_t>(id >> bits);
1193 }
1194 
GetSurfaceNodeLinkerIds(uint64_t windowNodeId)1195 std::vector<uint64_t> VSyncDistributor::GetSurfaceNodeLinkerIds(uint64_t windowNodeId)
1196 {
1197     std::lock_guard<std::mutex> locker(mutex_);
1198     auto iter = connectionsMap_.find(windowNodeId);
1199     if (iter == connectionsMap_.end()) {
1200         return {};
1201     }
1202 
1203     std::vector<uint64_t> connectionLinkerIds {};
1204     for (auto& connection : iter->second) {
1205         if (connection != nullptr) {
1206             connectionLinkerIds.push_back(connection->id_);
1207         }
1208     }
1209 
1210     return connectionLinkerIds;
1211 }
1212 
SetQosVSyncRate(uint64_t windowNodeId,int32_t rate,bool isSystemAnimateScene)1213 VsyncError VSyncDistributor::SetQosVSyncRate(uint64_t windowNodeId, int32_t rate, bool isSystemAnimateScene)
1214 {
1215     std::lock_guard<std::mutex> locker(mutex_);
1216     VsyncError resCode = SetQosVSyncRateByPid(ExtractPid(windowNodeId), rate, isSystemAnimateScene);
1217     auto iter = connectionsMap_.find(windowNodeId);
1218     if (iter == connectionsMap_.end()) {
1219         return resCode;
1220     }
1221     bool isNeedNotify = false;
1222     for (auto& connection : iter->second) {
1223         if (connection != nullptr && connection->highPriorityRate_ != rate) {
1224             connection->highPriorityRate_ = rate;
1225             connection->highPriorityState_ = true;
1226             VLOGD("in, conn name:%{public}s, highPriorityRate:%{public}d", connection->info_.name_.c_str(),
1227                 connection->highPriorityRate_);
1228             isNeedNotify = true;
1229         }
1230     }
1231     if (isNeedNotify) {
1232 #if defined(RS_ENABLE_DVSYNC)
1233         if (dvsync_->IsFeatureEnabled()) {
1234             con_.notify_all();
1235         } else
1236 #endif
1237         {
1238             EnableVSync();
1239         }
1240     }
1241     return VSYNC_ERROR_OK;
1242 }
1243 
ChangeConnsRateLocked(uint32_t vsyncMaxRefreshRate)1244 void VSyncDistributor::ChangeConnsRateLocked(uint32_t vsyncMaxRefreshRate)
1245 {
1246     std::lock_guard<std::mutex> locker(changingConnsRefreshRatesMtx_);
1247     for (auto conn : connections_) {
1248         auto it = changingConnsRefreshRates_.find(conn->id_);
1249         if (it == changingConnsRefreshRates_.end()) {
1250             continue;
1251         }
1252         uint32_t refreshRate = it->second;
1253         if ((generatorRefreshRate_ == 0) || (refreshRate == 0) ||
1254             (vsyncMaxRefreshRate % refreshRate != 0) || (generatorRefreshRate_ % refreshRate != 0)) {
1255             conn->refreshRate_ = 0;
1256             conn->vsyncPulseFreq_ = 1;
1257             continue;
1258         }
1259         conn->refreshRate_ = refreshRate;
1260         conn->vsyncPulseFreq_ = vsyncMaxRefreshRate / refreshRate;
1261         conn->referencePulseCount_ = event_.vsyncPulseCount;
1262     }
1263     changingConnsRefreshRates_.clear();
1264 }
1265 
1266 // Start of DVSync
DisableDVSyncController()1267 void VSyncDistributor::DisableDVSyncController()
1268 {
1269     if (dvsyncController_ != nullptr && dvsyncControllerEnabled_ == true) {
1270         dvsyncController_->SetEnable(false, dvsyncControllerEnabled_);
1271     }
1272 }
1273 
OnDVSyncEvent(int64_t now,int64_t period,uint32_t refreshRate,VSyncMode vsyncMode,uint32_t vsyncMaxRefreshRate)1274 void VSyncDistributor::OnDVSyncEvent(int64_t now, int64_t period,
1275     uint32_t refreshRate, VSyncMode vsyncMode, uint32_t vsyncMaxRefreshRate)
1276 {
1277 #if defined(RS_ENABLE_DVSYNC_2)
1278     int64_t dvsyncPeriod = DVSync::Instance().GetOccurPeriod();
1279     uint32_t dvsyncRefreshRate = DVSync::Instance().GetOccurRefreshRate();
1280     if (dvsyncPeriod != 0 && dvsyncRefreshRate != 0) {
1281         period = dvsyncPeriod;
1282         refreshRate = dvsyncRefreshRate;
1283     }
1284 
1285     std::vector<sptr<VSyncConnection>> conns;
1286     uint32_t generatorRefreshRate;
1287     int64_t vsyncCount;
1288     {
1289         bool waitForVsync = false;
1290         std::lock_guard<std::mutex> locker(mutex_);
1291         DVSync::Instance().RecordVSync(this, now, period, refreshRate, true);
1292         vsyncCount = DVSync::Instance().GetVsyncCount(event_.vsyncCount);
1293         if (refreshRate > 0) {
1294             event_.vsyncPulseCount += static_cast<int64_t>(vsyncMaxRefreshRate / refreshRate);
1295             generatorRefreshRate_ = refreshRate;
1296         }
1297         vsyncMode_ = vsyncMode;
1298         ChangeConnsRateLocked(vsyncMaxRefreshRate);
1299         // must ltpo mode
1300         for (uint32_t i = 0; i < connections_.size(); i++) {
1301             if (connections_[i] != DVSync::Instance().GetConnectionApp()) {
1302                 continue;
1303             }
1304             if (!connections_[i]->triggerThisTime_ && connections_[i]->rate_ <= 0) {
1305                 continue;
1306             }
1307             waitForVsync = true;
1308             if (now <= 0) {
1309                 break;
1310             }
1311             connections_[i]->triggerThisTime_ = false;
1312             if (connections_[i]->rate_ == 0) {
1313                 connections_[i]->rate_ = -1;
1314             }
1315             conns.push_back(connections_[i]);
1316         }
1317 
1318         if (!waitForVsync && !IsUiDvsyncOn()) {
1319             DisableDVSyncController();
1320             return;
1321         }
1322 
1323         countTraceValue_ = (countTraceValue_ + 1) % 2; // 2 : change num
1324         CountTrace(HITRACE_TAG_GRAPHIC_AGP, "vsync-" + name_, countTraceValue_);
1325 
1326         generatorRefreshRate = generatorRefreshRate_;
1327     }
1328     ConnectionsPostEvent(conns, now, period, generatorRefreshRate, vsyncCount, true);
1329 #endif
1330 }
1331 // End of DVSync
1332 
IsDVsyncOn()1333 bool VSyncDistributor::IsDVsyncOn()
1334 {
1335 #if defined(RS_ENABLE_DVSYNC)
1336     return dvsync_->IsEnabledAndOn();
1337 #else
1338     return false;
1339 #endif
1340 }
1341 
SetFrameIsRender(bool isRender)1342 void VSyncDistributor::SetFrameIsRender(bool isRender)
1343 {
1344 #if defined(RS_ENABLE_DVSYNC)
1345     std::unique_lock<std::mutex> locker(mutex_);
1346     ScopedBytrace trace("SetFrameIsRender:" + std::to_string(isRender));
1347     if (isRender) {
1348         dvsync_->UnMarkRSNotRendering();
1349     } else {
1350         dvsync_->MarkRSNotRendering();
1351     }
1352 #endif
1353 #if defined(RS_ENABLE_DVSYNC_2)
1354     ScopedBytrace trace("SetFrameIsRender:" + std::to_string(isRender));
1355     DVSync::Instance().MarkRSRendering(isRender);
1356 #endif
1357 }
1358 
MarkRSAnimate()1359 void VSyncDistributor::MarkRSAnimate()
1360 {
1361 #if defined(RS_ENABLE_DVSYNC)
1362     dvsync_->MarkRSAnimate();
1363 #endif
1364 }
1365 
UnmarkRSAnimate()1366 void VSyncDistributor::UnmarkRSAnimate()
1367 {
1368 #if defined(RS_ENABLE_DVSYNC)
1369     dvsync_->UnmarkRSAnimate();
1370 #endif
1371 }
1372 
HasPendingUIRNV()1373 bool VSyncDistributor::HasPendingUIRNV()
1374 {
1375 #if defined(RS_ENABLE_DVSYNC)
1376     return dvsync_->HasPendingUIRNV();
1377 #else
1378     return false;
1379 #endif
1380 }
1381 
SetUiDvsyncSwitch(bool dvsyncSwitch,const sptr<VSyncConnection> & connection)1382 VsyncError VSyncDistributor::SetUiDvsyncSwitch(bool dvsyncSwitch, const sptr<VSyncConnection> &connection)
1383 {
1384 #if defined(RS_ENABLE_DVSYNC)
1385     std::lock_guard<std::mutex> locker(mutex_);
1386     dvsync_->RuntimeMark(connection, dvsyncSwitch);
1387 #endif
1388 #if defined(RS_ENABLE_DVSYNC_2)
1389     DVSync::Instance().SetAppDVSyncSwitch(connection, dvsyncSwitch, false);
1390 #endif
1391     return VSYNC_ERROR_OK;
1392 }
1393 
SetUiDvsyncConfig(int32_t bufferCount)1394 VsyncError VSyncDistributor::SetUiDvsyncConfig(int32_t bufferCount)
1395 {
1396 #if defined(RS_ENABLE_DVSYNC)
1397     std::lock_guard<std::mutex> locker(mutex_);
1398     dvsync_->SetUiDvsyncConfig(bufferCount);
1399 #endif
1400 #if defined(RS_ENABLE_DVSYNC_2)
1401     DVSync::Instance().SetUiDVSyncConfig(bufferCount);
1402 #endif
1403     return VSYNC_ERROR_OK;
1404 }
1405 
SetNativeDVSyncSwitch(bool dvsyncSwitch,const sptr<VSyncConnection> & connection)1406 VsyncError VSyncDistributor::SetNativeDVSyncSwitch(bool dvsyncSwitch, const sptr<VSyncConnection> &connection)
1407 {
1408 #if defined(RS_ENABLE_DVSYNC)
1409     std::lock_guard<std::mutex> locker(mutex_);
1410     dvsync_->RuntimeMark(connection, dvsyncSwitch, true);
1411 #endif
1412 #if defined(RS_ENABLE_DVSYNC_2)
1413     DVSync::Instance().SetAppDVSyncSwitch(connection, dvsyncSwitch, true);
1414 #endif
1415     return VSYNC_ERROR_OK;
1416 }
1417 
GetRefreshRate()1418 uint32_t VSyncDistributor::GetRefreshRate()
1419 {
1420 #if defined(RS_ENABLE_DVSYNC)
1421     std::lock_guard<std::mutex> locker(mutex_);
1422     return dvsync_->GetRefreshRate();
1423 #else
1424     return generatorRefreshRate_;
1425 #endif
1426 }
1427 
RecordVsyncModeChange(uint32_t refreshRate,int64_t period)1428 void VSyncDistributor::RecordVsyncModeChange(uint32_t refreshRate, int64_t period)
1429 {
1430 #if defined(RS_ENABLE_DVSYNC)
1431     std::lock_guard<std::mutex> locker(mutex_);
1432     dvsync_->RecordVsyncModeChange(refreshRate, period);
1433 #endif
1434 }
1435 
IsUiDvsyncOn()1436 bool  VSyncDistributor::IsUiDvsyncOn()
1437 {
1438 #if defined(RS_ENABLE_DVSYNC)
1439     return dvsync_->IsUiDvsyncOn();
1440 #elif defined(RS_ENABLE_DVSYNC_2)
1441     return DVSync::Instance().IsAppDVSyncOn();
1442 #else
1443     return false;
1444 #endif
1445 }
GetUiCommandDelayTime()1446 int64_t VSyncDistributor::GetUiCommandDelayTime()
1447 {
1448 #if defined(RS_ENABLE_DVSYNC)
1449     return dvsync_->GetUiCommandDelayTime();
1450 #elif defined(RS_ENABLE_DVSYNC_2)
1451     return DVSync::Instance().GetUiCommandDelayTime();
1452 #else
1453     return 0;
1454 #endif
1455 }
1456 
UpdatePendingReferenceTime(int64_t & timeStamp)1457 void VSyncDistributor::UpdatePendingReferenceTime(int64_t &timeStamp)
1458 {
1459 #if defined(RS_ENABLE_DVSYNC)
1460     if (IsDVsyncOn()) {
1461         dvsync_->UpdatePendingReferenceTime(timeStamp);
1462     }
1463 #endif
1464 #if defined(RS_ENABLE_DVSYNC_2)
1465     DVSync::Instance().UpdatePendingReferenceTime(timeStamp);
1466 #endif
1467 }
1468 
GetRealTimeOffsetOfDvsync(int64_t time)1469 uint64_t VSyncDistributor::GetRealTimeOffsetOfDvsync(int64_t time)
1470 {
1471 #if defined(RS_ENABLE_DVSYNC)
1472     if (IsDVsyncOn()) {
1473         return dvsync_->GetRealTimeOffsetOfDvsync(time);
1474     }
1475 #elif defined(RS_ENABLE_DVSYNC_2)
1476     return DVSync::Instance().GetRealTimeOffsetOfDvsync(time);
1477 #else
1478     return 0;
1479 #endif
1480 }
1481 
SetHardwareTaskNum(uint32_t num)1482 void VSyncDistributor::SetHardwareTaskNum(uint32_t num)
1483 {
1484 #if defined(RS_ENABLE_DVSYNC)
1485     if (IsDVsyncOn()) {
1486         dvsync_->SetHardwareTaskNum(num);
1487     }
1488 #endif
1489 #if defined(RS_ENABLE_DVSYNC_2)
1490     DVSync::Instance().SetHardwareTaskNum(num);
1491 #endif
1492 }
1493 
GetVsyncCount()1494 int64_t VSyncDistributor::GetVsyncCount()
1495 {
1496     std::unique_lock<std::mutex> locker(mutex_);
1497     return event_.vsyncCount;
1498 }
1499 
SetHasNativeBuffer()1500 void VSyncDistributor::SetHasNativeBuffer()
1501 {
1502 #if defined(RS_ENABLE_DVSYNC)
1503     std::unique_lock<std::mutex> locker(mutex_);
1504     dvsync_->SetHasNativeBuffer();
1505 #endif
1506 }
1507 
InitDVSync(DVSyncFeatureParam dvsyncParam)1508 void VSyncDistributor::InitDVSync(DVSyncFeatureParam dvsyncParam)
1509 {
1510 #if defined(RS_ENABLE_DVSYNC_2)
1511     DVSync::Instance().InitWithParam(dvsyncParam);
1512     bool IsEnable = DVSync::Instance().SetDistributor(isRs_, this);
1513     if (IsEnable && isRs_ == false) {
1514         auto generator = CreateVSyncGenerator();
1515         dvsyncController_ = new DVSyncController(generator, 0);
1516     }
1517 #endif
1518 }
1519 
DVSyncAddConnection(const sptr<VSyncConnection> & connection)1520 void VSyncDistributor::DVSyncAddConnection(const sptr<VSyncConnection> &connection)
1521 {
1522 #if defined(RS_ENABLE_DVSYNC_2)
1523     DVSync::Instance().SetConnection(isRs_, connection);
1524 #endif
1525 }
1526 
DVSyncDisableVSync()1527 void VSyncDistributor::DVSyncDisableVSync()
1528 {
1529 #if defined(RS_ENABLE_DVSYNC_2)
1530     DVSync::Instance().DisableVSync(this);
1531 #endif
1532 }
1533 
DVSyncRecordVSync(int64_t now,int64_t period,uint32_t refreshRate,bool isDvsyncController)1534 void VSyncDistributor::DVSyncRecordVSync(int64_t now, int64_t period, uint32_t refreshRate, bool isDvsyncController)
1535 {
1536 #if defined(RS_ENABLE_DVSYNC_2)
1537     DVSync::Instance().RecordVSync(this, now, period, refreshRate, false);
1538 #endif
1539 }
1540 
DVSyncCheckSkipAndUpdateTs(const sptr<VSyncConnection> & connection,int64_t & timeStamp)1541 bool VSyncDistributor::DVSyncCheckSkipAndUpdateTs(const sptr<VSyncConnection> &connection, int64_t &timeStamp)
1542 {
1543 #if defined(RS_ENABLE_DVSYNC_2)
1544     return DVSync::Instance().NeedSkipAndUpdateTs(connection, timeStamp);
1545 #else
1546     return false;
1547 #endif
1548 }
1549 
DVSyncNeedSkipUi(const sptr<VSyncConnection> & connection)1550 bool VSyncDistributor::DVSyncNeedSkipUi(const sptr<VSyncConnection> &connection)
1551 {
1552 #if defined(RS_ENABLE_DVSYNC_2)
1553     return DVSync::Instance().NeedSkipUi(connection);
1554 #else
1555     return false;
1556 #endif
1557 }
1558 
RecordEnableVsync()1559 void VSyncDistributor::RecordEnableVsync()
1560 {
1561 #if defined(RS_ENABLE_DVSYNC_2)
1562     DVSync::Instance().RecordEnableVsync(this);
1563 #endif
1564 }
1565 
DVSyncRecordRNV(const sptr<VSyncConnection> & connection,const std::string & fromWhom,int64_t lastVSyncTS)1566 void VSyncDistributor::DVSyncRecordRNV(const sptr<VSyncConnection> &connection, const std::string &fromWhom,
1567     int64_t lastVSyncTS)
1568 {
1569 #if defined(RS_ENABLE_DVSYNC_2)
1570     DVSync::Instance().RecordRNV(connection, fromWhom, vsyncMode_, lastVSyncTS);
1571 #endif
1572 }
1573 
DVSyncCheckPreexecuteAndUpdateTs(const sptr<VSyncConnection> & connection,int64_t & timestamp,int64_t & period,int64_t & vsyncCount)1574 bool VSyncDistributor::DVSyncCheckPreexecuteAndUpdateTs(const sptr<VSyncConnection> &connection, int64_t &timestamp,
1575     int64_t &period, int64_t &vsyncCount)
1576 {
1577 #if defined(RS_ENABLE_DVSYNC_2)
1578     bool NeedPreexecute = DVSync::Instance().NeedPreexecuteAndUpdateTs(connection, timestamp, period);
1579     if (NeedPreexecute) {
1580         RS_TRACE_NAME_FMT("DVSync::DVSyncCheckPreexecuteAndUpdateTs timestamp:%ld, period:%ld", timestamp, period);
1581         event_.vsyncCount++;
1582         vsyncCount = event_.vsyncCount;
1583         if (connection->rate_ == 0) {
1584             connection->rate_ = -1;
1585         }
1586         connection->triggerThisTime_ = false;
1587     }
1588     return NeedPreexecute;
1589 #else
1590     return false;
1591 #endif
1592 }
1593 
NotifyPackageEvent(const std::vector<std::string> & packageList)1594 void VSyncDistributor::NotifyPackageEvent(const std::vector<std::string>& packageList)
1595 {
1596 #if defined(RS_ENABLE_DVSYNC_2)
1597     DVSync::Instance().NotifyPackageEvent(packageList);
1598 #endif
1599 }
1600 
NotifyTouchEvent(int32_t touchStatus,int32_t touchCnt)1601 void VSyncDistributor::NotifyTouchEvent(int32_t touchStatus, int32_t touchCnt)
1602 {
1603 #if defined(RS_ENABLE_DVSYNC_2)
1604     DVSync::Instance().NotifyTouchEvent(touchStatus, touchCnt);
1605 #endif
1606 }
1607 
AdaptiveDVSyncEnable(const std::string & nodeName,int64_t timeStamp,int32_t bufferCount,bool & needConsume)1608 bool VSyncDistributor::AdaptiveDVSyncEnable(const std::string &nodeName, int64_t timeStamp, int32_t bufferCount,
1609     bool &needConsume)
1610 {
1611 #if defined(RS_ENABLE_DVSYNC_2)
1612     return DVSync::Instance().AdaptiveDVSyncEnable(nodeName, timeStamp, bufferCount, needConsume);
1613 #else
1614     return false;
1615 #endif
1616 }
1617 
SetBufferInfo(uint64_t id,const std::string & name,uint32_t queueSize,int32_t bufferCount,int64_t lastConsumeTime)1618 void VSyncDistributor::SetBufferInfo(uint64_t id, const std::string &name, uint32_t queueSize,
1619     int32_t bufferCount, int64_t lastConsumeTime)
1620 {
1621 #if defined(RS_ENABLE_DVSYNC_2)
1622     DVSync::Instance().SetBufferInfo(id, name, queueSize, bufferCount, lastConsumeTime);
1623 #endif
1624 }
1625 
PrintConnectionsStatus()1626 void VSyncDistributor::PrintConnectionsStatus()
1627 {
1628     std::unique_lock<std::mutex> locker(mutex_);
1629     for (uint32_t i = 0; i < connections_.size(); i++) {
1630         VLOGW("[Info]PrintConnectionsStatus, i:%{public}d, name:%{public}s, proxyPid:%{public}d"
1631             ", highPriorityRate:%{public}d, rate:%{public}d, vsyncPulseFreq:%{public}u",
1632             i, connections_[i]->info_.name_.c_str(), connections_[i]->proxyPid_, connections_[i]->highPriorityRate_,
1633             connections_[i]->rate_, connections_[i]->vsyncPulseFreq_);
1634     }
1635     VLOGW("[Info]PrintVSyncInfo, beforeWaitRnvTime %{public}" PRId64 " afterWaitRnvTime %{public}" PRId64
1636         " lastNotifyTime %{public}" PRId64 " beforePostEvent %{public}" PRId64 " startPostEvent %{public}" PRId64,
1637         beforeWaitRnvTime_, afterWaitRnvTime_, lastNotifyTime_, beforePostEvent_.load(), startPostEvent_.load());
1638 #if defined(RS_ENABLE_DVSYNC)
1639     VLOGW("[Info]DVSync featureEnable %{public}d on %{public}d needDVSyncRnv %{public}d, needDVSyncTrigger %{public}d",
1640         dvsync_->IsFeatureEnabled(), IsDVsyncOn(), dvsync_->NeedDVSyncRNV(), dvsync_->NeedDVSyncTrigger());
1641 #endif
1642 }
1643 
FirstRequestVsync()1644 void VSyncDistributor::FirstRequestVsync()
1645 {
1646     std::unique_lock<std::mutex> locker(mutex_);
1647     isFirstRequest_ = true;
1648 }
1649 }
1650 }
1651