🚧 Glyx is pre-release software. APIs may change before v1.0. Get started →
Documentation
Roadmap
Renderer Roadmap

Renderer Roadmap

Glyx ships three 2D rendering backends today: TinySkia, Vello, and (Windows, experimental) Direct2D. This page explains why, and corrects an earlier version of this page that framed Vello as a consolidation target — that framing turned out to be wrong once real memory measurements were taken.


Current backend selection

BackendWhen selectedStatus
TinySkia (via softbuffer)Integrated/no GPU, or explicit renderMode: 'skia'✅ Stable — zero wgpu, flat ~27–40 MB RSS under interaction load
Vello (wgpu)Discrete GPU, or explicit renderMode: 'gpu'/'cpu'✅ Stable — GPU-parallel vector renderer, real memory cost under load
Direct2D (Windows)Explicit renderMode: 'direct2d' only — never auto-selected🧪 Experimental — see Renderer Selection

Selection is automatic at startup via a GPU capability probe (auto, the default). Override with renderMode in glyx.config — see Renderer & Engine Selection for the full config reference, decision matrix, and per-backend memory numbers.

⚠️

There is no GLYX_RENDER_MODE environment variable — that was a stale reference in an earlier version of this page. The config field is window.renderMode ('auto' | 'skia' | 'gpu' | 'cpu' | 'direct2d'). GLYX_CPU_RENDER=1 is a real env var, but it only forces TinySkia (renderMode: 'skia''s equivalent) — it doesn't select between backends generally.


FemtoVG — removed

FemtoVG was a legacy OpenGL-style renderer. It has been removed from Glyx.

Why it was removed

  • FemtoVG created a new wgpu BindGroup for every distinct draw-state per frame, causing per-frame GPU buffer churn. Measured directly this session: under the same fast-hover-repaint-burst stress test used to evaluate every backend on this page, FemtoVG spiked even higher than Vello — the proper fix (dynamic uniform offsets) was a significant change to femtovg internals, not something maintainable long-term as a patch.
  • The upstream femtovg crate had slowed maintenance. We vendored it only to keep the fallback path alive.
  • TinySkia (CPU rasterizer via softbuffer) already outperforms FemtoVG on integrated GPUs in both memory and visual quality.

What changed

  • RenderMode::FemtoVG is gone from the native API and the renderMode config field.
  • Hardware that previously routed to FemtoVG (Intel Arc discrete GPUs) now routes to Vello under auto.

Migration

No app-level changes are needed. Backends are an implementation detail — the Canvas2D, View, Text, and Image APIs are identical across backends. If you set renderMode: 'femtovg' explicitly, remove it.


Vello — a real cost, not a bug

An earlier version of this page framed Vello as the long-term "consolidation target" for Glyx's 2D rendering. That framing was wrong. Direct measurement (fast-hover-and-repaint-burst stress test, same methodology used for every backend on this page) found Vello's memory behavior is not a tuning problem to be fixed with a bigger buffer-pool trim schedule — it's structural:

  • Vello (GPU and CPU modes both) keeps a persistent scene/compute buffer pool that grows to match rendering load and only releases on occlusion, focus-loss, or periodic idle checks — never instantly.
  • Under the stress test, idle RSS around ~350–430 MB spiked to 600–700 MB under interaction, with slow, erratic recovery afterward.
  • Vello's CPU path is not a lighter-weight fallback — it inherits the same buffer-pool memory cost as Vello GPU, without the GPU-parallel throughput that cost exists to buy. It is not recommended; only reach for it if you need Vello-specific rendering features with no GPU available.

None of this makes Vello a bad renderer — it's the right tool when a scene's 2D rendering load is genuinely GPU-throughput-bound (dense paths/text, large canvases, heavy gradients at scale), which is exactly the workload its architecture is built for. It's the wrong default for typical app UI, which is why auto only selects it on discrete GPUs and TinySkia remains the default elsewhere.

Roadmap items for Vello:

  • Investigate whether the buffer-pool trim schedule can be made more aggressive without regressing throughput on the workloads Vello is actually meant for, as a partial mitigation — not a fix for the structural cost itself.
  • Layer compositing (RepaintBoundary → GPU render layer → blit-only on clean frames).
  • Text subpixel rendering on Vello (Parley integration improvement).

TinySkia — the default, not a compromise

TinySkia via softbuffer (zero wgpu) is the right choice for the large majority of apps, not a fallback for weak hardware:

  • No wgpu device, no GPU buffer pool of any kind — nothing to grow under load. Measured flat (~27–40 MB) both idle and under the same stress burst that spiked Vello to 600–700 MB.
  • CPU rasterization at 60 fps is viable for typical app UIs on any machine made after 2015.
  • On integrated GPUs specifically, GPU buffer memory is system RAM — skipping wgpu entirely avoids that cost outright, not just reduces it.

TinySkia will remain and be maintained alongside Vello. The selection heuristic (GpuTier::Integrated → TinySkia) is intentional, not temporary.


Direct2D — Windows, experimental

Added after Vello's structural memory cost was understood: Direct2D (ID2D1DeviceContext + DXGI swap chain, with a DirectWrite text bridge) gives GPU-accelerated output on Windows with TinySkia-like flat memory behavior — because its resource caches are managed by the OS/graphics driver and shared system-wide across every app, not privately allocated per-app the way Vello's (or FemtoVG's) are.

This was verified before any integration work started: a standalone spike (bare HWND, no Glyx code) measured 32.5 MB idle with zero memory growth under a 500-repaint invalidate burst. The real integration, once built, confirmed the same flat-memory pattern on a full app (tasks, all primitives — shapes, gradients, text, images, layers/opacity) under the same fast-hover-burst stress test used to evaluate every other backend.

Current scope:

CapabilityStatus
Shapes (rects, circles, lines, paths)
Gradient/brush fills
Text (DirectWrite bridge)
Images
Layers, clipping, real per-layer opacity
<Canvas3D> on a Direct2D window❌ — no safe D3D11/wgpu device-sharing pattern investigated yet; silently skipped with a log message
macOS equivalent (CoreGraphics)Not started — needs its own validation spike on real macOS hardware

Explicitly not on a path to replacing Vello or TinySkia — see Renderer & Engine Selection for opt-in config and current limitations.


3D (Canvas3D / glyx-3d)

The 3D layer uses wgpu directly, independent of the 2D backend. It is always GPU-accelerated and always present when a Canvas3D node exists (TinySkia and Vello both support lazily standing up a wgpu device on first Canvas3D use; Direct2D does not yet — see above). See the 3D Rendering roadmap for what's planned there.