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


原文阅读:
Android Codec2(十六)C2AllocatorGralloc

扫描下方二维码,关注公众号《青山渺渺》阅读音视频开发内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青山渺渺

感谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值