Android Codec2 CCodec(十六)C2AllocatorGralloc

发布于:2024-10-08 ⋅ 阅读:(147) ⋅ 点赞:(0)

这一篇文章我们一起来瞧瞧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

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

请添加图片描述


网站公告

今日签到

点亮在社区的每一天
去签到