这几天总是被他事打搅,今天终于看完Gralloc HAL最重要的gralloc.cpp
Gralloc的最重要的功能应该都体现在本文件中了:为显存分配空间。
先不看该文件的内容,回想一下Framebuffer.cpp中,高通MSM在做硬件blit操作时传入的结构体buffer_handle_t handle。
这个buffer_handle_t可以向前追溯至 native_handle_t。
typedef const native_handle* buffer_handle_t;
typedef native_handle_t native_handle;
typedef struct
{
int version; /* sizeof(native_handle_t) */
int numFds; /* number of file-descriptors at &data[0] */
int numInts; /* number of ints at &data[numFds] */
int data[0]; /* numFds + numInts ints */
} native_handle_t;
更重要的一个结构体是继承native_handle_t的 private_handle_t,系统常将buffer_handle_t和private_handle_t进行转换。
可以说 private_handle_t这个句柄是显示缓冲区的关键,如果想用硬件加速,就需要通过PMEM申请private_handle_t,并将获得的fd存入private_handle_t结构体中,但传参时是将private_handle_t转换为buffer_handle_t的,调用硬件加速时又将buffer_handle_t转换为private_handle_t以获取fd。
1、int gralloc_device_open(const hw_module_t* module, const char* name,
hw_device_t** device)
有两种硬件会调用gralloc
1)gpu0 分配空间 ,调用gralloc_alloc
2)fb0 ,调用fb_device_open
2、static int gralloc_alloc(alloc_device_t* dev,
int w, int h, int format, int usage,
buffer_handle_t* pHandle, int* pStride)
1)判断图像格式,技术bpp和size
2)判断是申请FB还是申请显存空间
FB:gralloc_alloc_framebuffer
显存:gralloc_alloc_buffer
3、static int gralloc_alloc_framebuffer(alloc_device_t* dev,
size_t size, int usage, buffer_handle_t* pHandle)
调用: gralloc_alloc_framebuffer_locked
4、static int gralloc_alloc_framebuffer_locked(alloc_device_t* dev,
size_t size, int usage, buffer_handle_t* pHandle)
1)如果当前没有Framebuffer-->mapFrameBufferLocked(m);
2)如果不支持PAGE_FLIP,通过软件方法分配gralloc_alloc_buffer
3)决定使用双Framebuffer中的哪个作为缓冲地址。
5、最重要的部分,注意用了PMEM就没有用ASHMEM
static int gralloc_alloc_buffer(alloc_device_t* dev,
size_t size, int usage, buffer_handle_t* pHandle);
1)如果系统没用PMEM,直接fd = ashmem_create_region("gralloc-buffer", size);
2)如果有PMEM,init_pmem_area(m);
3)获取本次需要的size,offset = sAllocator.allocate(size);
4)建立PMEM region,struct pmem_region sub = { offset, size };
5)重新打开,fd = open("/dev/pmem", O_RDWR, 0);
6)链接空间,err = ioctl(fd, PMEM_CONNECT, m->pmem_master);
7)make it available to the client process,ioctl(fd, PMEM_MAP, &sub);
8)获取句柄,private_handle_t* hnd = new private_handle_t(fd, size, flags);
6、static int init_pmem_area_locked(private_module_t* m)
1)打开PMEM,open("/dev/pmem", O_RDWR, 0);
2)获取所有空间,ioctl(master_fd, PMEM_GET_TOTAL_SIZE, ®ion)
3)分配这么多空间,sAllocator.setSize(size);
4)mmap,void* base = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, master_fd, 0);
5)m->pmem_master = master_fd;
m->pmem_master_base = base;
7、高通MSM做了啥?
MSM的3D hardware也需要使用特殊的内存分配
主要是给他的GPU写了
static int init_gpu_area_locked(private_module_t* m)
和
static int init_gpu_area(private_module_t* m)
以及相关的初始化话GPU的代码。