Android 16 显示系统 | 从View 到屏幕系列 - 8 | SurfaceFlinger 合成 (一)

写在前面

SurfaceFlinger 合成流程比较复杂,但是如果把它一个个拆解的话,就比较容易理解了,我觉得可以大致分为三个阶段:

  1. 初始化阶段 : 在这个阶段初始化 HWComposerRenderEngineDisplayBufferQueue 等合成的关键组件。
  2. 数据处理阶段:在执行合成之前,会对 Layer 进行进一步处理,如计算每个 Layer 的可见区域,构建最终的 Layer Stack 等。
  3. 合成阶段 :这个阶段就是真正的 HWComposerRenderEngine 进行合成

这一小节先了解初始化阶段

合成初始化

SurfaceFlinger

scss 复制代码
void SurfaceFlinger::init() FTL_FAKE_GUARD(kMainThreadContext) {

    ...
    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);
    // 1. 创建 RenderEngine
    mRenderEngine = renderengine::RenderEngine::create(builder.build());    
    mCompositionEngine->setRenderEngine(mRenderEngine.get());
    ...
    
    // 2. 创建 HWComposer
    mHWComposer = getFactory().createHWComposer(mHwcServiceName);
    mCompositionEngine->setHwComposer(mHWComposer.get());
    auto& composer = mCompositionEngine->getHwComposer();
    // 把 SurfaceFlinger 注册到 HWComposer 的回调中
    composer.setCallback(*this);

    ...

    //3. 初始化 primary display.
    sp<const DisplayDevice> display;
    if (const auto indexOpt = mCurrentState.getDisplayIndex(mActiveDisplayId)) {
        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();
    }



    //4. 初始化 secondary display(s).
    processDisplayChangesLocked();

    // initialize our drawing state
    mDrawingState = mCurrentState;
    ...
}

目前 SurfaceFlinger 合成方式有两种

ini 复制代码
enum class Composition : int32_t {
  INVALID = 0,
  CLIENT = 1,
  DEVICE = 2,
  SOLID_COLOR = 3,
  CURSOR = 4,
  SIDEBAND = 5,
  DISPLAY_DECORATION = 6,
};

一种是 CLIENT,使用 GPU 合成,另一种是 DEVICE,使用硬件合成。

  1. RenderEngine: 持有 GPU 合成接口,负责 GPU 合成
  2. HWComposer: 负责和硬件合成器(HWC) 通信,负责硬件合成。

1. 初始化 RenderEngine

rust 复制代码
// frameworks/native/libs/renderengine/RenderEngine.cpp
std::unique_ptr<RenderEngine> RenderEngine::create(const RenderEngineCreationArgs& args) {
    threaded::CreateInstanceFactory createInstanceFactory;

    const RenderEngine::SkiaBackend actualSkiaBackend = args.skiaBackend;
   
    if (actualSkiaBackend == SkiaBackend::GRAPHITE) {
        createInstanceFactory = [args]() {
            return android::renderengine::skia::GraphiteVkRenderEngine::create(args);
        };
    } else
    { 
        if (args.graphicsApi == GraphicsApi::VK) {
            createInstanceFactory = [args]() {
                return android::renderengine::skia::GaneshVkRenderEngine::create(args);
            };
        } else {
            createInstanceFactory = [args]() {
                return android::renderengine::skia::SkiaGLRenderEngine::create(args);
            };
        }
    }

    if (args.threaded == Threaded::YES) {
        return renderengine::threaded::RenderEngineThreaded::create(createInstanceFactory);
    } else {
        return createInstanceFactory();
    }
}
  1. 这里会根据参数,来创建不同的 RenderEngine 实例, Android 提供三种不同的 RenderEngine:GraphiteVkRenderEngine(高性能渲染 ) GaneshVkRenderEngine(稳定性强 ) 和 SkiaGLRenderEngine(轻量级渲染,兼容旧设备)
  2. 根据是否启用线程封装(异步渲染),使用 RenderEngineThreaded 还是返回 RenderEngine 实例。

这里以创建 SkiaGLRenderEngine 并开启异步渲染为例:

c 复制代码
std::unique_ptr<RenderEngineThreaded> RenderEngineThreaded::create(CreateInstanceFactory factory) {
    return std::make_unique<RenderEngineThreaded>(std::move(factory));
}
css 复制代码
RenderEngineThreaded::RenderEngineThreaded(CreateInstanceFactory factory)
      : RenderEngine(Threaded::YES) {
    mThread = std::thread(&RenderEngineThreaded::threadMain, this, factory);
}

启动 RenderEngineThreaded::threadMain 线程

