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 .