Passthrough - HAL通常是framework进程通过HIDL接口调用,运行在framework层,
<transport>hwbinder</transport> 中标明是直通式还是绑定式
out/target/product/nx563j/vendor/etc/vintf/manifest.xml
XML
<hal format="hidl">
<name>android.hardware.graphics.mapper</name>
<transport arch="32+64">passthrough</transport>
<fqname>@2.1::IMapper/default</fqname>
</hal>
<hal format="hidl">
<name>android.hardware.gnss</name>
<transport>hwbinder</transport>
<fqname>@1.0::IGnss/default</fqname>
</hal>
dequeueBuffer流程
frameworks/native/libs/gui/BufferQueueProducer.cpp
在dequeueBuffer的时候回构造GraphicBuffer对象
cpp
status_t BufferQueueProducer::dequeueBuffer(int* outSlot, sp<android::Fence>* outFence,
uint32_t width, uint32_t height, PixelFormat format,
uint64_t usage, uint64_t* outBufferAge,
FrameEventHistoryDelta* outTimestamps) {
//...
#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_EXTENDEDALLOCATE)
std::vector<GraphicBufferAllocator::AdditionalOptions> tempOptions;
tempOptions.reserve(allocOptions.size());
for (const auto& it : allocOptions) {
tempOptions.emplace_back(it.name.c_str(), it.value);
}
const GraphicBufferAllocator::AllocationRequest allocRequest = {
.importBuffer = true,
.width = width,
.height = height,
.format = format,
.layerCount = BQ_LAYER_COUNT,
.usage = usage,
.requestorName = {mConsumerName.c_str(), mConsumerName.size()},
.extras = std::move(tempOptions),
};
sp<GraphicBuffer> graphicBuffer = new GraphicBuffer(allocRequest);
#else
sp<GraphicBuffer> graphicBuffer =
new GraphicBuffer(width, height, format, BQ_LAYER_COUNT, usage,
{mConsumerName.c_str(), mConsumerName.size()});
#endif
//...
}
frameworks/native/libs/ui/GraphicBuffer.cpp
构造器会调用GraphicBufferMapper::get()
cpp
GraphicBuffer::GraphicBuffer()
: BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),
mInitCheck(NO_ERROR), mId(getUniqueId()), mGenerationNumber(0)
{
width =
height =
stride =
format =
usage_deprecated = 0;
usage = 0;
layerCount = 0;
handle = nullptr;
}
native/libs/ui/include_vndk/ui/GraphicBufferMapper.h
cpp
static inline GraphicBufferMapper& get() { return getInstance(); }
native/libs/ui/Gralloc2.cpp
调用了 mMapper = hardware::graphics::mapper::V2_0::IMapper::getService();
IMapper 这是一个hal接口
cpp
Gralloc2Mapper::Gralloc2Mapper() {
mMapper = hardware::graphics::mapper::V2_0::IMapper::getService();
if (mMapper == nullptr) {
ALOGW("mapper 2.x is not supported");
return;
}
if (mMapper->isRemote()) {
LOG_ALWAYS_FATAL("gralloc-mapper must be in passthrough mode");
}
// IMapper 2.1 is optional
mMapperV2_1 = IMapper::castFrom(mMapper);
}
soong/.intermediates/hardware/interfaces/graphics/mapper/2.0/android.hardware.graphics.mapper@2.0_genc++/gen/android/hardware/graphics/mapper/2.0/MapperAll.cpp
cpp
::android::sp<IMapper> IMapper::getService(const std::string &serviceName, const bool getStub) {
return ::android::hardware::details::getServiceInternal<BpHwMapper>(serviceName, true, getStub);
}
system/libhidl/transport/include/hidl/HidlTransportSupport.h
cpp
template <typename BpType, typename IType = typename BpType::Pure,
typename = std::enable_if_t<std::is_same<i_tag, typename IType::_hidl_tag>::value>,
typename = std::enable_if_t<std::is_same<bphw_tag, typename BpType::_hidl_tag>::value>>
sp<IType> getServiceInternal(const std::string& instance, bool retry, bool getStub) {
using ::android::hidl::base::V1_0::IBase;
sp<IBase> base = getRawServiceInternal(IType::descriptor, instance, retry, getStub);
//...
return IType::castFrom(base);
}
libhidl/transport/ServiceManagement.cpp
这个getTransport就相当于从manifest中查询这个服务是什么模式的
cpp
sp<::android::hidl::base::V1_0::IBase> getRawServiceInternal(const std::string& descriptor,
const std::string& instance,
bool retry, bool getStub) {
// ...
sm = defaultServiceManager1_1();
//...
Return<Transport> transportRet = sm->getTransport(descriptor, instance);
//...
transport = transportRet;
}
const bool vintfHwbinder = (transport == Transport::HWBINDER);
const bool vintfPassthru = (transport == Transport::PASSTHROUGH);
const bool trebleTestingOverride = isTrebleTestingOverride();
const bool allowLegacy = !kEnforceVintfManifest || (trebleTestingOverride && isDebuggable());
const bool vintfLegacy = (transport == Transport::EMPTY) && allowLegacy;
//...
//绑定式代码
...
//直通式代码
if (getStub || vintfPassthru || vintfLegacy) {
const sp<IServiceManager1_0> pm = getPassthroughServiceManager();
if (pm != nullptr) {
sp<IBase> base = pm->get(descriptor, instance).withDefault(nullptr);
if (!getStub || trebleTestingOverride) {
base = wrapPassthrough(base);
}
return base;
}
}
return nullptr;
}
sp<IServiceManager1_0> getPassthroughServiceManager() {
return getPassthroughServiceManager1_1();
}
sp<IServiceManager1_1> getPassthroughServiceManager1_1() {
static sp<PassthroughServiceManager> manager(new PassthroughServiceManager());
return manager;
}
sp<IBase> base = pm->get(descriptor, instance).withDefault(nullptr);
sym 就是 HIDL_FETCH_IMapper 方法,dlopen 的形式调用
name 就是 default 就是 HIDL_FETCH_IMapper 方法的入参
cpp
Return<sp<IBase>> get(const hidl_string& fqName,
const hidl_string& name) override {
sp<IBase> ret = nullptr;
//...
openLibs(fqName, [&](void* handle, const std::string &lib, const std::string &sym) {
IBase* (*generator)(const char* name);
*(void **)(&generator) = dlsym(handle, sym.c_str());
//...
ret = (*generator)(name.c_str());
//...
});
return ret;
}
openLibs
以android.hardware.graphics.mapper@2.0-impl-2.1.so为例
prefix 就是 android.hardware.graphics.mapper@2.0-impl
sym 就是 interfaces/graphics/mapper/2.1/default/passthrough.cpp
HIDL_FETCH_IMapper
最后通过 eachLib 返回回去
cpp
static void openLibs(
const std::string& fqName,
const std::function<bool /* continue */ (void* /* handle */, const std::string& /* lib */,
const std::string& /* sym */)>& eachLib) {
//fqName looks like android.hardware.foo@1.0::IFoo
size_t idx = fqName.find("::");
//... 拼凑名称
const std::string prefix = packageAndVersion + "-impl";
const std::string sym = "HIDL_FETCH_" + ifaceName;
//...
for (const std::string& path : paths) {
std::vector<std::string> libs = findFiles(path, prefix, ".so");
for (const std::string &lib : libs) {
const std::string fullPath = path + lib;
if (kIsRecovery || path == HAL_LIBRARY_PATH_SYSTEM) {
handle = dlopen(fullPath.c_str(), dlMode);
} else {
#if !defined(__ANDROID_RECOVERY__) && defined(__ANDROID__)
handle = android_load_sphal_library(fullPath.c_str(), dlMode);
#endif
}
//...
if (!eachLib(handle, lib, sym)) {
return;
}
}
}
}
findFiles 找一个以入参开头的文件 StartsWith
cpp
static std::vector<std::string> findFiles(const std::string& path, const std::string& prefix,
const std::string& suffix) {
std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(path.c_str()), closedir);
if (!dir) return {};
std::vector<std::string> results{};
dirent* dp;
while ((dp = readdir(dir.get())) != nullptr) {
std::string name = dp->d_name;
if (base::StartsWith(name, prefix) && base::EndsWith(name, suffix)) {
results.push_back(name);
}
}
return results;
}
dlopen找到对应的库后调用代码
interfaces/graphics/mapper/2.1/default/passthrough.cpp
cpp
extern "C" IMapper* HIDL_FETCH_IMapper(const char* /*name*/) {
return GrallocLoader::load();
}
interfaces/graphics/mapper/2.1/utils/passthrough/include/mapper-passthrough/2.1/GrallocLoader.h
cpp
static IMapper* load() {
const hw_module_t* module = loadModule();
if (!module) {
return nullptr;
}
auto hal = createHal(module);
if (!hal) {
return nullptr;
}
return createMapper(std::move(hal));
}
interfaces/graphics/mapper/2.0/utils/passthrough/include/mapper-passthrough/2.0/GrallocLoader.h
cpp
#define GRALLOC_HARDWARE_MODULE_ID "gralloc"
static const hw_module_t* loadModule() {
const hw_module_t* module;
int error = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
if (error) {
ALOGE("failed to get gralloc module");
return nullptr;
}
return module;
}
NX563J:/vendor/lib64/hw # ls | grep gralloc
gralloc.default.so
gralloc.msm8998.so