GCanvas 渲染引擎介紹

發表於2017-07-31
GCanvas 渲染引擎介紹

GCanvas 提供了一套類似於 H5 Canvas 標準的 JavaScript API。基於這套 API 可以方便的去做圖形繪製、動畫渲染等,開發的體驗與 H5 Canvas 是完全一樣的。

GCanvas 介紹

GCanvas發展經歷了兩個階段。

  • 第一階段,2014 年中到 2015 年底,解決 Android 平臺 WebView Canvas 渲染效能差的問題。
  • 第二階段,2016 年 11 月到現在,為前端提供 Native 圖形繪製能力。

用一句話來概括 GCanvas,即遵循 W3C 標準,移動端的跨平臺的高效能圖形渲染引擎。可以從三個方面來解釋。

  • 遵循 W3C 標準
    GCanvas 提供了一套類似於 H5 Canvas 標準的 JavaScript API,開發人員基於這套 API 可以方便的去做圖形繪製、動畫渲染等。開發的體驗與 H5 Canvas 是完全一樣的。
  • 跨平臺
    GCanvas 的核心基於 OpenGL ES, 用 C++ 實現了一套用於描述 Canvas 標準 API 的介面實現。我們將其稱為渲染引擎核心。並通過交叉編譯,使得可以適配 Android、iOS 這兩大主流移動平臺,因而具有跨平臺的特性。
  • 高效能
    早期移動平臺上 H5 Canvas 去做一些複雜的動畫或遊戲,在 WebView 上的體驗非常差。 主要原因是 WebView 對 GPU 硬體加速的支援差。高效能則是充分利用了 GPU 硬體的渲染能力,主要體現兩個方面:
    • 對於 Android 3.0 以前的系統,Android 的渲染管線是不支援硬體加速的,WebView 中的 Canvas 不能獲得 GPU 的圖形渲染能力的支援。對於這類系統,通過 GCanvas 可以獲得更底層的 OpenGL ES 的硬體加速能力提高渲染效率。
    • 鏈路上來看,縮短了呼叫路徑,提高了渲染效能。使用了 GCanvas 則不需要經過 WebView 內部的複雜邏輯處理和圖層樹渲染,而是讓 JavaScript 通過橋接方式直接呼叫渲染引擎核心(OpenGL ES)。

GCanvas 組成

如上圖所示 GCanvas 由三層組成 JavaScript 層、外掛層、核心渲染庫。

  • JavaScript 層
    JavaScript 提供對外統一的 API,支援 Canvas 2D 和 WebGL 的功能介面。介面支援情況請參考 API 覆蓋
  • 外掛層
    外掛層核心包含三部分。
    • Bridge 橋接
      JavaScript 到 Native 的橋接,比較主流的方式 JSBridge 和 JSBinding。JSBridge 實現方式,如 Cordva、WebviewJavascriptBridge 等。 還可以用 JSBinding 方式來實現,如 V8、JavascriptCore 等。實際的應用場景中這兩種橋接方式都有支援。
    • 通用外掛
      通用外掛包含了通用外掛介面與實現、GCanvas 的管理、渲染命令佇列管理、紋理快取等。支援不同型別橋接方式下的擴充套件。
    • 系統適配
      系統適配涉及 Android 和 iOS 對 OpenGL ES 實現的差異,網路圖片下載,字型渲染等方面。
  • 核心渲染庫
    核心渲染庫包括對外統一的介面,以及 Contex2D 和 WebGL 模組,底層則是對 OpenGL ES API 等分裝。

GCanvas 流程

上圖是 JavaScript 層渲染核心庫的概要流程,關鍵的兩個流程是初始化和渲染。

  • 初始化
    初始化,JavaSript 層獲取配置判斷執行環境,通過橋接層,外掛層完成檢視和 GCanvas 的建立。進一步完成對 OpenGL 環境的初始化。
  • 渲染
    渲染,JavaScript 層將所有的API呼叫託管,並且轉換成自定義的命令格式(命令型別 + 引數的組合)。渲染觸發則由 JavaScript 定時器觸發或者手動觸發的方式,將這些命令下發到渲染核心庫執行。

以 Weex 為例, 繪製圖形和圖片的測試程式碼如下。

