hi,粉絲朋友們:
本節(jié)將使用perfetto的trace來鞏固Vsync的源碼分析的部分的流程。
具體抓取trace方法及相關(guān)操作建議:
a.抓取trace期間需要主要不能讓畫面一直刷新,因?yàn)檫@樣一直刷新不方便看vsync的結(jié)束和開始
b.建議選著桌面,滑動(dòng)桌面一下后停止1左右,再繼續(xù)滑動(dòng),盡量讓抓取的trace可以有如下圖的間隔效果
c.需要在surfaceflinger中額外補(bǔ)充自己加的一些ATRACE代碼方便追蹤流程

1、app請求Vsync部分
這里我們回憶一下app的Vsync的申請,一般都是app主動(dòng)申請的,一般都是應(yīng)用端
Choreographer#scheduleVsyncLocked方法跨進(jìn)程調(diào)用到Surfaceflinger端的requestNextVsync方法,具體trace如下圖

surfaceflinger作為服務(wù)端如下:

所有的Vsync邏輯其實(shí)就是從SurfaceFlinger的requestNextVsync方法開始的:
binder::Status EventThreadConnection::requestNextVsync() {
ATRACE_CALL();
//這里加個(gè)ATRACE標(biāo)準(zhǔn)方便確定是app申請還是appSf申請的Vsync
ATRACE_BEGIN(((impl::EventThread*)mEventThread)->toNameString());
mEventThread->requestNextVsync(this);
ATRACE_END();
return binder::Status::ok();
}
調(diào)用到了 mEventThread->requestNextVsync(this);
代碼如下
void EventThread::requestNextVsync(const sp<EventThreadConnection>& connection) {
ATRACE_NAME("EventThread::requestNextVsync");
if (connection->resyncCallback) {
connection->resyncCallback();
}
std::lock_guard<std::mutex> lock(mMutex);
if (connection->vsyncRequest == VSyncRequest::None) { //如果這個(gè)是第一次申請進(jìn)入一般這里就是None
connection->vsyncRequest = VSyncRequest::Single;
ATRACE_NAME("connection->vsyncRequest None notify_all");
mCondition.notify_all();//第一次則會(huì)通過mCondition喚醒等待
} else if (connection->vsyncRequest == VSyncRequest::SingleSuppressCallback) { //這里代表前一次剛剛已經(jīng)進(jìn)入vsync,準(zhǔn)備進(jìn)入停止回調(diào)狀態(tài)
ATRACE_NAME("connection->vsyncRequest SingleSuppressCallback ");
connection->vsyncRequest = VSyncRequest::Single; //這里不需要喚醒,代表thread運(yùn)行等待vsync,需要靠vsync時(shí)間到了才喚醒
}
}
這里都會(huì)吧vsyncRequest變變成Single,最重要mCondition.notify_all()會(huì)喚醒一直等待的EventThread的線程,讓他繼續(xù)執(zhí)行:
這里喚醒也可以通過perfetto看出來:

