前面我们讲解了整个android图形显示系统的主要模块关系,和framebuffer,接下来我们讲解hwc叠加模块。
Android7.0提供了HWC和HWC2两个版本,到了Android8.0就都默认使用HWC2,我们接下来的介绍都是基于HWC2的。
文章目录
一、hwc模块定义与规格场景分析
产生背景—让GPU专心绘制提 升整体性能 降低功耗
为了解放GPU的绘制能力,很多芯片厂家会提供硬件叠加合成,如果硬件叠加器支持的场景都可以走硬件叠加,解放GPU的绘制能力专心绘制,提升的渲染性能同时还能大幅度的降低功耗(GPU强绘制,叠加搬移并不擅长,高功耗)。
hwc模块定义—The Hardware Composer硬件叠加器
应用把要显示的layers交给SurfaceFlinger,SurfaceFlinger直接把这些layers交给hwc,hwc就可以在自己能力范围内做好合成,再把合成好的结果拿去显示。如果芯片显示硬件模块功能较弱,不支持某些合成场景,就会用CPU(纯软件合成)或者GPU去做。
如果 SurfaceFlinger 具有可合成的新内容,则会唤醒,且每个 VSYNC 唤醒一次。该新内容可以是来自应用的新图像缓冲区,也可以是一个或多个图层的属性更改。如果缓冲变化或者属性调整导致画面变化,SurfaceFlinger 会调用 presentDisplay,以告知 HWC 完成合成过程并显示最终结果。
常见的hwc典型规格—叠加支持/回调事件
叠加能力:1、至少 4 个叠加层(状态栏 系统栏 应用 壁纸/背景);2、支持大于屏幕的图层(例如壁纸);3、支持预乘像素 Alpha 和图层 Alpha 混合叠加;4、支持受保护(安全)视频播放的硬件通路;5、支持各类RGBA PACKEGE顺序、YUV 格式以及Tiling(将image进行切割处理再拼接使用)、swizzling(向量的单元可以被任意地重排或重复)和stride属性;
事件功能:HWC也提供了事件的注册与回调,比如VSync事件,用于管理渲染和图层合成时机。
hwc基础模块抽象—device/display/layer
hwc中的抽象主要涉及3个关键类:
HWC2:Device—叠加器设备抽象(包含多个叠加通路)
表示整个硬件合成显示设备(里面包含多个display通路)。
关键成员:
std::unique_ptr<android::Hwc2::Composer> mComposer; // 叠加器对象指针
std::unordered_map<hwc2_display_t, std::unique_ptr<Display>> mDisplays; // 叠加通路列表
关键函数:
注册回调事件 registerCallback;
创建虚拟通路(非显示通路,如录屏)createVirtualDisplay:
热拔插事件onHotplug:
HWC2:Display—叠加器通路抽象(把多个输入层 叠加 输出送显 的通路):
表示一个显示屏幕,可以是支持热插拔的真实显示通路(该添加/删除可以应 HWC 设备的热插拔请求),也可以是虚拟显示通路(如录屏,发送到 Gralloc 缓冲区 而非 显示驱动)。物理屏幕是通过热插拔创建的。在热插拔物理屏幕时,HWC 会创建一个句柄并通过热插拔回调将该句柄传递给 SurfaceFlinger。虚拟屏幕是由通过调用 createVirtualDisplay() 来请求屏幕的 SurfaceFlinger 创建的。
关键成员:
DisplayType mType; // 叠加通路的类型(主显示 / 辅显示 / 虚拟通路)
android::Hwc2::Composer& mComposer; // 指向叠加器引用
std::unordered_map<hwc2_layer_t, std::unique_ptr<Layer>> mLayers; // 叠加通路的输入layer列表
关键函数:
输入layer的管理createLayer / destroyLayer
叠加输出buffer设置setClientTarget / setOutputBuffer
显示触发present
设置vsync使能setVsyncEnabled
HWC2:Layer—叠加通路输入的层抽象:
表示一个叠加图层,对应与应用侧的Surface。可以多个HWC DISPLAY包含同一个layer(同一个图层同时在两个通道上叠加显示)。当 SurfaceFlinger 要创建新图层时,它会调用 createLayer,该函数会针对直接实现返回 Layer 类型,或者针对直通式实现返回 hwc2_layer_t 类型。当 SurfaceFlinger 要修改该图层的属性时,它会将该 hwc2_layer_t 值以及进行修改所需的任何其他信息传递给相应的修改函数。
关键成员:
android::Hwc2::Composer& mComposer; // 指向叠加器引用
hwc2_display_t mDisplayId; // 对应的叠加通路id
关键函数:
设置层的buffer setBuffer:
设置层的属性 setBlendMode/setColor/setDataspace/setDisplayFrame(显示区域)/setPlaneAlpha/setSourceCrop/setZOrder
设置层的sidband流 setSidebandStream
设置叠加方式setCompositionType:Device表示硬件叠加,Client表示GPU叠加
引用夕月风(https://www.jianshu.com/p/824a9ddf68b9)博文中的一个非常直观的图,看图层的各种属性
Layer区域和屏幕区域就是Layer和屏幕本身的大小区域;sourceCrop 是对Layer剪切后获取的区域;displayFrame是对Layer 显示区域表示sourceCrop在屏幕上的显示区域(过程可能缩放)。visibleRegion 可见区域,displayFrame没有被上层Layer盖住的部分就是可见区域。coveredRegion被上层Layer覆盖的区域。damageRegion 受损区域/更新区域,表示Layer内容变了,重新合成时只去合成damageRegion区域。transparentRegion透明区域看到的是底层Layer的内容。
二、hwc框架分析(基于HIDL)
整体关系client & binder & service & vender impl
Android 8.0 及更高版本使用一个名为Composer HAL 的 HIDL 接口,用于在 HWC 和 SurfaceFlinger 之间binderized IPC通信。即将上层Androd和底层HAL分别采用两个不用的进程实现,最终调用到vender的具体实现hwc中,中间采用Binder进行通信。形成如下几个关键部分:
HWC2 Client在surfaceFlinger的service进程上下文中。HWC2 Server表示hwc的hal层服务端有独立的进程process;
HWRVL:/ $ ps -A | grep compose
system 607 1 2249520 3268 0 0 S android.hardware.graphics.composer@2.2-service
HWRVL:/ $ ps -A | grep surface
system 657 1 2866640 18124 0 0 S surfaceflinger
三、dumpsys SurfaceFlinger命令查看状态
想要查看通道和对应图层的关系,可以用dumpsys SurfaceFlinger名称查看。
查看HWC通道Display与参与层叠Layer加关系
如下图dumpsys SurfaceFlinger内容,这个设备只有1个叠加通路Display 0(如果有第二屏会在后续出现Display 1 HWC layers),这个得加通路上有5个layer输入。可以看到每个层的名字,叠加类型(Device表示 硬件叠加,如果是Client表示GPU叠加),每个图层的显示范围和源crop范围。
Display 0 HWC layers:
-------------------------------------------------------------------------------
Layer name
Z | Comp Type | Disp Frame (LTRB) | Source Crop (LTRB)
-------------------------------------------------------------------------------
com.android.systemui.HwImageWallpaper#0
rel 0 | Device | 0 0 1080 2220 | 0.0 0.0 1080.0 2220.0
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
com.huawei.android.launcher/com.huaw[...]d.launcher.unihome.UniHomeLauncher#0
rel 0 | Device | 0 0 1080 2220 | 0.0 0.0 1080.0 2220.0
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
StatusBar#0
rel 0 | Device | 0 0 1080 2220 | 0.0 0.0 1080.0 2220.0
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
com.huawei.RoundCornerDisplay_Bottom#0
2147483646 | Device | 0 2154 1080 2220 | 0.0 0.0 1080.0 66.0
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
com.huawei.RoundCornerDisplay_Top#0
2147483647 | Device | 0 0 1080 66 | 0.0 0.0 1080.0 66.0
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
四、hwc主要流程分析(待补充)
1、初始化流程
2、叠加准备流程
3、叠加流程
4、叠加完成
五、hwc驱动关键设计(待补充)
1、输入输出fence管理
2、双显示输出双通路设计
3、虚拟通路设计
参考
https://source.android.google.cn/devices/graphics/hwc
https://www.jianshu.com/p/824a9ddf68b9
https://blog.csdn.net/tli600605/article/details/101710446
https://my.oschina.net/u/3367385/blog/3112746
http://androidxref.com/9.0.0_r3/xref/frameworks/native/services/surfaceflinger/DisplayHardware/