Files
Sylpheed/tools/re-capture/frame_clock.sh
sylph-decoder 89d90294b4 re: the boot splash dwells are declared -- and wall clock is the wrong unit
The port asked for two wall-clock timestamps across the boot splashes. Measured,
and the measurement's own result is that timestamps are not the invariant.

The dwells are the bundles' own declared timelines: publisher t=0..255 = 4.250 s
at 60 units/s, developer t=0..210 = 3.500 s. The corpus's independent screenshot
timing over three cold boots gives 4.30/4.60/4.37 and 3.51/3.50/3.37 -- the
developer agreeing to 1.1%, two of its three runs to 0.3%.

A fresh no-input boot with a frame->wall-clock map puts the same two dwells at
5.10-5.61 s and 3.83-4.30 s, 15-20% longer than both the declared values and the
corpus's runs, on the same disc and the same declared timeline. So the
wall-clock dwell is an emulator-pacing artefact that varies run to run, and a
port authoring seconds is authoring one run's pacing.

Boundaries from the draw stream, read per quad: publisher glow frame 1, wordmark
6-119, three frames with NO sprite drawn, developer glows 123, wordmarks
140-209, intro video 216. The 3-frame gap replicates the earlier 4-frame
measurement within the +-1 both are quantised to.

New tool frame_clock.sh, and its limitation found by its own control: it
resolves to one BUFFER FLUSH, not one frame. The capture writes through a C++
ofstream, so tail sees the log in bursts -- 69 of 125 samples showed no advance
and the rest jumped 7-15 frames. Naive interpolation inside a burst made the
apparent rate swing between 0.0164 and 0.0316 s/frame, which is the flush and
not the guest. Frames 119 and 123 fall in one burst, so the inter-splash gap is
not separable by this clock at all. Everything is quoted as brackets and the
point estimates were withdrawn before being reported.

palogo_anima never appears in the log and is NOT reported as undrawn: the
developer bundle batches 7 elements into one draw and only the first two quads
are logged. That is the trap that produced the eff3 false negative, so it is
named rather than claimed.

Also records the port's correction: ptcopyright has 105 instants with alpha >= 1
(t=139..243) against 105.89 units of span; I had quoted the rounded span.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QsEPXWVaEpyfudtR6re1Pd
2026-08-29 21:29:06 +00:00

44 lines
2.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# Sample (wall clock, last captured frame) while a UI draw capture runs.
#
# The `xenia_re_ui_draws_NN.log` carries frame NUMBERS and no timestamps, and
# Canary logs no fps, so a draw capture can say "4 frames of black" and not how
# long that is. Two runs measured 13.1 and ~28 presented fps, so a nominal rate
# cannot be assumed either.
#
# This polls the growing log and writes `epoch frame` pairs, which invert to give
# any frame's wall-clock time.
#
# 🔴 RESOLUTION IS ONE BUFFER FLUSH, NOT ONE FRAME. The capture writes through a
# C++ ofstream, so `tail` sees the log in flush-sized bursts: measured, 69 of 125
# samples showed NO advance and the rest jumped 7-15 frames at once. Interpolating
# a frame's time *inside* a burst invents precision -- it made the apparent rate
# swing between 0.016 and 0.032 s/frame, which is the flush, not the guest.
#
# Use BRACKETS: a frame's true time lies between the last sample that had not
# reached it and the first that had. Two frames inside one burst (the 3-frame
# black gap between the boot splashes) are not separable at all.
#
# It also GUARDS canary.stdout: a guest fault dumps registers without bound
# (223 MB and 519 MB observed on a filesystem at 91 %), so the run is killed if
# stdout passes the cap.
#
# frame_clock.sh <draws.log> <out.tsv> [seconds] [interval] [stdout-file] [cap-MB]
set -u
LOG="$1"; OUT="$2"; DUR="${3:-150}"; IVAL="${4:-0.25}"; SOUT="${5:-}"; CAP="${6:-400}"
: > "$OUT"
end=$(( $(date +%s) + DUR ))
while [ "$(date +%s)" -lt "$end" ]; do
f=$(tail -c 400000 "$LOG" 2>/dev/null | grep -oE '^--- frame [0-9]+' | tail -1 | awk '{print $3}')
[ -n "$f" ] && printf '%s\t%s\n' "$(date +%s.%N)" "$f" >> "$OUT"
if [ -n "$SOUT" ] && [ -f "$SOUT" ]; then
mb=$(( $(stat -c %s "$SOUT") / 1048576 ))
if [ "$mb" -gt "$CAP" ]; then
echo "STDOUT ${mb}MB > ${CAP}MB cap — guest is dumping registers, killing" >&2
pkill -9 -x xenia_canary; exit 3
fi
fi
sleep "$IVAL"
done
echo "sampled $(wc -l < "$OUT") points"