Ahao's Technical Blog Ahao's Technical Blog
首页
  • 001.基础篇
  • 002.玩转AOSP篇
  • 003.学穿Binder篇
  • 004.基础组件篇
  • 005.系统启动过程分析
  • 006.Hal开发入门与实践
  • 007.显示系统
  • 008.核心系统服务
  • 009.输入系统
  • 010.开发工具
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

阿豪讲Framework

不积跬步无以至千里
首页
  • 001.基础篇
  • 002.玩转AOSP篇
  • 003.学穿Binder篇
  • 004.基础组件篇
  • 005.系统启动过程分析
  • 006.Hal开发入门与实践
  • 007.显示系统
  • 008.核心系统服务
  • 009.输入系统
  • 010.开发工具
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 基础篇

  • 玩转AOSP篇

  • 学穿Binder篇

  • 基础组件篇

  • 系统启动过程分析

  • Hal开发入门与实践

  • 显示系统

    • 如何调试SurfaceFlinger
    • SurfaceFlinger概述
    • HWC 接口分析
    • 启动过程总览
    • SurfaceFlinger 初始化
    • RenderEnginge 初始化
    • 显示设备初始化
    • Scheduler 初始化
      • 1. Scheduler 初始化整体流程
      • 2. Scheduler 对象的构建
        • 2.1 Scheduler 的结构
        • 2.1.1 MessageQueue
        • 2.1.2 IEventThreadCallback
        • 2.2 Scheduler 的初始化
        • 2.2.1 MessageQueue
        • 2.2.2 VsyncConfiguration
        • 2.2.3 VsyncModulator
      • 3. Scheduler::registerDisplay 过程分析
        • 3.1 VsyncSchedule
        • 3.2 registerDisplayInternal
        • 3.2.1 demotePacesetterDisplay 与 promotePacesetterDisplayLocked
        • 3.2.2 Scheduler::Display 对象构建
        • 3.2.3 应用新的 VsyncSchedule
      • 4. EventThread 初始化
    • 跨进程通信
    • 显示疑难问题分析基础
  • 核心系统服务

  • 输入系统

  • 开发工具

  • Framework
  • 显示系统
ahao
2025-11-24
目录

Scheduler 初始化

# 深入理解 SurfaceFlinger —— Scheduler 初始化

Scheduler 在 SurfaceFlinger 中主要负责:

  1. 主线程任务调度,通过父类 MessageQueue 实现
  2. VSYNC 的调度和管理
    • 硬件 VSYNC 同步
    • 动态软件 VSYNC 信号的计算与分发
    • 软件 VSYNC 信号的相位管理

整体的类图:https://boardmix.cn/app/share/CAE.CMLx1wwgASoQUKJdPfT_sYgzSx5tiYHtmjAGQAE/hxtUlY

本文主要分析 Scheduler 的初始化过程,熟悉 Scheduler 的结构组成。

# 1. Scheduler 初始化整体流程

在 Android 系统启动过程中,会执行到 SurfaceFlinger::init 函数来完成 SurfaceFlinger 对象的初始化,该函数中会执行到 SurfaceFlinger::initScheduler 函数来完成 Scheduler 对象的构建与初始化。

// frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::initScheduler(const sp<const DisplayDevice>& display) {
    using namespace scheduler;

    // 防止 mScheduler 的重复初始化
    LOG_ALWAYS_FATAL_IF(mScheduler);

    const auto activeMode = display->refreshRateSelector().getActiveMode();
    const Fps activeRefreshRate = activeMode.fps;
    

    // 通过手机上的配置决定 Scheduler 支持的 Feature
    FeatureFlags features;

    // 根据内容自动调整刷新率
    const auto defaultContentDetectionValue =
            FlagManager::getInstance().enable_fro_dependent_features() &&
            sysprop::enable_frame_rate_override(true);

    if (sysprop::use_content_detection_for_refresh_rate(defaultContentDetectionValue)) {
        features |= Feature::kContentDetection;
        // 小区域脏内容检测
        if (FlagManager::getInstance().enable_small_area_detection()) {
            features |= Feature::kSmallDirtyContentDetection;
        }
    }

    // Vsync 预测
    if (base::GetBoolProperty("debug.sf.show_predicted_vsync"s, false)) {
        features |= Feature::kTracePredictedVsync;
    }

    // Present Fence 支持(用于精确的帧呈现时间测量)
    if (!base::GetBoolProperty("debug.sf.vsync_reactor_ignore_present_fences"s, false) &&
        mHasReliablePresentFences) {
        features |= Feature::kPresentFences;
    }

    // 内核空闲定时器
    if (display->refreshRateSelector().kernelIdleTimerController()) {
        features |= Feature::kKernelIdleTimer;
    }

    // GPU 合成背压控制
    if (mBackpressureGpuComposition) {
        features |= Feature::kBackpressureGpuComposition;
    }

    // 预期呈现时间支持
    if (getHwComposer().getComposer()->isSupported(
                Hwc2::Composer::OptionalFeature::ExpectedPresentTime)) {
        features |= Feature::kExpectedPresentTime;
    }

    // 关注点1,第 2 节,创建 Scheduler 实例,传入必要的接口和配置参数
    mScheduler = std::make_unique<Scheduler>(static_cast<ICompositor&>(*this),
                                             static_cast<ISchedulerCallback&>(*this), features,
                                             getFactory(), activeRefreshRate, *mTimeStats);

    // 关注点2,第 3 节,将显示设备注册到调度器中,建立调度器与显示设备的关联
    // The pacesetter must be registered before EventThread creation below.
    mScheduler->registerDisplay(display->getPhysicalId(), display->holdRefreshRateSelector(),
                                mActiveDisplayId);


    if (FlagManager::getInstance().vrr_config()) {
        mScheduler->setRenderRate(display->getPhysicalId(), activeMode.fps,
                                  /*applyImmediately*/ true);
    }

    // 关注点4,第 4 节,创建两个 EventThread,用于分发软件 Vsync 信号
    const auto configs = mScheduler->getCurrentVsyncConfigs();

    mScheduler->createEventThread(scheduler::Cycle::Render, mFrameTimeline->getTokenManager(),
                                  /* workDuration */ configs.late.appWorkDuration,
                                  /* readyDuration */ configs.late.sfWorkDuration);
    mScheduler->createEventThread(scheduler::Cycle::LastComposite,
                                  mFrameTimeline->getTokenManager(),
                                  /* workDuration */ activeRefreshRate.getPeriod(),
                                  /* readyDuration */ configs.late.sfWorkDuration);

   
    // Dispatch after EventThread creation, since registerDisplay above skipped dispatch.
    // 热插拔事件分发给 EventThread
    mScheduler->dispatchHotplug(display->getPhysicalId(), scheduler::Scheduler::Hotplug::Connected);

    mScheduler->initVsync(*mFrameTimeline->getTokenManager(), configs.late.sfWorkDuration);

    // 创建区域采样线程和 FPS 报告器
    mRegionSamplingThread =
            sp<RegionSamplingThread>::make(*this,
                                           RegionSamplingThread::EnvironmentTimingTunables());
    mFpsReporter = sp<FpsReporter>::make(*mFrameTimeline);

    // Timer callbacks may fire, so do this last.
    // 启动 mTouchTimer 和 mDisplayPowerTimer 定时器
    mScheduler->startTimers();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98

相关调用栈如下:

SurfaceFlinger::init()
    SurfaceFlinger::initScheduler                      
       std::make_unique<Scheduler>(features)     
       Scheduler::registerDisplay                
       Scheduler::setRenderRate                  
       Scheduler::createEventThread              
       Scheduler::dispatchHotplug
       Scheduler::initVsync
       Scheduler::startTimers
1
2
3
4
5
6
7
8
9

# 2. Scheduler 对象的构建

# 2.1 Scheduler 的结构

Scheduler 类的定义:

// frameworks/native/services/surfaceflinger/Scheduler/Scheduler.h
class Scheduler : public IEventThreadCallback, android::impl::MessageQueue {
    // ......
    std::unique_ptr<EventThread> mRenderEventThread;
    std::unique_ptr<EventThread> mLastCompositeEventThread;
    const std::unique_ptr<VsyncConfiguration> mVsyncConfiguration;
    const sp<VsyncModulator> mVsyncModulator;
    const std::unique_ptr<RefreshRateStats> mRefreshRateStats;
    LayerHistory mLayerHistory;
    ftl::Optional<OneShotTimer> mTouchTimer;
    ftl::Optional<OneShotTimer> mDisplayPowerTimer;
    ui::PhysicalDisplayMap<PhysicalDisplayId, Display> mDisplays GUARDED_BY(mDisplayLock)
            GUARDED_BY(kMainThreadContext);
    struct Policy {
        // Policy for choosing the display mode.
        LayerHistory::Summary contentRequirements;
        TimerState idleTimer = TimerState::Reset;
        TouchState touch = TouchState::Inactive;
        TimerState displayPowerTimer = TimerState::Expired;
        hal::PowerMode displayPowerMode = hal::PowerMode::ON;

