android 8.0 Hwcomposer2 HIDL流程

在android O之後google爲了更好的管理以及方便OTA的升級,加入了HIDL,將Android Framework和Hal進行分離
每個模塊流程大致都一樣,我主要從hwcomposer流程入手分析學習一下,本文沒有涉及到HIDL的啓動以及通訊,主要談到hotplug的傳遞流程以及註冊過程
首先看看hotplug的註冊流程
查看framework native部分
frameworks\native\services\surfaceflinger\surfaceflinger.h頭文件裏面可以看到
我們目前使用的是hwc2,所以SurfaceFlinger 繼承了ComposerCallback類

class SurfaceFlinger : public BnSurfaceComposer,
                       private IBinder::DeathRecipient,
#ifdef USE_HWC2
                       private HWC2::ComposerCallback
#else
                       private HWComposer::EventHandler
#endif

看看ComposerCallback這個類
在frameworks\native\services\surfaceflinger\DisplayHardware\hwc2.h中

class ComposerCallback {
 public:
    virtual void onHotplugReceived(int32_t sequenceId, hwc2_display_t display,
                                   Connection connection,
                                   bool primaryDisplay) = 0;
    virtual void onRefreshReceived(int32_t sequenceId,
                                   hwc2_display_t display) = 0;
    virtual void onVsyncReceived(int32_t sequenceId, hwc2_display_t display,
                                 int64_t timestamp) = 0;
    virtual ~ComposerCallback() = default;
};

在hwc2.h的頭文件裏面ComposerCallback 類中定義了,主要有同步,熱拔插,刷新三個虛方法,目前猜測在surfaceflinger.cpp中應該會實現這三個方法,然而你的猜測是對的
frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp

void SurfaceFlinger::onHotplugReceived(int32_t sequenceId,
        hwc2_display_t display, HWC2::Connection connection,
        bool primaryDisplay) {
    ALOGV("onHotplugReceived(%d, %" PRIu64 ", %s, %s)",
          sequenceId, display,
          connection == HWC2::Connection::Connected ?
                  "connected" : "disconnected",
          primaryDisplay ? "primary" : "external");
    ConditionalLock lock(mStateLock,
            std::this_thread::get_id() != mMainThreadId);
    if (primaryDisplay) {
        mHwc->onHotplug(display, connection);
        if (!mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY].get()) {
            createBuiltinDisplayLocked(DisplayDevice::DISPLAY_PRIMARY);
        }
        createDefaultDisplayDevice();
    } else {
        if (sequenceId != mComposerSequenceId) {
            return;
        }
        if (mHwc->isUsingVrComposer()) {
            ALOGE("External displays are not supported by the vr hardware composer.");
            return;
        }
        mHwc->onHotplug(display, connection);
        auto type = DisplayDevice::DISPLAY_EXTERNAL;
        if (connection == HWC2::Connection::Connected) {
            createBuiltinDisplayLocked(type);
        } else {
            mCurrentState.displays.removeItem(mBuiltinDisplays[type]);
            mBuiltinDisplays[type].clear();
        }
        setTransactionFlags(eDisplayTransactionNeeded);

        // Defer EventThread notification until SF has updated mDisplays.
    }
}

好了,我們現在知道了這三個方法的實現,但是是如何註冊的呢?以及hal層是如何實現回調的呢?
那麼下面來看看具體的註冊方式以及回調方法
在surfaceflinger.cpp文件中,SurfaceFlinger的init() 的函數裏面有調用registerCallback函數代碼

void SurfaceFlinger::init() {
	.....
    mHwc.reset(new HWComposer(false));
    mHwc->registerCallback(this, mComposerSequenceId);
    .....
    }
//其中mHwc在surfaceflinger.h中定義
std::unique_ptr<HWComposer> mHwc;    

於是調用frameworks\native\services\surfaceflinger\DisplayHardware\HWComposer.cpp

void HWComposer::registerCallback(HWC2::ComposerCallback* callback,int32_t sequenceId) 
{
    mHwcDevice->registerCallback(callback, sequenceId);
}

mHwcDevice變量在frameworks\native\services\surfaceflinger\DisplayHardware\HWComposer.cpp中定義

    std::unique_ptr<HWC2::Device>   mHwcDevice;

