做者| 蒋卫星(韦青) 前端
出品|阿里巴巴新零售淘系技术部算法
本文内容大纲:编程
一、轻量级图形渲染引擎与应用小程序
二、渲染引擎演进与优化之路后端
三、渲染引擎将来的发展方向缓存
GCanvas 的定位是遵循 w3c 标准的跨平台的轻量级图形渲染引擎。有清晰的定位和目标,而且紧贴现有的业务,为业务提供丰富表现形式。架构
GCanvas 引擎从早期的 H5 性能加速,到 Weex 业务落地,从小游戏的业务探索,到服务端渲染,再到小程序。通过几个阶段的发展后日渐成熟。
框架
淘系无线架构的不断升级迭代,GCanvas 随之保持着更新迭代的步调,在多个业务场景中使用,了解下一些应用案例。机器学习
GCanvas 的目标人群是业务开发者,知足业务的功能需求,对开发者也很是友好,尤为是前端开发者。熟悉 H5 Canvas 的同窗,很容易上手,无任何学习成本。ide
Weex
2017年双十一预热会场,GCanvas 与魔影合做的版头动画
天猫将来店
天猫将来店的智能电子标签,基于 GCanvas JSBinding 的智能电子标签
小游戏
野生小伙伴,基于GCanvas小游戏应用
Sketch Render
Demo+ 中的 Sketch Render ,基于 GCanvas 实现的服务端渲染 Sketch 文件
支付宝小程序/淘宝商家应用Canvas
基于支付宝小程序/淘系商家应用同层渲染组件
支付宝小程序诸葛找房 - 2D
淘宝商家应用AR试妆 - WebGL
以业务先赢的基本原则,保证业务的前提下,架构容器和升级变化过程当中,GCanvas 引擎也经历了演进和升级优化。
2017年的架构
以插件为主的实现,仅支持移动端
最新架构
提供标准接口,链路升级,API升级,不只支持移动端还支持服务端
架构变化主要有如下几个方面:
适配支持更多的 JS 框架和库
JS 到 Native 调用通路,从模块路由反射升级到 JSBinding
渲染 API 支持 Metal
增长 MacOS 和 Linux 平台支持
► 内功修炼
在快速迭代太重中,保持修炼内功。为保证高性能这个根本,在链路、内核以及底层图形 API 等方面也都作了很多优化与升级。
JS 到 Native 链路优化
从 Weex 调用链路到 JSBinding,Weex 容器的 JS 到 Native 的通路采用模块路由和反射的调用方式调用具体的模块和组件。在 UI 和一些非高频的场景彻底能知足需求。
可是对于连续操做、连续动画等高频的 JS 到 Native 通信的场景,链路上的耗时很是大,致使卡顿产生。这也是为什会 BindingX 和 GCanvas 的 JSBinding 的出现。
BindingX是另外一种解决频发通信消耗的方案,有兴趣的能够看下BindingX。(地址戳阅读原文)
GCanvas 的 JSBinding 的实现:经过链路调用的改造,总体帧率平均提高10帧左右。Android 和 iOS 的 JSBinding 实现方案相似。
以 iOS 举例说明:iOS 尝试使用 JSExport 和全局方法,两种 JSBinding 方案。
第一种方案,使用 JSExport 和 JSExportAS
@import JavaScriptCore;
@import JavaScriptCore;
@protocol TestObjecJSExport <JSExport>
JSExportAs(foo, - (void)foo:(NSString *)msg);
@end
@protocol TestObjecJSExport <JSExport>JSExportAs(foo, - (void)foo:(NSString *)msg);@end
第二种方案,使用 C Export 将方法和属性用 JSStaticFunction 和 JSStaticValue 进行绑定
//方法JSStaticFunctiontypedef struct { const char* name; //方法名 JSObjectCallAsFunctionCallback callAsFunction; //Native方法实现 JSPropertyAttributes attributes; //方法设置} JSStaticFunction;
//方法JSStaticFunction
typedef struct {
const char* name; //方法名
JSObjectCallAsFunctionCallback callAsFunction; //Native方法实现
JSPropertyAttributes attributes; //方法设置
} JSStaticFunction;
//属性JSStaticValue
typedef struct {
const char* name; //属性名
JSObjectGetPropertyCallback getProperty; //Native属性Getter实现
JSObjectSetPropertyCallback setProperty; //Native属性Setter实现
JSPropertyAttributes attributes; //属性的读写设置
} JSStaticValue;
//属性JSStaticValuetypedef struct {const char* name; //属性名JSObjectGetPropertyCallback getProperty; //Native属性Getter实现JSObjectSetPropertyCallback setProperty; //Native属性Setter实现JSPropertyAttributes attributes; //属性的读写设置} JSStaticValue;
两种实现方案,通过测试对比第二种方案在性能更好。缘由在于静态 JS 方法是经过方法名到 Native 函数的直接映射,而 JSExport 的方案则须要类型检查,协议校验,再调用 Native 方法中间通过额外的处理。
简单的耗时测试数据对比:
JS 到 Native 数据传输
方法调用与属性访问以外,参数数据的传输也影响每帧耗时,尤为是在 WebGL 的场景,一般有很大顶 点数据须要处理,有几万-几十万字节,甚至更多。JS 到 Native 的大数据传输避免内存拷贝。
JS 与 Native 对象生命周期
JSBinding 的对象生命周期管理,JS 对象与 Native 对象一一对应,在 JS 对象建立触发 JSObjectInitializeCallback 回调,建立 Native 对象,并将 JS 与 Native 创建关联。JS 的 GC 回收对象触发 JSObjectFinalizeCallback 的回调中去释放对应 Native 对象。
帧率优化
除了调用链路对帧率的提高,单帧绘制的 CPU 和 GPU 耗时相关的优化点
顶点数据计算,顶点数据合并提交
优化缓存策略,优化文字相关纹理的缓存
增长状态管理,减小 GPU 提交数据和频次
优化多边形填充效率
抗锯齿等耗时特性可选
w3c 标准完善
支持阴影
支持虚线
支持多Clip区域嵌套
支持Winding Rule支持
扩展能力,扩展一些非标接口支持 Sketch 渲染,
阴影的扩散
路径的图案填充
路径的高斯模糊
路径的内描边和外描边
底层图形API升级
在 iOS12 以后,苹果将 OpenGL ES API 设为废弃,在已支持的设备上 OpenGL ES 的调用都已映射到 Metal 相应的后端实现,Metal 替换 OpenGL 势在必行。GCanvas 也已投入开发 Metal,可选择使用 Metal 做为渲染的后端。已完成了 2D 的绝大部分能力。
选择 Metal 会带来如下方面的收益:
内存数据使用更高效,内存数据可共享,
尽量的榨取更多 GPU 性能
摆脱 OpenGL 的状态机,更友好的面向对象编程
苹果后续的持续投入和更新
丰富的调试工具,能精确到每一个顶点数据和每一个素点颜色
便捷调试这着色器语言(Metal Shader Language)
在内核升级优化的过程当中,也有不少同窗积极参与其中来在此表示感谢。
增长了 API 的自动化测试以及 CI 创建保障稳定性。
GCanvas 开源社区加大投入增长社区影响力, 请你们积极关注并star
更多纹理压缩格式的支持
Vulkan 的持续演进
更多平台的支持,IoT 设备上应用
与云端渲染的融合,提供 Fass 能力
WebGPU 以及 GPU 计算方向探索
WebAssembly 的应用
We are hiring
淘系技术部依托淘系丰富的业务形态和海量的用户,咱们持续以技术驱动产品和商业创新,不断探索和衍生颠覆型互联网新技术,以更加智能、友好、普惠的科技深度重塑产业和用户体验,打造新商业。咱们不断吸引用户增加、机器学习、视觉算法、音视频通讯、数字媒体、移动技术、端侧智能等领域全球顶尖专业人才加入,让科技引领面向将来的商业创新和进步。
请投递简历至邮箱:ruoqi.zlj@taobao.com
了解更多职位详情:2684亿成交!每秒订单峰值54.4W!这样的团队你想加入吗?
END
干货好文
点击下方图片便可阅读
BindingX 地址点击阅读原文