Chinaunix首页 | 论坛 | 博客
  • 博客访问: 278024
  • 博文数量: 95
  • 博客积分: 2047
  • 博客等级: 大尉
  • 技术积分: 1022
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-14 16:18
文章分类

全部博文(95)

文章存档

2013年(1)

2011年(94)

我的朋友

分类: 嵌入式

2011-08-27 10:54:55

这几天总是被他事打搅,今天终于看完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的代码。
阅读(1974) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~