4.1 Gralloc概述
Android系统在硬件抽象层中提供了一个Gralloc模块,封装了对framebuffer的所有访问操作。Gralloc模块符合Android标准的HAL架构设计。Gralloc对应的hardware id为:GRALLOC_HARDWARE_MODULE_ID
Gralloc模块实现源码位于:hardware/libhardware/modules/gralloc
用户空间的应用程序在使用帧缓冲区之前,首先要加载Gralloc模块,并且获得一个gpu0设备(gralloc_device, modulename:GRALLOC_HARDWARE_GPU0)和一个fb0设备(modulename:GRALLOC_HARDWARE_FB0)。
有了alloc设备之后,用户空间中的应用程序就可以申请分配一块图形缓冲区,并且将这块图形缓冲区映射到应用程序的地址空间来,以便可以向里面写入要绘制的画面的内容。最后,用户空间中的应用程序就通过fb0设备来将已经准备好了的图形缓冲区渲染到帧缓冲区中去,即将图形缓冲区的内容绘制到显示屏中去。相应地,当用户空间中的应用程序不再需要使用一块图形缓冲区的时候,就可以通过alloc设备来释放它,并且将它从地址空间中解除映射。
由于历史的原因,gralloc设备和alloc设备是同一个概念。本文以alloc设备进行说明。
4.2 Gralloc库的加载
Gralloc模块是在HWComposer的构造函数中,完成对应库的加载的。
HWComposer::HWComposer( const sp<SurfaceFlinger>& flinger, EventHandler& handler) : mFlinger(flinger), mFbDev(0), mHwc(0), mNumDisplays(1), mCBContext(new cb_context), mEventHandler(handler), mDebugForceFakeVSync(false) { 。。。。。
bool needVSyncThread = true; //加载Gralloc中的GRALLOC_HARDWARE_FB0设备,和HWC设备 // Note: some devices may insist that the FB HAL be opened before HWC. int fberr = loadFbHalModule(); loadHwcModule(); 。。。。。 }
|
我们来看下loadFbHalModule()的具体实现,从代码的实现来看,首先是通过GRALLOC_HARDWARE_MODULE_ID,并利用HAL架构完成对应的so库的找寻并加载,然后打开fb0设备。
// Load and prepare the FB HAL, which uses the gralloc module. Sets mFbDev. int HWComposer::loadFbHalModule() { hw_module_t const* module;
int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module); if (err != 0) { ALOGE("%s module not found", GRALLOC_HARDWARE_MODULE_ID); return err; }
return framebuffer_open(module, &mFbDev); } // 定义在hardware/libhardware/include/hardware/gralloc.h #define GRALLOC_HARDWARE_MODULE_ID "gralloc" |
/** convenience API for opening and closing a supported device */
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); } #define GRALLOC_HARDWARE_FB0 "fb0" |
暂时放下open函数。我们先来看看加载的是哪个库文件。根据HAL的规则,系统会在/vendor/lib/hw及/system/lib/hw两个目录下面找寻gralloc.*.so,并加载。
比如:
gralloc.<ro.hardware>.so
gralloc.<ro.product.board>.so
gralloc.<ro.board.platform>.so
gralloc.<ro.arch>.so
以N5为例,对应的so库应该为gralloc.msm8974.so
在编译的时候,是通过PRODUCT_PACKAGES来完成拷贝的。
@device/tencent/hammerhead/device.mk PRODUCT_PACKAGES += \ gralloc.msm8974 \ libgenlock \ HWComposer.msm8974 \ memtrack.msm8974 \ libqdutils \ libqdMetaData
|
其源码定义在/hardware/qcom/display/msm8974/libgrallo中。