scss 复制代码
void RenderEngineThreaded::threadMain(CreateInstanceFactory factory) NO_THREAD_SAFETY_ANALYSIS {

    ...    
    // 1.创建 RenderEngine 实例
    mRenderEngine = factory();

    mInitializedCondition.notify_all();
    
    // 2.等待渲染任务
    while (mRunning) {
        const auto getNextTask = [this]() -> std::optional<Work> {
            std::scoped_lock lock(mThreadMutex);
            if (!mFunctionCalls.empty()) {
                Work task = mFunctionCalls.front();
                mFunctionCalls.pop();
                return std::make_optional<Work>(task);
            }
            return std::nullopt;
        };

        const auto task = getNextTask();

        if (task) {
            (*task)(*mRenderEngine);
        }

        std::unique_lock<std::mutex> lock(mThreadMutex);
        mCondition.wait(lock, [this]() REQUIRES(mThreadMutex) {
            return !mRunning || !mFunctionCalls.empty();
        });
    }
    
    mRenderEngine.reset();
}
  1. 创建 RenderEngine 实例,这里是创建 SkiaGLRenderEngine
  2. 在主线程中,开启一个 while 循环不断从任务队列中取任务执行,没有任务就等待。这里的任务就是 GPU 合成的任务。

RenderEngine 的实例创建完成之后, 通过setRenderEngine(mRenderEngine.get()) 设置到 mCompositionEngine 中。

接下来看 HWComposer 的创建。

2. 初始化 HWComposer

mHWComposer = getFactory().createHWComposer(mHwcServiceName)

c 复制代码
std::unique_ptr<HWComposer> DefaultFactory::createHWComposer(const std::string& serviceName) {
    return std::make_unique<android::impl::HWComposer>(serviceName);
}

实例化一个 HWComposer

rust 复制代码
HWComposer::HWComposer(const std::string& composerServiceName)
      : HWComposer(Hwc2::Composer::create(composerServiceName)) {}

在 HWComposer 的构造函数中调用 Hwc2::Composer::create

c 复制代码
// frameworks/native/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
std::unique_ptr<Composer> Composer::create(const std::string& serviceName) {
    ...
    return std::make_unique<AidlComposer>(serviceName);
    ...
}

创建一个 AidlComposer

css 复制代码
// frameworks/native/services/surfaceflinger/DisplayHardware/AidlComposerHal.cpp
AidlComposer::AidlComposer(const std::string& serviceName) {
    // 通过 serviceName 拿到这个 Binder 句柄
    mAidlComposer = AidlIComposer::fromBinder(
            ndk::SpAIBinder(AServiceManager_waitForService(instance(serviceName).c_str())));
}

到这里就很明确了,AIDL 的常规套路,通过传入的 serviceName,拿到一个 Binder Server 句柄,通过这个句柄,就可以像调用本地函数一样调用远程的服务中实现的接口方法了。

到这里为止,mHWComposer 的初始化就完成了,mHWComposer 持有 AidlComposerAidlComposer 通过 Binder 负责 和 HWComposer Server 通信。

3. 初始化 Display

回到 SurfaceFlinger::init

ini 复制代码
void SurfaceFlinger::init() FTL_FAKE_GUARD(kMainThreadContext) {
    //3. 初始化 primary display.
    sp<const DisplayDevice> display;
    if (const auto indexOpt = mCurrentState.getDisplayIndex(mActiveDisplayId)) {
        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();
    }

这里的核心方法是 processDisplayAdded

scss 复制代码
void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken,
                                         const DisplayDeviceState& state) {
    ...
    //1. 创建 Display
    auto compositionDisplay = getCompositionEngine().createDisplay(builder.build());

    sp<compositionengine::DisplaySurface> displaySurface;
    sp<IGraphicBufferProducer> producer;
    sp<IGraphicBufferProducer> bqProducer;
    sp<IGraphicBufferConsumer> bqConsumer;
    //2. 创建 BufferQueue,并初始化 BufferQueue 对应的 "生产者" & "消费者"
    getFactory().createBufferQueue(&bqProducer, &bqConsumer, /*consumerIsSurfaceFlinger =*/false);
    // Virtual Display 相关,后面会单独说
    if (state.isVirtual()) {
        ...
    } else {
        const auto displayId = PhysicalDisplayId::tryCast(compositionDisplay->getId());
        //3. 创建 frameBufferSurface
        const auto frameBufferSurface =
                sp<FramebufferSurface>::make(getHwComposer(), *displayId, bqProducer, bqConsumer,
                                             state.physical->activeMode->getResolution(),
                                             ui::Size(maxGraphicsWidth, maxGraphicsHeight));
        displaySurface = frameBufferSurface;
        producer = frameBufferSurface->getSurface()->getIGraphicBufferProducer();
    }

    // 4.创建 DisplayDevice 
    auto display = setupNewDisplayDeviceInternal(displayToken, std::move(compositionDisplay), state,
                                                 displaySurface, producer);
    // 5.把新的 DisplayDevice 添加到 mDisplays 数组中,后续的 Composition 会遍历这数组
    mDisplays.try_emplace(displayToken, std::move(display));
}

