Android图形系统系统篇之HWC

Android图形系统系统篇之HWC,第1张

HWC (hwcomposer)是Android中进行窗口( Layer )合成和显示的HAL层模块,其实现是特定于设备的,而且通常由显示设备制造商 (OEM)完成,为 SurfaceFlinger 服务提供硬件支持。

SurfaceFlinger 可以使用 OpenGL ES 合成 Layer ,这需要占用并消耗GPU资源。大多数GPU都没有针对图层合成进行优化,当 SurfaceFlinger 通过GPU合成图层时,应用程序无法使用GPU进行自己的渲染。而 HWC 通过硬件设备进行图层合成,可以减轻GPU的合成压力。

显示设备的能力千差万别,很难直接用API表示硬件设备支持合成的 Layer 数量, Layer 是否可以进行旋转和混合模式 *** 作,以及对图层定位和硬件合成的限制等。因此HWC描述上述信息的流程是这样的:

虽然每个显示设备的能力不同,但是官方要求每个 HWC 硬件模块都应该支持以下能力:

但是并非所有情况下 HWC 都比GPU更高效,例如:当屏幕上没有任何变化时,尤其是叠加层有透明像素并且需要进行图层透明像素混合时。在这种情况下, HWC 可以要求部分或者全部叠加层都进行GPU合成,然后 HWC 持有合成的结果Buffer,如果 SurfaceFlinger 要求合成相同的叠加图层列表, HWC 可以直接显示之前合成的结果Buffer,这有助于提高待机设备的电池寿命。

HWC 也提供了 VSync 事件,用于管理渲染和图层合成时机,后续文章会进行介绍。

Android7.0提供了HWC和HWC2两个版本,默认使用HWC,但是手机厂商也可以选择HWC2,如下所示:

SurfaceFlinger 通过 HWComposer 使用 HWC 硬件能力, HWComposer 构造函数通过 loadHwcModule 方法加载HWC模块,并封装成 HWC2::Device 结构,如下所示:

上述通过 hw_get_module 方法(hardware\libhardware\hardware.c)加载 hwcomposer 模块,此模块由硬件厂商提供实现,例如:hardware\libhardware\modules\hwcomposer\hwcomposer.cpp是 hwcomposer 模块基于HWC1的default实现,对应的共享库是 hwcomposer.default.so ;hardware\qcom\display\msm8994\libhwcomposer\hwc.cpp是高通MSM8994基于HWC1的实现,对应的共享库是 hwcomposer.msm8994.so 。

如果是基于HWC2协者码议实现,则需要实现hwcomposer2.h中定义的 hwc2_device_t 接口,例如: class VendorComposer : public hwc2_device_t 。Android7.0的 hwcomposer 模块默认都是基于HWC1协议实现的。

每个HAL层模块实现都要定义一个 HAL_MODULE_INFO_SYM 数据结构,并且该结构的第一个字段必须是 hw_module_t ,下面是高通MSM8994 hwcomposer 模块的定义:

frameworks\native\services\surfaceflinger\DisplayHardware\HWC2.h主要定义了以下三个结构体:

它们是对 HWC 硬件模块的进一步封装,方便进行调用。 HWC2::Device 持有一个 hwc2_device_t ,用于连接硬件设备,它包含了很多HWC2_PFN开头的函数指针变量,这些函数指针定义在 hwcomposer2.h 。

在 HWC2::Device 的构造函数中,会通过 Device::loadFunctionPointers -> loadFunctionPointer(FunctionDescriptor desc, PFN&outPFN) -> hwc2_device_t::getFunction 的调用链从硬件设备中获取具体的函数指针实现首蠢哪。关键模板函数如下所示:

这些函数指针主要分为三类:

通过上述档羡函数指针可以与 hwc2_device_t 表示的硬件合成模块进行交互。三类指针分别选取了一个示例:

可以通过类图,直观感受下引用关系。

HWC2::Device 构造函数除了完成获取函数指针实现以外,还会通过 Device::registerCallbacks 向硬件设备注册三个 Display 的回调:热插拔,刷新和VSync信号,如下所示:

总结一下, HWC2::Device 构造函数向硬件设备注册三个 Display 回调:热插拔,刷新和VSync信号。当 HWC2::Device 收到这些回调时,会通过监听器向外回调到对应的HWComposer函数: HWComposer::hotplug / HWComposer::invalidate / HWComposer::vsync 。HWComposer再通过这些信息驱动对应工作,后续文章进行介绍。

上文提到 HWC2::Device 中的函数指针是hardware\libhardware\include\hardware\hwcomposer2.h中定义的,除此之外,该头文件还定义了一些重要的结构体,这里介绍两个比较重要的:

DisplayType 表示显示屏类型,上面注释已经介绍,重点看下Layer合成类型:

那么一个 Layer 的合成方式是怎么确定的那?大致流程如下所示:

本篇文章只是简单介绍了HWC模块的相关类: HWComposer 、 HWC2::Device 、 HWC2::Display 和 HWC2::Layer ,以及它们的关系。此外,还着重介绍了Layer的合成方式和合成流程。后续文章会更加全面的介绍 SurfaceFlinger 是如何通过HWC模块完成Layer合成和上屏的(虚拟屏幕是到离屏缓冲区)。

一返桐种简单的方法是:把主函数中的变量作为参数传给回调函数,就是回调函数加所需的参数。

如果您有兴趣,还可以学习一下C++中的函者碧数对象和bind, 看看是否可以用函数对象代替回调函首世举数。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/8209445.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-14
下一篇 2023-04-14

发表评论

登录后才能评论

评论列表(0条)

保存