图像显示框架六——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中实现

如下:

相关推荐
Winter_Sun灬2 小时前
CentOS 7 编译安卓 arm64-v8a 版 OpenSSL 动态库(.so)
android·linux·centos
柯南二号2 小时前
【大前端】【Android】用 Python 脚本模拟点击 Android APP —— 全面技术指南
android·前端·python
壮哥_icon2 小时前
Android 使用 PackageInstaller 实现静默安装,并通过 BroadcastReceiver 自动重启应用
android·gitee·android-studio·android系统
ao_lang2 小时前
MySQL的存储过程和触发器
android·数据库·mysql
WebCsDn_TDCode2 小时前
Android Studio使用教程
android·android studio
小蜜蜂嗡嗡2 小时前
Android studio配置忽略文件
android·ide·android studio
颜颜yan_3 小时前
DevUI自定义开发实践:从零开始构建自定义组件和插件
android·java·数据库
爬也要爬着前进3 小时前
k8s部署wordpress
android·容器·kubernetes
儿歌八万首3 小时前
Flutter 混合开发指南:项目打包与原生 Android/iOS 集成
android·flutter·ios