Android 图形系统:图形总览 + SurfaceFlinger 与 WindowManager

Android 图形系统:图形总览 + SurfaceFlinger 与 WindowManager

内容整理自 AOSP 官方文档:


第一部分:Android 图形系统总览

Android 框架提供了各种用于 2D 和 3D 图形渲染的 API,可与制造商的图形驱动程序实现代码交互。这类驱动程序构建于图形硬件抽象层(HAL) 之上。应用开发者可通过三种方式将图像绘制到屏幕上:画布(Canvas)、OpenGL ES 或 Vulkan。

1.1 基本术语

术语 说明
画布 / Canvas 一种绘图 Surface,用于对照位图或 Surface 对象处理实际的位合成。包含位图、线条、圆形、矩形、文字等标准绘制方法,是屏幕上绘制 2D 对象最简便的方式,基类为 Canvas。
可绘制对象(Drawable) 经过编译的视觉资源,可用作背景、标题或界面其他部分。不能接收事件,但可指定状态、调度等属性以支持动画等子类。资源会被编译成 android.graphics.drawable 的子类。
布局资源 描述 Activity 界面布局的 XML 文件。
九宫格(NinePatch) 可调整大小的位图资源,可用作背景或其他图片。
OpenGL ES 渲染 2D/3D 图形的跨平台 API,可实现硬件加速的 3D 渲染;2D 渲染用 Canvas 更简单。NDK、android.opengl 和 javax.microedition.khronos.opengles 包均提供支持。
Surface 表示要合成到界面的内存块。Surface 包含用于绘图的 Canvas,并提供绘制图层、调整大小的辅助方法。应使用 SurfaceView 类,而非直接使用 Surface。
SurfaceView 封装 Surface 的 View 对象,可动态指定大小和格式。为游戏、相机预览等资源密集型操作提供独立于界面线程的绘制方式(代价是占用额外内存),同时支持 Canvas 和 OpenGL ES。
主题(Theme) 一组捆绑的默认显示属性(文字大小、背景颜色等),标准主题列于 R.style 中,以 Theme_ 开头。
View 在屏幕上绘制为矩形区域,处理点击、按键等互动事件,是大多数界面组件的基类。View 接收父对象调用以绘制自身,并向父对象报告首选大小和位置(父对象不一定遵循)。
ViewGroup 对子视图分组,负责确定子视图的位置和大小,并在适当时调用其绘制自身。有的不可见仅用于布局,有的具有固有界面(如滚动列表框)。
视图层次结构 View 与 ViewGroup 的排列方式,定义应用界面。可通过 SDK 的 Hierarchy Viewer 可视化。
Vulkan 适用于高性能 3D 图形的低开销、跨平台 API。
微件(Widget) 完全实现的 View 子类,渲染表单元素等界面组件(文本框、弹出式菜单),自行处理测量和绘制并响应屏幕事件,位于 android.widget 包。
Window 派生自 Window 抽象类的对象,指定常规窗口的元素(外观风格、标题栏文字、菜单位置内容等)。对话框和 Activity 使用其实现来渲染,应用无需自行实现。

1.2 Android 图形组件

无论开发者使用什么渲染 API,一切内容都会渲染到 Surface 上。 Surface 表示缓冲区队列中的生产方 ,而缓冲区队列通常会被 SurfaceFlinger 消耗。Android 平台上创建的每个窗口都由 Surface 提供支持,所有被渲染的可见 Surface 都被 SurfaceFlinger 合成到屏幕。

(原文图 1:Surface 如何被渲染------展示关键组件如何协同工作)

图像流生产方

可以是生成图形缓冲区以供消耗的任何东西,例如 OpenGL ES、Canvas 2D、mediaserver 视频解码器。

图像流消耗方
  • 最常见的消耗方是 SurfaceFlinger :该系统服务消耗当前可见的 Surface,并使用 WindowManager 提供的信息将它们合成到屏幕。SurfaceFlinger 是唯一可以修改所显示内容的服务,它使用 OpenGL 和 Hardware Composer 来合成一组 Surface。
  • 其他 OpenGL ES 应用也可以消耗图像流(如相机应用消耗相机预览图像流)。
  • 非 GL 应用也可以是消耗方,例如 ImageReader 类。
