从字面就可以看出来Gralloc接口是为了显示内存分配与释放 – Graphics Allocation。
它的主要目的有三个:
Ø 为应用分配显示用内存;
Ø 可以把显示内存在不同进程间进行映射;
Ø 同步
通过加载gralloc抽象层(gralloc.xxx.so),可以打开fb设备(/dev/fb0)和gpu设备(/dev/graphic/),
fb设备用于操作framebuffer,gpu设备负责图形缓冲区的分配和释放。
对于SurfaceFlinger服务端的本地窗口FramebufferNativeWindow将分别打开fb设备和gpu设备,
FramebufferNativeWindow通过gpu设备从Framebuffer中分配图形缓冲区,可用来GPU render。
通过fb设备来分配framebuffer,可以显示经SurfaceFlinger混合后的图像。
是在FrameBufferNativeWindow的构造代码中,可以看到打开fb0设备获取Framebuffer Info,然后使用gralloc为该FrameBufferNativeWindow分配两个或者三个Framebuffer,即双缓冲或者三缓冲。
而对于应用程序端的SurfaceTextureClient本地窗口,其需要的图形缓冲区也是由SurfaceFlinger服务端来分配,应用程序进程只需要将服务端分配的图形缓冲区映射到应用程序的虚拟地址空间,图形缓冲区的映射过程也是由Gralloc模块完成。
gpu设备
Gpu打开过程就是创建并初始化一个gralloc_context_t对象,gpu负责图形buffer的分配和释放。
fb设备
Fb设备打开过程就是创建并初始化一个fb_context_t对象,关于屏幕大小、格式、刷新频率等信息都是通过Framebuffer驱动来获取,最后将Framebuffer映射到SurfaceFlinger进程地址空间,并将映射后的首地址保持到private_module_t的framebuffer->base变量中。
可以认为Gralloc module中有两个设备gpu_alloc_device和fb_device,前者用于分配GPU0使用的内存和FB内存,GPU0内存管理使用ION allocator;后者用于获取分配Framebuffer Info并操作fb。
注意,在Android系统中,在系统帧缓冲区中分配的图形缓冲区是在SurfaceFlinger服务中使用的,
而在内存中分配的图形缓冲区既可以在SurfaceFlinger服务中使用,也可以在其它的应用程序中使用。
当其它的应用程序需要使用图形缓冲区的时候,它们就会请求SurfaceFlinger服务为它们分配。
因此,对于其它的应用程序来说,它们只需要将SurfaceFlinger服务返回来的图形缓冲区映射到自己的进程地址空间来使用就可以了。
下面是分配内存最核心的函数:
static int gralloc_alloc(alloc_device_t* dev,
int w, int h, int format, int usage,
buffer_handle_t* pHandle, int* pStride)
{
if (!pHandle || !pStride)
return -EINVAL;
size_t size, stride;
int align = 4;
int bpp = 0;
switch (format) {
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_RGBX_8888:
case HAL_PIXEL_FORMAT_BGRA_8888:
b