歡迎您光臨本站 註冊首頁

Linux 圖形領域 Framebuffer

←手機掃碼閱讀     火星人 @ 2014-03-23 , reply:0

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 是編寫跨平台遊戲和多媒體應用的最佳平台,也的確得到了廣泛應用。相關信息,可參閱 http://www.libsdl.org。

2.3 Allegro

Allegro 是一個專門為 x86 平台設計的遊戲圖形庫。最初的 Allegro 運行在 DOS 環境下,而目前可運行在 Linux FrameBuffe 控制台、Linux SVGALib、X Window 等系統上。Allegro 提供了一些豐富的圖形功能,包括矩形填充和樣條曲線生成等等,而且具有較好的三維圖形顯示能力。由於 Allegro 的許多關鍵代碼是採用彙編編寫的,所以該函數庫具有運行速度快、資源佔用少的特點。然而,Allegro 也存在如下缺點:

1)對線程的支持較差。Allegro 的許多函數是非線程安全的,不能同時在兩個以上的線程中使用。
2)對硬體加速能力的支持不足,在設計上沒有為硬體加速提供介面。

有關 Allegro 的進一步信息,可參閱http://www.allegro.cc/。

2.4 Mesa3D

Mesa3D 是一個兼容 OpenGL 規範的開放源碼函數庫,是目前 Linux 上提供專業三維圖形支持的惟一選擇。Mesa3D 同時也是一個跨平台的函數庫,能夠運行在 X Window、X Window with DGA、BeOS、Linux SVGALib 等平台上。

有關 Mesa3D 的進一步信息,可參閱 http://www.mesa3d.org/。

2.5 DirectFB

DirectFB 是專註於 Linux FrameBuffer 加速的一個圖形庫,並試圖建立一個兼容 GTK 的嵌入式 GUI 系統。它以可裝載函數庫的形勢提供對加速 FrameBuffer 驅動程序的支持。目前,該函數庫正在開發之中(最新版本 0.9.97),詳情可見 http://www.directfb.org/。


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(http://www.minigui.org)是由筆者主持,並由許多自由軟體開發人員支持的一個自由軟體項目(遵循 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 當中增加對矢量字體的支持。

[火星人 ] Linux 圖形領域 Framebuffer已經有674次圍觀

http://coctec.com/docs/linux/show-post-116850.html