gpu-compositing

1 posts

figma

Building a professional design tool on the web | Figma Blog (opens in new tab)

Figma set out to prove that a professional, high-fidelity design tool could run reliably in the browser. The challenge was that the web exposed specialized features rather than general-purpose graphics primitives, so Figma effectively had to build “a browser inside a browser.” Its solution combined C++ compiled through Emscripten with a custom rendering engine, enabling tighter control over memory, performance, and cross-platform consistency. ## Building Beyond the Web’s Original Design - The web was originally designed for documents, with application features added later as isolated APIs. - This limits advanced applications: - CSS provides sophisticated text layout but does not expose or customize the layout process. - Browsers have optimized GPU compositors, but developers cannot directly modify compositing or add custom blend modes. - Image decoders are highly optimized but offer limited control over details such as EXIF orientation and color-space handling. - Technologies such as WebGL and asm.js began exposing lower-level access to hardware, making demanding browser-based graphics applications practical. ## C++ and Emscripten - Figma’s editor was written in C++ and cross-compiled to JavaScript using Emscripten. - Emscripten targeted asm.js, allowing JavaScript engines to generate predictable and compact machine code. - This approach provided: - Direct control over memory layout, including compact 32-bit floats and bytes instead of JavaScript’s 64-bit numbers. - Manual allocation that avoids garbage-collection pauses and helps maintain 60 fps. - LLVM optimization and C++ template specialization for performance approaching native code. - More predictable execution because asm.js avoids the deoptimization points common in regular JavaScript. ## Memory Constraints and Indirect Buffers - Large contiguous typed-array allocations caused problems, especially in 32-bit Chrome on Windows, where address-space fragmentation from ASLR could prevent allocations as small as 256 MB. - Figma created an `IndirectBuffer` API to reference external typed arrays from C++. - Moving large image and geometry buffers outside the main heap: - Reduced fragmentation during long sessions. - Allowed better use of limited 32-bit address space. - Helped bypass typed-array size limits in 64-bit browsers. - The post also points toward future improvements from WebAssembly, which would reduce asm.js parsing costs, and shared typed arrays, which would enable shared-memory multithreading. ## Custom Rendering - Figma implemented its own rendering engine to achieve fast, consistent output across platforms. - Rather than relying entirely on browser graphics implementations, the team began building the rendering layer needed for a professional design application. Figma’s broader recommendation is to use low-level browser capabilities such as WebGL and compiled code when standard web APIs cannot provide the required performance or control.