BufferQueue 是 Android 中所有图形处理操作的核心。它的作用很简单:将生成图形数据缓冲区的一方(生产者)连接到接受数据以显示或进一步处理的一方(消费者)。几乎所有在系统中移动图形数据缓冲区的内容都依赖于 BufferQueue。
Android 定义了一个类 BufferQueue,用于创建 BufferQueue、生产者和消费者。该类定义(位于frameworks/native/include/gui/BufferQueue.h)如下:
BufferQueue 定义了一个类 ProxyConsumerListener 用于方便 ConsumerListener 的 IPC,它会把所有对它的调用,都转发给实际的 consumer 对象。
BufferQueue 类只有一个静态成员函数 createBufferQueue() 用于创建 BufferQueue,该函数定义(位于 frameworks/native/libs/gui/BufferQueueCore.cpp)如下:
createBufferQueue()函数基于 IGraphicBufferAlloc 创建 BufferQueueCore,并基于后者创建 BufferQueueProducer 和 BufferQueueConsumer 返回给调用者。Android 图形系统的核心在 BufferQueue,BufferQueue 的核心则在 BufferQueueCore 类,而不是 BufferQueue 类。
图形缓冲区分配器 IGraphicBufferAlloc
BufferQueueConsumer 管理的图形缓冲区均由 BufferQueueProducer 通过 IGraphicBufferAlloc 分配。创建 BufferQueue 时,传入的 allocator 通常为空值,此时 BufferQueueCore 通过如下方式(位于
 frameworks/native/libs/gui/BufferQueueCore.cpp)获得 IGraphicBufferAlloc:
BufferQueueCore 的 IGraphicBufferAlloc 来自于 ComposerService。ComposerService 定义(位于frameworks/native/include/private/gui/ComposerService.h)如下:
ComposerService 类本身仅仅持有到 composer service,如 SurfaceFlinger 的连接,即 ISurfaceComposer。如果远程服务挂掉了,这个类通过 Binder 的 linkToDeath 机制得到通知,并将重新建立连接。
ComposerService 类的成员函数定义(位于 frameworks/native/libs/gui/SurfaceComposerClient.cpp)如下:
实际的 composer service 是 SurfaceFlinger。SurfaceFlinger 中是这样创建 IGraphicBufferAlloc 的(配置使用 HWC2 的情况,位于frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp):
IGraphicBufferAlloc 实际为 GraphicBufferAlloc,该类定义(位于 frameworks/native/include/gui/GraphicBufferAlloc.h)如下:
GraphicBufferAlloc 继承自 BnGraphicBufferAlloc,后者定义(位于 frameworks/native/include/gui/IGraphicBufferAlloc.h)如下:
GraphicBufferAlloc 只有一个成员函数,该函数定义(frameworks/native/libs/gui/GraphicBufferAlloc.cpp)如下:
BufferQueueCore 为 GraphicBuffer 的容器,IGraphicBufferAlloc 仅仅用于创建 GraphicBuffer 对象。但对于实际的图形内存块的管理,还不在 IGraphicBufferAlloc 这一层。
图形缓冲区 GraphicBuffer
GraphicBuffer 类是更底层 操作系统/硬件 层图形内存块的封装,该类的定义如下:
ANativeObjectBase 模板的声明(位于 frameworks/native/include/ui/ANativeObjectBase.h)是这样的:
以此来看,GraphicBuffer 也将继承 ANativeWindowBuffer。ANativeWindowBuffer 定义(位于 system/core/include/system/window.h)如下:
这个结构体描述了更底层 操作系统/硬件 层图形内存块的信息,包括图形内存块的句柄 handle,图像的宽度、高度,像素格式等。图形内存块的句柄类型 buffer_handle_t 为 const native_handle_t* 的别名,native_handle_t 定义(位于 system/core/include/cutils/native_handle.h)如下:
可以看到 GraphicBuffer 类的主要职责主要有三块:
- 主要通过继承自 
ANativeWindowBuffer结构体的成员,来描述图形内存块的信息。 - 分配释放图形内存块。这主要通过 
initSize()/reallocate()/free_handle()等操作完成。 - 分配的图形内存块未必已经映射到应用程序的虚拟地址空间了。应用程序要想像访问普通内存那样访问图形内存块,还需要通过 
lockXXX操作将图形内存块映射到应用程序进程的虚拟地址空间内。应用程序在把图形内存块还回去的时候则需要unlockXXX操作。 
此外 GraphicBuffer 的 mInitCheck 用于记录图形缓冲区的状态;mGenerationNumber 用于记录 generation number;mId 用于标识图形缓冲区,它通过如下方式计算得到:
mID 通过进程的 PID 和一个不断递增的整数计算获得。
GraphicBuffer 依赖于 GraphicBufferAllocator 完成图形内存块的分配和释放,依赖于 GraphicBufferMapper 执行图形内存块的 lock/unlock 操作。
GraphicBuffer 的图形内存块分配和释放操作实现(位于 frameworks/native/libs/ui/GraphicBuffer.cpp)如下:
GraphicBuffer 的图形内存块的 lock/unlock 操作实现(位于 frameworks/native/libs/ui/GraphicBuffer.cpp)如下:
这些操作基本上都是比较直接的委托。
GraphicBufferAllocator 和 GraphicBufferMapper
GraphicBufferAllocator 和 GraphicBufferMapper 则依赖于 Gralloc1::Loader 和
 Gralloc1::Device 完成图形内存的分配释放和 lock / unlock 操作,其中 Gralloc1::Loader 用于加载 HAL 层的 gralloc 模块并创建 Gralloc1::Device,Gralloc1::Device 则用于执行最终的图形内存的分配释放和 lock / unlock 操作。
