功能:Galloc模块是显示框架的硬件抽象层,主要是封装了/dev/graphics/fb%d设备文件的操作,
为框架层提供接口。
实现:Gralloc是HAl中的模块,会被编译成动态链接库。框架层会将动态链接库加载到内存中,
并利用导出符号得到封装的方法。
问题: Gralloc模块如何加载使用、Gralloc做了哪些事、Gralloc模块内部结构?
Gralloc模块如何加载、使用
答:框架层利用hw_get_module查找模块,并获取导出符号HMI对应的结构体。
hw_get_module(id, module) 提供给框架层调用
int hw_get_module(const char *id, const struct hw_module_t **module)
{
return hw_get_module_by_class(id, NULL, module);
}
hw_get_module直接调用了hw_get_module_by_class
int hw_get_module_by_class(const char *class_id, const char *inst,
const struct hw_module_t **module)
{
for (i=0 ; i
if (i
if (property_get(variant_keys[i], prop, NULL) == 0) {
continue;
}
//1.在/system/lib/hw/和/vendor/lib/hw/目录下查找四个指定名称的gralloc.xx.so
snprintf(path, sizeof(path), "%s/%s.%s.so",
HAL_LIBRARY_PATH2, name, prop);
if (access(path, R_OK) == 0) break;
snprintf(path, sizeof(path), "%s/%s.%s.so",
HAL_LIBRARY_PATH1, name, prop);
if (access(path, R_OK) == 0) break;
} else {
//2.没有指定gralloc.xx.so时,使用 /system/lib/hw/gralloc.default.so
snprintf(path, sizeof(path), "%s/%s.default.so",
HAL_LIBRARY_PATH1, name);
if (access(path, R_OK) == 0) break;
}
}
status = -ENOENT;
if (i
//3.加载gralloc.xx.so到内存
status = load(class_id, path, module);
}
return status;
}
函数很简单,在几个路径下查询gralloc.xx.so模块选用一个,最后利用load函数将其加载到内存
static int load(const char *id,
const char *path,
const struct hw_module_t **pHmi)
{
//1.使用dlopen打开动态链接库
handle = dlopen(path, RTLD_NOW);
//2.获取动态链接库符号HMI对应地址,得到结构体hw_module_t
(HAL_MODULE_INFO_SYM_AS_STR是一个常量"HMI",也就是HAL中所有动态链接库导出的都是HMI符号)
const char *sym = HAL_MODULE_INFO_SYM_AS_STR;
hmi = (struct hw_module_t *)dlsym(handle, sym);
hmi->dso = handle;
//3.返回给调用者hw_module_t
*pHmi = hmi;