對于的代碼:
void EventThread::threadMain(std::unique_lock<std::mutex>& lock) {
DisplayEventConsumers consumers;
while (mState != State::Quit) {
if (!mPendingEvents.empty()) {//檢測是否有mPendingEvent,遍歷各個(gè)Event,
event = mPendingEvents.front();
mPendingEvents.pop_front();
switch (event->header.type) {
case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG:
if (event->hotplug.connected && !mVSyncState) {
mVSyncState.emplace(event->header.displayId);
} else if (!event->hotplug.connected && mVSyncState &&
mVSyncState->displayId == event->header.displayId) {
mVSyncState.reset();
}
break;
case DisplayEventReceiver::DISPLAY_EVENT_VSYNC:
if (mInterceptVSyncsCallback) {
mInterceptVSyncsCallback(event->header.timestamp);
}
break;
}
}
bool vsyncRequested = false;//初始化為false
// Find connections that should consume this event.
auto it = mDisplayEventConnections.begin();
while (it != mDisplayEventConnections.end()) {//遍歷一下所有的connection,和EventTread綁定的app鏈接
if (const auto connection = it->promote()) {
vsyncRequested |= connection->vsyncRequest != VSyncRequest::None;//這里會(huì)檢測一下是前面設(shè)置過的request是不是還是None,明顯前面設(shè)置成了Single
if (event && shouldConsumeEvent(*event, connection)) {//這里會(huì)判斷當(dāng)前event是否要讓這個(gè)connection消費(fèi)
consumers.push_back(connection);
ATRACE_FORMAT("shouldConsumeEvent consumers push %s",toString(*connection).c_str());
}
++it;
} else {
it = mDisplayEventConnections.erase(it);
}
}
if (!consumers.empty()) {//進(jìn)行相關(guān)的事件派發(fā)
dispatchEvent(*event, consumers);
consumers.clear();
}
ATRACE_FORMAT("vsyncRequested = %d",vsyncRequested);
State nextState;
//設(shè)置下一個(gè)nextstate,這里注意nextstate很關(guān)鍵,如果沒有vsyncRequested,那么就nextstate就一定為Idle
if (mVSyncState && vsyncRequested) {
nextState = mVSyncState->synthetic ? State::SyntheticVSync : State::VSync;
} else {
ALOGW_IF(!mVSyncState, "Ignoring VSYNC request while display is disconnected");
nextState = State::Idle;
}
//nextState和當(dāng)前state進(jìn)行比較不相等進(jìn)入
if (mState != nextState) {
if (mState == State::VSync) {//如果當(dāng)前是vsync,那么nextState不是Vsync了說明vsync要停止
ATRACE_NAME("mVSyncSource->setVSyncEnabled(false)");
mVSyncSource->setVSyncEnabled(false);
} else if (nextState == State::VSync) {//mState當(dāng)前不是Vsync,下一個(gè)state是Vsync,就會(huì)進(jìn)入以下關(guān)鍵方法
ATRACE_NAME("mVSyncSource->setVSyncEnabled(true)");
mVSyncSource->setVSyncEnabled(true);//調(diào)用啟動(dòng)vsync相關(guān)
}
//上面操作完成就代表狀態(tài)已經(jīng)切換
mState = nextState;
}
if (event) {//如果有event不會(huì)進(jìn)入下面的wait而是會(huì)繼續(xù)從頭開始執(zhí)行
continue;
}
// Wait for event or client registration/request.
if (mState == State::Idle) {
mCondition.wait(lock);//開始長時(shí)間沒有vsync申請,就在這等待,第一次app申請時(shí)候就會(huì)喚醒這里
} else {
// Generate a fake VSYNC after a long timeout in case the driver stalls. When the
// display is off, keep feeding clients at 60 Hz.
const std::chrono::nanoseconds timeout =
mState == State::SyntheticVSync ? 16ms : 1000ms;
//進(jìn)行超時(shí)等待
if (mCondition.wait_for(lock, timeout) == std::cv_status::timeout) {
//省略
}
}
}
}
EventThread的執(zhí)行情況如下:

這里發(fā)現(xiàn)主要業(yè)務(wù)在 mVSyncSource->setVSyncEnabled(true)代碼中,這里面開啟了一系列的vsync計(jì)算和定時(shí)任務(wù)
大概上面可以看出調(diào)用棧如下:
VSyncSource->setVSyncEnabled(true)
----》 VSyncDispatchTimerQueue::schedule
----------》rearmTimerSkippingUpdateFor
--------------》setTimer
這樣就完成了設(shè)置定時(shí)觸發(fā)操作,具體這里不進(jìn)行詳細(xì)講述定時(shí)這部分,因?yàn)檩^為復(fù)雜需要單獨(dú)章節(jié),這里大家只要知道最后獲取了自己app的vsync觸發(fā)時(shí)間targetTime,定時(shí)器設(shè)置了到時(shí)間就觸發(fā),回調(diào)相關(guān)的timeCallback方法。
到此就EventThread就執(zhí)行到了等待定時(shí)等待狀態(tài),等待定時(shí)時(shí)間的到來。
2、Vsync時(shí)間到了后觸發(fā)timeCallback
上面步驟的定時(shí)器觸發(fā)后,回調(diào)執(zhí)行是在單獨(dú)的TimerDispatch線程,具體trace的體現(xiàn)如下:

來看看timeCallback里面又干啥了,代碼如下:
void VSyncDispatchTimerQueue::timerCallback() {
ATRACE_CALL();
std::vector<Invocation> invocations;
{
//遍歷3個(gè)vsync,app,sf,appSf
for (auto it = mCallbacks.begin(); it != mCallbacks.end(); it++) {
auto& callback = it->second;
auto const wakeupTime = callback->wakeupTime();
if (!wakeupTime) {//如果沒有wakupTime直接下一個(gè),因?yàn)閴焊鶝]有vsync的任何申請蹤跡
continue;
}
auto const readyTime = callback->readyTime();
auto const lagAllowance = std::max(now - mIntendedWakeupTime, static_cast<nsecs_t>(0));
//判斷的wakeupTime是不是比(mIntendedWakeupTime + mTimerSlack + lagAllowance)小,正常第一app請求肯定會(huì)進(jìn)入這里
if (*wakeupTime < mIntendedWakeupTime + mTimerSlack + lagAllowance) {
callback->executing();
invocations.emplace_back(Invocation{callback, *callback->lastExecutedVsyncTarget(),
*wakeupTime, *readyTime});
}
}
mIntendedWakeupTime = kInvalidTime;//設(shè)置一個(gè)無窮大的值
rearmTimer(mTimeKeeper->now());//重新準(zhǔn)備設(shè)置定時(shí)器
}
for (auto const& invocation : invocations) {//開始回調(diào)上面獲取的callback
invocation.callback->callback(invocation.vsyncTimestamp, invocation.wakeupTimestamp,
invocation.deadlineTimestamp);
}
}