1. 创建 Display

getCompositionEngine().createDisplay 的调用链如下

rust 复制代码
   CompositionEngine::createDisplay
       --> compositionengine::impl::createDisplay()
         --> createDisplayTemplated<Display>()
           --> createOutputTemplated<BaseDisplay>()

createOutputTemplated

c 复制代码
std::shared_ptr<BaseOutput> createOutputTemplated(const CompositionEngine& compositionEngine,
                                                  Args... args) {
    class Output final : public BaseOutput {

        explicit Output(const CompositionEngine& compositionEngine, Args... args)
              : BaseOutput(std::forward<Args>(args)...), mCompositionEngine(compositionEngine) {}
       
    private:
        const CompositionEngine& mCompositionEngine;
        OutputCompositionState mState;
        std::vector<std::unique_ptr<OutputLayer>> mCurrentOutputLayersOrderedByZ;
        std::vector<std::unique_ptr<OutputLayer>> mPendingOutputLayersOrderedByZ;
    };
    // 返回一个 Output 对象
    return std::make_shared<Output>(compositionEngine, std::forward<Args>(args)...);
}

所以,getCompositionEngine().createDisplay 会最终创建一个 Output 对象,代表一块屏幕 , 在 Output 对象中有两个关键的成员变量 mCurrentOutputLayersOrderedByZmPendingOutputLayersOrderedByZ,在后续的合成中会多次使用。

2. 创建 BufferQueue

这里的 BufferQueue 和 之前提到的 BLASTBufferQueue 类似,用来管理 GraphicBuffer,同时初始化相对应的 ComsumerProducer

arduino 复制代码
void BufferQueue::createBufferQueue(sp<IGraphicBufferProducer>* outProducer,
        sp<IGraphicBufferConsumer>* outConsumer,
        bool consumerIsSurfaceFlinger) {
    ...
    sp<BufferQueueCore> core(new BufferQueueCore());
    // BufferQueue 生产者
    sp<IGraphicBufferProducer> producer(new BufferQueueProducer(core, consumerIsSurfaceFlinger));
    // BufferQueue 消费者
    sp<IGraphicBufferConsumer> consumer(new BufferQueueConsumer(core));
    *outProducer = producer;
    *outConsumer = consumer;
    ...
}

这里的逻辑和之前的提到的 juejin.cn/post/752723... 一模一样。

BufferQueueProducer

arduino 复制代码
// frameworks/native/libs/gui/include/gui/BufferQueueProducer.h
class BufferQueueProducer : public BnGraphicBufferProducer {
    ...
    virtual status_t dequeueBuffer(int* outSlot, sp<Fence>* outFence, uint32_t width,
                                   uint32_t height, PixelFormat format, uint64_t usage,
                                   uint64_t* outBufferAge,
                                   FrameEventHistoryDelta* outTimestamps) override;
                                   
    virtual status_t queueBuffer(int slot,
            const QueueBufferInput& input, QueueBufferOutput* output);
    ...
}
  1. dequeueBuffer:可以从 BufferQueueCore 的队列中获取一块 GraphicBuffer
  2. queueBuffer:可以将一块渲染完成的 GraphicBuffer 插入 BufferQueueCore 的队列中

BufferQueueConsumer :

arduino 复制代码
class BufferQueueConsumer : public IGraphicBufferConsumer {
    ...
    virtual status_t acquireBuffer(BufferItem* outBuffer,
            nsecs_t expectedPresent, uint64_t maxFrameNumber = 0) override;
    ...
}

acquireBuffer:可以 BufferQueueCore 的队列中获取渲染完成的 GraphicBuffer

3. 创建 frameBufferSurface

frameBufferSurface 的构造函数如下

