这一篇我们介绍一下 IComposer 中的另一个比较重要的方法,通过注册监听 Hal 层实现监听驱动的关键动作。
一、注册监听
在前面文章 SurfaceFlinger 的 init() 方法中,我们注册了一个 Callback 到 Hal 层中。最终通过 HIDL 调用到 Hal 层。
1、SurfaceFlinger.cpp
源码位置:/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::init() {ALOGI( "SurfaceFlinger's main thread ready to run. " "Initializing graphics H/W...");Mutex::Autolock _l(mStateLock);……mCompositionEngine->setHwComposer(getFactory().createHWComposer(mHwcServiceName));mCompositionEngine->getHwComposer().setCallback(*this);……ALOGV("Done initializing");
}
这里通过 getHwComposer() 获取对应的 HWComposer 实例,然后调用 HWComposer 的 setCallback() 方法设置监听。
SurfaceFlinger::getHwComposer
HWComposer& SurfaceFlinger::getHwComposer() const {return mCompositionEngine->getHwComposer();
}
mCompositionEngine 参数在 SurfaceFlinger.h 中定义。
SurfaceFlinger.h
源码位置:/frameworks/native/services/surfaceflinger/SurfaceFlinger.h
std::unique_ptr<compositionengine::CompositionEngine> mCompositionEngine;
所以,上面最终调用的是 CompositionEngine 中的 getHwComposer() 方法。
CompositionEngine::getHwComposer
源码位置:/frameworks/native/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp
HWComposer& CompositionEngine::getHwComposer() const {return *mHwComposer.get();
}
这里最终返回的是一个 HwComposer,在 DisplayDevice.h 中定义。
DisplayDevice.h
源码位置:/frameworks/native/services/surfaceflinger/DisplayDevice.h
class HWComposer;
……
HWComposer& mHwComposer;
所以上面最终调用的是 HWComposer 中的 setCallback() 方法。
2、HWComposer.cpp
源码位置:/frameworks/native/services/surfaceflinger/DisplayHardware/HWComposer.cpp
void HWComposer::setCallback(HWC2::ComposerCallback& callback) {loadCapabilities();loadLayerMetadataSupport();if (mRegisteredCallback) {ALOGW("Callback already registered. Ignored extra registration attempt.");return;}mRegisteredCallback = true;mComposer->registerCallback(callback);
}
可以看到这里调用了 Composer 的 registerCallback() 方法,而 HidlComposerHal 继承了 Composer,最终调用的是 HidlComposerHal 的 registerCallback() 方法。
3、HidlComposerHal.cpp
源码位置:/frameworks/native/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp
void HidlComposer::registerCallback(ComposerCallback& callback) {const bool vsyncSwitchingSupported = isSupported(Hwc2::Composer::OptionalFeature::RefreshRateSwitching);registerCallback(sp<ComposerCallbackBridge>::make(callback, vsyncSwitchingSupported));
}void HidlComposer::registerCallback(const sp<IComposerCallback>& callback) {android::hardware::setMinSchedulerPolicy(callback, SCHED_FIFO, 2);auto ret = [&]() {if (mClient_2_4) {return mClient_2_4->registerCallback_2_4(callback);}return mClient->registerCallback(callback);}();if (!ret.isOk()) {ALOGE("failed to register IComposerCallback");}
}
这里的 mClient 为 sp<V2_1::IComposerClient>,所以这里调用到 ComposerClient 的 registerCallback() 方法。
4、ComposerClient.h
源码位置:/hardware/interfaces/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerClient.h
Hal* const mHal;Return<void> registerCallback(const sp<IComposerCallback>& callback) override {// 没有锁,因为我们要求这个函数只被调用一次mHalEventCallback = std::make_unique<HalEventCallback>(mHal, callback, mResources.get());mHal->registerEventCallback(mHalEventCallback.get());return Void();
}
可以看到在这里面会把 IComposerCallback 再一次包裹成 HalEventCallback 对象(后面回回调的时候会分析),才会注册到 mHal,也就是 HwcHalImpl 对象。
5、HwcHal.h
源码位置:/hardware/interfaces/graphics/composer/2.1/utils/passthrough/include/composer-passthrough/2.1/HwcHal.h
void registerEventCallback(hal::ComposerHal::EventCallback* callback) override {mEventCallback = callback;mDispatch.registerCallback(mDevice, HWC2_CALLBACK_HOTPLUG, this,reinterpret_cast<hwc2_function_pointer_t>(hotplugHook));mDispatch.registerCallback(mDevice, HWC2_CALLBACK_REFRESH, this,reinterpret_cast<hwc2_function_pointer_t>(refreshHook));mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC, this,reinterpret_cast<hwc2_function_pointer_t>(vsyncHook));
}
此时将会调用 mDispatch 的 registerCallback 方法。其实这个方法是一个模版方法,其实就是调用 mDevice 的 registerCallback 方法,并且把后面几个作为参数设置进去。从上文就解析到 mDevice 其实是 hw2_device_t 结构体也是 HWC2On1Adapter,那么其实就是调用 HWC2On1Adapter 中的注册方法。
6、HWC2On1Adapter
源码位置:/hardware/interfaces/graphics/composer/2.1/utils/hwc2on1adapter/HWC2On1Adapter.cpp
Error HWC2On1Adapter::registerCallback(Callback descriptor,hwc2_callback_data_t callbackData, hwc2_function_pointer_t pointer) {// 有效性验证if (!isValid(descriptor)) {return Error::BadParameter;}ALOGV("registerCallback(%s, %p, %p)", to_string(descriptor).c_str(), callbackData, pointer);// 获取互斥锁std::unique_lock<std::recursive_timed_mutex> lock(mStateMutex);// 回调注册/注销if (pointer != nullptr) {mCallbacks[descriptor] = {callbackData, pointer};} else {ALOGI("unregisterCallback(%s)", to_string(descriptor).c_str());mCallbacks.erase(descriptor);return Error::None;}bool hasPendingInvalidate = false;std::vector<hwc2_display_t> displayIds;std::vector<std::pair<hwc2_display_t, int64_t>> pendingVsyncs;std::vector<std::pair<hwc2_display_t, int>> pendingHotplugs;// 根据descriptor的类型,收集需要在注册回调后立即处理的待处理事件(如刷新、垂直同步、热插拔)if (descriptor == Callback::Refresh) {hasPendingInvalidate = mHasPendingInvalidate;if (hasPendingInvalidate) {for (auto& displayPair : mDisplays) {displayIds.emplace_back(displayPair.first);}}mHasPendingInvalidate = false;} else if (descriptor == Callback::Vsync) {for (auto pending : mPendingVsyncs) {auto hwc1DisplayId = pending.first;if (mHwc1DisplayMap.count(hwc1DisplayId) == 0) {ALOGE("hwc1Vsync: Couldn't find display for HWC1 id %d", hwc1DisplayId);continue;}auto displayId = mHwc1DisplayMap[hwc1DisplayId];auto timestamp = pending.second;pendingVsyncs.emplace_back(displayId, timestamp);}mPendingVsyncs.clear();} else if (descriptor == Callback::Hotplug) {// 热插拔主显示器pendingHotplugs.emplace_back(mHwc1DisplayMap[HWC_DISPLAY_PRIMARY], static_cast<int32_t>(Connection::Connected));for (auto pending : mPendingHotplugs) {auto hwc1DisplayId = pending.first;if (mHwc1DisplayMap.count(hwc1DisplayId) == 0) {ALOGE("hwc1Hotplug: Couldn't find display for HWC1 id %d", hwc1DisplayId);continue;}auto displayId = mHwc1DisplayMap[hwc1DisplayId];auto connected = pending.second;pendingHotplugs.emplace_back(displayId, connected);}}// 调用未持有状态锁的挂起回调lock.unlock();// 处理回调if (hasPendingInvalidate) {auto refresh = reinterpret_cast<HWC2_PFN_REFRESH>(pointer);for (auto displayId : displayIds) {refresh(callbackData, displayId);}}if (!pendingVsyncs.empty()) {auto vsync = reinterpret_cast<HWC2_PFN_VSYNC>(pointer);for (auto& pendingVsync : pendingVsyncs) {vsync(callbackData, pendingVsync.first, pendingVsync.second);}}if (!pendingHotplugs.empty()) {auto hotplug = reinterpret_cast<HWC2_PFN_HOTPLUG>(pointer);for (auto& pendingHotplug : pendingHotplugs) {hotplug(callbackData, pendingHotplug.first, pendingHotplug.second);}}return Error::None;
}
该函数充当 HWC1 与 HWC2 之间的桥梁,转换事件并管理通过注册的回调向 HWC2 客户端传递这些事件,同时确保了正确的同步机制。
可以看到有 2 个集合,一个标志位在 Hal 判断是否需要回调当顶层。当 mPendingHotplugs 存在还没有被通知的屏幕热插拔消息的时候将会调用 hotplug。当 mPendingVsyncs 存在还没有通知到的屏幕的同步也会调用 vsync。如果需要刷新则会有 hasPendingInvalidate 设置 true 的标志。但是,如果是 SurfaceFlinger 第一次进来就肯定不会有回调,因为此时还没有任何的拿到底层的任何数据。但是会把当前的监听类型和回调的方法指针都保存到 mCallbacks 数组中。
此时就会直接转型为每一个回调到上层,此时就是 HwcHalImpl 中的 refreshHook、hotplugHook 和 vsyncHook。