Flutter 新一代图形渲染器 Impeller
作者:谷鸣
出品:大淘宝技术
Flutter在2022年的Roadmap中提出需要重新考虑着色器的使用方式,计划重写图像渲染后端。最近该渲染后端 Impeller(叶轮)初见端倪,本文将介绍 Impeller 解决的问题、目标、架构和渲染细节。
背景
Flutter在过去一年多时间解决了很多Jank问题,但着色器编译导致的Jank问题一直没有彻底解决。这里我们先了解下什么着色器编译Jank。Flutter底层使用了skia做为2D图形渲染库,而skia内部定义了一套SkSL(Skia shading language),SkSL 属于 GLSL 变体。在Flutter的光栅化阶段,当第一次使用着色器时Skia会根据绘图命令和设备参数生成 SkSL,然后再将 SkSL 转换为特定后端(GLSL、GLSL ES 或 Metal SL)着色器,并在设备上编译为着色器程序。而编译着色器可能花费几百毫秒,导致数十帧的丢失。定位着色器编译Jank问题可以查看trace信息是否有 GrGLProgramBuilder::finalize 调用。
Flutter为了解决该问题,在Flutter 1.20 版本中为GL后端实现了SkSL预热机制,支持离线收集应用程序中使用的SkSL 着色器并保存为json文件,然后把该文件打包到应用程序中,最终用户首次打开应用程序时预编译 SkSL着色器,从而减少着色器编译 jank。随后,在 Flutter 2.5中支持了 iOS metal 着色器的预编译。
Flutter gallery应用预热前后,在Moto G4上从~90ms减少到~40ms,在iPhone 4s上从~300ms减少到
~80ms,性能提升很明显。
在Flutter官方提供了SkSL着色器预热后,社区经常提到的一些高频问题收集如下:
Q1. 为什么不预编译用到的所有着色器?
为了获得最佳性能,Skia GPU backend在运行时会根据一些参数(如绘图命令,设备型号等)动态生成着色器。这些参数的组合会生成大量的着色器,无法在应用程序中预编译和内置。
Q2. 不同设备上捕获的 SkSL shader 通用吗?
理论上,没有机制保证在一台设备上捕获的 SkSL shader 在其他设备上也有效。实际上,(有限的)测试表明SkSL shader 能表现的较好,即使在iOS上捕获的 SkSL 应用到Android设备,或者模拟器上捕获的SkSL应用到真机上。
带你读《2022技术人的百宝黑皮书》——Flutter 新一代图形渲染器 Impeller(2)https://developer.aliyun.com/article/1340790?groupCode=taobaotech