我们平时在做应用开发时,通常只关心应用进程主线程的绘制,那么我们的界面是怎么被渲染并显示出来的呢?下面这个图大致描述了从应用主线程到渲染线程再到SurfaceFlinger 的工作流程:
-
应用有绘制需求,主线程申请绘制,即ViewRootImpl 向Choreographer申请Vsync ,Vsync 到来后开始绘制三部曲measure、layout、draw
-
draw 之后开始把绘制操作同步给渲染线程,渲染线程RenderThread 循环执行渲染任务,即申请buffer、将绘制操作提交到GPU,GPU 绘制完成通知渲染线程dequeueBuffer,到此应用进程的全部绘制完成
-
queueBuffer后,向SF 申请合成,SF收到Vsync 后开始合成,主要是处理两个消息Invalidate、Refresh
-
Invalidate消息:遍历各个Layer ,通过BufferQueue取出待合成(应用进程queueBuffer但是还没被消费)buffer
-
Refresh消息:主要是确定合成策略Device/Client,计算脏区和可见layer,Client 合成是通过GPU 合成后将buffer传给HWC, 而Device合成直接将待合成的buffer 送给HWC,HWC完成计算合成
上面描述了应用的界面绘制和显示,那么我们的系统通常是需要同时显示多个窗口的,比如应用窗口、Activity、statusbar 等,那么这些窗口又是如何管理的呢?这就涉及FrameWork的系统服务AMS 、WMS 了。下图中描述了系统服务在应用进程和SF进程之间的交互。
- Activity 启动或新建窗口时,通过ViewRootImpl调用WMS relayoutWindow
- 这里会在system server 进程创建WMS窗口管理单位WindowState,以及Surface、SurfaceControl
- SurfaceControl创建过程会创建对应的native层 surface 以及SurfaceFlinger 进程的Layer
- 每个Layer 创建时会创建一个BufferQueue对象,用于管理Layer 对应的buffer
到此,应用进程的一个Activity 或窗口创建后,在system server 中有与之对应SurfaceControl对象,用于管理其窗口大小、层级等属性,SurfaceFlinger 进程中与之对应的Layer, 接收来自应用进程或system server 设置的窗口属性,Layer 中的BufferQueue用于和应用进程通信管理buffer。
下面章节,比较偏向于SF 和上层交互的流程,后面继续学习再来补充^^