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, ¶m);
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 ×tamp,
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 ×tamp, 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 ×tamp,
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 ×tamp,
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