在上一篇 HWC2On1Adapter 初始化完成后,调用 initWithDevice() 实例化 HwcHal 对象,然后创建高级接口(IComposer),使得调用者能够通过这个接口与硬件进行交互。这里我们就来看一下 HwcHal 和 IComposer 的初始化流程。
一、HWC HAL初始化
1、HwcLoader.h
源码位置:/hardware/interfaces/graphics/composer/2.1/utils/passthrough/include/composer-passthrough/2.1/HwcLoader.h
initWithDevice
namespace detail {
……
// HwcHalImpl implements V2_*::hal::ComposerHal on top of hwcomposer2
template <typename Hal>
class HwcHalImpl : public Hal {public:virtual ~HwcHalImpl() {if (mDevice) {hwc2_close(mDevice);}}……bool initWithDevice(hwc2_device_t* device, bool requireReliablePresentFence) {// 从现在起,我们拥有这个设备mDevice = device;initCapabilities();if (requireReliablePresentFence &&hasCapability(HWC2_CAPABILITY_PRESENT_FENCE_IS_NOT_RELIABLE)) {ALOGE("present fence must be reliable");mDevice->common.close(&mDevice->common);mDevice = nullptr;return false;}if (!initDispatch()) {mDevice->common.close(&mDevice->common);mDevice = nullptr;return false;}return true;}……
} // namespace detailusing HwcHal = detail::HwcHalImpl<hal::ComposerHal>;
HwcHalImpl 本质上就是继承 hal::ComposerHal,也就是说 ComposerHal 持有一个 hw_device_t 结构体,作为真正的操作对象。
调用 initDispatch 为 mDispatch 结构体中所有的函数指针都初始化。
mDispatch
struct {HWC2_PFN_ACCEPT_DISPLAY_CHANGES acceptDisplayChanges;HWC2_PFN_CREATE_LAYER createLayer;HWC2_PFN_CREATE_VIRTUAL_DISPLAY createVirtualDisplay;HWC2_PFN_DESTROY_LAYER destroyLayer;HWC2_PFN_DESTROY_VIRTUAL_DISPLAY destroyVirtualDisplay;HWC2_PFN_DUMP dump;HWC2_PFN_GET_ACTIVE_CONFIG getActiveConfig;HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES getChangedCompositionTypes;HWC2_PFN_GET_CLIENT_TARGET_SUPPORT getClientTargetSupport;HWC2_PFN_GET_COLOR_MODES getColorModes;HWC2_PFN_GET_DISPLAY_ATTRIBUTE getDisplayAttribute;HWC2_PFN_GET_DISPLAY_CONFIGS getDisplayConfigs;HWC2_PFN_GET_DISPLAY_NAME getDisplayName;HWC2_PFN_GET_DISPLAY_REQUESTS getDisplayRequests;HWC2_PFN_GET_DISPLAY_TYPE getDisplayType;HWC2_PFN_GET_DOZE_SUPPORT getDozeSupport;HWC2_PFN_GET_HDR_CAPABILITIES getHdrCapabilities;HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT getMaxVirtualDisplayCount;HWC2_PFN_GET_RELEASE_FENCES getReleaseFences;HWC2_PFN_PRESENT_DISPLAY presentDisplay;HWC2_PFN_REGISTER_CALLBACK registerCallback;HWC2_PFN_SET_ACTIVE_CONFIG setActiveConfig;HWC2_PFN_SET_CLIENT_TARGET setClientTarget;HWC2_PFN_SET_COLOR_MODE setColorMode;HWC2_PFN_SET_COLOR_TRANSFORM setColorTransform;HWC2_PFN_SET_CURSOR_POSITION setCursorPosition;HWC2_PFN_SET_LAYER_BLEND_MODE setLayerBlendMode;HWC2_PFN_SET_LAYER_BUFFER setLayerBuffer;HWC2_PFN_SET_LAYER_COLOR setLayerColor;HWC2_PFN_SET_LAYER_COMPOSITION_TYPE setLayerCompositionType;HWC2_PFN_SET_LAYER_DATASPACE setLayerDataspace;HWC2_PFN_SET_LAYER_DISPLAY_FRAME setLayerDisplayFrame;HWC2_PFN_SET_LAYER_PLANE_ALPHA setLayerPlaneAlpha;HWC2_PFN_SET_LAYER_SIDEBAND_STREAM setLayerSidebandStream;HWC2_PFN_SET_LAYER_SOURCE_CROP setLayerSourceCrop;HWC2_PFN_SET_LAYER_SURFACE_DAMAGE setLayerSurfaceDamage;HWC2_PFN_SET_LAYER_TRANSFORM setLayerTransform;HWC2_PFN_SET_LAYER_VISIBLE_REGION setLayerVisibleRegion;HWC2_PFN_SET_LAYER_Z_ORDER setLayerZOrder;HWC2_PFN_SET_OUTPUT_BUFFER setOutputBuffer;HWC2_PFN_SET_POWER_MODE setPowerMode;HWC2_PFN_SET_VSYNC_ENABLED setVsyncEnabled;HWC2_PFN_VALIDATE_DISPLAY validateDisplay;
} mDispatch = {};
之后所有调用函数都是是通过 mDispatch 调用 hw_device_t 的方法。
二、创建IComposer接口
1、createComposer
源码位置:/hardware/interfaces/graphics/composer/2.1/utils/passthrough/include/composer-passthrough/2.1/HwcLoader.h
// 创建IComposer实例
static IComposer* createComposer(std::unique_ptr<hal::ComposerHal> hal) {return hal::Composer::create(std::move(hal)).release();
}
2、Composer.h
源码位置:/hardware/interfaces/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/Composer.h
static std::unique_ptr<ComposerImpl> create(std::unique_ptr<Hal> hal) {return std::make_unique<ComposerImpl>(std::move(hal));
}
可以看到,这里本质上就是一个 ComposerImpl 持有了 ComposerHal。 接下来结合前两篇文章看一下整个 UML 图。
硬件加载完成后创建了 HAL 实例,又完成了 IComposer 的创建,到这里就可以通过 IComposer 与 HWC 进行交互。 我们来看其中两个比较重要的方法,一个是通过 createClient() 方法创建 ComposerClient,而该函数是在 ComposerHal 中调用。另一个就是通过注册监听 Hal 层实现监听驱动的关键动作。
三、创建ComposerClient
1、HidlComposerHal.cpp
源码位置:/frameworks/native/services/surfaceflinger/DisplayHardware/HidlComposerHal.cpp
HidlComposer::HidlComposer(const std::string& serviceName) : mWriter(kWriterInitialSize) {mComposer = V2_1::IComposer::getService(serviceName);……if (sp<IComposer> composer_2_4 = IComposer::castFrom(mComposer)) {……} else if (sp<V2_3::IComposer> composer_2_3 = V2_3::IComposer::castFrom(mComposer)) {……} else {mComposer->createClient([&](const auto& tmpError, const auto& tmpClient) {if (tmpError != Error::NONE) {return;}mClient = tmpClient;if (sp<V2_2::IComposer> composer_2_2 = V2_2::IComposer::castFrom(mComposer)) {mClient_2_2 = V2_2::IComposerClient::castFrom(mClient);}});}if (mClient == nullptr) {LOG_ALWAYS_FATAL("failed to create composer client");}
}
mComposer 通过 getService 拿到 Hal 层的 IComposer 对象。调用到 ComposerImpl 中的 createClient() 方法。
2、createClient
public:
Return<void> createClient(IComposer::createClient_cb hidl_cb) override {std::unique_lock<std::mutex> lock(mClientMutex);if (!waitForClientDestroyedLocked(lock)) {hidl_cb(Error::NO_RESOURCES, nullptr);return Void();}sp<IComposerClient> client = createClient();if (!client) {hidl_cb(Error::NO_RESOURCES, nullptr);return Void();}mClient = client;hidl_cb(Error::NONE, client);return Void();
}protected:
virtual IComposerClient* createClient() {auto client = ComposerClient::create(mHal.get());if (!client) {return nullptr;}auto clientDestroyed = [this]() { onClientDestroyed(); };client->setOnClientDestroyed(clientDestroyed);return client.release();
}void onClientDestroyed() {std::lock_guard<std::mutex> lock(mClientMutex);mClient.clear();mClientDestroyedCondition.notify_all();
}
这里最终调用了 ComposerClient::create() 方法实例化一个 IComposerClient,并调用相关回调。同时让 Composer 持有一个 mClient 对象,当销毁的时候,会调用 mClient 的 clear 方法,并且唤起阻塞。也就是销毁一个 HWC::Device 的 mClient 对象。
3、ComposerClient.h
源码位置:/hardware/interfaces/graphics/composer/2.1/utils/hal/include/composer-hal/2.1/ComposerClient.h
static std::unique_ptr<ComposerClientImpl> create(Hal* hal) {auto client = std::make_unique<ComposerClientImpl>(hal);return client->init() ? std::move(client) : nullptr;
}using ComposerClient = detail::ComposerClientImpl<IComposerClient, ComposerHal>;
这里实际调用的是 ComposerClient 的实现类 ComposerClientImpl 中的对应方法,接着调用 init() 方法。
bool init() {mResources = createResources();if (!mResources) {ALOGE("failed to create composer resources");return false;}mCommandEngine = createCommandEngine();return true;
}
可以看到 Client 会持有两个对象,一个是 ComposerResources,另一个是ComposerCommandEngine。
- ComposerResources 控制整个 SurfaceFlinger 的 Hal 的资源,如绘制面 Layer、图元等。
- ComposerCommandEngine 处理从 SurfaceFlinger 上层到hal层的一些命令,用来实现一些需要直接通信到驱动的命令。
virtual std::unique_ptr<ComposerResources> createResources() {return ComposerResources::create();
}virtual std::unique_ptr<ComposerCommandEngine> createCommandEngine() {return std::make_unique<ComposerCommandEngine>(mHal, mResources.get());
}
ComposerResources 初始化
源码位置:/hardware/interfaces/graphics/composer/2.1/utils/resources/ComposerResources.cpp
std::unique_ptr<ComposerResources> ComposerResources::create() {auto resources = std::make_unique<ComposerResources>();return resources->init() ? std::move(resources) : nullptr;
}bool ComposerResources::init() {return mImporter.init();
}
可以看到在 ComposerResources 初始化时,调用了 ComposerHandleImporter 的 init() 方法。
bool ComposerHandleImporter::init() {mMapper4 = mapper::V4_0::IMapper::getService();if (mMapper4) {return true;}ALOGI_IF(!mMapper4, "failed to get mapper 4.0 service, falling back to mapper 3.0");mMapper3 = mapper::V3_0::IMapper::getService();if (mMapper3) {return true;}ALOGI_IF(!mMapper3, "failed to get mapper 3.0 service, falling back to mapper 2.0");mMapper2 = mapper::V2_0::IMapper::getService();ALOGE_IF(!mMapper2, "failed to get mapper 2.0 service");return mMapper2 != nullptr;
}
该对象初始化了一个 IMapper 的 Hal 服务,其实该 Hal 服务就是图元申请器。换句话说 Composer 将会通过 ComposerResources 调用 ComposerHandleImporter 控制图元的状态。
ComposerCommandEngine 初始化
ComposerCommandEngine(ComposerHal* hal, ComposerResources* resources) : mHal(hal), mResources(resources) {mWriter = createCommandWriter(kWriterInitialSize);
}
对于 ComposerCommandEngine 这个对象,等到用的时候再去详细分析。这里只要记住这两个比较重要的重要对象即可,后面会和它们打交道。
到这里 ComposerClient 就算创建完成了,也完成了一次与 HWC 的交互流程,对于注册监听的分析我们放到下一篇文章。