必读:
Android 12(S) 图像显示系统 - 开篇
接口定义
源码位置:/hardware/interfaces/graphics/composer/
在源码目录下可以看到4个版本的HIDL Interface定义,最新版本是2.4,也是目前我的测试平台在用的,不同版本使用带有版本号的包名来区分,例如 :package android.hardware.graphics.composer@2.4
各版本中均有相同的接口,并且具有继承关系,新版本继承旧版接口并扩展了新方法。
/frameworks/native/services/surfaceflinger/DisplayHardware/ 中 android::Hwc2::impl::Composer 相当于HIDL的客户端,framework通过impl::Composer中的方法看跨进程和 hwc hal 互动。
各个版本接口的继承关系
Composer HIDL Service
代码位置
/hardware/interfaces/graphics/composer/2.4/default/service.cpp
/hardware/interfaces/graphics/composer/2.4/default/android.hardware.graphics.composer@2.4-service.rc
开机启动时,init进程解析rc文件带起服务进程,在service.cpp的main函数中,注册服务
int main() { ... android::sp<IComposer> composer = HwcLoader::load(); if (composer == nullptr) { return 1; } if (composer->registerAsService() != android::NO_ERROR) { ALOGE("failed to register service"); return 1; } ... }
可以看到其中调用了一个非常重要的方法HwcLoader::load(),看其代码:
[/hardware/interfaces/graphics/composer/2.4/utils/passthrough/include/composer-passthrough/2.4/HwcLoader.h] static IComposer* load() { const hw_module_t* module = loadModule(); if (!module) { return nullptr; } auto hal = createHalWithAdapter(module); if (!hal) { return nullptr; } return createComposer(std::move(hal)).release(); }
再看loadModule的定义,去找HAL library中定义的HAL_MODULE_INFO_SYM结构体变量
[/hardware/interfaces/graphics/composer/2.1/utils/passthrough/include/composer-passthrough/2.1/HwcLoader.h] static const hw_module_t* loadModule() { const hw_module_t* module; int error = hw_get_module(HWC_HARDWARE_MODULE_ID, &module); if (error) { ALOGI("falling back to gralloc module"); error = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module); } if (error) { ALOGE("failed to get hwcomposer or gralloc module"); return nullptr; } return module; }
可以看到基本的调用流程:
开机启动 ==> HwcLoader::load() ==> HwcLoader::loadModule() ==> hw_get_module
hw_get_module就是去打开Vendor厂商实现的HWC HAL模块,这个流程本质上还是旧有的HAL打开方式,只是外包装了一层HIDL。
最终得到一个指向HWC module的hw_module_t指针
再回到HwcLoader::load()方法中,接下来就是 createHalWithAdapter ==> createComposer
先看 createHalWithAdapter 做了哪些工作
[/hardware/interfaces/graphics/composer/2.4/utils/passthrough/include/composer-passthrough/2.4/HwcLoader.h] // create a ComposerHal instance, insert an adapter if necessary static std::unique_ptr<hal::ComposerHal> createHalWithAdapter(const hw_module_t* module) { bool adapted; hwc2_device_t* device = openDeviceWithAdapter(module, &adapted); if (!device) { return nullptr; } auto hal = std::make_unique<HwcHal>(); return hal->initWithDevice(std::move(device), !adapted) ? std::move(hal) : nullptr; }
其中调用了openDeviceWithAdapter去打开 hwc2_device_t
[/hardware/interfaces/graphics/composer/2.1/utils/passthrough/include/composer-passthrough/2.1/HwcLoader.h] // open hwcomposer2 device, install an adapter if necessary static hwc2_device_t* openDeviceWithAdapter(const hw_module_t* module, bool* outAdapted) { if (module->id && std::string(module->id) == GRALLOC_HARDWARE_MODULE_ID) { *outAdapted = true; return adaptGrallocModule(module); } hw_device_t* device; int error = module->methods->open(module, HWC_HARDWARE_COMPOSER, &device); if (error) { ALOGE("failed to open hwcomposer device: %s", strerror(-error)); return nullptr; } int major = (device->version >> 24) & 0xf; if (major != 2) { *outAdapted = true; return adaptHwc1Device(std::move(reinterpret_cast<hwc_composer_device_1*>(device))); } *outAdapted = false; return reinterpret_cast<hwc2_device_t*>(device); }
openDeviceWithAdapter中调用了open方法
hw_device_t* device; int error = module->methods->open(module, HWC_HARDWARE_COMPOSER, &device);
这样就获取到了 hwc2_device
typedef struct hwc2_device { struct hw_device_t common; void (*getCapabilities)(struct hwc2_device* device, uint32_t* outCount, int32_t* /*hwc2_capability_t*/outCapabilities); hwc2_function_pointer_t (*getFunction)(struct hwc2_device* device, int32_t /*hwc2_function_descriptor_t*/descriptor); } hwc2_device_t;
回到createHalWithAdapter中再调用initWithDevice及保存到了HwcHal中的mDevice这个变量中
bool initWithDevice(hwc2_device_t* device, bool requireReliablePresentFence) { // we own the device from this point on mDevice = device; …. }
getFunction函数关联到了 vendor 厂商实现的hwc hal中具体实现,这个函数通过函数描述符来获取对应的函数指针。
initDispatch的作用介绍
initDispatch()来初始化HWC通用的函数指针
2.4 <---2.3<---2.2<---2.1 版本的initDispatch()会被调用到来初始化函数指针
在这里就是把mDispatch函数指针和HWC HAL具体实现的方法一一对应起来
注意一下继承关系:
V2_1
class HwcHalImpl : public Hal
V2_2
class HwcHalImpl : public V2_1::passthrough::detail::HwcHalImpl<Hal>
V2_3
class HwcHalImpl : public V2_2::passthrough::detail::HwcHalImpl<Hal>
V2_4
class HwcHalImpl : public V2_3::passthrough::detail::HwcHalImpl<Hal>
各个版本的HwcHalImpl类中都有定义一个结构体变量mDispatch,这个结构体的成员变量均为函数指针,是以 HWC2_PFN_* 开头的函数指针类型。
struct { HWC2_PFN_ACCEPT_DISPLAY_CHANGES acceptDisplayChanges; HWC2_PFN_CREATE_LAYER createLayer; …… HWC2_PFN_VALIDATE_DISPLAY validateDisplay; } mDispatch = {};
initDispatch通过调用vendor厂商实现的hwc hal中的getFunction方法获取到descriptor对应的函数指针,并保存到mDispatch的成员中
template <typename T> bool initDispatch(hwc2_function_descriptor_t desc, T* outPfn) { auto pfn = mDevice->getFunction(mDevice, desc); if (pfn) { *outPfn = reinterpret_cast<T>(pfn); return true; } else { ALOGE("failed to get hwcomposer2 function %d", desc); return false; } }
简单总结下上述的分析内容
1. 开机后启动了一个名字为android.hardware.graphics.composer@2.4-service的服务进程,用于 framework 和 hwc hal 的通信;
2. 这个composer service启动时,进行了必要的初始化工作,主要就是loadModule和openDevice,在这一过程中获取到hal层实现的函数的指针,
并保存在了mDispatch中
3. 之后运行时,framework 呼叫功能时,本质就是通过mDispatch持有的函数指针调用到 hwc hal 的具体实现
Framework 与 hwc hal通信的流程
直接打印调用栈信息来展示这一流程,以其中的setClientTarget这个方法的调用过程为例:
SurfaceFlinger进程的调用栈信息
11-13 00:47:20.455 224 224 E HwcComposer: stackdump:#00 pc 00086f8f /system/bin/surfaceflinger (android::Hwc2::impl::Composer::setClientTarget(unsigned long long, unsigned int, android::sp<android::GraphicBuffer> const&, int, android::hardware::graphics::common::V1_2::Dataspace, std::__1::vector<android::hardware::graphics::composer::V2_1::IComposerClient::Rect, std::__1::allocator<android::hardware::graphics::composer::V2_1::IComposerClient::Rect> > const&)+182) 11-13 00:47:20.455 224 224 E HwcComposer: stackdump:#01 pc 00096791 /system/bin/surfaceflinger (android::impl::HWComposer::setClientTarget(android::HalDisplayId, unsigned int, android::sp<android::Fence> const&, android::sp<android::GraphicBuffer> const&, android::hardware::graphics::common::V1_2::Dataspace)+408) 11-13 00:47:20.455 224 224 E HwcComposer: stackdump:#02 pc 0008e881 /system/bin/surfaceflinger (android::FramebufferSurface::advanceFrame()+332) 11-13 00:47:20.455 224 224 E HwcComposer: stackdump:#03 pc 00122a55 /system/bin/surfaceflinger (android::compositionengine::impl::RenderSurface::queueBuffer(android::base::unique_fd_impl<android::base::DefaultCloser>)+436) 11-13 00:47:20.455 224 224 E HwcComposer: stackdump:#04 pc 001069ed /system/bin/surfaceflinger (android::compositionengine::impl::Output::finishFrame(android::compositionengine::CompositionRefreshArgs const&)+168) 11-13 00:47:20.455 224 224 E HwcComposer: stackdump:#05 pc 00100c89 /system/bin/surfaceflinger (android::compositionengine::impl::Display::finishFrame(android::compositionengine::CompositionRefreshArgs const&)+76) 11-13 00:47:20.455 224 224 E HwcComposer: stackdump:#06 pc 001054ef /system/bin/surfaceflinger (android::compositionengine::impl::Output::present(android::compositionengine::CompositionRefreshArgs const&)+114) 11-13 00:47:20.455 224 224 E HwcComposer: stackdump:#07 pc 000ff727 /system/bin/surfaceflinger (android::compositionengine::impl::CompositionEngine::present(android::compositionengine::CompositionRefreshArgs&)+146) 11-13 00:47:20.455 224 224 E HwcComposer: stackdump:#08 pc 000d600b /system/bin/surfaceflinger (android::SurfaceFlinger::onMessageRefresh()+1530) 11-13 00:47:20.455 224 224 E HwcComposer: stackdump:#09 pc 000d570d /system/bin/surfaceflinger (android::SurfaceFlinger::onMessageInvalidate(long long, long long)+8784) 11-13 00:47:20.455 224 224 E HwcComposer: stackdump:#10 pc 000b9907 /system/bin/surfaceflinger (android::impl::MessageQueue::Handler::handleMessage(android::Message const&)+94) 11-13 00:47:20.456 224 224 E HwcComposer: stackdump:#11 pc 00010179 /system/lib/libutils.so (android::Looper::pollInner(int)+288) 11-13 00:47:20.456 224 224 E HwcComposer: stackdump:#12 pc 0000ffff /system/lib/libutils.so (android::Looper::pollOnce(int, int*, int*, void**)+62) 11-13 00:47:20.456 224 224 E HwcComposer: stackdump:#13 pc 000b9dd1 /system/bin/surfaceflinger (android::impl::MessageQueue::waitMessage()+56) 11-13 00:47:20.456 224 224 E HwcComposer: stackdump:#14 pc 000cc50d /system/bin/surfaceflinger (android::SurfaceFlinger::run()+6) 11-13 00:47:20.456 224 224 E HwcComposer: stackdump:#15 pc 000ff253 /system/bin/surfaceflinger (main+1182) 11-13 00:47:20.456 224 224 E HwcComposer: stackdump:#16 pc 0003253b /apex/com.android.runtime/lib/bionic/libc.so (__libc_init+54)
HWC HAL端的调用栈信息
11-08 06:04:30.920 339 339 E hwc_display: stackdump:#00 pc 000287cb /vendor/lib/hw/hwcomposer.stark.so (Display::setClientTarget(native_handle const*, int, int, hwc_region)+90) 11-08 06:04:30.920 339 339 E hwc_display: stackdump:#01 pc 00023255 /vendor/lib/hw/hwcomposer.stark.so (hwc_setClientTarget(hwc2_device*, unsigned long long, native_handle const*, int, int, hwc_region)+56) 11-08 06:04:30.920 339 339 E hwc_display: stackdump:#02 pc 00007d93 /vendor/bin/hw/android.hardware.graphics.composer@2.4-service (android::hardware::graphics::composer::V2_1::passthrough::detail::HwcHalImpl<android::hardware::graphics::composer::V2_4::hal::ComposerHal>::setClientTarget(unsigned long long, native_handle const*, int, int, std::__1::vector<hwc_rect, std::__1::allocator<hwc_rect> > const&)+40) 11-08 06:04:30.920 339 339 E hwc_display: stackdump:#03 pc 00010b11 /vendor/bin/hw/android.hardware.graphics.composer@2.4-service (android::hardware::graphics::composer::V2_1::hal::ComposerCommandEngine::executeSetClientTarget(unsigned short)+244) 11-08 06:04:30.920 339 339 E hwc_display: stackdump:#04 pc 0000ed3f /vendor/bin/hw/android.hardware.graphics.composer@2.4-service (android::hardware::graphics::composer::V2_1::hal::ComposerCommandEngine::execute(unsigned int, android::hardware::hidl_vec<android::hardware::hidl_handle> const&, bool*, unsigned int*, android::hardware::hidl_vec<android::hardware::hidl_handle>*)+86) 11-08 06:04:30.920 339 339 E hwc_display: stackdump:#05 pc 0000d0a1 /vendor/bin/hw/android.hardware.graphics.composer@2.4-service (android::hardware::graphics::composer::V2_1::hal::detail::ComposerClientImpl<android::hardware::graphics::composer::V2_3::IComposerClient, android::hardware::graphics::composer::V2_3::hal::ComposerHal>::executeCommands(unsigned int, android::hardware::hidl_vec<android::hardware::hidl_handle> const&, std::__1::function<void (android::hardware::graphics::composer::V2_1::Error, bool, unsigned int, android::hardware::hidl_vec<android::hardware::hidl_handle> const&)>)+84) 11-08 06:04:30.920 339 339 E hwc_display: stackdump:#06 pc 0001df97 /vendor/lib/android.hardware.graphics.composer@2.2.so (android::hardware::graphics::composer::V2_2::BnHwComposerClient::_hidl_executeCommands_2_2(android::hidl::base::V1_0::BnHwBase*, android::hardware::Parcel const&, android::hardware::Parcel*, std::__1::function<void (android::hardware::Parcel&)>)+294) 11-08 06:04:30.920 339 339 E hwc_display: stackdump:#07 pc 0003182f /vendor/lib/android.hardware.graphics.composer@2.4.so (android::hardware::graphics::composer::V2_4::BnHwComposerClient::onTransact(unsigned int, android::hardware::Parcel const&, android::hardware::Parcel*, unsigned int, std::__1::function<void (android::hardware::Parcel&)>)+1198) 11-08 06:04:30.920 339 339 E hwc_display: stackdump:#08 pc 000546d9 /apex/com.android.vndk.v31/lib/libhidlbase.so (android::hardware::BHwBinder::transact(unsigned int, android::hardware::Parcel const&, android::hardware::Parcel*, unsigned int, std::__1::function<void (android::hardware::Parcel&)>)+96) 11-08 06:04:30.920 339 339 E hwc_display: stackdump:#09 pc 000536a7 /apex/com.android.vndk.v31/lib/libhidlbase.so (android::hardware::IPCThreadState::getAndExecuteCommand()+974) 11-08 06:04:30.920 339 339 E hwc_display: stackdump:#10 pc 00053239 /apex/com.android.vndk.v31/lib/libhidlbase.so (android::hardware::IPCThreadState::joinThreadPool(bool)+56) 11-08 06:04:30.920 339 339 E hwc_display: stackdump:#11 pc 000070fb /vendor/bin/hw/android.hardware.graphics.composer@2.4-service (main+270) 11-08 06:04:30.920 339 339 E hwc_display: stackdump:#12 pc 0003253b /apex/com.android.runtime/lib/bionic/libc.so (__libc_init+54)
发起端:
[/frameworks/native/services/surfaceflinger/DisplayHardware/ComposerHal.cpp] Error Composer::setClientTarget(Display display, uint32_t slot, const sp<GraphicBuffer>& target, int acquireFence, Dataspace dataspace, const std::vector<IComposerClient::Rect>& damage) { mWriter.selectDisplay(display); const native_handle_t* handle = nullptr; if (target.get()) { handle = target->getNativeBuffer()->handle; } mWriter.setClientTarget(slot, handle, acquireFence, dataspace, damage); return Error::NONE; }
中转站:
[/hardware/interfaces/graphics/composer/2.1/utils/command-buffer/include/composer-command-buffer/2.1/ComposerCommandBuffer.h] void setClientTargetInternal(...) { beginCommand(IComposerClient::Command::SET_CLIENT_TARGET, length); ... endCommand(); } 跨进程了 [/hardware/interfaces/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerCommandEngine.h] virtual bool executeCommand(IComposerClient::Command command, uint16_t length) { switch (command) { ... case IComposerClient::Command::SET_CLIENT_TARGET: return executeSetClientTarget(length); } } bool executeSetClientTarget(uint16_t length) { ... err = mHal->setClientTarget(mCurrentDisplay, clientTarget, fence, dataspace, damage); ... }
处理终端:
Vendor厂商实现的HAL,具体实现setClientTarget的功能