在 HIDL HAL 中我们聊过 Same-Process HALs,这类 hal 的调用对性能要求高,一般直接链接,不适用跨进程的方式来调用。
在 AIDL HAL 中,与之对应的是 stable-c HAL。stable-c HAL 就是一个对外接口稳定的 so 库。
接着我们来看一个源码中的 stable-c HAL, hardware/interfaces/graphics/mapper
这里只是给出一个框架,具体需要芯片厂商来做实现。
其中最重要的就是 hardware/interfaces/graphics/mapper/stable-c/implutils/include/android/hardware/graphics/mapper/utils/IMapperProvider.h
,其中的 IMapperV5Impl
就是 stable-c HAL 的对外接口:
struct IMapperV5Impl {
static const auto version = AIMAPPER_VERSION_5;
virtual ~IMapperV5Impl() = default;
virtual AIMapper_Error importBuffer(const native_handle_t* _Nonnull handle,
buffer_handle_t _Nullable* _Nonnull outBufferHandle) = 0;
virtual AIMapper_Error freeBuffer(buffer_handle_t _Nonnull buffer) = 0;
virtual AIMapper_Error getTransportSize(buffer_handle_t _Nonnull buffer,
uint32_t* _Nonnull outNumFds,
uint32_t* _Nonnull outNumInts) = 0;
virtual AIMapper_Error lock(buffer_handle_t _Nonnull buffer, uint64_t cpuUsage,
ARect accessRegion, int acquireFence,
void* _Nullable* _Nonnull outData) = 0;
virtual AIMapper_Error unlock(buffer_handle_t _Nonnull buffer, int* _Nonnull releaseFence) = 0;
virtual AIMapper_Error flushLockedBuffer(buffer_handle_t _Nonnull buffer) = 0;
virtual AIMapper_Error rereadLockedBuffer(buffer_handle_t _Nonnull buffer) = 0;
virtual int32_t getMetadata(buffer_handle_t _Nonnull buffer, AIMapper_MetadataType metadataType,
void* _Nullable destBuffer, size_t destBufferSize) = 0;
virtual int32_t getStandardMetadata(buffer_handle_t _Nonnull buffer,
int64_t standardMetadataType, void* _Nullable destBuffer,
size_t destBufferSize) = 0;
virtual AIMapper_Error setMetadata(buffer_handle_t _Nonnull buffer,
AIMapper_MetadataType metadataType,
const void* _Nonnull metadata, size_t metadataSize) = 0;
virtual AIMapper_Error setStandardMetadata(buffer_handle_t _Nonnull buffer,
int64_t standardMetadataType,
const void* _Nonnull metadata,
size_t metadataSize) = 0;
virtual AIMapper_Error listSupportedMetadataTypes(
const AIMapper_MetadataTypeDescription* _Nullable* _Nonnull outDescriptionList,
size_t* _Nonnull outNumberOfDescriptions) = 0;
virtual AIMapper_Error dumpBuffer(buffer_handle_t _Nonnull bufferHandle,
AIMapper_DumpBufferCallback _Nonnull dumpBufferCallback,
void* _Null_unspecified context) = 0;
virtual AIMapper_Error dumpAllBuffers(
AIMapper_BeginDumpBufferCallback _Nonnull beginDumpBufferCallback,
AIMapper_DumpBufferCallback _Nonnull dumpBufferCallback,
void* _Null_unspecified context) = 0;
virtual AIMapper_Error getReservedRegion(buffer_handle_t _Nonnull buffer,
void* _Nullable* _Nonnull outReservedRegion,
uint64_t* _Nonnull outReservedSize) = 0;
};
Google 给出了一个模拟器的实现 /external/minigbm/cros_gralloc/mapper_stablec
:
在 external/minigbm/cros_gralloc/mapper_stablec/Mapper.cpp
中实现了一个 CrosGrallocMapperV5 类继承自 IMapperV5Impl,实现了所有的对外接口。
另外,定义了两个对外的入口符号:
extern "C" uint32_t ANDROID_HAL_MAPPER_VERSION = AIMAPPER_VERSION_5;
extern "C" AIMapper_Error AIMapper_loadIMapper(AIMapper* _Nullable* _Nonnull outImplementation) {
static vendor::mapper::IMapperProvider<CrosGrallocMapperV5> provider;
return provider.load(outImplementation);
}
使用 mapper hal 的程序可以通过 AIMapper_loadIMapper 获取 AIMapper 指针,AIMapper 内部的函数最终都会调用到 CrosGrallocMapperV5 类中的具体实现中。
这里两个符号都使用 extern "C" 修饰,也就是, c 和 cpp 程序都可以使用这两个符号来使用 mmaper 模块。