主要干的幾件事如下:
1、遍歷3個(gè)類型vsync看看誰是有定時(shí)任務(wù)的,比較wakeupTime和intentedTime符合回調(diào)情況
2、符合回調(diào)情況的,會(huì)調(diào)用executing清除定時(shí)器,和wakeupTime,并吧intentedTime設(shè)置成很大數(shù)字
3、繼續(xù)下一個(gè)rearmTimer定時(shí)任務(wù)
4、回調(diào)相關(guān)類型vsync,vsync到來
上面四個(gè)任務(wù)就是TimeDispatch完成的。
這里要注意一下mCallbacks這個(gè)變量哪來的,是怎么對應(yīng)剛好就是app,appSf,sf,3個(gè)vsync的呢?
mCallbacks都是通過這個(gè)方法register來注冊的:
VSyncDispatchTimerQueue::CallbackToken VSyncDispatchTimerQueue::registerCallback(
Callback callback, std::string callbackName) {
std::lock_guard lock(mMutex);
return CallbackToken{
mCallbacks
.emplace(++mCallbackToken,//這里構(gòu)造出來了VSyncDispatchTimerQueueEntry的實(shí)體
std::make_shared<VSyncDispatchTimerQueueEntry>(std::move(callbackName),
std::move(callback),
mMinVsyncDistance))
.first->first};
}
那么什么地方調(diào)用注冊呢?實(shí)在構(gòu)造VSyncCallbackRegistration時(shí)候
VSyncCallbackRegistration::VSyncCallbackRegistration(VSyncDispatch& dispatch,
VSyncDispatch::Callback callback,
std::string callbackName)
: mDispatch(dispatch),
//給mToken賦值時(shí)候,直接調(diào)用的注冊callback返回的token
mToken(dispatch.registerCallback(std::move(callback), std::move(callbackName))),
mValidToken(true) {}
那么這個(gè)VSyncCallbackRegistration是在什么時(shí)候構(gòu)造的呢?
對于sf是在MessageQueue中進(jìn)行的:
void MessageQueue::initVsync(scheduler::VSyncDispatch& dispatch,
frametimeline::TokenManager& tokenManager,
std::chrono::nanoseconds workDuration) {
setDuration(workDuration);
mVsync.tokenManager = &tokenManager;
//構(gòu)造VSyncCallbackRegistration
mVsync.registration = std::make_unique<
scheduler::VSyncCallbackRegistration>(dispatch,
std::bind(&MessageQueue::vsyncCallback, this,
std::placeholders::_1,
std::placeholders::_2,
std::placeholders::_3),
"sf");
}
對于EventThread如下代碼進(jìn)行的:
CallbackRepeater(VSyncDispatch& dispatch, VSyncDispatch::Callback cb, const char* name,
std::chrono::nanoseconds workDuration, std::chrono::nanoseconds readyDuration,
std::chrono::nanoseconds notBefore)
: mName(name),
mCallback(cb),
//構(gòu)造VSyncCallbackRegistration
mRegistration(dispatch,
std::bind(&CallbackRepeater::callback, this, std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3),
mName),
mStarted(false),
mWorkDuration(workDuration),
mReadyDuration(readyDuration),
mLastCallTime(notBefore) {}
那么上面就知曉各自的callback在哪里了。
接下來這里重點(diǎn)關(guān)注一下回調(diào)vsync部分的任務(wù),app類型的vsync回調(diào)任務(wù)代碼如下:
frameworks/native/services/surfaceflinger/Scheduler/DispSyncSource.cpp的CallbackRepeater的callback方法:
void callback(nsecs_t vsyncTime, nsecs_t wakeupTime, nsecs_t readyTime) {
ATRACE_CALL();
//調(diào)用mCallback方法,其實(shí)就是DispSyncSource::onVsyncCallback
mCallback(vsyncTime, wakeupTime, readyTime);
{
std::lock_guard lock(mMutex);
if (!mStarted) {//注意一下這個(gè)值哈,和前面的EventThread的中有停止Vsync有關(guān)系
ATRACE_NAME("callback return not mRegistration.schedule");
return;
}
auto const scheduleResult =
mRegistration.schedule({.workDuration = mWorkDuration.count(),
.readyDuration = mReadyDuration.count(),
.earliestVsync = vsyncTime});
LOG_ALWAYS_FATAL_IF(!scheduleResult.has_value(), "Error rescheduling callback");
}
}
這里的mCallback在哪里賦值的呢?
DispSyncSource::DispSyncSource(VSyncDispatch& vSyncDispatch, VSyncTracker& vSyncTracker,
std::chrono::nanoseconds workDuration,
std::chrono::nanoseconds readyDuration, bool traceVsync,
const char* name)
: mName(name),
mValue(base::StringPrintf("VSYNC-%s", name), 0),
mTraceVsync(traceVsync),
mVsyncOnLabel(base::StringPrintf("VsyncOn-%s", name)),
mVSyncTracker(vSyncTracker),
mWorkDuration(base::StringPrintf("VsyncWorkDuration-%s", name), workDuration),
mReadyDuration(readyDuration) {
//這里進(jìn)行了關(guān)鍵的DispSyncSource::onVsyncCallback傳遞到CallbackRepeater對象
mCallbackRepeater =
std::make_unique<CallbackRepeater>(vSyncDispatch,
std::bind(&DispSyncSource::onVsyncCallback, this,
std::placeholders::_1,
std::placeholders::_2,
std::placeholders::_3),
name, workDuration, readyDuration,
std::chrono::steady_clock::now().time_since_epoch());
}
//這里的第二個(gè)參數(shù)就是VSyncDispatch::Callback
CallbackRepeater(VSyncDispatch& dispatch, VSyncDispatch::Callback cb, const char* name,
std::chrono::nanoseconds workDuration, std::chrono::nanoseconds readyDuration,
std::chrono::nanoseconds notBefore)
: mName(name),
mCallback(cb),
mRegistration(dispatch,
std::bind(&CallbackRepeater::callback, this, std::placeholders::_1,
std::placeholders::_2, std::placeholders::_3),
mName),
mStarted(false),
mWorkDuration(workDuration),
mReadyDuration(readyDuration),
mLastCallTime(notBefore) {}
重點(diǎn)看看 DispSyncSource::onVsyncCallback方法:
void DispSyncSource::onVsyncCallback(nsecs_t vsyncTime, nsecs_t targetWakeupTime,
nsecs_t readyTime) {
ATRACE_CALL();
VSyncSource::Callback* callback;
{
std::lock_guard lock(mCallbackMutex);
callback = mCallback;
}
if (mTraceVsync) {
mValue = (mValue + 1) % 2; //這里就是前面講解的vsync的方波圖展示部分靠這里
}
if (callback != nullptr) {//這里關(guān)鍵一步會(huì)調(diào)用到EventTread中
callback->onVSyncEvent(targetWakeupTime, {vsyncTime, readyTime});
}
}
void EventThread::onVSyncEvent(nsecs_t timestamp, VSyncSource::VSyncData vsyncData) {
std::lock_guard<std::mutex> lock(mMutex);
//注意這里進(jìn)行了PendingEvents的插入
mPendingEvents.push_back(makeVSync(mVSyncState->displayId, timestamp, ++mVSyncState->count,
vsyncData.expectedPresentationTime,
vsyncData.deadlineTimestamp));
mCondition.notify_all();//進(jìn)行線程喚醒,又切換回了EventThread工作了
}

