这几天总是被他事打搅,今天终于看完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的代码。 |