Skip to content

WebGL terminal renderer attaches without checking for CPU-emulated GPU #3280

@gregpriday

Description

@gregpriday

Summary

TerminalWebGLManager attempts to attach @xterm/addon-webgl to focused terminals regardless of whether hardware GPU acceleration is available. On machines with software-only WebGL (CPU-emulated via llvmpipe or ANGLE software fallback), the WebGL renderer is measurably slower than the DOM renderer — the opposite of the intended optimization.

Problem Statement

Chromium can silently fall back to CPU-emulated WebGL when GPU hardware acceleration is unavailable or blocklisted (common in VMs, certain CI configurations, some Linux GPU driver setups, and macOS VMs on Sequoia/Sonoma). In this state, app.getGPUFeatureStatus().webgl returns "software_only" rather than "enabled".

The current code wraps loadAddon in a try/catch to handle hard failures, but a software-only WebGL context does not throw — it silently succeeds while delivering worse performance than the DOM renderer. A focused terminal that should be running at 0.69ms/frame (GPU WebGL) instead runs slower than the 4.80ms/frame DOM baseline while consuming significantly more CPU.

The app already has CANOPY_DISABLE_WEBGL=1 as an explicit escape hatch for this scenario, but it requires the user to know about and set an environment variable — it doesn't happen automatically when the GPU is incapable.

Current Behavior

  • TerminalWebGLManager.ensureContext() calls terminal.loadAddon(addon) after only checking the CANOPY_DISABLE_WEBGL env flag (src/services/terminal/TerminalWebGLManager.ts#L19-L58)
  • app.getGPUFeatureStatus() is called in smoke test mode only (electron/main.ts#L1636) — its result is logged but never acted on
  • No runtime check prevents WebGL attachment on software-only GPU configurations

Expected Behavior

Before attaching the WebGL addon to any terminal, the app should confirm that hardware-accelerated WebGL is available. When GPU feature status indicates software-only rendering, the TerminalWebGLManager should skip WebGL attachment entirely and allow all terminals to use the DOM renderer — the same outcome as CANOPY_DISABLE_WEBGL=1.

Context

Relevant code:

Acceptance Criteria

  • When the Electron GPU process reports WebGL as "software_only", no terminal attaches the WebGL addon — all terminals use the DOM renderer
  • When GPU status is "enabled" (hardware accelerated), WebGL attachment proceeds as today
  • The detection is automatic — no user intervention or environment variable required
  • The existing CANOPY_DISABLE_WEBGL=1 flag continues to work as an explicit override
  • The app logs a clear message when WebGL is skipped due to software-only GPU

Edge Cases & Risks

  • app.getGPUFeatureStatus() can only be called from the main process, not the renderer. The result needs to be communicated to the renderer process where TerminalWebGLManager lives — either via IPC at startup or through an existing initialization channel.
  • GPU status can theoretically change after startup (e.g., eGPU disconnection), but this is rare enough that a startup-time check is sufficient.
  • The webgl2 feature status key should be checked rather than webgl, since @xterm/addon-webgl requires WebGL2.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions