DirectFB (Direct Frame Buffer)是一组建立在Linux framebuffer 设备(fbdev)抽象层之上实现的图形api。DirectFB运行在Frame Buffer Device (/dev/fb)之上,并利用芯片组驱动程序的硬件加速,实现对图形图像的高效处理。
它的架构如下图所示:
注意图中的蓝色箭头,它是实现硬件加速的关键,我们以代码为例,分析一下DirectFB硬件加速的实现原理。
获取代码:
DirectFB的源很多,随便在gitee上找到一个仓库下载,看名字是在新唐的SOC上的directfb加速实现。
git clone https://gitee.com/ufbycd/NUC970_DirectFB.git
代码目录结构:
核心实现代码:
数据源模块实现:
interface目录中实现的模块,可以作为数据源,输出图像供DIRECTFB贴图实现,以./interfaces/IDirectFBVideoProvider/idirectfbvideoprovider_v4l.c为例,它可以直接从v4l设备读取yuv数据,软件贴图显示视频,idirectfbvideoprovider_gif.c 则同样,之不是它提供的是GIF数据源。
帧缓冲区实现:
核心实现代码在src目录下,主要是其中的core目录。
system目录则是不同的不同的framebuffer 驱动实现,可以看到这里有最常见的fbdev,除了fbdev,framebuffer还可以是android的帧缓冲机制,它是基于egl 实现,还可以是x11/sdl等其它的帧缓冲区实现。
以fbdev为例,我们可以看它的关键实现是:
android 基于egl 实现:
加速器实现:
加速器的实现在另外一个目录,这个目录下有各个支持G2D加速的厂家的针对自己加速器的porting.比如allwinner也可以自己写一个针对自家G2D的加速实现代码,放到这里。
我们看一下核心实现机制:
以AW为例,google到一套开源社区的实现,它是基于vmware的实现改的,地址在这里
https://github.com/allwinner-ics/lichee_buildroot/blob/master/package/directfb/directfb-1.4.11-vmware.patch
可以看到,它的实现中调用了AW G2D接口API。
回到代码,我们顺着这套思路继续找,首先找到新塘的FillRectangle,可见,AW的叫G2D,而新唐的叫GE2D,从功能上来讲,其实指的都是同一个东西。
可以看到,对于对接一个新的G2D加速设备,需要实现的接口有:Blit, StrechBlit, DrawLine, DrawRectangle, FillRectangle, SetState, CheckState,EmitCommands, EngineReset, EngineSync几个接口。更具体的要看typedef struct _GraphicsDeviceFuncs 函数表结构体中的函数有哪些。
Nvidia的实现更加复杂
接下来我们看driver_init_driver是如何被调用的,流程比较简单,就不过多介绍了。
所以,基本上DirectFB的工作原理可以摸清楚了。