DirectFB是一个轻量级的提供硬件图形加速,输入设备处理和抽象的图形库,它集成了支持半透明的视窗系统以及在LinuxFramebuffer驱动之上的多层显示。它是一个用软件封装当前硬件无法支持的图形算法来完成硬件加速的层。DirectFB是为嵌入式系统而设计。它是以最小的资源开销来实现最高的硬件加速性能。
主机环境:32位Ubuntu 10.10
交叉编译工具:arm-linux-gcc-4.5.1
下载地址:http://code.google.com/p/mini6410-debian/downloads/detail?name=arm-linux-gcc-4.5.1-v6-vfp-20101103.tar.gz&can=2&q=
DirectFB版本:DirectFB-1.5.0.tar.gz
下载地址:http://www.directfb.org/index.php?path=Main%2FDownloads
DirectFB测试用例版本:DirectFB-examples-1.5.2.tar.gz
下载地址:http://www.directfb.org/index.php?path=Main%2FDownloads&page=1
DirectFB依赖库:freetype-2.4.4.tar.gz,jpegsrc.v8c.tar.gz,libpng-1.2.44.tar.gz,zlib-1.2.5.tar.gz
freetype-2.4.4.tar.gz下载地址:http://download.csdn.net/source/3214785
jpegsrc.v8c.tar.gz下载地址:http://download.csdn.net/source/3567307
libpng-1.2.44.tar.gz下载地址:http://download.csdn.net/source/3567317
zlib-1.2.5.tar.gz下载地址:http://download.csdn.net/source/3567321
环境变量配置:
export PREFIX=/usr
export DEST_DIR=/home //以上两个环境变量的是移植后库生成的位置,最好是把以后有提到的库都存放到/home目录下
export PATH=$PATH:/home/opt/FriendlyARM/toolschain/4.5.1/bin
export CC=arm-none-linux-gnueabi-gcc
export LDFLAGS=-L$DEST_DIR$PREFIX/lib
export CFLAGS="-g -I$DEST_DIR$PREFIX/include"
export PKG_CONFIG_PATH=$DEST_DIR$PREFIX/lib/pkgconfig
export FREETYPE_CFLAGS="-I${DEST_DIR}${PREFIX}/include/freetype2 -I${DEST_DIR}${PREFIX}/include"
export PKG_CONFIG_PATH=${DEST_DIR}${PREFIX}/lib/pkgconfig
export PKG_CONFIG_LIBDIR=$PKG_CONFIG_PATH
export CFLAGS="-I${DEST_DIR}${PREFIX}/include/"
export LDFLAGS="-L${DEST_DIR}${PREFIX}/lib"
export LIBPNG_CFLAGS="-I${DEST_DIR}${PREFIX}/include/libpng12"
export LIBPNG_LIBS="-L${DEST_DIR}${PREFIX}/lib -lpng12"
export FREETYPE_CFLAGS="-I${DEST_DIR}${PREFIX}/include/freetype2 -I${DEST_DIR}${PREFIX}/include"
export DIRECTFB_CFLAGS="-I${DEST_DIR}${PREFIX}/include/directfb -I${DEST_DIR}${PREFIX}/include"
export FREETYPE_LIBS="-L${DEST_DIR}${PREFIX}/lib -lfreetype"
移植步骤:
1.
#Make zlib
cd $ZLIB
./configure --prefix=$PREFIX
make
make DESTDIR=$DEST_DIR install
2.
cd $LIBPNG
./configure --prefix=$PREFIX --host=arm-none-linux-gnueabi
make
make DESTDIR=$DEST_DIR install
3.
cd $LIBJPEG
./configure --prefix=$PREFIX --host=arm-none-linux-gnueabi
make
make DESTDIR=$DEST_DIR install
4.
cd $FREETYPE
./configure --prefix=$PREFIX --host=arm-none-linux-gnueabi
make
make DESTDIR=$DEST_DIR install
5.
cd $DFB
./configure --host=arm-none-linux-gnueabi --prefix=$PREFIX --disable-x11 --with-gfxdrivers=none --enable-jpeg --enable-png --enable-freetype --with-inputdrivers=linuxinput
make
make DESTDIR=$DEST_DIR install
错误及解决办法:
1. ../../lib/direct/atomic.h:188:70: error: expected ',' or '...' before 'new'
解决办法:进入到atomic.h文件,把关键字 new 改成new_1等任意不是关键词。
2. ../../lib/direct/serial.h:112:14: error: invalid conversion from 'void*' to 'volatile int*'
../../lib/direct/serial.h:112:14: error: initializing argument 2 of 'int _D__atomic_add_return(int, volatile int*)'
解决办法:进入到atomic.h文件,把有这方面的调动, 通过强制转换把(void *) -> (volatile int *)
6.
cd $DFBEXAMPLE
./configure --prefix=$PREFIX --host=arm-none-linux-gnueabi
make
make DESTDIR=$DEST_DIR install
这样就完成了基本的DirectFB的移植,把/home/usr目录下的全部文件拷贝到开发板的/usr下,运行测试用例就知道成不成功了。
环境说明:这么加速你有移植成功了DirectFB,且你的开发板支持硬件加速功能。不同的硬件平台有不同的配置,我这里就说说我的配置。这里所说的目录都是/home/usr下。
步骤:
编译你的硬件加速模块,会生成相应的库文件。把生成的所有库放到/home/usr/lib下。
在/home/usr/lib/directfb-1.5-0目录下,创建目录gfxdrivers,并把编译硬件模块的有关DirectFB的库放到此目录下,我这里的库文件是libdirectfb_gal.so.
在/home/usr目录下,创建目录etc
进入到/home/usr目录下,在终端输入:no-software>>directfbrc
完成以上步骤后DirectFB就可以支持相应的硬件加速了。
1. 概述
================
本文主要研究DirectFB及其向上向下的接口,顺带讲一下QT搭配DirectFB使用的一些笔记。
其他,如DirectFB的内部结构、Qt的内部结构、及其他GUI系统如android不在本文讨论范围内。
本文会设计一些DirectFB的2D加速函数介绍,3D加速不再本文讨论范围内。
================
桌面GUI系统涉及很多图像运算,比如画点、画线、填充、透明度处理、平滑度处理、层的叠加、字体处理、贴图等等。如果这些运算都由CPU来处理,那这将是对CPU的一个很大的负载。在QT的文档中曾说到,假如一个图形运算让加速设备来做需要1到2个CLK,同样的图形运算让CPU来算则至少需要20个CLK,而且,对于嵌入式SoC来说,CPU的频率和SDRAM/DRAM的带宽始终是图形运算的瓶颈。所以这些芯片的图形加速能力有无、高低,最终决定其目标GUI的质量。
近两年嵌入式设备主芯片越来越多的嵌入了2D/3D加速功能,由此软件可以搭建越来越复杂、炫酷、先进的桌面系统,如Qt/Android等。这些加速硬件,通常也因其是否拥有私有内存、是否支持3D、加速接口是否可编程等特性而分为三六九等。硬件的加速功能如果要在目标GUI系统中跑起来,还得需要一些软件中间层为不同的硬件加速提供同一的接口,并且为上层GUI提供服务。DirectFB就是这样一个软件中间层,它主要为上层提供2D加速服务。OpenGL/ES 主要为上层提供3D加速服务。
DirectFB是一个专门针对Linux图形库设计的图形加速中间层。它的上层直接面向图形库比如QT,提供如显示、画图、输入设备控制等服务,他的下层直接面向GFX加速硬件,要求硬件驱动实现全部或部分预定的画图函数。
DirectFB移植的过程中,因尽量保证idirectb(各种接口结构、函数)不能变,可适当扩展其宏定义。
在上一篇文章中启动好了framebuffer,现在可以用这样一个简单的例子来检验下效果。
来自DirectFB官方网站的简单程序,在屏幕上画一条线。
编译后,执行 成功了。
Simple fullscreen application that draws a horizontal line.
代码如下:
#include <stdio.h>
#include <unistd.h>
#include <directfb.h>
static IDirectFB *dfb = NULL;
static IDirectFBSurface *primary = NULL;
static int screen_width = 0;
static int screen_height = 0;
#define DFBCHECK(x...) /
{ /
DFBResult err = x; /
/
if (err != DFB_OK) /
{ /
fprintf( stderr, "%s <%d>:/n/t", __FILE__, __LINE__ ); /
DirectFBErrorFatal( #x, err ); /
} /
}
int main(int argc, char **argv)
{
DFBSurfaceDescription dsc;
DFBCHECK (DirectFBInit (&argc, &argv));
DFBCHECK (DirectFBCreate (&dfb));
DFBCHECK (dfb->SetCooperativeLevel (dfb, DFSCL_FULLSCREEN));
dsc.flags = DSDESC_CAPS;
dsc.caps = DSCAPS_PRIMARY | DSCAPS_FLIPPING;
DFBCHECK (dfb->CreateSurface( dfb, &dsc, &primary ));
DFBCHECK (primary->GetSize (primary, &screen_width, &screen_height));
DFBCHECK (primary->FillRectangle (primary, 0, 0, screen_width, screen_height));
DFBCHECK (primary->SetColor (primary, 0x80, 0x80, 0xff, 0xff));
DFBCHECK (primary->DrawLine (primary,
0, screen_height / 2,
screen_width - 1, screen_height / 2));
DFBCHECK (primary->Flip (primary, NULL, 0));
sleep(5);
primary->Release(primary);
dfb->Release(dfb);
return 23;
}
下面我们来看这个程序,前三行:
#include <stdio.h>
#include <unistd.h>
#include <directfb.h>
为头文件包含。第5到第8行:
static IDirectFB *dfb = NULL;
static IDirectFBSurface *primary = NULL;
static int screen_width = 0;
static int screen_height = 0;
为全局变量定义。第10到第19行为出错处理宏:
#define DFBCHECK(x...) /
{ /
DFBResult err = x; /
/
if (err != DFB_OK) /
{ /
fprintf( stderr, "%s <%d>:/n/t", __FILE__, __LINE__ ); /
DirectFBErrorFatal( #x, err ); /
} /
}
此宏定义在官方给的程序中很常见,确实也挺好用。第21到46行为主程序代码段。
其中,第23行:
DFBSurfaceDescription dsc;
为局部变量定义,dsc为平面属性描述变量,用以创建与其相匹配的平面。
第25到26行:
DFBCHECK (DirectFBInit (&argc, &argv));
DFBCHECK (DirectFBCreate (&dfb));
为DirectFB初始化函数,第25行用以初始化命令行参数,而第26行用以创建DirectFB的主接口。
第28到30行对平面属性进行了初始化,其中第28行:
DFBCHECK (dfb->SetCooperativeLevel (dfb, DFSCL_FULLSCREEN));
设置了DirectFB的主接口的同步等级,DFSCL_FULLSCREEN与DFSCL_EXCLUSIVE相同,均为非共享的同步等级,在总接口使用CreateSurface方法创建平面时,将创建全屏平面。
第29到30行:
dsc.flags = DSDESC_CAPS;
dsc.caps = DSCAPS_PRIMARY | DSCAPS_FLIPPING;
说明了即将创建的平面的属性,在本例中,我们要创建一个可flip的主平面。
第32到34行:
DFBCHECK (dfb->CreateSurface( dfb, &dsc, &primary ));
DFBCHECK (primary->GetSize (primary, &screen_width, &screen_height));
DFBCHECK (primary->FillRectangle (primary, 0, 0, screen_width, screen_height));
创建了一个平面,并对此平面作了相应的初始化操作。第33行获取了此平面(全屏主平面)的宽高值,第34行在平面上画了一个黑色(DirectFB系统默认颜色)的屏幕大小矩形,此函数是受stb225平台硬件加速支持的。
第36到41行:
DFBCHECK (primary->SetColor (primary, 0x80, 0x80, 0xff, 0xff));
DFBCHECK (primary->DrawLine (primary,
0, screen_height / 2,
screen_width - 1, screen_height / 2));
DFBCHECK (primary->Flip (primary, NULL, 0));
sleep(5);
的功能为在屏幕正中心画一条横线,并显示5秒钟。第36行设置了线的颜色,第37到39行进行画线操作,将36行所设置颜色的线画到primary平面上,第40行将画有横线的平面显示出来,第41行,程序休眼5秒,即此线在屏幕上显示5秒。
第43到45行:
primary->Release(primary);
dfb->Release(dfb);
return 23;
程序作了相应的清理操作,而后退出。
DirectFB程序中,如果定义了接口,则一定需要使用相应的Release方法将此接口进行释放,否则可能引起内存泄漏问题,甚至可能破坏程序的稳定性。
from:http://blog.csdn.net/wangjijian/article/details/6161889
由于第一次搞嵌入式,交叉编译DirectFB费了一些周折。
首先记录下编译的过程
1 准备源文件包,下载freetype2.4.4和DirectFB-1.4.11.tar.gz,解压。
2 交叉编译安装freetype
export CC=arm-none-linux-gnueabi-gcc
指定交叉编译器。(我用的交叉编译器来自source G++)
./configure --host=arm-linux --prefix=/opt/freetype/
make
make install
freetype安装完毕
3 交叉编译directfb
export LDFLAGS=-L/opt/freetype/lib
export CFLAGS="-g -I/opt/freetype/include"
./configure --host=arm-linux --prefix=$PREFIX --with-gfxdrivers=none --with-inputdrivers=all --disable-png --disable-jpeg --disable-zlib --enable-sdl=no --enable-gif=no --disable-x11
make
make install
交叉编译directfb完毕。
4 修改/etc/bash.bashrc 把新安装的库的路径,LD_LIBRARY_PATH ,PKG_CONFIG_PATH , PATH 设置完毕。
source /etc/bash.bashrc 使路径生效。
5 交叉编译自己的程序。
arm-none-linux-gnueabi-gcc `pkg-config --cflags --libs directfb`fb.c -o fb
交叉编译成功 。
总结:期间遇到的一些问题
1 要交叉编译自己的程序,需要先交叉编译所依赖的库
2 如何交叉编译库
在网上查找学习后,通过如下命令并不成功
./configure --host=arm-linux --prefix=$PREFIX --with-gfxdrivers=none --with-inputdrivers=all --disable-png --disable-jpeg --disable-zlib --enable-sdl=no --enable-gif=no --disable-x11
原因:在执行configure时 指定了 --host=arm-linux 但是没有指定交叉编译器,系统没有找到交叉编译器,貌似就用了gcc编译,最后并未生成arm-linux的库,在编译后续的库时链接会找不到合适的库。需要先
export CC=arm-none-linux-gnueabi-gcc
指定交叉编译器。
3 交叉编译好库之后 设置好路径后就可以交叉编译程序了。
下面引用一篇关于交叉编译链接库配置的文章
交叉编译的时候不能使用本地(i686机器,即PC机器,研发机器)机器上的库,但是在做编译链接的时候默认的是使用本地库,即/usr/lib,/lib两个目录。因此,在交叉编译的时候,要采取一些方法使得在编译链接的时候找到需要的库。
首先,要知道:编译的时候只需要头文档,真正实际的库文档在链接的时候用到。 (这是我的理解,假如有不对的地方,敬请网上各位大侠指教) 然后,讲讲如何在交叉编译链接的时候找到需要的库。
(1)、交叉编译时候直接使用-L和-I参数指定搜索非标准的库文档和头文档的路径。例如:
arm-linux-gcc test.c -L/usr/local/arm/2.95.3/arm-linux/lib -I/usr/local/arm/2.95.3/arm-linux/include
(2)、使用ld.so.conf文档,将用到的库所在文档目录添加到此文档中,然后使用ldconfig命令刷新缓存。
(3)、使用如下命令:
$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/arm/2.95.3/arm-linux-lib
参见《ld.so.conf 文档和PKG_CONFIG_PATH变量》这篇文章。
通过环境变量LD_LIBRARY_PATH指定动态库搜索路径(!)。
通过设定环境变量LD_LIBRARY_PATH也可以指定动态库搜索路径。当通过该环境变量指定多个动态库搜索路径时,路径之间用冒号":"分隔。
不过LD_LIBRARY_PATH的设定作用是全局的,过多的使用可能会影响到其他应用程序的运行,所以多用在调试。(LD_LIBRARY_PATH 的缺陷和使用准则,可以参考《Why LD_LIBRARY_PATH is bad》 )。通常情况下推荐还是使用gcc的-R或-rpath选项来在编译时就指定库的查找路径,并且该库的路径信息保存在可执行文件中,运行时它会直接到该路 径查找库,避免了使用LD_LIBRARY_PATH环境变量查找。
(4)、交叉编译时使用软件的configure参数。例如我编译minigui-1.3.3,使用如下配置:
#!/bin/bash
rm -f config.cache config.status
./configure --build=i686-linux --host=arm-linux --target=arm-linux /
CFLAGS=-I/usr/local/arm/2.95.3/arm-linux/include /
LDFLAGS=-L/usr/local/arm/2.95.3/arm-linux/lib /
--prefix=/usr/local/arm/2.95.3/arm-linux /
--enable-lite /
--disable-galqvfb /
--disable-qvfbial /
--disable-vbfsupport /
--disable-ttfsupport /
--disable-type1support /
--disable-imegb2312py /
--enable-extfullgif /
--enable-extskin /
--disable-videoqvfb /
--disable-videoecoslcd
这里我配置了CFLAGS和LDFLAGS参数,这样一来,我就不用去修改每个Makefile里-L和-I参数了,也不用再去配置LD_LIBRARY_PATH或改写ld.so.conf文档了。
Linux下动态库使用小结
1. 静态库和动态库的基本概念
静态库,是在可执行程序连接时就已经加入到执行码中,在物理上成为执行程序的一部分;使用静态库编译的程序运行时无需该库文件支持,哪里都可以用,但是生成的可执行文件较大。动态库,是在可执行程序启动时加载到执行程序中,可以被多个可执行程序共享使用。使用动态库编译生成的程序相对较小,但运行时需要库文件支持,如果机器里没有这些库文件就不能运行。
2. 如何使用动态库
如何程序在连接时使用了共享库,就必须在运行的时候能够找到共享库的位置。linux的可执行程序在执行的时候默认是先搜索/lib和/usr/lib这两个目录
Makefile预定义变量
含义
$*
不包含扩展名的目标文件名称。
$+
所有的依赖文件,以空格分开,并以出现的先后为序,可能包含重复的依赖文件。
$<
第一个依赖文件的名称。
$?
所有的依赖文件,以空格分开,这些依赖文件的修改日期比目标的创建日期晚。
$@
目标的完整名称。
$^
所有的依赖文件,以空格分开,不包含重复的依赖文件。
$%
如果目标是归档成员,则该变量表示目标的归档成员名称。例如,如果目标名称为
mytarget.so(image.o),则 $@ 为 mytarget.so,而 $% 为 image.o。
AR
归档维护程序的名称,默认值为 ar。
ARFLAGS
归档维护程序的选项。
AS
汇编程序的名称,默认值为 as。
ASFLAGS
汇编程序的选项。
CC
C 编译器的名称,默认值为 cc。
CFLAGS
C 编译器的选项。
CPP
C 预编译器的名称,默认值为 $(CC) -E。
CPPFLAGS
C 预编译的选项。
CXX
C++ 编译器的名称,默认值为 g++。
CXXFLAGS
C++ 编译器的选项。
FC
FORTRAN 编译器的名称,默认值为 f77。
FFLAGS
FORTRAN 编译器的选项。