        // Chosen display mode.
        ftl::Optional<FrameRateMode> modeOpt;

        // Display mode of latest emitted event.
        std::optional<FrameRateMode> emittedModeOpt;
    } mPolicy GUARDED_BY(mPolicyLock);   
    // ......
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
  1. Scheduler 继承自 android::impl::MessageQueue,MessageQueue 利用 Looper 和 Hander 承担了 SurfaceFlinger 主线程事件管理分发的职责,MessageQueue 同时也负责了 Vsync-sf 信号的申请与分发。
  2. Scheduler 实现了 IEventThreadCallback 接口,IEventThreadCallback 是 Scheduler 提供给 EventThread 的回调接口,定义了 Evnentthread 访问 Scheduler 的协议
  3. EventThread 类型成员用于管理 Vysnc-app 信号的申请与分发
  4. mVsyncConfiguration 和 mVsyncModulator 成员用于存储和管理软件 Vsync 信号的相位差
  5. mDisplays 是 Scheduler::Display 的集合,是 Scheduler 内部显示设备的抽象,方便在 Scheduler 访问显示设备相关特性
  6. mTouchTimer,mDisplayPowerTimer:两个 OneShotTimer 成员,触摸事件定时器和显示电源定时器,用于响应再触摸和显示电源状态的变化
  7. mPolicy 用于保存 DMS 传递到 SF 的刷新率需求

# 2.1.1 MessageQueue

MessageQueue 在 SF 中的主要作用:

  • 主线程事件调度分发
  • Vsync-sf 信号的申请与分发

Scheduler 继承自 android::impl::MessageQueue,android::impl::MessageQueue 又继承自 android::MessageQueue。android::MessageQueue 的定义如下:

// frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.h
class MessageQueue {
public:
    virtual ~MessageQueue() = default;

    // Vsync 相关配置
    virtual void initVsyncInternal(std::shared_ptr<scheduler::VSyncDispatch>,
                                   frametimeline::TokenManager&,
                                   std::chrono::nanoseconds workDuration) = 0;
    virtual void destroyVsync() = 0;
    virtual void setDuration(std::chrono::nanoseconds workDuration) = 0;
    // Message 相关操作
    virtual void waitMessage() = 0;
    virtual void postMessage(sp<MessageHandler>&&) = 0;
    virtual void postMessageDelayed(sp<MessageHandler>&&, nsecs_t uptimeDelay) = 0;
    // 发起显示配置操作
    virtual void scheduleConfigure() = 0;
    // 发起帧合成操作
    virtual void scheduleFrame(Duration workDurationSlack = Duration::fromNs(0)) = 0;

    virtual std::optional<scheduler::ScheduleResult> getScheduledFrameResult() const = 0;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

这里是 MessageQueue 的接口设计,定义 MessageQueue 具有的四类功能:

  • Vsync 相关配置
  • Message 相关操作
  • 显示配置操作
  • 帧合成操作

接口的具体实现 android::impl::MessageQueue 的定义如下:

namespace impl {

class MessageQueue : public android::MessageQueue {
protected:

    // 自定义 Handler
    class Handler : public MessageHandler {
        MessageQueue& mQueue;
        std::atomic_bool mFramePending = false;

        std::atomic<VsyncId> mVsyncId;
        std::atomic<TimePoint> mExpectedVsyncTime;

    public:
        explicit Handler(MessageQueue& queue) : 
        (queue) {}
        void handleMessage(const Message& message) override;

        virtual TimePoint getExpectedVsyncTime() const { return mExpectedVsyncTime.load(); }

        virtual bool isFramePending() const;

        virtual void dispatchFrame(VsyncId, TimePoint expectedVsyncTime);
    };

    friend class Handler;

    // For tests.
    MessageQueue(ICompositor&, sp<Handler>);

    void vsyncCallback(nsecs_t vsyncTime, nsecs_t targetWakeupTime, nsecs_t readyTime);

    void onNewVsyncSchedule(std::shared_ptr<scheduler::VSyncDispatch>) EXCLUDES(mVsync.mutex);

private:
    virtual void onFrameSignal(ICompositor&, VsyncId, TimePoint expectedVsyncTime) = 0;

    ICompositor& mCompositor;
    const sp<Looper> mLooper;
    const sp<Handler> mHandler;

    //用于 Vsync-sf 信号申请相关的成员
    struct Vsync {
        frametimeline::TokenManager* tokenManager = nullptr;

        mutable std::mutex mutex;
        std::unique_ptr<scheduler::VSyncCallbackRegistration> registration GUARDED_BY(mutex);
        TracedOrdinal<std::chrono::nanoseconds> workDuration
                GUARDED_BY(mutex) = {"VsyncWorkDuration-sf", std::chrono::nanoseconds(0)};
        TimePoint lastCallbackTime GUARDED_BY(mutex);
        std::optional<scheduler::ScheduleResult> scheduledFrameTimeOpt GUARDED_BY(mutex);
        TracedOrdinal<int> value = {"VSYNC-sf", 0};
    };

    Vsync mVsync;

    // Returns the old registration so it can be destructed outside the lock to
    // avoid deadlock.
    std::unique_ptr<scheduler::VSyncCallbackRegistration> onNewVsyncScheduleLocked(
            std::shared_ptr<scheduler::VSyncDispatch>) REQUIRES(mVsync.mutex);

public:
    explicit MessageQueue(ICompositor&);

    void initVsyncInternal(std::shared_ptr<scheduler::VSyncDispatch>, frametimeline::TokenManager&,
                           std::chrono::nanoseconds workDuration) override;
    void destroyVsync() override;
    void setDuration(std::chrono::nanoseconds workDuration) override;

    void waitMessage() override;
    void postMessage(sp<MessageHandler>&&) override;
    void postMessageDelayed(sp<MessageHandler>&&, nsecs_t uptimeDelay) override;

    void scheduleConfigure() override;
    void scheduleFrame(Duration workDurationSlack = Duration::fromNs(0)) override;

    std::optional<scheduler::ScheduleResult> getScheduledFrameResult() const override;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78

impl::MessageQueue 作为 Scheduler 的父类,为 Schedler 提供了两类功能:

  • 主线程调度
  • Vsync-sf 信号的申请与分发

impl::MessageQueue 主要成员:

  • mCompositor:合成器接口引用,实现类是 SurfaceFlinger,用于 Scheduler 向 Surfaceflinger 发起合成操作
  • mLooper:Android 消息循环(事件驱动核心)
  • mHandler:消息处理器
  • mVsync:SurfaceFlinger 相关的 Vsync 状态和注册信息

内部定义了一个 Handler,主要作用包括:

