Expand description
kui’s recording format (docs/adr/0058-a-recording-is-a-timeline.md):
a timeline of what happened in a kui app, in frames and between them.
One clock — µs since the recording began — and Records placed on
it: frames begun and finished with why they ran and who held them,
presents, nested spans with their CPU time and the node they began
under, inputs arriving, events handed to the app, wakes, frame
requests, the driver’s loop going to sleep and waking, counters,
gauges, marks, the app’s notes, and each component placed and how it
was filled. Frames are intervals on the clock; what
happens after one ends and before the next begins is the next one’s
gap.
kui-core writes it (the devtools’ Perf tab records it, and
KUI_PERF_TRACE=path streams it to a file); this crate reads it with
no kui at all:
use kui_trace::{Record, Track, Trace, Span, Origin};
let mut t = Trace::new();
let (build, _) = t.names.get("build");
t.records.push(Record::FrameBegin { t: 0, frame: 1, causes: vec![] });
t.records.push(Record::Span(Span {
track: Track::MAIN, id: 1, parent: 0, name: build, origin: Origin::Kui,
start: 10, dur: 400, cpu: None, node: 0, cut: false,
}));
t.records.push(Record::FrameEnd { t: 500, frame: 1, unchanged: Some(false), nodes: 12 });
let back = Trace::from_bytes(&t.to_bytes()).unwrap();
let tl = back.timeline();
assert_eq!(tl.frames[0].core_us(), 500);
assert_eq!(back.name(tl.spans[0].name), "build");A recording still being written is read as it grows: a Stream
decodes what its Transport hands over — a FileTransport, with a
Watch that says when the file moved — and keeps the record cut
between reads for the next (ADR 0075, decision 5).
analysis reads a timeline the way the Perf tab does — phases, an
input’s path to the screen, a frame’s verdict, burns, spans grouped by
name and origin — and adapters write it out for Chrome’s trace
viewer, Perfetto, speedscope and the Firefox Profiler.
Modules§
- adapters
- The recording written for the tools that already exist (ADR 0058,
decision 12): Chrome’s trace-event JSON (
chrome://tracing, Perfetto’s viewer), Perfetto’s own protobuf, speedscope’s and the Firefox Profiler’s. An adapter maps what its format has and drops what it has not. - analysis
- What a timeline says, read the same way by every reader (ADR 0058, decisions 9 and 10): a frame’s phases, the path from an input to the screen, a verdict on why it lagged, the runs of frames with no input, and the recording grouped by span, by origin and by what its gaps held.
- diff
- Two recordings compared (ADR 0058, decision 12): each span’s and
phase’s spread, the burns, the gaps and the counters, before and after
—
kui-trace diff A B, with--fail-overa CI’s threshold. - dump
- A recording as text, one record a line (
kui-trace dump): for a diff between two runs, a grep, a bug report’s body. - query
- Shared, windowless perf exploration (ADR 0078). All times are µs. Selection chooses a frame population; span filters only affect attribution. The module has no dependency on Lua, channels, a window, or serialization.
- synth
- Recordings made up, in the shape a session writes (backlog F250, ADR 0075 decision 12): for a reader’s tests, a bench, and the inspector’s spike, which needs ten minutes at 120 Hz — 72,000 frames, a million spans — that no Perf tab keeps.
Structs§
- Encoder
- Encodes records one after another, keeping the last time written.
- Event
- File
Transport - A recording’s file, read as it grows.
- Frame
- One frame of the timeline.
- Gauge
- Holder
- Who held a frame.
- Input
- Mark
- Names
- Names to ids, as a writer hands them out: each string once.
- Placement
- A component placed, and how it was filled (
Record::Placement). - Present
- A frame drawn: the driver’s render and vsync’s wait, µs.
- Reader
- Reads records back, in order.
- Request
- Session
- What the recording was made of, once, first.
- Span
- A span closed: a name, a start and a length on its track, nested in its parent.
- Stream
- A recording decoded as its bytes come.
- Timeline
- Every record of a recording, placed: frames in order, everything else sorted by time.
- Trace
- A recording in memory: what it was made of, its names and tracks, and the rest of its records in the order written.
- Track
- A row of the timeline:
Track::MAINthe thread the core runs on,Track::LOOPthe driver’s loop, and one per nameperf_measurewas given, declared by aRecord::Track. - Watch
- A file watched on a thread of its own:
on_changeruns there whenever the file’s size or modification time moved since the last look. The thread stops when theWatchdrops. - Writer
- Records written to
Was they come —KUI_PERF_TRACE’s stream.
Enums§
- Error
- What went wrong reading.
- Loop
Event - What the driver’s loop did.
- Origin
- Who a span or a measurement is for.
- Poll
Error - Why
Stream::pollstopped. - Polled
- What a
Transporthad. - Record
- One record.
Constants§
Traits§
- Transport
- Where a recording’s bytes come from (ADR 0075, decision 5): a file
([
FileTransport]), and later a pipe or a socket, behind one door.
Functions§
- header
- The header every recording opens with.
Type Aliases§
- NameId
- A string written once per recording by a
Record::Name;0is the empty string, never written.