VSYNC 信号流程分析 (Android 14)
概述
本文档详细分析 VSYNC 信号从 App 请求到 SurfaceFlinger 处理,最终回调到 App 的完整流程。
核心组件
1. App 端组件
| 组件 | 位置 | 作用 |
|---|---|---|
Choreographer |
frameworks/base/core/java/android/view/ |
协调动画、输入和绘制的时序 |
DisplayEventReceiver |
frameworks/base/core/java/android/view/ |
Java 层显示事件接收器 |
DisplayEventDispatcher |
frameworks/native/libs/gui/ |
Native 层事件分发器 |
DisplayEventReceiver |
frameworks/native/libs/gui/ |
Native 层事件接收器 |
2. SurfaceFlinger 端组件
| 组件 | 位置 | 作用 |
|---|---|---|
EventThread |
frameworks/native/services/surfaceflinger/Scheduler/ |
VSYNC 事件分发线程 |
EventThreadConnection |
同上 | 与 App 端的连接通道 |
VsyncSchedule |
frameworks/native/services/surfaceflinger/Scheduler/ |
VSYNC 调度管理 |
VSyncDispatchTimerQueue |
同上 | VSYNC 回调分发队列 |
VSyncPredictor |
同上 | VSYNC 时间预测器 |
Scheduler |
frameworks/native/services/surfaceflinger/Scheduler/ |
统一调度器 |
3. 硬件抽象层
| 组件 | 位置 | 作用 |
|---|---|---|
HWComposer |
frameworks/native/services/surfaceflinger/DisplayHardware/ |
Hardware Composer HAL 封装 |
ISurfaceComposer |
frameworks/native/libs/gui/aidl/ |
SurfaceFlinger AIDL 接口 |
完整流程图
scss
┌─────────────────────────────────────────────────────────────────────────────────┐
│ APP 端 │
│ ┌─────────────────┐ ┌───────────────────┐ ┌─────────────────────────┐ │
│ │ Choreographer │ │ DisplayEventReceiver│ │ DisplayEventDispatcher │ │
│ │ │ │ (Java) │ │ (Native) │ │
│ │ postFrameCallback │ │ │ │ │ │
│ │ scheduleVsyncLocked│ │ │ │ │ │
│ └────────┬──────────┘ └─────────┬─────────┘ └────────────┬────────────┘ │
│ │ │ │ │
│ │ scheduleVsync() │ │ │
│ │ (nativeScheduleVsync) │ │ │
│ ▼ ▼ ▼ │
└─────────────────────────────────────────────────────────────────────────────────┘
│
│ AIDL: requestNextVsync()
▼
┌─────────────────────────────────────────────────────────────────────────────────┐
│ SurfaceFlinger 端 │
│ │
│ ┌─────────────────┐ ┌───────────────────┐ ┌─────────────────────────┐ │
│ │ EventThread │ │ EventThread │ │ VsyncSchedule │ │
│ │ Connection │ │ │ │ │ │
│ │ │ │ │ │ │ │
│ │ requestNextVsync│───▶│ requestNextVsync │ │ │ │
│ │ │ │ │ │ │ │
│ └─────────────────┘ └─────────┬─────────┘ └────────────┬────────────┘ │
│ │ │ │
│ │ 设置 vsyncRequest │ │
│ │ = Single │ │
│ ▼ │ │
│ ┌─────────────────┐ │ │
│ │ threadMain() │◀─────────────────│ onVsync() │
│ │ (EventThread 循环)│ │ │
│ │ │ │ │
│ │ shouldConsumeEvent│ │ │
│ │ dispatchEvent │ │ │
│ └────────┬────────┘ │ │
│ │ │ │
│ │ BitTube (Binder) │ │
│ ▼ │ │
└─────────────────────────────────────────────────────────────────────────────────┘
│
│ 读取事件
▼
┌─────────────────────────────────────────────────────────────────────────────────┐
│ App 端回调 │
│ │
│ ┌─────────────────┐ ┌───────────────────┐ ┌─────────────────────────┐ │
│ │ DisplayEvent │ │ NativeDisplay │ │ Choreographer │ │
│ │ Dispatcher │ │ EventReceiver │ │ FrameDisplayEventReceiver│ │
│ │ │ │ (JNI) │ │ │ │
│ │ handleEvent() │ │ │ │ │ │
│ │ processPending │ │ dispatchVsync() │ │ onVsync() │ │
│ │ Events() │ │ (JNI 回调) │ │ doFrame() │ │
│ └─────────────────┘ └───────────────────┘ └─────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────────┘
详细流程分析
阶段一:App 端注册 VSYNC 请求
1.1 Choreographer 请求 VSYNC
文件 : frameworks/base/core/java/android/view/Choreographer.java
java
// Choreographer.java:967-975
private void scheduleVsyncLocked() {
try {
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "Choreographer#scheduleVsyncLocked");
mDisplayEventReceiver.scheduleVsync();
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
}
当 App 调用 Choreographer.postFrameCallback() 时:
- 如果 frame 未调度,调用
scheduleFrameLocked() - 最终调用
scheduleVsyncLocked()请求下一个 VSYNC
1.2 DisplayEventReceiver (Java) 调用 Native 方法
文件 : frameworks/base/core/java/android/view/DisplayEventReceiver.java
java
// DisplayEventReceiver.java:328-336
public void scheduleVsync() {
if (mReceiverPtr == 0) {
Log.w(TAG, "Attempted to schedule a vertical sync pulse...");
} else {
nativeScheduleVsync(mReceiverPtr);
}
}
1.3 JNI 层调用 Native DisplayEventReceiver
文件 : frameworks/base/core/jni/android_view_DisplayEventReceiver.cpp
cpp
// android_view_DisplayEventReceiver.cpp:285-293
static void nativeScheduleVsync(JNIEnv* env, jclass clazz, jlong receiverPtr) {
sp<NativeDisplayEventReceiver> receiver =
reinterpret_cast<NativeDisplayEventReceiver*>(receiverPtr);
status_t status = receiver->scheduleVsync();
if (status) {
String8 message;
message.appendFormat("Failed to schedule next vertical sync pulse. status=%d", status);
jniThrowRuntimeException(env, message.string());
}
}
1.4 DisplayEventDispatcher 请求 VSYNC
文件 : frameworks/native/libs/gui/DisplayEventDispatcher.cpp
cpp
// DisplayEventDispatcher.cpp:76-93
status_t DisplayEventDispatcher::scheduleVsync() {
if (!mWaitingForVsync) {
ALOGV("dispatcher %p ~ Scheduling vsync.", this);
// 清空所有待处理事件
nsecs_t vsyncTimestamp;
PhysicalDisplayId vsyncDisplayId;
uint32_t vsyncCount;
VsyncEventData vsyncEventData;
if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount, &vsyncEventData)) {
ALOGE("dispatcher %p ~ last event processed while scheduling was for %" PRId64 "", this,
ns2ms(static_cast<nsecs_t>(vsyncTimestamp)));
}
status_t status = mReceiver.requestNextVsync();
if (status) {
ALOGW("Failed to request next vsync, status=%d", status);
return status;
}
mWaitingForVsync = true;
mLastScheduleVsyncTime = systemTime(SYSTEM_TIME_MONOTONIC);
}
return OK;
}
1.5 通过 Binder 调用 SurfaceFlinger
文件 : frameworks/native/libs/gui/DisplayEventReceiver.cpp
cpp
// DisplayEventReceiver.cpp:89-97
status_t DisplayEventReceiver::requestNextVsync() {
if (mEventConnection != nullptr) {
mEventConnection->requestNextVsync();
return NO_ERROR;
}
return mInitError.has_value() ? mInitError.value() : NO_INIT;
}
文件 : frameworks/native/libs/gui/aidl/android/gui/IDisplayEventConnection.aidl
aidl
// IDisplayEventConnection.aidl:39-41
/**
* requestNextVsync() schedules the next vsync event. It has no effect if the vsync rate is > 0.
*/
oneway void requestNextVsync(); // Asynchronous
阶段二:SurfaceFlinger 接收并处理请求
2.1 EventThreadConnection 接收请求
文件 : frameworks/native/services/surfaceflinger/Scheduler/EventThread.cpp
cpp
// EventThread.cpp:199-204
binder::Status EventThreadConnection::requestNextVsync() {
ATRACE_CALL();
mEventThread->requestNextVsync(sp<EventThreadConnection>::fromExisting(this));
return binder::Status::ok();
}
2.2 EventThread 处理 VSYNC 请求
文件 : frameworks/native/services/surfaceflinger/Scheduler/EventThread.cpp
cpp
// EventThread.cpp:346-360
void EventThread::requestNextVsync(const sp<EventThreadConnection>& connection) {
if (connection->resyncCallback) {
connection->resyncCallback();
}
std::lock_guard<std::mutex> lock(mMutex);
if (connection->vsyncRequest == VSyncRequest::None) {
connection->vsyncRequest = VSyncRequest::Single;
mCondition.notify_all();
} else if (connection->vsyncRequest == VSyncRequest::SingleSuppressCallback) {
connection->vsyncRequest = VSyncRequest::Single;
}
}
关键点:
- 设置
vsyncRequest = VSyncRequest::Single表示请求单次 VSYNC - 通过
mCondition.notify_all()唤醒 EventThread 主循环
2.3 EventThread 主循环
文件 : frameworks/native/services/surfaceflinger/Scheduler/EventThread.cpp
cpp
// EventThread.cpp:439-507
void EventThread::threadMain(std::unique_lock<std::mutex>& lock) {
DisplayEventConsumers consumers;
while (mState != State::Quit) {
std::optional<DisplayEventReceiver::Event> event;
// 1. 确定下一个要分发的事件
if (!mPendingEvents.empty()) {
event = mPendingEvents.front();
mPendingEvents.pop_front();
// ... 处理热插拔事件
}
bool vsyncRequested = false;
// 2. 查找应该消费此事件的连接
auto it = mDisplayEventConnections.begin();
while (it != mDisplayEventConnections.end()) {
if (const auto connection = it->promote()) {
if (event && shouldConsumeEvent(*event, connection)) {
consumers.push_back(connection);
}
vsyncRequested |= connection->vsyncRequest != VSyncRequest::None;
++it;
} else {
it = mDisplayEventConnections.erase(it);
}
}
// 3. 分发事件
if (!consumers.empty()) {
dispatchEvent(*event, consumers);
consumers.clear();
}
// 4. 根据状态调度 VSYNC 回调
if (mVSyncState && vsyncRequested) {
mState = mVSyncState->synthetic ? State::SyntheticVSync : State::VSync;
} else {
mState = State::Idle;
}
if (mState == State::VSync) {
const auto scheduleResult =
mVsyncRegistration.schedule({.workDuration = mWorkDuration.get().count(),
.readyDuration = mReadyDuration.count(),
.earliestVsync = mLastVsyncCallbackTime.ns()});
LOG_ALWAYS_FATAL_IF(!scheduleResult, "Error scheduling callback");
} else {
mVsyncRegistration.cancel();
}
// 5. 等待事件或客户端注册/请求
if (mState == State::Idle) {
mCondition.wait(lock); // 等待 requestNextVsync 唤醒
} else {
// 超时处理
const std::chrono::nanoseconds timeout =
mState == State::SyntheticVSync ? 16ms : 1000ms;
if (mCondition.wait_for(lock, timeout) == std::cv_status::timeout) {
// 生成伪 VSYNC 事件
}
}
}
}
阶段三:硬件 VSYNC 信号到达
3.1 HWComposer 接收硬件 VSYNC
文件 : frameworks/native/services/surfaceflinger/DisplayHardware/HWComposer.cpp
cpp
// HWComposer.cpp:152-184
std::optional<PhysicalDisplayId> HWComposer::onVsync(hal::HWDisplayId hwcDisplayId,
nsecs_t timestamp) {
const auto displayIdOpt = toPhysicalDisplayId(hwcDisplayId);
if (!displayIdOpt) {
LOG_HWC_DISPLAY_ERROR(hwcDisplayId, "Invalid HWC display");
return {};
}
RETURN_IF_INVALID_DISPLAY(*displayIdOpt, {});
auto& displayData = mDisplayData[*displayIdOpt];
// 过滤重复的 VSYNC 事件
{
if (timestamp == displayData.lastPresentTimestamp) {
ALOGW("Ignoring duplicate VSYNC event from HWC for display %s (t=%" PRId64 ")",
to_string(*displayIdOpt).c_str(), timestamp);
return {};
}
displayData.lastPresentTimestamp = timestamp;
}
ATRACE_INT(ftl::Concat("HW_VSYNC_", displayIdOpt->value).c_str(),
displayData.vsyncTraceToggle);
displayData.vsyncTraceToggle = !displayData.vsyncTraceToggle;
return displayIdOpt;
}
3.2 SurfaceFlinger 处理 VSYNC
文件 : frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
cpp
// SurfaceFlinger.cpp:2091-2104
void SurfaceFlinger::onComposerHalVsync(hal::HWDisplayId hwcDisplayId, int64_t timestamp,
std::optional<hal::VsyncPeriodNanos> vsyncPeriod) {
ATRACE_NAME(vsyncPeriod
? ftl::Concat(__func__, ' ', hwcDisplayId, ' ', *vsyncPeriod, "ns").c_str()
: ftl::Concat(__func__, ' ', hwcDisplayId).c_str());
Mutex::Autolock lock(mStateLock);
if (const auto displayIdOpt = getHwComposer().onVsync(hwcDisplayId, timestamp)) {
if (mScheduler->addResyncSample(*displayIdOpt, timestamp, vsyncPeriod)) {
// 周期刷新完成
mScheduler->modulateVsync(displayIdOpt, &VsyncModulator::onRefreshRateChangeCompleted);
}
}
}
3.3 Scheduler 添加 VSYNC 样本
文件 : frameworks/native/services/surfaceflinger/Scheduler/VsyncSchedule.cpp
cpp
// VsyncSchedule.cpp:146-163
bool VsyncSchedule::addResyncSample(TimePoint timestamp, ftl::Optional<Period> hwcVsyncPeriod) {
bool needsHwVsync = false;
bool periodFlushed = false;
{
std::lock_guard<std::mutex> lock(mHwVsyncLock);
if (mHwVsyncState == HwVsyncState::Enabled) {
needsHwVsync = mController->addHwVsyncTimestamp(timestamp.ns(),
hwcVsyncPeriod.transform(&Period::ns),
&periodFlushed);
}
}
if (needsHwVsync) {
enableHardwareVsync();
} else {
constexpr bool kDisallow = false;
disableHardwareVsync(kDisallow);
}
return periodFlushed;
}
3.4 VSyncController 触发回调
文件 : frameworks/native/services/surfaceflinger/Scheduler/VsyncSchedule.cpp
cpp
// VsyncSchedule.cpp:35-42
constexpr auto makeVsyncCallback() {
return [this](nsecs_t, nsecs_t, nsecs_t) {
mParity = !mParity;
schedule();
};
}
VSyncDispatchTimerQueue 会在预测的 VSYNC 时间前触发回调,调用 EventThread::onVsync()。
3.5 EventThread 生成 VSYNC 事件
文件 : frameworks/native/services/surfaceflinger/Scheduler/EventThread.cpp
cpp
// EventThread.cpp:400-408
void EventThread::onVsync(nsecs_t vsyncTime, nsecs_t wakeupTime, nsecs_t readyTime) {
std::lock_guard<std::mutex> lock(mMutex);
mLastVsyncCallbackTime = TimePoint::fromNs(vsyncTime);
LOG_FATAL_IF(!mVSyncState);
mVsyncTracer = (mVsyncTracer + 1) % 2;
mPendingEvents.push_back(makeVSync(mVSyncState->displayId, wakeupTime, ++mVSyncState->count,
vsyncTime, readyTime));
mCondition.notify_all();
}
阶段四:VSYNC 事件分发到 App
4.1 EventThread 分发事件
文件 : frameworks/native/services/surfaceflinger/Scheduler/EventThread.cpp
cpp
// EventThread.cpp:467-470
if (!consumers.empty()) {
dispatchEvent(*event, consumers);
consumers.clear();
}
文件 : frameworks/native/services/surfaceflinger/Scheduler/EventThread.cpp
cpp
// EventThread.cpp:569-580
void EventThread::dispatchEvent(const DisplayEventReceiver::Event& event,
DisplayEventConsumers& consumers) {
for (const auto& consumer : consumers) {
if (status_t status = consumer->postEvent(event); status != NO_ERROR) {
ALOGE("Failed to post event to %s: %s", toString(*consumer).c_str(),
statusToString(status));
}
}
}
4.2 EventThreadConnection 发送事件
文件 : frameworks/native/services/surfaceflinger/Scheduler/EventThread.cpp
cpp
// EventThread.cpp:229-243
status_t EventThreadConnection::postEvent(const DisplayEventReceiver::Event& event) {
constexpr auto toStatus = [](ssize_t size) {
return size < 0 ? status_t(size) : status_t(NO_ERROR);
};
if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE ||
event.header.type == DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH) {
mPendingEvents.emplace_back(event);
if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE) {
return status_t(NO_ERROR);
}
auto size = DisplayEventReceiver::sendEvents(&mChannel, mPendingEvents.data(),
mPendingEvents.size());
mPendingEvents.clear();
return toStatus(size);
}
auto size = DisplayEventReceiver::sendEvents(&mChannel, &event, 1);
return toStatus(size);
}
事件通过 BitTube (基于 Binder 的共享内存管道) 发送到 App 端。
4.3 App 端接收事件
文件 : frameworks/native/libs/gui/DisplayEventDispatcher.cpp
cpp
// DisplayEventDispatcher.cpp:115-143
int DisplayEventDispatcher::handleEvent(int, int events, void*) {
if (events & (Looper::EVENT_ERROR | Looper::EVENT_HANGUP)) {
ALOGE("Display event receiver pipe was closed or an error occurred.");
return 0;
}
if (!(events & Looper::EVENT_INPUT)) {
ALOGW("Received spurious callback for unhandled poll event.");
return 1;
}
// 读取所有待处理事件,保留最后一个 vsync
nsecs_t vsyncTimestamp;
PhysicalDisplayId vsyncDisplayId;
uint32_t vsyncCount;
VsyncEventData vsyncEventData;
if (processPendingEvents(&vsyncTimestamp, &vsyncDisplayId, &vsyncCount, &vsyncEventData)) {
ALOGV("dispatcher %p ~ Vsync pulse: timestamp=%" PRId64 ", displayId=%s, count=%d",
this, ns2ms(vsyncTimestamp), to_string(vsyncDisplayId).c_str(), vsyncCount);
mWaitingForVsync = false;
mLastVsyncCount = vsyncCount;
dispatchVsync(vsyncTimestamp, vsyncDisplayId, vsyncCount, vsyncEventData);
}
return 1;
}
4.4 JNI 回调到 Java
文件 : frameworks/base/core/jni/android_view_DisplayEventReceiver.cpp
cpp
// android_view_DisplayEventReceiver.cpp:158-203
void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId,
uint32_t count, VsyncEventData vsyncEventData) {
JNIEnv* env = AndroidRuntime::getJNIEnv();
ScopedLocalRef<jobject> receiverObj(env, GetReferent(env, mReceiverWeakGlobal));
ScopedLocalRef<jobject> vsyncEventDataObj(env, GetReferent(env, mVsyncEventDataWeakGlobal));
if (receiverObj.get() && vsyncEventDataObj.get()) {
// 更新 VsyncEventData 字段
env->SetIntField(vsyncEventDataObj.get(),
gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo
.preferredFrameTimelineIndex,
vsyncEventData.preferredFrameTimelineIndex);
// ... 更新其他字段
// 调用 Java 层的 dispatchVsync
env->CallVoidMethod(receiverObj.get(), gDisplayEventReceiverClassInfo.dispatchVsync,
timestamp, displayId.value, count);
}
mMessageQueue->raiseAndClearException(env, "dispatchVsync");
}
4.5 Java 层处理 VSYNC
文件 : frameworks/base/core/java/android/view/DisplayEventReceiver.java
java
// DisplayEventReceiver.java:343-348
@SuppressWarnings("unused")
private void dispatchVsync(long timestampNanos, long physicalDisplayId, int frame) {
onVsync(timestampNanos, physicalDisplayId, frame, mVsyncEventData);
}
4.6 Choreographer 执行 Frame 回调
文件 : frameworks/base/core/java/android/view/Choreographer.java
java
// Choreographer.java:1301-1321
@Override
public void onVsync(long timestampNanos, long physicalDisplayId, int frame,
VsyncEventData vsyncEventData) {
// ... 追踪代码省略
long now = System.nanoTime();
if (timestampNanos > now) {
Log.w(TAG, "Frame time is " + ((timestampNanos - now) * 0.000001f)
+ " ms in the future!");
timestampNanos = now;
}
if (mHavePendingVsync) {
Log.w(TAG, "Already have a pending vsync event.");
} else {
mHavePendingVsync = true;
}
mTimestampNanos = timestampNanos;
mFrame = frame;
mLastVsyncEventData.copyFrom(vsyncEventData);
// 发送消息到 Handler,在 vsync 时间执行
Message msg = Message.obtain(mHandler, this);
msg.setAsynchronous(true);
mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS);
}
@Override
public void run() {
mHavePendingVsync = false;
doFrame(mTimestampNanos, mFrame, mLastVsyncEventData);
}
4.7 执行 App 注册的回调
文件 : frameworks/base/core/java/android/view/Choreographer.java
java
// Choreographer.java:844-878
void doFrame(long frameTimeNanos, int frame, DisplayEventReceiver.VsyncEventData vsyncEventData) {
// ... 更新 frame 数据
try {
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "mChoreographer.doFrame");
// 1. 处理输入回调
doCallbacks(CALLBACK_INPUT, frameIntervalNanos);
// 2. 处理动画回调
doCallbacks(CALLBACK_ANIMATION, frameIntervalNanos);
// 3. 处理 insets 动画回调
doCallbacks(CALLBACK_INSETS_ANIMATION, frameIntervalNanos);
// 4. 处理遍历回调 (layout/draw)
doCallbacks(CALLBACK_TRAVERSAL, frameIntervalNanos);
// 5. 处理提交回调
doCallbacks(CALLBACK_COMMIT, frameIntervalNanos);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
// 调度下一个 VSYNC
scheduleFrameLocked(now);
}
关键数据结构
VSyncRequest 枚举
cpp
// EventThread.cpp:53-64
enum class VSyncRequest {
None = 0,
Single = 1, // 单次 VSYNC (requestNextVsync)
SingleSuppressCallback = 2,
// Periodic = N (N > 1) // 周期性 VSYNC (setVsyncRate)
};
DisplayEventReceiver::Event
cpp
// 通过 BitTube 传输的事件结构
struct Event {
struct Header {
int32_t type; // 事件类型 (VSYNC, HOTPLUG, MODE_CHANGE 等)
PhysicalDisplayId displayId;
nsecs_t timestamp;
} header;
union {
struct {
uint32_t count;
VsyncData vsyncData;
} vsync;
struct {
bool connected;
} hotplug;
// ... 其他事件类型
};
};
VsyncEventData
java
// DisplayEventReceiver.java:145-232
public static final class VsyncEventData {
static final int FRAME_TIMELINES_CAPACITY = 7;
public static class FrameTimeline {
public long vsyncId; // VSYNC ID,用于关联 frame
public long expectedPresentationTime; // 期望呈现时间
public long deadline; // 截止时间
}
public long frameInterval; // 帧间隔 (ns)
public final FrameTimeline[] frameTimelines; // 多个 frame timeline 选项
public int preferredFrameTimelineIndex; // 推荐的 timeline 索引
public int frameTimelinesLength; // 实际 timeline 数量
}
通信机制
BitTube (Binder 传输通道)
EventThreadConnection 使用 BitTube 将 VSYNC 事件从 SurfaceFlinger 传输到 App:
- 创建连接 :
ISurfaceComposer.createDisplayEventConnection()创建 EventThreadConnection - 获取通道 :
stealReceiveChannel()将接收端 FD 转移给 App - 发送事件 : SurfaceFlinger 通过
sendEvents()写入共享内存 - 接收事件 : App 通过 Looper 监听 FD 可读事件,调用
getEvents()读取
时序关系
yaml
时间轴 (ns):
─────────────────────────────────────────────────────────────────────────►
T0: App 调用 postFrameCallback()
│
▼
T1: scheduleVsyncLocked() → nativeScheduleVsync()
│
▼
T2: DisplayEventDispatcher::scheduleVsync()
│
▼
T3: EventThreadConnection::requestNextVsync()
│
▼
T4: EventThread::requestNextVsync() 设置 vsyncRequest=Single
│
▼
T5: EventThread 被 condition.notify_all() 唤醒
│
▼
T6: 硬件 VSYNC 到达 (HWComposer::onVsync)
│
▼
T7: VsyncSchedule::addResyncSample() 更新预测器
│
▼
T8: VSyncDispatchTimerQueue 触发回调 (提前 workDuration+readyDuration)
│
▼
T9: EventThread::onVsync() 创建 VSYNC 事件
│
▼
T10: EventThread::dispatchEvent() 通过 BitTube 发送
│
▼
T11: App 端 Looper 检测到 FD 可读
│
▼
T12: DisplayEventDispatcher::handleEvent() 读取事件
│
▼
T13: JNI dispatchVsync() 回调到 Java
│
▼
T14: Choreographer.onVsync() 发送 MSG_DO_FRAME 消息
│
▼
T15: FrameHandler 在 vsync 时间执行 doFrame()
│
▼
T16: 执行 App 注册的 FrameCallback.doFrame()
关键链路补充:VSyncDispatchTimerQueue → EventThread::onVsync()
完整调用链
ruby
VSyncDispatchTimerQueue::timerCallback()
↓ (遍历所有到期的回调)
VSyncDispatchTimerQueueEntry::callback()
↓ (调用注册的 std::function)
EventThread::createDispatchCallback() 返回的 lambda
↓ (捕获 this 指针调用)
EventThread::onVsync()
详细分析
1. EventThread 注册回调到 VSyncDispatchTimerQueue
文件 : frameworks/native/services/surfaceflinger/Scheduler/EventThread.cpp
cpp
// EventThread.cpp:253-254
EventThread::EventThread(...)
: ...
mVsyncRegistration(mVsyncSchedule->getDispatch(), createDispatchCallback(), name),
...
{}
mVsyncSchedule->getDispatch() 返回 std::shared_ptr<VSyncDispatch>,实际类型是 VSyncDispatchTimerQueue。
2. createDispatchCallback 创建绑定到 onVsync 的 lambda
文件 : frameworks/native/services/surfaceflinger/Scheduler/EventThread.cpp
cpp
// EventThread.cpp:751-755
scheduler::VSyncDispatch::Callback EventThread::createDispatchCallback() {
return [this](nsecs_t vsyncTime, nsecs_t wakeupTime, nsecs_t readyTime) {
onVsync(vsyncTime, wakeupTime, readyTime);
};
}
关键点:
- 返回类型
VSyncDispatch::Callback是std::function<void(nsecs_t, nsecs_t, nsecs_t)> - Lambda 捕获
this指针,确保能调用成员函数onVsync()
3. VSyncCallbackRegistration 保存回调
文件 : frameworks/native/services/surfaceflinger/Scheduler/VSyncDispatch.h
cpp
// VSyncDispatch.h:149-156
class VSyncCallbackRegistration {
public:
VSyncCallbackRegistration(std::shared_ptr<VSyncDispatch>, VSyncDispatch::Callback,
std::string callbackName);
~VSyncCallbackRegistration();
// ...
private:
std::shared_ptr<VSyncDispatch> mDispatch;
std::optional<VSyncDispatch::CallbackToken> mToken;
};
构造函数中调用 registerCallback() 将 lambda 注册到 VSyncDispatchTimerQueue。
4. VSyncDispatchTimerQueue 注册回调
文件 : frameworks/native/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp
cpp
// VSyncDispatchTimerQueue.cpp:328-337
VSyncDispatchTimerQueue::CallbackToken VSyncDispatchTimerQueue::registerCallback(
Callback callback, std::string callbackName) {
std::lock_guard lock(mMutex);
return CallbackToken{
mCallbacks
.emplace(++mCallbackToken,
std::make_shared<VSyncDispatchTimerQueueEntry>(std::move(callbackName),
std::move(callback),
mMinVsyncDistance))
.first->first};
}
关键点:
- 回调被包装成
VSyncDispatchTimerQueueEntry对象 - 存储在
mCallbacksunordered_map 中,key 是CallbackToken
5. EventThread 调度 VSYNC 回调
文件 : frameworks/native/services/surfaceflinger/Scheduler/EventThread.cpp
cpp
// EventThread.cpp:484-491
if (mState == State::VSync) {
const auto scheduleResult =
mVsyncRegistration.schedule({.workDuration = mWorkDuration.get().count(),
.readyDuration = mReadyDuration.count(),
.earliestVsync = mLastVsyncCallbackTime.ns()});
LOG_ALWAYS_FATAL_IF(!scheduleResult, "Error scheduling callback");
} else {
mVsyncRegistration.cancel();
}
6. VSyncDispatchTimerQueue 设置定时器
文件 : frameworks/native/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp
cpp
// VSyncDispatchTimerQueue.cpp:362-383
ScheduleResult VSyncDispatchTimerQueue::scheduleLocked(CallbackToken token,
ScheduleTiming scheduleTiming) {
auto it = mCallbacks.find(token);
if (it == mCallbacks.end()) {
return {};
}
auto& callback = it->second;
auto const now = mTimeKeeper->now();
const ScheduleResult result = callback->schedule(scheduleTiming, *mTracker, now);
if (!result.has_value()) {
return {};
}
// 如果这个回调的唤醒时间最早,重新设置定时器
if (callback->wakeupTime() < mIntendedWakeupTime - mTimerSlack) {
rearmTimerSkippingUpdateFor(now, it);
}
return result;
}
7. VSyncDispatchTimerQueueEntry 计算唤醒时间
文件 : frameworks/native/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp
cpp
// VSyncDispatchTimerQueue.cpp:93-114
ScheduleResult VSyncDispatchTimerQueueEntry::schedule(VSyncDispatch::ScheduleTiming timing,
VSyncTracker& tracker, nsecs_t now) {
auto nextVsyncTime = tracker.nextAnticipatedVSyncTimeFrom(
std::max(timing.earliestVsync, now + timing.workDuration + timing.readyDuration));
auto nextWakeupTime = nextVsyncTime - timing.workDuration - timing.readyDuration;
// ... 检查是否需要跳过某些 vsync
nextVsyncTime = adjustVsyncIfNeeded(tracker, nextVsyncTime);
nextWakeupTime = nextVsyncTime - timing.workDuration - timing.readyDuration;
auto const nextReadyTime = nextVsyncTime - timing.readyDuration;
mScheduleTiming = timing;
mArmedInfo = {nextWakeupTime, nextVsyncTime, nextReadyTime}; // 保存唤醒时间、vsync 时间、截止时间
return getExpectedCallbackTime(nextVsyncTime, timing);
}
关键计算:
nextVsyncTime: 预测的下一个 VSYNC 时间nextWakeupTime: 回调唤醒时间 =nextVsyncTime - workDuration - readyDurationnextReadyTime: 完成工作的截止时间 =nextVsyncTime - readyDuration
8. 设置 Linux timerfd
文件 : frameworks/native/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp
cpp
// VSyncDispatchTimerQueue.cpp:243-247
void VSyncDispatchTimerQueue::setTimer(nsecs_t targetTime, nsecs_t /*now*/) {
mIntendedWakeupTime = targetTime;
mTimeKeeper->alarmAt(std::bind(&VSyncDispatchTimerQueue::timerCallback, this),
mIntendedWakeupTime);
mLastTimerSchedule = mTimeKeeper->now();
}
9. TimeKeeper (Timer) 使用 timerfd
文件 : frameworks/native/services/surfaceflinger/Scheduler/src/Timer.cpp
cpp
// Timer.cpp:109-131
void Timer::alarmAt(std::function<void()> callback, nsecs_t time) {
std::lock_guard lock(mMutex);
using namespace std::literals;
static constexpr int ns_per_s =
std::chrono::duration_cast<std::chrono::nanoseconds>(1s).count();
mCallback = std::move(callback);
mExpectingCallback = true;
struct itimerspec old_timer;
struct itimerspec new_timer {
.it_interval = {.tv_sec = 0, .tv_nsec = 0},
.it_value = {.tv_sec = static_cast<long>(time / ns_per_s),
.tv_nsec = static_cast<long>(time % ns_per_s)},
};
if (timerfd_settime(mTimerFd, TFD_TIMER_ABSTIME, &new_timer, &old_timer)) {
ALOGW("Failed to set timerfd %s (%i)", strerror(errno), errno);
}
}
关键点:
- 使用
timerfd_create(CLOCK_MONOTONIC, ...)创建定时器 timerfd_settime()设置绝对时间 (TFD_TIMER_ABSTIME)- 定时器到期时,
timerfd变为可读
10. Timer 线程等待并触发回调
文件 : frameworks/native/services/surfaceflinger/Scheduler/src/Timer.cpp
cpp
// Timer.cpp:168-218
bool Timer::dispatch() {
// 设置线程优先级为实时
struct sched_param param = {0};
param.sched_priority = 2;
pthread_setschedparam(pthread_self(), SCHED_FIFO, ¶m);
// 将 timerfd 添加到 epoll
epoll_event timerEvent;
timerEvent.events = EPOLLIN;
timerEvent.data.u32 = DispatchType::TIMER;
epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mTimerFd, &timerEvent);
while (true) {
epoll_event events[DispatchType::MAX_DISPATCH_TYPE];
int nfds = epoll_wait(mEpollFd, events, DispatchType::MAX_DISPATCH_TYPE, -1);
for (auto i = 0; i < nfds; i++) {
if (events[i].data.u32 == DispatchType::TIMER) {
// 读取 timerfd,清除事件
uint64_t mIgnored = 0;
read(mTimerFd, &mIgnored, sizeof(mIgnored));
// 获取并调用回调
std::function<void()> cb;
{
std::lock_guard lock(mMutex);
cb = mCallback;
mExpectingCallback = false;
}
if (cb) {
cb(); // 调用 VSyncDispatchTimerQueue::timerCallback
}
}
}
}
}
11. VSyncDispatchTimerQueue::timerCallback 触发所有到期的回调
文件 : frameworks/native/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp
cpp
// VSyncDispatchTimerQueue.cpp:289-326
void VSyncDispatchTimerQueue::timerCallback() {
struct Invocation {
std::shared_ptr<VSyncDispatchTimerQueueEntry> callback;
nsecs_t vsyncTimestamp;
nsecs_t wakeupTimestamp;
nsecs_t deadlineTimestamp;
};
std::vector<Invocation> invocations;
{
std::lock_guard lock(mMutex);
auto const now = mTimeKeeper->now();
mLastTimerCallback = now;
// 遍历所有注册的回调
for (auto it = mCallbacks.begin(); it != mCallbacks.end(); it++) {
auto& callback = it->second;
auto const wakeupTime = callback->wakeupTime();
if (!wakeupTime) {
continue;
}
auto const readyTime = callback->readyTime();
// 检查是否到期(考虑 timer slack 和 lag)
auto const lagAllowance = std::max(now - mIntendedWakeupTime, static_cast<nsecs_t>(0));
if (*wakeupTime < mIntendedWakeupTime + mTimerSlack + lagAllowance) {
callback->executing(); // 标记为执行中,解除武装
invocations.emplace_back(Invocation{callback,
*callback->lastExecutedVsyncTarget(),
*wakeupTime,
*readyTime});
}
}
mIntendedWakeupTime = kInvalidTime;
rearmTimer(mTimeKeeper->now()); // 重新设置定时器
}
// 在锁外调用所有到期的回调
for (auto const& invocation : invocations) {
invocation.callback->callback(invocation.vsyncTimestamp,
invocation.wakeupTimestamp,
invocation.deadlineTimestamp);
}
}
12. VSyncDispatchTimerQueueEntry::callback 调用 std::function
文件 : frameworks/native/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp
cpp
// VSyncDispatchTimerQueue.cpp:175-187
void VSyncDispatchTimerQueueEntry::callback(nsecs_t vsyncTimestamp, nsecs_t wakeupTimestamp,
nsecs_t deadlineTimestamp) {
{
std::lock_guard<std::mutex> lk(mRunningMutex);
mRunning = true;
}
mCallback(vsyncTimestamp, wakeupTimestamp, deadlineTimestamp); // 调用 EventThread 的 lambda
std::lock_guard<std::mutex> lk(mRunningMutex);
mRunning = false;
mCv.notify_all();
}
mCallback 就是:
cpp
[this](nsecs_t vsyncTime, nsecs_t wakeupTime, nsecs_t readyTime) {
onVsync(vsyncTime, wakeupTime, readyTime);
}
13. EventThread::onVsync 创建 VSYNC 事件
文件 : frameworks/native/services/surfaceflinger/Scheduler/EventThread.cpp
cpp
// EventThread.cpp:400-408
void EventThread::onVsync(nsecs_t vsyncTime, nsecs_t wakeupTime, nsecs_t readyTime) {
std::lock_guard<std::mutex> lock(mMutex);
mLastVsyncCallbackTime = TimePoint::fromNs(vsyncTime);
LOG_FATAL_IF(!mVSyncState);
mVsyncTracer = (mVsyncTracer + 1) % 2;
mPendingEvents.push_back(makeVSync(mVSyncState->displayId, wakeupTime, ++mVSyncState->count,
vsyncTime, readyTime));
mCondition.notify_all(); // 唤醒 EventThread 主循环
}
时序图
scss
时间轴 (ns):
─────────────────────────────────────────────────────────────────────────►
T0: EventThread::requestNextVsync() 设置 vsyncRequest=Single
│
▼
T1: EventThread::threadMain() 检测到 vsyncRequested
│
▼
T2: mVsyncRegistration.schedule() 调度回调
│
▼
T3: VSyncDispatchTimerQueue::scheduleLocked()
│
▼
T4: VSyncDispatchTimerQueueEntry::schedule() 计算唤醒时间
│ wakeupTime = vsyncTime - workDuration - readyDuration
│
▼
T5: VSyncDispatchTimerQueue::rearmTimer()
│
▼
T6: Timer::alarmAt() 设置 timerfd
│ timerfd_settime(TFD_TIMER_ABSTIME, wakeupTime)
│
▼
T7: Timer::dispatch() epoll_wait 等待
│
▼
T8: timerfd 到期,epoll_wait 返回
│
▼
T9: Timer::dispatch() 读取 timerfd,调用回调
│ cb() → VSyncDispatchTimerQueue::timerCallback()
│
▼
T10: VSyncDispatchTimerQueue::timerCallback() 遍历所有回调
│ 检查 wakeupTime < now + timerSlack + lagAllowance
│
▼
T11: VSyncDispatchTimerQueueEntry::callback()
│ mCallback(vsyncTimestamp, wakeupTimestamp, deadlineTimestamp)
│
▼
T12: EventThread::createDispatchCallback() lambda
│ onVsync(vsyncTime, wakeupTime, readyTime)
│
▼
T13: EventThread::onVsync() 创建 VSYNC 事件
│ mPendingEvents.push_back(makeVSync(...))
│ mCondition.notify_all()
│
▼
T14: EventThread::threadMain() 被唤醒,调用 dispatchEvent()
关键设计点
1. 提前唤醒机制
cpp
// workDuration: SurfaceFlinger 处理一帧需要的时间 (如 8ms)
// readyDuration: 留给 App 渲染的时间 (如 8ms)
wakeupTime = vsyncTime - workDuration - readyDuration
这样设计确保:
- T0: Timer 唤醒 SurfaceFlinger
- T0 + workDuration: SurfaceFlinger 完成合成
- T0 + workDuration + readyDuration: App 完成渲染,buffer 就绪
- vsyncTime: 显示刷新,呈现最新 frame
2. Timer Slack 优化
cpp
// VSyncDispatchTimerQueue.cpp:307
auto const lagAllowance = std::max(now - mIntendedWakeupTime, static_cast<nsecs_t>(0));
if (*wakeupTime < mIntendedWakeupTime + mTimerSlack + lagAllowance) {
// 触发回调
}
timerSlack(默认 500μs): 允许将相近的回调合并,减少唤醒次数lagAllowance: 补偿处理延迟
3. 最小 VSYNC 距离
cpp
// 防止同一 VSYNC 被多次调度
bool const wouldSkipAVsyncTarget =
mArmedInfo && (nextVsyncTime > (mArmedInfo->mActualVsyncTime + mMinVsyncDistance));
minVsyncDistance: 防止重复调度同一 VSYNC 事件
4. 线程安全
Timer使用独立的TimerDispatch线程 (SCHED_FIFO 实时优先级)VSyncDispatchTimerQueue::timerCallback()在锁内收集到期回调,在锁外调用VSyncDispatchTimerQueueEntry::mRunning标志防止注销时回调正在执行
总结
App 端 VSYNC 注册流程
Choreographer.postFrameCallback()→scheduleFrameLocked()scheduleVsyncLocked()→DisplayEventReceiver.scheduleVsync()- JNI
nativeScheduleVsync()→DisplayEventDispatcher.scheduleVsync() DisplayEventReceiver.requestNextVsync()→ Binder 调用EventThreadConnection.requestNextVsync()→EventThread.requestNextVsync()- 设置
vsyncRequest = Single,唤醒 EventThread
SurfaceFlinger 端 VSYNC 等待与派发
- 硬件 VSYNC →
HWComposer::onVsync()→SurfaceFlinger::onComposerHalVsync() VsyncSchedule::addResyncSample()更新 VSYNC 预测VSyncDispatchTimerQueue在预测时间前触发回调EventThread::onVsync()创建 VSYNC 事件EventThread::threadMain()遍历连接,调用shouldConsumeEvent()EventThread::dispatchEvent()→EventThreadConnection::postEvent()- 通过 BitTube 发送到 App 端
App 端 VSYNC 回调流程
- Looper 检测到 FD 可读 →
DisplayEventDispatcher::handleEvent() processPendingEvents()读取 VSYNC 事件dispatchVsync()→ JNI 回调到 JavaNativeDisplayEventReceiver::dispatchVsync()→DisplayEventReceiver.dispatchVsync()Choreographer.FrameDisplayEventReceiver.onVsync()- 发送
MSG_DO_FRAME消息到 vsync 时间执行 doFrame()执行各类回调 (INPUT → ANIMATION → TRAVERSAL → COMMIT)- 调用
scheduleFrameLocked()调度下一帧