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