Android P 显示流程(一)---Display设备初始化过程分析

SurfaceFlinger

SurfaceFlinger在Android中是显示的核心部分,所以我们今天从SurfaceFlinger开始来研究。

SurfaceFlinger的启动

SurfaceFlinger的启动要从main_surfaceflinger.cpp开始看:

int main(int, char**){
	...
	//启动 Hal层的IAllocator : hardware::graphics::allocator::V2.0::IAllocator
	startGraphicsAllocatorService();
	...
	//instantiate surfaceflinger
	sp<SurfaceFlinger> flinger = new SurfaceFlinger();
	//initialize before clients can connect
	flinger->init();
	//publish surface flinger
	sp<IServiceManager> sm(defaultServiceManager());
	sm->addService(String16(SrufaceFlinger::getServiceName()), flinger, false, 
		IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);
	//启动DisplayService
	startDisplayService();
	//run surface flinger in this thread
	flinger->run();
}

重点来看SurfaceFlinger实例化,以及init(), run()…

void SurfaceFlinger::init(){
	...
	//初始化mBE 即 SurfaceFlingerBE
	getBE().mRenderEngine = RE::impl::RenderEngine::create(HAL_PIXEL_FORMAT_RGBA_8888, hasWideColorDisplay? RE::RenderEngine::WIDE_COLOR_SUPPORT:0);
	getBE().mHwc.reset(new HWComposer(std::make_unique<Hwc2::impl::Composer>(getBe().mHwcServiceName)));
	//注册HAL事件上报的回调
	getBE().mHwc->registerCallback(this, getBE().mComposerSequenceId);
	//处理HAL层上报的事件回调
	processDisplayHotplugEventsLocked();
	getBE().mRenderEngine->primeCache();
	//初始化Displays
	initializeDisplays();
}

void SurfaceFlinger::run(){
	do{
		waitForEvent();
	}while(true);
}

init中有一部分是用来初始化SurfaceFlingerBE中的属性变量。主要是将SurfaceFlinger与Hal层的Composer连接起来。getBE()中的mHwc 就可以关联到HWComposer。
上面init()里主要有三步,第一步是注册回调,第二步为回调事件处理,第三步为显示的初始化。因为SurfaceFlinger启动时,kernel里的DRM的显示屏一般已经初始化好了,然后通过onHotPlug事件报上来了,这里再来获取配置相关参数。

注册HAL层事件回调