frameworks\native\services\surfaceflinger\DisplayHardware\hwc2.cpp

void Device::registerCallback(ComposerCallback* callback, int32_t sequenceId) {
    if (mRegisteredCallback) {
        ALOGW("Callback already registered. Ignored extra registration "
                "attempt.");
        return;
    }
    mRegisteredCallback = true;
    sp<ComposerCallbackBridge> callbackBridge(
            new ComposerCallbackBridge(callback, sequenceId));
    mComposer->registerCallback(callbackBridge);
    LOG_ALWAYS_FATAL_IF(!callbackBridge->HasPrimaryDisplay(),
            "Registered composer callback but didn't get primary display");
}

在上面的函數中涉及到ComposerCallbackBridge類,調用了ComposerCallbackBridge構造函數,將callback賦值了mCallback,並初始化了callbackBridge對象,而且onHotplug函數裏面進行了surfaceflinger類裏面onHotplugReceived回調

class ComposerCallbackBridge : public Hwc2::IComposerCallback {
public:
    ComposerCallbackBridge(ComposerCallback* callback, int32_t sequenceId)
            : mCallback(callback), mSequenceId(sequenceId),
              mHasPrimaryDisplay(false) {}
           Return<void> onHotplug(Hwc2::Display display,
                           IComposerCallback::Connection conn) override
    {
        HWC2::Connection connection = static_cast<HWC2::Connection>(conn);
        if (!mHasPrimaryDisplay) {
            LOG_ALWAYS_FATAL_IF(connection != HWC2::Connection::Connected,
                    "Initial onHotplug callback should be "
                    "primary display connected");
            mHasPrimaryDisplay = true;
            mCallback->onHotplugReceived(mSequenceId, display,
                                         connection, true);
        } else {
            mCallback->onHotplugReceived(mSequenceId, display,
                                         connection, false);
        }
        return Void();
    }

	......
}

繼續註冊調用frameworks\native\services\surfaceflinger\DisplayHardware\ComposerHal.cpp
注意現在變了變成了callbackBridge

void Composer::registerCallback(const sp<IComposerCallback>& callback)
{
    auto ret = mClient->registerCallback(callback);
    if (!ret.isOk()) {
        ALOGE("failed to register IComposerCallback");
    }
}
frameworks\native\services\surfaceflinger\DisplayHardware\ComposerHal.h
````c++
    sp<IComposer> mComposer;
    sp<IComposerClient> mClient;

對接了Treble架構的Hal,接着來到Treble層
hardware\interfaces\graphics\composer\2.1\default\ComposerClient.cpp

Return<void> ComposerClient::registerCallback(
        const sp<IComposerCallback>& callback)
{
    // no locking as we require this function to be called only once
    mCallback = callback;
    mHal.enableCallback(callback != nullptr);
    return Void();
}

hardware\interfaces\graphics\composer\2.1\default\ComposerClient.h中申明如下

sp<IComposerCallback> mCallback;
ComposerBase& mHal;

查看ComposerBase類中虛函數

class ComposerBase {
public:
    virtual ~ComposerBase() {};

    virtual void removeClient() = 0;
    virtual void enableCallback(bool enable) = 0;
    ......
    }

Hwchal類繼承了ComposerBase ,並實現了接口函數

hardware\interfaces\graphics\composer\2.1\default\hwc.h
class HwcHal : public IComposer, public ComposerBase {

hardware\interfaces\graphics\composer\2.1\default\hwc.cpp

void HwcHal::enableCallback(bool enable)
{
    if (enable) {
        mDispatch.registerCallback(mDevice, HWC2_CALLBACK_HOTPLUG, this,
                reinterpret_cast<hwc2_function_pointer_t>(hotplugHook));
        mDispatch.registerCallback(mDevice, HWC2_CALLBACK_REFRESH, this,
                reinterpret_cast<hwc2_function_pointer_t>(refreshHook));
        mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC, this,
                reinterpret_cast<hwc2_function_pointer_t>(vsyncHook));
    } else {
        mDispatch.registerCallback(mDevice, HWC2_CALLBACK_HOTPLUG, this,
                nullptr);
        mDispatch.registerCallback(mDevice, HWC2_CALLBACK_REFRESH, this,
                nullptr);
        mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC, this,
                nullptr);
    }
}

