Android 图形系统之五:Gralloc

Gralloc (Graphics Allocator) 是 Android 系统中的关键组件之一,用于管理图形缓冲区的分配、映射以及处理。在 Android 的图形架构中,Gralloc 充当了 HAL (Hardware Abstraction Layer) 的一部分,为系统和硬件提供了通用的接口,使应用程序能够高效地处理图形数据。

Gralloc 的主要功能

Gralloc 的功能可以划分为以下几个核心部分:

1. 图形缓冲区分配

  • 目标:为应用程序或系统组件分配物理内存,用于存储显示图形数据。
  • 细节 :缓冲区的分配依据 宽度、高度、像素格式使用场景 (Usage Flags)。显存分配通常由底层 GPU 或特定硬件模块管理。

2. 内存映射

  • 目标:通过映射将物理内存的缓冲区暴露给用户态程序。
  • 细节:映射操作将内存映射到调用进程的虚拟地址空间。支持映射为 CPU 可访问的地址(用户态程序可直接操作数据)。

3. 跨进程共享

  • 目标:缓冲区能在不同进程间高效传递。
  • 细节:Gralloc 使用文件描述符 (FD) 作为缓冲区的共享句柄。通过 binder 或其他机制,FD 可在生产者和消费者之间传递,无需拷贝数据。

4. 缓冲区属性管理

  • 目标:为缓冲区附加元数据,描述缓冲区的用途和限制。
  • 细节 :包括 像素格式 (RGB、YUV 等)、宽高尺寸使用标志(Usage Flags)等。这些属性会影响底层驱动分配显存的策略。

Gralloc 的架构设计

Gralloc 的架构可以分为以下几个层次:

1. 高层:应用程序接口

  • 上层应用通常通过图形库(如 OpenGL ES、Vulkan)或 Android 提供的 UI 组件(如 SurfaceView、TextureView)使用 Gralloc。
  • 示例:OpenGL ES 使用 GPU 渲染后,需要通过 Gralloc 分配的缓冲区将结果共享到显示层。视频解码时,MediaCodec 使用 Gralloc 分配的缓冲区存储解码后的帧。

2. 中间层:Framework 和 HAL

  • Gralloc HAL提供抽象接口,屏蔽硬件细节,支持多种硬件实现。HAL 的接口通过 allocator 和 mapper 提供主要功能:IGraphicBufferAllocator:缓冲区分配接口。IGraphicBufferMapper:缓冲区映射、属性管理和释放接口。HAL 的实现位于 /hardware/interfaces/graphics/。
  • BufferQueue****BufferQueue 是 Android 图形堆栈的核心组件,管理生产者(Producer)和消费者(Consumer)之间的缓冲区流转。生产者使用 Gralloc 分配缓冲区后,交由消费者处理。BufferQueue 通过 Binder IPC 支持跨进程通信。

3. 底层:驱动与硬件

  • Gralloc 的底层实现依赖硬件供应商提供的驱动支持:显存分配:显存通常由 GPU 驱动分配。DMA 支持:某些硬件支持通过 DMA 直接访问内存。Cache 操作:确保 CPU 和 GPU 对缓冲区的访问保持一致。
  • 映射内存管理内存映射需要确保多进程、多设备的一致性,通常通过内核接口(如 mmap)实现。

Gralloc 的关键组件

1. GraphicBuffer
  • 它是 Android Framework 中用于表示图形缓冲区的核心类,封装了分配、引用和访问缓冲区的功能。
cpp 复制代码
sp buffer = new GraphicBuffer(width, height, format, usage);
2. BufferQueue
  • BufferQueue 是 Android 图形堆栈的核心组件之一,负责管理生产者(Producer)和消费者(Consumer)之间的缓冲区传递。
3. Buffer 分配策略

Gralloc 的分配通常基于以下参数:

  • 大小(宽度和高度)
  • 格式(如 RGB、YUV)
  • 用途(Usage Flags,例如 CPU/GPU 读取或写入)

示例 Usage Flags

  • GRALLOC_USAGE_SW_READ_OFTEN:缓冲区需要频繁被软件读取。
  • GRALLOC_USAGE_HW_TEXTURE:缓冲区用作 GPU 纹理。

数据流分析

