基于 Linux 和 MiniGUI 的嵌入式系統軟件開發指南(五)
2024-07-21 02:38:19
供稿:網友
作者:魏永明
MiniGUI 1.1.0 版本引入的新 GDI 功能和函數
本文向讀者展現了 MiniGUI 的最新開發成果,即在 MiniGUI 1.1.0PRe4 版本中引入的新的 GAL 和新的 GDI 功能和接口。這些接口最終會出現在 MiniGUI 1.1.0 正式版本中。本文主要內容包括 GAL 和 GDI 的關系,新 GAL 引擎的接口特點,新 GDI 的功能增強以及接口應用范例等等。
1 引言
在本系列開發指南(四)中,我們具體講解了 MiniGUI 的 GDI 函數及其使用。我們也曾提到,MiniGUI 現有的 GDI 函數和功能,尚不能對機頂盒、瘦客戶機等高端嵌入式系統提供良好支持。因此,我們在 MiniGUI 1.1.0 版本的開發中,重點對 GAL 和 GDI 進行了大規模的改良,幾乎重新編寫了所有代碼。這些新的接口和功能,首先出現在最近發布的 MiniGUI 1.1.0Pre4 版本中,為了幫助開發人員正確理解和使用這些功能,特撰文說明新 GAL 和新 GDI 的接口和功能。
2 新 GAL 和新 GDI 接口的設計目標
首先,MiniGUI 舊的 GDI 接口非常簡單,其功能主要集中在位圖和塊操作上,例如 FillBox 函數、FillBoxWithBitmap 等等,而缺少對其他高級圖形操作的支持,比如橢圓、圓弧、樣條曲線等等。其次,舊的 GDI 接口還缺少基本的光柵操作功能。這里的光柵操作,指欲設定象素如何與屏幕上已有的象素進行運算。最基本的光柵操作功能是二進制的位操作,包括與、或、異或以及直接設置等等;高級的光柵操作包括透明處理和 Alpha 混和。這些 GDI 功能的缺乏,使得 MiniGUI 在機頂盒、瘦客戶等系統中應用時,顯得"力不從心"。再次,舊的 GDI 接口基本上沒有考慮到任何硬件加速功能。我們大家都知道,顯示卡自身提供的硬件加速功能,能夠大大提高圖形程序的運行速度,使得畫面流暢而自然,假如 GUI 系統不能充分利用這些硬件特性的話,則圖形處理能力將大打折扣。最后,舊的 GAL 設計存在抽象層次太高的問題,導致了 GAL 引擎臃腫,且重復代碼很多,也不便于進行代碼上的優化。
綜上所述,我們參照聞名的跨平臺游戲和多媒體函數庫 SDL(Simple DirectMedia Layer)對 GAL 引擎結構進行了重新設計,并且重新實現了所有的 GDI 函數,使得新的 GDI 接口具備如下特性:
能夠充分利用硬件特性,包括顯示內存和硬件加速能力。
支持高級圖形操作,包括基本光柵操作、透明處理和 Alpha 混和。
增強了剪切區域處理能力,有助于優化圖形輸出函數。
增強了原有的 BITMAP 接口,使之支持透明和 Alpha 通道。
充分利用嵌入式匯編代碼進行代碼優化。
下面將重點講述新的 GAL 功能和新的 GDI 接口。
3 新 GAL 功能特性
新的 GAL 結構來自聞名的跨平臺游戲和多媒體庫 SDL(Simple DirectMedia Layer)。目前提供了對 linux FrameBuffer 的支持,計劃在將來提供對 X、SVGALib 和 VGL(FreeBSD)等等圖形庫的支持。
3.1 GAL 和 GDI 的關系
大家都知道,MiniGUI 的 GAL 是一個圖形抽象層,提供給上層 GDI 函數一些基礎的功能和設施。在先前的設計中,GAL 可以看成是 GDI 圖形驅動程序,許多圖形操作函數,比如點、線、矩形填充、位圖操作等等,均通過 GAL 的相應函數完成。這種設計的最大問題是無法對 GDI 進行擴展。比如要增加橢圓繪制函數,就需要在每個引擎當中實現橢圓的繪制函數。并且 GDI 治理的是剪切域,而 GAL 引擎卻基于剪切矩形進行操作。這種方法也導致了 GDI 函數無法進行繪制優化。因此,在新的 GAL 和 GDI 接口設計中,我們將 GAL 的接口進行了限制,而將原有許多由 GAL 引擎完成的圖形輸出函數,提高到上層 GDI 函數中完成。GAL 和 GDI 的新的功能劃分如下:
GAL 負責對顯示設備進行初始化,并治理顯示內存的使用;
GAL 負責為上層 GDI 提供映射到進程地址空間的線性顯示內存,以及諸如調色板等其他相關信息;
GAL 負責實現快速的位塊操作,包括矩形填充和 Blitting 操作等,并且在可能的情況下,充分利用硬件加速功能;
GDI 函數實現高級圖形功能,包括點、線、圓、橢圓、圓弧、樣條曲線,以及更加高級的邏輯畫筆和邏輯畫刷,必要時調用 GAL 接口完成加速功能;
盡管某些顯示卡也提供有對上述高級繪圖功能的硬件支持,但考慮到其他因素,這些硬件加速功能不由 GAL 接口提供;而統統通過軟件實現。
這樣,GAL 主要實現的繪圖功能限制在位塊操作上,比如矩形填充和 Blitting 操作;而其他的高級圖形功能,則全部由 GDI 函數實現。
3.2 顯示內存的有效利用
新的 GAL 接口能夠有效利用顯示卡上的顯示內存,并充分利用硬件加速功能。我們知道,現在顯示卡一般具有 4M 以上的顯示內存,而一般的顯示模式下,不會占用所有的顯示內存。比如在顯示模式為 1204x768x32bpp 時,一屏象素所占用的內存為 3M,還有 1M 的內存可供給用程序使用。
因此,新的 GAL 引擎能夠治理這部分未被使用的顯示內存,并分配給應用程序使用。這樣,一方面可以節省系統內存的使用,另一方面,可以充分利用顯示卡提供的加速功能,在顯示內存的兩個不同內存區域之間進行快速的位塊操作,也就是常說的 Blitting。
3.3 Blitting 操作
在上層 GDI 接口在建立內存 DC 設備時,將首先在顯示內存上分配內存,假如失敗,才會考慮使用系統內存。這樣,假如 GAL 引擎提供了硬件加速功能,兩個不同 DC 設備之間的 Blitting 操作(即 GDI 函數 BitBlt),將以最快的速度運行。更進一步,假如硬件支持透明或 Alpha 混和功能,則透明的或者 Alpha 混和的 Blitting 操作也將以最快的速度運行。新的 GAL 接口能夠根據底層引擎的加速能力自動利用這些硬件加速功能。目前支持的硬件加速能力主要有:矩形填充,普通的 Blitting 操作,透明、Alpha 混和的 Blitting 操作等。當然,假如硬件不支持這些加速功能,新的 GAL 接口也能夠通過軟件實現這些功能。目前通過 GAL 的 FrameBuffer 引擎提供上述硬件加速功能的顯卡有:Matrox、3dfx 等。
在通過軟件實現透明或混和的 DC 間 Blitting 操作時,新的 GAL 接口利用了兩種有效的優化措施:
在 i386 平臺上,充分利用嵌入式匯編代碼進行優化處理;比如在處理 32 位色模式下的普通 Blitting 操作時,在利用普通的 C 庫函數,即 memcpy 進行位塊復制時,由于 memcpy 函數是以字節為單位進行復制的,從而無法利用 32 位 CPU 對 32 位字的處理能力,為此,可以使用嵌入式匯編,并以 32 位字為單位進行復制,這將大大提高 Bliting 操作的處理速度。
對源 DC 進行 RLE(Run Length Encoding)編碼,從而對象素的處理數量最小化。RLE 可以看成是一種圖象壓縮算法,Windows BMP 文件就利用了這種算法。RLE 是按水平掃描線進行壓縮編碼處理的。在一條掃描線上,假如有大量相同的象素,則不會保存這些象素點,而是首先保存具有相同象素點的數目,然后保存這些象素點的值。這樣,在進行透明或者混和的 Blitting 操作時,可以大大降低逐點運算帶來的速度損失。但是,假如在最壞的情況下,比如所有水平掃描線上的象素點都具有和相鄰點不同的象素值,則 RLE 編碼反而會增加象素的存儲空間(最壞的情況是原有空間的兩倍),同時也會降低 Blitting 操作的速度。因此是否使用 RLE 編碼,要根據情況而定。新的 GDI 接口在指定源 DC 的透明和 Alpha 通道值時,可以指定是否使用 RLE 編碼。
3.4 有效分辨率
新的 GAL 引擎可以設定一個不同于實際顯示分辨率的有效分辨率。比如實際的顯示分辨率是 1024x768,則可以在 /etc/MiniGUI.cfg 文件中指定比實際分辨率低的有效分辨率。這種特性有利于在 PC 上調試需要運行在較小分辨率系統上的應用程序。比如:
[system]
gal_engine=native
ial_engine=native
[native]
defaultmode=320x240x16
其中在 defaultmode 當中指定了有效分辨率為 320x240,16 則表示顏色深度,即 16 位色,或者稱為每象素的二進制位數。需要注重的是,對 VESA FramBuffer 設備,必須指定和當前顏色深度一致的顏色深度值。對其他的 FrameBuffer 設備,假如能夠支持多種顯示模式,則會根據 defaultmode 指定的模式設置當前分辨率。
3.5 新 GAL 的限制
需要注重的是,新的 GAL 結構只打算支持線性顯示內存,并且只支持 8 位色以上的顯示模式。假如要支持低于 8 位色的顯示模式,則可以選擇使用老的 GAL 和 GDI 接口。在配置 MiniGUI 的時候,你可以指定是否使用老的 GAL 和 GDI 接口。默認情況下的配置是使用新的 GAL 和 GDI 接口,需要使用老的 GAL 和 GDI 接口時,應進行如下的配置:
./configure --disable-newgal
另外,新的 GAL 接口支持 Gamma 校正和 YUV Overlay,但目前尚未在 GDI 接口中體現這些功能。在新的版本中,會逐步添加相應的 GDI 接口。
4 新的 GDI 接口
4.1 新的區域算法
新的 GDI 采用了新的區域算法,即在 X Window 和其他 GUI 系統當中廣泛使用的區域算法。這種區域稱作"x-y-banned"區域,并且具有如下特點:
區域由互不相交的非空矩形組成;
區域又可以劃分為若干互不相交的水平條帶,每個水平條帶中的矩形是等高,而且是上對齊的;或者說,這些矩形具有相同的高度,而且所有矩形的左上角 y 坐標相等。
區域中矩形的排列,首先是在 x 方向(在一個條帶中)從左到右排列,然后按照 y 坐標從上到下排列。
在 GDI 函數進行繪圖輸出時,可以利用 x-y-banned 區域的非凡性質進行繪圖的優化。在將來版本中添加的繪圖函數,將充分利用這一特性進行繪圖輸出上的優化。
新