Fix periodic tvOS playback stutter from render stalls on mpvQueue

Build 264 stutters for a split second every ~10 seconds. The periodic
playback-stats task fetches ~30 debug properties in one ~190ms block on
mpvQueue, and MPVClient.render() wrapped mpv_render_context_render in
mpvQueue.sync - so the render thread queued behind the fetch and stalled
~190ms, at exactly the stats interval. Build 261 predates the stats
task, which is why it was unaffected.

libmpv's render API is documented thread-safe relative to the client
API, so render-context calls no longer go through mpvQueue:

- New renderContextLock protects renderContext lifecycle vs use;
  render(), renderWithDepth(), renderSoftware(), reportSwap(),
  shouldRenderUpdateFrame() and hasRenderContext use it
- Render-update callbacks dispatch on a dedicated renderEventQueue so
  frame-ready notifications can't queue behind property/command work
- destroyRenderContext takes mpvQueue then the lock, still excluding
  in-flight renders during teardown
- The stats task skips its property fetch on iOS/tvOS unless verbose
  MPV logging is on (macOS keeps it for the render watchdog)
- performRender slow-frame warnings now break down render vs present
  time and report frame-delivery gaps for future triage
This commit is contained in:
Arkadiusz Fal
2026-07-19 00:53:06 +02:00
parent c3bb01e862
commit 6aa5fd8ee7
3 changed files with 150 additions and 76 deletions

View File

@@ -2063,6 +2063,15 @@ extension MPVBackend: MPVClientDelegate {
try? await Task.sleep(for: .seconds(10))
guard let self, !Task.isCancelled, let client = self.mpvClient else { return }
#if !os(macOS)
// Only macOS needs the property fetch every tick (render
// watchdog below). Elsewhere the batched mpv_get_property
// calls contend with the playback core and caused a visible
// stutter every 10s on tvOS, so skip the fetch entirely
// unless verbose logging wants the stats line.
guard MPVLogging.verboseEnabled else { continue }
#endif
let props = await client.getDebugPropertiesAsync()
#if os(macOS)