作者 魏永明
主题八MiniGUI 和其他嵌入式 Linux 上的图形及图形用户界面系统
为了让读者对嵌入式 Linux 当中能够使用的图形及图形用户界面有个较为全面的认识本文将为读者介绍一些嵌入式 Linux 系统中常见的图形及图形用户界面系统并作为基于 Linux 和 MiniGUI 的嵌入式系统软件开发指南系列的最后一篇文章本文首先概述了 Linux 图形领域的基本设施然后描述了一些可供嵌入式 Linux 系统使用的高级图形库以及图形用户界面支持系统并大概比较了这些系统的优缺点希望能对嵌入式 Linux 系统的开发有所帮助
Linux 图形领域的基础设施
本小节首先向读者描述 Linux 图形领域中常见的基础设施之所以称为基础设施是因为这些系统(或者函数库)一般作为其他高级图形或者图形应用程序的基本函数库这些系统(或者函数库)包括X WindowSVGALibFrameBuffer 等等
X Window
提起 Linux 上的图形许多人首先想到的是 X Window这一系统是目前类 UNIX 系统中处于控制地位的桌面图形系统无疑X Window 作为一个图形环境是成功的它上面运行着包括 CAD建模工具和办公套件在内的大量应用程序但必须看到的是由于 X Window 在体系接口上的原因限制了其对游戏多媒体的支持能力用户在 X Window 上运行 VCD 播放器或者运行一些大型的三维游戏时经常会发现同样的硬件配置却不能获得和 Windows 操作系统一样的图形效果――即使使用了加速的 X Server其效果也不能令人满意另外大型的应用程序(比如 Mozilla 浏览器)在 X Window 上运行时的响应能力也相当不能令人满意当然这里有 Linux 内核在进程调度上的问题也有 X Window 的原因
X Window 为了满足对游戏多媒体等应用对图形加速能力的要求提供了 DGA(直接图形访问)扩展通过该扩展应用程序可以在全屏模式下直接访问显示卡的帧缓沖区并能够提供对某些加速功能的支持
TinyX是XServer在嵌入式系统的小巧实现它由Xfree Core Team 的Keith Packard开发它的目标是运行于小内存系统环境典型的运行于X CPU 上的TinyX Server 尺寸接近(小于)MB
SVGALib
SVGALib 是 Linux 系统中最早出现的非 X 图形支持库这个库从最初对标准 VGA 兼容芯片的支持开始一直发展到对老式 SVGA 芯片的支持以及对现今流行的高级视频芯片的支持它为用户提供了在控制台上进行图形编程的接口使用户可以在 PC 兼容系统上方便地获得图形支持但该系统有如下不足
接口杂乱SVGALib 从最初的 vgalib 发展而来保留了老系统的许多接口而这些接口却不能良好地迎合新显示芯片的图形能力
未能较好地隐藏硬件细节许多操作不能自动使用显示芯片的加速能力支持
可移植性差SVGALib 目前只能运行在 x 平台上对其他平台的支持能力较差(Alpha 平台除外)
发展缓慢有被其他图形库取代的可能SVGALib 作为一个老的图形支持库目前的应用范围越来越小尤其在 Linux 内核增加了 FrameBuffer 驱动支持之后有逐渐被其他图形库替代的迹象
对应用的支持能力较差SVAGLib 作为一个图形库对高级图形功能的支持比如直线和曲线等等却不能令人满意尽管 SVGALib 有许多缺点但 SVGALib 经常被其他图形库用来初始化特定芯片的显示模式并获得映射到进程地址空间的线性显示内存首地址(即帧缓沖区)而其他的接口却很少用到另外SVGALib 中所包含的诸如键盘鼠标和游戏桿的接口也很少被其他应用程序所使用
因此SVGALib 的使用越来越少笔者也不建议用户使用这个图形库当然如果用户的显示卡只支持标准 VGA 模式则 SVGALib 还是比较好的选择
FrameBuffer
FrameBuffer 是出现在 xx 内核当中的一种驱动程序接口这种接口将显示设备抽象为帧缓沖区用户可以将它看成是显示内存的一个映像将其映射到进程地址空间之后就可以直接进行读写操作而写操作可以立即反应在屏幕上该驱动程序的设备文件一般是 /dev/fb/dev/fb 等等比如假设现在的显示模式是 x 位色则可以通过如下的命令清空屏幕
$ dd if=/dev/zero of=/dev/fb bs= count=
在应用程序中一般通过将 FrameBuffer 设备映射到进程地址空间的方式使用比如下面的程序就打开 /dev/fb 设备并通过 mmap 系统调用进行地址映射随后用 memset 将屏幕清空(这里假设显示模式是 x 位色模式线性内存模式)
int fb;
unsigned char* fb_mem;
fb = open (/dev/fb O_RDWR);
fb_mem = mmap (NULL * PROT_READ|PROT_WRITEMAP_SHAREDfb);
memset (fb_mem *);
FrameBuffer 设备还提供了若干 ioctl 命令通过这些命令可以获得显示设备的一些固定信息(比如显示内存大小)与显示模式相关的可变信息(比如分辨率象素结构每扫描线的字节宽度)以及伪彩色模式下的调色板信息等等
通过 FrameBuffer 设备还可以获得当前内核所支持的加速显示卡的类型(通过固定信息得到)这种类型通常是和特定显示芯片相关的比如目前最新的内核()中就包含有对 SMatroxnVidiaDfx 等等流行显示芯片的加速支持在获得了加速芯片类型之后应用程序就可以将 PCI 设备的内存I/O(memio)映射到进程的地址空间这些 memio 一般是用来控制显示卡的寄存器通过对这些寄存器的操作应用程序就可以控制特定显卡的加速功能
PCI 设备可以将自己的控制寄存器映射到物理内存空间而后对这些控制寄存器的访问给变成了对物理内存的访问因此这些寄存器又被称为memio一旦被映射到物理内存Linux 的普通进程就可以通过 mmap 将这些内存 I/O 映射到进程地址空间这样就可以直接访问这些寄存器了
当然因为不同的显示芯片具有不同的加速能力对memio 的使用和定义也各自不同这时就需要针对加速芯片的不同类型来编写实现不同的加速功能比如大多数芯片都提供了对矩形填充的硬件加速支持但不同的芯片实现方式不同这时就需要针对不同的芯片类型编写不同的用来完成填充矩形的函数
说到这里读者可能已经意识到 FrameBuffer 只是一个提供显示内存和显示芯片寄存器从物理内存映射到进程地址空间中的设备所以对于应用程序而言如果希望在 FrameBuffer 之上进行图形编程还需要完成其他许多工作举个例子来讲FrameBuffer 就像一张画布使用什么样子的画笔如何画画还需要你自己动手完成
LibGGI
LibGGI 试图建立一个一般性的图形接口而这个抽象接口连同相关的输入(鼠标键盘游戏桿等)抽象接口一起可以方便地运行在 X WindowSVGALibFrameBuffer 等等之上建立在 LibGGI 之上的应用程序不经重新编译就可以在上述这些底层图形接口上运行但不知何故LibGGI 的发展几乎停滞
Linux 图形领域的高级函数库
Xlib 及其他相关函数库
在 X Window 系统中进行图形编程时可以选择直接使用 XlibXlib 实际是对底层 X 协议的封装可通过该函数库进行一般的图形输出如果你的 X Server 支持 DGA则可以通过 DGA 扩展直接访问显示设备从而获得加速支持对一般用户而言由于 Xlib 的接口太原始而且复杂因此一般的图形程序选择其他高级一些的图形库作为基础比如GTKQT 等等这两个函数同时还是一些高级的图形用户界面支持函数库由于种种原因GTKQT 等函数库存在有庞大占用系统资源多的问题不太适合在嵌入式系统中使用这时你可以选择使用 FLTK这是一个轻量级的图形函数库但它的主要功能集中在用户界面上提供了较为丰富的控件集
SDL
SDL(Simple DirectMedia Layer)是一个跨平台的多媒体游戏支持库其中包含了对图形声音游戏桿线程等等的支持目前可以运行在许多平台上其中包括 X WindowX Window with DGALinux FrameBuffer 控制台Linux SVGALib以及Windows DirectXBeOS 等等
因为 SDL 专门为游戏和多媒体应用而设计开发所以它对图形的支持非常优秀尤其是高级图形能力比如 Alpha 混和透明处理YUV 覆盖Gamma 校正等等而且在 SDL 环境中能够非常方便地加载支持 OpenGL 的 Mesa 库从而提供对二维和三维图形的支持
可以说SDL 是编写跨平台游戏和多媒体应用的最佳平台也的确得到了广泛应用相关信息可参阅
Allegro
Allegro 是一个专门为 x 平台设计的游戏图形库最初的 Allegro 运行在 DOS 环境下而目前可运行在 Linux FrameBuffe 控制台Linux SVGALibX Window 等系统上Allegro 提供了一些丰富的图形功能包括矩形填充和样条曲线生成等等而且具有较好的三维图形显示能力由于 Allegro 的许多关键代码是采用汇编编写的所以该函数库具有运行速度快资源占用少的特点然而Allegro 也存在如下缺点
对线程的支持较差Allegro 的许多函数是非线程安全的不能同时在两个以上的线程中使用
对硬件加速能力的支持不足在设计上没有为硬件加速提供接口
有关 Allegro 的进一步信息可参阅
MesaD
MesaD 是一个兼容 OpenGL 规范的开放源码函数库是目前 Linux 上提供专业三维图形支持的