写在前面
SurfaceFlinger
合成流程比较复杂,但是如果把它一个个拆解的话,就比较容易理解了,我觉得可以大致分为三个阶段:
- 初始化阶段 : 在这个阶段初始化
HWComposer
、RenderEngine
、Display
和BufferQueue
等合成的关键组件。 - 数据处理阶段:在执行合成之前,会对 Layer 进行进一步处理,如计算每个 Layer 的可见区域,构建最终的 Layer Stack 等。
- 合成阶段 :这个阶段就是真正的
HWComposer
或RenderEngine
进行合成
这一小节先了解初始化阶段
合成初始化
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
,使用硬件合成。
RenderEngine
: 持有 GPU 合成接口,负责 GPU 合成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();
}
}
- 这里会根据参数,来创建不同的 RenderEngine 实例, Android 提供三种不同的 RenderEngine:
GraphiteVkRenderEngine
(高性能渲染 )GaneshVkRenderEngine
(稳定性强 ) 和SkiaGLRenderEngine
(轻量级渲染,兼容旧设备) - 根据是否启用线程封装(异步渲染),使用
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();
}
- 创建 RenderEngine 实例,这里是创建
SkiaGLRenderEngine
- 在主线程中,开启一个 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
持有 AidlComposer
,AidlComposer
通过 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 对象中有两个关键的成员变量 mCurrentOutputLayersOrderedByZ
和 mPendingOutputLayersOrderedByZ
,在后续的合成中会多次使用。
2. 创建 BufferQueue
这里的 BufferQueue
和 之前提到的 BLASTBufferQueue
类似,用来管理 GraphicBuffer
,同时初始化相对应的 Comsumer
和 Producer
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);
...
}
dequeueBuffer
:可以从 BufferQueueCore 的队列中获取一块 GraphicBufferqueueBuffer
:可以将一块渲染完成的 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
间接持有 BufferQueue
的 produce
。
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
间接持有 BufferQueue
的 produce
,所以 RenderSurface
也间接持有 BufferQueue
的 produce
,所以 RenderSurface
本质上也是 BufferQueue
的生产者。
到目前为止, BufferQueue
以及对应的生产者: RenderSurface
和对应的消费者 frameBufferSurface
都初始化完成了,这些组件将会在 GPU 合成过程中使用。
到这里, 合成所需要的关键组件,渲染引擎,显示设备,缓冲区管理者(BufferQueue) 都创建完成,下一小节了解合成的数据处理。