HWComposer->registerCallback(this, getBE().mComposerSequenceId)---->
HWC2::Device->registerCallback(callback, sequenceId)---->
HWC2::impl::Composer->registerCallback(new ComposerCallbackBridge(callback, sequenceId))---->
IComposerClient->registerCallback(callback)---->
HwcHalImpl->registerEventCallback(make_unique(callback, mResources.get())---->
mDispatch.registerCallback(mDevice, HWC2_CALLBACK_HOTPLUG, this,reinterpret_cast<hwc2_function_pointer_t>(hotplugHook))---->
HWC2On1Adapter::registerCallbackHook(mDevice, HWC2_CALLBACK_HOTPLUG, this,reinterpret_cast<hwc2_function_pointer_t>(hotplugHook)) ---->
HWC2On1Adapter::registerCallback(HWC2_CALLBACK_HOTPLUG,
hwc2_callback_data_t callbackData, reinterpret_cast<hwc2_function_pointer_t>(hotplugHook))
以上为完整的registerCallback的调用链。

Error HWC2On1Adapter::registerCallback(Callback descriptor,
        hwc2_callback_data_t callbackData, hwc2_function_pointer_t pointer)
{
	...
	 std::vector<std::pair<hwc2_display_t, int>> pendingHotplugs;
	 } else if (descriptor == Callback::Hotplug) {
        // Hotplug the primary display
        pendingHotplugs.emplace_back(mHwc1DisplayMap[HWC_DISPLAY_PRIMARY],
                static_cast<int32_t>(Connection::Connected));
		for (auto pending : mPendingHotplugs) {
            auto hwc1DisplayId = pending.first;
            ...
            auto displayId = mHwc1DisplayMap[hwc1DisplayId];
            auto connected = pending.second;
            pendingHotplugs.emplace_back(displayId, connected);
        }
        auto hotplug = reinterpret_cast<HWC2_PFN_HOTPLUG>(pointer);
        for (auto& pendingHotplug : pendingHotplugs) {
            hotplug(callbackData, pendingHotplug.first, pendingHotplug.second);
        }
    }

显示器插入事件回调分析

从最后的HWC2On1Adapter.registerCallback开始分析,先把HWC_DISPLAY_PRIMARY的connected事件加入到pendingHotplugs集合中,确认有一个显示设备插入事件触发,保证后面不管有没有真正的显示设备插入,surfaceFlinger都能正常初始化下去,然后再把之前的kernel上报上来的display的plug事件加入集合中,最后遍历出所有事件,调用hotplug调用,hotplug就上registerCallback里调用的hotplugHook, 下面又是一系列的回调链:

HwcHalImpl::hotplugHook ---->
HWC2On1Adapter::hwc1Hotplug(display, connected) ---->
ComposerHal->mEventCallback->onHotplug(display, connected) ---->
ComposerClientImpl::HalEventCallback::onHotplug(display, connected) ---->
(…/2.1/ComposerClient.h) IComposerCallback->onHotplug(display, connected) ---->
(…/DisplayHardware/HWC2.cpp)ComposerCallback->onHotplugReceived(mSequenceId, display, connection) ---->
(surfaceflinger/SurfaceFlinger.cpp) SurfaceFlinger::onHotplugReceived(…){}
(HWComposer.cpp) HWComposer::onHotplug(…)
那来看看SurfaceFlinger::onHotplugReceived的函数:

void SurfaceFlinger::onHotplugReceived(int32_t sequenceId, hwc2_display_t display, HWC2::Connection connection) {
	...
	mPendingHotplugEvents.emplace_back(HotplugEvent{display, connection});
	processDisplayHotplugEventsLocked();
	...
}
void SurfaceFlinger::processDisplayHotplugEventsLocked() {
	...
	getBE().mHwc->onHotplug(event.display, displayType, event.connection);
        if (event.connection == HWC2::Connection::Connected) {
            if (!mBuiltinDisplays[displayType].get()) {
                ALOGV("Creating built in display %d", displayType);
                mBuiltinDisplays[displayType] = new BBinder();
                // All non-virtual displays are currently considered secure.
                DisplayDeviceState info(displayType, true);
                info.displayName = displayType == DisplayDevice::DISPLAY_PRIMARY ?
                        "Built-in Screen" : "External Screen";
                mCurrentState.displays.add(mBuiltinDisplays[displayType], info);
                mInterceptor->saveDisplayCreation(info);
            }
        } else {
            ssize_t idx = mCurrentState.displays.indexOfKey(mBuiltinDisplays[displayType]);
            if (idx >= 0) {
                const DisplayDeviceState& info(mCurrentState.displays.valueAt(idx));
                mInterceptor->saveDisplayDeletion(info.displayId);
                mCurrentState.displays.removeItemsAt(idx);
            }
            mBuiltinDisplays[displayType].clear();
        }
}	

在这里就将上报来的显示状态设置到mCurrentState里了,同时调用到了HWComposer.onHotplug里。

void HWComposer::onHotplug(hwc2_display_t displayId, int32_t displayType,
                           HWC2::Connection connection) {
	...
	mHwcDevice->onHotplug(displayId, connection);
	...
}
void Device::onHotplug(hwc2_display_t displayId, Connection connection) {
	...
	 if (connection == Connection::Connected) {
	 	auto newDisplay = std::make_unique<Display>(
                *mComposer.get(), mCapabilities, displayId, displayType);
        newDisplay->setConnected(true);
        mDisplays.emplace(displayId, std::move(newDisplay));
      } else if (connection == Connection::Disconnected) {
      	auto display = getDisplayById(displayId);
        if (display) {
            display->setConnected(false);
        } 
      }
	...
}

通过调用HWComposer里的onHotplug,就增加了一个Display到mDsiplays里,同时将connected状态设置为True, 在这里就将第一个显示器的插入事件给分析完了,因为上面对于各类的关系调用及回调涉及的类很多,下面通过分析initialzeDisys方法来详细说明其调用或继承关系。

初始化显示

(ComposerHal.cpp 定义了HWC2::impl::Composer)
我们再回到SurfaceFlinger的init()函数,registerCallback之后就是initializeDisplays() 初始化Displays了。
关于SurfaceFlinger::run()就很简单了,就是一直轮询等待Event事件。
重点来看看initializeDisplays(), 它其实调用的是surfaceflinger->onInitializeDisplays(), 这个也会先增加默认的display,然后调用 setPowerModeInternal(getDisplayDevice(mBuiltinDisplays[DISPLAY_PRIMARY]), HWC_POWER_MODE_NORMAL, false );

void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& hw, int mode, bool stateLockHeld){
	int32_t type = hw->getDisplayType();
	int currentMode = hw->getPowerMode();
	if(mode == currentMode)
		return;
	hw->setPowerMode(mode);
	...
	getHwComposer().setPowerMode(type, mode);
	....
}
HWComposer& getComposer() const{return *getBE().mHwc}

