当前位置: 首页 > article >正文

Android Codec2 CCodec(十六)C2AllocatorGralloc

这一篇文章我们一起来瞧瞧2D(Graphic) buffer分配器C2AllocatorGralloc是如何工作的。

1、GraphicBuffer

在Android系统中,GraphicBufferAllocator和GraphicBufferMapper是与图形缓冲区(Graphic Buffers)管理相关的重要组件,C2AllocatorGralloc依赖这两个组件进行buffer分配,这一小节我们先看看这两个组件是如何协同工作的。由于笔者不太了解graphic相关的内容,因此在这只能根据自己的理解做一点简单的介绍,顺带看看它们的层级结构与调用流程,如有错误欢迎指出。

GraphicBufferAllocator主要负责图形缓冲区的内存分配,GraphicBufferMapper主要负责将分配好的图形缓冲区映射到虚拟地址空间,使CPU可以直接访问这些缓冲区。

接下来会涉及到GraphicBufferAllocator、GraphicBufferMapper、GrallocMapper(Gralloc5Mapper)、和GrallocAllocator(Gralloc5Allocator)这六个类,相关代码实现位于frameworks/native/libs/ui目录下。

2、GraphicBufferMapper

先来看GraphicBufferMapper的构造函数:

GraphicBufferMapper::GraphicBufferMapper() {
    mMapper = std::make_unique<const Gralloc5Mapper>();
    if (mMapper->isLoaded()) {
        mMapperVersion = Version::GRALLOC_5;
        return;
    }
    mMapper = std::make_unique<const Gralloc4Mapper>();
    if (mMapper->isLoaded()) {
        mMapperVersion = Version::GRALLOC_4;
        return;
    }
    // ...
}

GraphicBufferMapper会尝试由高到低,创建不同版本GrallocMapper,如果调用GrallocMapper的isLoaded方法返回true,说明创建成功。

Gralloc4Mapper是HIDL版本的service,Gralloc5Mapper是AIDL版本的service,接下来以最新的Gralloc5Mapper为例看看创建过程:

static const Gralloc5 &getInstance() {
    static Gralloc5 instance = []() {
        // 1.
        auto allocator = waitForAllocator();
        if (!allocator) {
            return Gralloc5{};
        }
        // 2.
        void *so = loadIMapperLibrary();
        if (!so) {
            return Gralloc5{};
        }
        // 3.
        auto loadIMapper = (AIMapper_loadIMapperFn)dlsym(so, "AIMapper_loadIMapper");
        AIMapper *mapper = nullptr;
        // 4.
        AIMapper_Error error = loadIMapper(&mapper);
        if (error != AIMAPPER_ERROR_NONE) {
            ALOGE("AIMapper_loadIMapper failed %d", error);
            return Gralloc5{};
        }
        return Gralloc5{std::move(allocator), mapper};
    }();
    return instance;
}

Gralloc5Mapper::Gralloc5Mapper() {
    mMapper = getInstance().mapper;
}

Gralloc5Mapper的构造函数会调用静态方法getInstance:

  1. 调用waitForAllocator获取IAllocator服务;
  2. IAllocator服务获取成功后获取IMapper lib的名称,打开lib;
  3. 获取AIMapper_loadIMapper函数指针;
  4. 创建AIMapper对象,将获取的IAllocator服务和AIMapper对象打包为Gralloc5。
static const auto kIAllocatorServiceName = IAllocator::descriptor + std::string("/default");

static std::shared_ptr<IAllocator> waitForAllocator() {
    if (__builtin_available(android 31, *)) {
        if (!AServiceManager_isDeclared(kIAllocatorServiceName.c_str())) {
            return nullptr;
        }
        auto allocator = IAllocator::fromBinder(
                ndk::SpAIBinder(AServiceManager_waitForService(kIAllocatorServiceName.c_str())));
        if (!allocator) {
            ALOGE("AIDL IAllocator declared but failed to get service");
            return nullptr;
        }

        int32_t version = 0;
        if (!allocator->getInterfaceVersion(&version).isOk()) {
            ALOGE("Failed to query interface version");
            return nullptr;
        }
        if (version < kIAllocatorMinimumVersion) {
            return nullptr;
        }
        return allocator;
    } else {
        return nullptr;
    }
}

waitForAllocator其实就是在获取android.hardware.graphics.allocator/default这个服务。

static void *loadIMapperLibrary() {
    static void *imapperLibrary = []() -> void * {
        auto allocator = waitForAllocator();
        std::string mapperSuffix;
        auto status = allocator->getIMapperLibrarySuffix(&mapperSuffix);
        if (!status.isOk()) {
            ALOGE("Failed to get IMapper library suffix");
            return nullptr;
        }

        std::string lib_name = "mapper." + mapperSuffix + ".so";
        void *so = android_load_sphal_library(lib_name.c_str(), RTLD_LOCAL | RTLD_NOW);
        if (!so) {
            ALOGE("Failed to load %s", lib_name.c_str());
        }
        return so;
    }();
    return imapperLibrary;
}

查看了早前的Gralloc4实现,看到除了IAllocator service外,还有一个IMapper service。从loadIMapperLibrary这里大致可以了解到,在Gralloc5中已经移除IMapper service了,会直接通过加载lib获取IMapper对象,lib名为mapper.xxx.so。

3、GraphicBufferAllocator

4、C2AllocatorGralloc

5、C2HandleGralloc

6、C2GraphicAllocation

7、C2AllocationGralloc

关注公众号《青山渺渺》订阅合集阅读完整内容

请添加图片描述


http://www.kler.cn/news/336709.html

相关文章:

  • 241006-Gradio中Chatbot通过CSS自适应调整高度
  • 黑名单与ip禁令是同一个东西吗
  • CSS中的class与id
  • VirtulBOX Ubuntu22安装dpdk23.11
  • 计算机网络——p2p
  • Prometheus监控MySQL主从数据库
  • simple c++ 无锁队列
  • Mybatis测试案例
  • 什么是 Angular 的 @HostBinding 注解
  • VMware Tools 安装和配置
  • Python Kivy库学习路线
  • 如何在国内线上开通国外银行帐户
  • 毕设 基于大数据情感分析的网络舆情分析系统(源码+论文)
  • 5.人员管理模块(以及解决运行Bug)——帝可得管理系统
  • 谱减法和维纳滤波的关系
  • SpringCloud学习记录|day1
  • Cocos_鼠标滚轮放缩地图
  • [运维]6.github 本地powershell登录及设置ssh连接
  • Golang 进阶4—— 网络编程
  • ASK, PSK, FSK, DPSK