Add optional Metal GPU-accelerated terminal renderer#480
Open
trsdn wants to merge 1 commit intomigueldeicaza:mainfrom
Open
Add optional Metal GPU-accelerated terminal renderer#480trsdn wants to merge 1 commit intomigueldeicaza:mainfrom
trsdn wants to merge 1 commit intomigueldeicaza:mainfrom
Conversation
Introduce a TerminalRenderer protocol that abstracts the rendering backend,
allowing CoreGraphics (default, backward-compatible) and Metal to be swapped.
New files in Sources/SwiftTerm/Rendering/:
- TerminalRenderer.swift: Protocol with setup/draw/resize/fontChanged/colorsChanged
- CoreGraphicsRenderer.swift: Thin wrapper around existing drawTerminalContents()
- MetalTerminalRenderer.swift: GPU-accelerated renderer with instanced drawing
- GlyphAtlas.swift: CoreText → MTLTexture shelf-packed glyph cache
- ShaderTypes.h: Shared Metal/Swift struct definitions
- TerminalShaders.metal: Reference shaders (compiled at runtime for SPM compat)
Rendering pipeline: 4 instanced draw passes (background → text → decorations → images).
Glyph atlas rasterized at backing scale for 1:1 texel-to-pixel on Retina displays.
Step threshold in fragment shader for crisp text without font smoothing artifacts.
Usage:
let tv = LocalProcessTerminalView(frame: frame)
if MetalTerminalRenderer.isAvailable {
tv.renderer = MetalTerminalRenderer()
}
Existing CoreGraphics behavior is completely unchanged — Metal is opt-in only.
Closes migueldeicaza#479
Co-authored-by: Copilot <[email protected]>
Owner
|
I have attempted this a few times, the most recent one is in my |
Owner
|
My last update was about 3 weeks ago, I will try to merge main into that branch, so we can compare apples to apples. |
Owner
|
Ok, I merged my changes into the gpu branch, would love if you could review if my branch is missing any features from the work you did. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds an optional Metal-based rendering backend as an alternative to CoreGraphics. The renderer is opt-in — existing behavior is completely unchanged unless the user explicitly sets
tv.renderer = MetalTerminalRenderer().Changes
New files (all in
Sources/SwiftTerm/Rendering/):TerminalRenderer.swiftCoreGraphicsRenderer.swiftdrawTerminalContents()MetalTerminalRenderer.swiftGlyphAtlas.swiftShaderTypes.hTerminalShaders.metalModified files:
MacTerminalView.swift(+25 lines):rendererproperty, defaultCoreGraphicsRendererinsetup(),draw()dispatchArchitecture
Rendering pipeline: Background → Text → Decorations → Images (all instanced, single draw call per pass).
Key Design Decisions
backingScaleFactor(2x on Retina) for 1:1 texel-to-pixel mapping. No bilinear blur.step(0.35, alpha)in fragment shader for crisp binary edges. CoreText anti-aliasing captures full glyph shape, threshold converts to sharp output.floor()on all cell origins prevents sub-pixel seams.setShouldSmoothFonts(false)+setShouldAntialias(true). Smoothing in a grayscale context creates wide halos that look washed out.MetalTerminalRenderer.isAvailablereturnsfalseon VMs/CI without GPU..metalfiles.Usage
What's NOT changed
Tested with
Closes #479