这下面就会出现一个调用链条:getHwcComposer()->setPowerMode(type,mode) ----> HWComposer::setPowerMode(type, mode) ----> auto& hwcDisplay = mDisplayData[type].hwcDisplay; hwcDisplay-> setPowerMode(mode)
这个hwcDisplay 实现是在HWC2.cpp里实现的Display. 即调用的是mComposer.setPowerMode(mId, intMode); 这里的mComposer是指 android::Hwc2::Composer mComposer, 也就是ComposerHal.cpp 里实现的Composer类。

Composer::setPowerMode(Display display, IComposerClient::PowerMode mode){
	mClient->setPowerMode(display, mode);
}
sp<V2_1::IComposerClient> mClient;
cp<V2_1::IComposer> mComposer;
Composer::Composer(string& serviceName){
	mComposer = V2.1::IComposer::getService(serviceName);
	mComposer->createClient([&](const auto& tmpError, const auto& tmpClient{
		if(tmpError == Error::NONE)
			mClient = tmpClient;
	}))
}

从代码里可以看到,mClient是mComposer根据调用createClient(),mClient 和 mComposer根据HAL层里HIDL的对象。
从这里开始,我们需要转到HAL层里撸代码了,在这里我们以qcom的msm8994的libcomposer为例来分析:

template <typename Interface, typename Hal>
class ComposerImpl : public Interface {
    virtual IComposerClient* createClient() {
        auto client = ComposerClient::create(mHal.get());
        ...
    }
}
using Composer = detail::ComposerImpl<IComposer, ComposerHal>;

template <typename Interface, typename Hal>
class ComposerClientImpl : public Interface {
   public:
    static std::unique_ptr<ComposerClientImpl> create(Hal* hal) {
        auto client = std::make_unique<ComposerClientImpl>(hal);
        return client->init() ? std::move(client) : nullptr;
    }
    Return<Error> setPowerMode(Display display, IComposerClient::PowerMode mode) override {
        Error err = mHal->setPowerMode(display, mode);
        return err;
    }    
}
using ComposerClient = detail::ComposerClientImpl<IComposerClient, ComposerHal>;

Composer接口是由ComposerImpl类来实现的,IComposerClient接口是由ComposerClientImpl来实现的。实际上setPowerMode就会调用ComposerClientImpl->setPowerMode(Display display, IComposerClient::mode) 调用链是 —> ComposerHal->setPowerMode(),HwcHalImpl是继承ComposeHal类来的,也就调用到了HwcHalImpl->setPowerMode(…)

