5分鐘帶你看懂GCanvas渲染引擎的演進

阿里巴巴淘系技術發表於2019-12-06
5分鐘帶你看懂GCanvas渲染引擎的演進

本文內容大綱:

1、輕量級圖形渲染引擎與應用

2、渲染引擎演進與優化之路

3、渲染引擎未來的發展方向

GCanvas 的定位是遵循 w3c 標準的跨平臺的輕量級圖形渲染引擎。有清晰的定位和目標,並且緊貼現有的業務,為業務提供豐富表現形式。

GCanvas 發展

GCanvas 引擎從早期的 H5 效能加速,到 Weex 業務落地,從小遊戲的業務探索,到服務端渲染,再到小程式。經過幾個階段的發展後日漸成熟。
5分鐘帶你看懂GCanvas渲染引擎的演進淘系無線架構的不斷升級迭代,GCanvas 隨之保持著更新迭代的步調,在多個業務場景中使用,瞭解下一些應用案例。

應用案例

GCanvas 的目標人群是業務開發者,滿足業務的功能需求,對開發者也非常友好,尤其是前端開發者。熟悉 H5 Canvas 的同學,很容易上手,無任何學習成本。

Weex
2017年雙十一預熱會場,GCanvas 與魔影合作的版頭動畫
5分鐘帶你看懂GCanvas渲染引擎的演進
天貓未來店
天貓未來店的智慧電子標籤,基於 GCanvas JSBinding 的智慧電子標籤
5分鐘帶你看懂GCanvas渲染引擎的演進
小遊戲
野生小夥伴,基於GCanvas小遊戲應用
5分鐘帶你看懂GCanvas渲染引擎的演進
Sketch Render
Demo+ 中的 Sketch Render ,基於 GCanvas 實現的服務端渲染 Sketch 檔案
5分鐘帶你看懂GCanvas渲染引擎的演進
支付寶小程式/淘寶商家應用Canvas
基於支付寶小程式/淘系商家應用同層渲染元件
  • 支付寶小程式諸葛找房 - 2D
    5分鐘帶你看懂GCanvas渲染引擎的演進5分鐘帶你看懂GCanvas渲染引擎的演進

  • 淘寶商家應用AR試妝 - WebGL

5分鐘帶你看懂GCanvas渲染引擎的演進

架構演進與優化

以業務先贏的基本原則,保證業務的前提下,架構容器和升級變化過程中,GCanvas 引擎也經歷了演進和升級優化。

2017年的架構
以外掛為主的實現,僅支援移動端
5分鐘帶你看懂GCanvas渲染引擎的演進
最新架構
提供標準介面,鏈路升級,API升級,不僅支援移動端還支援服務端
5分鐘帶你看懂GCanvas渲染引擎的演進架構變化主要有以下幾個方面:
  • 適配支援更多的 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;

@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 方法中間經過額外的處理。

簡單的耗時測試資料對比:

5分鐘帶你看懂GCanvas渲染引擎的演進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

相關文章