目录
[🏗️ 核心架构组件说明](#🏗️ 核心架构组件说明)
[1. 调度器(Scheduler)](#1. 调度器(Scheduler))
[2. 事件线程(EventThread)](#2. 事件线程(EventThread))
一.代码路径:
本篇的代码路径,基于Android 15代码进行分析的
/frameworks/native/services/surfaceflinger
二.SurfaceFlinger初始化
接上篇:
https://blog.csdn.net/gongjdde/article/details/154454305?spm=1001.2101.3001.10796
我们分析了Surfaceflinger的创建过程,在main_surfaceflinger.cpp的main函数中进行Surfaceflinger的创建以及初始化操作,具体如下是我简略过后的代码:
int main(int, char**) {
...
// instantiate surfaceflinger
// 创建Surfaceflinger实例
sp<SurfaceFlinger> flinger = surfaceflinger::createSurfaceFlinger();
// Set the minimum policy of surfaceflinger node to be SCHED_FIFO.
// So any thread with policy/priority lower than {SCHED_FIFO, 1}, will run
// at least with SCHED_FIFO policy and priority 1.
if (errorInPriorityModification == 0) {
flinger->setMinSchedulerPolicy(SCHED_FIFO, newPriority);
}
setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);
set_sched_policy(0, SP_FOREGROUND);
// initialize before clients can connect
// 进行Surfaceflinger的初始化操作
flinger->init();
// publish surface flinger
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,
IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);
// publish gui::ISurfaceComposer, the new AIDL interface
sp<SurfaceComposerAIDL> composerAIDL = sp<SurfaceComposerAIDL>::make(flinger);
if (FlagManager::getInstance().misc1()) {
composerAIDL->setMinSchedulerPolicy(SCHED_FIFO, newPriority);
}
sm->addService(String16("SurfaceFlingerAIDL"), composerAIDL, false,
IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);
startDisplayService(); // dependency on SF getting registered above
if (SurfaceFlinger::setSchedFifo(true) != NO_ERROR) {
ALOGW("Failed to set SCHED_FIFO during boot: %s", strerror(errno));
}
// run surface flinger in this thread
flinger->run();
return 0;
}
如上代码可以看出来创建的SurfaceFlinger先调用init函数,进行一些初始化操作,然后调用run函数
首先我们来分析下SurfaceFlinger的init函数
cpp
/**
* SurfaceFlinger 核心初始化流程 - 建立Android图形系统运行环境
*
* 此函数在系统启动时调用,负责创建和配置所有图形合成相关的核心组件,
* 包括渲染引擎、硬件合成器、调度系统、显示管理等。
*/
void SurfaceFlinger::init() FTL_FAKE_GUARD(kMainThreadContext) {
ATRACE_CALL();
ALOGI("SurfaceFlinger's main thread ready to run. Initializing graphics H/W...");
// 1. 基础设置:事务过滤器和线程锁
addTransactionReadyFilters();
Mutex::Autolock lock(mStateLock);
// 2. 创建渲染引擎 (RenderEngine) - 负责2D/3D图形渲染
auto builder = renderengine::RenderEngineCreationArgs::Builder()
.setPixelFormat(static_cast<int32_t>(defaultCompositionPixelFormat))
.setImageCacheSize(maxFrameBufferAcquiredBuffers)
.setEnableProtectedContext(enable_protected_contents(false))
.setPrecacheToneMapperShaderOnly(false)
.setBlurAlgorithm(chooseBlurAlgorithm(mSupportsBlur))
.setContextPriority(
useContextPriority
? renderengine::RenderEngine::ContextPriority::REALTIME
: renderengine::RenderEngine::ContextPriority::MEDIUM);
chooseRenderEngineType(builder);
mRenderEngine = renderengine::RenderEngine::create(builder.build());
mCompositionEngine->setRenderEngine(mRenderEngine.get());
mMaxRenderTargetSize =
std::min(getRenderEngine().getMaxTextureSize(), getRenderEngine().getMaxViewportDims());
// 3. 设置线程调度策略和硬件合成器
if (!SetTaskProfiles(0, {"SFMainPolicy"})) {
ALOGW("Failed to set main task profile");
}
mCompositionEngine->setTimeStats(mTimeStats);
mCompositionEngine->setHwComposer(getFactory().createHWComposer(mHwcServiceName));
auto& composer = mCompositionEngine->getHwComposer();
composer.setCallback(*this);
mDisplayModeController.setHwComposer(&composer);
// 4. 客户端缓存和配置标志设置
ClientCache::getInstance().setRenderEngine(&getRenderEngine());
mHasReliablePresentFences =
!getHwComposer().hasCapability(Capability::PRESENT_FENCE_IS_NOT_RELIABLE);
enableLatchUnsignaledConfig = getLatchUnsignaledConfig();
// 5. 初始显示配置 - 检测启动时已连接的显示器
LOG_ALWAYS_FATAL_IF(!configureLocked(), "Initial display configuration failed: HWC did not hotplug");
// 6. 提交主显示器配置并初始化调度器
sp<const DisplayDevice> display;
if (const auto indexOpt = mCurrentState.getDisplayIndex(getPrimaryDisplayIdLocked())) {
const auto& displays = mCurrentState.displays;
const auto& token = displays.keyAt(*indexOpt);
const auto& state = displays.valueAt(*indexOpt);
processDisplayAdded(token, state);
mDrawingState.displays.add(token, state);
display = getDefaultDisplayDeviceLocked();
}
LOG_ALWAYS_FATAL_IF(!display, "Failed to configure the primary display");
LOG_ALWAYS_FATAL_IF(!getHwComposer().isConnected(display->getPhysicalId()),
"Primary display is disconnected");
// 7. 初始化调度系统 (Scheduler) - 图形合成的"大脑"
initScheduler(display);
// 8. 设置显示模式变化监听器
mDisplayModeController.setActiveModeListener(
display::DisplayModeController::ActiveModeListener::make(
[this](PhysicalDisplayId displayId, Fps vsyncRate, Fps renderRate) {
static_cast<void>(mScheduler->schedule([=, this]() FTL_FAKE_GUARD(mStateLock) {
if (const auto display = getDisplayDeviceLocked(displayId)) {
display->updateRefreshRateOverlayRate(vsyncRate, renderRate);
}
}));
}));
// 9. 设置图层追踪和快照功能 (用于调试和性能分析)
mLayerTracing.setTakeLayersSnapshotProtoFunction([&](uint32_t traceFlags) {
auto snapshot = perfetto::protos::LayersSnapshotProto{};
mScheduler
->schedule([&]() FTL_FAKE_GUARD(mStateLock) FTL_FAKE_GUARD(kMainThreadContext) {
snapshot = takeLayersSnapshotProto(traceFlags, TimePoint::now(),
mLastCommittedVsyncId, true);
})
.wait();
return snapshot;
});
// 10. 处理次级显示器并完成状态初始化
processDisplayChangesLocked();
mDrawingState = mCurrentState;
onActiveDisplayChangedLocked(nullptr, *display);
// 11. 异步初始化显示器和电源管理
static_cast<void>(mScheduler->schedule(
[this]() FTL_FAKE_GUARD(kMainThreadContext) { initializeDisplays(); }));
mPowerAdvisor->init();
// 12. 着色器缓存预热 (性能优化 - 减少运行时卡顿)
if (base::GetBoolProperty("service.sf.prime_shader_cache"s, true)) {
if (setSchedFifo(false) != NO_ERROR) {
ALOGW("Can't set SCHED_OTHER for primeCache");
}
mRenderEnginePrimeCacheFuture.callOnce([this] {
renderengine::PrimeCacheConfig config;
// ... 配置各种图层的缓存预热参数
return getRenderEngine().primeCache(config);
});
if (setSchedFifo(true) != NO_ERROR) {
ALOGW("Can't set SCHED_FIFO after primeCache");
}
}
// 13. 后台初始化和调试支持
mInitBootPropsFuture.callOnce([this] {
return std::async(std::launch::async, &SurfaceFlinger::initBootProperties, this);
});
initTransactionTraceWriter();
/* QTI扩展初始化 (高通特定功能) */
mQtiSFExtnIntf = mQtiSFExtnIntf->qtiPostInit(/* 参数 */);
surfaceflingerextension::QtiExtensionContext::instance().setCompositionEngine(
&getCompositionEngine());
if (base::GetBoolProperty("debug.sf.enable_hwc_vds"s, false)) {
enableHalVirtualDisplays(true);
}
mQtiSFExtnIntf->qtiStartUnifiedDraw();
ALOGV("Done initializing");
}
上述init函数主要做了如下工作:
- 基础设置:事务过滤器和线程锁
- CompositionEngine的配置,创建RenderEngine对象(负责2D/3D图形渲染)用于Client合成模式(GPU)合成;
- 初始化HWComposer,注册回调接口composer.setCallback(*this);,HAL会回调一些方法
- configureLocked()初始显示配置 - 检测启动时已连接的显示器(热插拔检查)
- 提交主显示器配置并初始化调度器
- 初始化调度系统 (Scheduler) - 图形合成的"大脑"
- setActiveModeListener设置显示模式变化监听器
根据之前的分析,**HWC2::ComposerCallback是**硬件合成器 (HAL)的回调,主要监听并处理处理热插拔、VSync 事件,代码如下:
cpp
/**
* 硬件合成器(HWC)回调接口
*
* 定义与底层显示硬件(HWC HAL)通信的事件回调方法。
* 当显示硬件发生状态变化时,HWC HAL 会通过这些回调通知上层系统。
*/
struct ComposerCallback {
/**
* 显示器热插拔事件回调
*
* 当显示器连接或断开时触发,用于处理显示器的添加和移除。
*
* @param displayId 硬件显示器ID,标识具体的物理显示器
* @param event 热插拔事件类型(连接/断开)
*/
virtual void onComposerHalHotplugEvent(hal::HWDisplayId displayId,
DisplayHotplugEvent event) = 0;
/**
* 显示器刷新请求回调
*
* 当HWC请求立即刷新指定显示器时触发,通常表示显示内容需要更新。
*
* @param displayId 需要刷新的硬件显示器ID
*/
virtual void onComposerHalRefresh(hal::HWDisplayId displayId) = 0;
/**
* VSync 信号回调
*
* 当显示器生成垂直同步信号时触发,用于帧同步和时序控制。
* 这是图形流水线中最重要的事件之一。
*
* @param displayId 产生VSync的硬件显示器ID
* @param timestamp VSync信号的时间戳(纳秒)
* @param vsyncPeriod 可选的VSync周期信息(纳秒)
*/
virtual void onComposerHalVsync(hal::HWDisplayId displayId,
nsecs_t timestamp,
std::optional<hal::VsyncPeriodNanos> vsyncPeriod) = 0;
/**
* VSync 周期变化回调
*
* 当显示器的刷新率(VSync周期)发生变化时触发。
* 例如从60Hz切换到90Hz时会发生此事件。
*
* @param displayId 刷新率变化的硬件显示器ID
* @param timeline VSync周期变化的时间线信息
*/
virtual void onComposerHalVsyncPeriodTimingChanged(
hal::HWDisplayId displayId,
const hal::VsyncPeriodChangeTimeline& timeline) = 0;
/**
* 无缝切换支持回调
*
* 通知系统指定的显示器是否支持无缝显示模式切换。
* 无缝切换允许在不闪烁或黑屏的情况下改变显示模式。
*
* @param displayId 支持无缝切换的硬件显示器ID
*/
virtual void onComposerHalSeamlessPossible(hal::HWDisplayId displayId) = 0;
/**
* VSync 空闲状态回调
*
* 当显示器进入VSync空闲状态时触发,表示一段时间内没有显示内容更新。
* 可用于电源管理优化,如降低刷新率以节省功耗。
*
* @param displayId 进入空闲状态的硬件显示器ID
*/
virtual void onComposerHalVsyncIdle(hal::HWDisplayId displayId) = 0;
/**
* 刷新率变化调试回调
*
* 提供刷新率变化的详细调试信息,主要用于性能分析和问题诊断。
*
* @param data 刷新率变化的调试数据,包含变化原因、时间等信息
*/
virtual void onRefreshRateChangedDebug(const RefreshRateChangedDebugData& data) = 0;
};
HWC2::ComposerCallback中的注释已经做了很清楚的说明。实现这个接口可以接收来自HWC的事件。这些callback都是由hwc hal透过hwbinder跨进程传递过来的。其中,当第一次注 册callback时,onComposerHalHotplugEvent()会立即在调用registerCallback()的线程中被调用,并跨进程回调到SurfaceFlinger::onComposerHalHotplugEvent。
SurfaceFlinger::init方法中设置完HWC的回调后,会立即收到一个Hotplug事件,并在SurfaceFlinger::onComposerHalHotplugEvent中去处理。然后会调用到mScheduler->scheduleConfigure();函数,触发显示配置更新,这里和后面说的VSYNC信号接收处理有很大关系
SurfaceFlinger::run
可执行档surfaceflinger的main函数中,把SurfaceFinger这个服务注册进ServiceManger中后,后续执行了SurfaceFlinger::run这个方法,代码如下:
cpp
void SurfaceFlinger::run() {
mScheduler->run();
}
然后调用到任务调度器(Scheduler)中
cpp
void Scheduler::run() {
while (true) {
waitMessage();
}
}
这个方法也很简单,一个while(true)的无限死循环,消息队列等待消息的到来。surfaceflinger主线程中等待消息处理
这就是SurfaceFlinger的概要启动流程,然后我们继续深入任务调度器中
三.任务调度器(Scheduler)
首先看一下任务调度器的实现的类:
Scheduler.h

可以看出来任务调度器中继承了MessageQueue(消息队列),这个是和Android 12有所区别的,Android 12中MessageQueue是在SurfaceFlinger中实现的,这里做了解耦,将消息队列放到任务调度器里面了
ps:在Android 15中Scheduler有两个作用事件线程回调契约 和消息队列功能
接着前面的分析,在插拔显示屏的回调方法onComposerHalHotplugEvent会调用mScheduler->scheduleConfigure();
然后看下任务调度器mScheduler中的scheduleConfigure函数
由于前面说的Scheduler实现了MessageQueue,此时其实是调用到MessageQueue的scheduleConfigure函数,如下:
cpp
void MessageQueue::scheduleConfigure() {
struct ConfigureHandler : MessageHandler {
explicit ConfigureHandler(ICompositor& compositor) : compositor(compositor) {}
void handleMessage(const Message&) override { compositor.configure(); }
ICompositor& compositor;
};
// TODO(b/241285876): Batch configure tasks that happen within some duration.
postMessage(sp<ConfigureHandler>::make(mCompositor));
}
上述主要是看postMessage将当前线程切换到主线程(因为是在SurfaceFlinger中创建的MessageQueue,SurfaceFlinger是主线程的)
然后是通过compositor.configure()将显示配置更新,由于SurfaceFlinger实现了Compositor接口,所以具体实现是在SurfaceFlinger中,然后我们看下SurfaceFlinger中的configure()方法
如下:
cpp
void SurfaceFlinger::configure() {
Mutex::Autolock lock(mStateLock);
if (configureLocked()) {
setTransactionFlags(eDisplayTransactionNeeded);
}
}
再看setTransactionFlags函数
cpp
void SurfaceFlinger::setTransactionFlags(uint32_t mask, TransactionSchedule schedule,
const sp<IBinder>& applyToken, FrameHint frameHint) {
// 1. 🎛️ VSync 时序调制(性能优化)
mScheduler->modulateVsync({}, &VsyncModulator::setTransactionSchedule, schedule, applyToken);
// 2. 🏷️ 原子操作设置事务标志
uint32_t transactionFlags = mTransactionFlags.fetch_or(mask);
ATRACE_INT("mTransactionFlags", transactionFlags); // 性能追踪
// 3. 🚦 提交调度决策
if (const bool scheduled = transactionFlags & mask; !scheduled) {
scheduleCommit(frameHint); // 🎯 新事务,需要调度提交
} else if (frameHint == FrameHint::kActive) {
// 4. ⏰ 活跃状态维护(防休眠)
mScheduler->resetIdleTimer(); // 重置空闲计时器
}
}
setTransactionFlags()是图形事务处理的"调度中心",负责:
•
✅ 设置事务状态标志 - 标记需要处理的事务类型
•
✅ VSync 时序调制 - 优化事务提交的时机
•
✅ 提交调度决策 - 决定何时执行事务提交
•
✅ 空闲状态管理 - 控制系统活跃状态检测
然后再来看下之前SurfaceFlinger.cpp中的initScheduler函数,如下:
cpp
/**
* 初始化 SurfaceFlinger 的 VSync 调度系统
*
* 这个函数创建了 Android 图形系统的"心跳机制",负责管理:
* - VSync 信号的产生和分发(用于应用渲染和 SurfaceFlinger 合成)
* - 事件处理线程的创建和管理
* - 显示器的注册和配置
* - 性能监控组件的初始化
*/
void SurfaceFlinger::initScheduler(const sp<const DisplayDevice>& display) {
using namespace scheduler;
// 防止重复初始化调度器
LOG_ALWAYS_FATAL_IF(mScheduler);
// 获取当前显示器的激活模式和刷新率(如60Hz、90Hz、120Hz)
const auto activeMode = display->refreshRateSelector().getActiveMode();
const Fps activeRefreshRate = activeMode.fps;
// 初始化特性标志,用于启用/禁用不同的调度功能
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; // 小区域更新检测
}
}
// 调试和诊断特性
if (base::GetBoolProperty("debug.sf.show_predicted_vsync"s, false)) {
features |= Feature::kTracePredictedVsync; // VSync预测追踪
}
// 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;
}
/**
* 创建核心调度器实例
*
* Scheduler 是 Android 图形系统的"大脑",负责:
* - 管理 VSync 信号的产生和分发
* - 协调应用渲染和 SurfaceFlinger 合成的时序
* - 处理多种显示器的同步问题
*/
mScheduler = std::make_unique<Scheduler>(
static_cast<ICompositor&>(*this), // SurfaceFlinger 作为合成器
static_cast<ISchedulerCallback&>(*this), // SurfaceFlinger 作为回调接收器
features, // 配置的特性标志
getFactory(), // 对象工厂
activeRefreshRate, // 当前显示器刷新率
*mTimeStats); // 时间统计组件
// 注册主显示器(Pacesetter)- 作为同步基准
mScheduler->registerDisplay(display->getPhysicalId(),
display->holdRefreshRateSelector(),
mActiveDisplayId);
// 配置可变刷新率(VRR)显示器的渲染率
if (FlagManager::getInstance().vrr_config()) {
mScheduler->setRenderRate(display->getPhysicalId(), activeMode.fps,
/*applyImmediately*/ true); // 立即应用新速率
}
// 获取 VSync 配置参数(应用和SurfaceFlinger的工作时长)
const auto configs = mScheduler->getVsyncConfiguration().getCurrentConfigs();
/**
* 创建事件处理线程 - 图形系统的"消息泵"
*
* Android 使用多个专用线程处理不同类型的 VSync 信号:
*/
// 1. 渲染事件线程(VSYNC-app)- 控制应用UI渲染
mScheduler->createEventThread(scheduler::Cycle::Render,
mFrameTimeline->getTokenManager(),
/* workDuration */ configs.late.appWorkDuration, // 应用工作时间
/* readyDuration */ configs.late.sfWorkDuration); // SurfaceFlinger准备时间
// 2. 最后合成事件线程(VSYNC-sf)- 控制SurfaceFlinger层合成
mScheduler->createEventThread(scheduler::Cycle::LastComposite,
mFrameTimeline->getTokenManager(),
/* workDuration */ activeRefreshRate.getPeriod(), // 使用显示器的刷新周期
/* readyDuration */ configs.late.sfWorkDuration);
// 分发热插拔事件(通知系统显示器已连接)
mScheduler->dispatchHotplug(display->getPhysicalId(),
scheduler::Scheduler::Hotplug::Connected);
// 初始化 VSync 系统(注册回调并启动VSync信号生成)
mScheduler->initVsync(*mFrameTimeline->getTokenManager(),
configs.late.sfWorkDuration);
/**
* 创建性能监控组件
*/
// 区域采样线程 - 用于智能刷新率调整(根据屏幕内容动态调整刷新率)
mRegionSamplingThread = sp<RegionSamplingThread>::make(*this,
RegionSamplingThread::EnvironmentTimingTunables());
// FPS 报告器 - 帧率统计和监控
mFpsReporter = sp<FpsReporter>::make(*mFrameTimeline);
// 最后启动所有定时器(避免回调过早触发)
mScheduler->startTimers();
}
SurfaceFlinger::initScheduler()函数负责初始化 VSync 调度系统,这是图形流水线的核心计时和同步引擎
🏗️ 核心架构组件说明
1. 调度器(Scheduler)
-
作用:图形系统的中央计时控制器,协调所有VSync相关活动
-
重要性:确保应用渲染和SurfaceFlinger合成在正确的时间点执行
2. 事件线程(EventThread)
-
VSYNC-app :专门处理应用渲染请求,通过
Choreographer通知应用进行UI更新 -
VSYNC-sf:专门处理SurfaceFlinger合成请求,触发图层合成操作
然后继续看initVsync函数,如下:
cpp
void Scheduler::initVsync(frametimeline::TokenManager& tokenManager,
std::chrono::nanoseconds workDuration) {
Impl::initVsyncInternal(getVsyncSchedule()->getDispatch(), tokenManager, workDuration);
}



