fix(desktop): stop terminal render lag from WebGL context exhaustion

AV
4mo ago
+372-74

Summary

Typing echo lagged in terminal panes (v1 and v2) once enough terminals had been opened. Root cause: every terminal ever opened held a live WebGL context while parked off-screen, and Chromium caps a renderer process at ~16 contexts — past that it silently evicts one, which tripped a module-global fallback latch (suggestedRendererType) that downgraded every future terminal to the slow DOM renderer for the rest of the session. Under agent streaming the DOM renderer saturates the UI thread, so typed characters render late.

  • New shared webgl-renderer.ts controller: the WebGL addon is acquired on attach and released on park. Parked terminals pause rendering anyway (xterm's IntersectionObserver), so live GPU contexts now equal visible panes — permanently under the cap.
  • Context loss falls back to the DOM renderer for that terminal only and retries WebGL on its next attach; addon load failure (no GPU support) disables WebGL per instance, never globally.
  • Fallbacks are no longer silent: console.warn + terminal_webgl_fallback PostHog event.
  • v1 (helpers.ts / v1-terminal-cache.ts) and v2 (terminal-runtime.ts) now share the one controller instead of duplicating the WebGL loading block.

Test Plan

  • 7 new unit tests for the controller (acquire/release, pending-load cancel, context-loss retry, per-instance load-failure isolation, dispose)
  • All 309 terminal-related tests pass
  • tsc --noEmit and bun run lint clean
  • Manual: open 20+ terminals across workspaces — focused pane keeps its <canvas>, #terminal-parking terminals hold no WebGL contexts, typing stays crisp while agents stream in background tabs

Open in Stage

Summary by cubic

Fixes terminal typing lag by preventing WebGL context exhaustion. WebGL is now acquired only for visible terminals and released when parked, keeping contexts under Chromium’s cap and preserving the fast renderer.

  • Bug Fixes
    • Added a shared controller for @xterm/addon-webgl: acquire on attach, release on park.
    • Fallback to DOM is per-terminal; WebGL retries on next attach. Load failures disable WebGL for that instance only.
    • Logs console warnings and tracks terminal_webgl_fallback.
    • Unified v1 and v2 terminals to use the same controller; removed duplicate WebGL logic.
    • Added unit tests for acquire/release, cancellation, context-loss retry, and per-instance isolation.

Summary by CodeRabbit

  • New Features

    • Terminal rendering now manages GPU/WebGL usage more intelligently when tabs are attached, parked, or reopened.
    • Improved fallback handling helps terminals recover more reliably when WebGL is unavailable or loses context.
  • Bug Fixes

    • Reduced idle GPU pressure by releasing rendering resources when terminals are not visible.
    • Added safeguards so failed WebGL rendering falls back cleanly without affecting other terminal sessions.