3. fb設備的打開過程
在Gralloc模塊中,fb設備的ID值定義爲GRALLOC_HARDWARE_FB0。GRALLOC_HARDWARE_FB0是一個宏,定義在文件hardware/libhardware/include/hardware/gralloc.h中, 以下所示:
-
#define GRALLOC_HARDWARE_FB0 "fb0"
fb設備使用結構體framebuffer_device_t 來描述。結構體framebuffer_device_t是用來描述系統幀緩衝區的信息,它定義在文件hardware/libhardware/include/hardware/gralloc.h中, 以下所示:
-
typedef struct framebuffer_device_t {
-
struct hw_device_t common;
-
-
-
const uint32_t flags;
-
-
-
const uint32_t width;
-
const uint32_t height;
-
-
-
const int stride;
-
-
-
const int format;
-
-
-
const float xdpi;
-
const float ydpi;
-
-
-
const float fps;
-
-
-
const int minSwapInterval;
-
-
-
const int maxSwapInterval;
-
-
int reserved[8];
-
-
int (*setSwapInterval)(struct framebuffer_device_t* window,
-
int interval);
-
-
int (*setUpdateRect)(struct framebuffer_device_t* window,
-
int left, int top, int width, int height);
-
-
int (*post)(struct framebuffer_device_t* dev, buffer_handle_t buffer);
-
-
int (*compositionComplete)(struct framebuffer_device_t* dev);
-
-
void* reserved_proc[8];
-
-
} framebuffer_device_t;
成員變量flags用來記錄系統幀緩衝區的標誌,目前沒有使用這成員變量,它的值被設置爲0。
成員變量width和height分別用來描述設備顯示屏的寬度和高度,它們是以像素爲單位的。
成員變量stride用來描述設備顯示屏的一行有多少個像素點。
成員變量format用來描述系統幀緩衝區的像素格式,支持的像素格式主要有HAL_PIXEL_FORMAT_RGBX_8888和HAL_PIXEL_FORMAT_RGB_565兩種。HAL_PIXEL_FORMAT_RGBX_8888表示一個像素使用32位來描述,R、G和B分別佔8位,另外8位未使用。HAL_PIXEL_FORMAT_RGB_565表示一個像素使用16位來描述,R、G和B分別佔五、6和5位。
成員變量xdpi和ydpi分別用來描述設備顯示屏在寬度和高度上的密度,即每英寸有多少個像素點。
成員變量fps用來描述設備顯示屏的刷新頻率,它的單位是幀每秒。
成員變量minSwapInterval和maxSwapInterval用來描述幀緩衝區交換先後兩個圖形緩衝區的最小和最大時間間隔。
成員變量reserved是保留給未來使用的。
成員函數setSwapInterval用來設置幀緩衝區交換先後兩個圖形緩衝區的最小和最大時間間隔。
成員函數setUpdateRect用來設置幀緩衝區的更新區域。
成員函數post用來將圖形緩衝區buffer的內容渲染到幀緩衝區中去,即顯示在設備的顯示屏中去。
成員函數compositionComplete用來通知fb設備device,圖形緩衝區的組合工做已經完成,目前沒有使用這個成員函數。
成員變量reserved是一個函數指針數組,它們是保留給未來使用的。
在結構體framebuffer_device_t的一系列成員函數中,post是最重要的一個成員函數,用戶空間的應用程序經過調用這個成員函數就能夠在設備的顯示屏中渲染指定的畫面,後面咱們將詳細這個函數的實現。
Gralloc模塊在在文件hardware/libhardware/include/hardware/gralloc.h中定義了一個幫助函數framebuffer_open,用來打開fb設備,以下所示:
-
static inline int framebuffer_open(const struct hw_module_t* module,
-
struct framebuffer_device_t** device) {
-
return module->methods->open(module,
-
GRALLOC_HARDWARE_FB0, (struct hw_device_t**)device);
-
}
參數module指向的是一個用來描述Gralloc模塊的hw_module_t結構體,前面提到,它的成員變量methods所指向的一個hw_module_methods_t結構體的成員函數open指向了Gralloc模塊中的函數gralloc_device_open,這個函數打開fb設備的代碼段以下所示:
-
int gralloc_device_open(const hw_module_t* module, const char* name,
-
hw_device_t** device)
-
{
-
int status = -EINVAL;
-
if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {
-
......
-
} else {
-
status = fb_device_open(module, name, device);
-
}
-
return status;
-
}
參數name的值等於GRALLOC_HARDWARE_FB0,所以,函數gralloc_device_open接下來會調用另一個函數fb_device_open來執行打開fb設備的操做。
函數fb_device_open定義在文件hardware/libhardware/modules/gralloc/framebuffer.cpp中,以下所示:
-
struct fb_context_t {
-
framebuffer_device_t device;
-
};
-
-
......
-
-
int fb_device_open(hw_module_t const* module, const char* name,
-
hw_device_t** device)
-
{
-
int status = -EINVAL;
-
if (!strcmp(name, GRALLOC_HARDWARE_FB0)) {
-
alloc_device_t* gralloc_device;
-
status = gralloc_open(module, &gralloc_device);
-
if (status < 0)
-
return status;
-
-
-
fb_context_t *dev = (fb_context_t*)malloc(sizeof(*dev));
-
memset(dev, 0, sizeof(*dev));
-
-
-
dev->device.common.tag = HARDWARE_DEVICE_TAG;
-
dev->device.common.version = 0;
-
dev->device.common.module = const_cast<hw_module_t*>(module);
-
dev->device.common.close = fb_close;
-
dev->device.setSwapInterval = fb_setSwapInterval;
-
dev->device.post = fb_post;
-
dev->device.setUpdateRect = 0;
-
-
private_module_t* m = (private_module_t*)module;
-
status = mapFrameBuffer(m);
-
if (status >= 0) {
-
int stride = m->finfo.line_length / (m->info.bits_per_pixel >> 3);
-
int format = (m->info.bits_per_pixel == 32)
-
? HAL_PIXEL_FORMAT_RGBX_8888
-
: HAL_PIXEL_FORMAT_RGB_565;
-
#ifdef NO_32BPP
-
format = HAL_PIXEL_FORMAT_RGB_565;
-
#endif
-
const_cast<uint32_t&>(dev->device.flags) = 0;
-
const_cast<uint32_t&>(dev->device.width) = m->info.xres;
-
const_cast<uint32_t&>(dev->device.height) = m->info.yres;
-
const_cast<int&>(dev->device.stride) = stride;
-
const_cast<int&>(dev->device.format) = format;
-
const_cast<float&>(dev->device.xdpi) = m->xdpi;
-
const_cast<float&>(dev->device.ydpi) = m->ydpi;
-
const_cast<float&>(dev->device.fps) = m->fps;
-
const_cast<int&>(dev->device.minSwapInterval) = 1;
-
const_cast<int&>(dev->device.maxSwapInterval) = 1;
-
*device = &dev->device.common;
-
}
-
}
-
return status;
-
}
這個函數主要是用來建立一個fb_context_t結構體,而且對它的成員變量device進行初始化。結構體fb_context_t的成員變量device的類型爲framebuffer_device_t,前面提到,它是用來描述fb設備的。fb設備主要是用來渲染圖形緩衝區的,這是經過調用它的成員函數post來實現的。從這裏能夠看出,函數fb_device_open所打開的fb設備的成員函數post被設置爲Gralloc模塊中的函數fb_post,後面咱們再詳細分析它的實現。