Android 显示系统框架

一.FrameBuffer

FrameBuffer 介绍:

FrameBuffer中文译名为帧缓冲驱动,它是出现在2.2.xx内核中的一种驱动程序接口。主设备号为29,次设备号递增。

Linux抽象出FrameBuffer这个设备来供用户态进程实现直接写屏。FrameBuffer机制模仿显卡的功能,将显卡硬件结构抽象掉,可以通过FrameBuffer的读写直接对显存进行操作。用户可以将FrameBuffer看成是显示内存的一个映像,将其映射到进程地址空间之后,就可以直接进行读写操作,而写操作可以立即反应在屏幕上。这种操作是抽象的,统一的。用户不必关心物理显存的位置、换页机制等等具体细节,这些都是由FrameBuffer设备驱动来完成的。

FrameBuffer实际上就是嵌入式系统中专门为GPU所保留的一块连续的物理内存,LCD通过专门的总线从framebuffer读取数据,显示到屏幕上。

FrameBuffer本质上是一块显示缓存,往显示缓存中写入特定格式的数据就意味着向屏幕输出内容。所以说FrameBuffer就是一块白板。

framebuffer常见的设计规格:

fb常见的典型规格:支持几个图形层(如果只有一个图层,那么鼠标必须叠加到内容中),每个图形层 支持哪些 像素数据格式 / 分辨率 / 颜色空间 / 是否支持裁剪crop / 是否支持显示偏移设置 / 是否支持压缩数据解压读取(降低带宽) / 是否支持缩放 等;

二.FrameBuffer与Android

当我们的程序 想要 在屏幕上显示内容时,我们的机制是直接向FrameBuffer(后面简称FB)写入内容来实现。接下来谈谈Android 实用FB的策略:

如果只有一个FB,当APP写入速度>LCD显示速度时没问题;当APP写入速度 <=LCD显示速度时,会卡顿和闪烁,为了解决这个问题,一般采用2个以上FB。以2个FB为例,APP写入FB0,LCD此时渲染FB1,FB0写入结束后,LCD渲染FB0,此时APP写入FB1,之后不断循环即可。

对于Android系统来说,有很多个APP,如果这些APP同时向FB写入内容那显示的内容就乱了,因此 需要一个大管家来管理,这个大管家就是 SurfaceFlinger。

三.SurfaceFlinger整体框架简图说明

SurfaceFlinger(后 简称SF)主要可以做以下几件事情:

1.给app提供buffer: 通过gralloc模块向ashmen申请内存得到文件句柄fd,将fd通过binder机制传递给对应的app,app再执行mmap操作即可获得 对应的buffer。

2.将app发来的buffer(界面数据)进行合成:根据各个界面的layer(就是Z值,由WindowManagerService来确定),把这些排序后的整体buffer传递给HardwareComposer(后简称HWC)。

3.当HWC不能处理(无HWC硬件、超出HWC层数)buffer时,使用图形库GL来处理。

4.SF也好,APP也好,都可以直接调用EGL层接口来实现 渲染功能。

四.Gralloc模块

用户空间的应用程序在使用帧缓冲区之间,首先要加载Gralloc模块,并且获得一个gralloc设备和一个fb设备。有了gralloc设备之后,用户空间中的应用程序就可以申请分配一块图形缓冲区,并且将这块图形缓冲区映射到应用程序的地址空间来,以便可以向里面写入要绘制的画面的内容。最后,用户空间中的应用程序就通过fb设备来将前面已经准备好了的图形缓冲区渲染到帧缓冲区中去,即将图形缓冲区的内容绘制到显示屏中去。相应地,当用户空间中的应用程序不再需要使用一块图形缓冲区的时候,就可以通过gralloc设备来释放它,并且将它从地址空间中解除映射。

五.HWC叠加器

hwc模块定义—The Hardware Composer硬件叠加器

应用把要显示的layers交给SurfaceFlinger,SurfaceFlinger直接把这些layers交给hwc,hwc就可以在自己能力范围内做好合成,再把合成好的结果拿去显示。如果芯片显示硬件模块功能较弱,不支持某些合成场景,就会用CPU(纯软件合成)或者GPU去做。

六.OpenGL

OpenGL( Open Graphics Library 开发图形接口)是一个跨平台的图形 API,用于指定 3D 图形处理硬件中的标准软件接口。

总结的来讲,OpenGl 提供了指定图形处理的硬件接口,我们在处理图形的时候,只要按照它的规则来调用,就可以获得更加高效的图形处理方法。

通过下面这张图可以看到,它其实是 CPU 和 GPU 图形交互的一个桥梁,可以理解成一个库

因为 GPU 在处理逻辑运算方面,有天然的优势,因此,可以理解 OpenGL ES 就是一个能操作 GPU 的API。