但是這里喚醒App的EventThread后trace中沒看到具體干啥活,因?yàn)槲覀儧]有加相關(guān)ATRACE,加上一下相關(guān)TRACE如下:

明顯看到這里其實(shí)就是開始派發(fā)Vsync相關(guān)的Event到app端。
callback這里除了onVsyncCallback之外,下一步就是執(zhí)行新的一次schedule進(jìn)行相關(guān)的定時(shí)觸發(fā)Vsync任務(wù)。
代碼就是上面callback方法的
auto const scheduleResult =
mRegistration.schedule({.workDuration = mWorkDuration.count(),
.readyDuration = mReadyDuration.count(),
.earliestVsync = vsyncTime});
這里面又回到最開的是設(shè)置定時(shí)器任務(wù)了,啟動(dòng)下一個(gè)vsync的定時(shí),這里其實(shí)就可以知道,也就是app發(fā)起第一次的vsync請求,一般都會(huì)有兩個(gè)vsync定時(shí)任務(wù)哈。
3、app的vsync繼續(xù)請求和sf的vsync申請
針對上面分析的已經(jīng)知道了第一次的app請求vsync情況,但是一般app都是會(huì)很多次的vsync連續(xù)請求,因?yàn)楸容^少見就一次刷新情況。那么看看產(chǎn)生連續(xù)的vsync請求會(huì)是什么樣。

明顯看到第二次的requestVsync就和 第一次不一樣了,這個(gè)時(shí)候的并沒有喚醒a(bǔ)pp的EventThread線程。因?yàn)榍懊娲a就說了這個(gè)情況
void EventThread::requestNextVsync(const sp<EventThreadConnection>& connection) {
if (connection->vsyncRequest == VSyncRequest::None) { //如果這個(gè)是第一次申請進(jìn)入一般這里就是None
connection->vsyncRequest = VSyncRequest::Single;
ATRACE_NAME("connection->vsyncRequest None notify_all");
mCondition.notify_all();//第一次則會(huì)通過mCondition喚醒等待
} else if (connection->vsyncRequest == VSyncRequest::SingleSuppressCallback) { //這里代表前一次剛剛已經(jīng)進(jìn)入vsync,準(zhǔn)備進(jìn)入停止回調(diào)狀態(tài)
ATRACE_NAME("connection->vsyncRequest SingleSuppressCallback ");
connection->vsyncRequest = VSyncRequest::Single; //這里不需要喚醒,代表thread運(yùn)行等待vsync,需要靠vsync時(shí)間到了才喚醒
}
}
也就是一旦Vsync的定時(shí)器啟動(dòng)后,EventThread的線程就會(huì)阻塞,知道定時(shí)器時(shí)間到了才會(huì)繼續(xù)執(zhí)行,后面的app的requestVsync根本不會(huì)喚醒。
那么他的喚醒靠誰呢?當(dāng)然是靠第一次timeCallback時(shí)候的定時(shí)器觸發(fā)啦