這裏有個mDispatch是個什麼東東?而且也看到有註冊hotplugHook,refreshHook,vsyncHook函數
接着跟到頭文件hardware\interfaces\graphics\composer\2.1\default\hwc.h發現mDispatch是一個結構體

    struct {
		....
        HWC2_PFN_REGISTER_CALLBACK registerCallback;
		....
    } mDispatch;

hardware\libhardware\include\hardware\Hwcomposer2.h
HWC2_PFN_REGISTER_CALLBACK 是一個自定義函數指針類型
typedef int32_t /*hwc2_error_t*/ (*HWC2_PFN_REGISTER_CALLBACK)(
        hwc2_device_t* device,
        int32_t /*hwc2_callback_descriptor_t*/ descriptor,
        hwc2_callback_data_t callbackData, hwc2_function_pointer_t pointer);

那這個是如何讓實現調用的呢,
其實在HwcHal結構函數中進行結構體初始化


HwcHal::HwcHal(const hw_module_t* module)
    : mDevice(nullptr), mDispatch(), mAdapter()
{
	....
    initDispatch();
}


template<typename T>
void HwcHal::initDispatch(hwc2_function_descriptor_t desc, T* outPfn)
{
    auto pfn = mDevice->getFunction(mDevice, desc);
    if (!pfn) {
        LOG_ALWAYS_FATAL("failed to get hwcomposer2 function %d", desc);
    }

    *outPfn = reinterpret_cast<T>(pfn);
}

void HwcHal::initDispatch()
{
	....
    initDispatch(HWC2_FUNCTION_REGISTER_CALLBACK,
            &mDispatch.registerCallback);
            .....
}

看到這裏是不是有一種柳暗花明的感覺
通過mDevice->getFunction(mDevice, desc);函數結構調用hal層函數,各函數結構由各廠商自己完成,可以看到

hardware\libhardware\include\hardware\Hwcomposer2.h
typedef struct hwc2_device {
    /* Must be the first member of this struct, since a pointer to this struct
     * will be generated by casting from a hw_device_t* */
    struct hw_device_t common;

    /* getCapabilities(..., outCount, outCapabilities)
     *
     * Provides a list of capabilities (described in the definition of
     * hwc2_capability_t above) supported by this device. This list must
     * not change after the device has been loaded.
     *
     * Parameters:
     *   outCount - if outCapabilities was NULL, the number of capabilities
     *       which would have been returned; if outCapabilities was not NULL,
     *       the number of capabilities returned, which must not exceed the
     *       value stored in outCount prior to the call
     *   outCapabilities - a list of capabilities supported by this device; may
     *       be NULL, in which case this function must write into outCount the
     *       number of capabilities which would have been written into
     *       outCapabilities
     */
    void (*getCapabilities)(struct hwc2_device* device, uint32_t* outCount,
            int32_t* /*hwc2_capability_t*/ outCapabilities);

    /* getFunction(..., descriptor)
     *
     * Returns a function pointer which implements the requested description.
     *
     * Parameters:
     *   descriptor - the function to return
     *
     * Returns either a function pointer implementing the requested descriptor
     *   or NULL if the described function is not supported by this device.
     */
    hwc2_function_pointer_t (*getFunction)(struct hwc2_device* device,
            int32_t /*hwc2_function_descriptor_t*/ descriptor);
} hwc2_device_t;

看到註冊的函數hotplugHook函數

void HwcHal::hotplugHook(hwc2_callback_data_t callbackData,
        hwc2_display_t display, int32_t connected)
{
    auto hal = reinterpret_cast<HwcHal*>(callbackData);
    auto client = hal->getClient();
    if (client != nullptr) {
        client->onHotplug(display,
                static_cast<IComposerCallback::Connection>(connected));
    }
}

void ComposerClient::onHotplug(Display display,
        IComposerCallback::Connection connected)
{
	....
    auto ret = mCallback->onHotplug(display, connected);
    ALOGE_IF(!ret.isOk(), "failed to send onHotplug: %s",
            ret.description().c_str());
}

到此三個註冊回調接口就完成了,hotplugHook函數調用有hal完成,當hal檢測到有device接入的時候,產生中斷從而回調hotplugHook這樣整個流程就完成了!
關於HIDL的通訊,服務相關的內容後續在分析

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章