图像显示框架六——SurfaceFlinger的初始化以及任务调度(基于Android 15源码分析)

目录

一.代码路径:

二.SurfaceFlinger初始化

三.任务调度器(Scheduler)

[🏗️ 核心架构组件说明](#🏗️ 核心架构组件说明)

[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中实现

如下:

相关推荐
TheNextByte110 小时前
Android USB文件传输无法使用?5种解决方法
android
quanyechacsdn11 小时前
Android Studio创建库文件用jitpack构建后使用implementation方式引用
android·ide·kotlin·android studio·implementation·android 库文件·使用jitpack
程序员陆业聪12 小时前
聊聊2026年Android开发会是什么样
android
编程大师哥13 小时前
Android分层
android
极客小云14 小时前
【深入理解 Android 中的 build.gradle 文件】
android·安卓·安全架构·安全性测试
Juskey iii14 小时前
Android Studio Electric Eel | 2022.1.1 Patch 2 版本下载
android·ide·android studio
Android技术之家14 小时前
2025年度Android行业总结:AI驱动生态重构,跨端融合开启新篇
android·人工智能·重构
洞见前行14 小时前
Android第二代加固技术原理详解(附源码)
android
风清云淡_A15 小时前
【JetCompose】入门教程实战基础案例01之显隐动画
android
2501_9160074715 小时前
iPhone APP 性能测试怎么做,除了Instruments还有什么工具?
android·ios·小程序·https·uni-app·iphone·webview