通過 Weex Playground 執行結果如下

GCanvas 渲染引擎介紹

具體分析下整個流程。結合外掛層和核心渲染庫來分析。

  • 外掛層流程
    以 iOS 為例分析,Android 的過程是類似的。
    • GLKView 檢視建立,並且與 GCanvas 物件建立繫結關係;
    • GCVCommon,資源載入與紋理繫結;
    • GCanvasPlugin,設定位置資訊、裝置比率、下發渲染命令;
  • 渲染庫流程

渲染命令的解析,最終通過呼叫 OpenGL ES 的方法或組合方法來實現 Context2D 和 WebGL 的效果,生成幀快取,提交給 GPU 渲染,最後在繫結的 GLKView 檢視上顯示。

  • Context2D,需要實現諸如 GPath、GTexture、GTransform、GTriangulate 等來實現 Canvas 的渲染效果;
  • WebGL 相對簡單,WebGL1.0 的 API 基本都能與從 OpenGL ES2.0 找到與之相對應的 API;

GCanvas 測試例子

下面給出一些 GCanvas 的案例。

  • GCanvas 與 H5 Canvas 效能對比

video

  • Android 平臺,左邊是 GCanvas,右邊是 H5 Canvas。同屏渲染圖片越多,效能差異越明顯。
  • Hilo 2D
    100 條魚基於 Hilo 2D 動畫庫,滿屏魚的動畫測試。
  • Chart 圖示渲染
    Chart 圖示庫的渲染效果基於圖表庫,不同型別的圖表渲染測試。

附:GCanvas API 支援情況

最後附上 GCanvas Contex2D 和 WebGLAPI 的支援列表,支援常用的介面。另外,WebGL 的 API 目前正在做補全開發,後續會支援 WebGL1.0 API 的全覆蓋。

  • Context2D API
API名稱 API型別 狀態
fillStyle Attribute getter/setter Implemented
strokeStyle Attribute getter/setter Empty
shadowColor Attribute getter/setter Empty
shadowBlur Attribute getter/setter Empty
shadowOffsetX Attribute getter/setter Empty
shadowOffsetY Attribute getter/setter Empty
createLinearGradient() Method Empty
createPattern() Method Empty
createRadialGradient() Method Empty
addColorStop() Method Empty
isPointInPath() Method Empty
createEvent() Method Empty
toDataURL() Method Empty
lineCap Attribute getter/setter Implemented
lineJoin Attribute getter/setter Implemented
lineWidth Attribute getter/setter Implemented
miterLimit Attribute getter/setter Implemented
font Attribute getter/setter Implemented
textAlign Attribute getter/setter Implemented
textBaseline Attribute getter/setter Implemented
globalAlpha Attribute getter/setter Implemented
globalCompositeOperation Attribute getter/setter Implemented
rect() Method Implemented
fillRect() Method Implemented
strokeRect() Method Implemented
clearRect() Method Implemented
fill() Method Implemented
stroke() Method Implemented
beginPath() Method Implemented
moveTo() Method Implemented
closePath() Method Implemented
lineTo() Method Implemented
clip() Method Implemented
quadraticCurveTo() Method Implemented
bezierCurveTo() Method Implemented
arc() Method Implemented
arcTo() Method Implemented
scale() Method Implemented
rotate() Method Implemented
translate() Method Implemented
transform() Method Implemented
setTransform() Method Implemented
fillText() Method Implemented
strokeText() Method Implemented
measureText() Method Implemented
drawImage() Method Implemented
createImageData() Method Implemented
getImageData() Method Implemented
putImageData() Method Implemented
save() Method Implemented
restore() Method Implemented
getContext() Method Implemented
loadTexture() Method Implemented
unloadTexture() Method Implemented
resetTransform() Method Implemented
render() Method Implemented
capture() Method Implemented
resetClip() Method Implemented
  • WebGL API
