Skip to content

Proper dingus click support#492

Open
migueldeicaza wants to merge 1 commit intodingusfrom
main
Open

Proper dingus click support#492
migueldeicaza wants to merge 1 commit intodingusfrom
main

Conversation

@migueldeicaza
Copy link
Owner

No description provided.

* Initial Metal backend

* Adds image support

* Metal Cursor blinking

* Strikethrough support

* Dirty‑row caching is in place for the Metal renderer.

It now caches per‑row draw data and only rebuild rows in the update
range, with cache invalidation when scale/view/font/buffer/kitty state
changes.

Also moved row rendering into a dedicated builder, and
AppleTerminalView now hands the absolute dirty range to Metal so
blinks don’t trigger full rebuilds.

* Debug FPS counter

* Implemented an atlas eviction/resize policy with a max size of 2048 per side for now

* Split atlas, a grayscale one for text, a color one for emojis.  We determine this by scanning the resulting rendered image

* Two modes for caching the row data caches.

New property in TerminalView.metalBufferingMode

perRowPersistent: caches MTLBuffer so we no longer rebuild big vertex buffers
every frame; we now create persistent buffers only when a row is rebuilt and
then reuse them across frames.

MetalTerminalRenderer now stores RowDrawBuffers in rowCache and builds
ImageDrawBuffer/vertex buffers once per dirty row (makeRowBuffers +
makeStaticBuffer).

The draw path iterates cached row buffers per category to preserve layer
ordering while avoiding per‑frame buffer allocation churn.

The cursor rendering still uses the per‑frame BufferPool, which is appropriate
because it can change every frame.

The second mode of operation is closer to what Ghostty does, krow‑level CPU
caching + per‑frame GPU buffer sync, instead of persistent per‑row GPU buffers.

Concretely:

- Rebuilds only dirty rows into RowDrawData (CPU arrays).

- Concatenates all visible row arrays into single per‑pass arrays (background,
  gray glyphs, color glyphs, decorations, images).

- Uploads those arrays into one GPU buffer per pass using the per‑frame
  BufferPool.

- Draws in the same layered order as before, but from those frame‑level buffers.

* Implemented a Ghostty-style shaper cache and moved Metal row building
onto shaped runs (CPU row model), so we reuse glyph/position shaping
across redraws instead of recreating CTLine each time.

MetalTerminalRenderer now has ShaperCache (keyed by font + text) and
buildShapedSegments, and both background + text/ decoration paths
consume shaped runs instead of per-run CTLine creation.

Row rebuilds still use the existing dirty-row cache, but shaping is
now reused across selection/attribute-only changes.

* Implemented the Ghostty-style cell buffer model so backgrounds, text glyphs, and
decorations are now emitted as per-cell structs and expanded to quads in the
GPU; cursor/images still use the existing per-vertex paths.

This reduces CPU-side vertex churn and aligns SwiftTerm’s renderer with the
Ghostty approach.

* Add Metal support for iOS

* Close a small feature gap with the CoreGraphics version

* Do not run async the data reception

* Metal: Do not render every time a change, use a poor man's display-link, like we do with CoreGraphics

* Rendering: Add additional underline styles

* Fix build

* Fix

* Set throttling during resize

* Add CustomBlockGlyph support for the GPU renderer

* Document the GPU features
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.

1 participant