Skip to content

fix(terminal): repair stale GPU glyphs after scrolling - #790

Merged
Juliusolsson05 merged 2 commits into
mainfrom
fix/terminal-atlas-repaint
Sep 5, 2026
Merged

Juliusolsson05 merged 2 commits into
mainfrom
fix/terminal-atlas-repaint

Conversation

@Juliusolsson05

Copy link
Copy Markdown
Owner

Problem

The newly enabled GPU path exposes corruption in pinned xterm WebGL 0.19.0 under colored CLI output and scrollback. Atlas merges during rendering leave stale cell coordinates; per-page texture-version collisions can also keep the wrong GPU texture bound. Refresh alone is insufficient.

Change

  • Coalesce atlas layout events into one deferred texture-binding invalidation plus viewport refresh through xterm’s frame scheduler.
  • Preserve GPU acceleration, shared glyph cache, scrollback, terminal dimensions, palette, and PTY/input ordering. No periodic or unconditional per-scroll repaint.
  • Fence pending repairs and dispose all subscriptions on context loss/unmount.
  • Isolate one shape-checked, version-pinned private bridge in the loader: setAtlas with the existing atlas invalidates GPU bindings without clearing glyphs. Fail back to DOM if this bridge is incompatible or throws. Remove it when a stable addon includes upstream xterm.js #5883.

Refs #789
Upstream: xtermjs/xterm.js#5883 and xtermjs/xterm.js#6038

Verification

  • Type-check passed.
  • 25 focused tests passed: version canary, coalescing, invalidation ordering, teardown/context-loss fences, partial registration failure, DOM fallback, and mounted shell/agent/inline host behavior.
  • Test-contract check and git diff --check passed.
  • Repeatable real Electron GPU script: node scripts/smoke-terminal-renderer.mjs; use --control for the unwrapped addon.
  • Control: 33 output-frame mismatches, one scroll mismatch, 1,264,868 differing pixel channels against a fresh independent atlas. Production loader: zero frame mismatches and zero reference differences; GPU stays active.
  • Synthetic screenshots inspected. No live Agent Code restart, provider calls, session termination, or user profile access.

Limits

The exact user screenshot still requires post-deployment confirmation, so this references rather than closes #789. The fix repairs stale frames on the next scheduled frame; it is not an upstream synchronous merge-loop backport. GPU smoke coverage is opt-in because ordinary headless CI cannot guarantee a usable graphics context. The broader React/performance refactor remains isolated in its separate worktree. Not merged; awaiting review and CI.

Scrolling colored output exposes stale cell coordinates and texture-version collisions in the pinned WebGL addon. Coalesce a texture rebind and viewport refresh after atlas changes without evicting shared glyphs or touching terminal state. Keep the version-specific bridge isolated and fail back to DOM if its shape changes.

Refs #789
@Juliusolsson05
Juliusolsson05 merged commit 4c641f6 into main Sep 5, 2026
2 checks passed
@Juliusolsson05
Juliusolsson05 deleted the fix/terminal-atlas-repaint branch September 5, 2026 03:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(terminal): WebGL atlas changes leave stale glyphs after scrolling

1 participant