Android研究_Hardware Composer_1 HWC概述

来源:互联网 发布:汉字笔顺软件注册码 编辑:程序博客网 时间:2024/05/29 18:37

3.1 HWComposer概述

      HWComposer 是 Andrid 4.0后推出的新特性,它定义一套HAL层接口,然后各个芯片厂商根据各种硬件特点来实现,对应的hardware id为HWC_HARDWARE_MODULE_ID。 

      SurfaceFlinger提供所有软图层信息给HWComposer,询问其处理方式。HWComposer根据硬件性能决定是使用硬件图层合成器还是GPU合成,SurfaceFlinger处理需要GPU合成的软图层,将结果递交给HWComposer做显示,需要硬件图层合成器合成的软图层由HWComposer自行处理。

      它的主要工作是将SurfaceFlinger计算好的Layer的显示参数最终合成到一个显示Buffer上。说的更加直接一点,就是HWC本质是是HAL层,是Android规范的一层api,用于对硬件合成模块的操作。

      注意的是,SurfaceFlinger并非是HWComposer的唯一输入,有的Surface 不由Android的WindowManager 管理,比如说摄像头的预览输入Buffer, 可以有硬件直接写入,然后作为HWComposer的输入之一与SurfaceFlinger的输出做最后的合成。

HWComposer中有几个重要的功能:

1)动态加载Gralloc 和hwc SO库

2)生成Vsync;

3)遍历layer情况,判断混合方式;

4)HWC处理Uenvent事件

我们先来看看HWComposer的构建函数:

HWComposer::HWComposer(

        const sp<SurfaceFlinger>& flinger,

        EventHandler& handler)

    : mFlinger(flinger),

      mFbDev(0), mHwc(0), mNumDisplays(1),

      mCBContext(new cb_context),

      mEventHandler(handler),

      mDebugForceFakeVSync(false)

{

    for (size_t i =0 ; i<MAX_HWC_DISPLAYS ; i++) {

        mLists[i] = 0;

    }

 //首先是一些和VSYNC有关的信息的初始化

 //因为在硬件支持的情况下,VSYNC的功能就是由HWC提供的

    for (size_t i=0 ; i<HWC_NUM_PHYSICAL_DISPLAY_TYPES ; i++) {

        mLastHwVSync[i] = 0;

        mVSyncCounts[i] = 0;

    }

 

//根据配置debug.sf.no_hw_vsync来看是否需要模拟VSYNC消息

    char value[PROPERTY_VALUE_MAX];

    property_get("debug.sf.no_hw_vsync", value, "0");

    mDebugForceFakeVSync = atoi(value);

 

    bool needVSyncThread = true;

//加载Gralloc中的GRALLOC_HARDWARE_FB0设备,和HWC设备 

    // Note: some devices may insist that the FB HAL be opened before HWC.

    int fberr = loadFbHalModule();

    loadHwcModule();

 

    if (mFbDev && mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {

        // close FB HAL if we don't needed it.

        // FIXME: this is temporary until we're not forced to open FB HAL

        // before HWC.

        framebuffer_close(mFbDev);

        mFbDev = NULL;

    }

 

    // If we have no HWC, or a pre-1.1 HWC, an FB dev is mandatory.

    if ((!mHwc || !hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1))

            && !mFbDev) {

        ALOGE("ERROR: failed to open framebuffer (%s), aborting",

                strerror(-fberr));

        abort();

    }

 

    // these display IDs are always reserved

    for (size_t i=0 ; i<NUM_BUILTIN_DISPLAYS ; i++) {

        mAllocatedDisplayIDs.markBit(i);

    }

//如果我们有HWC这个硬件设备,那么我们就注册一些HWC回调函数,比如hook_invalidatehook_vsynchook_hotplug

    if (mHwc) {

        ALOGI("Using %s version %u.%u", HWC_HARDWARE_COMPOSER,

              (hwcApiVersion(mHwc) >> 24) & 0xff,

              (hwcApiVersion(mHwc) >> 16) & 0xff);

        if (mHwc->registerProcs) {

            mCBContext->hwc = this;

            mCBContext->procs.invalidate = &hook_invalidate;

            mCBContext->procs.vsync = &hook_vsync;

            if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1))

                mCBContext->procs.hotplug = &hook_hotplug;

            else

                mCBContext->procs.hotplug = NULL;

            memset(mCBContext->procs.zero, 0, sizeof(mCBContext->procs.zero));

            mHwc->registerProcs(mHwc, &mCBContext->procs);

        }

//另外,就不需要使用vsync的进程,因为我们有了硬件支持的VSYNC中断

        // don't need a vsync thread if we have a hardware composer

        needVSyncThread = false;

        // always turn vsync off when we start

        eventControl(HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0);

 

        // the number of displays we actually have depends on the

        // hw composer version

//根据HWC硬件的支持情况,来设置显示屏幕的数量 

        if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_3)) {

            // 1.3 adds support for virtual displays

            mNumDisplays = MAX_HWC_DISPLAYS;

        } else if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {

            // 1.1 adds support for multiple displays

            mNumDisplays = NUM_BUILTIN_DISPLAYS;

        } else {

            mNumDisplays = 1;

        }

    }

//如果我们能获取到FB设置,那么我们就从FB设备里面读取一些屏幕相关的数据

    if (mFbDev) {

        ALOG_ASSERT(!(mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)),

                "should only have fbdev if no hwc or hwc is 1.0");

 

        DisplayData& disp(mDisplayData[HWC_DISPLAY_PRIMARY]);

        disp.connected = true;

        disp.format = mFbDev->format;

        DisplayConfig config = DisplayConfig();

        config.width = mFbDev->width;

        config.height = mFbDev->height;

        config.xdpi = mFbDev->xdpi;

        config.ydpi = mFbDev->ydpi;

        config.refresh = nsecs_t(1e9 / mFbDev->fps);

        disp.configs.push_back(config);

        disp.currentConfig = 0;

    } else if (mHwc) {//否则我们将会从HWC中读取相关配置

        // here we're guaranteed to have at least HWC 1.1

        for (size_t i =0 ; i<NUM_BUILTIN_DISPLAYS ; i++) {

            queryDisplayProperties(i);

        }

    }

//显然,如果需要模拟VSync信号的话,我们需要线程来做这个工作

    if (needVSyncThread) {

        // we don't have VSYNC support, we need to fake it

//VSyncThread类的实现很简单,无非就是一个计时器而已,定时发送消息而已

        mVSyncThread = new VSyncThread(*this);

    }

}