Android11 记录Vsync的流程 只截取了部分代码
SurfaceFlinger.cpp
void SurfaceFlinger::onVsyncReceived(int32_t sequenceId, hal::HWDisplayId hwcDisplayId,
int64_t timestamp,
std::optional<hal::VsyncPeriodNanos> vsyncPeriod) {
...
...
bool periodFlushed = false;
mScheduler->addResyncSample(timestamp, vsyncPeriod, &periodFlushed);
...
...
}
Schedule.cpp
void Scheduler::addResyncSample(nsecs_t timestamp, std::optional<nsecs_t> hwcVsyncPeriod,
bool* periodFlushed) {
...
{
// Scope for the lock
std::lock_guard<std::mutex> lock(mHWVsyncLock);
if (mPrimaryHWVsyncEnabled) {
needsHwVsync =
mPrimaryDispSync->addResyncSample(timestamp, hwcVsyncPeriod, periodFlushed);
}
}
...
}
DispSync.cpp
bool DispSync::addResyncSample(nsecs_t timestamp, std::optional<nsecs_t> /*hwcVsyncPeriod*/,
bool* periodFlushed) {
...
...
// Always update the reference time with the most recent timestamp.
mReferenceTime = timestamp;
mThread->updateModel(mPeriod, mPhase, mReferenceTime);
if (mNumResyncSamples < MAX_RESYNC_SAMPLES) {
mNumResyncSamples++;
} else {
mFirstResyncSample = (mFirstResyncSample + 1) % MAX_RESYNC_SAMPLES;
}
updateModelLocked();
...
...
}
DispSync.cpp
DispSyncThread::
void updateModel(nsecs_t period, nsecs_t phase, nsecs_t referenceTime) {
...
...
// 给等待中的线程发送信号
mCond.signal(); // -> threadloop()
}
一直在循环的 threadloop 收到信号
virtual bool threadLoop() {
status_t err;
nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
while (true) {
std::vector<CallbackInvocation> callbackInvocations;
nsecs_t targetTime = 0;
{
// Scope for lock
Mutex::Autolock lock(mMutex);
...
...
// 取出eventListener 放入 callbackInvocations,等待后面的调用
callbackInvocations =
gatherCallbackInvocationsLocked(now, computeNextRefreshLocked(0, now));
}
if (callbackInvocations.size() > 0) {
fireCallbackInvocations(callbackInvocations);
}
}
return false;
}
std::vector<CallbackInvocation> gatherCallbackInvocationsLocked(nsecs_t now,
nsecs_t expectedVSyncTime) {
if (mTraceDetailedInfo) ATRACE_CALL();
ALOGV("[%s] gatherCallbackInvocationsLocked @ %" PRId64, mName, ns2us(now));
std::vector<CallbackInvocation> callbackInvocations;
nsecs_t onePeriodAgo = now - mPeriod;
for (auto& eventListener : mEventListeners) {
nsecs_t t = computeListenerNextEventTimeLocked(eventListener, onePeriodAgo);
if (t < now) {
if (isCloseToPeriod(now - eventListener.mLastCallbackTime)) {
eventListener.mLastEventTime = t;
ALOGV("[%s] [%s] Skipping event due to model error", mName,
eventListener.mName);
continue;
}
CallbackInvocation ci;
ci.mCallback = eventListener.mCallback;
ci.mEventTime = t;
ci.mExpectedVSyncTime = expectedVSyncTime;
if (eventListener.mPhase < 0) {
ci.mExpectedVSyncTime += mPeriod;
}
ALOGV("[%s] [%s] Preparing to fire, latency: %" PRId64, mName, eventListener.mName,
t - eventListener.mLastEventTime);
callbackInvocations.push_back(ci);
eventListener.mLastEventTime = t;
eventListener.mLastCallbackTime = now;
}
}
void fireCallbackInvocations(const std::vector<CallbackInvocation>& callbacks) {
if (mTraceDetailedInfo) ATRACE_CALL();
for (size_t i = 0; i < callbacks.size(); i++) {
callbacks[i].mCallback->onDispSyncEvent(callbacks[i].mEventTime,
callbacks[i].mExpectedVSyncTime);
}
}
DispSyncSource.cpp
void DispSyncSource::onDispSyncEvent(nsecs_t when, nsecs_t expectedVSyncTimestamp) {
...
...
if (callback != nullptr) {
callback->onVSyncEvent(when, expectedVSyncTimestamp);
}
}
EventThread.cpp
notify_all() 告知等待的进程
void EventThread::onVSyncEvent(nsecs_t timestamp, nsecs_t expectedVSyncTimestamp) {
std::lock_guard<std::mutex> lock(mMutex);
LOG_FATAL_IF(!mVSyncState);
mPendingEvents.push_back(makeVSync(mVSyncState->displayId, timestamp, ++mVSyncState->count,
expectedVSyncTimestamp));
mCondition.notify_all();
}
EventThread.cpp
EventThreadConnection::
status_t EventThreadConnection::postEvent(const DisplayEventReceiver::Event& event) {
ssize_t size = DisplayEventReceiver::sendEvents(&mChannel, &event, 1);
return size < 0 ? status_t(size) : status_t(NO_ERROR);
}
frameworks/native/libs/gui/DisplayEventReceiver.cpp
ssize_t DisplayEventReceiver::sendEvents(gui::BitTube* dataChannel,
Event const* events, size_t count)
{
return gui::BitTube::sendObjects(dataChannel, events, count);
}
frameworks/native/libs/gui/BitTube.cpp
ssize_t BitTube::sendObjects(BitTube* tube, void const* events, size_t count, size_t objSize) {
const char* vaddr = reinterpret_cast<const char*>(events);
ssize_t size = tube->write(vaddr, count * objSize);
// should never happen because of SOCK_SEQPACKET
LOG_ALWAYS_FATAL_IF((size >= 0) && (size % static_cast<ssize_t>(objSize)),
"BitTube::sendObjects(count=%zu, size=%zu), res=%zd (partial events were "
"sent!)",
count, objSize, size);
// ALOGE_IF(size<0, "error %d sending %d events", size, count);
return size < 0 ? size : size / static_cast<ssize_t>(objSize);
最后这个消息会由MessageQueue获取进行绘制,绘制完成由surfaceflinger进行显示