经过一年半时间的紧张研发以及灰度验证,我们很高兴地宣布 PAG 4.0 版本于今天正式发布。这个版本可能是 PAG 迭代到目前最大的一次升级,主要侧重在渲染引擎内核的升级和更多平台的支持上。在渲染引擎方面,PAG 4.0 完成了将 Skia 替换为自研的全新绘图引擎 TGFX ,为 SDK 在包体和性能上取进一步的突破打下了坚实基础,最终在包体上直线降低了约 65% 左右,并在矢量渲染性能方面提升了约 60%。另外,4.0 版本新增了对 Web 平台的渲染支持,也标志着 PAG SDK 完成了对几乎所有主流平台的全面覆盖。
4.0 版本主要修改内容
1、功能层面
接口变更
· 移除 2.0 版本中标注废弃的接口,如果使用了废弃接口,需要切换至最新接口
· PAGPlayer C 层增加 autoClear 接口,允许不清空屏幕绘制
· PAGPlayer 增加 prepare 接口, 用于加速首帧渲染
· PAGSurface 增加 makeSnapshot 接口,用于获取单帧渲染内容
软解注入
在兼容支持之前软件解码注入方式的基础上,新提供了 ffavc 软件解码注入库:
· iOS 端由于硬件解码比较完善,提供的版本默认不带软解,支持通过 CocoaPods 拉取 ffavc 注入;
· Android 端提供了两个版本:默认版本内置 ffavc,以及不带 ffavc 的版本
· Web 端提供了 ffavc 的 wasm 文件供注入使用
预编译库
· Android 端 pag 动态库的名称由之前的 “libpag” 修改为跟其他平台一致的 “pag”,如果使用 so 插件下发,需要使用"pag"字符串进行加载
· iOS 端库构建产物全面切换为 XCFramework 形式,更好的兼容最新的 Xcode 使用,不再发布 framework 形式的包
问题修复
· 修复 Android、iOS 端使用 PNG 图片替换占位图解码时发生 crash 的问题;
· 修复 PAGView 播放逻辑,一次播放结束后再调用 play 方法可自动从头播放;
· 修复荣耀畅玩 6x 渲染异常问题;
· 修复 iPhone 5s 上使用 CVPixelBuffer 时纹理混合不起作用问题;
· 修复 Android 侧 JNI 野指针 crash 问题
2、渲染架构升级
底层渲染引擎由 Skia 切换为自研绘制引擎 TGFX。
3、平台支持
通过 WebAssembly 技术增加了 Web 端支持,目前 SDK 已全面覆盖:iOS,Android,macOS,Windows,Linux 和 Web 等所有主流平台。
渲染架构升级解读
1、升级背景
包体大小
在 PAG 的前 3 个大版本的迭代过程中,大部分的业务痛点问题都已经得到了很好的解决和覆盖。在平台侧支持方面,虽然 PAG 覆盖了 Android、iOS、macOS、Windows、Linux 平台,但是对于 Web 端始终没有支持。在 Web 端,Lottie 和 SVGA 使用 Web 的 HTML、CSS 和 Javascript 重新实现了一遍,而 PAG 全平台共享一套 C 代码的架构,我们期待通过 WebAssembly 来支持 Web 端,来实现跨平台的渲染一致性。其中遇到的最大的问题就是包体问题,针对 Web 端编译完的 wasm 文件大小为 3MB 多,这个包体对于 Web 而言有些偏大。
同时,在某些头部的 App 对接过程中,甚至要求接入后包体 0 增量。对于大部分应用来说,包体直接影响增长拉新的数据,因此包体优化确实是个刚需。
在之前的版本里,我们的渲染架构由于依赖了谷歌的 Skia 2D 绘图库,虽然我们已经针对性做了非常多的定制和裁剪,但是 Skia 依然占据了 PAG SDK 80% 左右的包体,无法再进一步进行裁剪。
性能优化
而在性能方面,PAG 3.0 版本上层的 PAG 渲染架构已经做了游戏引擎几乎所有能做的优化策略。但是由于 Skia 需要兼容历史遗留的 CPU 绘制模式,在 API 上暴露会比较保守,很多针对现代 GPU 绘制管线可以进一步优化性能的接口都没暴露出来。另外由于 Skia 是针对 UI 这种随机绘制设计的引擎,内部做了大量的缓存来确保随机渲染的性能,而对于动画这种可预测的渲染模式没有很好的优化,如果针对性优化可以有效降低平均的内存占用。整体上由于渲染对 Skia 的依赖,导致我们在性能上想要进一步突破也遇到了瓶颈。
2、全新绘图引擎 TGFX
为了彻底打破包体和性能的限制,我们花了将近一年半的时间自研实现了一套轻量的纯 GPU 绘图引擎
包体优化策略
相对于 Skia,Skia 需要兼容 CPU 绘制管线,而 TGFX 没有历史包袱,不需要去兼容那些逻辑,可以采用全 GPU 渲染方案,这里节省了绝大部分包体。
同时,对于图片解码、文字解析、Path 绘制等,我们优先使用了平台端提供的能力,例如复杂矢量图形的栅格化, iOS 直接使用平台自带的 CoreGraphics,文本方面利用起 CoreText ,Android 端图片解码通过 JNI 调用系统接口等,只有当平台端的能力无法覆盖的使用,才会考虑引入图片解码库或者 FreeType 等第三方依赖。尽最大可能利用平台端已有能力也对我们包体优化起到了较为显著的作用。
多 GPU 渲染后端支持
TGFX 从设计之初就考虑了多 GPU 渲染后端的架构,目前已经完全实现了 OpenGL 的渲染后端全平台支持,接下来会逐步补全 Metal 以及 Vulkan 等后端的实现。在原生平台适配方面,我们也新增了更加完善的 Device & Window 系统,可以完美解决线程安全以及退后台等平台相关兼容性问题,在 OpenGL 方面已通过 EGL,EAGL,CGL,WebGL,QT 等接口全面适配了所有主流平台的原生窗口系统。
性能及架构优化
在接口设计上,TGFX 充分暴露了针对 GPU 渲染的优化能力给到调用层,例如提交纹理后统一不再重复缓存一份 CPU 图片;文字图集的缓存交给上层精确控制;暴露 Path 拆解为三角形数据后的缓存接口,并在移动端全面开启了 HardwareBuffer 接口来加速纹理提交。在减小包体和内存占用的同时进一步提升了渲染性能的天花板。在接口易用性方面也自带线程安全的设计,所有 GPU 资源统一管理,外部任意线程释放引用都可以确保正确销毁,降低了使用 Skia 的 GPU 绘制模式时,容易出错并需要大量封装平台相关上下文代码的门槛。
3、Web 平台支持
在去掉 Skia 之后,我们通过 Emscripten 把 PAG 的 C 代码编译为 WebAssembly,运行在 Web 浏览器中。这样 PAG 只需要维护同一份 C 代码,然后编译到不同平台,各个平台的效果也能保持一致。在 Web 端我们同样遵循了最大化利用平台端能力的原则来继续优化包体,例如采用 Canvas2D 接口来绘制 Path 和文本内容,使用 Video 标签实现硬件加速解码视频序列帧,使用浏览器自带的图片解码能力等。除了包体优化外,我们还补全了 Skia 的 Web 版本无法读取浏览器默认字体的缺陷,避免了在渲染 CJK 文本内容时,必须下载上百 MB 默认字体的下载压力,并且在 TGFX 层面封装了全平台统一的字体接口。
PAG 4.0 升级收益
1、SDK 包体显著降低
相对比 PAG 3.0 版本,PAG 4.0 版本的包体 Android 端单架构压缩后由之前的 2.36MB 减少至0.89MB,iOS 端单架构压缩后由之前的 1.93MB 减少至 0.68MB,Web 端包体大小由之前的 3.0MB 减少至 0.72MB,分别减少了62.3%、64.8%、76.0%。
2、渲染性能提升
相比 PAG 3.0 版本,PAG 4.0 版本对于大部分矢量和文字动画素材的渲染,性能提升明显,矢量渲染性能平均提升 60% 左右。
3、Web 端支持
PAG 4.0 目前已经发布 Web 稳定版本,已完成对于常用浏览器的支持(如下图所示),更多的浏览器适配完善正在进行中。
总结
PAG 4.0 版本的发布,不仅实现了 SDK 在包体和性能上的进一步突破,以及新增 Web 平台的支持,还带来了 TGFX 这个全新的纯 GPU 绘图引擎,在 2D 绘图引擎领域为行业提供了 Skia 外的另一个选择。完成了渲染引擎的升级后,接下来 PAG 团队的重心会回归到更多新增 AE 特性的支持和工具链的完善上,也欢迎大家积极参与到需求建议或源码共建中来,帮助我们持续打造更加完善的动效工作流。
已正式开源
Github地址:https://github.com/Tencent/libpag
如果想了解、接入 PAG,欢迎访问 PAG 的官网或微信公众号