[关闭]
@ltlovezh 2019-10-06T13:21:26.000000Z 字数 2811 阅读 393

Android图形系统概述

图形系统


图形系统是Android中非常重要的子系统,与其他子系统相互协作,完成图形界面的渲染和显示。

概述

官方提供了一个图形系统的关键组件协作图,如下所示:
Android官方图形架构
这幅图大致描述了图形数据的流转:OpenGL ES、MediaPlayer等生产者生产图形数据到Surface,Surface通过IGraphicBufferProducerGraphicBuffer跨进程传输给消费者SurfaceFlingerSurfaceFlinger根据WMS提供的窗口信息合成所有的Layer(对应于Surface),具体的合成策略由hwcomposerHAL模块决定并实施,最后也是由该模块送显到Display,而Gralloc模块则负责分配图形缓冲区。不过该图缺乏层次感,通过下图我们详细分析整个流程。
图形系统架构

大体上,应用开发者可以通过两种方式将图像绘制到屏幕上:

Canvas是一个2D图形API,是Android View树实际的渲染者。Canvas又可分为Skia软件绘制和hwui硬件加速绘制。
Android4.0之前默认是Skia绘制,该方式完全通过CPU完成绘图指令,并且全部在主线程操作,在复杂场景下单帧容易超过16ms导致卡顿。
从Android4.0开始,默认开启硬件加速渲染,而且5.0开始把渲染操作拆分到了两个线程:主线程和渲染线程,主线程负责记录渲染指令,渲染线程负责通过OpenGL ES完成渲染,两个线程可以并发执行。

除了Canvas,开发者还可以在异步线程直接通过OpenGL ES进行渲染,一般适用于游戏、视频播放等独立场景。

从应用侧来看,不管是Canvas,还是OpenGL ES,最终渲染到的目标都是Surface,现在比较流行的跨平台UI框架Flutter在Android平台上也是直接渲染到Surface。Surface是一个窗口,例如:一个Activity是一个Surface、一个Dialog也是一个Surface,承载了上层的图形数据,与SurfaceFlinger侧的Layer相对应。
Native层Surface实现了ANativeWindow结构体,在构造函数中持有一个IGraphicBufferProducer,用于和BufferQueue进行交互。BufferQueue是连接Surface和Layer的纽带,当上层图形数据渲染到Surface时,实际是渲染到了BufferQueue中的一个GraphicBuffer,然后通过IGraphicBufferProducerGraphicBuffer提交到BufferQueue,让SurfaceFlinger进行后续的合成显示工作。

SurfaceFlinger负责合成所有的Layer并送显到Display,这些Layer主要有两种合成方式:

BufferQueue

Android图形系统包含了两对生产者和消费者模型,它们都通过BufferQueue进行连接:
1. CanvasOpenGL ES生产图形数据,SurfaceFlinger消费图形数据。
2. SurfaceFlinger合成所有图层的图形数据,Display显示合成结果。

Surface属于APP进程,Layer属于系统进程,如果它们之间只用一个Buffer,那么必然存在显示和性能问题,所以图形系统引入了BufferQueue,一个Buffer用于绘制,一个Buffer用于显示,双方处理完之后,交换一下Buffer,这样效率就高很多了。BufferQueue的通信流程如下所示:
BufferQueue

Surface与SurfaceFlinger

Surface表示APP进程的一个窗口,承载了窗口的图形数据,SurfaceFlinger是系统进程合成所有窗口(Layer)的系统服务,负责合成所有Surface提供的图形数据,然后送显到屏幕。SurfaceFlinger既是上层应用的消费者,又是Display的生产者,起到了承上启下的作用。官方提供了一个架构图,如下所示:
Android图形管道

该图可能较抽象,我们通过一个实例理解下这层关系,下图是微信添加朋友的弹窗界面:

我们可以通过adb shell dumpsys SurfaceFlinger查看该界面包含几个窗口(Surface):
微信多Surface
SurfaceFlinger的dump信息可以看到:

总结

本篇文章从上到下简述了Android图形系统的流转流程,以及承载图形数据流转的重要结构:BufferQueue,最后通过dump信息论证了多Surface实例。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注