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, web controls, display web pages