HWComposer 分析

Posted Achillisjack

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HWComposer 分析相关的知识,希望对你有一定的参考价值。

HWComposer

Vsync信号的产生有两种来源,一种是硬件,也就是显示模块产生;另外一种是软件模拟,因为目前基本都是硬件产生的,所以软件模拟的代码就没有分析的必要了。

接下来分析由硬件产生的vsync是怎么传到surfaceflinger的。

这个硬件源就是HWComposer,它一方面管理这composer的hal模块,composer模块是厂商定制UI合成的接口,通常不会直接操作HWComposer模块,而是通过surfaceflinger使用它;另一方面就是产生vsync信号。

在SurfaceFlinger_hwc1.cpp中的init方法中会构造HWComposer对象,

mHwc.reset(new HWComposer(this, *static_cast<HWComposer::EventHandler *>(this)));

HWComposer_hwc1.cpp的HWComposer的构造方法主要逻辑如下,

1,加载FB的hal模块,对应设备用framebuffer_device_t*    mFbDev表示, 然后加载Hwc模块,对应的设备用struct hwc_composer_device_1*   mHwc表示。  

int fberr = loadFbHalModule();
loadHwcModule();

2, 注册硬件回调事件

if (mHwc->registerProcs) 
   mCBContext->hwc = this;
   mCBContext->procs.invalidate = &hook_invalidate;
   mCBContext->procs.vsync = &hook_vsync;
•••
mHwc->registerProcs(mHwc, &mCBContext->procs);

loadFbHalModule方法逻辑如下,

1, 打开的硬件模块

hw_module_t const* module;
int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);

2,调用硬件模块的open方法,打开指定的硬件设备

return framebuffer_open(module, &mFbDev);

对应的HAL的模块是哪个呢? 关键字 GRALLOC_HARDWARE_MODULE_ID

hardware\\libhardware\\modules\\gralloc路径下的gralloc.cpp文件中的HAL_MODULE_INFO_SYM定义如下,

.base = 
     .common = 
     .tag = HARDWARE_MODULE_TAG,
     .version_major = 1,
     .version_minor = 0,
     .id = GRALLOC_HARDWARE_MODULE_ID,
     .name = "Graphics Memory Allocator Module",
     .author = "The android Open Source Project",
     .methods = &gralloc_module_methods
     ,
    .registerBuffer = gralloc_register_buffer,
    .unregisterBuffer = gralloc_unregister_buffer,
    .lock = gralloc_lock,
    .unlock = gralloc_unlock,
 ,
.framebuffer = 0,
.flags = 0,
.numBuffers = 0,
.bufferMask = 0,
.lock = PTHREAD_MUTEX_INITIALIZER,
.currentBuffer = 0,

因此, HWComposer 对应的HAL模块就是gralloc。

gralloc_module_methods结构体定义如下,

.open = gralloc_device_open

也就是说对应的open方法为gralloc_device_open。

hardware\\libhardware\\include\\hardware中的fb.h 的framebuffer_open方法如下,

static inline int framebuffer_open(const struct hw_module_t* module,
        struct framebuffer_device_t** device) 
    return module->methods->open(module,
            GRALLOC_HARDWARE_FB0, TO_HW_DEVICE_T_OPEN(device));

GRALLOC_HARDWARE_FB0定义如下,
#define GRALLOC_HARDWARE_FB0 "fb0"

因此,最后打开的实际上是 /dev/graphics/fb0节点。

调用gralloc 模块的open方法,也就是gralloc_device_open 方法,第二个输入参数为GRALLOC_HARDWARE_FB0,因此gralloc_device_open 方法对应的代码如下,

status = fb_device_open(module, name, device);

framebuffer设备的打开过程开始打开。

framebuffer.cpp中的fb_device_open方法如下,

1,对变量/方法 进行映射

dev->device.common.tag      = HARDWARE_DEVICE_TAG;
dev->device.common.version  = 0;
dev->device.common.module   = const_cast<hw_module_t*>(module);
dev->device.common.close    = fb_close;
dev->device.setSwapInterval = fb_setSwapInterval;
dev->device.post            = fb_post;
dev->device.setUpdateRect   = 0;
dev->device.compositionComplete = fb_compositionComplete;

2,调用mapFrameBuffer方法获取帧缓存设备的参数并将其设备节点映射到用户空间

status = mapFrameBuffer((framebuffer_device_t*)dev);

Hwc模块的加载过程和fb模块完全相同。loadHwcModule方法逻辑如下,

1,加载HWC模块,

if (hw_get_module(HWC_HARDWARE_MODULE_ID, &module) != 0) 
    ALOGE("%s module not found", HWC_HARDWARE_MODULE_ID);
    return;

2,调用open方法,

int err = hwc_open_1(module, &mHwc);

对这2个方法,逐个分析。

hardware\\libhardware\\include\\hardware中的hwcomposer_defs.h文件对HWC_HARDWARE_MODULE_ID 定义如下,

#define HWC_HARDWARE_MODULE_ID "hwcomposer"

hardware\\libhardware\\modules\\hwcomposer中的hwcomposer.cpp的HAL_MODULE_INFO_SYM定义如下,

hwc_module_t HAL_MODULE_INFO_SYM = 
    .common = 
        .tag = HARDWARE_MODULE_TAG,
        .version_major = 1,
        .version_minor = 0,
        .id = HWC_HARDWARE_MODULE_ID,
        .name = "Sample hwcomposer module",
        .author = "The Android Open Source Project",
        .methods = &hwc_module_methods,
    
;

因此,对应的HWC 模块就是 hwcomposer.cpp。

hwc_module_methods结构体定义如下,

static struct hw_module_methods_t hwc_module_methods = 
    .open = hwc_device_open
;

也就是说 模块对应的open方法为hwc_device_open

hardware\\libhardware\\include\\hardware中的hwcomposer.h 文件中的hwc_open_1方法如下,

static inline int hwc_open_1(const struct hw_module_t* module,
        hwc_composer_device_1_t** device) 
    return module->methods->open(module,
            HWC_HARDWARE_COMPOSER, TO_HW_DEVICE_T_OPEN(device));

HWC_HARDWARE_COMPOSER在前面已经论述过,因此open方法还是调用的是HWC模块的open方法,对应的方法为hwc_device_openhardware\\qcom\\display\\libhwcomposer中的hwc.cpp的该方法如下,

•••
dev->device.eventControl        = hwc_eventControl;
dev->device.setPowerMode        = hwc_setPowerMode;
dev->device.query               = hwc_query;
dev->device.registerProcs       = hwc_registerProcs;
dev->device.dump                = hwc_dump;
•••

主要是为函数指针赋值。

其他的函数后面会分析,主要看registerProcs 函数。也就是说hwcomposer 如果调用registerProcs方法,实际上调用的是HWC模块的hwc_registerProcs方法。

这样就完成了HWC模块的加载和打开。

以上是关于HWComposer 分析的主要内容,如果未能解决你的问题,请参考以下文章

vsync信号

vsync信号

Android图形系统之HWComposer

有关软件工程专业的论述

论述性文本分类

Android SurfaceFlinger服务 ----- VSync信号的分发