CompositionEngine 是 Android 图形系统的核心合成引擎 ,位于系统服务 SurfaceFlinger 内部。你可以把它理解为 SurfaceFlinger 的"绘图执行部门"。
它的核心任务就是将多个应用图层(Layer)高效地合成(Compose)为一个最终画面,并送显。这个过程的关键在于,它会智能地选择最高效的方式来完成工作。
核心职责与工作方式
CompositionEngine 主要负责以下几点:
-
接收"图纸"与"命令" :它接收来自
SurfaceFlinger前端(FrontEnd)处理好的、不可变的图层快照(LayerSnapshot)。这些快照包含了每个图层的内容、位置、大小、透明度等所有信息。 -
决定"怎么画" (Composition Strategy) :这是它的核心智能所在。它会分析所有图层的属性,决定每一帧的最佳合成策略。
- 硬件合成 (HWC) :对于简单的、不重叠的图层(如视频层),它会尝试交给专业的硬件
Hardware Composer (HWC)去处理,这是最快、最省电的方式。 - GPU合成 (GPU Composition) :对于复杂的、需要叠加、混合或特效的图层,它会使用
RenderEngine(基于OpenGL ES或Vulkan)调用GPU进行合成。 - 缓存与优化 :它还会识别出静止不变的图层,将其缓存起来(
Planner模块负责),避免重复合成,从而大幅提升性能并节省电量。
- 硬件合成 (HWC) :对于简单的、不重叠的图层(如视频层),它会尝试交给专业的硬件
-
协调"画师"干活 :在确定了策略后,它就像一个项目经理,协调GPU(
RenderEngine)和硬件(HWC HAL)完成具体的绘制工作。 -
最终输出:将所有图层合成为一个完整的帧缓冲区(Frame Buffer),并交给显示硬件进行呈现。
核心组件与架构
CompositionEngine 内部是模块化设计的,主要由以下几个部分协同工作:
CompositionEngine(核心) :总管,负责创建和管理所有的Output实例。Output(显示输出) :代表一个合成目标,比如一个物理屏幕或一个虚拟显示器。它负责管理属于这个屏幕的所有图层。OutputLayer(输出图层) :描述一个图层在特定Output上的最终状态。它会计算出图层在屏幕上的精确位置和裁剪区域。RenderSurface(渲染表面) :封装了用于GPU合成的渲染目标。LayerFE(图层前端接口) :CompositionEngine用来与SurfaceFlinger前端层对象通信的接口。
CompositionEngine 是 Android 实现流畅、省电图形效果的关键。它通过智能地决策使用GPU还是专用硬件来合成画面,并进行缓存优化,确保了用户界面的丝滑体验和设备的续航。
初始化与准备:创建合成环境
在系统启动时,SurfaceFlinger 会初始化所有合成相关的核心组件。
- 创建
CompositionEngine:在SurfaceFlinger::init()中完成,并保存HWComposer的实例。 - 创建
Display(Output) :为每个物理或虚拟屏幕创建一个Display对象,作为合成目标。它会关联一个用于GPU渲染的RenderSurface和一个HWC的硬件层。
每帧合成:
每一帧的合成工作都由 VSync 信号触发。
-
触发合成 (
SurfaceFlinger::onMessageReceived)SurfaceFlinger的主循环收到REFRESH消息后,开始处理一帧的合成。这个过程的入口是SurfaceFlinger::onMessageReceived。 -
准备图层状态 (
SurfaceFlinger→FrontEnd)SurfaceFlinger更新所有Layer的属性(位置、大小、透明度等),并生成一个不可变的LayerSnapshot(图层快照)。这个快照包含了该帧所有图层的最终状态。 -
协商合成策略 (
CompositionEngine::prepare)这是
CompositionEngine介入的第一步。SurfaceFlinger调用CompositionEngine::prepare,将LayerSnapshot和Display列表作为参数传入。CompositionEngine内部会调用HWC的validateDisplay()方法。HWC会根据硬件能力决定每个图层的最佳合成方式,是硬件合成 (HWC) 、GPU合成 (GPU) ,还是混合模式 (Mixed) 。
-
执行合成 (
CompositionEngine::present)协商完成后,真正的合成工作开始,入口是
CompositionEngine::present方法。它主要执行以下步骤:-
制定计划 (
Output::planComposition) :根据HWC的反馈,为每个Display制定最终的合成计划。 -
写入状态 (
Output::writeCompositionState) :将需要合成的图层信息写入HWC的硬件层。 -
执行合成:根据计划,执行具体的合成操作。
- GPU 合成 :对于标记为 GPU 合成的图层,
CompositionEngine会调用RenderEngine使用 OpenGL ES 或 Vulkan 进行合成。 - HWC 合成 :对于标记为 HWC 合成的图层,
CompositionEngine会调用HWC的presentDisplay()等方法,由硬件完成合成。
- GPU 合成 :对于标记为 GPU 合成的图层,
-
策略决策的核心:HWC
CompositionEngine 本身并不直接做"合成"的决策,其策略(用GPU还是HWC)完全依赖于 HWC (Hardware Composer) HAL 的 validateDisplay() 方法。它会根据硬件能力,返回一个最优的合成方案。
HWC 的全称是 Hardware Composer ,即硬件合成器 。它属于 HAL (硬件抽象层) 的一部分,是 Android 图形系统中连接 SurfaceFlinger 与具体显示硬件(如屏幕驱动芯片)的关键模块。
你可以把它理解为一个专门负责合成画面的硬件加速器 。它的核心目标是利用专用硬件(而非GPU)来完成图层的合成工作,以达到更高的效率和更低的功耗。
为什么需要HWC?
- 为GPU减负:GPU 的主要任务是渲染应用的内容(如游戏画面、UI元素)。如果让 GPU 同时负责合成所有图层,会占用其宝贵的计算资源,可能导致应用卡顿或掉帧。HWC 将这些合成工作卸载到专门的硬件上,让 GPU 能专注于渲染。
- 提升能效:专用硬件处理特定任务的效率远高于通用GPU。对于静态或变化不大的画面,HWC 可以利用硬件叠加层直接合成,从而显著降低功耗。
- 厂商定制优化 :HWC 的实现是设备相关 (device-specific) 的,通常由显示硬件 OEM 厂商完成。这使得厂商可以根据自家硬件的特性进行深度定制,实现最优性能。
它是如何工作的?
HWC 的工作流程可以概括为"协商-分工-执行 ",这与上一轮提到的 CompositionEngine::prepare 和 present 阶段紧密相关:
-
协商 (Negotiation) :
SurfaceFlinger将当前帧的所有图层列表发给 HWC,并询问:"这些图层,你打算怎么处理?"。 -
决策 (Decision) :HWC 会根据自身硬件能力(比如支持多少个叠加层)进行分析,然后将每个图层标记为两种类型之一:
- 设备合成 (Device Composition) :由 HWC 硬件自己处理。
- 客户端合成 (Client Composition) :需要
SurfaceFlinger通过 GPU(RenderEngine)先合成好,再把结果交给 HWC。
-
执行 (Execution) :
SurfaceFlinger会先处理所有标记为"客户端合成"的图层,然后将结果连同其他"设备合成"图层一并交给 HWC。最后,由 HWC 完成所有图层的最终合成并送显
简单来说,HWC 就像是 SurfaceFlinger 的一个"硬件加速外挂 "。SurfaceFlinger 负责统筹规划,而 HWC 则利用专门的硬件电路,以最高效、最省电的方式完成最繁重的图层合成工作。它是 Android 系统能够提供流畅、省电视觉体验的关键硬件抽象层之一。
HWC工作流程:
阶段一:准备与策略协商 (Prepare Phase)
这个阶段由 VSync 信号触发,SurfaceFlinger 和 HWC 会共同确定每帧的最佳合成方案。
-
触发与事务处理 :VSync 信号唤醒
SurfaceFlinger的主循环。它首先处理各种图层事务(handleMessageTransaction),如更新图层位置、大小、透明度等属性。 -
准备合成计划 :
SurfaceFlinger调用CompositionEngine::prepare()。此方法会遍历所有图层,并为每个Output(显示输出) 调用prepareFrame()。 -
与HWC协商 :
CompositionEngine进而调用 HWC 的validateDisplay()方法。SurfaceFlinger将完整的图层列表提供给 HWC,并询问:"这些图层,你打算怎么处理?"。 -
HWC决策:HWC 根据其硬件能力(如支持的叠加层数量),为每个图层标记合成方式:
- 设备合成 (Device / HWC) :由 HWC 硬件直接处理,性能最优。
- 客户端合成 (Client / GPU) :需要
SurfaceFlinger通过 GPU (RenderEngine) 先合成好。 - 混合合成 (Mixed) :部分图层用 HWC,部分用 GPU。
-
策略同步 :
SurfaceFlinger检查 HWC 是否对任何图层的合成方式做出了改变,并相应地进行内部调整,然后调用acceptDisplayChanges通知 HWC。
阶段二:执行合成与送显 (Set/Present Phase)
策略确定后,CompositionEngine 负责调度执行最终的合成操作。
-
执行合成 (
CompositionEngine::present) :SurfaceFlinger调用CompositionEngine::present()。这是实际合成工作的入口。 -
制定与写入计划 :
CompositionEngine为每个Output调用planComposition()和writeCompositionState()。它会将需要合成的图层信息写入 HWC 的硬件层。 -
分类处理与合成:
- 处理 GPU 合成 (Client Target) :对于标记为
Client的图层,CompositionEngine会调用RenderEngine,使用 OpenGL ES 或 Vulkan 将它们合成到一个离屏的client target缓冲区中。 - 提交 GPU 结果 :GPU 合成完成后,
CompositionEngine调用HWC::setClientTarget(),将这个包含所有 GPU 合成结果的缓冲区地址传递给 HWC。
- 处理 GPU 合成 (Client Target) :对于标记为
-
硬件合成与送显 :最后,
CompositionEngine调用HWC::presentDisplay()(或set())。HWC 会原子性地将所有Device图层和刚收到的client target缓冲区进行最终合成,并立即送显。
CompositionEngine 与 HWC 是一个高效的两阶段流水线:
- 准备阶段 (
prepare) :CompositionEngine作为中介,让SurfaceFlinger与 HWC 协商出最优的"施工方案"(GPU还是硬件合成)。 - 执行阶段 (
present) :CompositionEngine作为"包工头",先调度RenderEngine(GPU) 完成自己的那部分"客户单"(Client 合成),再将成果打包,连同其他"材料"(Device 图层)一并交给 HWC 这个"专业施工队",由它完成最终合成并显示。
这种分工协作最大化了硬件效率,并确保了画面的流畅与稳定。