Android GDI之屏幕設(shè)備管理-動(dòng)態(tài)鏈接庫
萬丈高樓從地起,從最根源的硬件幀緩沖區(qū)開始。我們知道顯示FrameBuffer在系統(tǒng)中就是一段內(nèi)存,GDI的工作就是把需要輸出的內(nèi)容放入到該段內(nèi)存的某個(gè)位置。我們從基本的點(diǎn)(像素點(diǎn))和基本的緩沖區(qū)操作開始。
1 基本知識(shí)
1.1點(diǎn)的格式
對(duì)于不同的LCD來講,F(xiàn)rameBuffer的二進(jìn)制格式不一樣,并且可以分為兩部分:
1)點(diǎn)的格式:通常將Depth,即表示多少位表示一個(gè)點(diǎn)。
1位表示一個(gè)點(diǎn)
2位表示一個(gè)點(diǎn)
16位表示一個(gè)點(diǎn)
32位表示一個(gè)點(diǎn)(Alpha通道)
2) 點(diǎn)內(nèi)格式:RGB分量分布表示。
例如對(duì)于我們常見的16位表示一個(gè)點(diǎn)
1.2.格式之間的轉(zhuǎn)換
所以屏幕輸出實(shí)際上是一個(gè)值映射的關(guān)系。我們可以有如下的點(diǎn)格式轉(zhuǎn)換,
源格式可能來自單色位圖和彩色位圖,對(duì)于具體的目標(biāo)機(jī)來講,我們的目標(biāo)格式可能就是一種,例如16位(5/6/5)格式。其實(shí)就只存在一種格式的轉(zhuǎn)換,即從目標(biāo)格式都是16位格式。
但是,在設(shè)計(jì)GDI時(shí),基本要求有一個(gè)可移植性好,所以我們還是必須考慮對(duì)于不同點(diǎn)格式LCD之間的轉(zhuǎn)換操作。所以在GDI的驅(qū)動(dòng)程序中涉及到如下幾類主要操作:
區(qū)域操作(Blit):我們?cè)陲@示緩沖區(qū)上做的最多的操作就是區(qū)塊搬運(yùn)。由此,很多的應(yīng)用處理器使用了硬件圖形加速器來完成區(qū)域搬運(yùn):blit.從我們的主要操作的對(duì)象來看,可以分為兩個(gè)方向:
1)內(nèi)存區(qū)域到屏幕區(qū)域
2)屏幕區(qū)域到屏幕區(qū)域
3)屏幕區(qū)域到內(nèi)存區(qū)域
4)內(nèi)存區(qū)域到內(nèi)存區(qū)域
在這里我們需要特別提出的是,由于在Linux不同進(jìn)程之間的內(nèi)存不能自由的訪問,使得我們的每個(gè)Android應(yīng)用對(duì)于內(nèi)存區(qū)域和屏幕緩沖區(qū)的使用變得很復(fù)雜。在Android的設(shè)計(jì)中,在屏幕緩沖區(qū)和顯示內(nèi)存緩沖區(qū)的管理分類很多的層次,最上層的對(duì)象是可以在進(jìn)程間自由傳遞,但是對(duì)于緩沖區(qū)內(nèi)容則使用共享內(nèi)存的機(jī)制。
基于以上的基礎(chǔ)知識(shí),我們可以知道:
(1)代碼中Config及其Format的意義所在了。也就理解了兼容性的意義:采用同硬件相同的點(diǎn)的描述對(duì)象
(2)所有屏幕上圖形的移動(dòng)都是顯示緩沖區(qū)搬運(yùn)的結(jié)果。
1.2圖形加速器
應(yīng)用處理器都可能帶有圖形加速器,對(duì)于不同的應(yīng)用處理器對(duì)其圖形加速器可能有不同的處理方式,對(duì)于2D加速來講,都可歸結(jié)為Blit。多為數(shù)據(jù)的搬運(yùn),放大縮小,旋轉(zhuǎn)等。
2 Android的緩沖區(qū)抽象定義
不同的硬件有不同的硬件圖形加速設(shè)備和緩沖內(nèi)存實(shí)現(xiàn)方法。Android Gralloc動(dòng)態(tài)庫抽象的任務(wù)就是消除不同的設(shè)備之間的差別,在上層看來都是同樣的方法和對(duì)象。在Moudle層隱藏緩沖區(qū)操作細(xì)節(jié)。Android使用了動(dòng)態(tài)鏈接庫gralloc.xxx.so,來完成底層細(xì)節(jié)的封裝。
2.1 本地定義@hardware\libhandware\modules\gralloc
每個(gè)動(dòng)態(tài)鏈接庫都是用相同名稱的調(diào)用接口:
1)硬件圖形加速器的抽象:BlitEngine,CopyBit的加速操作。
2)硬件FrameBuffer內(nèi)存管理
3)共享緩存管理
從數(shù)據(jù)關(guān)系上我們來考察..動(dòng)態(tài)鏈接庫的抽象行為:在層次:
Hardware.c@hardware\libhardware 中對(duì)動(dòng)態(tài)鏈接庫中的內(nèi)容作了全新的包裝。/system/lib/hw/gralloc.xxx.so動(dòng)態(tài)庫文件。從文件Gralloc.h(handware\libhardware\include\hardware)是抽象的結(jié)果:hw_get_module從gralloc.xxx.so提取了HAL_MODULE_INFO_SYM(SYM變量)
從展露在外部的數(shù)據(jù)結(jié)構(gòu),我們?cè)贎Gralloc.cpp看到到了這樣的布局:
static struct hw_module_methods_t gralloc_module_methods = {
open: gralloc_device_open
};
struct private_module_t HAL_MODULE_INFO_SYM = {
base: {
common: {
tag: HARDWARE_MODULE_TAG,
…
id: GRALLOC_HARDWARE_MODULE_ID,
name: "Graphics Memory Allocator Module",
author: "The Android Open Source Project",
methods: &gralloc_module_methods
},
registerBuffer: gralloc_register_buffer,
unregisterBuffer: gralloc_unregister_buffer,
lock: gralloc_lock,
unlock: gralloc_unlock,
},
framebuffer: 0,
flags: 0,
numBuffers: 0,
bufferMask: 0,
…
};
我們建立了什么對(duì)象來支撐緩沖區(qū)的操作?
buffer_handle_t:外部接口。
methods.open,registerBuffer,unregisterBuffer,lock,unlock
下面是外部接口和內(nèi)部對(duì)象的結(jié)構(gòu)關(guān)系,該類型的結(jié)構(gòu)充分利用C Struct的數(shù)據(jù)排列特性:基本結(jié)構(gòu)體放置在最前面,本地私有放置在后面,滿足了抽象的需要。
typedef const native_handle* buffer_handle_t;
private_module_t HAL_MODULE_INFO_SYM 向往暴露的動(dòng)態(tài)鏈接庫接口,通過該接口,我們直接可以使用該對(duì)象。
看不清楚上面圖,可以偏一下頭橫著看:
幾個(gè)接口函數(shù)的解釋:
(1)fb_post
對(duì)于幀緩沖區(qū)實(shí)際地址并不需要向上層報(bào)告,所有的操作都是通過fb_post了完成。
fp_post的任務(wù)就是將一個(gè)Buffer的內(nèi)容傳遞到硬件緩沖區(qū)。其實(shí)現(xiàn)方式有兩種:
(方式1)無需拷貝動(dòng)作,是把Framebuffer的后buffer切為前buffer,然后通過IOCTRL機(jī)制告訴FB驅(qū)動(dòng)切換DMA源地地址。這個(gè)實(shí)現(xiàn)方式的前提是Linux內(nèi)核必須分配至少兩個(gè)緩沖區(qū)大小的物理內(nèi)存和實(shí)現(xiàn)切換的ioctrol,這個(gè)實(shí)現(xiàn)快速切換。
(方式2)利用Copy的方式。不修改內(nèi)核,則在適配層利用從拷貝的方式進(jìn)行,但是這個(gè)是費(fèi)時(shí)了。
(2)gralloc的主要功能是要完成:
1)打開屏幕設(shè)備 "/dev/fb0",,并映射硬件顯示緩沖區(qū)。
2)提供分配共享顯示緩存的接口
3)提供BiltEngine接口(完成硬件加速器的包裝)
(3)gralloc_alloc輸出buffer_handle_t句柄。
這個(gè)句柄是共享的基本依據(jù),其基本原理在后面的章節(jié)有詳細(xì)描述。
3 總結(jié)
總結(jié)一下,/system/lib/hw/gralloc.xxx.so是跟硬件體系相關(guān)的一個(gè)動(dòng)態(tài)鏈接庫,也可以叫做Android的硬件抽象層。他實(shí)現(xiàn)了Android的硬件抽象接口標(biāo)準(zhǔn),提供顯示內(nèi)存的分配機(jī)制和CopyBit等的加速實(shí)現(xiàn)。而如何具體實(shí)現(xiàn)這些功能,則跟硬件平臺(tái)的配備有關(guān)系,所以我們看到了對(duì)于與不同的硬件架構(gòu),有不同的配置關(guān)系。