下面簡單介紹一下中的各個Layer:
*藍色部分-使用者空間應用程式
應用程式層,其中包括Android應用程式以及架構和系統運行庫,和底層相關的是系統運行庫,而其中和顯示相關的就是Android的Surface Manager, 它負責對顯示子系統的管理,並且為多個應用程式提 供了2D和3D圖層的無縫融合。
*黑色部分-HAL層,在2.2.1部分會有介紹
*紅色部分-Linux kernel層
Linux kernel,其中和顯示部分相關的就是Linux的FrameBuffer,它是Linux系統中的顯示部分驅動程式介面。Linux工作在保護模式下,User空間的應用程式無法直接調用顯卡的驅動程式來直接畫屏,FrameBuffer機制模仿顯卡的功能,將顯卡硬體結構抽象掉,可以通過 Framebuffer的讀寫直接對顯存進行操作。使用者可以將Framebuffer看成是顯示記憶體的一個映像,將其映射到進程地址空間之後,就可以直接進行讀寫操作,而寫操作可以立即反應在螢幕上。這種操作是抽象的,統一的。使用者不必關心物理顯存的位置、換頁機制等等具體細節。這些都是由
Framebuffer裝置驅動來完成的。
*綠色部分-HW驅動層
該部分可以看作高通顯卡的驅動程式,和高通顯示部分硬體相關以及外圍LCD相關的驅動都被定義在這邊,比如上述的顯卡的一些特性都是在這邊被初始化的,同樣MDP和MDDI相關的驅動也都定義在這裡
User Space Display功能介紹
這裡的User Space就是與應用程式相關的上層部分(參考中的藍色部分),其中與Kernel空間互動的部分稱之為HAL-HW Abstraction Layer。
HAL其實就是使用者空間的驅動程式。如果想要將 Android 在某硬體平台上執行,基本上完成這些驅動程式就行了。其內定義了 Android 對各硬體裝置例如顯示晶片、聲音、數位相機、GPS、GSM 等等的需求。
HAL存在的幾個原因:
1、 並不是所有的硬體裝置都有標準的linux kernel的介面。
2、 Kernel driver涉及到GPL的著作權。某些裝置製造商並不原因公開硬體驅動,所以才去HAL方式繞過GPL。
3、 針對某些硬體,Android有一些特殊的需求。
在display部分,HAL的實現code在copybit.c中,應用程式直接操作這些介面即可,具體的介面如下
struct copybit_context_t *ctx = malloc(sizeof(struct copybit_context_t)); memset(ctx, 0, sizeof(*ctx)); ctx->device.common.tag = HARDWARE_DEVICE_TAG; ctx->device.common.version = 0; ctx->device.common.module = module; ctx->device.common.close = close_copybit; ctx->device.set_parameter = set_parameter_copybit;//設定參數 ctx->device.get = get; ctx->device.blit = blit_copybit;//傳送顯示資料 ctx->device.stretch = stretch_copybit; ctx->mAlpha = MDP_ALPHA_NOP; ctx->mFlags = 0; ctx->mFD = open("/dev/graphics/fb0", O_RDWR, 0);//開啟裝置
Kernel Space Display功能介紹
這裡的Kernel空間(與Display相關)是Linux平台下的FB裝置(參考中的紅色部分)。下面介紹一下FB裝置。
Fb即FrameBuffer的簡稱。framebuffer 是一種能夠提取圖形的硬體裝置,是使用者進入圖形介面很好的介面。有了framebuffer,使用者的應用程式不需要對底層驅動有深入瞭解就能夠做出很好的圖形。對於使用者而言,它和/dev 下面的其他裝置沒有什麼區別,使用者可以把
framebuffer 看成一塊記憶體,既可以向這塊記憶體中寫入資料,也可以從這塊記憶體中讀取資料。它允許上層應用程式在圖形模式下直接對顯示緩衝區進行讀寫操作。這種操作是抽象的,統一的。使用者不必關心物理顯存的位置、換頁機制等等具體細節。這些都是由Framebuffer裝置驅動來完成的。
從使用者的角度看,幀緩衝裝置和其他位於/dev下面的裝置類似,它是一個字元裝置,通常主裝置號是29,次裝置號定義幀緩衝的個數。
在LINUX系統中,裝置被當作檔案來處理,所有的檔案包括裝置檔案,Linux都提供了統一的操作函數介面。上面的結構體就是Linux為FB裝置提供的操作函數介面。
1)、讀寫(read/write)介面,即讀寫螢幕緩衝區(應用程式不一定會調用該介面)
2)、映射(map)操作(使用者空間不能直接存取顯存物理空間,需map成虛擬位址後才可以)
由於Linux工作在保護模式,每個應用程式都有自己的虛擬位址空間,在應用程式中是不能直接存取物理緩衝區地址的。為此,Linux在檔案操作 file_operations結構中提供了mmap函數,可將檔案的內容映射到使用者空間。對於幀緩衝裝置,則可通過映射操作,可將螢幕緩衝區的物理地址映射到使用者空間的一段虛擬位址中,之後使用者就可以通過讀寫這段虛擬位址訪問螢幕緩衝區,在螢幕上繪圖了。實際上,使用幀緩衝裝置的應用程式都是通過映射操作來顯示圖形的。由於映射操作都是由核心來完成,下面我們將看到,幀緩衝驅動留給開發人員的工作並不多
3)、I/O控制:對於幀緩衝裝置,對裝置檔案的ioctl操作可讀取/設定顯示裝置及螢幕的參數,如解析度,顯示顏色數,螢幕大小等等。ioctl的操作是由底層的驅動程式來完成
Note:上述部分請參考檔案fbmem.c。