Android 显示系统(文章综述)

1. CPU 与 GPU 职责对比

由于 CPU 和 GPU 的设计不同,CPU 更擅长复杂逻辑控制,而 GPU 得益于大量 ALU 和并行结构设计,更擅长数学运算。在 Android 系统中,CPU 与 GPU 的分工不同,CPU 主要负责包括 Measure,Layout,Record,Execute 的计算操作,GPU 主要负责 Rasterization(栅格化)操作。

GPU

在这里插入图片描述
Resterization 栅格化是绘制那些 Button,Shape,Path,String,Bitmap 等组件最基础的操作。它把那些组件拆分到不同的像素上进行显示。这是一个很费时的操作,GPU 的引入就是为了加快栅格化的操作。

CPU

在这里插入图片描述
CPU 负责把 UI 组件计算成 Polygons,Texture 纹理,然后交给 GPU 进行栅格化渲染

2. Android 渲染机制

在这里插入图片描述
在 Android 应用程序中,每一个 Activity 组件都关联有一个或者若干个窗口,每一个窗口都对应有一个 Surface,Surface 使用的图形缓冲是通过 Gralloc 来分配的。有了这个 Surface 之后,应用程序就可以在上面渲染窗口的 UI。最终这些已经绘制好了的 Surface 都会被统一提交给 Surface 管理服务 SurfaceFlinger 进行合成,最后显示在屏幕上面。无论是应用程序,还是 SurfaceFlinger,都可以利用 GPU 等硬件来进行 UI 渲染,以便获得更流畅的 UI。当图形数据用于屏幕显示时,SurfaceFlinger 使用窗口元数据将图形缓冲合成到显示上。图形数据最终渲染到显示设备上是通过 Hardware Composer 完成的。

  • ViewRootImpl
    用来控制窗口的渲染,以及用来与 WindowManagerService、SurfaceFlinger 通信。

  • WindowManager
    WindowManager 会控制窗口对象,它们是用于容纳view对象的容器。窗口对象始终由 Surface 对象提供支持。WindowManager 会监督生命周期、输入和聚焦事件、屏幕方向、转换、动画、位置、变形、Z 轴顺序以及窗口的许多其他方面。WindowManager 会将所有窗口元数据发送到 SurfaceFlinger,以便 SurfaceFlinger 可以使用这些数据在屏幕上合成 Surface。

  • Surface
    Android 应用的每个窗口对应一个画布(Canvas),即 Surface,可以理解为 Android 应用程序的一个窗口。Surface 是一个接口,供生产方与使用方交换缓冲区。

  • SurfaceView
    SurfaceView 是一个组件,可用于在 View 层次结构中嵌入其他合成层。SurfaceView 采用与其他 View 相同的布局参数,因此可以像对待其他任何 View 一样对其进行操作,但 SurfaceView 的内容是透明的。当 SurfaceView 的 View 组件即将变得可见时,框架会要求 SurfaceControl 从 SurfaceFlinger 请求新的 Surface。

  • BufferQueue
    BufferQueue 类将可生成图形数据缓冲区的组件(生产方)连接到接受数据以便进行显示或进一步处理的组件(使用方)。几乎所有在系统中移动图形数据缓冲区的内容都依赖于 BufferQueue。

  • SurfaceFlinger
    Android 系统服务,负责管理 Android 系统的帧缓冲区,即显示屏幕。SurfaceFlinger合成,有两种方式,Client和Device。Client就是Client合成完Layer后再将合成后的数据给到HWComposer,HWComposer此时做的工作很少,直接给到Display。Device则是将未合成的Layer,给到硬件合成的设备,合成完后再给到Display。Android 使用 OpenGL ES (GLES) API 渲染图形。GPU 将视图栅格化后,生成 Surface。GPU 作为图像流生产方将显示内容,最终发送给图像流的消耗方 SurfaceFlinger。
    SurfaceFlinger 接受来自多个源的数据缓冲区,然后将它们进行合成并发送到显示屏。WindowManager 为 SurfaceFlinger 提供缓冲区和窗口元数据,而 SurfaceFlinger 可使用这些信息将 Surface 合成到屏幕。

  • EGLSurface 和 OpenGL ES
    OpenGL ES (GLES) 定义了用于与 EGL 结合使用的图形渲染 API。EGL是一个规定如何通过操作系统创建和访问窗口的库(要绘制纹理多边形,请使用 GLES 调用;要将渲染放到屏幕上,请使用 EGL 调用)。

