Expand description
Inline media: resolving an image block’s pixels off the UI thread, so the renderer only ever paints decoded pixels or a placeholder (IM.4).
Design: docs/dev/architecture/inline-media.md §5.
§The rule this code exists to serve
Decode never happens on the UI thread. gpui::img() will happily take
a path and load it, which means file I/O and PNG decode inside the render
pass — precisely the forbidden pattern (paramount goal #1). So the peer
never gets a path to draw; it gets pixels that were produced elsewhere, or
it gets nothing and paints the placeholder.
That guarantee lives at the CALL SITE, not here. MediaCache::get is
async and goes through spawn_blocking, which is the ergonomic path; but
decode is public and synchronous, and nothing in this crate’s
dependency graph prevents a renderer calling it from inside a paint. The
rule is enforced by the caller and by the tests that assert frame time is
unaffected — stating otherwise would be a false comfort.
§Why a crate, and why not inside the GPUI peer
Only GPUI draws images today. This is not in lattice-ui-gpui because
terminal graphics (kitty / sixel / iTerm2) is deliberately not foreclosed —
see docs/dev/architecture/inline-media.md §9 — and the day the TUI grows
an image path, both peers need this code. A thing both peers need can live
in neither of them.
It is not in lattice-cells either: that crate has one dependency and ten
dependents, and none of lattice-completion, lattice-listing or
lattice-diff should be compiling PNG decoders.
§Size before pixels
probe reads only enough of the file to learn its dimensions;
decode reads and decodes the whole thing. They are separate because a
block must be able to reserve the right amount of space before its
pixels exist — otherwise the document reflows when an image finishes
loading, which breaks the keystroke contract (“no pixel change to content
the user did not edit”) on every scroll past it.
A header read is bounded and cheap; it still happens off-thread, because “cheap” and “on the UI thread” are different claims.
§The cache
Keyed by (path, mtime, target). mtime is what makes an edited image
reappear rather than serving a stale decode forever, and target is in the
key because the same file at two display scales is two different decodes.
Structs§
- Decoded
Image - Decoded, scaled pixels ready for a peer to upload.
- Media
Cache - A bounded decode cache.
Enums§
- Media
Error - Why a block has no pixels. Every variant is a placeholder plus alt text outcome, never a panic and never a stall.
- Pixel
Format - The byte layout a consumer needs.
Constants§
- MAX_
PIXELS - Refuse anything above ~64 megapixels.
- MIN_
BLOCK_ LH - A block never draws thinner than this, however extreme its aspect ratio.
Functions§
- block_
geometry - How much space a block should take, given what it is and where it goes.
- decode
- Decode
pathand scale it to fittarget(width, height in px), preserving aspect ratio and never scaling up. - fit_
within - Scale
srcdown to fit insidebounds, preserving aspect ratio. Returnssrcunchanged when it already fits — the never-upscale rule. - probe
- A file’s natural size, from its header alone.