FrameBuffer 是 Linux 系统中的一种显示驱动接口。FrameBuffer 将显示硬件进行抽象,对用户表现为一块显示内存,用户空间进程可以直接操作这块内存空间完成写屏操作。FrameBuffer 在设备上表现为一个字符设备,设备节点为 /dev/fb*
。用户对设备节点进程 open、mmap、ioctl、read、write 等操作,就可以控制最终的显示输出。
FrameBuffer 在结构上是一个相对简单的驱动,操作流程也比较简单,一般的流程为:
FrameBuffer 驱动的实现与硬件关系非常大,很难有一个统一的开发流程,所以实现细节也不介绍了。在软件实现上,很多都是围绕驱动中的几个数据结构来实现的。
FrameBuffer 驱动结构上比较简单,但这并不意味着开发会很简单,开发复杂度与硬件复杂度有很大关系。如果仅仅是一个显示控制,那么实现对应的驱动接口可能就差不多了。但是如果显示单元中包含显示后处理,画质调节等其他硬件单元时,显示驱动就可能变得比较复杂,并且调试难度也增加很多。
FrameBuffer 这种简单的结构也带来了很大的灵活性,许多复杂的处理可以交给上层应用或更底层的硬件来做。例如多个图层渲染,可以由应用使用软件或 GPU 先进行合成,再交给 FrameBuffer 显示。如果硬件支持多个显示层,也可以将每个图层送给 FrameBuffer,然后由硬件进行合成。
另一个常见的问题就是显示流畅性。当使用单缓冲时,很难确保显示画面没有撕裂。单缓冲的流畅显示需要保证软件送显与硬件显示保持相同的帧率,并且显示缓冲的准备时间要尽量短,必须小于帧周期。使用双缓冲时,要求就小很多,更容易保证显示流畅。双缓冲使用乒乓结构,当一个缓冲用于硬件显示时,另一个缓冲用来软件写入。双缓冲可以在应用层或驱动层实现,驱动实现时通过 FBIOPAN_DISPLAY 来交换缓冲。为了确保流畅性,现在有使用三缓冲或更多缓冲来实现,缓冲越多越有利于流畅性,但消耗的内存会更多。设计架构时需要根据实际情况来选择缓冲数。