scss 复制代码
FramebufferSurface::FramebufferSurface(HWComposer& hwc, PhysicalDisplayId displayId,
                                       const sp<IGraphicBufferProducer>& producer,
                                       const sp<IGraphicBufferConsumer>& consumer,
                                       const ui::Size& size, const ui::Size& maxSize)
      : ConsumerBase(producer, consumer),
        mDisplayId(displayId),
        mMaxSize(maxSize),
        mCurrentBufferSlot(-1),
        mCurrentBuffer(),
        mCurrentFence(Fence::NO_FENCE),
        mHwc(hwc),
        mHasPendingRelease(false),
        mPreviousBufferSlot(BufferQueue::INVALID_BUFFER_SLOT),
        mPreviousBuffer() {

    mName = "FramebufferSurface";
    mConsumer->setConsumerName(mName);
    mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_FB |
                                       GRALLOC_USAGE_HW_RENDER |
                                       GRALLOC_USAGE_HW_COMPOSER);
    const auto limitedSize = limitSize(size);
    mConsumer->setDefaultBufferSize(limitedSize.width, limitedSize.height);
    mConsumer->setMaxAcquiredBufferCount(
            SurfaceFlinger::maxFrameBufferAcquiredBuffers - 1);

    for (size_t i = 0; i < sizeof(mHwcBufferIds) / sizeof(mHwcBufferIds[0]); ++i) {
        mHwcBufferIds[i] = UINT64_MAX;
    }
}

frameBufferSurface 内部持有 mConsumer,可以从 BufferQueueCore 的队列中取出 Buffer 进行消费。所以 frameBufferSurface 本质上是 BufferQueue 的消费者

4. 创建 DisplayDevice

scss 复制代码
sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal(
        const wp<IBinder>& displayToken,
        std::shared_ptr<compositionengine::Display> compositionDisplay,
        const DisplayDeviceState& state,
        const sp<compositionengine::DisplaySurface>& displaySurface,
        const sp<IGraphicBufferProducer>& producer) {
    DisplayDeviceCreationArgs creationArgs(sp<SurfaceFlinger>::fromExisting(this), getHwComposer(),
                                           displayToken, compositionDisplay);
    ...

    // 1. 创建 NativeWindowSurface
    auto nativeWindowSurface = getFactory().createNativeWindowSurface(producer);
    // nativeWindowSurface->getNativeWindow 返回 mSurface
    auto nativeWindow = nativeWindowSurface->getNativeWindow();
    // 把 mSurface 传入 creationArgs.nativeWindow
    creationArgs.nativeWindow = nativeWindow;

    ...
    // 2. 创建 DisplayDevice
    sp<DisplayDevice> display = getFactory().createDisplayDevice(creationArgs);
    // nativeWindowSurface 提前分配一块 GraphicBuffer
    nativeWindowSurface->preallocateBuffers();

    ...
    // 对 DisplayDevice 进行一些列初始化
    display->setLayerFilter(
            makeLayerFilterForDisplay(display->getDisplayIdVariant(), state.layerStack));
    display->setProjection(state.orientation, state.layerStackSpaceRect,
                           state.orientedDisplaySpaceRect);
    display->setDisplayName(state.displayName);
    display->setOptimizationPolicy(state.optimizationPolicy);
    display->setFlags(state.flags);

    return display;
}

首先创建 NativeWindowSurface,然后创建 DisplayDevice 对象,最后再对 DisplayDevice 进行一系列设置。

1. 创建 NativeWindowSurface
arduino 复制代码
// frameworks/native/services/surfaceflinger/NativeWindowSurface.cpp
std::unique_ptr<surfaceflinger::NativeWindowSurface> createNativeWindowSurface(
        const sp<IGraphicBufferProducer>& producer) {
    class NativeWindowSurface final : public surfaceflinger::NativeWindowSurface {
    public:
        // 初始化 mSurface,并出入 Producer
        explicit NativeWindowSurface(const sp<IGraphicBufferProducer>& producer)
              : mSurface(sp<Surface>::make(producer, /* controlledByApp */ false)) {}

        ~NativeWindowSurface() override = default;

        sp<ANativeWindow> getNativeWindow() const override { return mSurface; }

        void preallocateBuffers() override { mSurface->allocateBuffers(); }

    private:
        sp<Surface> mSurface;
    };

    return std::make_unique<NativeWindowSurface>(producer);
}

createNativeWindowSurface 中创建了一个 NativeWindowSurface 对象,并且初始化 NativeWindowSurface 的成员变量 mSurface (把 produce 作为参数传入 Surface), 如果不了解 Surface 的作用,可以回过头看 juejin.cn/post/752699...

NativeWindowSurface 持有 Surface, 而 Surface 持有 produce,所以 NativeWindowSurface 间接持有 BufferQueueproduce

2. 创建 DisplayDevice