那么app的vsync就是這樣循環(huán)只要不斷有app的requestVsync,那么SurfaceFlinger的Vsync呢?
首先我們得知道sf的vsync也是由app層面進(jìn)行queuebuffer后,通過跨進(jìn)程setTransactionState方法調(diào)用到SurfaceFlinger端,SurfaceFlinger端會(huì)檢測transation是否有相關(guān)的變化,有變化則觸發(fā)申請vsync信號:
void SurfaceFlinger::setTransactionFlags(uint32_t mask, TransactionSchedule schedule,
const sp<IBinder>& applyToken, FrameHint frameHint) {
ATRACE_CALL();
modulateVsync(&VsyncModulator::setTransactionSchedule, schedule, applyToken);
std::atomic<int32_t> tmp = getTransactionFlags();
if (const bool scheduled = mTransactionFlags.fetch_or(mask) & mask; !scheduled) {
ATRACE_BEGIN("scheduleCommit");
scheduleCommit(frameHint);//申請vsync
ATRACE_END();
}
}
void SurfaceFlinger::scheduleCommit(FrameHint hint) {
//省略部分
mScheduler->scheduleFrame();
}
void MessageQueue::scheduleFrame() {
//調(diào)用到了registration->schedule
mVsync.scheduledFrameTime =
mVsync.registration->schedule({.workDuration = mVsync.workDuration.get().count(),
.readyDuration = 0,
.earliestVsync = mVsync.lastCallbackTime.count()});
}
//下面是VSyncCallbackRegistration的schedule
ScheduleResult VSyncCallbackRegistration::schedule(VSyncDispatch::ScheduleTiming scheduleTiming) {
if (!mValidToken) {
return std::nullopt;
}
return mDispatch.get().schedule(mToken, scheduleTiming);
}
上面的調(diào)用關(guān)系都很簡單,沒啥業(yè)務(wù),直到調(diào)用到了dispatch的schedule才是核心
ScheduleResult VSyncDispatchTimerQueue::schedule(CallbackToken token,
ScheduleTiming scheduleTiming) {
ScheduleResult result;
{
//這里又會(huì)調(diào)用到callback的schedule,其實(shí)就另一個(gè)重載方法,這里會(huì)獲取出具體的wakeupTime等,是核心部分
result = callback->schedule(scheduleTiming, mTracker, now);
//這里會(huì)判斷上面計(jì)算的wakeupTime是否小于mIntendedWakeupTime,小于才需要重新定時(shí),如果大于就不需要了,直接return
if (callback->wakeupTime() < mIntendedWakeupTime - mTimerSlack) {
rearmTimerSkippingUpdateFor(now, it);//啟動(dòng)定時(shí)任務(wù)相關(guān)
}
}
return result;
}
來看看核心方法callback->schedule是怎么計(jì)算的這個(gè)wakeup等重要參數(shù)的:
ScheduleResult VSyncDispatchTimerQueueEntry::schedule(VSyncDispatch::ScheduleTiming timing,
VSyncTracker& tracker, nsecs_t now) {
//核心方法,給一個(gè)時(shí)間點(diǎn),然后可以獲取到這個(gè)時(shí)間點(diǎn)對于的硬件vsync,即上屏的vsync時(shí)間點(diǎn)就是nextVsyncTime
auto nextVsyncTime = tracker.nextAnticipatedVSyncTimeFrom(
std::max(timing.earliestVsync, now + timing.workDuration + timing.readyDuration));
//通過nextVsyncTime來獲取喚醒時(shí)間部分
auto nextWakeupTime = nextVsyncTime - timing.workDuration - timing.readyDuration;
//省略
//上面計(jì)算出來的時(shí)間,然后包裝到mArmedInfo中
mArmedInfo = {nextWakeupTime, nextVsyncTime, nextReadyTime};
//返回時(shí)間點(diǎn)
return getExpectedCallbackTime(nextVsyncTime, timing);
}
//其實(shí)是返回wakeuptime
nsecs_t getExpectedCallbackTime(nsecs_t nextVsyncTime,
const VSyncDispatch::ScheduleTiming& timing) {
return nextVsyncTime - timing.readyDuration - timing.workDuration;
}
核心方法是nextAnticipatedVSyncTimeFrom,這個(gè)方法很復(fù)雜,大家先把他當(dāng)做個(gè)功能黑盒,后面會(huì)帶大家詳細(xì)分析。
所以Sf接收到跨進(jìn)程transaction的請求后申請vsync,計(jì)算出來的vsync時(shí)間,從而得出wakeupTime,一般這里的wakeupTime會(huì)大于前面app Vsync時(shí)候定時(shí)的wakeupTime,所以這里不會(huì)進(jìn)行任何的定時(shí)。
結(jié)合trace看看vsync的情況:
sf的vsync申請觸發(fā)部分情況:

和app vsync一起合作的解釋部分:

這里展開一下app ,sf都被回調(diào)的trace,對應(yīng)的代碼就是上面的timeCallback方法:

