在上一篇 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 detail
using 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 的交互流程,对于注册监听的分析我们放到下一篇文章。