HAL层Buffer可以分为两类:ImageBuffer和CmdBuffer。接下来对系统中ImageBuffer模块分析介绍。
模块结构与组成
图1-1 ImageBuffer静态模型
ImageBufferManager通过注册的方式获取MemPoolBufferManager操作句柄,ImageBuffer通过ImageBufferManage注册的MemPoolBuffer Manager完成相应MemPoolGoup的激活/去活。
从ImageBuffer模型中可以看出ImageBuffer有两种,一种是来自CSL设备的CSLBuffer,一种来自Gralloc的GrallocBuffer。那么这两种类型的ImageBuffer区别:
缓冲区的来源不同,CSL是Hw camera module的CSL内存;Gralloc是Hw Gralloc module的内存。Gralloc是Android图形架构中的一个角色,由此看来Gralloc大概是Hw中连接显示和Camera的内存分配模块。Gralloc分配的内存需要映射到CSL设备后,供Camera使用。
图1-2 Buffer组件关系
MemPoolBuffer中的memPoolBufferManager指向创建该MemPoolBuffer的MemPoolGroup中m_bufferManagerList中创建注册的某个Mgr。MemPoolGroup好比是池子,池中有一个个小池子,MemPoolBuffer相当于池子中的小池子。
图1-3 ImageBuffer管理模块框图
ImageBuffer对外提供管理的示意图。这里先学习CSL类型的Buffer。
模块实现逻辑
核心MemPoolMgr,ImageBufferManager是对MemPoolMgr的封装。
ImageBuffer Manager根据使用场景,分为两种类型:
- CamxBufferManager Camx中创建,一般立即创建
- ChiBufferManager Chi usecase通过BufferManagerOps创建
缓冲池管理器的实现
1.注册缓冲池管理器
创建ImageBufferManager时注册ImageBuffer管理器到MemPoolGroup,没有CSL buffer和Gralloc buffer区分。注册管理后,全局memPoolMgr会对注册管理的MemPoolGroup进行统一的回收管理。
图2-1 注册BufferManager的过程
2.取消缓冲池管理器的注册
图2-2 取消缓冲管理器注册的过程
3.缓冲池管理器监控线程
图2-3 缓冲池管理器监控线程运行原理
4.缓冲池的激活
图2-4 缓冲池激活过程
一个缓冲池组激活的过程实质是一次缓冲池的分配过程。根据MemPoolMgr缓冲池管理器释放完成状态时可以进行下一次的激活,一次buffer分配,即AllocateBuffer。上图缓存分配部分是CSL类型Buffer分配过程的描述,后边会对Gralloc类型缓存分配进行说明。
Gralloc类型缓存的激活:通过Gralloc模块最终调用Hw module实现缓冲区的分配和释放。Gralloc模块以单例模式提供全局模块对象。由于Gralloc模块在Android图形中和BufferQueue比较紧密,这里暂时不做过多介绍,放在图形系统进一步研究学习。
5.缓冲池的去活
图2-5 缓冲池组去活过程
缓冲池组挂在缓冲池管理器上进行管理,去活即不再受缓冲器管理器的管理
缓冲池资源的使用
1.分配缓存
图2-6 从缓冲池获取缓存的过程
从缓冲池获取缓存时,第一次没获取到缓存时(0阶段)会进行二外两次的尝试获取(0', 0''),如果再次尝试获取还是不成功时则真正的获取失败。这里会涉及一个缓存到设备注册的过程,后续会单独介绍。
2.释放缓存
图2-7 释放从缓冲池获取的缓存
可以参考“从缓冲池获取缓存中的圈5:node关联到MemPoolBufferManager”
3.映射缓存到dev
图2-8 缓冲区的映射过程
通过图2-8 缓冲区映射示意图可以看出最终通过CSL(相机服务层)模块完成映射。通常有两种情况需要保留映射关系:Gralloc类型缓存(和缓存使用类型有关,需要通过Gralloc将生产的数据交给图形架构Surface);给UMD准备的CSL类型缓存(即用户空间要访问的)。CSL模块映射具体实现将在CSL模块介绍。通过返回的信息,大概可以知道,CSL UMD映射的应该类似于linux的 fd remap(将文件中的数据通过文件句柄映射到一块内存中),是不是这样?CSL模块整理后确认。
映射规则:
给定缓冲区允许的最大增量映射为4。即一个缓冲区最大映射到4个dev
两种映射:Gralloc Buffer,CSLMapNativeBuffer; CSL Buffer, CSLMapBuffer
CSL映射返回的映射信息和缓存的类型有关,如果Gralloc类型缓存,需要更新CSLBufferInfo类型信息到要映射的缓存结构;对于CSL类型的缓存,如果允许UMD访问,则需要将虚拟地址更新到输入的缓存结构中。
memPoolGroup -> CSLMapNativeBuffer -> CSLMapNativeBufferHW -> CSLMapBufferHW
4.获取buffer info
根据输入的缓冲管理句柄检查要查询的缓冲池组是不是在缓冲池管理器的管理管理池组链表(m_groupList)中,当要查询的缓存所属的缓冲池组将好在缓冲池管理器的管理链表中时,缓冲池组根据输入的缓冲句柄获取具体的MemPoolBuffer info。
模块接口
管理相关接口
- 注册管理
创建并注册一个新的MemPoolGroup到缓冲管理器: MemPoolMgr::RegisterNewMemPoolGroup
将一个已存在MemPoolGroup注册到缓冲管理器: MemPoolMgr::RegisterBufferManager
2.取消注册
注销缓冲管理器对某个MemPoolGroup的管理: MemPoolMgr::UnregisterBufferManager
3.激活
实际是MemPoolGroup分配的触发:MemPoolMgr::ActivateBufferManager
4.去活
实际是手动失效MemPoolMgr管理的缓冲池组,退还到freeList: MemPoolMgr:: DeactivateBufferManager
缓冲池分配回收接口
1.从缓冲池里获取缓冲
MemPoolMgr:: GetBufferFromPool
2.释放缓存,归还到MemPoolGroup
MemPoolMgr::ReleaseBufferToPool
4.映射缓存到设备
MemPoolMgr::MapBufferToDevices
具体怎么用的暂时不了解
5.获取Buffer信息
MemPoolMgr::GetBufferInfo
模块应用
-
Gralloc 类型缓存
-
CSL类型缓存
CSLBufferManager
1.Gralloc类型缓存的应用
2.CSL类型缓存的应用