本文首先概述了 Linux 圖形領域的基本設施,然後描述了一些可供嵌入式 Linux 系統使用的高級圖形庫以及圖形用戶界面支持系統。希望對嵌入式 Linux 系統的開發有所幫助。
1 Linux 圖形領域的基礎設施
本小節首先向讀者描述 Linux 圖形領域中常見的基礎設施。之所以稱為基礎 設施,是因為這些系統(或者函數庫),一般作為其他高級圖形或者圖形應用程 序的基本函數庫。這些系統(或者函數庫)包括:X Window、SVGALib、 FrameBuffer 等等。
1.1 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(直接圖形訪問)擴展,通過該擴展,應用程序可以在全屏模式下直接訪問 顯示卡的幀緩沖區,並能夠提供對某些加速功能的支持。
1.2 SVGALib
SVGALib 是 Linux 系統中最早出現的非 X 圖形支持庫。這個庫從最初對標 准 VGA 兼容芯片的支持開始,一直發展到對老式 SVGA 芯片的支持以及對現今 流行的高級視頻芯片的支持。它為用戶提供了在控制台上進行圖形編程的接口, 使用戶可以在 PC 兼容系統上方便地獲得圖形支持。但該系統有如下不足:
1)接口雜亂。SVGALib 從最初的 vgalib 發展而來,保留了老系統的許多接 口,而這些接口卻不能良好地迎合新顯示芯片的圖形能力。
2)未能較好地隱藏硬件細節。許多操作,不能自動使用顯示芯片的加速能力 支持。
3)可移植性差。SVGALib 目前只能運行在 x86 平台上,對其他平台的支持 能力較差(Alpha 平台除外)。
4)發展緩慢,有被其他圖形庫取代的可能。SVGALib 作為一個老的圖形支持 庫,目前的應用范圍越來越小,尤其在 Linux 內核增加了 FrameBuffer 驅動支 持之後,有逐漸被其他圖形庫替代的跡象。
5)對應用的支持能力較差。SVAGLib 作為一個圖形庫,對高級圖形功能的支 持,比如直線和曲線等等,卻不能令人滿意。盡管 SVGALib 有許多缺點,但 SVGALib 經常被其他圖形庫用來初始化特定芯片的顯示模式,並獲得映射到進程 地址空間的線性顯示內存首地址(即幀緩沖區),而其他的接口卻很少用到。另 外,SVGALib 中所包含的諸如鍵盤、鼠標和游戲桿的接口,也很少被其他應用程 序所使用。
因此,SVGALib 的使用越來越少,筆者也不建議用戶使用這個圖形庫。當然 ,如果用戶的顯示卡只支持標准 VGA 模式,則 SVGALib 還是比較好的選擇。
1.3 FrameBuffer
FrameBuffer 是出現在 2.2.xx 內核當中的一種驅動程序接口。這種接口將 顯示設備抽象為幀緩沖區。用戶可以將它看成是顯示內存的一個映像,將其映射 到進程地址空間之後,就可以直接進行讀寫操作,而寫操作可以立即反應在屏幕 上。該驅動程序的設備文件一般是 /dev/fb0、/dev/fb1 等等。比如,假設現在 的顯示模式是 1024x768-8 位色,則可以通過如下的命令清空屏幕:
$ dd if=/dev/zero of=/dev/fb0 bs=1024 count=768
在應用程序中,一般通過將 FrameBuffer 設備映射到進程地址空間的方式使 用,比如下面的程序就打開 /dev/fb0 設備,並通過 mmap 系統調用進行地址映 射,隨後用 memset 將屏幕清空(這裡假設顯示模式是 1024x768-8 位色模式, 線性內存模式):
int fb;
unsigned char* fb_mem;
fb = open (“/dev/fb0”, O_RDWR);
fb_mem = mmap (NULL, 1024*768, PROT_READ|PROT_WRITE,MAP_SHARED,fb,0);
memset (fb_mem, 0, 1024*768);
FrameBuffer 設備還提供了若干 ioctl 命令,通過這些命令,可以獲得顯示 設備的一些固定信息(比如顯示內存大小)、與顯示模式相關的可變信息(比如 分辨率、象素結構、每掃描線的字節寬度),以及偽彩色模式下的調色板信息等 等。
通過 FrameBuffer 設備,還可以獲得當前內核所支持的加速顯示卡的類型( 通過固定信息得到),這種類型通常是和特定顯示芯片相關的。比如目前最新的 內核(2.4.9)中,就包含有對 S3、Matrox、nVidia、3Dfx 等等流行顯示芯片 的加速支持。在獲得了加速芯片類型之後,應用程序就可以將 PCI 設備的內存 I/O(memio)映射到進程的地址空間。這些 memio 一般是用來控制顯示卡的寄 存器,通過對這些寄存器的操作,應用程序就可以控制特定顯卡的加速功能。
PCI 設備可以將自己的控制寄存器映射到物理內存空間,而後,對這些控制 寄存器的訪問,給變成了對物理內存的訪問。因此,這些寄存器又被稱為 “memio”。一旦被映射到物理內存,Linux 的普通進程就可以通過 mmap 將這些內存 I/O 映射到進程地址空間,這樣就可以直接訪問這些寄存器了 。
當然,因為不同的顯示芯片具有不同的加速能力,對memio 的使用和定義也 各自不同,這時,就需要針對加速芯片的不同類型來編寫實現不同的加速功能。 比如大多數芯片都提供了對矩形填充的硬件加速支持,但不同的芯片實現方式不 同,這時,就需要針對不同的芯片類型編寫不同的用來完成填充矩形的函數。
說到這裡,讀者可能已經意識到 FrameBuffer 只是一個提供顯示內存和顯示 芯片寄存器從物理內存映射到進程地址空間中的設備。所以,對於應用程序而言 ,如果希望在 FrameBuffer 之上進行圖形編程,還需要完成其他許多工作。舉 個例子來講,FrameBuffer 就像一張畫布,使用什麼樣子的畫筆,如何畫畫,還 需要你自己動手完成。
1.4 LibGGI
LibGGI 試圖建立一個一般性的圖形接口,而這個抽象接口連同相關的輸入( 鼠標、鍵盤、游戲桿等)抽象接口一起,可以方便地運行在 X Window、SVGALib 、FrameBuffer 等等之上。建立在 LibGGI 之上的應用程序,不經重新編譯,就 可以在上述這些底層圖形接口上運行。但不知何故,LibGGI 的發展幾乎停滯。
2 Linux 圖形領域的高級函數庫
2.1 Xlib 及其他相關函數庫
在 X Window 系統中進行圖形編程時,可以選擇直接使用 Xlib。Xlib 實際 是對底層 X 協議的封裝,可通過該函數庫進行一般的圖形輸出。如果你的 X Server 支持 DGA,則可以通過 DGA 擴展直接訪問顯示設備,從而獲得加速支持 。對一般用戶而言,由於 Xlib 的接口太原始而且復雜,因此一般的圖形程序選 擇其他高級一些的圖形庫作為基礎。比如,GTK、QT 等等。這兩個函數同時還是 一些高級的圖形用戶界面支持函數庫。由於種種原因,GTK、QT 等函數庫存在有 龐大、占用系統資源多的問題,不太適合在嵌入式系統中使用。這時,你可以選 擇使用 FLTK,這是一個輕量級的圖形函數庫,但它的主要功能集中在用戶界面 上,提供了較為豐富的控件集。
2.2 SDL
SDL(Simple DirectMedia Layer)是一個跨平台的多媒體游戲支持庫。其中 包含了對圖形、聲音、游戲桿、線程等等的支持,目前可以運行在許多平台上, 其中包括 X Window、X Window with DGA、Linux FrameBuffer 控制台、Linux SVGALib,以及Windows DirectX、BeOS 等等。
因為 SDL 專門為游戲和多媒體應用而設計開發,所以它對圖形的支持非常優 秀,尤其是高級圖形能力,比如 Alpha 混和、透明處理、YUV 覆蓋、Gamma 校 正等等。而且在 SDL 環境中能夠非常方便地加載支持 OpenGL 的 Mesa 庫,從 而提供對二維和三維圖形的支持。
可以說,SDL 是編寫跨平台游戲和多媒體應用的最佳平台,也的確得到了廣 泛應用。
2.3 Allegro
Allegro 是一個專門為 x86 平台設計的游戲圖形庫。最初的 Allegro 運行 在 DOS 環境下,而目前可運行在 Linux FrameBuffe 控制台、Linux SVGALib、 X Window 等系統上。Allegro 提供了一些豐富的圖形功能,包括矩形填充和樣 條曲線生成等等,而且具有較好的三維圖形顯示能力。由於 Allegro 的許多關 鍵代碼是采用匯編編寫的,所以該函數庫具有運行速度快、資源占用少的特點。 然而,Allegro 也存在如下缺點:
1)對線程的支持較差。Allegro 的許多函數是非線程安全的,不能同時在兩 個以上的線程中使用。
2)對硬件加速能力的支持不足,在設計上沒有為硬件加速提供接口。
2.4 Mesa3D
Mesa3D 是一個兼容 OpenGL 規范的開放源碼函數庫,是目前 Linux 上提供 專業三維圖形支持的惟一選擇。Mesa3D 同時也是一個跨平台的函數庫,能夠運 行在 X Window、X Window with DGA、BeOS、Linux SVGALib 等平台上。
2.5 DirectFB
DirectFB 是專注於 Linux FrameBuffer 加速的一個圖形庫,並試圖建立一 個兼容 GTK 的嵌入式 GUI 系統。它以可裝載函數庫的形勢提供對加速 FrameBuffer 驅動程序的支持。目前,該函數庫正在開發之中(最新版本 0.9.97),詳情可見 。
3 面向嵌入式Linux 系統的圖形用戶界面
3.1 MicoroWindows/NanoX
MicroWindows(http://microwindows.censoft.com)是一個開放源碼的項目 ,目前由美國 Century Software 公司主持開發。該項目的開發一度非常活躍, 國內也有人參與了其中的開發,並編寫了 GB2312 等字符集的支持。但在 Qt/Embedded 發布以來,該項目變得不太活躍,並長時間停留在 0.89Pre7 版本 。可以說,以開放源碼形勢發展的 MicroWindows 項目,基本停滯。
MicroWindows 是一個基於典型客戶/服務器體系結構的 GUI 系統,基本分為 三層。最底層是面向圖形輸出和鍵盤、鼠標或觸摸屏的驅動程序;中間層提供底 層硬件的抽象接口,並進行窗口管理;最高層分別提供兼容於 X Window 和 Windows CE(Win32 子集)的 API。
該項目的主要特色在於提供了類似 X 的客戶/服務器體系結構,並提供了相 對完善的圖形功能,包括一些高級的功能,比如 Alpha 混合,三維支持, TrueType 字體支持等。但需要注意的是,MicroWindows 的圖形引擎存在許多問 題,可以歸納如下:
1)無任何硬件加速能力。
2)圖形引擎中存在許多低效算法,同時未經任何優化。比如在直線或者圓弧 繪圖函數中,存在低效的逐點判斷剪切的問題。
3)代碼質量較差。由於該項目缺少一個強有力的核心代碼維護人員,因此代 碼質量參差不齊,影響整體系統穩定性。這也是 MicroWindows 長時間停留在 0.89Pre7 版本上的原因。
MicroWindows 采用 MPL 條款發布(該條款基本類似 LGPL 條款)。
3.2 OpenGUI
OpenGUI(http://www.tutok.sk/fastgl/)在 Linux 系統上存在已經很長時 間了。最初的名字叫 FastGL,只支持 256 色的線性顯存模式,但目前也支持其 他顯示模式,並且支持多種操作系統平台,比如 MS-DOS、QNX 和 Linux 等等, 不過目前只支持 x86 硬件平台。OpenGUI 也分為三層。最低層是由匯編編寫的 快速圖形引擎;中間層提供了圖形繪制 API,包括線條、矩形、圓弧等,並且兼 容於 Borland 的 BGI API。第三層用 C++ 編寫,提供了完整的 GUI 對象集。
OpenGUI 采用 LGPL 條款發布。OpenGUI 比較適合於基於 x86 平台的實時系 統,可移植性稍差,目前的發展也基本停滯。
3.3 Qt/Embedded
Qt/Embedded是著名的 Qt 庫開發商 TrollTech (http://www.trolltech.com/)發布的面向嵌入式系統的 Qt 版本。因為 Qt 是 KDE 等項目使用的 GUI 支持庫,所以有許多基於 Qt 的 X Window 程序可以 非常方便地移植到 Qt/Embedded 版本上。因此,自從 Qt/Embedded 以 GPL 條 款形勢發布以來,就有大量的嵌入式 Linux 開發商轉到了 Qt/Embedded 系統上 。比如韓國的 Mizi 公司,台灣省的某些嵌入式 Linux 應用開發商等等。
不過,在筆者看來,Qt/Embedded 還有一些問題值得開發者注意:
1)目前,該系統采用兩種條款發布,其中包括 GPL 條款。對函數庫使用 GPL 條款,意味著其上的應用需要遵循 GPL 條款。當然了,如果要開發商業程 序,TrollTech 也允許你采用另外一個授權條款,這時,就必須向 TrollTech 交納授權費用了。
2)Qt/Embedded 是一個 C++ 函數庫,盡管 Qt/Embedded 聲稱可以裁剪到最 少 630K,但這時的 Qt/Embedded 庫已經基本上失去了使用價值。低的程序效率 、大的資源消耗也對運行 Qt/Embedded 的硬件提出了更高的要求。
3)Qt/Embedded 庫目前主要針對手持式信息終端,因為對硬件加速支持的匮 乏,很難應用到對圖形速度、功能和效率要求較高的嵌入式系統當中,比如機頂 盒、游戲終端等等。
4)Qt/Embedded 提供的控件集風格沿用了 PC 風格,並不太適合許多手持設 備的操作要求。
5)Qt/Embedded 的結構過於復雜,很難進行底層的擴充、定制和移植,尤其 是那個用來實現 signal/slot 機制的著名的 moc 文件。
因為上述這些原因,目前所見到的 Qt/Embedded 的運行環境,幾乎是清一色 基於 StrongARM 的 iPAQ。
3.4 MiniGUI
MiniGUI是由筆者主持,並由許多自由軟件開發人員支持的一個自由軟件項目 (遵循 LGPL 條款發布),其目標是為基於 Linux 的實時嵌入式系統提供一個 輕量級的圖形用戶界面支持系統。該項目自 1998 年底開始到現在,已歷經 3 年多的開發過程。到目前為止,已經非常成熟和穩定。目前,我們已經正式發布 了穩定版本 1.0.9,並且開始了新版本系列的開發,即 MiniGUI Version 1.1.x ,該系列的正式版也即將發布。
在 MiniGUI 幾年的發展過程中,有許多值得一提的技術創新點,正是由於這 些技術上的創新,才使得 MiniGUI 更加適合實時嵌入式系統;而且 MiniGUI 的 靈活性非常好,可以應用在包括手持設備、機頂盒、游戲終端等等在內的各種高 端或者低端的嵌入式系統當中。這些技術創新包括:
1)圖形抽象層。圖形抽象層對頂層 API 基本沒有影響,但大大方便了 MiniGUI 應用程序的移植、調試等工作。目前包含三個圖形引擎,SVGALib、 LibGGI 以及直接基於 Linux FrameBuffer 的 Native Engine,利用 LibGGI 時 ,可在 X Window 上運行 MiniGUI 應用程序,並可非常方便地進行調試。與圖 形抽象層相關的還有輸入事件的抽象層。MiniGUI 現在已經被證明能夠在基於 ARM、MIPS、StrongARM 以及 PowerPC 等的嵌入式系統上流暢運行。
2)多字體和多字符集支持。這部分通過設備上下文(DC)的邏輯字體 (LOGFONT)實現,不管是字體類型還是字符集,都可以非常方便地進行擴充。 應用程序在啟動時,可切換系統字符集,比如 GB、BIG5、EUCKR、UJIS。利用 DrawText 等函數時,可通過指定字體而獲得其他字符集支持。對於一個窗口來 說,同時顯示不同語種的文字是可能的。MiniGUI 的這種字符集支持不同於傳統 通過 UNICODE 實現的多字符集支持,這種實現更加適合於嵌入式系統。
3)兩個不同架構的版本。最初的 MiniGUI 運行在 PThread 庫之上,這個版 本適合於功能單一的嵌入式系統,但存在系統健壯性不夠的缺點。在 0.9.98 版 本中,我們引入了 MiniGUI-Lite 版本,這個版本在提高系統健壯性的同時,通 過一系列創新途徑,避免了傳統 C/S 結構的弱點,為功能復雜的嵌入式系統提 供了一個高效、穩定的 GUI 系統。
在 MiniGUI 1.1.0 版本的開發中,我們參照 SDL 和 Allegro 的圖形部分, 重新設計了圖形抽象層,並增強了圖形功能,同時增強了 MiniGUI-Lite 版本的 某些特性。這些特性包括:
1)MiniGUI-Lite 支持層的概念。同一層可容納多個能夠同時顯示的客戶程 序,並平鋪在屏幕上顯示。
2)新的 GAL 能夠支持硬件加速能力,並能夠充分使用顯示內存;新 GAL 之 上的新 GDI 接口得到進一步增強。新的 GDI 接口可以支持 Alpha 混和、透明 位塊傳輸、光柵操作、YUV覆蓋、Gamma 校正,以及高級圖形功能(橢圓、多邊 形、樣條曲線)等等。
MiniGUI 新版本在圖形方面的增強和提高,將大大擴展它的應用領域,希望 能夠對嵌入式 Linux 上的多媒體應用、游戲開發提供支持。
縱觀嵌入式 Linux 系統上的各種圖形系統方案,我們發現,許多圖形系統( 如 Qt/Embedded 和 MicoroWindows),只注重手持設備上的需求,卻不太注重 其他應用領域的需求,而其他許多需要圖形支持的嵌入式 Linux 系統卻需要許 多獨特的、高級的圖形功能,而不僅僅是圖形用戶界面。為此,在接下來的開發 中,我們還將在如下領域繼續開發 MiniGUI:
1)提供運行在 MiniGUI 上的 JAVA 虛擬機 AWT 組件的實現。
2)提供 MiniGUI 上的 OpenGL 實現。
3)提供類 QT 控件集的 C++ 封裝。
3)提供窗口/控件風格主題支持。
4)在 MiniGUI-Lite 當中增加對矢量字體的支持。
4 小結
綜上所述,筆者認為在嵌入式 Linux 圖形領域,還有許多有待開發人員仔細 研究和解決的問題。MiniGUI 的新的發展,也正源於對這些需求的認識之上。我 們也衷心希望能夠有更多的自由軟件開發人員加盟 MiniGUI 的開發,一同開發 新的嵌入式 Linux 的圖形系統。