转自:http://blog.sina.com.cn/s/blog_7213e0310102wmc0.html
1.
在Android1.5 cupcake以前,Android的显示接口就是framebuffer接口。显示内容被直接写到framebuffer里,再调pan display ioctl就可以了。Framebuffer驱动是一个标准的linux driver接口,为什么还要实现hwcomposer接口呢?
主要原因可能是很多芯片显示接口功能很强,如果只使用framebuffer接口就有点大材小用。既然显示硬件功能强,那就尽量发挥它的功能。用hwcomposer的另外一个优点是在加入Fence机制后,hwc有利于显示,渲染,应用几方进行同步。
2.
先看一下下面的一幅图。
这个视频播放器的工具条是透明的。仔细想一下,如果只是framebuffer的话,SurfaceFlinger得把视频播放内容和工具条做合成,计算。如果不借助GPU的话,这个CPU计算量还是比较大的。如果不透明,直接把工具条层所占视频层的对应buffer数据覆盖就可以了。但对于透明工具条,需要计算工具条和视频两层个合成结果。而且,很多视频输出是YUV格式,可能还需要同时进行YUV->RGB转化。CPU忙啊。
有了hwcomposer,这个问题就简单多了。应用把要显示的layers交给SurfaceFlinger,比如对于上面视频播放的例子,应用程序交给SF一层视频,一层工具条。SF不必去合成,直接把这些layers交给hwc,hwc就可以在自己能力范围内做好合成,再把合成好的结果拿去显示。也就是说合成由显示模块硬件完成。目前主流的SOC平台显示模块都支持多层显示。
多说一句,如果芯片显示硬件模块功能较弱,不支持某些格式合成则么办呢?如果不支持的话SF会找GPU(硬件或软件)去做合成。这个会对显示性能有点影响。
第一节里提到的Fence和同步的话题比较复杂,如果感兴趣可以用度娘搜一下,网上很多这方面的文档。
3.
和gralloc模块一样,hwc也是以一个.so文件用dlopen方式被加载,它们的名字也很像,hwc的名字一般是hwcomposer.名字>.so存在于/system/lib/hw/路径下。
Hwc只会被SurfaceFlinger加载。这个也是合理的,因为只有SurfaceFlinger才能真正去向显示硬件接口进行render操作。SurfaceFlinger在init初始化函数里,调用” new HWComposer”产生一个hwc的对象。这里的HWComposer是Android里标准的hwc对象,不是平台相关的实现对象。在HWComposer的构造函数里,它调用HWComposer::loadHwcModule。真正的hwc .so文件加载就在这个函数里面。HWComposer::loadHwcModule先调用” hw_get_module(HWC_HARDWARE_MODULE_ID, &module)”加载.so文件,然后再调hwc_open_1,这个函数(hwc_open_1)会调用hw_module_methods_t::open函数,open函数就是平台相关了。这个加载过程跟gralloc非常相似,区别是gralloc既可以被SF加载,又会被应用加载,而hwcomposer只会被SF加载。正常情况hwcomposer只会被加载一次。
具体调用关系如下:
SurfaceFlinger main
flinger->init
SurfaceFlinger::init
new HWComposer
HWComposer::HWComposer
HWComposer::loadHwcModule
hw_get_module(HWC_HARDWARE_MODULE_ID, &module), hwc_open_1
4.
hwc API接口是google定义好的,具体可以参见hardware/libhardware/include/hardware/hwcomposer.h.
里面的主要接口说明如下:
hwc_composer_device_1:: prepare
SF把要显示的layers放在** displays参数里,主要是有几层,每层的格式,以及layers的Fences fd。如果当前芯片平台显示硬件模块可以支持layer的格式,它把相应的layer设成HWC_OVERLAY,如果显示硬件不支持其中的某个layer的格式,就把相应的layer设成HWC_FRAMEBUFFER。
hwc_composer_device_1:: set
SF告诉hwc,把里面所有layers输出到显示屏上,overlay的layer由hwc来处理,framebuffer的layer由SF调gpu的合成来完成。这个函数相当于过去framebuffer接口里的pan display。
hwc_composer_device_1::eventControl
使能/禁止vsync
hwc_composer_device_1::blank/setPowerMode
老的hwc(1.3以前)用blank控制display on/off,最新的hwc里用setPowerMode。实现的功能差不多,但setPowerMode的参数更丰富,不像blank就0/1。
hwc_procs_t:: vsync
这个也算是最重要的接口函数之一。Android在4.1里加入了对vsync的支持,这是对Android显示流畅度最大的提高措施之一。每一帧显示完毕hwc都会调用这个接口告诉SF一帧显示完成了。这个函数一般由内核里显示驱动中断出发,经过sys, proc, ioctl, uevent 或其他文件系统接口来通知hwc,再由hwc回调到SF里。
hwc_procs_t::hotplug
只有支持外接热插拔显示硬件的平台才考虑这个接口。比如hdmi。如果是一个出了显示屏不带其它接口的硬件,则不必考虑它。
Hwc 1.4接口里还加入了getDisplayConfigs/setActiveConfig等接口,貌似这是参考EGL接口实现的。如果hwc版本是1.4,这些函数在hwc里必须实现。