Skip to content

perf(gc573): faster start-up and timestamped streamer log - #60

Merged
Everlite merged 6 commits into
Everlite:devfrom
Scyllinice:perf/faster-startup
Nov 10, 2026
Merged

Everlite merged 6 commits into
Everlite:devfrom
Scyllinice:perf/faster-startup

Conversation

@Scyllinice

Copy link
Copy Markdown
Contributor

Faster GC573 start-up and a timestamped streamer log

Depends on the HDMI 2.0 receiver equalisation PR (fix/hdmi2-rx-eq). This branch is stacked on it, so until that PR merges the diff also shows its four commits. The changes in this PR are the last five commits, starting at a155c16.

Why

Starting capture on a GC573 took ~9.5 s from launch to the first frame, and the log couldn't show where the time went. streamer.log was written in 4 KB blocks with no timestamps, so the Control Hub also saw status lines late.

What

  • Timestamped, line-buffered log (gc573_user_log.[ch]). After argument parsing, stdout and stderr are replaced with fopencookie() streams that write each line straight to the fd, prefixed with the seconds since start ([ 5.706] ...). The banner records the wall-clock start time. Output stays synchronous, so a crash loses at most the line being written. EVERLIVE_LOG_TIMESTAMPS=0 turns the prefix off. The Control Hub matches log lines with unanchored regexes, so the prefix doesn't affect it.
  • Poll the FPGA DDR sampler instead of sleeping a fixed 2 s after each kick. The lock has to hold for 50 ms before it counts, and the timeout and number of attempts are unchanged. On the test card it locks after ~1.63 s, which saves ~0.35 s.
  • Reuse the last clean link EQ. gc573_rx_eq_tune() takes the RS and DFE taps that last left the port error-free, applies them and keeps them if one 100 ms CED window reads zero. Otherwise it runs the normal auto-EQ, so stale settings cost one extra window. The streamer keeps the settings per receiver in memory and in $XDG_STATE_HOME/everlive/link-eq (default ~/.local/state). The Link EQ log line shows how the saved settings measured (saved EQ 0 errors, or none).

Results (GC573, RetroTINK 4K → 4K60 RGB)

Before After
Launch → capturing ~9.5 s 7.7–8.0 s with saved EQ
Input link EQ ~730 ms (2.6 s when the RS sweep runs) ~227 ms
DDR sampler wait 2.0 s fixed ~1.63 s (measured)

In 22 starts the saved settings passed their check every time.

The remaining ~8 s is mostly fixed by the hardware or the source: card reset ~0.6 s, DDR sampler ~1.6 s, chip init and EDID programming ~2.1 s (including a deliberate 500 ms HPD-low pulse), and the source handshake ~1.0 s.

Tried and dropped

  • Retraining skew around the saved RS before falling back. With bad saved settings it only roughly halved the errors, never rescued a start, and added ~0.3 s.
  • Arming HDMI OUT (TX2) only after capture starts (~0.47 s). That setup would then block the main loop, which also renders the window, right after the first frame, and HDMI OUT would come up 2–3 s later. Not done.

Testing

  • Every commit builds with gcc and clang, and make selftest passes.
  • Hardware: repeated timed starts on a GC573 with a RetroTINK 4K. Saved-EQ hits and misses were both exercised: misses were forced with deliberately wrong saved settings, and the normal auto-EQ path took over.

Scyllinice and others added 6 commits November 9, 2026 22:28
streamer.log is written through stdio, which buffers file output in
4 KB blocks.  The Control Hub saw status lines seconds late, and the
log had no timing, so slow starts could not be diagnosed.

Replace stdout/stderr with fopencookie() streams after argument parsing.
They are line-buffered, write straight to fd 1/2, and prefix each line
with the seconds since start ([   5.706] ...).  The banner records the
wall-clock start time.  EVERLIVE_LOG_TIMESTAMPS=0 keeps plain lines (but
still line-buffered).  The Control Hub matches log lines with unanchored
regexes, so the prefix does not affect it.
gc573_user_bridge_wait_for_ddr() kicked the sampler, slept a fixed
2000 ms and checked once.  Poll every 10 ms within the same 2 s budget,
and accept the lock once it has held for 50 ms, so a transient bit
right after the kick is not taken as a lock.  The number of attempts
and the timeout are unchanged.

On the test card (GC573, RetroTINK 4K source) the sampler locks after
~1.63 s, so this saves ~0.35 s per start.  The log now reports the
time taken.
Every HDMI 2.0 lock ran the full hardware auto-EQ on the input
receiver (~0.75 s), or the RS sweep when that left errors (~2.6 s),
although the source and cable rarely change between starts.

gc573_rx_eq_tune() now takes the settings that left the port
error-free last time (RS and DFE taps per lane).  After the baseline
it applies them and keeps them if one 100 ms CED window reads zero.
Otherwise it continues with the normal auto-EQ path, so a stale entry
costs one extra window.  The result returns the final settings when
the link ends clean.

The streamer keeps them per receiver in memory for re-locks and in
$XDG_STATE_HOME/everlive/link-eq (default ~/.local/state) across
restarts.  The log shows 'auto-EQ skipped (saved EQ clean)' when they
were used.

Hardware (GC573, RetroTINK 4K, 4K60 RGB): input EQ took 227 ms with
the saved settings, against 731 ms for a fresh auto-EQ.
The Link EQ line now has a 'saved EQ' field: 'none' when nothing was
saved for the port, otherwise the error count from the saved settings'
100 ms check.  This shows whether a full auto-EQ ran because the saved
settings failed or because there were none.

A skew retrain around the saved RS before falling back was also
tested.  On the card it only roughly halved the errors from bad saved
settings, never rescued a start, and added ~0.3 s to the fallback, so
it was dropped.  Across 22 starts the saved settings passed the check
every time.
@Everlite
Everlite marked this pull request as ready for review November 10, 2026 17:51
@Everlite
Everlite merged commit 7985150 into Everlite:dev Nov 10, 2026
1 check passed
@Everlite

Copy link
Copy Markdown
Owner

Thank you so much, Scyllinice!

We tested this locally on physical GC573 hardware and timed the startup:

  • Time from launch to active video capture dropped from ~9.5 s down to ~5.2 s.
  • The timestamped log works great and line buffering gives immediate feedback.
  • Rock solid 60.00 FPS and clean shutdown in 110 ms.

Merged into dev. Outstanding work!

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.

2 participants