sp<DisplayDevice> display = getFactory().createDisplayDevice(creationArgs) 最终会调用 DisplayDevice 的构造函数

scss 复制代码
DisplayDevice::DisplayDevice(DisplayDeviceCreationArgs& args)
      : mFlinger(args.flinger),
        mHwComposer(args.hwComposer),
        mDisplayToken(args.displayToken),
        mSequenceId(args.sequenceId),
        mCompositionDisplay{args.compositionDisplay},
        mPhysicalOrientation(args.physicalOrientation),
        mPowerMode(ftl::Concat("PowerMode ", getId().value).c_str(), args.initialPowerMode),
        mIsPrimary(args.isPrimary),
        mRequestedRefreshRate(args.requestedRefreshRate),
        mRefreshRateSelector(std::move(args.refreshRateSelector)) {
    mCompositionDisplay->editState().isSecure = args.isSecure;
    mCompositionDisplay->editState().isProtected = args.isProtected;
    // 创建 RenderSurface
    mCompositionDisplay->createRenderSurface(
            compositionengine::RenderSurfaceCreationArgsBuilder()
                    .setDisplayWidth(ANativeWindow_getWidth(args.nativeWindow.get()))
                    .setDisplayHeight(ANativeWindow_getHeight(args.nativeWindow.get()))
                    .setNativeWindow(std::move(args.nativeWindow))
                    .setDisplaySurface(std::move(args.displaySurface))
                    .setMaxTextureCacheSize(
                            static_cast<size_t>(SurfaceFlinger::maxFrameBufferAcquiredBuffers))
                    .build());
    // 初始化 RenderSurface
    mCompositionDisplay->getRenderSurface()->initialize();
    ...
}

DisplayDevice的构造函数中,主要是对 DisplayDevice的成员变量进行初始化,其中最主要的就是创建了 RenderSurface

css 复制代码
// frameworks/native/services/surfaceflinger/CompositionEngine/src/Display.cpp
void Display::createRenderSurface(const RenderSurfaceCreationArgs& args) {
    setRenderSurface(
            compositionengine::impl::createRenderSurface(getCompositionEngine(), *this, args));
            
// frameworks/native/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp
std::unique_ptr<compositionengine::RenderSurface> createRenderSurface(
        const compositionengine::CompositionEngine& compositionEngine,
        compositionengine::Display& display,
        const compositionengine::RenderSurfaceCreationArgs& args) {
    return std::make_unique<RenderSurface>(compositionEngine, display, args);
}

RenderSurface::RenderSurface(const CompositionEngine& compositionEngine, Display& display,
                             const RenderSurfaceCreationArgs& args)
      : mCompositionEngine(compositionEngine),
        mDisplay(display),
        mNativeWindow(args.nativeWindow),
        mDisplaySurface(args.displaySurface),
        mSize(args.displayWidth, args.displayHeight),
        mMaxTextureCacheSize(args.maxTextureCacheSize) {
    LOG_ALWAYS_FATAL_IF(!mNativeWindow);
}
}

RenderSurface 持有 mNativeWindow, 而这个 mNativeWindow 就是前面创建的 NativeWindowSurface

前面提到 NativeWindowSurface 间接持有 BufferQueueproduce,所以 RenderSurface 也间接持有 BufferQueueproduce,所以 RenderSurface 本质上也是 BufferQueue 的生产者

到目前为止, BufferQueue 以及对应的生产者: RenderSurface 和对应的消费者 frameBufferSurface 都初始化完成了,这些组件将会在 GPU 合成过程中使用。

到这里, 合成所需要的关键组件,渲染引擎,显示设备,缓冲区管理者(BufferQueue) 都创建完成,下一小节了解合成的数据处理。

相关推荐
auxor2 小时前
Android 窗口管理 - 窗口添加过程分析Client端
android
雨白3 小时前
HTTP协议详解(一):工作原理、请求方法与状态码
android·http
Yang-Never3 小时前
Kotlin -> object声明和object表达式
android·java·开发语言·kotlin·android studio
小白马丶4 小时前
Jetpack Compose开发框架搭建
android·前端·android jetpack
攻城狮Talk4 小时前
FocusParkingView清除旧Window焦点
android
Wgllss4 小时前
完整案例:Kotlin+Compose+Multiplatform跨平台之桌面端实现(二)
android·架构·android jetpack
深盾安全5 小时前
Android 16KB页面对齐介绍
android
智江鹏5 小时前
Android 之 Kotlin 和 MVVM 架构的 Android 登录示例
android·开发语言·kotlin
凛_Lin~~6 小时前
2025-08 安卓开发面试拷打记录(面试题)
android