We have talked about HAL data structures hw_module_t and hw_module_methods_t for the Gralloc module. The last one, hw_device_t, is initialized in the open method of the Gralloc HAL module. Now we can look at the open method of the Gralloc module as follows:
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));
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 = 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;
}
As we can see here, the gralloc_device_open function can be used to initialize two kinds of device, GRALLOC_HARDWARE_GPU0 and GRALLOC_HARDWARE_FB0, according to the name input parameter.
Let's look at the initialization of the GPU0 device first. The output parameter of the open method is the address of the hw_device_t data structure. After the calling applications get an instance of hw_device_t, they can use the hardware device to do their work. In the open method of Gralloc HAL, it allocates the memory for the gralloc_context_t data structure first. After that, it populates its device member variable and assigns the output parameter to the address of the dev->device.common member variable. As we expect, the output is the address of an hw_device_t instance. Let's look at the relationship between gralloc_context_t, alloc_device_t, and hw_device_t:
![](http://images-20200215.ebookreading.net/16/4/4/9781787125360/9781787125360__android-system-programming__9781787125360__assets__image_10_003.png)
As we can see from the preceding diagram, the first field or member variable of gralloc_context_t is device, which is data type alloc_device_t:
struct gralloc_context_t {
alloc_device_t device;
/* our private data here */
};
The following is the definition of the alloc_device_t data structure. It is defined in the gralloc.h file:
typedef struct alloc_device_t {
struct hw_device_t common;
int (*alloc)(struct alloc_device_t* dev,
int w, int h, int format, int usage,
buffer_handle_t* handle, int* stride);
int (*free)(struct alloc_device_t* dev,
buffer_handle_t handle);
void (*dump)(struct alloc_device_t *dev, char *buff, int buff_len);
void* reserved_proc[7];
} alloc_device_t;
We can see that the data type of the first field of alloc_device_t is hw_device_t. This is the technique for simulating inheritance relationships in the C language that we mentioned when we discussed the relationship between private_module_t, gralloc_module_t and hw_module_t.
The alloc and free methods of the Gralloc device are implemented in the gralloc_alloc and gralloc_free functions in the gralloc.cpp file.