  • 管理帧调度标记 mFramePending(原子操作,防止重复调度)
  • 记录 Vsync ID 和预期时间戳
  • 将 Vsync 信号转换为 Looper 消息

impl::MessageQueue 的构造函数实现:

// frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.cpp
MessageQueue::MessageQueue(ICompositor& compositor)
      : MessageQueue(compositor, sp<Handler>::make(*this)) {}

MessageQueue::MessageQueue(ICompositor& compositor, sp<Handler> handler)
      : mCompositor(compositor),
        mLooper(sp<Looper>::make(kAllowNonCallbacks)),
        mHandler(std::move(handler)) {}
1
2
3
4
5
6
7
8

在构造函数中构建了 mLooper 和 mHandler 成员,用于支持 Scheduler 的消息循环功能。

在 SurfaceFligner 的主线程中开启了 Looper 的消息循环处理机制:

// frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp
int main() {
    // ....
    flinger->run();
    // ....
}
1
2
3
4
5
6
// frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::run() {
    mScheduler->run();
}
1
2
3
4
// frameworks\native\services\surfaceflinger\Scheduler\Scheduler.cpp
void Scheduler::run() {
    while (true) {
        waitMessage();
    }
}
1
2
3
4
5
6
void MessageQueue::waitMessage() {
    do {
        IPCThreadState::self()->flushCommands();
        int32_t ret = mLooper->pollOnce(-1);
        switch (ret) {
            case Looper::POLL_WAKE:
            case Looper::POLL_CALLBACK:
                continue;
            case Looper::POLL_ERROR:
                ALOGE("Looper::POLL_ERROR");
                continue;
            case Looper::POLL_TIMEOUT:
                // timeout (should not happen)
                continue;
            default:
                // should not happen
                ALOGE("Looper::pollOnce() returned unknown status %d", ret);
                continue;
        }
    } while (true);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

Vsync-sf 信号的申请的整体的工作流程如下(了解):

  1. scheduleFrame()  应用层请求帧合成
           ↓
  2. VSyncCallbackRegistration::schedule()
     - 传递 workDuration、lastVsync      
           ↓
  3. VSyncDispatchTimerQueue::schedule()  
     - 加锁保护                          
           ↓
  4. VSyncDispatchTimerQueueEntry::schedule()
     - VSyncTracker 预测下一个 Vsync 时间 
     - 计算唤醒时间 = vsync - work - ready
           ↓
  5. rearmTimer()                         
     - 找到所有回调中最早的唤醒时间      
     - 设置硬件定时器                     
           ↓
  6. TimeKeeper::alarmAt()                
     - 系统定时器注册                     
           ↓ (定时器到期)
  7. timerCallback()                      
     - 遍历所有待触发的回调               
     - 执行 callback->executing()         
           ↓
  8. vsyncCallback(vsyncTime, wakeup, ready)
     - 生成 VsyncId (TokenManager)        
     - Handler::dispatchFrame()           
           ↓
  9. Looper::sendMessage()                
     - 投递到主线程消息队列               
           ↓
 10. Handler::handleMessage()             
     - onFrameSignal(Compositor)          
     - 开始帧合成                         
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

Vsync-sf 信号的分发的整体的工作流程如下(了解):

1. VSyncDispatch 产生信号 
   ↓
2. vsyncCallback() 接收 (wakeup/ready/vsync 时间)
   ↓
3. 生成 VsyncId (TokenManager)
   ↓
4. Handler::dispatchFrame() (原子标记防重入)
   ↓
5. Looper 发送消息到主线程
   ↓
6. Handler::handleMessage() 执行
   ↓
7. onFrameSignal() 通知 Compositor 开始合成
1
2
3
4
5
6
7
8
9
10
11
12
13

# 2.1.2 IEventThreadCallback

cheduler 实现了 IEventThreadCallback 接口,IEventThreadCallback 是 Scheduler 提供给 EventThread 的回调接口,定义了 Evnentthread 访问 Scheduler 的协议:

struct IEventThreadCallback {
    virtual ~IEventThreadCallback() = default;
    virtual bool throttleVsync(TimePoint, uid_t) = 0;
    virtual Period getVsyncPeriod(uid_t) = 0;
    virtual void resync() = 0;
    virtual void onExpectedPresentTimePosted(TimePoint) = 0;
};
1
2
3
4
5
6
7
  • VSync 节流控制 : throttleVsync() - 根据 UID 控制 VSync 信号的节流
  • VSync 周期获取 : getVsyncPeriod() - 获取特定 UID 的 VSync 周期
  • 重新同步 : resync() - 触发硬件 VSync 重新同步
  • 预期呈现时间通知 : onExpectedPresentTimePosted() - 处理预期呈现时间的发布

# 2.2 Scheduler 的初始化

在了解了 Scheduler 的整体结构以后,我们接着看 Scheduler 对象的构建过程:

// frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::initScheduler(const sp<const DisplayDevice>& display) {
    ...
    FeatureFlags features;
    ...
    mScheduler = std::make_unique<Scheduler>(static_cast<ICompositor&>(*this),
                                             static_cast<ISchedulerCallback&>(*this), features,
                                             getFactory(), activeRefreshRate, *mTimeStats);
1
2
3
4
5
6
7
8

在 SurfaceFlinger::initScheduler 中,根据系统属性和硬件能力构造 FeatureFlags,并以当前活跃刷新率实例化 Scheduler,传入 ICompositor、ISchedulerCallback、Factory、TimeStats 等依赖。

Scheduler 构造函数的实现如下:

// frameworks/native/services/surfaceflinger/Scheduler/Scheduler.cpp
Scheduler::Scheduler(ICompositor& compositor, ISchedulerCallback& callback, FeatureFlags features,
                     surfaceflinger::Factory& factory, Fps activeRefreshRate, TimeStats& timeStats)
        // 2.2.1 父类 MessageQueue 的初始化过程
      : android::impl::MessageQueue(compositor),  
        mFeatures(features), // 特性标记
        // 2.2.2 mVsyncConfiguration 成员的初始化
        mVsyncConfiguration(factory.createVsyncConfiguration(activeRefreshRate)),
        // 2.2.3 mVsyncModulator 成员初始化
        mVsyncModulator(sp<VsyncModulator>::make(mVsyncConfiguration->getCurrentConfigs())),
        // 刷新率统计
        mRefreshRateStats(std::make_unique<RefreshRateStats>(timeStats, activeRefreshRate)),
        // 2.2.4 mSchedulerCallback 用于向 SF 通知调度相关事件
        mSchedulerCallback(callback) {}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 2.2.1 MessageQueue

// frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.cpp
MessageQueue::MessageQueue(ICompositor& compositor)
      : MessageQueue(compositor, sp<Handler>::make(*this)) {}

MessageQueue::MessageQueue(ICompositor& compositor, sp<Handler> handler)
      : mCompositor(compositor),
        mLooper(sp<Looper>::make(kAllowNonCallbacks)),
        mHandler(std::move(handler)) {}
1
2
3
4
5
6
7
8

前面已经提到,这里实例化的成员 mLooper 和 mHander 用于给 SF 提供事件消息机制。

compositor 参数传入的是 SurfaceFlinger 实例,这是一个 ICompositor 接口的实现,该接口用于 Scheduler 在特定的时机向 Surfaceflinger 发起显示图形相关的操作,具体的接口定义如下:

struct ICompositor {
    // 显示器热插拔/配置
    // Configures physical displays, processing hotplug and/or mode setting via the Composer HAL.
    virtual void configure() = 0;

    // 图层的合成的 commit 阶段
    // Commits transactions for layers and displays. Returns whether any state has been invalidated,
    // i.e. whether a frame should be composited for each display.
    virtual bool commit(PhysicalDisplayId pacesetterId, const scheduler::FrameTargets&) = 0;

    // 图层的合成的 composite 阶段
    // Composites a frame for each display. CompositionEngine performs GPU and/or HAL composition
    // via RenderEngine and the Composer HAL, respectively.
    virtual CompositeResultsPerDisplay composite(PhysicalDisplayId pacesetterId,
                                                 const scheduler::FrameTargeters&) = 0;

    // 向显示子系统发送预期的帧呈现时间提示
    // 用于可变刷新率(VRR)场景
    // 帮助显示面板/驱动提前做准备
    // Sends a hint about the expected present time
    virtual void sendNotifyExpectedPresentHint(PhysicalDisplayId) = 0;

    // 通过 RegionSamplingThread 采样合成后的帧
    // 用于亮度采样(Luma Sampling)
    // 支持自适应亮度/色彩调整
    // Samples the composited frame via RegionSamplingThread.
    virtual void sample() = 0;

protected:
    ~ICompositor() = default;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

# 2.2.2 VsyncConfiguration

mVsyncConfiguration 用于保存软件 Vsync 信号的相位差,其值来自 DefaultFactory::createVsyncConfiguration 函数:

// /frameworks/native/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp
std::unique_ptr<scheduler::VsyncConfiguration> DefaultFactory::createVsyncConfiguration(
        Fps currentRefreshRate) {
    if (property_get_bool("debug.sf.use_phase_offsets_as_durations", false)) {
        // 走这个分支
        return std::make_unique<scheduler::impl::WorkDuration>(currentRefreshRate);
    } else {
        return std::make_unique<scheduler::impl::PhaseOffsets>(currentRefreshRate);
    }
}
1
2
3
4
5
6
7
8
9
10

WorkDuration 继承自 VsyncConfiguration,我们先看 VsyncConfiguration 的结构:

// frameworks/native/services/surfaceflinger/Scheduler/VsyncConfiguration.h
class VsyncConfiguration {
public:
    virtual ~VsyncConfiguration() = default;
    virtual VsyncConfigSet getCurrentConfigs() const = 0;
    virtual VsyncConfigSet getConfigsForRefreshRate(Fps fps) const = 0;
    virtual void reset() = 0;

    virtual void setRefreshRateFps(Fps fps) = 0;
    virtual void dump(std::string& result) const = 0;
};

class VsyncConfiguration : public scheduler::VsyncConfiguration {
public:
    explicit VsyncConfiguration(Fps currentFps);

    // Returns early, early GL, and late offsets for Apps and SF for a given refresh rate.
    VsyncConfigSet getConfigsForRefreshRate(Fps fps) const override EXCLUDES(mLock);

    // Returns early, early GL, and late offsets for Apps and SF.
    VsyncConfigSet getCurrentConfigs() const override EXCLUDES(mLock) {
        std::lock_guard lock(mLock);
        return getConfigsForRefreshRateLocked(mRefreshRateFps);
    }

    // Cleans the internal cache.
    void reset() override EXCLUDES(mLock) {
        std::lock_guard lock(mLock);
        mOffsetsCache.clear();
    }

    // This function should be called when the device is switching between different
    // refresh rates, to properly update the offsets.
    void setRefreshRateFps(Fps fps) override EXCLUDES(mLock) {
        std::lock_guard lock(mLock);
        mRefreshRateFps = fps;
    }

    // Returns current offsets in human friendly format.
    void dump(std::string& result) const override;

protected:
    virtual VsyncConfigSet constructOffsets(nsecs_t vsyncDuration) const = 0;

    VsyncConfigSet getConfigsForRefreshRateLocked(Fps fps) const REQUIRES(mLock);

    mutable ftl::SmallMap<Fps, VsyncConfigSet, 2, FpsApproxEqual> mOffsetsCache GUARDED_BY(mLock);
    Fps  
     GUARDED_BY(mLock);
    mutable std::mutex mLock;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

WorkDuration 的实现如下:

// frameworks/native/services/surfaceflinger/Scheduler/VsyncConfiguration.h
class WorkDuration : public VsyncConfiguration {
public:
    explicit WorkDuration(Fps currentRefreshRate);
    WorkDuration(Fps currentRefreshRate, Duration minSfDuration, Duration maxSfDuration,
                 Duration appDuration);

protected:
    // Used for unit tests
    WorkDuration(Fps currentFps, nsecs_t sfDuration, nsecs_t appDuration, nsecs_t sfEarlyDuration,
                 nsecs_t appEarlyDuration, nsecs_t sfEarlyGpuDuration, nsecs_t appEarlyGpuDuration,
                 nsecs_t hwcMinWorkDuration);

private:
    VsyncConfigSet constructOffsets(nsecs_t vsyncDuration) const override;
    
    // 一共三组配置
    
    // late 组,默认使用呢
    const nsecs_t mSfDuration;
    const nsecs_t mAppDuration;

    // early 组
    const nsecs_t mSfEarlyDuration;
    const nsecs_t mAppEarlyDuration;

    // early GPU 组
    const nsecs_t mSfEarlyGpuDuration;
    const nsecs_t mAppEarlyGpuDuration;

    const nsecs_t mHwcMinWorkDuration;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

WorkDuration 构造函数实现如下:

// /frameworks/native/services/surfaceflinger/Scheduler/VsyncConfiguration.cpp
WorkDuration::WorkDuration(Fps currentRefreshRate)
      : WorkDuration(currentRefreshRate, getProperty("debug.sf.late.sf.duration").value_or(-1),
                     getProperty("debug.sf.late.app.duration").value_or(-1),
                     getProperty("debug.sf.early.sf.duration").value_or(mSfDuration),
                     getProperty("debug.sf.early.app.duration").value_or(mAppDuration),
                     getProperty("debug.sf.earlyGl.sf.duration").value_or(mSfDuration),
                     getProperty("debug.sf.earlyGl.app.duration").value_or(mAppDuration),
                     getProperty("debug.sf.hwc.min.duration").value_or(0)) {
    validateSysprops();
}

WorkDuration::WorkDuration(Fps currentRefreshRate, nsecs_t sfDuration, nsecs_t appDuration,
                           nsecs_t sfEarlyDuration, nsecs_t appEarlyDuration,
                           nsecs_t sfEarlyGpuDuration, nsecs_t appEarlyGpuDuration,
                           nsecs_t hwcMinWorkDuration)
      : VsyncConfiguration(currentRefreshRate),
        mSfDuration(sfDuration),
        mAppDuration(appDuration),
        mSfEarlyDuration(sfEarlyDuration),
        mAppEarlyDuration(appEarlyDuration),
        mSfEarlyGpuDuration(sfEarlyGpuDuration),
        mAppEarlyGpuDuration(appEarlyGpuDuration),
        mHwcMinWorkDuration(hwcMinWorkDuration) {}

}

static void validateSysprops() {
    const auto validatePropertyBool = [](const char* prop) {
        LOG_ALWAYS_FATAL_IF(!property_get_bool(prop, false), "%s is false", prop);
    };

    validatePropertyBool("debug.sf.use_phase_offsets_as_durations");

    LOG_ALWAYS_FATAL_IF(sysprop::vsync_event_phase_offset_ns(-1) != -1,
                        "ro.surface_flinger.vsync_event_phase_offset_ns is set but expecting "
                        "duration");

    LOG_ALWAYS_FATAL_IF(sysprop::vsync_sf_event_phase_offset_ns(-1) != -1,
                        "ro.surface_flinger.vsync_sf_event_phase_offset_ns is set but expecting "
                        "duration");

    const auto validateProperty = [](const char* prop) {
        LOG_ALWAYS_FATAL_IF(getProperty(prop).has_value(),
                            "%s is set to %" PRId64 " but expecting duration", prop,
                            getProperty(prop).value_or(-1));
    };

    validateProperty("debug.sf.early_phase_offset_ns");
    validateProperty("debug.sf.early_gl_phase_offset_ns");
    validateProperty("debug.sf.early_app_phase_offset_ns");
    validateProperty("debug.sf.early_gl_app_phase_offset_ns");
    validateProperty("debug.sf.high_fps_late_app_phase_offset_ns");
    validateProperty("debug.sf.high_fps_late_sf_phase_offset_ns");
    validateProperty("debug.sf.high_fps_early_phase_offset_ns");
    validateProperty("debug.sf.high_fps_early_gl_phase_offset_ns");
    validateProperty("debug.sf.high_fps_early_app_phase_offset_ns");
    validateProperty("debug.sf.high_fps_early_gl_app_phase_offset_ns");
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

# 2.2.3 VsyncModulator

VsyncModulator 用于修改软件 Vsync 信号的相位差,相位差从 WorkDuration 中保存的三组配置中选取。

// frameworks/native/services/surfaceflinger/Scheduler/VsyncModulator.h
// Modulates VSYNC phase depending on transaction schedule and refresh rate changes.
class VsyncModulator : public IBinder::DeathRecipient {
public:
    // Number of frames to keep early offsets after an early transaction or GPU composition.
    // This acts as a low-pass filter in case subsequent transactions are delayed, or if the
    // composition strategy alternates on subsequent frames.
    static constexpr int MIN_EARLY_TRANSACTION_FRAMES = 2;
    static constexpr int MIN_EARLY_GPU_FRAMES = 2;

    // Duration to delay the MIN_EARLY_TRANSACTION_FRAMES countdown after an early transaction.
    // This may keep early offsets for an extra frame, but avoids a race with transaction commit.
    static const std::chrono::nanoseconds MIN_EARLY_TRANSACTION_TIME;

    using VsyncConfigOpt = std::optional<VsyncConfig>;

    using Clock = std::chrono::steady_clock;
    using TimePoint = Clock::time_point;
    using Now = TimePoint (*)();

    explicit VsyncModulator(const VsyncConfigSet&, Now = Clock::now);

    bool isVsyncConfigEarly() const EXCLUDES(mMutex);
#ifdef MTK_SF_CPU_POLICY
    bool isVsyncConfigEarlyOnly() const EXCLUDES(mMutex);
#endif
    VsyncConfig getVsyncConfig() const EXCLUDES(mMutex);

    void cancelRefreshRateChange() { mRefreshRateChangePending = false; }

    [[nodiscard]] VsyncConfig setVsyncConfigSet(const VsyncConfigSet&) EXCLUDES(mMutex);

    // Changes offsets in response to transaction flags or commit.
    [[nodiscard]] VsyncConfigOpt setTransactionSchedule(TransactionSchedule,
                                                        const sp<IBinder>& = {}) EXCLUDES(mMutex);
    [[nodiscard]] VsyncConfigOpt onTransactionCommit();

    // Called when we send a refresh rate change to hardware composer, so that
    // we can move into early offsets.
    [[nodiscard]] VsyncConfigOpt onRefreshRateChangeInitiated();

    // Called when we detect from VSYNC signals that the refresh rate changed.
    // This way we can move out of early offsets if no longer necessary.
    [[nodiscard]] VsyncConfigOpt onRefreshRateChangeCompleted();

    [[nodiscard]] VsyncConfigOpt onDisplayRefresh(bool usedGpuComposition);

protected:
    // Called from unit tests as well
    void binderDied(const wp<IBinder>&) override EXCLUDES(mMutex);

private:
    enum class VsyncConfigType { Early, EarlyGpu, Late };

    VsyncConfigType getNextVsyncConfigType() const REQUIRES(mMutex);
    const VsyncConfig& getNextVsyncConfig() const REQUIRES(mMutex);
    [[nodiscard]] VsyncConfig updateVsyncConfig() EXCLUDES(mMutex);
    [[nodiscard]] VsyncConfig updateVsyncConfigLocked() REQUIRES(mMutex);

    mutable std::mutex mMutex;
    VsyncConfigSet mVsyncConfigSet GUARDED_BY(mMutex);

    VsyncConfig mVsyncConfig GUARDED_BY(mMutex){mVsyncConfigSet.late};

    using Schedule = TransactionSchedule;
    std::atomic<Schedule> mTransactionSchedule = Schedule::Late;

    std::unordered_set<wp<IBinder>, WpHash> mEarlyWakeupRequests GUARDED_BY(mMutex);
    std::atomic<bool> mRefreshRateChangePending = false;

    std::atomic<int> mEarlyTransactionFrames = 0;
    std::atomic<int> mEarlyGpuFrames = 0;
    std::atomic<TimePoint> mEarlyTransactionStartTime = TimePoint();
    std::atomic<TimePoint> mLastTransactionCommitTime = TimePoint();

    const Now mNow;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77

VsyncModulator 是 SurfaceFlinger 调度器中的 VSYNC 相位调制器 ,主要负责:

  • 动态调整 VSYNC 偏移量 :根据事务调度和刷新率变化调整 VSYNC 相位
  • 优化渲染时机 :为不同场景提供最优的 SF 和 App 工作时间窗口
  • 响应系统状态变化 :根据 GPU 合成、事务状态等动态切换配置

一般在三种模式直接做切换,三种模式的值保存在 WorkDuration 中:

  • Early 模式 : 提前唤醒,用于处理复杂事务或刷新率变化
  • EarlyGpu 模式 : GPU 合成时的早期唤醒
  • Late 模式 : 正常的延迟唤醒,节省功耗

# 3. Scheduler::registerDisplay 过程分析

// frameworks/native/services/surfaceflinger/Scheduler/Scheduler.h

// mPacesetterDisplayId 用于标识当前的 主导显示器 (Pacesetter Display)。在多显示器系统中,主导显示器负责驱动整个系统的帧率和 VSync 调度。
ftl::Optional<PhysicalDisplayId> mPacesetterDisplayId GUARDED_BY(mDisplayLock)
            GUARDED_BY(kMainThreadContext);

// frameworks/native/services/surfaceflinger/Scheduler/Scheduler.cpp
void Scheduler::registerDisplay(PhysicalDisplayId displayId, RefreshRateSelectorPtr selectorPtr,
                                PhysicalDisplayId activeDisplayId) {

    // 3.1 VsyncSchedule
    auto schedulePtr =
            std::make_shared<VsyncSchedule>(selectorPtr->getActiveMode().modePtr, mFeatures,
                                            [this](PhysicalDisplayId id, bool enable) {
                                                onHardwareVsyncRequest(id, enable);
                                            });

    // 2.2 registerDisplayInternal
    registerDisplayInternal(displayId, std::move(selectorPtr), std::move(schedulePtr),
                            activeDisplayId);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 3.1 VsyncSchedule

先初始化一个 VsyncSchedule 对象,

VsyncSchedule::VsyncSchedule(ftl::NonNull<DisplayModePtr> modePtr, FeatureFlags features,
                             RequestHardwareVsync requestHardwareVsync)
      : mId(modePtr->getPhysicalDisplayId()),
        mRequestHardwareVsync(std::move(requestHardwareVsync)),
        mTracker(createTracker(modePtr)),
        mDispatch(createDispatch(mTracker)),
        mController(createController(modePtr->getPhysicalDisplayId(), *mTracker, features)),
        mTracer(features.test(Feature::kTracePredictedVsync)
                        ? std::make_unique<PredictedVsyncTracer>(mDispatch)
                        : nullptr) {
}
1
2
3
4
5
6
7
8
9
10
11

VsyncSchedule 主要成员有:

using RequestHardwareVsync = std::function<void(PhysicalDisplayId, bool enabled)>;

const PhysicalDisplayId mId;                        // 物理显示器 ID
const RequestHardwareVsync mRequestHardwareVsync;   // 硬件 VSync 请求回调
const TrackerPtr mTracker;                          // VSync 跟踪器
const DispatchPtr mDispatch;                        // VSync 分发器
const ControllerPtr mController;                    // VSync 控制器
const TracerPtr mTracer;                            // VSync 跟踪器(调试用)

// 硬件 VSync 状态相关
mutable std::mutex mHwVsyncLock;                    // 硬件 VSync 状态锁
enum class HwVsyncState {
    Enabled,     // 硬件 VSync 已启用
    Disabled,    // 硬件 VSync 已禁用(可重新启用)
    Disallowed,  // 硬件 VSync 不允许(如显示器关闭)
};
HwVsyncState mHwVsyncState GUARDED_BY(mHwVsyncLock);
HwVsyncState mPendingHwVsyncState GUARDED_BY(kMainThreadContext);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

核心功能组件:

  1. VSync 跟踪器 (VsyncTracker)
VsyncSchedule::TrackerPtr VsyncSchedule::createTracker(ftl::NonNull<DisplayModePtr> modePtr) {
    constexpr size_t kHistorySize = 20;
    constexpr size_t kMinSamplesForPrediction = 6;
    constexpr uint32_t kDiscardOutlierPercent = 20;

    return std::make_unique<VSyncPredictor>(std::make_unique<SystemClock>(), modePtr, 
                                            kHistorySize, kMinSamplesForPrediction, 
                                            kDiscardOutlierPercent);
}
1
2
3
4
5
6
7
8
9
  • VSync 预测 : 基于历史数据预测下一个 VSync 时间
  • 周期跟踪 : 监控和调整 VSync 周期
  • 异常检测 : 识别和丢弃异常的 VSync 样本
  1. VSync 分发器 (VsyncDispatch)
VsyncSchedule::DispatchPtr VsyncSchedule::createDispatch(TrackerPtr tracker) {
    constexpr std::chrono::nanoseconds kGroupDispatchWithin = 500us;
    constexpr std::chrono::nanoseconds kSnapToSameVsyncWithin = 3ms;

    return std::make_unique<VSyncDispatchTimerQueue>(std::make_unique<Timer>(), 
                                                     std::move(tracker),
                                                     kGroupDispatchWithin.count(),
                                                     kSnapToSameVsyncWithin.count());
}
1
2
3
4
5
6
7
8
9
  • 回调调度 : 管理和调度 VSync 回调函数
  • 时间优化 : 将相近的回调合并到同一个 VSync 周期
  • 精确定时 : 确保回调在正确的时间执行
  1. VSync 控制器 (VsyncController)
VsyncSchedule::ControllerPtr VsyncSchedule::createController(PhysicalDisplayId id,
                                                             VsyncTracker& tracker,
                                                             FeatureFlags features) {
    constexpr size_t kMaxPendingFences = 20;
    const bool hasKernelIdleTimer = features.test(Feature::kKernelIdleTimer);

    auto reactor = std::make_unique<VSyncReactor>(id, std::make_unique<SystemClock>(), 
                                                  tracker, kMaxPendingFences, 
                                                  hasKernelIdleTimer);
    return reactor;
}
1
2
3
4
5
6
7
8
9
10
11
  • 硬件同步 : 与硬件 VSync 信号同步
  • 自适应调节 : 根据系统负载调整 VSync 行为
  • 栅栏管理 : 处理显示栅栏和同步

# 3.2 registerDisplayInternal

完成 VsyncSchedule 的初始化后,接着调用 Scheduler::registerDisplayInternal 函数,注册新的显示设备:

// /frameworks/native/services/surfaceflinger/Scheduler/Scheduler.cpp
void Scheduler::registerDisplayInternal(PhysicalDisplayId displayId,
                                        RefreshRateSelectorPtr selectorPtr,
                                        VsyncSchedulePtr schedulePtr,
                                        PhysicalDisplayId activeDisplayId) {
    const bool isPrimary = (ftl::FakeGuard(mDisplayLock), !mPacesetterDisplayId);

    // Start the idle timer for the first registered (i.e. primary) display.
    // 为主显示设备启用空闲定时器切换
    // PromotionParams 结构体控制是否启动/停止空闲定时器
    const PromotionParams promotionParams = {.toggleIdleTimer = isPrimary};

    // 3.2.1
    demotePacesetterDisplay(promotionParams);

    auto [pacesetterVsyncSchedule, isNew] = [&]() REQUIRES(kMainThreadContext) {
        std::scoped_lock lock(mDisplayLock);
        // 3.2.2 Scheduler::Display 对象构建
        const bool isNew = mDisplays
                                   .emplace_or_replace(displayId, displayId, std::move(selectorPtr),
                                                       std::move(schedulePtr), mFeatures)
                                   .second;

        // 3.2.1
        return std::make_pair(promotePacesetterDisplayLocked(activeDisplayId, promotionParams),
                              isNew);
    }();

    // 3.2.3 应用新的 VsyncSchedule
    applyNewVsyncSchedule(std::move(pacesetterVsyncSchedule));

    // Disable hardware VSYNC if the registration is new, as opposed to a renewal.
    if (isNew) {
        onHardwareVsyncRequest(displayId, false);
    }

    dispatchHotplug(displayId, Hotplug::Connected);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

# 3.2.1 demotePacesetterDisplay 与 promotePacesetterDisplayLocked

demotePacesetterDisplay 用于降级当前 Pacesetter:

// frameworks/native/services/surfaceflinger/Scheduler/Scheduler.h
void Scheduler::demotePacesetterDisplay(PromotionParams params) {
    if (params.toggleIdleTimer) {
        // No need to lock for reads on kMainThreadContext.
        // 拿到 RefreshRateSelector
        if (const auto pacesetterPtr =
                    FTL_FAKE_GUARD(mDisplayLock, pacesetterSelectorPtrLocked())) {
            pacesetterPtr->stopIdleTimer();  // 停止旧 pacesetter 的空闲定时器
            pacesetterPtr->clearIdleTimerCallbacks(); // 清除相关回调
        }
    }

    // Clear state that depends on the pacesetter's RefreshRateSelector.
    std::scoped_lock lock(mPolicyLock);
    mPolicy = {};   // 重置调度策略
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

promotePacesetterDisplayLocked 用于晋升新 Pacesetter:

// frameworks/native/services/surfaceflinger/Scheduler/Scheduler.h
std::shared_ptr<VsyncSchedule> Scheduler::promotePacesetterDisplayLocked(
        PhysicalDisplayId pacesetterId, PromotionParams params) {
    // TODO: b/241286431 - Choose the pacesetter among mDisplays.
    // 设置 mPacesetterDisplayId,
    // 关键,该参数用于确定主显示设备
    mPacesetterDisplayId = pacesetterId;
    ALOGI("Display %s is the pacesetter", to_string(pacesetterId).c_str());

    std::shared_ptr<VsyncSchedule> newVsyncSchedulePtr;
    if (const auto pacesetterOpt = pacesetterDisplayLocked()) {
        const Display& pacesetter = *pacesetterOpt;

        if (params.toggleIdleTimer) {
            // 配置空闲定时器回调(platform、kernel、VRR)
            pacesetter.selectorPtr->setIdleTimerCallbacks(
                    {.platform = {.onReset = [this] { idleTimerCallback(TimerState::Reset); },
                                  .onExpired = [this] { idleTimerCallback(TimerState::Expired); }},
                     .kernel = {.onReset = [this] { kernelIdleTimerCallback(TimerState::Reset); },
                                .onExpired =
                                        [this] { kernelIdleTimerCallback(TimerState::Expired); }},
                     .vrr = {.onReset = [this] { mSchedulerCallback.vrrDisplayIdle(false); },
                             .onExpired = [this] { mSchedulerCallback.vrrDisplayIdle(true); }}});
            // 启动空闲定时器
            pacesetter.selectorPtr->startIdleTimer();
        }

        newVsyncSchedulePtr = pacesetter.schedulePtr;

        constexpr bool kForce = true;
        // 通知 VysncSchedule 显示模式变化
        newVsyncSchedulePtr->onDisplayModeChanged(pacesetter.selectorPtr->getActiveMode().modePtr,
                                                  kForce);
    }
    return newVsyncSchedulePtr;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

# 3.2.2 Scheduler::Display 对象构建

Scheduler::Display 对象构建过程:

        ui::PhysicalDisplayMap<PhysicalDisplayId, Display> mDisplays GUARDED_BY(mDisplayLock)
            GUARDED_BY(kMainThreadContext);

         const bool isNew = mDisplays
                                   .emplace_or_replace(displayId, displayId, std::move(selectorPtr),
                                                       std::move(schedulePtr), mFeatures)
                                   .second;

1
2
3
4
5
6
7
8

Scheduler::Display 是事件调度和 Vsync 管理过程中显示设备的抽象,其定义如下:

    // frameworks/native/services/surfaceflinger/Scheduler/Scheduler.h
    struct Display {
        Display(PhysicalDisplayId displayId, RefreshRateSelectorPtr selectorPtr,
                VsyncSchedulePtr schedulePtr, FeatureFlags features)
              : displayId(displayId),
                selectorPtr(std::move(selectorPtr)),
                schedulePtr(std::move(schedulePtr)),
                targeterPtr(std::make_unique<FrameTargeter>(displayId, features)) {}

        const PhysicalDisplayId displayId;

        // Effectively const except in move constructor.
        RefreshRateSelectorPtr selectorPtr;
        VsyncSchedulePtr schedulePtr;
        FrameTargeterPtr targeterPtr;

        hal::PowerMode powerMode = hal::PowerMode::OFF;
    };
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

Scheduler::Display 保存了显示显示设备相关的熟悉和管理类,方便在调度过程中使用。

# 3.2.3 应用新的 VsyncSchedule

// /frameworks/native/services/surfaceflinger/Scheduler/Scheduler.cpp
void Scheduler::applyNewVsyncSchedule(std::shared_ptr<VsyncSchedule> vsyncSchedule) {
    onNewVsyncSchedule(vsyncSchedule->getDispatch());

    if (hasEventThreads()) { // 目前还执行不懂啊
        eventThreadFor(Cycle::Render).onNewVsyncSchedule(vsyncSchedule);
        eventThreadFor(Cycle::LastComposite).onNewVsyncSchedule(vsyncSchedule);
    }
}

1
2
3
4
5
6
7
8
9
10
// frameworks/native/services/surfaceflinger/Scheduler/MessageQueue.cpp
void MessageQueue::onNewVsyncSchedule(std::shared_ptr<scheduler::VSyncDispatch> dispatch) {
    std::unique_ptr<scheduler::VSyncCallbackRegistration> oldRegistration;
    {
        std::lock_guard lock(mVsync.mutex);
        oldRegistration = onNewVsyncScheduleLocked(std::move(dispatch));
    }

    // The old registration needs to be deleted after releasing mVsync.mutex to
    // avoid deadlock. This is because the callback may be running on the timer
    // thread. In that case, timerCallback sets
    // VSyncDispatchTimerQueueEntry::mRunning to true, then attempts to lock
    // mVsync.mutex. But if it's already locked, the VSyncCallbackRegistration's
    // destructor has to wait until VSyncDispatchTimerQueueEntry::mRunning is
    // set back to false, but it won't be until mVsync.mutex is released.
    oldRegistration.reset();
}

std::unique_ptr<scheduler::VSyncCallbackRegistration> MessageQueue::onNewVsyncScheduleLocked(
        std::shared_ptr<scheduler::VSyncDispatch> dispatch) {
    const bool reschedule = mVsync.registration &&
            mVsync.registration->cancel() == scheduler::CancelResult::Cancelled;
    auto oldRegistration = std::move(mVsync.registration);

    // 重点
    // 1. 构建一个 VSyncCallbackRegistration 对象,VSyncCallbackRegistration 有两个重要成员:
    //    * mToken, VSyncCallbackRegistration 初始化时,会向 mDispatch(VSyncDispatchTimerQueue)注册一个 Callback(MessageQueue::vsyncCallback,sf),这里的 mToken 是 Callback 对象在  mCallbacks 中的 index,实际就是一个 size_t
    //    * mDispatch,实际类型是 VSyncDispatchTimerQueue,主要用于软件 Vsync 的申请和分发
    mVsync.registration = std::make_unique<
            scheduler::VSyncCallbackRegistration>(std::move(dispatch),
                                                  std::bind(&MessageQueue::vsyncCallback, this,
                                                            std::placeholders::_1,
                                                            std::placeholders::_2,
                                                            std::placeholders::_3),
                                                  "sf");
    if (reschedule) {
        mVsync.scheduledFrameTimeOpt =
                mVsync.registration->schedule({.workDuration = mVsync.workDuration.get().count(),
                                               .readyDuration = 0,
                                               .lastVsync = mVsync.lastCallbackTime.ns()});
    }
    return oldRegistration;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

这里更新 mVsync 中的数据,为后续 Vsync-sf 的申请和分发做好准备。

// frameworks/native/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp
VSyncCallbackRegistration::VSyncCallbackRegistration(std::shared_ptr<VSyncDispatch> dispatch,
                                                     VSyncDispatch::Callback callback,
                                                     std::string callbackName)
      : mDispatch(std::move(dispatch)),
        mToken(mDispatch->registerCallback(std::move(callback), std::move(callbackName))) {}
1
2
3
4
5
6

mToken 是一个 Callback 的索引。

// frameworks/native/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.h
using CallbackMap =
            ftl::SmallMap<CallbackToken, std::shared_ptr<VSyncDispatchTimerQueueEntry>, 5>;
CallbackMap mCallbacks GUARDED_BY(mMutex);
CallbackToken mCallbackToken GUARDED_BY(mMutex); // 实际就是一个 size_t

// frameworks/native/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp
VSyncDispatchTimerQueue::CallbackToken VSyncDispatchTimerQueue::registerCallback(
        Callback callback, std::string callbackName) {
    std::lock_guard lock(mMutex);
    // 注册到这里
    return mCallbacks
            .try_emplace(++mCallbackToken,
                         std::make_shared<VSyncDispatchTimerQueueEntry>(std::move(callbackName),
                                                                        std::move(callback),
                                                                        mMinVsyncDistance))
            .first->first;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 4. EventThread 初始化

EventThread 用于管理和分发 Vsync-app Vsync-appsf 信号。

本节分析 EventThread 的初始化过程:

// frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::initScheduler(const sp<const DisplayDevice>& display) {

    //.....

    // 创建两个 EventThread,用于分发软件 Vsync 信号
    const auto configs = mScheduler->getCurrentVsyncConfigs();

    mScheduler->createEventThread(scheduler::Cycle::Render, mFrameTimeline->getTokenManager(),
                                  /* workDuration */ configs.late.appWorkDuration,
                                  /* readyDuration */ configs.late.sfWorkDuration);
    mScheduler->createEventThread(scheduler::Cycle::LastComposite,
                                  mFrameTimeline->getTokenManager(),
                                  /* workDuration */ activeRefreshRate.getPeriod(),
                                  /* readyDuration */ configs.late.sfWorkDuration);
    // ......

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

获取软件 Vsync 的配置:

// frameworks/native/services/surfaceflinger/Scheduler/Scheduler.h
    VsyncConfigSet getCurrentVsyncConfigs() const EXCLUDES(mVsyncConfigLock) {
        std::scoped_lock lock{mVsyncConfigLock};
        return mVsyncConfiguration->getCurrentConfigs();
    }
1
2
3
4
5

EventThread 对象的初始化过程:

// frameworks/native/services/surfaceflinger/Scheduler/Scheduler.cpp
void Scheduler::createEventThread(Cycle cycle, frametimeline::TokenManager* tokenManager,
                                  std::chrono::nanoseconds workDuration,
                                  std::chrono::nanoseconds readyDuration) {
    auto eventThread =
            std::make_unique<android::impl::EventThread>(cycle == Cycle::Render ? "app" : "appSf",
                                                         getVsyncSchedule(), tokenManager, *this,
                                                         workDuration, readyDuration);

    if (cycle == Cycle::Render) {
        mRenderEventThread = std::move(eventThread);
    } else {
        mLastCompositeEventThread = std::move(eventThread);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

EventThread 的定义:

// frameworks/native/services/surfaceflinger/Scheduler/EventThread.h
// EventThread 接口
class EventThread {
public:
    virtual ~EventThread();

    virtual sp<EventThreadConnection> createEventConnection(
            EventRegistrationFlags eventRegistration = {}) const = 0;

    // Feed clients with fake VSYNC, e.g. while the display is off.
    virtual void enableSyntheticVsync(bool) = 0;

    virtual void omitVsyncDispatching(bool) = 0;

    virtual void onHotplugReceived(PhysicalDisplayId displayId, bool connected) = 0;

    virtual void onHotplugConnectionError(int32_t connectionError) = 0;

    // called when SF changes the active mode and apps needs to be notified about the change
    virtual void onModeChanged(const scheduler::FrameRateMode&) = 0;

    // called when SF rejects the mode change request
    virtual void onModeRejected(PhysicalDisplayId displayId, DisplayModeId modeId) = 0;

    // called when SF updates the Frame Rate Override list
    virtual void onFrameRateOverridesChanged(PhysicalDisplayId displayId,
                                             std::vector<FrameRateOverride> overrides) = 0;****

    virtual void dump(std::string& result) const = 0;

    virtual void setDuration(std::chrono::nanoseconds workDuration,
                             std::chrono::nanoseconds readyDuration) = 0;

    virtual status_t registerDisplayEventConnection(
            const sp<EventThreadConnection>& connection) = 0;
    virtual void setVsyncRate(uint32_t rate, const sp<EventThreadConnection>& connection) = 0;
    // Requests the next vsync. If resetIdleTimer is set to true, it resets the idle timer.
    virtual void requestNextVsync(const sp<EventThreadConnection>& connection) = 0;
    virtual VsyncEventData getLatestVsyncEventData(const sp<EventThreadConnection>& connection,
                                                   nsecs_t now) const = 0;

    virtual void onNewVsyncSchedule(std::shared_ptr<scheduler::VsyncSchedule>) = 0;

    virtual void onHdcpLevelsChanged(PhysicalDisplayId displayId, int32_t connectedLevel,
                                     int32_t maxLevel) = 0;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

imp::EventThread 实现:

namespace impl {

class EventThread : public android::EventThread {
public:
    EventThread(const char* name, std::shared_ptr<scheduler::VsyncSchedule>,
                frametimeline::TokenManager*, IEventThreadCallback& callback,
                std::chrono::nanoseconds workDuration, std::chrono::nanoseconds readyDuration);
    ~EventThread();

    sp<EventThreadConnection> createEventConnection(
            EventRegistrationFlags eventRegistration = {}) const override;

    status_t registerDisplayEventConnection(const sp<EventThreadConnection>& connection) override;
    void setVsyncRate(uint32_t rate, const sp<EventThreadConnection>& connection) override;
    void requestNextVsync(const sp<EventThreadConnection>& connection) override;
    VsyncEventData getLatestVsyncEventData(const sp<EventThreadConnection>& connection,
                                           nsecs_t now) const override;

    void enableSyntheticVsync(bool) override;

    void omitVsyncDispatching(bool) override;

    void onHotplugReceived(PhysicalDisplayId displayId, bool connected) override;

    void onHotplugConnectionError(int32_t connectionError) override;

    void onModeChanged(const scheduler::FrameRateMode&) override;

    void onModeRejected(PhysicalDisplayId displayId, DisplayModeId modeId) override;

    void onFrameRateOverridesChanged(PhysicalDisplayId displayId,
                                     std::vector<FrameRateOverride> overrides) override;

    void dump(std::string& result) const override;

    void setDuration(std::chrono::nanoseconds workDuration,
                     std::chrono::nanoseconds readyDuration) override;

    void onNewVsyncSchedule(std::shared_ptr<scheduler::VsyncSchedule>) override EXCLUDES(mMutex);

    void onHdcpLevelsChanged(PhysicalDisplayId displayId, int32_t connectedLevel,
                             int32_t maxLevel) override;

private:
    friend EventThreadTest;

    using DisplayEventConsumers = std::vector<sp<EventThreadConnection>>;

    void threadMain(std::unique_lock<std::mutex>& lock) REQUIRES(mMutex);

    bool shouldConsumeEvent(const DisplayEventReceiver::Event& event,
                            const sp<EventThreadConnection>& connection) const REQUIRES(mMutex);
    void dispatchEvent(const DisplayEventReceiver::Event& event,
                       const DisplayEventConsumers& consumers) REQUIRES(mMutex);

    void removeDisplayEventConnectionLocked(const wp<EventThreadConnection>& connection)
            REQUIRES(mMutex);

    void onVsync(nsecs_t vsyncTime, nsecs_t wakeupTime, nsecs_t readyTime);

    int64_t generateToken(nsecs_t timestamp, nsecs_t deadlineTimestamp,
                          nsecs_t expectedPresentationTime) const;
    void generateFrameTimeline(VsyncEventData& outVsyncEventData, nsecs_t frameInterval,
                               nsecs_t timestamp, nsecs_t preferredExpectedPresentationTime,
                               nsecs_t preferredDeadlineTimestamp) const;

    scheduler::VSyncDispatch::Callback createDispatchCallback();

    // Returns the old registration so it can be destructed outside the lock to
    // avoid deadlock.
    scheduler::VSyncCallbackRegistration onNewVsyncScheduleInternal(
            std::shared_ptr<scheduler::VsyncSchedule>) EXCLUDES(mMutex);

    const char* const mThreadName;
    TracedOrdinal<int> mVsyncTracer;
    TracedOrdinal<std::chrono::nanoseconds> mWorkDuration GUARDED_BY(mMutex);
    std::chrono::nanoseconds mReadyDuration GUARDED_BY(mMutex);
    std::shared_ptr<scheduler::VsyncSchedule> mVsyncSchedule GUARDED_BY(mMutex);
    TimePoint mLastVsyncCallbackTime GUARDED_BY(mMutex) = TimePoint::now();
    TimePoint mLastCommittedVsyncTime GUARDED_BY(mMutex) = TimePoint::now();
    scheduler::VSyncCallbackRegistration mVsyncRegistration GUARDED_BY(mMutex);
    frametimeline::TokenManager* const mTokenManager;

    IEventThreadCallback& mCallback;

    std::thread mThread;
    mutable std::mutex mMutex;
    mutable std::condition_variable mCondition;

    std::vector<wp<EventThreadConnection>> mDisplayEventConnections GUARDED_BY(mMutex);
    std::deque<DisplayEventReceiver::Event> mPendingEvents GUARDED_BY(mMutex);

    // VSYNC state of connected display.
    struct VSyncState {
        // Number of VSYNC events since display was connected.
        uint32_t count = 0;

        // True if VSYNC should be faked, e.g. when display is off.
        bool synthetic = false;

        // True if VSYNC should not be delivered to apps. Used when the display is off.
        bool omitted = false;
    };

    // TODO(b/74619554): Create per-display threads waiting on respective VSYNC signals,
    // and support headless mode by injecting a fake display with synthetic VSYNC.
    std::optional<VSyncState> mVSyncState GUARDED_BY(mMutex);

    // State machine for event loop.
    enum class State {
        Idle,
        Quit,
        SyntheticVSync,
        VSync,
    };

    State mState GUARDED_BY(mMutex) = State::Idle;

    static const char* toCString(State);
};

// ---------------------------------------------------------------------------

} // namespace impl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124

EventThread 构造函数的实现:

EventThread::EventThread(const char* name, std::shared_ptr<scheduler::VsyncSchedule> vsyncSchedule,
                         android::frametimeline::TokenManager* tokenManager,
                         IEventThreadCallback& callback, std::chrono::nanoseconds workDuration,
                         std::chrono::nanoseconds readyDuration)
      : mThreadName(name),
        mVsyncTracer(base::StringPrintf("VSYNC-%s", name), 0),
        mWorkDuration(base::StringPrintf("VsyncWorkDuration-%s", name), workDuration),
        mReadyDuration(readyDuration),
        mVsyncSchedule(std::move(vsyncSchedule)),
        mVsyncRegistration(mVsyncSchedule->getDispatch(), createDispatchCallback(), name),
        mTokenManager(tokenManager),
        mCallback(callback) {

    // 启动线程
    mThread = std::thread([this]() NO_THREAD_SAFETY_ANALYSIS {
        std::unique_lock<std::mutex> lock(mMutex);
        threadMain(lock);
    });

    pthread_setname_np(mThread.native_handle(), mThreadName);

    pid_t tid = pthread_gettid_np(mThread.native_handle());

    // Use SCHED_FIFO to minimize jitter
    constexpr int EVENT_THREAD_PRIORITY = 2;
    struct sched_param param = {0};
    param.sched_priority = EVENT_THREAD_PRIORITY;
    if (pthread_setschedparam(mThread.native_handle(), SCHED_FIFO, &param) != 0) {
        ALOGE("Couldn't set SCHED_FIFO for EventThread");
    }

    set_sched_policy(tid, SP_FOREGROUND);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
  • mThreadName(name):保存线程名(如 "app" 或 "appSf"),用于日志和 tracing
  • mVsyncTracer:初始化 systrace 追踪器,标签为 "VSYNC-{name}",便于性能分析
  • mWorkDuration:带追踪的工作耗时参数("VsyncWorkDuration-{name}"),用于调度器计算唤醒时机
  • mReadyDuration:准备耗时(app 绘制完成到提交的时间)
  • mVsyncSchedule:VSYNC 调度器(包含 VSyncDispatch 和 VSyncTracker),用 move 语义获取所有权
  • mVsyncRegistration:关键步骤!向调度器注册回调 createDispatchCallback(),使得硬件 VSYNC 到来时能调用 onVsync 方法
  • mTokenManager:帧时间线令牌管理器(用于生成 vsyncId)
  • mCallback:外部回调接口(用于节流判断、获取帧间隔、触发同步等),这里传入的 Scheduler 对象

mCallback 成员是 EventThread 向 Scheduler 通信的接口

// frameworks/native/services/surfaceflinger/Scheduler/EventThread.h
struct IEventThreadCallback {
    virtual ~IEventThreadCallback() = default;

    virtual bool throttleVsync(TimePoint, uid_t) = 0;
    virtual Period getVsyncPeriod(uid_t) = 0;
    virtual void resync() = 0;
    virtual void onExpectedPresentTimePosted(TimePoint) = 0;
};
1
2
3
4
5
6
7
8
9
  1. throttleVsync(TimePoint expectedPresentTime, uid_t uid)
  • 作用:判断是否应该对特定客户端进行 VSYNC 节流(throttle)
  • 调用时机:在 shouldConsumeEvent 中决定是否向某个连接派发 VSYNC 事件时
  • 典型实现逻辑(由 Scheduler 提供):
    • 检查该 UID 的应用是否在后台或低优先级状态
    • 判断当前系统负载是否过高
    • 检查该客户端的请求频率是否超出限制
    • 根据电源策略决定是否降低 VSYNC 频率 返回值:
    • true:应该节流,跳过本次 VSYNC 派发
    • false:不节流,正常派发
  1. getVsyncPeriod(uid_t uid)
  • 作用: 获取特定客户端应该使用的 VSYNC 周期(帧间隔)
  • 调用时机: 在 dispatchEvent 中为 VSYNC 事件填充帧时间线数据时
  • 典型实现逻辑:
    • 查询该 UID 的帧率覆盖设置(Frame Rate Override)
    • 检查应用请求的帧率模式(如 120Hz、90Hz、60Hz)
    • 返回对应的周期(例如 16.6ms 对应 60Hz)
  1. resync()
  • 作用: 请求硬件 VSYNC 重新同步
  • 调用时机: 当检测到 VSYNC 时序异常或系统需要重新校准软件预测时
  • 典型场景:
    • 显示模式切换(如刷新率从 60Hz 变为 120Hz)
    • VSYNC 预测偏差过大
    • 系统从休眠恢复
    • 硬件 VSYNC 计数器重置
  • 实现效果:
    • 触发 Scheduler 启用硬件 VSYNC 信号采样
    • 更新 VSyncTracker 的模型参数
    • 重新建立软件预测的基准
  1. onExpectedPresentTimePosted(TimePoint expectedPresentTime)
  • 作用: 通知调度器已向客户端发送承诺的预期呈现时间
  • 调用时机: 在 dispatchEvent 成功派发 VSYNC 事件后(仅在 VRR 配置启用时) 典型用途:
  • Variable Refresh Rate (VRR) 调度:让 Scheduler 知道应用预期的渲染目标时间,以便动态调整刷新率
  • 工作负载预测:帮助 Scheduler 提前规划 CPU/GPU 资源分配
  • 功耗优化:在低负载时降低刷新率,节省电量
EventThread (事件派发)
    ↓ 查询策略
IEventThreadCallback
    ↓ 实现
Scheduler (调度策略)
    ↓ 控制
VSyncTracker / RefreshRateSelector / PowerAdvisor ....
1
2
3
4
5
6
7
显示设备初始化
跨进程通信

← 显示设备初始化 跨进程通信→

最近更新
01
跨进程通信
11-24
02
显示设备初始化
10-17
03
显示疑难问题分析基础
10-08
更多文章>
Theme by Vdoing | Copyright © 2020-2025 AHao Framework | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式