Android display SW架構分析
下面簡單介紹一下中的各個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
。