GCanvas渲染引擎的演进
作者:韦青
发布于:2019-12-02 11:59:46
GCanvas的定位是遵循w3c标准的跨平台的轻量级图形渲染引擎。有清晰的定位和目标,并且紧贴现有的业务,为业务提供丰富表现形式。
GCanvas发展
GCanvas引擎从早期的H5性能加速,到Weex业务落地,从小游戏的业务探索,到服务端渲染,再到小程序。经过几个阶段的发展后日渐成熟。

淘系无线架构的不断升级迭代,GCanvas随之保持着更新迭代的步调,在多个业务场景中使用,了解下一些应用案例。
应用案例
GCanvas的目标人群是业务开发者,满足业务的功能需求,对开发者也非常友好,尤其是前端开发者。熟悉H5 Canvas的同学,很容易上手,无任何学习成本。
-
Weex
2017年双十一预热会场,GCanvas与魔影合作的版头动画
-
天猫未来店
天猫未来店的智能电子标签,基于GCanvas JSBinding的智能电子标签
-
小游戏
野生小伙伴,基于GCanvas小游戏应用
-
Sketch Render
Demo+中的Sketch Render,基于GCanvas实现的服务端渲染Sketch文件
架构演进与优化
以业务先赢的基本原则,保证业务的前提下,架构容器和升级变化过程中,GCanvas引擎也经历了演进和升级优化。
-
2017年的架构
以插件为主的实现,仅支持移动端
-
最新架构
提供标准接口,链路升级,API升级,不仅支持移动端还支持服务端
架构变化主要有这几个方面。
- JS到Native调用通路,从模块路由反射升级到JSBinding
内功修炼
在快速迭代过重中,保持修炼内功。为保证高性能这个根本,在链路、内核以及底层图形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;
@protocol TestObjecJSExport <JSExport>
JSExportAs(foo, - (void)foo:(NSString *)msg);
@end
- 第二种方案,使用C Export将方法和属性用
JSStaticFunction
和JSStaticValue
进行绑定
//方法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;
两种实现方案,经过测试对比第二种方案在性能更好。原因在于静态JS方法是通过方法名到Native函数的直接映射,而JSExport的方案则需要类型检查,协议校验,再调用Native方法中间经过额外的处理。
简单的耗时测试数据对比
方式 | 耗时(ms/百万次) | |
---|
JSExport | 1278 | |
C Export | 452 | |
-
JS到Native数据传输
方法调用与属性访问之外,参数数据的传输也影响每帧耗时,尤其是在WebGL的场景,通常有很大顶 点数据需要处理,有几万-几十万字节,甚至更多。JS到Native的大数据传输避免内存拷贝。
-
JS与Native对象生命周期
JSBinding的对象生命周期管理,JS对象与Native对象一一对应,在JS对象创建触发JSObjectInitializeCallback
回调,创建Native对象,并将JS与Native建立关联。JS的GC回收对象触发JSObjectFinalizeCallback
的回调中去释放对应Native对象。
-
帧率优化
除了调用链路对帧率的提升,单帧绘制的CPU和GPU耗时相关的优化点
-
底层图形API升级
在iOS12之后,苹果将OpenGL ES API设为废弃,在已支持的设备上OpenGL ES的调用都已映射到Metal相应的后端实现,Metal替换OpenGL势在必行。GCanvas也已投入开发Metal,可选择使用Metal作为渲染的后端。已完成了2D的绝大部分能力。
选择Metal会带来以下方面的收益:
- 丰富的调试工具,能精确到每个顶点数据和每个素点颜色
- 便捷调试这着色器语言(Metal Shader Language)
在内核升级优化的过程中,也有很多同学积极参与其中来在此表示感谢。
稳定性
增加了API的自动化测试以及CI建立保障稳定性。
未来的方向
结束语
有图形相关的业务需求和问题可联系淘宝前端-无线架构组。
← Rax PWA - 快速升级 Web 体验
ALive:助力阿里经济体,开启直播新纪元 →