硬件混合渲染器(Hardware Composer, HWC)
  • 显示子系统的硬件抽象实现。SurfaceFlinger 可以将某些合成工作委托给 HWC,以分担 OpenGL 和 GPU 上的工作量。
  • SurfaceFlinger 本身只是充当另一个 OpenGL ES 客户端:当它把一个或两个缓冲区合成到第三个缓冲区时使用 OpenGL ES,这比完全通过 GPU 计算功耗更低。
  • HWC HAL 是所有 Android 图形渲染的中心点 ,它必须支持事件,其中之一是 VSYNC(另一个是支持即插即用 HDMI 的热插拔)。
Gralloc

显存分配器,用于分配图像生产方请求的内存(详见 Gralloc HAL 文档)。

1.3 数据流

(原文图 2:流经 Android 的图形数据流------左侧是生成图形缓冲区的渲染器,如主屏幕、状态栏和系统界面;SurfaceFlinger 是合成器,HWC 是混合渲染器)

BufferQueue

BufferQueue 是 Android 图形组件之间的粘合剂 :一对队列,调解缓冲区从生产方到消耗方的固定周期。一旦生产方移交缓冲区,SurfaceFlinger 便负责将所有内容合成到显示部分。

(原文图 3:BufferQueue 通信过程)

要点:

  • BufferQueue 包含将图像流生产方与消耗方结合在一起的逻辑。
    • 生产方示例:相机 HAL 生成的相机预览、OpenGL ES 游戏。
    • 消耗方示例:SurfaceFlinger、显示 GL 流的另一个应用(如相机取景器)。
  • BufferQueue 是将缓冲区池与队列相结合的数据结构 ,使用 Binder IPC 在进程间传递缓冲区。
  • 生产方接口为 IGraphicBufferProducer(SurfaceTexture 的一部分)。BufferQueue 通常用于渲染到 Surface,并与 GL 消耗方及其他任务一起消耗内容。

BufferQueue 的三种运行模式:

模式 行为
类同步模式(默认) 从生产方进入的每个缓冲区都在消耗方那退出,不舍弃任何缓冲区。若生产方速度过快,将阻塞并等待可用缓冲区。
非阻塞模式 不等待缓冲区,而是生成错误;也不舍弃缓冲区。有助于避免不了解图形框架复杂依赖的应用出现潜在死锁。
舍弃模式 配置为丢弃旧缓冲区而非报错或等待。例如对纹理视图执行 GL 渲染并尽快绘制时,必须丢弃缓冲区。

合成工作分两半:SurfaceFlinger 作为 OpenGL ES 客户端执行一部分(用 GLES 把缓冲区合成),HWC HAL 执行另一半,充当所有 Android 图形渲染的中心点。


第二部分:SurfaceFlinger 和 WindowManager

一句话概括职责分工:

  • SurfaceFlinger:接受缓冲区,对它们进行合成,然后发送到屏幕。
  • WindowManager:为 SurfaceFlinger 提供缓冲区和窗口元数据,SurfaceFlinger 使用这些信息将 Surface 合成到屏幕。

2.1 SurfaceFlinger

SurfaceFlinger 可通过两种方式接受缓冲区:

方式一:BufferQueue + SurfaceControl
  1. 应用进入前台时,向 WindowManager 请求缓冲区。
  2. WindowManager 向 SurfaceFlinger 请求层(Layer)。
  3. 层 = Surface(包含 BufferQueue)+ SurfaceControl(包含显示框架等层元数据) 的组合。
  4. SurfaceFlinger 创建层并发送至 WindowManager。
  5. WindowManager 将 Surface 发送给应用 ,但保留 SurfaceControl 以操控应用在屏幕上的外观。
方式二:ASurfaceControl(Android 10 新增)

ASurfaceControl 将 Surface 和 SurfaceControl 组合到一个事务包中发送至 SurfaceFlinger。它与层相关联,应用可通过 ASurfaceTransaction 更新该层,并通过回调(传递包含锁定时间、获取时间等信息的 ASurfaceTransactionStats)获取事务信息。

