Gralloc 接口全解析(Android 14+ 最新版本)
前面我有篇博客说了gralloc1_perform这个函数,主要是因为我知道有刷cache这个动作,但是不知道具体在哪里实现。但是gralloc1_perform这个接口是很老版本的gralloc用的。这篇博客概括一下最新版本的Gralloc接口。
Gralloc(Graphics Allocation)主要用于 GPU/CPU 共享图形缓冲区(buffer)。最新的 Gralloc 体系由 Allocator HAL 3.x 和 Mapper HAL 4.x 组成,分别负责 buffer 分配 和 buffer 访问/管理。
1️⃣ Gralloc 最新架构
模块 | 作用 |
---|---|
Allocator HAL 3.x | 负责 buffer 分配 |
Mapper HAL 4.x | 负责 buffer 访问、映射、缓存管理等 |
2️⃣ Allocator HAL 3.x(分配 Buffer)
接口类:android.hardware.graphics.allocator@3.0::IAllocator
🔹 主要接口
函数 | 作用 |
---|---|
IAllocator::allocate() | 申请 buffer |
IAllocator::dumpDebugInfo() | 获取 allocator 相关调试信息 |
🔹 代码示例
sp<IAllocator> allocator = IAllocator::getService();
if (allocator != nullptr) {
hidl_vec<uint8_t> rawHandle;
auto result = allocator->allocate(1, {/*请求参数*/},
[&](auto error, auto buffers) {
if (error == Error::NONE) {
rawHandle = buffers[0];
}
});
}
✅ 作用:向 Gralloc 请求 1 个 buffer 并返回 handle。
3️⃣ Mapper HAL 4.x(管理 Buffer)
接口类:android.hardware.graphics.mapper@4.0::IMapper
🔹 主要接口
函数 | 作用 |
---|---|
IMapper::importBuffer() | 通过 native handle 获取 buffer |
IMapper::freeBuffer() | 释放 buffer |
IMapper::lock() | 申请 CPU 访问 buffer |
IMapper::unlock() | 释放 CPU 访问权限 |
IMapper::flushLockedBuffer() | 刷新 CPU 缓存,确保数据写入内存 |
IMapper::invalidateLockedBuffer() | 失效缓存,确保读取最新数据 |
🔹 代码示例
// 1. 获取 Mapper 服务
sp<IMapper> mapper = IMapper::getService();
// 2. Import Buffer
buffer_handle_t importedHandle = nullptr;
mapper->importBuffer(rawHandle, [&](auto error, auto buffer) {
if (error == Error::NONE) {
importedHandle = buffer;
}
});
// 3. Lock Buffer 进行 CPU 读写
void* data = nullptr;
mapper->lock(importedHandle, GRALLOC_USAGE_SW_WRITE_OFTEN,
{}, [&](auto error, void* addr) {
if (error == Error::NONE) {
data = addr;
}
});
// 4. Unlock Buffer 释放访问权限
mapper->unlock(importedHandle, [&](auto error, auto releaseFence) {
if (error != Error::NONE) {
LOG(ERROR) << "Failed to unlock buffer";
}
});
✅ 作用:
-
importBuffer()
获取 buffer -
lock()
获取 buffer 读写权限 -
unlock()
释放权限
4️⃣ 旧版本 vs. 新版本
功能 | Gralloc 1.0(旧) | Gralloc 3.x/4.x(新) |
---|---|---|
分配 Buffer | gralloc1_perform(GRALLOC1_PERFORM_ALLOCATE, …) | IAllocator::allocate() |
释放 Buffer | gralloc1_perform(GRALLOC1_PERFORM_FREE, …) | IMapper::freeBuffer() |
CPU 读写 | gralloc1_perform(GRALLOC1_PERFORM_LOCK, …) | IMapper::lock() / IMapper::unlock() |
缓存管理 | gralloc1_perform(GRALLOC1_PERFORM_FLUSH_CACHE, …) | IMapper::flushLockedBuffer() / invalidateLockedBuffer() |
5️⃣ 总结
-
Gralloc 3.x/4.x 采用 IAllocator(分配)+ IMapper(管理)架构
-
gralloc1_perform()
已被IMapper::lock/unlock
替代 -
所有 buffer 访问(如 cache flush)必须使用
IMapper::flushLockedBuffer()
Gralloc 最新版本引入了更现代化的 HIDL 接口,相比旧的 gralloc1_perform
方式,更加模块化、安全、可扩展。🚀
如果追一下代码,会发现QtiMapper::flushLockedBuffer最终会调用到:
118 int DmaManager::CleanBuffer(void * /*base*/, unsigned int /*size*/, unsigned int /*offset*/,
119 int /*handle*/, int op, int dma_buf_fd) {
120 ATRACE_CALL();
121 ATRACE_INT("operation id", op);
122
123 struct dma_buf_sync sync;
124 int err = 0;
125
126 switch (op) {
127 case CACHE_CLEAN:
128 sync.flags = DMA_BUF_SYNC_END | DMA_BUF_SYNC_RW;
129 break;
130 case CACHE_INVALIDATE:
131 sync.flags = DMA_BUF_SYNC_START | DMA_BUF_SYNC_RW;
132 break;
133 case CACHE_READ_DONE:
134 sync.flags = DMA_BUF_SYNC_END | DMA_BUF_SYNC_READ;
135 break;
136 default:
137 ALOGE("%s: Invalid operation %d", __FUNCTION__, op);
138 return -1;
139 }
140
141 if (ioctl(dma_buf_fd, INT(DMA_BUF_IOCTL_SYNC), &sync)) {
142 err = -errno;
143 ALOGE("%s: DMA_BUF_IOCTL_SYNC failed with error - %s", __FUNCTION__, strerror(errno));
144 return err;
145 }
146
147 return 0;
148 }
这里就看到具体的ioctl操作了。