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