从Android 12开始,Android的绘制系统有结构性变化, 在绘制的生产消费者模式中,新增BLASTBufferQueue,客户端进程自行进行queue的生产和消费,随后通过Transation提交到SurfaceFlinger,如此可以使得各进程将缓存提交到SufrfaceFlinger后合并到同一事务后同步提交,在同一帧生效。实际上,从Android12到Android14整个绘制系统在各个环节也都有了或大或小的调整,比如Android13发布了1.3版本的Vulkan, Android14新增了TextureView,等等。本文基于Android14。
Android 绘制系统整体架构:
从上到下可以理解为“生产者(Producer)”到“消费者(Consumer)”的处理过程。
首先,从WindowManagerService的角度,每个窗口称为Window,一个Window一般是一个APP的页面,或者Status Bar,或者Navigation Bar,或者WallPaper,这些都是一个个Window。WindowManagerService(WMS)作为服务端,对所有客户端窗口的添加、层级、布局等进行统一管理。在WMS端,每个Window对应一个Surface。Surface可以理解为图像数据缓存的持有者,以及Canvas的持有者。Canvas是画布,提供了绘制各种图形的能力供开发者使用。一个客户端窗口在建立之初,会先向WMS去申请一个Surface,WMS在创建了Surface之后,通过binder返回给客户端。客户端拿到Surface后,会去创建一个BLASTBufferQueue来管理图像内存的申请。每次要使用Surface的Canvas进行绘制前,需要先向BLASTBufferQueue申请一块内存(dequeue),我们这里称为Buffer,然后再将生成的图像数据写入Buffer。这个向BLASTBufferQueue申请Buffer并写入图像数据的过程,可以认为是“生产”阶段。随后,enqueue这个buffer,将其提交给SurfaceFlinger去合成。这个阶段,可以理解为图像Buffer的“消费”阶段。
SurfaceFlinger(SF)是负责与Hardware层沟通,维护着设备挂载、VSync信号收发、Layer合成等工作。WMS的每个Surface在SurfaceFlinger中都对应生成一个Layer对象。客户端将某个Surface上的Buffer提交给SurfaceFlinger,实际上就是更新了对应Layer的Buffer数据。SurfaceFlinger调用HWComposer将这些Layer进行合成并显示在屏幕。
Android在HAL层提供称为一个Hardware Composer的组件,用于隔离与具体硬件的交互。Hardware Composer简称HWComposer或HWC2(之所以是2,是早期已有一个HWC版本,只支持软件合成)。SurfaceFlinger把Layer数据交给HWComposer,各厂商来负责HWComposer合成接口的具体实现。在合成完毕后,将数据提交到屏幕设备的缓存(一般称为Frame Buffer),屏幕就显示出画面来了。
上面的过程,可以拆解为几部分:
- Surface的创建与管理。
- 客户端(EndPoint)绘制(Draw)和渲染(Render)图像。
- 第三部分,是硬件Composition(合成)工作
- Vsync:由硬件产生的信号,用于同步framebuffer的生产和消费。SurfaceFlinger对Vsync进行了使用和管理,并向上分发给APP。Vsync是不断绘制的驱动力,也是图像缓存有序投送到屏幕的重要机制。
现在,分别讨论下四部分:
- Surface的创建与管理
在Surface的创建过程中,有几个角色贯穿其中:
PhoneWindow:一个Activity对应一个PhoneWindow,代表一个应用窗口。在AMS创建Activity之初,PhoneWindow在服务端的对应的window对象(ActivityRecord)已经添加到WMS。
ViewRootImpl:其主要作用是与服务端通信,承接外部触发的绘制调用,从而从上往下对整个View树进行绘制。可以把ViewRootImp理解为View的调度者。ViewRootImp在逻辑上是View Hierarchy的最顶层,但其并不是一个真正