SurfaceFlinger介绍
Android的GUI系统(Graphic User Interface),是基于opengl/egl实现的。
一,opengles/egl的关系,借鉴网上的图。
1),hal层提供了gralloc,包括fb和gralloc两个设备,fb负责打开内核中的framebuffer,提供post,setwapInterval等操作,gralloc负责帧缓冲区的分配和释放。
hal层另一个模块composer,被surfacefligner中的hwcomposer使用,hwcompsoer还负责vsync信号的产生和控制,vsync也可能由硬件产生。
hal层也是子系统跟kernel驱动之间通信的统一接口。
2),opengles要跟具体平台的本地窗口建立关联,framebuffernativewindow就是负责opengles在android平台上本地化的中介之一。opengles的具体实现可以由软件实现(libagl),也可以由硬件实现(libhgl)。
3),surfaceflinger中有个数组来描述系统支持的显示设备,即DisplayDevice。
为了确保hal层接口的稳定性,对于每一类硬件,android系统预先定义了这些接口,硬件设备商只需要按要求来实现即可,hal层个硬件接口的定义放在:hardware/libhardware/include/hardware/目录。
二,android显示设备相关的两个模块-Gralloc和Framebuffer
Framebuffer是一块包含屏幕显示信息的缓冲区,可以看成是终端显示设备的化身。framebuffer提供的设备文件节点是dev/graphics/fb*,理论上支持多个显示屏,fb0是主显示屏。
Android的子系统通常不会直接使用内核驱动,而是由hal层间接引用底层框架。显示系统也是这样,借助hal层的gralloc操作帧缓冲区。
Gralloc提供的接口:
gralloc.cpp
struct private_module_t HAL_MODULE_INFO_SYM = {
.base = {
.common = {
.tag = HARDWARE_MODULE_TAG,
.version_major = 1,
.version_minor = 0,
.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,
.lock = PTHREAD_MUTEX_INITIALIZER,
.currentBuffer = 0,
};
每个硬件模块都必须有一个名称是HAL_MODULE_INFO_SYM的数据结构,以上是gralloc中的实现。它的第一个数据成员是gralloc_module_tbase;类型,而gralloc_module_t的定义中第一个成员是hw_module_t,这就形成了类似C++中的继承关系,结构体的第一个成员是其父类。
gralloc.h
typedef struct gralloc_module_t {
struct hw_module_t common;
}
每个硬件模块的数据结构,都是以hw_module_t开头,hw_module_t的结构体定义中只有一个函数指针open,在调用hw_get_module时,系统在指定的目录中加载正确的hal库,然后通过open方法打开指定的设备。open方法对应的实现是gralloc_device_open()@gralloc.cpp。
#define GRALLOC_HARDWARE_GPU0 "gpu0"
#define GRALLOC_HARDWARE_MODULE_ID "gralloc"
int gralloc_device_open(const hw_module_t* module, const char* name,
hw_device_t** device)@gralloc.cpp{
//这是打开gralloc设备,else是打开fb设备。
if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {
// gralloc_context_t是gralloc内部的一个结构体,
gralloc_context_t *dev;
dev = (gralloc_context_t*)malloc(sizeof(*dev));//分配空间
/* initialize our state here */
memset(dev, 0, sizeof(*dev));//初始化。
/* initialize the procs */
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 = gralloc_close;
dev->device.alloc = gralloc_alloc;//主要负责缓冲区的分配和释放
dev->device.free = gralloc_free;
//函数参数 device的内容,只是gralloc_context_t内部的device.common。
*device = &dev->device.common;
status = 0;
} else {
status = fb_device_open(module, name, device);
}
return status;
}
下面看framebuffer设备的打开过程:
int fb_device_open(hw_module_t const* module, const char* name,
hw_device_t** device)@framebuffer.cpp{
//分配空间,初始化
fb_context_t *dev = (fb_context_t*)malloc(sizeof(*dev));
memset(dev, 0, sizeof(*dev));
//主要接口指针的赋值。
//设置两个缓冲区交换的事件间隔。
dev->device.setSwapInterval = fb_setSwapInterval;
//将数据post到显示屏,这样buffer的内容在下次的vsync中被显示出来。
dev->device.post = fb_post;
//在mapFrameBuffer 中尝试打开fb设备,为fb设备做内存映射。
private_module_t* m = (private_module_t*)module;
status = mapFrameBuffer(m);
}