然后其实就到了handle将这个vsync信号进行消息分发,如下:
cpp
void MessageQueue::Handler::dispatchFrame(VsyncId vsyncId, TimePoint expectedVsyncTime) {
if (!mFramePending.exchange(true)) {
mVsyncId = vsyncId;
mExpectedVsyncTime = expectedVsyncTime;
mQueue.mLooper->sendMessage(sp<MessageHandler>::fromExisting(this), Message());
}
}
如果有vsync信号就会调用到MessageQueue的handleMessage的函数中
cpp
void MessageQueue::Handler::handleMessage(const Message&) {
mFramePending.store(false);
mQueue.onFrameSignal(mQueue.mCompositor, mVsyncId, mExpectedVsyncTime);
}
然后调用到
cpp
/**
* VSync 信号帧处理入口函数
*
* 这是 Android 图形系统的核心调度点,当 VSync 信号到来时被调用,
* 负责协调整个帧合成流水线,支持多显示器环境下的协同工作。
*
* @param compositor 合成器接口(通常是 SurfaceFlinger)
* @param vsyncId VSync 信号标识符,用于帧追踪
* @param expectedVsyncTime 预期的 VSync 时间点
*/
void Scheduler::onFrameSignal(ICompositor& compositor, VsyncId vsyncId,
TimePoint expectedVsyncTime) {
// 1. 🎯 准备帧合成参数
const FrameTargeter::BeginFrameArgs beginFrameArgs = {
.frameBeginTime = SchedulerClock::now(), // 帧开始时间(当前时间)
.vsyncId = vsyncId, // VSync 标识,用于帧追踪
.expectedVsyncTime = expectedVsyncTime, // 预期 VSync 时间
.sfWorkDuration = mVsyncModulator->getVsyncConfig().sfWorkDuration, // SurfaceFlinger 工作时长
.hwcMinWorkDuration = mVsyncConfiguration->getCurrentConfigs().hwcMinWorkDuration // HWC 最小工作时长
};
// 2. 🏁 获取主显示器(Pacesetter)并开始其帧处理
ftl::NonNull<const Display*> pacesetterPtr = pacesetterPtrLocked();
pacesetterPtr->targeterPtr->beginFrame(beginFrameArgs, *pacesetterPtr->schedulePtr);
// 3. 🔄 多显示器帧目标协调
{
FrameTargets targets;
// 3.1 添加主显示器的帧目标
targets.try_emplace(pacesetterPtr->displayId, &pacesetterPtr->targeterPtr->target());
// 3.2 更新预期 VSync 时间(beginFrame 可能调整了时间)
expectedVsyncTime = pacesetterPtr->targeterPtr->target().expectedPresentTime();
// 3.3 处理从显示器(Followers)的帧同步
for (const auto& [id, display] : mDisplays) {
if (id == pacesetterPtr->displayId) continue; // 跳过主显示器
// 为从显示器调整 VSync 时间(基于主显示器时序)
auto followerBeginFrameArgs = beginFrameArgs;
followerBeginFrameArgs.expectedVsyncTime =
display.schedulePtr->vsyncDeadlineAfter(expectedVsyncTime);
// 开始从显示器的帧处理
FrameTargeter& targeter = *display.targeterPtr;
targeter.beginFrame(followerBeginFrameArgs, *display.schedulePtr);
targets.try_emplace(id, &targeter.target());
}
// 4. 📨 尝试提交合成(前置检查)
if (!compositor.commit(pacesetterPtr->displayId, targets)) {
// 4.1 提交失败处理:VRR 环境发送提示并通知回调
if (FlagManager::getInstance().vrr_config()) {
compositor.sendNotifyExpectedPresentHint(pacesetterPtr->displayId);
}
mSchedulerCallback.onCommitNotComposited(pacesetterPtr->displayId);
return; // 🎯 提前退出,不执行本次合成
}
}
// 5. 🔄 重新获取主显示器(commit 过程中可能发生变化)
pacesetterPtr = pacesetterPtrLocked();
// 6. 🎯 准备所有显示器的合成目标器
FrameTargeters targeters;
targeters.try_emplace(pacesetterPtr->displayId, pacesetterPtr->targeterPtr.get());
// 添加从显示器的目标器
for (auto& [id, display] : mDisplays) {
if (id == pacesetterPtr->displayId) continue;
FrameTargeter& targeter = *display.targeterPtr;
targeters.try_emplace(id, &targeter);
}
// 7. ⚡ 可选的性能测试:注入延迟模拟卡顿
if (FlagManager::getInstance().vrr_config() &&
CC_UNLIKELY(mPacesetterFrameDurationFractionToSkip > 0.f)) {
const auto period = pacesetterPtr->targeterPtr->target().expectedFrameDuration();
const auto skipDuration = Duration::fromNs(
static_cast<nsecs_t>(period.ns() * mPacesetterFrameDurationFractionToSkip));
ATRACE_FORMAT("Injecting jank for %f%% of the frame (%" PRId64 " ns)",
mPacesetterFrameDurationFractionToSkip * 100, skipDuration.ns());
std::this_thread::sleep_for(skipDuration); // 主动睡眠模拟卡顿
mPacesetterFrameDurationFractionToSkip = 0.f; // 重置卡顿比例
}
// 8. 🎨 执行实际的图形合成(核心操作)
const auto resultsPerDisplay = compositor.composite(pacesetterPtr->displayId, targeters);
// 9. 🔔 VRR 环境:发送预期呈现时间提示
if (FlagManager::getInstance().vrr_config()) {
compositor.sendNotifyExpectedPresentHint(pacesetterPtr->displayId);
}
// 10. 📊 采样性能数据
compositor.sample();
// 11. 🏁 结束帧处理:传递合成结果给各目标器
for (const auto& [id, targeter] : targeters) {
const auto resultOpt = resultsPerDisplay.get(id);
LOG_ALWAYS_FATAL_IF(!resultOpt); // 确保每个显示器都有结果
targeter->endFrame(*resultOpt); // 结束帧,清理资源
}
}
然后实际合成的函数在composite(),这个函数在SurfaceFlinger中实现
如下: