概述
http://blog.csdn.net/new_abc/article/details/8658168
一、HAL调用方式或流程(以gralloc为例):
hw_module_t const* module;
alloc_device_t* grDev;
hw_get_module(GRALLOC_HARDWARE_MODULE_ID,&module);获取hw_module_t结构
gralloc_open(module, &grDev); //调用相应的open接口,在这个接口里会对gralloc设备结构grDev初始化,以 后就可以使用其中的方法
如grDev->alloc(******);
再看一下gralloc.h提供的信息(与gralloc相关):
1、首先是扩展的hw_module_t结构:
- typedef struct gralloc_module_t {
- struct hw_module_t common;
- /*
- * (*registerBuffer)() must be called before a buffer_handle_t that has not
- * been created with (*alloc_device_t::alloc)() can be used.
- *
- * This is intended to be used with buffer_handle_t's that have been
- * received in this process through IPC.
- *
- * This function checks that the handle is indeed a valid one and prepares
- * it for use with (*lock)() and (*unlock)().
- *
- * It is not necessary to call (*registerBuffer)() on a handle created
- * with (*alloc_device_t::alloc)().
- *
- * returns an error if this buffer_handle_t is not valid.
- */
- int (*registerBuffer)(struct gralloc_module_t const* module,
- buffer_handle_t handle);
- /*
- * (*unregisterBuffer)() is called once this handle is no longer needed in
- * this process. After this call, it is an error to call (*lock)(),
- * (*unlock)(), or (*registerBuffer)().
- *
- * This function doesn't close or free the handle itself; this is done
- * by other means, usually through libcutils's native_handle_close() and
- * native_handle_free().
- *
- * It is an error to call (*unregisterBuffer)() on a buffer that wasn't
- * explicitly registered first.
- */
- int (*unregisterBuffer)(struct gralloc_module_t const* module,
- buffer_handle_t handle);
- /*
- * The (*lock)() method is called before a buffer is accessed for the
- * specified usage. This call may block, for instance if the h/w needs
- * to finish rendering or if CPU caches need to be synchronized.
- *
- * The caller promises to modify only pixels in the area specified
- * by (l,t,w,h).
- *
- * The content of the buffer outside of the specified area is NOT modified
- * by this call.
- *
- * If usage specifies GRALLOC_USAGE_SW_*, vaddr is filled with the address
- * of the buffer in virtual memory.
- *
- * THREADING CONSIDERATIONS:
- *
- * It is legal for several different threads to lock a buffer from
- * read access, none of the threads are blocked.
- *
- * However, locking a buffer simultaneously for write or read/write is
- * undefined, but:
- * - shall not result in termination of the process
- * - shall not block the caller
- * It is acceptable to return an error or to leave the buffer's content
- * into an indeterminate state.
- *
- * If the buffer was created with a usage mask incompatible with the
- * requested usage flags here, -EINVAL is returned.
- *
- */
- int (*lock)(struct gralloc_module_t const* module,
- buffer_handle_t handle, int usage,
- int l, int t, int w, int h,
- void** vaddr);
- /*
- * The (*unlock)() method must be called after all changes to the buffer
- * are completed.
- */
- int (*unlock)(struct gralloc_module_t const* module,
- buffer_handle_t handle);
- /* reserved for future use */
- int (*perform)(struct gralloc_module_t const* module,
- int operation, ... );
- /* reserved for future use */
- void* reserved_proc[7];
- } gralloc_module_t;
- 2、然后是扩展的hw_device_t结构:
- typedef struct alloc_device_t {
- struct hw_device_t common;
- /*
- * (*alloc)() Allocates a buffer in graphic memory with the requested
- * parameters and returns a buffer_handle_t and the stride in pixels to
- * allow the implementation to satisfy hardware constraints on the width
- * of a pixmap (eg: it may have to be multiple of 8 pixels).
- * The CALLER TAKES OWNERSHIP of the buffer_handle_t.
- *
- * Returns 0 on success or -errno on error.
- */
- int (*alloc)(struct alloc_device_t* dev,
- int w, int h, int format, int usage,
- buffer_handle_t* handle, int* stride);
- /*
- * (*free)() Frees a previously allocated buffer.
- * Behavior is undefined if the buffer is still mapped in any process,
- * but shall not result in termination of the program or security breaches
- * (allowing a process to get access to another process' buffers).
- * THIS FUNCTION TAKES OWNERSHIP of the buffer_handle_t which becomes
- * invalid after the call.
- *
- * Returns 0 on success or -errno on error.
- */
- int (*free)(struct alloc_device_t* dev,
- buffer_handle_t handle);
- } alloc_device_t;
3、最后是两个方法:
- static inline int gralloc_open(const struct hw_module_t* module,
- struct alloc_device_t** device) {
- return module->methods->open(module,
- GRALLOC_HARDWARE_GPU0, (struct hw_device_t**)device);
- }
- static inline int gralloc_close(struct alloc_device_t* device) {
- return device->common.close(&device->common);
- }
这里直接调用modules里面的open方法,该open指针是在hw_get_module时候赋值的。
所有模块的实现基本都是这样,一个扩展的hw_module_t结构,一个扩展的hw_device_t结构,hw_module_t结构的赋值是通过hw_get_module然后传相应的module ID,如GRALLOC_HARDWARE_MODULE_ID,获取相应ID hw_module_t结构的首地址;而hw_device_t结构是通过相应的Open方法,如这里的gralloc_open,通过这个接口,就获得了操作这个设备的方法了。
二、HAL相关实现
首先看一下hw_module_t结构:
- typedef struct hw_module_t {
- /** tag must be initialized to HARDWARE_MODULE_TAG */
- uint32_t tag;
- /** major version number for the module */
- uint16_t version_major;
- /** minor version number of the module */
- uint16_t version_minor;
- /** Identifier of module */
- const char *id;
- /** Name of this module */
- const char *name;
- /** Author/owner/implementor of the module */
- const char *author;
- /** Modules methods */
- struct hw_module_methods_t* methods;
- /** module's dso */
- void* dso;
- /** padding to 128 bytes, reserved for future use */
- uint32_t reserved[32-7];
- } hw_module_t;
比较重要的是id和methods,id用来区分各个模块,而hw_module_methods_t我们可以看到其定义是:
- typedef struct hw_module_methods_t {
- /** Open a specific device */
- int (*open)(const struct hw_module_t* module, const char* id,
- struct hw_device_t** device);
- } hw_module_methods_t;
一个open方法,指向了打开这个模块的Open方法
我们看一下gralloc模块相关结构的关系图:
1、 先看一下private_module_t(hw_module_t)结构的赋值
- 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,
- pmem_master: -1,
- pmem_master_base: 0
- };
这里id赋值为GRALLOC_HARDWARE_MODULE_ID,methods赋值为gralloc_module_methods
看一下gralloc_module_methods
gralloc_module_t扩展了hw_module_t,增加4个方法,这四个方法可以在调用open之前调用。
- static struct hw_module_methods_t gralloc_module_methods = {
- open: gralloc_device_open
- };
再看一下alloc_device_t的初始化,是在gralloc_device_open函数中
- 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)) {
- 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 = &dev->device.common;
- status = 0;
- } else {
- status = fb_device_open(module, name, device);
- }
- return status;
- }
可以看到,这里把module和device关联起来了
dev->device.common.module =const_cast<hw_module_t*>(module);
并对gralloc设备提供的两个方法进行赋值
dev->device.alloc = gralloc_alloc;
dev->device.free = gralloc_free;
这样,我们就可以调用gralloc提供的另外两个方法了。
最后
以上就是耍酷溪流为你收集整理的HAL学习的全部内容,希望文章能够帮你解决HAL学习所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复