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 EventHandler& handler) : mFlinger(flinger), mFbDev(0), mHwc(0), mNumDisplays(1), mCBContext(new cb_context), mEventHandler(handler), mDebugForceFakeVSync(false) { for (size_t i =0 ; i mLists[i] = 0; } //首先是一些和VSYNC有关的信息的初始化 //因为在硬件支持的情况下,VSYNC的功能就是由HWC提供的 for (size_t i=0 ; 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 mAllocatedDisplayIDs.markBit(i); } //如果我们有HWC这个硬件设备,那么我们就注册一些HWC回调函数,比如hook_invalidate,hook_vsync,hook_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 queryDisplayProperties(i); } } //显然,如果需要模拟VSync信号的话,我们需要线程来做这个工作 if (needVSyncThread) { // we don't have VSYNC support, we need to fake it //VSyncThread类的实现很简单,无非就是一个计时器而已,定时发送消息而已 mVSyncThread = new VSyncThread(*this); } } |