template <typename hal>
class HwcHalImpl:public Hal{
    Error setPowerMode(Display display, IComposerClient::PowerMode mode) override {
        int32_t err = mDispatch.setPowerMode(mDevice, display, static_cast<int32_t>(mode));
    }
	struct {
	...
	 HWC2_PFN_SET_POWER_MODE setPowerMode;
	 ...
	 }mDispatch = {};
    template <typename T>
    bool initDispatch(hwc2_function_descriptor_t desc, T* outPfn) {	 
    	//mDevice实际上是HWC2On1Adapter的实例对象,后续有分析如何关联到HWC2On1Adapter
        auto pfn = mDevice->getFunction(mDevice, desc);
        ...
        *outPfn = reinterpret_cast<T>(pfn);
        ...
    } 
    virtual bool initDispatch() {
    ...
    initDispatch(HWC2_FUNCTION_SET_POWER_MODE, &mDispatch.setPowerMode)
    ...   
}
using HwcHal = detail::HwcHalImpl<hal::ComposerHal>;

调用到了mDispatch.setPowerMode, mDispatch也就是一个包括很多方法句柄的结构体,而initDsipatch就将方法描述符与实际方法映射对应了,将当用setPowerMode方法,就需要mDevice 通过getFunction方法获取实际的方法。那mDevice是指哪个类了,其际上mDevice就是HWC2On1Adapter
现在看到调用与HWC2On1Adapter关联起来,看Composer是怎么关联到HWC2On1Adapter上的呢,这就要从hwcomposer初始化开始看:
因为IComposer是passthrough直通模式,上面调用Composer的HIDL接口时,会调用到HIDL_FETCH_IComposer函数,

extern "C" IComposer* HIDL_FETCH_IComposer(const char* /* name */) {
    return HwcLoader::load();
}
static IComposer* load() {
	//加载Hal的so库
    const hw_module_t* module = loadModule();
    ...
	auto hal = createHalWithAdapter(module);
	...
}
static const hw_module_t* loadModule() {
    const hw_module_t* module;
    //加载/vendor/lib64/hw/hwcomposer.xxx.so
    int error = hw_get_module(HWC_HARDWARE_MODULE_ID, &module);
    ...
    return module;
}
static std::unique_ptr<hal::ComposerHal> createHalWithAdapter(const hw_module_t* module) {
    bool adapted;
    hwc2_device_t* device = openDeviceWithAdapter(module, &adapted);
    auto hal = std::make_unique<HwcHal>();
    return hal->initWithDevice(std::move(device), !adapted) ? std::move(hal) : nullptr;
}
static hwc2_device_t* openDeviceWithAdapter(const hw_module_t* module, bool* outAdapted) {
    hw_device_t* device;
    int error = module->methods->open(module, HWC_HARDWARE_COMPOSER, &device);
	....
    return adaptHwc1Device(std::move(reinterpret_cast<hwc_composer_device_1*>(device)));
}
static hwc2_device_t* adaptHwc1Device(hwc_composer_device_1* device) {
    ...
    return new HWC2On1Adapter(device);
}

根据上面的完整的调用链,可以看到初始化得到的hwc2_device_t mdevice,就是HWC2On1Adapter的实例对象。

HWC2On1Adapter::HWC2On1Adapter(hwc_composer_device_1_t* hwc1Device){
	...
	 getFunction = getFunctionHook;
	...
}
static hwc2_function_pointer_t getFunctionHook(hwc2_device_t* device,
        int32_t intDesc) {
    auto descriptor = static_cast<HWC2::FunctionDescriptor>(intDesc);
    return getAdapter(device)->doGetFunction(descriptor);
}
hwc2_function_pointer_t HWC2On1Adapter::doGetFunction(
        FunctionDescriptor descriptor)
{
		case FunctionDescriptor::SetPowerMode:
            return asFP<HWC2_PFN_SET_POWER_MODE>(setPowerModeHook);
}

上面看到了mDispatch.setPowerMode 其它就是HWC2On1Adapter.dogetFunction(FunctionDescriptor::SetPowerMode), 之后的调用链就是HWC2On1Adapter.setPowerModeHook(…) ----->
HWC2On1Adapter.callDisplayFunction(device, display, &Display::setPowerMode) —>
Display.setPowerMode(mode)

Error HWC2On1Adapter::Display::setPowerMode(PowerMode mode)
{
   error = mDevice.mHwc1Device->setPowerMode(mDevice.mHwc1Device,
                mHwc1Id, getHwc1PowerMode(mode));    
    ...
}
static int hwc_device_open(const struct hw_module_t* module, const char* name,
                           struct hw_device_t** device)
{
	...
      dev->device.setPowerMode        = hwc_setPowerMode;
    ...
}
static int hwc_setPowerMode(struct hwc_composer_device_1* dev, int dpy,
        int mode)
{
    switch(mode) {
        case HWC_POWER_MODE_OFF:
        ...
    }
    switch(dpy) {
    case HWC_DISPLAY_PRIMARY:
		...
	}    
}

因为hwc.cpp里声明的minorversion为5,最后调用到了mDevice.mHwc1Device->setPowerMode(…) , 因为hwc.cpp中setPowerMode也就是hwc_setPowerMode, 最后在函数里根据mode和display做对应的处理
到这里setPowerMode就分析完了。

  • 5
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值