图形
Android的框架为2D和3D提供了各种各样的图形着色APIs与厂家实现的图形驱动进行交互,所以明白这些APIs在更高一层如何工作是很重要的。这页介绍了那些建立在图形硬件抽
象层上的驱动。
应用开发者在屏幕上绘制图片有两个方法:使用Canvas或OpenGL。 更详细的关于Android图形组件的描述,可以查看系统级图形架构。
androd.graphics.Canvas 是一个2D的图形API,也是开发者最常用的API。Canvas操作可以绘制所有Android库中的以及定制的android.view.Views。在Android里,硬件加速的
Canvas API是通过调用一个叫做OpenGLRender的库来完成的,主要是把Canvas的操作转换成OpenGL的操作,好让他们可以在GPU中执行。
Android 4.0开始,硬件加速的Canvas是默认可用的。结果,支持OpenGL ES 2.0的硬件GPU是Android 4.0以及后续设备必备的。关于硬件加速的绘制路径是如何的,以及他们与
软件绘制路径的差别的解释可以查看硬件加速指南。
除了Canvas之外,开发者另外一个主要的渲染图形的方式就是通过OpenGL ES直接在Surface上着色。Android给开发者提供位于android.opengl包中的OpenGL ES接口,使其可
以在他们的用SDK或由Android NDK提供的本地API实现的GL来调用。
Android Graphics components 安卓图形组件
无论开发者使用怎样的渲染API,所有的东西都是在“surface”上渲染的。Surface代表着buffer queue的生产者一方,并通常是由SurfaceFlinger来消费的。每一个在Android平台
上创建的窗口都由一个surface支持。所有的可见渲染好的Surface都由SurfaceFlinger组合并并送到显示。
下图图表显示了关键组件如何一起工作:
图1:Surfaces如何被渲染
主要的组件如下描述:
图像流的生产者:
图像流的生产者可以是任何能给消费者产生图形buffers的东西。例子如:OpenGL ES,Canvas 2D,以及 视频解码多媒体服务。
图像流的消费者
最普遍的图像流消费者就是SurfaceFlinger,它是一个系统服务,消费目前可见的surface,并且使用windowmanager提供的信息在显示器组合它们。SurfaceFlinger使用
OpenGL和硬件组合器来组合一组的surfaces。
其他OpenGL ES apps也可以消费图像流,如camera app消费一个camera的预览图像流。非GL应用也可以是消费者,举例如ImageRender类。
WindowManager
Android系统服务控制一个作为views的容器的窗口。一个窗口总是由一个surface支持的。这个服务监控着窗口的:生命周期,输入,焦点事件,屏幕方向,变化,动画,方位,变形,z次序以及许多其他方面。WindowManager发送一个窗口的所有元数据给SurfaceFlinger,好让它可以使用这些数据来在显示上组合surfaces。
Hardware Composer 硬件组合器
硬件是对显示子系统的抽象。SurfaceFlinger可以把某些合成工作委派给硬件组合器来分担来自OpenGL和GPU的工作。SurfaceFlinger担任了OpenGL ES另一个客户端。所以
当SurfaceFlinger正在积极的组合一buffer或二buffer到第三个时候,它正在使用OpenGL ES。这比使用GPU执行全部运算更省电。
硬件组合器HAL管理着其他一半工作。这个HAL是所有Android图形渲染系统的中心。硬件组合器必须支持事件,其中一个是VSYNC。另外一个是支持即插即播的HDMI热插
拔。
要获得更详细的信息,请查阅Harware Composer HAL
Gralloc
图形内存创建器被要来创建由图像生产者请求的内存。更详细的信息请查阅Gralloc HAL
Data Flow 数据流
查看以下关于Android图形管道解释的图表
图2:图形数据如何在Android里流动
左边的对象是生产图形Buffer的渲染者,如Home 屏幕,状态栏和系统UI。SurfaceFlinger是组合者,硬件组合器也是组合者。
BufferQueue
BufferQueue是Android图形组件的粘合剂。存在一对的队列来调解周期的buffer循环:从生产者到消费者。一旦生产者把他们的Buffers递交,SurfaceFlinger就有责任在显示上
组合所有东西。
看看下面有关BufferQueue交流过程
图3:BufferQueue交流过程
BufferQueue包含以下逻辑:把图像流生产者与图像流消费者绑在一起。一些图像生产者的例子如由cameraHal或OpenGL ES游戏提供的camera预览。一些图像消费者的例子
如SurfaceFlinger或其他能显示OpenGL ES流的应用app,如camera应用显示camera取景器。
BufferQueue是一个数据结构,结合一个带有一个队列的buffer池,并且使用Binder IPC在进程间传输。生产者接口或你传给希望产生图形buffer的人的东西,是
IGraphicBufferProducer(SurfaceTexture的部分)。BufferQueue常在其他任何中被用来渲染一个Surface,并被一个GL消费者消费。BufferQueue工作在三种模式:
类同步模式---BufferQueue默认工作在类同步模式,此模式中,每一个来自生产者的buffer去往消费者。此模式下,没有一个buffer被丢弃。如果生产者太快了,并且创建buffer
比他们被消耗的快,它会阻塞等待到空buffer。
非阻塞模式---BufferQueue也可以工作在非阻塞模式,此模式下,它返回一个错误而不是像其他案例一样等待一个buffer。此模式下,也没有buffer会被丢弃。对于避免潜在的存
在于不明白图形系统框架复杂度的应用软件中的死锁很有帮助。
丢弃模式---最后,BufferQueue也许被配置为丢弃旧的Buffer而不是产生错误或等待。举个例子,如果让GL渲染到一个texture view和尽可能快的绘制,buffers必须被丢弃。
Synchronization Framework 同步框架
既然Android图形提供非明确的并行机制,制造商一直在他们自己的驱动里实现隐含的同步。这不在是Android图形同步框架的需求了。实现指导可以查看
同步框架明确的描述了系统中不同异步操作的依赖性。框架提供了一个简单的API,使组件在buffers被释放时产生信号。它同时允许同步原语在内核区和用户区之间,用户区进
程间传递。
举个例子:一个应用也许让任务排着队在GPU中执行。GPU开始绘制图像。虽然图像还没有在内存中画好,伴随一个提示GPU完成工作的栅栏信号,buffer指针依然可以传递到
window合成者那里。窗口合成者或许提前开始处理,并把工作传递给显示控制器。这种方式,CPU工作可以提前完成。一旦GPU完成,显示控制器就能立即显示图像。
同步框架也允许实施者在他们自己的硬件组件内使用同步资源。最后,框架提供图形管道的可见性有助于调试。