消除动效研发成本:腾讯 PAG 动效解决方案
本文作者
陈仁健,腾讯 OVBU 媒资产品中心副总监,曾主导过开源 UI 框架 FlexLite 与 Egret 游戏引擎的设计研发。2018 年加入腾讯,作为腾讯多媒体技术委员会下 AVGenerator Oteam 核心 PMC 成员,持续专注在音视频编辑、图形图像特效、C++ 跨平台渲染等领域。主导研发的中台组件 PAG 动画解决方案已接入服务了 400+ 应用,包含微信、QQ、王者荣耀、小红书等头部 App,并于 2022 年 1 月正式对外开源。
T Chat|我在大厂做研发 系列直播第 16 场活动已圆满结束,本次活动我们在 T 技术沙龙 B 站账号、老司机技术视频号、CSDN 三个渠道直播,累计观看用户达到了 3000+ 人,同时在线观看人数最多 400+ 人。
下方为 Part.1 技术分享部分(45 分钟),本文为视频内容的文字总结(ps. 阅读原文,可获取 PPT!)
由于篇幅问题,1v1 访谈部分请看下一篇文章《T Chat: 1v1 访谈 - 对话 PAG 负责人陈仁健》
前言
动画是用户交互体验中至关重要的一环,为了降低或消除动画研发相关的成本,我们历时 5 年研发了一套 PAG 动效工作流的解决方案,能够一键将 AE 动画内容导出并应用到几乎所有的主流平台。本次分享除了介绍 PAG 的整体工作流及诞生背景外,将重点解读在产品需求驱动下遇到的重点技术挑战和架构演进细节,包括:动画文件的极限压缩原理,如何支持所有 AE 特性的导出,以及让 SDK 包体直线降低 65% 的全新渲染引擎等。
PAG 诞生背景
PAG 主要是诞生在音视频编辑场景下的。这是微视的一期运营海报,可以看到里面包含大量的视频动效素材。包括动画贴纸,转场特效,以及天气和地理位置等带动效的智能文本。对音视频发布来说,这些动效素材的生产需求是源源不断的,并且对产量,上线速度,以及视觉效果都有比较高的要求。
视频动效的需求量很大,但实现起来成本并不低。传统的思路是设计师使用 AE 先设计好动效,然后导出视频 Demo。研发再来根据 Demo 拆解动效组成。如果是不支持的特效能力,还需要单独排期进行开发。即使是已经支持的特效,还要花费大量时间手动还原动效的各种属性配置和时间轴,并与设计师反复联调确认还原度,最后再由运营验证素材配置上线。这套流程有几个核心的痛点:
第一是研发成本高:每个动效都需要研发通过代码来还原,单独排期的特效以及手工配置还原的过程,都需要大量的研发人力持续投入。由于研发人力有限,也导致这个流程无法批量化生产素材。
第二是生产周期长:设计师和研发人员的联调成本高,效果还原度需要反复确认。之前生产一个典型的视频模板,平均需要研发投入 5 人天还原才能上线。这样很难跟上运营节奏,容易错过时事热点。
第三是视觉动效弱:AE 里有很多复杂动效,使用纯代码还原起来非常困难,设计师只能不断简化效果以达到跟开发成本的平衡。导致最终上线的视觉效果都是打折过的,不达预期。
要彻底解决这些核心痛点,我们需要一套自动化的素材生产通路。
PAG 方案概述
PAG 动效工作流
PAG 目标是降低或消除动效相关的研发成本,打通设计师创作到素材上线的自动化工作流。整套工作流主要分为左边的 AE 导出插件和桌面预览工具部分,以及右边的 SDK 部分。AE 导出插件能够直接将设计师制作好的动效导出成 PAG 文件,经过桌面预览工具的确认,再上线到终端由 PAG SDK 渲染成动效内容。可以发现左边的部分实际上是不需要研发介入的,我们将之前需要研发介入的工作都变成了自动化的工具。整套工作流完美解决了传统工作流的三个核心痛点:
第一,研发成本方面:在 PAG 的动效工作流里,研发只有一次性接入 SDK 的成本,在后续整个素材生产流程都无需研发人力介入。整套工作流不再受制于研发的人力瓶颈,就能够开放给更多的设计师使用,批量化的进行素材生产。
第二,生产周期方面:由于砍掉了研发成本,最耗时的研发和设计的联调环节也不存在了。设计师可以所见即所得的生产素材,极大地缩短了生产周期,视频模板平均生产耗时从一周降低到四个小时,可以快速响应运营热点。
第三,视觉动效方面:PAG 的 SDK 已经完全还原了 AE 整个动效的渲染系统,接入一次,设计师就可以充分利用 AE 动效的原子能力,组合出无限的视觉动效,不用因为代码还原成本的问题而打折扣。
通过以上视频演示可以看到,设计师在制作完模板后,只需要很简单地点击菜单里的导出选项即可得到一个 PAG 文件,不需要任何复杂的配置过程。导出的文件双击就能直接播放,而且预览工具里还提供文本和占位图的编辑能力,可以直接看到替换用户素材后的效果。在经过预览工具的确认之后,设计师就可以将 PAG 文件交付上线了。通过 PAG 的 SDK 可以一次性渲染到几乎所有的主流平台上。
PAG 应用场景
PAG 方案虽然诞生在视频编辑场景下,但同样也适用于其他各种场景下的动效需求。这是到目前为止 PAG 的 5 个典型应用场景。直播礼物,UI 动画,贴纸花字,视频模板,和游戏战报。从左到右对编辑性的要求也依次提高。
目前微信视频号的直播就在采用 PAG 方案实现所有的礼物动效,也用在了之前西城男孩的线上演唱会里。
UI 动画这里演示的 Pick 按钮是一个 PAG 的可交互动效,支持编程控制进度、文本内容。整个动效文件体积非常小,仅 2KB 左右。
贴纸花字和视频模板相信大家在短视频产品中都已经非常熟悉了。其中 PAG 的视频模板现在也大规模地应用在了广告视频的生成中。
游戏战报场景使用了 PAG 提供的图层组合能力,可以从多个 PAG 文件动态组合出一个自适应的模板,相当于活字印刷的功能。这块目前的已经在王者荣耀以及和平精英的高光时刻战报功能里得到了充分的应用。
PAG 与同类方案对比
行业里跟 PAG 相似的解决方案还有 Lottie 和 SVGA,这三个方案背后其实存在一个比较有意思的共同点:它们的作者都具有 Flash 相关的研发背景。Flash 是历史上把研发和设计师的工作流打通的最为完善的平台,但是从 PC 时代过渡到移动端后,这里就出现了彻底的断层。这三个方案其实都是在将原先繁荣的 Flash 工作流复刻到移动端上,一起在推动行业动效工作流的持续完善。除了诞生场景的不同,目前 PAG 相比其他方案在文件格式,渲染架构,AE 特性支持,运行时编辑以及平台支持等各方面都更具有优势。相同的动画内容,PAG 导出的文件只有其他方案一半大小,额外还支持全部的 AE 特性导出,更丰富的运行时编辑接口,以及有对几乎所有主流平台的覆盖。
PAG 架构演进
1.0
PAG 方案到目前为止已经迭代了 5 年多,共经历 4 个大版本。在 1.0 版本时,我们的主要需求是在视频上叠加各种带动效的贴纸花字,并在保留预设动效的前提下提供文本的编辑能力。但当时刚刚发布的 Lottie 并不能满足以上需求,除了文本无法编辑外,整个方案也无法用于视频编辑场景下。因此我们从最底层开始实现了一套类似游戏引擎的渲染架构,能够无缝地跟视频渲染管线整合,并通过三级缓存等架构的设计满足了极高的实时性需求。另外在这个版本中,我们花了最多时间的部分还是在 PAG 文件格式的设计上。PAG 大量吸收借鉴了 Flash 的成熟文件格式设计,并针对 AE 时间轴的特点做了进一步的极限压缩。最终实现了相同动效内容只有 Lottie 一半左右的导出大小,而且解码平均还快 12 倍。PAG 的 1.0 版本可以总结为我们实现了一个全方位更好的 Lottie,在功能跟它对齐的情况下,性能,文件大小和使用场景上都全面更有优势。
2.0
但 1.0 版本的 PAG 和 Lottie 一样都只能支持 AE 里有限的矢量特性导出,我们在迭代过程中很快就收到大量设计师的痛点反馈,很多的素材都需要不断的删减效果才能完成上线,这样会极大限制设计师的创意发挥。于是我们在 2.0 版本里重点引入了 BMP 预合成的解决方案,并且比较创新的实现了矢量和序列帧的混合导出能力,从而在保留编辑性的前提下又实现了所有的 AE 特性的导出,从这个版本开始才真正意义上彻底释放了设计师的生产力。另外在这个版本中,我们还引入了占位图的概念来解决视频模板的需求,核心原理就是运行时将视频逐帧替换到指定的占位图上,由 PAG 文件来控制视频的画面动效和层级关系,输出完整的内容。设计师在制作视频模板时,只要添加一个占位图并当成视频处理就行,对它应用的任何变换和特效最终都会作用到替换后的视频上。这样可以把模板的创意生产完全交给设计师发挥,最终让照片或视频模板等应用场景进入了工业化批量生产的时代。
3.0
到 PAG 3.0 时,我们在运行时编辑性方面又遇到了新的挑战。在新出现的一键出片和游戏战报这些场景下,模板不再是单个 PAG 文件,而是引入了一个前置位分析的过程,会根据用户传的视频内容,随机生成一个自适应的模板。2.0 的单 PAG 模板更像是一个命题作文,让用户传视频或照片填空的模式。而 3.0 的模板存在无限种可能性,设计师也没法靠穷举每种可能性去生产素材。最佳方式是生产一个个小的 PAG 效果组件,然后进行拼装组合。基于这个目标,我们在 3.0 引入了图层渲染树的编辑架构。让素材的最小控制单元由文件变成了图层。一个文件就是一棵渲染树,内部每个图层都可以任意增删改,也可以把多个 PAG 文件组合成一棵新的渲染树。同时每个图层都同时具有空间位置和时间轴的调整能力。经过这些改造,新的接口不仅很好地满足了类似王者战报这样的需求场景,也为海量素材播放提供了新的优化可能,不再需要给每个动效创建独立的上下文,而是可以组合在一起共享同一个上下文渲染,实现性能的大幅提升。
4.0
在 PAG 的前 3 个大版本的迭代过程中,大部分的业务痛点问题都已经得到了很好的解决和覆盖。但是我们始终还存在 2 个难以回避的痛点:首先是在 SDK 的包体方面,绝大部分业务都对包体有很严格的要求,因为直接关系到增长拉新的数据,有的业务甚至要求接入后 0 增量。但在 4.0 版本之前,由于 PAG 依赖的 Skia 绘图引擎本身就占据了 80% 左右的包体,导致我们很难进一步优化。另外在平台支持方面,我们一直也还没补全对 Web 平台的支持。核心原因其实也是背后 Skia 所带来的限制。我们希望通过 WebAssembly+WebGL 的技术来实现跨平台渲染的一致性,确保 Web 端没有能力层面的阉割。但 Skia 的 Webassembly 版本存在包体巨大并且无法访问浏览器中文字体等缺陷,导致我们一直没有启动 Web 版本的支持。到 4.0 版本我们在上层能做的工作已经差不多到极限了,要继续突破只能深入到渲染引擎底层替换掉 Skia。因此我们花了将近一年半的时间从头实现了一套全新的纯 GPU 绘图引擎 TGFX,最终将 PAG 包体直线降低了 65% 左右,并将 PAG 的完整能力扩展到了 Web 端。
PAG 的技术挑战
挑战一:动效文件如何压缩到仅 Lottie 一半左右大小?
一个 AE 动效文件通常是这样层层包含的树状结构,其中时间轴属性是 AE 动效的最基本单元。它控制了一个目标值随着时间轴应该如何变化的规则。AE 动效的原理就是无数的时间轴属性随着时间变化,构成了每个瞬时的画面。那这样的一个 AE 动效文件,应该如何存储起来最高效呢?这里我们定了三个核心目标:单文件交付,解码速度快,动效文件小。单文件交付主要解决工作流中文件传递的效率,解码速度会影响首帧的播放体验,动效文件大小除了节省用户的下载时长,在很多 App 中也会直接关系到增长拉新的效果。
基于以上的目标,我们首先采用了二进制的数据结构来存储动效内容。因为二进制数据结构能够非常方便的单文件集成任何资源,并且由于不需要像 JSON 一样处理字符串匹配问题,解码速度可以快几十倍。而在压缩率方面,二进制数据结构可以跳过 Key 的内容,只存储 Value,这样也能节省大量空间。另外我们还引入了 TAG 数据块的结构,来解决二进制数据的向后兼容性问题。每个 PAG 文件都由无数个互相独立的 TAG 组成,扩展格式只需新增 TAG 即可。高版本 SDK 可以识别低版本所有的 TAG,低版本 SDK 遇到无法识别的 TAG 会跳过读取,如果不是关键的信息也可以正常解码不影响渲染。做到这个程度基本上已经满足前面提到的三个目标了,但也只是对齐了行业里通用序列化方案的上限,而在压缩率方面我们其实还有很大的空间,原理就是根据动效文件本身的特点跨越字节边界来压缩。
极限压缩这块主要有两个策略,核心就是要充分利用 AE 动效文件本身的特点:第一个策略是等于默认值可无需存储。时间轴属性是 AE 动效的最基本组成单元,而通常情况下大部分时间轴属性都等于默认值。这里可以用一个标志位就跳过默认值的存储。例如一个 Point 类型的时间轴属性,默认值最少需要 8 个字节存储。而我们如果使用一个字节的标志位来跳过默存储,单个属性就可以节省 7 个字节的空间。这是非常可观的。
第二个策略是是尽量聚合相似数据类型。我们在文件的每个属性组里,都会尽可能地把相似的数据重新排列,让他们聚合到一起。这样就可以绕开字节对齐的问题,使用比特位来紧凑存储。例如中间这一组的属性,经过重新排列后,符号位的区域可从 4 字节降到 4 比特,内容的区域还可以利用右边的连续数组编码压缩,平均减少一半以上的文件大小。
经过以上的压缩策略,我们就可以把一个动效文件尽可能地压缩到最小。这里是一些 PAG 和 Lottie 的动效文件大小的对比数据,两者都进行了 zip 压缩之后再进行对比,可以看到相同的动效内容平均 PAG 只有 Lottie 文件的 56%大小。如果不进行 zip 压缩,差距还会更大。
挑战二:渲染架构如何适配适配编辑场景下的复杂需求?
PAG 渲染架构设计这里我们也定了两个核心的目标:要能在视频合成中无缝渲染,并且性能方面要满足实时预览的流畅需求。先说第一个目标。现代的视频编辑框架都是基于 GPU 渲染的,接受的输入必须是纹理才可以获得最高的性能,并且视频导出大多需要运行在子线程,否则会严重卡顿 UI。Lottie 的主要问题就是依赖了平台相关的 UI 组件去开发,这样虽然开发成本比较低,但限制了不能直接输出到纹理,也无法运行在子线程里。而 PAG 的整套方案是基于跨平台的 C++ 和 OpenGL 研发的,一直从最底层的文件编解码,实现到上层的图层渲染树。虽然开发成本比较高,但是所有端共享同一套代码,天然的能保障跨端渲染的一致性。关键是能直接渲染到视频编辑框架提供的目标纹理上,并完美支持子线程渲染。
在解决了能不能的问题之后,还要考虑如何进一步优化。在视频编辑的场景里,对性能的要求很严格的。因为每帧并行地会存在视频编解码,以及各种特效处理,这时候留给 PAG 的渲染时间就不太多了。因此我们要尽可能地把 PAG 的渲染性能优化到极致,来满足视频编辑的实时预览需求。第一个方向是利用素材静态区间可跳过重复绘制。大部分的动效素材,实际上并不是整个时间轴都在变化的,或多或少会存在一些画面静止的区间。而 PAG 在刷新时,如果遇到这些静态区间,会直接返回上一帧的缓存内容,自动跳过任何重复的绘制。极限情况下,假设有一个一分钟的动效素材,但实际上全程都是静止的。它对 PAG 来说就相当于一张静态图片,整个刷新的过程中都是 0 开销。而在 Lottie 方案中,整个刷新过程都是全量的开销,因为它每帧都会清空屏幕重新刷新。
第二个方向是利用空间换时间的思路。我们在 PAG 里设计了三级缓存的架构:文件缓存,绘制缓存,和内容缓存。由下至上占用内存依次提高,加速效果也是依次更明显。在文件缓存层面,我们将解码后的对象设计成了可复用的。同一个动效文件只需要解码一次,就可以被复用到无限个动效实例中渲染。在绘制缓存层面,我们缓存了每帧的贝塞尔曲线插值以及计算完的文本和矢量等数据。这里还结合了静态区间的特点去优化,每个图层如果存在静态区间,都只缓存静态区间第一帧的数据。这样就可以达到最少的内存换来最大的缓存加速效果。最后在内容缓存的层面,我们会将一些内容静态但是非常复杂的图形缓存成纹理。但我们会在保证清晰度的前提下,只缓存最小的面积。例如一个 500x500 的动效,如果实际是按照 50x50 在播放,我们只会缓存 50x50 大小的面积。以上这些缓存都是渐进式生成的,再结合静态区间的特点,可以节省大量的重复计算。
挑战三:如何让设计师在 AE 里制作的所有效果都可以导出?
Lottie 的方案到今天都只支持纯矢量的导出方式。矢量导出方式优势就是文件极小,并且可以运行时编辑动效的内容。但这种方式注定无法支持所有 AE 特性,因为有很多的 AE 效果在有桌面显卡的情况下,都要走一个进度条才能预览,在移动端是没有可能做到实时渲染的。这也导致在实际的生产过程中,设计师有很多的复杂动效,都无法用矢量模式导出出来,这样会极大限制设计师的创意发挥。而传统的序列帧导出方式,运行时又无法编辑,文件也相对较大。PAG 方案在这里的创新点就是将两者的进行了完美整合,支持矢量和序列帧的混合导出。设计师可以主动标记哪些图层使用序列帧导出,例如不需要编辑并且有复杂的动效,而需要编辑的图层继续用简单的矢量方式导出。从而实现支持所有的 AE 特性又能保持运行时的编辑性。
在实现混合导出后,剩下的挑战就是怎么尽可能压缩序列帧的大小。我们在 PAG 内部设计了视频序列帧的格式,充分利用了视频的极限帧间压缩能力。另外视频的格式还可以在运行时利用硬件加速解码,从而获得更高的渲染性能。但它也有一个明显缺点,就是不支持透明通道。我们会在导出时,会将一张 RGBA 的截图扩展成两倍大小的不透明图片,左边放置 RGB 的内容,右边放置表示 Alpha 的灰度图。最后渲染时再合并回 RGBA 的图片,从而实现透明通道的支持。而在渲染的过程中,我们没有像常规做法一样先转换 YUV 到 RGB,再叠加 Alpha 通道的合并,而是直接实现了各种 YUV 硬解格式的一次性上屏,利用自定义 Shader 脚本,在一次绘制中同时完成 YUV 到 RGB 的转换以及与 Alpha 通道的合并,让视频序列帧也实现了接近普通图片一样的绘制性能。
解决了单个视频帧的导出和渲染后,我们还要考虑上层的数据封装格式。PAG 并没有使用标准的 MP4 容器作为视频帧的封装,而是设计了一个简化的数据结构。主要还是出于性能优化的原因。第一个方面是因为动效播放是存在随机性的,我们需要一次性拿到所有的关键帧列表,才可以做到精确的判断是否需要重置解码器,但要从标准的 MP4 容器里获取关键帧列表,耗时会非常高。另外一方面,视频序列帧本质上还是代表了一个动效,因此也存在前面提到过的静态区间。在导出时我们会根据静态区间来插入关键帧,并把静态区间存入自定义数据结构。这样在渲染时,就可以直接跳过不必要的解码器等待。例如右边这个俄罗斯方块的视频模板,每个方块虽然都是一个静态图层,但是使用了矢量不支持的效果,因此就会导出一个全时长都是静态的视频序列帧,这种情况也是比较常见的。而通过刚刚的优化,直接能够提升 99%的性能。
最后可以看一下各种序列帧方案文件大小的对比。相比传统的图片序列帧,视频序列帧可以轻松压缩到百分之一点几的大小。
挑战四:如何替换掉 Skia 取得包体和性能的进一步突破?
首先看一下为什么不继续使用 Skia?目前谷歌开源的 Skia 2D 绘图库是行业里事实标准,多年来几乎没有任何实质性的可替代方案出现,Chrome,Firefox,Flutter,Adobe 系列软件,乃至 Android 系统都在基于 Skia 做文本和矢量的绘制。但 Skia 本身是一个维护了近 20 年的方案,也存在很多的历史包袱,很难满足 PAG 对包体和性能的进一步优化需求。在包体方面,我们虽然已经针对 Skia 做了非常多的定制和裁剪,但是它依然占据了 PAG 3.0 版本 80% 左右的包体,也无法再进一步进行裁剪。而在性能方面,由于 Skia 需要兼容历史遗留的 CPU 绘制模式,在 API 上暴露会比较保守,很多针对现代 GPU 绘制管线可以进一步优化的接口都没暴露出来。另外由于 Skia 是针对 UI 这种随机绘制设计的引擎,内部做了大量的缓存来确保随机渲染的性能,但对于动效这种可预测的渲染模式没有很好的优化,会导致额外浪费了过多的内存。为了彻底突破包体和性能的限制,我们花了将近一年半的时间自研实现了一套轻量的纯 GPU 绘图引擎 TGFX,完成了对 Skia 的替换。
下面看一下 TGFX 具体做了哪些优化。在包体方面,我们最终以 400K 左右的包体覆盖了 Skia 近 2M 包体的绝大部分功能。核心优化策略主要有两点:
第一点是我们彻底抛弃了 CPU 渲染管线。因为现代的硬件已经几乎不存在没有 GPU 的设备了,即使像服务器端这种特殊的场景,通过 Swiftshader 来模拟 GPU 得到的性能也会让你很意外。但 Skia 由于历史原因一直同时包含了 CPU 和 GPU 的两条渲染管线,并且由于它的 GPU 渲染管线重度依赖 CPU 的部分,导致没法单独使用它的 GPU 渲染管线。我们在 TGFX 中彻底解决了这个耦合的问题,打造出了一个纯 GPU 的绘图引擎,这里就节省了大概一半的包体。
第二点是最大化的利用平台端内置的所有能力。例如图片解码,字体解析,矢量栅格化等等,这些都会优先使用系统原生的接口替代内置第三方库的策略。以文本和矢量的栅格化为例,在 iOS 上我们直接使用了系统提供的 CoreGraphics,文本方面则利用起 CoreText 等。而在其他平台才嵌入了 Freetype。虽然增加了不同平台适配的工作量,但是包体确实也获得了极致的优化。
在易用性方面,TGFX 也做了一些改进,尤其是这个 Skia 没有的 Device & Window 系统。Skia 虽然提供了 GPU 的渲染管线,但要用起来门槛还是比较高的。主要存在两个问题:
第一点是 Skia 只实现了跨平台渲染的部分,所有跟平台相关的视图桥接以及上下文的初始化都需要用户自己处理。这会导致用户正常用起来 Skia 的 GPU 模式需要对每个平台写大量的适配代码。除了工作量大外这部分还是兼容性的重灾区,要处理很多类似 iOS 中退到后台执行 OpenGL 的特殊情况。
第二点是 Skia 并不帮你保证线程安全或者上下文状态的切换,默认都由调用方自己处理。但绝大部分刚刚接触 Skia 的用户并不清楚这里的坑点,Skia 也没有显式说明过,按普通的方式接入使用,很容易就造成大量的显存泄露以及难以排查的随机 Crash。
但 TGFX 提供了完善的 Device & Window 系统,可以帮你把这些问题一次性都彻底解决,只要按照统一的模式进行调用,所有平台相关的复杂度都可以不用关心,并且从 API 上限制了你必须以线程安全的方式进行调用。即使没有非常资深的 GPU 渲染经验也可以很容易上手使用。
在性能和架构方面,可以快速看一下 TGFX 还做了哪些额外的优化:左边第一个,我们默认开启了 HardwareBuffer 的支持,来全面加速纹理的提交。这里重点是利用了运行时反射的机制彻底解决了设备兼容的问题,只要设备和系统存在这块能力我们就会自动开启。
左边第二个,因为没有兼容 CPU 模式的包袱,我们直接暴露了 Path 对应的 GPU 高速缓存,这样可以让业务有能力直接缓存最关键的 GPU 对象,避免每次绘制 Path 都重复生成缓存。
左边第三个,TGFX 彻底改进了 Skia 的 GPU 对象管理模型,所有的 GPU 对象都可以在任意线程释放,等关联的上下文激活时才真正清理,避免了在 Skia 中经常出现的随机 Crash 和泄露问题。
右边第一个,我们在 TGFX 的接口设计上约束了调用方在解码完图片只会缓存 GPU 的纹理部分,这样理论上全局可以直接降低一半的内存占用,避免像 Skia 里一样图片总是重复占用双份内存。
右边第二个,TGFX 把管理缓存的主动权交给了上层业务,这样可以上层更精确地管理缓存,不会像 Skia 一样内部产生过多的冗余缓存,只是通过设置一个上限才来触发清理。
右边最后一个,TGFX 在全平台都实现了默认字体的读取能力,包括读取浏览器的默认字体库。解决了 Skia 的 Web 版本在这块的缺陷,避免了渲染中文要下载上百 M 的字体包的问题。
以上这些还只是 TGFX 做的优化的一部分,更多的细节欢迎大家到 Github 源代码中参考研究。
最后来看一下成果,在我们把 Skia 彻底替换为 TGFX 绘图引擎后,PAG 4.0 版本的包体整体平均都下降了 65%左右,并且矢量渲染性能平均还提升了 60% 左右。整体的优化非常显著。后续我们也正在推动 TGFX 作为一个独立仓库开源。我们会持续完善并把它打造为一个通用的 2D 绘图引擎,为行业提供 Skia 之外的另一个轻量化的选择。
PAG 总结与展望
PAG 方案价值
PAG 方案诞生在最复杂的视频编辑下,也能够很好的满足其他各种场景下的动效需求。它提的供所见即所得的桌面工具和 AE 插件,能够一键将设计师的创意导出成 PAG 文件,并通过 SDK 快速渲染到几乎所有的主流平台上。整套工作流给业务带来了三方面的核心价值:
第一,去研发成本:素材生产环节无需研发介入,节省大量研发人力和调试返工成本。研发只需要接入一次 SDK 的成本,后续设计师可以独立完成素材的生产上线,也避免了最耗时的研发和设计的联调环节,最终将素材生产相关的研发成本大幅降低。
第二,工业化生产:由于不再受到研发人力瓶颈的限制,素材生产可以扩大到更多的设计师进行批量化生产。再加上桌面效率工具在效果预览和性能检测上的易用性,设计师可以所见即所得地生产素材,最终让视频模板平均生产耗时从一周降低到四个小时,实现快速响应运营热点。
第三,无限 AE 动效:PAG 的 SDK 已经完全还原了 AE 的整个动效渲染系统,并支持矢量和序列帧混合导出,接入一次,设计师就可以复用 PAG 经过 5 年积累的 AE 动效原子能力,组合出无限的视觉动效,不用因为代码还原成本的问题而对效果打折扣。
PAG 开源成果
PAG 已于今年 1 月 14 日正式开源至 Github,到目前已获得 2000+ star 数,官网累计上线 46 篇文档教程,团队日常对接 2300+ 持续增长的设计师和研发用户群,SDK 也已接入服务了腾讯内外 400+ 产品业务,包括微信,手机 QQ,王者荣耀,腾讯视频,QQ 音乐等头部 App,稳定性经过了海量用户的持续验证。
PAG 未来展望
最后是展望部分。过去一年多,我们团队主要的精力都投入到了 PAG 4.0 全新渲染引擎的升级上,目的也是为了后续整个 PAG 方案能有更高的天花板。接下来我们的重心会主要聚焦在以下四个方向上:首先会开始继续补全更多的 AE 特性支持,前面虽然我们依靠 BMP 预合成能力已经能导出所有 AE 特效,但用那个方式导出无法运行时编辑,所以我们围绕可编辑的图层还是需要继续补全 AE 特性支持。其次是会继续完善我们的工具链,重点会推出图层级别的性能分析工具,帮助设计师快速定位素材的性能热点,高效完成性能调优。然后是 TGFX 框架的持续迭代完善,继续增加更多渲染后端,适配 Metal 和 Vulkan 等硬件图形接口,最大化发挥现代 GPU 硬件的渲染性能。最后是会尝试搭建一个动效素材的开放平台,帮助企业快速触达海量的商用素材和优质设计师资源。
PAG 相关资源
感兴趣的朋友可以通过以下方式进一步了解 PAG
官网(下载及教程):https://pag.art/
QQ 群(用户交流):893379574
官方论坛(问题解决&官方互动):https://bbs.pag.art/
Github(源码研究&开源共建):https://github.com/Tencent/libpag
微信扫码关注该文公众号作者