API名稱 API型別 狀態
viewport() Method Implemented
vertexAttribPointer() Method Implemented
vertexAttrib2fv() Method Implemented
useProgram() Method Implemented
uniformMatrix4fv() Method Implemented
uniformMatrix3fv() Method Implemented
uniformMatrix2fv() Method Implemented
uniform4iv() Method Implemented
uniform4i() Method Implemented
uniform4fv() Method Implemented
uniform4f() Method Implemented
uniform3iv() Method Implemented
uniform3i() Method Implemented
uniform3fv() Method Implemented
uniform3f() Method Implemented
uniform2iv() Method Implemented
uniform2i() Method Implemented
uniform2fv() Method Implemented
uniform2f() Method Implemented
uniform1iv() Method Implemented
uniform1i() Method Implemented
uniform1fv() Method Implemented
uniform1f() Method Implemented
texParameteri() Method Implemented
texImage2D() Method Implemented
shaderSource() Method Implemented
scissor() Method Implemented
renderbufferStorage() Method Implemented
pixelStorei() Method Implemented
linkProgram() Method Implemented
lineWidth() Method Implemented
getUniformLocation() Method Implemented
getShaderParameter() Method Implemented
getAttribLocation() Method Implemented
generateMipmap() Method Implemented
frontFace() Method Implemented
framebufferTexture2D() Method Implemented
flush() Method Implemented
enableVertexAttribArray() Method Implemented
enable() Method Implemented
drawElements() Method Implemented
disableVertexAttribArray() Method Implemented
disable() Method Implemented
depthMask() Method Implemented
depthFunc() Method Implemented
deleteTexture() Method Implemented
deleteShader() Method Implemented
deleteRenderbuffer() Method Implemented
deleteProgram() Method Implemented
deleteFramebuffer() Method Implemented
deleteBuffer() Method Implemented
cullFace() Method Implemented
createTexture() Method Implemented
createShader() Method Implemented
createRenderbuffer() Method Implemented
createProgram() Method Implemented
createFramebuffer() Method Implemented
createBuffer() Method Implemented
compileShader() Method Implemented
colorMask() Method Implemented
clearStencil() Method Implemented
clearDepth() Method Implemented
clearColor() Method Implemented
clear() Method Implemented
bufferData() Method Implemented
blendFuncSeparate() Method Implemented
blendFunc() Method Implemented
blendEquationSeparate() Method Implemented
blendEquation() Method Implemented
bindRenderbuffer() Method Implemented
bindFramebuffer() Method Implemented
bindBuffer() Method Implemented
bindAttribLocation() Method Implemented
attachShader() Method Implemented
activeTexture() Method Implemented
validateProgram() Method Empty
texSubImage2D() Method Empty
texParameterf() Method Empty
stencilOpSeparate() Method Empty
stencilOp() Method Empty
stencilMaskSeparate() Method Empty
stencilMask() Method Empty
stencilFuncSeparate() Method Empty
stencilFunc() Method Empty
sampleCoverage() Method Empty
readPixels() Method Empty
polygonOffset() Method Empty
isTexture() Method Empty
isShader() Method Empty
isRenderbuffer() Method Empty
isProgram() Method Empty
isFramebuffer() Method Empty
isEnabled() Method Empty
isContextLost() Method Empty
isBuffer() Method Empty
getVertexAttribOffset() Method Empty
getVertexAttrib() Method Empty
getUniform() Method Empty
getTexParameter() Method Empty
getSupportedExtensions() Method Empty
getShaderSource() Method Empty
getShaderPrecisionFormat() Method Empty
getShaderInfoLog() Method Empty
getRenderbufferParameter() Method Empty
getProgramParameter() Method Empty
getProgramInfoLog() Method Empty
getParameter() Method Empty
getFramebufferAttachmentParameter() Method Empty
getExtension() Method Empty
getError() Method Empty
getContextAttributes() Method Empty
getBufferParameter() Method Empty
getAttachedShaders() Method Empty
getActiveUniform() Method Empty
getActiveAttrib() Method Empty
drawArrays / drawArraysInstancedANGLE() Method Empty
detachShader() Method Empty
depthRange() Method Empty
copyTexSubImage2D() Method Empty
copyTexImage2D() Method Empty
compressedTexSubImage2D() Method Empty
compressedTexImage2D() Method Empty
checkFramebufferStatus() Method Empty
bufferSubData() Method Empty
blendColor() Method Empty
bindTexture() Method Undefined
commit() Method Undefined
finish() Method Undefined
framebufferRenderbuffer() Method Undefined
hint() Method Undefined

相關文章