Vulkan:Vulkan 是一种用于高性能 3D 图形的低开销、跨平台 API。与 OpenGL ES 一样,Vulkan 提供用于在应用中创建高质量实时图形的工具。

3. Android 渲染流程

将渲染过程简单分为两个部分:应用程序侧绘制和系统侧渲染。
在这里插入图片描述

应用侧绘制

在绘制一个 Android 应用程序窗口的 UI 之前,我们首先要确定它里面的各个子 UI 元素在父 UI 元素里面的大小以及位置。确定各个子 UI 元素在父 UI 元素里面的大小以及位置的过程又称为测量过程和布局过程。因此,Android 应用程序窗口的 UI 渲染过程可以分为测量、布局和绘制三个阶段,最后生成 Display List。

  • 测量:递归(深度优先)确定所有视图的大小(高、宽)
  • 布局:递归(深度优先)确定所有视图的位置(左上角坐标)
  • 绘制:在画布 canvas 上绘制应用程序窗口所有的视图,Android 有两种绘制模型:基于软件的绘制模型和硬件加速的绘制模型。
  • 生成 Display List 数据。 Display List 数据保存了XML 布局文件转换成 GPU 能够识别并绘制的对象。Display List 持有所有将要交给 GPU 绘制到屏幕上的数据信息

系统侧渲染

  1. Display List 数据交由 GPU 进行渲染处理
    Display List 是一个缓存绘制命令的 Buffer,Display List 的本质是一个缓冲区,它里面记录了即将要执行的绘制命令序列。渲染 Display List,发生在应用程序进程的 Render Thread 中。增加 Render Thread 线程,也是为了避免 UI 线程任务过重,用于提高渲染性能。这些绘制命令最终会转化为 Open GL 命令由 GPU 执行。这意味着我们在调用 Canvas API 绘制 UI 时,实际上只是将 Canvas API 调用及其参数记录在 Display List 中,然后等到下一个 VSYNC 信号到来时,记录在 Display List 里面的绘制命令才会转化为 Open GL 命令由 GPU 执行。

  2. GPU 渲染处理
    Android 使用 OpenGL ES (GLES) API 渲染图形。GPU 将视图栅格化后,生成 Surface。GPU 作为图像流生产方将显示内容,最终发送给图像流的消耗方 SurfaceFlinger。大多数客户端使用 OpenGL ES 或 Vulkan 渲染到 Surface 上(硬件加速,使用了 GPU 渲染)。但是,有些客户端使用画布渲染到 Surface 上(未使用硬件加速)。

  3. 生成 Surface 并存储到 BufferQueue
    Surface 对象使应用能够渲染要在屏幕上显示的图像。通过 SurfaceHolder 接口,应用可以编辑和控制 Surface。Surface 是一个接口,供生产方与使用方交换缓冲区。

  4. SurfaceFlinger 将显示数据发送给显示屏
    SurfaceFlinger 接受来自多个源的数据缓冲区,然后将它们进行合成并发送到显示屏。WindowManager 为 SurfaceFlinger 提供缓冲区和窗口元数据,而 SurfaceFlinger 可使用这些信息将 Surface 合成到屏幕。

参考资料

https://www.codenong.com/cs110921652/
https://source.android.google.cn/devices/graphics
https://www.jianshu.com/p/b1b75ab6f17f
https://blog.csdn.net/vviccc/article/details/95597091
https://segmentfault.com/a/1190000022114641
https://community.nxp.com/t5/i-MX-Processors-Knowledge-Base/Android-Graphic-UI-with-GPU-Hardware-Acceleration/ta-p/1102023

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值