Scheduler 初始化
# 深入理解 SurfaceFlinger —— Scheduler 初始化
Scheduler 在 SurfaceFlinger 中主要负责:
- 主线程任务调度,通过父类 MessageQueue 实现
- 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();
}
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
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);
// ......
}
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
- Scheduler 继承自 android::impl::MessageQueue,MessageQueue 利用 Looper 和 Hander 承担了 SurfaceFlinger 主线程事件管理分发的职责,MessageQueue 同时也负责了 Vsync-sf 信号的申请与分发。
- Scheduler 实现了 IEventThreadCallback 接口,IEventThreadCallback 是 Scheduler 提供给 EventThread 的回调接口,定义了 Evnentthread 访问 Scheduler 的协议
- EventThread 类型成员用于管理 Vysnc-app 信号的申请与分发
- mVsyncConfiguration 和 mVsyncModulator 成员用于存储和管理软件 Vsync 信号的相位差
- mDisplays 是 Scheduler::Display 的集合,是 Scheduler 内部显示设备的抽象,方便在 Scheduler 访问显示设备相关特性
- mTouchTimer,mDisplayPowerTimer:两个 OneShotTimer 成员,触摸事件定时器和显示电源定时器,用于响应再触摸和显示电源状态的变化
- 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;
};
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;
};
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)) {}
2
3
4
5
6
7
8
在构造函数中构建了 mLooper 和 mHandler 成员,用于支持 Scheduler 的消息循环功能。
在 SurfaceFligner 的主线程中开启了 Looper 的消息循环处理机制:
// frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp
int main() {
// ....
flinger->run();
// ....
}
2
3
4
5
6
// frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::run() {
mScheduler->run();
}
2
3
4
// frameworks\native\services\surfaceflinger\Scheduler\Scheduler.cpp
void Scheduler::run() {
while (true) {
waitMessage();
}
}
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);
}
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)
- 开始帧合成
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 开始合成
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;
};
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);
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) {}
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)) {}
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;
};
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);
}
}
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;
};
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;
};
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");
}
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;
};
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);
}
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) {
}
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);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
核心功能组件:
- 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);
}
2
3
4
5
6
7
8
9
- VSync 预测 : 基于历史数据预测下一个 VSync 时间
- 周期跟踪 : 监控和调整 VSync 周期
- 异常检测 : 识别和丢弃异常的 VSync 样本
- 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());
}
2
3
4
5
6
7
8
9
- 回调调度 : 管理和调度 VSync 回调函数
- 时间优化 : 将相近的回调合并到同一个 VSync 周期
- 精确定时 : 确保回调在正确的时间执行
- 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;
}
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);
}
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 = {}; // 重置调度策略
}
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;
}
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;
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;
};
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);
}
}
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;
}
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))) {}
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;
}
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);
// ......
}
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();
}
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);
}
}
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;
};
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
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, ¶m) != 0) {
ALOGE("Couldn't set SCHED_FIFO for EventThread");
}
set_sched_policy(tid, SP_FOREGROUND);
}
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;
};
2
3
4
5
6
7
8
9
- throttleVsync(TimePoint expectedPresentTime, uid_t uid)
- 作用:判断是否应该对特定客户端进行 VSYNC 节流(throttle)
- 调用时机:在 shouldConsumeEvent 中决定是否向某个连接派发 VSYNC 事件时
- 典型实现逻辑(由 Scheduler 提供):
- 检查该 UID 的应用是否在后台或低优先级状态
- 判断当前系统负载是否过高
- 检查该客户端的请求频率是否超出限制
- 根据电源策略决定是否降低 VSYNC 频率 返回值:
- true:应该节流,跳过本次 VSYNC 派发
- false:不节流,正常派发
- getVsyncPeriod(uid_t uid)
- 作用: 获取特定客户端应该使用的 VSYNC 周期(帧间隔)
- 调用时机: 在 dispatchEvent 中为 VSYNC 事件填充帧时间线数据时
- 典型实现逻辑:
- 查询该 UID 的帧率覆盖设置(Frame Rate Override)
- 检查应用请求的帧率模式(如 120Hz、90Hz、60Hz)
- 返回对应的周期(例如 16.6ms 对应 60Hz)
- resync()
- 作用: 请求硬件 VSYNC 重新同步
- 调用时机: 当检测到 VSYNC 时序异常或系统需要重新校准软件预测时
- 典型场景:
- 显示模式切换(如刷新率从 60Hz 变为 120Hz)
- VSYNC 预测偏差过大
- 系统从休眠恢复
- 硬件 VSYNC 计数器重置
- 实现效果:
- 触发 Scheduler 启用硬件 VSYNC 信号采样
- 更新 VSyncTracker 的模型参数
- 重新建立软件预测的基准
- onExpectedPresentTimePosted(TimePoint expectedPresentTime)
- 作用: 通知调度器已向客户端发送承诺的预期呈现时间
- 调用时机: 在 dispatchEvent 成功派发 VSYNC 事件后(仅在 VRR 配置启用时) 典型用途:
- Variable Refresh Rate (VRR) 调度:让 Scheduler 知道应用预期的渲染目标时间,以便动态调整刷新率
- 工作负载预测:帮助 Scheduler 提前规划 CPU/GPU 资源分配
- 功耗优化:在低负载时降低刷新率,节省电量
EventThread (事件派发)
↓ 查询策略
IEventThreadCallback
↓ 实现
Scheduler (调度策略)
↓ 控制
VSyncTracker / RefreshRateSelector / PowerAdvisor ....
2
3
4
5
6
7