以应用程序绘制一帧图像到屏幕为例,Gralloc 的典型数据流如下:

  1. 分配缓冲区
    • 应用通过 SurfaceFlinger 或其他接口请求分配图形缓冲区。
    • SurfaceFlinger 调用 Gralloc HAL 完成分配。
    • 分配的缓冲区封装为 GraphicBuffer。
  2. 写入缓冲区
    • 生产者(如 GPU)通过 OpenGL/Vulkan API 渲染到缓冲区。
    • Gralloc 确保缓冲区内存可被写入。
  3. 共享缓冲区
  • 渲染完成后,缓冲区通过 BufferQueue 提供给消费者。
  • 消费者可以是显示系统(如 SurfaceFlinger)或其他应用程序。
  1. 释放缓冲区
    • 使用完成后,缓冲区由 Gralloc HAL 释放,回收资源。

Gralloc 的具体实现

1. Gralloc HAL 接口

接口定义

Gralloc HAL 主要接口位于 /hardware/interfaces/graphics/allocator/hardware/interfaces/graphics/mapper 中,定义如下:

  • IGraphicBufferAllocator:分配缓冲区
cpp 复制代码
// allocator.hal
virtual Error allocate(
    uint32_t width, uint32_t height, PixelFormat format,
    uint64_t usage, uint32_t stride, buffer_handle_t* handle) = 0;
  • IGraphicBufferMapper:映射和管理缓冲区
cpp 复制代码
// mapper.hal
virtual Error lock(
    buffer_handle_t buffer, uint64_t usage,
    const Rect& accessRegion, void** outData) = 0;

virtual Error unlock(buffer_handle_t buffer) = 0;

2. GraphicBuffer 类

GraphicBuffer 是 Android Framework 层对 Gralloc 分配的缓冲区的封装,定义在 /frameworks/native/libs/ui/GraphicBuffer.h

构造函数示例

cpp 复制代码
GraphicBuffer::GraphicBuffer(
    uint32_t width, uint32_t height, PixelFormat format, uint32_t usage)
{
    sp allocator = GraphicBufferAllocator::get();
    allocator->allocate(width, height, format, usage, &mHandle, &mStride);
}

代码示例

以下是使用 Gralloc HAL 分配缓冲区的代码示例:

cpp 复制代码
#include 
#include 

const hw_module_t* module;
gralloc_module_t* gralloc;
buffer_handle_t buffer;
int stride;
void* mappedData;

// 初始化 Gralloc 模块
if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) {
    gralloc = reinterpret_cast(module);

    // 分配缓冲区
    gralloc->alloc(gralloc, 1920, 1080, HAL_PIXEL_FORMAT_RGBA_8888,
                   GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN,
                   &buffer, &stride);

    // 映射缓冲区
    gralloc->lock(gralloc, buffer, GRALLOC_USAGE_SW_WRITE_OFTEN, 0, 0, 1920, 1080, &mappedData);

    // 操作缓冲区数据
    memset(mappedData, 0, 1920 * 1080 * 4); // 清除为黑色

    // 取消映射缓冲区
    gralloc->unlock(gralloc, buffer);

    // 释放缓冲区
    gralloc->free(gralloc, buffer);
}

Android 11 及后续版本的变化

  1. Allocator 3.x 和 Mapper 4.x
    • 新版本通过 AIDL/HIDL 提供更统一的分配和管理接口。
    • 增强了跨设备的兼容性。
  2. GPU 缓存一致性优化
    • 增加支持 CPU/GPU 混合访问场景的优化,减少同步开销。

相关资料

相关推荐
C4rpeDime1 小时前
自建MD5解密平台-续
android
鲤籽鲲3 小时前
C# Random 随机数 全面解析
android·java·c#
m0_548514777 小时前
2024.12.10——攻防世界Web_php_include
android·前端·php
凤邪摩羯7 小时前
Android-性能优化-03-启动优化-启动耗时
android
凤邪摩羯7 小时前
Android-性能优化-02-内存优化-LeakCanary原理解析
android
喀什酱豆腐8 小时前
Handle
android
m0_748232929 小时前
Android Https和WebView
android·网络协议·https
m0_748251729 小时前
Android webview 打开本地H5项目(Cocos游戏以及Unity游戏)
android·游戏·unity
m0_7482546611 小时前
go官方日志库带色彩格式化
android·开发语言·golang
zhangphil11 小时前
Android使用PorterDuffXfermode模式PorterDuff.Mode.SRC_OUT橡皮擦实现“刮刮乐”效果,Kotlin(2)
android·kotlin