文章转自:http://blog.csdn.net/yinjiabin/article/details/7674053
2. DirectFB给上层图形库提供的接口调用
2.1 主要接口
DirectFB由超级接口IDirectFB为上层提供接口调用,其他所有接口都由此接口生成,这些接口内容包括:
=========================
. IDirectFBScreen
. IDirectbFBDisplayLayer
. IDirectFBSurface
=========================
显示屏幕、显示层、显示表面,三者之间的关系可这样表述:
显示屏幕<-Output(connector)<-IDirectFBScreen<-(mixer)-DisplayLayers <-DisplayLayer's IDirectFBSurface<-gfx Accelarator <--显卡/或CPU运算画图
首先,用户在显示屏幕上看到一个Screen的输出,这个Screen由多个画面组成(比如同时包含:背景图片,前景视频/字幕/图片)。组成Screen的每个画面,都由一个单独的DisplayLayer来处理。多个DisplayLayers由Mixer来决定叠加的顺序/位置/以及透明度等。单独一个显示层DisplayLayer,可自由控制输出大小(放大/缩小)、背景颜色、翻转等。DisplayLayer所显示的数据(比如解析JPEG产生的RGB数据),则需要在DisplayLayer上生成一个Surface来显示,Surface控制实际的贴图操作,比如:画点/线/框/填充/变换位数、色深、分辨率,等等, Surface可直接和硬件加速打交道(gfxcard)。
以上描述的DisplayLayers和Surface都是Screen的后端,Screen的前端(就是输出部分),还有Encoder,Output等概念。Encoder着重描述输出信号的编码参数,Output着重描述输出接口. 它们有以下重要成员:
=========================
IDirectFBImageProvider
IDirectFBVideoProvider
IDirectFBFont
=========================
参见源代码:idirectfbimageprovider_dfiff.c / idirectfbimageprovider_gif.c / idirectfbimageprovider_jpeg.c / idirectfbimageprovider_png.c
DFB对dfiff/gif/jpeg(libjpeg.a)/png(libpng.a)第三方软件解码库做了简单封装,以在DFB的框架内在恰当的时候去解码或贴图。
在子目录“interfaces/IDirectFBImageProvider”下有具体图片格式的实现,具体是否生效取决于configure参数。
举例JPEG通过imageprovider解码和贴图的过程,具体参见以下代码:
2. 测试代码通过CreateImageProvider调用创建provider,此函数会定位到interface.c::DirectGetInterface()中。DirectGetInterface函数遍历interface链表,首先匹配provider类型,再通过具体implementation的Probe函数回调挨个匹配,Probe函数有的是通过文件扩展名匹配,有的需要读取文件内容进行匹配(这里JPEG是通过文件扩展名匹配的)。与某种类型的provider完全匹配后,返回provider,调用其Construct函数. test程序再调用GetSurfaceDescription获取图片的参数,再用此参数通过函数CreateSurface创建目标显示表面,再通过provider的RenderTo函数往目标Surface贴图。
视频采集与显示IDirectFBVideoProvider, VideoProvider分两种:
=========================
IDirectFBEventBuffer
IDirectFBDataBuffer
IDirectFBInputDevice
=========================
IDirectFBEventBuffer: 事件同步机制,一端接入产生事件的设备,使用PostEvent之类的接口递交事件,另一端使用WaitForEvent之类的接口等待事件,使用GetEvent之类的接口获取事件。
常用与输入设备
IDirectFBDataBuffer: 数据DataBuffer缓冲,提供同步等待功能,并提供CreateXXXProvider(XXX=Image/Video)功能,在原代码中被广泛使用.
IDirectFBInputDevice: 输入设备接口
2.2. QT与DirectFB之间的关系
QT从4.3版本开始尝试加入DirectFB,直到4.6版本以后才稳定下来。DirectFB至今也到了1.5.0版本(201106),给图形库提供的硬件加速接口也在不断的扩充。
需要说明,DirectFB并不包含QT的所有画图函数的实现,这一点在QT的文档中有表述。
QT中调用的DirectFB代码,主要分布在子目录"src/plugins/gfxdrivers/directfb/"下,上面提到的几乎所有接口都有涉及。
笔者移植QT+DirectFB过程中,使用了QT的Configure选项:
./configure -embedded mips -qt-gfx-directfb -little-endian -prefix /tftpboot/install -prefix-install -v
运行时敲入命令:
./browser -qws -display directfb
3. DirectFB给底层硬件提供的接口。
3.1 输入设备接口: InputDrivers
输入设备的管理位于核心代码src/core/input.c,输入设备的接口定义位于src/core/input_driver.h。 DFB对输入设备的管理、使用,只是简单的对输入设备的设备文件进行封装,并没有真正的去驱动某种输入设备。
要添加一个输入设备,首先要在DFBROOT目录下的子目录"inputdrivers/"下添加一个源文件,或者是在"inputdrivers/"目录下修改一个已有的源文件。 "inputdrivers"的名称来自于“src/core/input.c”头上的DEFINE_MODULE_DIRECTORY定义,所以不同DFB版本对应的目录名称可能不同。 其次,要在你的源文件中引用头文件'core/input_driver.h'并实现InputDriverFuncs所定义的函数:
3.2 硬件加速gfxcard.
* 涉及源代码src/core/graphics_driver.h, src/core/gfxcard.h, src/core/gfxcard.c, 举例:gfxdrivers/pxa3xx/
这一章很复杂,笔者也只能泛泛而谈。
个人认为,DirectFB最重要的功能就是能够统一不同的硬件显示加速设备的各种加速功能为上层图形库所用。
gfx加速在DFB中分两层概念:
真正实现加速功能的,是graphics device的函数调用。先看看DirectFB是如何把用户的画图动作,转化为gfxcard的硬件实现的。
前面讲过Surface控制实际的贴图操作,所以下面的调用堆栈跟踪都从IDirectFBSurface开始。
上层用户可通过IDirectFBSurface.GetAccelerationMask()的返回值判断所需画图动作是否可以加速,具体调用堆栈如下:
src/display/idirectfbsurface.c:IDirectFBSurface_Construct() -> IDirectFBSurface_GetAccelerationMask() -> src/core/gfxcard.c:dfb_gfxcard_state_check()
-> gfxdrivers/pxa3xx/pxa3xx.c & gfxdrivers/pxa3xx/pxa3xx_blt.c: pxa3xxCheckState()
即: Device的CheckState()函数,是用于判断所需加速功能是否可用的。
一次具体的画图操作(比如:填充矩形),调用堆栈如下:
src/display/idirectfbsurface.c:IDirectFBSurface_FillRectangle() -> src/core/gfxcard.c: dfb_gfxcard_fillrectangles()
dfb_gfxcard_state_check( state, DFXL_FILLRECTANGLE ) -> gfxdrivers/pxa3xx/pxa3xx_blt.c: pxa3xxCheckState()
dfb_gfxcard_state_acquire( state, DFXL_FILLRECTANGLE ) -> gfxdrivers/pxa3xx/pxa3xx_blt.c: pxa3xxSetState()
card->funcs.FillRectangle( driver_data, device_data, &rect ) -> gfxdrivers/pxa3xx/pxa3xx_blt.c: pxa3xxFillRectangle()
即: Surface在调用每一个加速画图函数之前,都会先调用Device.CheckState()判断所需函数是否可达,再调用Device.SetState()告知具体device即将使用此类加速函数(pxaxxx是在SetState()中确定接下来该使用哪个加速函数来实现当前画图功能),然后调用Device的具体加速函数画图。
了解了画图加速函数的调用堆栈,再来看看gfxcard支持哪些加速函数,(参考源代码src/core/gfxcard.h):
FillRectangle : 填充矩形
DrawRectangle : 画矩形
DrawLine : 画线
FillTriangle : 填充三角形
Blit : 位块传送(内存拷贝/移动?)
Blit2 : 位块传送2(支持源坐标)
StretchBlit : 位块传送并拉伸
TextureTriangles : ?
可以看出,列举的函数都是2D加速函数。
4. DirectFB移植事项
DirectFB是一个软件中间层,它为底层的硬件驱动和上层的GUI提供了统一的接口调用,但它不做任何实际画图操作。要移植DirectFB到目标嵌入式硬件上,为了最大限度利用硬件的加速功能,移植的过程中要考虑以下问题:
====================================================================================================================================
附:ubuntu 12.04中编译及运行DirectFB
DirectFb主页:http://www.directfb.org/
从上面下载源代码
DirectFB-1.6.2.tar.gz DirectFB-examples-1.6.0.tar.gz
先是库的编译,解压,进入代码目录
tar xvf DirectFB-1.6.2.tar.gz
cd DirectFB-1.6.2
配置,方便记录写成脚本 autoconf.sh
-----------------------------------------------------------------------------
#!/bin/sh
./configure --enable-osx=no \
--enable-x11=yes \
--enable-zlib=yes \
--enable-sdl=yes \
--enable-freetype=yes \
--with-tests
exit 0
------------------------------------------------------------------------------
可能会提示缺少一些库,比如jpeg\png\freetype库等,可以使用apt-cache search <libname> 查找,然后用 apt-get install <libname>安装,
然后再运行配置脚本 ./autoconf.sh
配置成功后编译,安装 (部分源代码为C++编写,编译需要g++)
make;make install
配置环境变量,同样写成脚本 setdirectfbenv.sh
------------------------------------------------------------------------------
#!/bin/sh
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
------------------------------------------------------------------------------
ubuntu 12.04 默认是不能直接使用framebuffer设备的,需要手动配置打开
可参考:http://my.oschina.net/u/212149/blog/69590 《ubuntu12.04开启Framebuffer》
大概流程是这样
1.修改 /etc/initramfs-tools/modules
加入这两行
fbcon
vesafb
2.修改 /etc/modprobe.d/blacklist-framebuffer.conf
#blacklist vesafb
3.重新生成ramfs文件
update-initramfs -u
4.重启
5..设定启动默认分辨率和颜色位数 (可不需要)
修改文件 /etc/default/grub
在GRUB_CMDLINE_LINUX_DEFAULT = “quiet splash” 后面增加vga参数。
比如: GRUB_CMDLINE_LINUX_DEFAULT = “quiet splash vga=788” (其实这里可以不设置,根据环境运行的需要,通过fbset工具设置分辨率和色深)
vga参数和分辨率的对照表为grub-mkconfig
update-grub
重启
也可以通过fbset命令临时设定分辨率和色度。
打开完成后可以运行DirectFB自带的例子
运行前配置环境变量,之前的脚本 ./setdirectfb.sh
cd DirectFB-1.6.2/tests/
./dfbtest_window
运行成功后可以,编译运行例子代码DirectFB-examples-1.6.0.tar.gz