Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Integrating WebGPU In Browser with ThorVG

Jinny You
November 12, 2024

Integrating WebGPU In Browser with ThorVG

Jinny You

November 12, 2024
Tweet

More Decks by Jinny You

Other Decks in Technology

Transcript

  1. What I’ll be talking 1. Introduction WebGPU for browser 2.

    WebGPU Integration 3. Binary size comparison 4. Browser testing for WebGPU 5. Performance comparison 6. WebGPU/WASM Debugging
  2. WebGPU Introduction In the browser leveraging the full power of

    the graphics driver from the web is challenging.
  3. WebGPU Introduction Not just new web technology But standard specification

    for universal graphics driver It doesn’t require much of knowledge about traditional graphics APIs like WebGL, Metal, Vulkan, Direct3D Start from new.
  4. WebGPU Introduction But limited Be aware of supported platforms https://caniuse.com/webgpu

    Safari and Mobile Device Have limitation of WebGPU *Experimental flags or not supported
  5. WebGPU Integration Old version of ECMAScript Isn’t fully supported We

    should bump up the Target ECMA version Check your JS bundler webpack, rollup, esbuild, vite… No support △ async/await We might need
  6. WebGPU Integration Supported in native but not in browser API

    Native Browser wgpuAdapterGetLimits() ✅ ❌ WGPUShaderModuleDescriptor (hintCount, hints) ✅ ❌ WGPUDeviceDescriptor (with empty requiredFeatures) ✅ ❌
  7. WebGPU Integration Handling async/await in C++ side browser In browser

    WebGPU initialization functions work different - wgpuInstanceRequestAdapter - wgpuAdapterRequestDevice
  8. WebGPU Integration The binding functions those include Asynchronous calls Will

    change to Asynchronous type in JS - Which means you should wrap super function with async, and call with “await” keyword - It could require interface change on JS API Handling async/await in C++ side
  9. WebGPU Integration Handling async/await in C++ side Browser does not

    wait for Those functions in C++ to be complete https://github.com/thorvg/thorvg/blob/main/src/bindings/wasm/tvgWasmLottieAnimation.cpp
  10. WebGPU Integration Handling async/await in C++ side Emscripten’s synchronize strategy

    https://emscripten.org/docs/api_reference/emscripten.h.html#pseudo-synchronous-functions
  11. WebGPU Integration Handling async/await in C++ side Be careful, concurrent

    async call at the same time causes runtime error ⚠ The system will freeze
  12. WebGPU Integration How WebGPU controls Canvas element 1. Create <canvas>

    element 2. Throw HTML selector to WebGPU 3. Attach target canvas in WebGPU API
  13. WebGPU Integration How WebGPU controls Canvas element - Surface →

    canvas element - Descriptor → dom selector In the browser
  14. WebGPU Integration Shadow root cannot be used ::shadow pseudo doesn’t

    work in browsers (firefox…) This isn’t string though
  15. WebGPU Integration Thinking about more practical case - WGPU adapter

    - WGPU device - WGPU instance These can be shared! ⚠ Do not waste resources!
  16. WebGPU Integration Thinking about more practical case In the JS

    WebGPU example we can see Adapter and Device are Requested once From browser side with WASM Must ensure this https://webgpufundamentals.org/webgpu/lessons/webgpu-multiple-canvases.html
  17. WebGPU Integration Shared singleton instance Initialize only on the first

    use. If it already exists, reuse it. https://github.com/thorvg/thorvg/blob/main/src/bindings/wasm/tvgWasmLottieAnimation.cpp
  18. Binary size comparison Browser runtime already include WebGPU implementation Using

    WebGPU itself doesn’t affect to binary size that much WASM doesn’t ship WebGPU runtime, just link
  19. Binary size comparison SW Only Binary (total 959KB) - WASM

    Binary : 858KB - Glue Code : 101KB WG Only Binary (total 988KB) - WASM Binary : 849KB - Glue Code : 139KB USE_WEBGPU doesn’t raise up the size
  20. Binary size comparison But we need “ASYNCIFY” Without this, WebGPU

    cannot be initialized Even though this option adds considerable size.
  21. Binary size comparison SW Only Binary (total 959KB) - WASM

    Binary : 858KB - Glue Code : 101KB WG Only Binary with ASYNCIFY (total 1.47MB) - WASM Binary : 1.3MB - Glue Code : 146KB After ASYNCIFY
  22. Binary size comparison SW+WG Combined Binary (total 1.54MB) - WASM

    Binary : 1.4MB - Glue Code : 147KB WG Only Binary with ASYNCIFY (total 1.47MB) - WASM Binary : 1.3MB - Glue Code : 146KB SW+WG Combined Binary
  23. WebGPU/WASM Debugging You’ll get a stack trace, fix the line

    Basically same as typical WASM debugging Build with “-g” flag, use DWARF extension
  24. WebGPU/WASM Debugging Do check! Where the issue comes from With

    WebGPU, the problem might not always be on C++ Glue code mutated by ASYNCIFY options
  25. WebGPU/WASM Debugging WebGPU may take more STACK_SIZE If animation isn’t

    rendered without clear reason → STACK_SIZE is not enough Test with large size, make sure proper size for your workload
  26. WebGPU/WASM Debugging Try to use latest version of emscripten Many

    of cases resolved in recent compiler Many bugs might happen in - Unsupported symbols (Native/C++ side) - Glue code JS compatibility issues
  27. Q&A