Commit Graph

3 Commits

Author SHA1 Message Date
Shokunin 992d3cfe73 Render thread: user-interactive QoS on macOS
A default-QoS pthread is scheduled onto efficiency cores when the host is
busy, which put the render thread, now on every frame's critical path,
behind the emulation thread it is supposed to relieve.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 12:49:53 -07:00
Shokunin 9abcff08a4 Render thread: skip a present only when two newer frames wait
One frame behind is the normal pipelined state when the render thread is
the slower side; skipping on it dropped nearly every present at 4K
widescreen. rt_frames_ahead() counts the complete frames queued after
the one being replayed; the backend skips only at two, where the
emulation thread is at the in-flight bound waiting on the render thread.
The unit test checks the count never exceeds the bound and that both
cases occur under a slow consumer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 12:49:47 -07:00
Shokunin 01f9cd34d6 Render thread core: SPSC command ring, frame bound, sync-point hand-off
Backend-neutral core for the opt-in [video] render_thread: the emulation
thread appends records to a single-producer/single-consumer ring and the
render thread replays them in order with the graphics context current.
rt_frame_end bounds closed frames in flight (backpressure), the render
thread can tell a frame is stale, and rt_acquire is the sync point:
drain, then move the context to the emulation thread until rt_release.
No lock is held while a record executes.

render_thread_test drives it with a fake executor and context token:
ordering and payload integrity across ring wraps, oversize refusal, the
in-flight bound under a slow consumer, stale detection, randomized
acquire/release interleaving and stop while held (TSan clean).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 12:49:14 -07:00