mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-09-20 20:48:06 +00:00
libghostty: faster render state reads and updates on wasm targets
This makes the `ghostty_render_state_*` C API significantly faster on wasm32-freestanding, measured in V8 via Node for Chrome. Also verified in `jsc` for Safari. The major change is a new bulk row read API that makes full-screen cell reads roughly 10x faster for wasm embedders. This should help any embedder with high FFI overhead, such as Go, Python, etc. too. Non-wasm performance is not impacted, all benchmarks were run on my mac too w/ no regressions (two of the changes are native wins as well). ## Changes * color: the "vectorized" palette conversion loop was silently scalarized by LLVM into per-byte ops because it loaded/stored through array-typed pointers. Zig 0.16 disables the LLVM loop vectorizer, so manually vectorized loops must go through vector-typed pointers. * C styles: major optimizations to converting Zig styles to C styles. This is a heavy operation for render state. * render: `endUpdate`'s style-run fill (`@memset` with a struct value) re-loaded its source every iteration and stored field by field. Now manually vectorized. * render: new `GHOSTTY_RENDER_STATE_ROW_DATA_CELLS_RAW` returns a borrowed `GhosttyCellsView` of the current row's raw cell values, valid until the next update. One call per row instead of 3-6 calls per cell. ## Benchmarks | Benchmark | Before | After | Speedup | |---|---|---|---| | colors_get | 114 ns | 35 ns | 3.3x | | style get, per styled cell | 7.8 ns | 6.7 ns | 1.2x | | raw+style read, per cell | 8.6 ns | 7.7 ns | 1.1x | | full-screen text read, per cell | 7.5 ns | 0.7 ns | 10.7x | | full-screen text+style read, per cell | 8.6 ns | 1.7 ns | 5.1x | | render state update, styled full frame | 3.4 us | 2.6 us | 1.3x | **AI usage:** Fable did the implementation and benchmarking and drafted this message. Comments were partially rewritten by me.
This commit is contained in:
@@ -236,6 +236,19 @@ typedef enum GHOSTTY_ENUM_TYPED {
|
||||
|
||||
/** Row-local selected cell range (GhosttyRenderStateRowSelection). */
|
||||
GHOSTTY_RENDER_STATE_ROW_DATA_SELECTION = 4,
|
||||
|
||||
/** A borrowed view of the raw cell values for the current row
|
||||
* (GhosttyCellsView). One value per column, identical to querying
|
||||
* GHOSTTY_RENDER_STATE_ROW_CELLS_DATA_RAW for each cell. The view
|
||||
* is only valid as long as the underlying render state is not
|
||||
* updated; it is unsafe to use after updating the render state.
|
||||
*
|
||||
* This is the bulk alternative to iterating cells one at a time.
|
||||
* It lets callers with expensive call boundaries (e.g. WebAssembly
|
||||
* embedders) read an entire row with a single call, then drill
|
||||
* into the cells iterator only for cells that need managed data
|
||||
* (styles, graphemes). */
|
||||
GHOSTTY_RENDER_STATE_ROW_DATA_CELLS_RAW = 5,
|
||||
GHOSTTY_RENDER_STATE_ROW_DATA_MAX_VALUE = GHOSTTY_ENUM_MAX_VALUE,
|
||||
} GhosttyRenderStateRowData;
|
||||
|
||||
|
||||
@@ -50,6 +50,23 @@ typedef uint64_t GhosttyCell;
|
||||
*/
|
||||
typedef uint64_t GhosttyRow;
|
||||
|
||||
/**
|
||||
* A borrowed view of contiguous raw cell values.
|
||||
*
|
||||
* The memory is not owned by this struct. The pointer is only valid
|
||||
* for the lifetime documented by the API that produces it. Each value
|
||||
* is queried via ghostty_cell_get() like any other GhosttyCell.
|
||||
*
|
||||
* @ingroup screen
|
||||
*/
|
||||
typedef struct {
|
||||
/** Pointer to len contiguous cell values. */
|
||||
const GhosttyCell* ptr;
|
||||
|
||||
/** Number of cells. */
|
||||
size_t len;
|
||||
} GhosttyCellsView;
|
||||
|
||||
/**
|
||||
* Cell content tag.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user