组件 说明
ASurfaceControl 封装 SurfaceControl,让应用能创建与屏幕上各层对应的 SurfaceControl。可作为 ANativeWindow 的子级或另一个 ASurfaceControl 的子级创建。
ASurfaceTransaction 包装事务,使客户端能修改层的描述性属性(如几何图形),并将更新后的缓冲区发送至 SurfaceFlinger。
ASurfaceTransactionStats 通过预先注册的回调,将已显示事务的信息(锁定时间、获取时间、上一个释放栅栏等)发送至应用。
缓冲区接收时机与 VSYNC
  • 应用可以随时提交缓冲区 ,但 SurfaceFlinger 仅在屏幕处于两次刷新之间时唤醒 以接受缓冲区(时机因设备而异)。这样可最大限度减少内存占用,并避免刷新期间更新显示内容造成的屏幕撕裂。
  • 屏幕在两次刷新之间向 SurfaceFlinger 发送 VSYNC 信号,表明此时可刷新屏幕而不会撕裂。
  • SurfaceFlinger 收到 VSYNC 后:
    1. 遍历其层列表,查找新缓冲区;
    2. 若找到新缓冲区则获取 ;否则继续使用上一次获取的缓冲区(SurfaceFlinger 必须始终显示内容,因此会保留一个缓冲区);
    3. 某层上没有提交缓冲区时,该层会被忽略。
  • 收集完可见层的所有缓冲区后,SurfaceFlinger 询问 HWC 应如何合成 :
    • 若 HWC 将层合成类型标记为客户端合成,则由 SurfaceFlinger 合成这些层;
    • 然后 SurfaceFlinger 将输出缓冲区传递给 HWC。

2.2 WindowManager

  • WindowManager 控制 Window 对象 (容纳 View 对象的容器),Window 对象始终由 Surface 对象提供支持。
  • WindowManager 监督:生命周期、输入和聚焦事件、屏幕方向、转换、动画、位置、变形、Z 轴顺序以及窗口的许多其他方面。
  • WindowManager 将所有窗口元数据发送到 SurfaceFlinger,供其在屏幕上合成 Surface 时使用。
预旋转(Pre-rotation)
  • 许多硬件叠加层不支持旋转 (即使支持也要耗费处理能力),解决方案是在缓冲区到达 SurfaceFlinger 之前对其进行转换。
  • Android 在 ANativeWindow 中支持查询提示 NATIVE_WINDOW_TRANSFORM_HINT ,表示最有可能由 SurfaceFlinger 应用于缓冲区的转换。GL 驱动程序可使用此提示在缓冲区到达前预转换,使其到达时已是正确方向。
  • 例如,接收到"旋转 90 度"提示时,会生成一个矩阵并应用于缓冲区,防止其从页面末尾运行。进行预旋转是为了节省电量。
  • 详见 system/core/include/system/window.h 中定义的 ANativeWindow 接口。

附:整体协作关系速览

复制代码
生产方(OpenGL ES / Canvas / 视频解码器 / 相机HAL)
      │  通过 BufferQueue(Binder IPC,IGraphicBufferProducer)
      ▼
应用渲染到 Surface ──► WindowManager(持有 SurfaceControl,
      │                   管理窗口元数据:位置/Z轴/动画/旋转...)
      │  层 = Surface + SurfaceControl(或 Android 10+ 的 ASurfaceControl 事务)
      ▼
SurfaceFlinger(VSYNC 触发,收集可见层缓冲区)
      │  询问 HWC 合成策略;客户端合成部分用 OpenGL ES
      ▼
HWC(硬件混合渲染器,图形渲染中心点)──► 屏幕
      ▲
Gralloc(负责图形缓冲区的内存分配)
相关推荐
2501_9159184141 分钟前
iOS 上架注意事项有哪些?Appuploader 的四个阶段自查清单
android·ios·小程序·https·uni-app·iphone·webview
张小姐的猫1 小时前
【MySQL】表的约束
android·linux·服务器·数据库·c++·mysql·adb
Kapaseker1 小时前
为什么程序员始终无法彻底解决内存泄漏?
android·kotlin
汤姆宝库2 小时前
推理工程深拆:调度、量化与投机解码
android·开发语言·kotlin
AirDroid_cn2 小时前
隔离风险:用备用机测试不明APP,电脑远程操控安卓保主力机安全
android·安全
恋猫de小郭2 小时前
Flutter 官方表示:AI 时代代码越来越容易写,为什么还要一套代码库?
android·前端·flutter
二宝哥2 小时前
把安卓平板变成电脑第二屏幕(扩展屏):局域网与外网方案全解析
android·电脑·平板·扩展屏
xiaoshiquan120617 小时前
Gradle 复合构建:宿主项目直接依赖 SDK 源码模块的配置实践
android
小师兄吃牛肉19 小时前
Android Studio 2025 专业介绍:新特性、性能与开发体验全面解析
android·ide·android studio