VSYNC 信号流程分析 (Android 14)

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() 时:

  1. 如果 frame 未调度,调用 scheduleFrameLocked()
  2. 最终调用 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:

  1. 创建连接 : ISurfaceComposer.createDisplayEventConnection() 创建 EventThreadConnection
  2. 获取通道 : stealReceiveChannel() 将接收端 FD 转移给 App
  3. 发送事件 : SurfaceFlinger 通过 sendEvents() 写入共享内存
  4. 接收事件 : 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::Callbackstd::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 对象
  • 存储在 mCallbacks unordered_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 - readyDuration
  • nextReadyTime: 完成工作的截止时间 = 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, &param);

    // 将 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 注册流程

  1. Choreographer.postFrameCallback()scheduleFrameLocked()
  2. scheduleVsyncLocked()DisplayEventReceiver.scheduleVsync()
  3. JNI nativeScheduleVsync()DisplayEventDispatcher.scheduleVsync()
  4. DisplayEventReceiver.requestNextVsync() → Binder 调用
  5. EventThreadConnection.requestNextVsync()EventThread.requestNextVsync()
  6. 设置 vsyncRequest = Single,唤醒 EventThread

SurfaceFlinger 端 VSYNC 等待与派发

  1. 硬件 VSYNC → HWComposer::onVsync()SurfaceFlinger::onComposerHalVsync()
  2. VsyncSchedule::addResyncSample() 更新 VSYNC 预测
  3. VSyncDispatchTimerQueue 在预测时间前触发回调
  4. EventThread::onVsync() 创建 VSYNC 事件
  5. EventThread::threadMain() 遍历连接,调用 shouldConsumeEvent()
  6. EventThread::dispatchEvent()EventThreadConnection::postEvent()
  7. 通过 BitTube 发送到 App 端

App 端 VSYNC 回调流程

  1. Looper 检测到 FD 可读 → DisplayEventDispatcher::handleEvent()
  2. processPendingEvents() 读取 VSYNC 事件
  3. dispatchVsync() → JNI 回调到 Java
  4. NativeDisplayEventReceiver::dispatchVsync()DisplayEventReceiver.dispatchVsync()
  5. Choreographer.FrameDisplayEventReceiver.onVsync()
  6. 发送 MSG_DO_FRAME 消息到 vsync 时间执行
  7. doFrame() 执行各类回调 (INPUT → ANIMATION → TRAVERSAL → COMMIT)
  8. 调用 scheduleFrameLocked() 调度下一帧
相关推荐
dalancon2 小时前
VSYNC 信号完整流程2
android
dalancon2 小时前
SurfaceFlinger 上帧后 releaseBuffer 完整流程分析
android
用户69371750013843 小时前
不卷AI速度,我卷自己的从容——北京程序员手记
android·前端·人工智能
程序员Android3 小时前
Android 刷新一帧流程trace拆解
android
墨狂之逸才4 小时前
解决 Android/Gradle 编译报错:Comparison method violates its general contract!
android
阿明的小蝴蝶5 小时前
记一次Gradle环境的编译问题与解决
android·前端·gradle
汪海游龙5 小时前
开源项目 Trending AI 招募 Google Play 内测人员(12 名)
android·github
qq_283720056 小时前
MySQL技巧(四): EXPLAIN 关键参数详细解释
android·adb
没有了遇见7 小时前
Android 架构之网络框架多域名配置<三>
android