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

Posted Give.Me.Five

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android P 显示流程---Display设备初始化过程分析相关的知识,希望对你有一定的参考价值。

android P 显示流程(一)

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(HotplugEventdisplay, 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() constreturn *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就分析完了。

以上是关于Android P 显示流程---Display设备初始化过程分析的主要内容,如果未能解决你的问题,请参考以下文章

Android Qcom lcd display 学习

Android P 显示流程分析---界面刷新

Android P 显示流程分析---界面刷新

安卓,网页控件,显示网页 Android, web controls, display web pages

Android P 显示流程分析--- buffer的生产消费者模式

Android P 显示流程分析--- buffer的生产消费者模式