DirectFB概述:
DirectFB是图形API存在于Frame Buffer层之上与高级图形管理层如GTK+等之下的。它可以以很小的系统资源占用来提供图形硬件加速功能,提供类如多路a通道渲染模型等高级图像操作。它不修改Linux内核,除了标准C库没有其他库的依赖。应用在了基于Linux系统的DTV显示系统的研发和其他有关Linux显示界面的项目上。支持市面上绝大多数显示卡,支持键盘、鼠标、遥控器、游戏手柄、触摸屏等输入设备。支持JPEG、PNG、GIF、mpeg1/2、AVI、MOV、Flash、Video4Linux、DirectFB bitmap font和TrueType等音视频文件和字体。
上层API支持DirectFB的有:
XDirectFB、DirectFBGL、GTK+、DFBTerm、DFBSee、DFBPoint、MythTV、Qt on DirectFB、SDL(Simple Directmedia Layer)。
关于DirectFB的layer问题
和石可箴讨论了一下DPF系统显示的layer数量的问题,总结出layer支持数量的多少要靠芯片和驱动的共同支持才能实现。以前DTV系统中就有若干个OSD层、Video层、Cursor层等。网上查了一下DirectFB能支持的layer层数,发现对于DirectFB的layer来说有两个层面上的理解:
1.作为硬件层面:硬件层面中layer的多寡取决于芯片的硬件资源。在DirectFB中使用的是IDirectFBDisplayLayer接口。其内容将直接显示在屏幕上。
2.作为软件层面:DirectFB没有专门的接口,但是可以利用IDirectFBWindow接口自己建立起多layer结构。如使用IDirectFBWindow->SetOpacity(IDirectFBWindow *thiz, __u8 opacity)来实现这样的结构。
> IDirectFBWindow OSD <--highest window
> IDirectFBWindow video with video Provider
> IDirectFBWindow mpegstill
> IDirectFBWindow background with image Provider<--lowest window
通过设置其opacity来实现一个硬件layer上的4个不同的layer。
根据这个实现方法,以及DirectFB直接将FrameBuffer的memory mapping到application的memory中的工作原理,突然联想到了RAMDAC,猜想我们DPF中可能也有这种器件。随即先查询了RAMDAC的相关资料,RAMDAC的作用是把数字图像数据转换成计算机显示需要的模拟数据。显示器收到的是RAMDAC处理过后的模拟型号。RAMDAC经历了与GPU分开放置——合并在一颗芯片——又分开放置的变迁过程,主要是成本与性能上的考量所致。然后查了一下DPF中是否也有类似的器件,没有发现,作罢。
DirectFB的安装流程
1. 解压DirectFB-1.0.0.tar.gz包
2. 入此目录执行
# ./configure
# make
# make install
一切正常。
DirectFB Sample的编译
先拿官方例子玩玩,第一次直接用#gcc draw_linc.c –o draw,报错,No such file or directory ‘directfb.h’
解决方法是include上DirectFB的安装目录,# gcc –I/usr/local/directfb draw_linc.c –o draw
这次是在link的时候报错,很多undefined reference to ’xxxx’
补上lib目录,# gcc -L/usr/local/lib -I/usr/local/include/directfb draw_line.c -o draw
但发现还是报错,根据提示,查看了/usr/local/lib/pkgconfig的directfb.pc文件,发现里面有编译参数信息
prefix=/usr/local
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
Name: DirectFB
Description: Graphics and windowing library for the Linux frame buffer device
Version:1.0.0
Requires: fusion direct
Libs: -L${libdir} -ldirectfb -lpthread -ldl -lz
Cflags: -D_REENTRANT -I${prefix}/include/directfb
显然还要加上参数。
解决方法如下,# gcc -L/usr/local/lib -I/usr/local/include/directfb -ldirectfb -lpthread -ldl -lz draw_line.c -o draw
编译通过。
当然,最方便的方法是pkg-config,因为DirectFB安装时已经自动配置好。
# gcc `pkg-config --cflags --libs directfb` draw_line.c -o draw
编译通过。
DirectFB Sample的运行
直接运行./draw,在打开framebuffer的时候报错。
查询结果是framebuffer也需要配置一下。
在/boot/grub/menu.lst中增加vga=0x317这个参数。
重启后,再次运行./draw,framebuffer错误已经解决,但又出现找不到shared libraries的问题。
添加# export LD_LIBRARY_PATH=/usr/DirectFB25/lib后,执行文件时又回到了framebuffer出错时的状态“/dev/fb0: No such file or directory”。晕倒了。周一继续查底层的framebuffer哪里有问题。
感谢上帝终于调通了,果然是底层FrameBuffer的问题。方法是在/boot/grub/menu.lst中的kernel这行后面加上vga=0x317,reboot后,启动画面中出现了两只可爱的小企鹅,这下我确信FrameBuffer打开了。运行程序后一切正常。
但是有一点要注意,在新打开一个终端后,为了运行DirectFB程序,必须要先设置一个环境变量,export LD_LIBRARY_PATH=/usr/local/lib。将这句话放在/root/.bashrc中,有效。明天的任务就是load一个图片出来。
一切ok,完成了剩余三个sample后,总结了一下,官方的五个sample提供了画线、画图片、画文字、图片按照键盘响应上下移动,图片按照键盘响应随机移动。
Sample中图片对象的创建都是用CreateImageProvider来实现的,经过实测,可以支持的图像格式为:jpg、png、gif,不支持的图像格式为:bmp、tif。
DirectFB的重新总结
经过多方面资料验证,DirectFB是将FrameBuffer重新封装,提供新的、功能较强大的图形API接口供上层GTK+、QT等调用。但自身并不提供控件,如果要实现下拉菜单等效果,必须使用GTK+等高级图形库调用DirectFB来实现。
DirectFB的学习
Today I learn the global settings of DirecFB: /etc/directfbrc, Every DirectFB application will read that setting file at first. And the parameter shows below can also be transmitted by the prefix --dfb behind the ./filename.
I’ve tried the parameters as below.
system=<system>, it could be fbdev, sdl. The fbdev is the default value, means it use the Linux frame buffer. The sdl is the fastest one in refreshing jpeg, but it flashing a lot and can’t run the sprite sample normally. But I found the main difference that if you use fbdev, it creates a full screen field to display picture, and if you use sdl mode, it just creates a window to show it and you can move your mouse out from the display field and to control other application.
mode= <width>x<height>, I tried, and it works. And it seems no limit range to the display field.
fbdev=<device>, the default device is “/dev/fb0”, and if you want to use fb1, fb2, etc, you should create the link in the /dev.
force-windowed, no use with another parameter scaled=800x600.