文章目錄
- 1 綜述
- 2 libui庫
- 3 顯示輸出與硬體的介面
1 綜述
Android的GUI系統由C語言架構和JAVA語言架構組成。對下層,Android的GUI系統通過調用顯示輸出裝置和輸入裝置的驅動,從而將Android的軟體系統和底層的硬體聯絡起來。對上層,Android的GUI系統提供了Java層次的繪圖結構,Android的Java架構層調用這些繪圖介面來構建各種UI元素,這些繪圖介面也可以供Java應用程式層來調用。
Android的GUI系統架構圖1所示:
圖1 GUI系統架構圖
其中驅動包括FrameBuffer驅動,Event輸入驅動等。
由可知,libui是提供介面的架構庫,其他的庫大部分通過繼承並實現libui中定義的類來實現相應的功能。因此,理解libui的構造對於瞭解GUI的整體架構存在必然性。以下就來介紹一下該庫。
2 libui庫
libui是Android在本地層次一個架構性質的整合庫,它不僅是現實的中樞,也是整個AndroidGUI系統的中樞。
這個庫提供了一些介面,由其他的庫通過類繼承方式來實現,而調用者只需要調用libui庫的介面即可。libui庫包含了顏色格式,Egl視窗(使用者顯示),按鍵及事件處理,Surface(顯示介面),Overlay(顯示疊加層介面),Camera(照相機介面)等多個方面的定義。
libui庫中包含的內容如下:
1) Format(顏色格式))部分
這個部分本身定義色彩空間的枚舉類型和資料結構,它需要重用pixelflinger中的一些資料格式的定義。
2) Native Windows(本地視窗)部分
本部分用於實現一個本地顯示的介面,也就是實現一個egl_native_window_t類,程式通過調用從而實現基本的顯示功能。
3) Key/Event(按鍵和時間處理)部分
本部分是系統輸入的基礎,其中定義按鍵的映射,通過操作Event時間裝置來實現擷取系統的輸入。
4) Surface(顯示介面)部分
本部分定義了顯示介面較高層次的介面,包含部分顯示介面的管理功能。
5) Overlay(顯示部分的疊加層)部分
定義了一個疊加的顯示輸出層介面,覆蓋在主顯示層之上,常用於視頻輸出。
6) Camera(照相機)部分
定義網路攝影機的架構和介面。
3 顯示輸出與硬體的介面
顯示輸出介面最終需要與硬體互動,對於Linux作業系統,就是要和驅動程式打交道。這兩部分原本也是屬於“硬體抽象層”的內容,由於Android中使用的是FrameBuffer的標準顯示驅動,因此本部分內容在libui庫中使用標準方式來實現。
對於Android的顯示部分,需要實現的介面是egl_native_window_t,它是一個OpenGL結構,也是給libEGL使用的。
Android使用標準的FrameBuffer作為驅動程式,同時也在本地架構中提供了系統和FrameBuffer驅動程式之間的適配層,即硬體抽象層。這個部分主要在Gralloc模組中實現調用標準的FrameBuffer驅動,它是系統和FrameBuffer裝置之間的介面,以硬體模組的形式存在。Gralloc被libui庫調用。
Gralloc模式是顯示模組的實現,其中,framebuffer.cpp用於基於FrameBuffer的顯示實現。其中定義了框架緩衝區為雙緩衝:
// numbers ofbuffers for page flipping
#defineNUM_BUFFERS 2
……
//使用FBIOGET_FSCREENINFO和FBIOGET_VSCREENINFO的ioctl()介面來擷取驅動程式的基本資料,並調用mmap()將驅動程式的記憶體映射到使用者空間
structfb_fix_screeninfo finfo;
if (ioctl(fd, FBIOGET_FSCREENINFO,&finfo) == -1)
return -errno;
structfb_var_screeninfo info;
if (ioctl(fd, FBIOGET_VSCREENINFO,&info) == -1)
return -errno;
//RequestNUM_BUFFERS screens (at lest 2 for page flipping)
info.yres_virtual= info.yres * NUM_BUFFERS;
libui對gralloc模組實現了調用,在FrameBufferNativeWindow.cpp中開啟了gralloc裝置。
FramebufferNativeWindow::FramebufferNativeWindow()
:BASE(),fbDev(0),grDev(0),mUpdateOnDemand(false)
{
hw_module_tconst* module;
if(hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) {
int stride;
int err;
err = framebuffer_open(module,&fbDev);
LOGE_IF(err,"couldn't open framebuffer HAL (%s)", strerror(-err));
err =gralloc_open(module, &grDev);
LOGE_IF(err,"couldn't open gralloc HAL (%s)", strerror(-err));
// ......
}