4、app vsync結(jié)束部分
vsync有申請就肯定有結(jié)束,不可能app沒有申請情況下,vsync還一直不斷的運(yùn)行,這樣對于系統(tǒng)的功耗影響巨大,而且也是無用功,所以vsync堅(jiān)持的原則就是有需要用時(shí)候app主動(dòng)申請,不需要了就停止。
上面只分析了vsync怎么開始的,接下來分析vsync的結(jié)束部分邏輯

邏輯是如下情況:
時(shí)間到了timeCallback
-----》在onVsyncCallback里面會(huì)喚醒EventThread
-------》EventThread運(yùn)行,但是因?yàn)闆]有app進(jìn)行requestVsync了,所以vsyncRequest = 0
-----》EventThread繼續(xù)執(zhí)行時(shí)候發(fā)現(xiàn)沒有vsyncRequest,故需要調(diào)用setVsyncEnbale(false)關(guān)閉定時(shí)
關(guān)閉定時(shí)器步驟trace:

該部分對應(yīng)核心代碼回顧:
app的EventThread執(zhí)行時(shí)候,會(huì)把vsyncRequest變成0,代表沒有app的vsync請求了
void EventThread::threadMain(std::unique_lock<std::mutex>& lock) {
DisplayEventConsumers consumers;
while (mState != State::Quit) {
std::optional<DisplayEventReceiver::Event> event;
ATRACE_FORMAT("threadMain");
bool vsyncRequested = false;
// Find connections that should consume this event.
auto it = mDisplayEventConnections.begin();
while (it != mDisplayEventConnections.end()) {
if (const auto connection = it->promote()) {
//這里會(huì)進(jìn)行遍歷connection,有vsync那么就為true,沒有就是false
vsyncRequested |= connection->vsyncRequest != VSyncRequest::None;
//注意這里會(huì)對每個(gè)connection的vsyncRequest進(jìn)行改變,注意這里的需要event不為null
if (event && shouldConsumeEvent(*event, connection)) {
consumers.push_back(connection);
}
++it;
} else {
it = mDisplayEventConnections.erase(it);
}
}
}
//這個(gè)方法里面會(huì)改變每個(gè)connection的vsyncRequest
bool EventThread::shouldConsumeEvent(const DisplayEventReceiver::Event& event,
const sp<EventThreadConnection>& connection) const {
switch (event.header.type) {
case DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE: {
return connection->mEventRegistration.test(
ISurfaceComposer::EventRegistration::modeChanged);
}
case DisplayEventReceiver::DISPLAY_EVENT_VSYNC:
switch (connection->vsyncRequest) {
case VSyncRequest::None:
return false;
//第一次SingleSuppressCallback后,就改成None
case VSyncRequest::SingleSuppressCallback:
connection->vsyncRequest = VSyncRequest::None;
return false;
case VSyncRequest::Single: {
if (throttleVsync()) {
return false;
}
//第一次Single后,就改成SingleSuppressCallback
connection->vsyncRequest = VSyncRequest::SingleSuppressCallback;
return true;
}
case VSyncRequest::Periodic:
if (throttleVsync()) {
return false;
}
return true;
default:
return event.vsync.count % vsyncPeriod(connection->vsyncRequest) == 0;
}
}
}
總結(jié)如下:
1、EventThread最核心的vsyncRequest是app進(jìn)行requestVsync進(jìn)行改變成Single
2、vsync定時(shí)時(shí)間到會(huì)回調(diào)觸發(fā)EventThread加入個(gè)event,event就是來派發(fā)Vsync事件給具體的connection即app,通過socket方式
3、消費(fèi)了event同時(shí),需要吧前面app設(shè)置的vsyncRequest變成SingleSuppressCallback
4、下次如果vsync再次觸發(fā),但是沒見到新的app吧vsyncRequest變成Single,如果還是上次的SingleSuppressCallback,那么vsyncRequest就變成了None,變成None之后就會(huì)調(diào)用 mVSyncSource->setVSyncEnabled(false)關(guān)閉vsync
本文章對應(yīng)視頻手把手教你學(xué)framework:
hal+perfetto+surfaceflinger
https://mp.weixin.qq.com/s/LbVLnu1udqExHVKxd74ILg

私聊作者+v(androidframework007)
七件套專題:

點(diǎn)擊這里 https://mp.weixin.qq.com/s/Qv8zjgQ0CkalKmvi8tMGaw