GraphicBufferAllocator 类定义(位于 frameworks/native/include/ui/GraphicBufferAllocator.h)如下:
GraphicBufferAllocator 主要定义了分配图形内存块的 allocate() 和释放图形内存块的 free() 两个函数,这两个函数的实现(位于 frameworks/native/libs/ui/GraphicBufferAllocator.cpp)如下:
GraphicBufferAllocator 分配图形内存块时,步骤如下:
- 通过 
Gralloc1::Device创建Gralloc1::Descriptor,并为其设置要分配的图形内存块的规格,包括图像的长和宽,图像的像素格式,图形内存块的使用场景,其中图形内存块的使用场景参数主要用于性能优化。 - 以 
Gralloc1::Descriptor、图形内存块的标识 ID,和图形内存块句柄的指针作为参数,通过Gralloc1::Device的allocate()分配图形内存块,分配的结果通过图形内存块句柄的指针返回。 - 分配完成之后,可以通过
Gralloc1::Device图形内存块的步进,即单行像素数据占用的内存字节数。底层可能为了性能优化,内存对齐等,分配的内存块可能大于保存实际图像所需要的大小。 - 对分配结果做记录。
GraphicBufferAllocator维护一个图形内存块句柄到图形内存块规格的映射。 
GraphicBufferAllocator 释放图形内存块时的步骤则基本相反:
- 通过 
Gralloc1::Device释放图形内存块句柄。 - 移除分配记录。
 
GraphicBufferMapper 类提供了对图形内存块的 lock / unlock 操作。该类定义(位于 frameworks/native/include/ui/GraphicBufferMapper.h)如下:
GraphicBufferMapper 通过 Gralloc1::Device 提供对图形内存块的 lock / unlock 操作,这些操作的定义(位于 frameworks/native/libs/ui/GraphicBufferMapper.cpp)如下:
lock 时,需要以 Rect 的形式给 GraphicBufferMapper 传入 lock 的区域,这个区域会被做一个转换。GraphicBufferMapper 通过 Gralloc1::Device 执行 lock 操作。并将 lock 的结果,也就是映射到应用程序进程的虚拟地址空间的图形内存块的地址通过传入的 vaddr 返回给调用者。
像素数据格式有 RGB 和 YUV 之分,在 lock YUV 图形内存块时,如果设备支持 GRALLOC1_CAPABILITY_ON_ADAPTER,会直接通过 Gralloc1::Device 完成操作;否则,通过 Gralloc1::Device 的 lockFlex() 完成操作。
这里的 fence 是什么,用来做什么的?
打赏
Done.
Android OpenGL 图形系统分析系列文章
在 Android 中使用 OpenGL
Android 图形驱动初始化
EGL Context 创建
Android 图形系统之图形缓冲区分配
Android 图形系统之gralloc