feat(oakrender): render-process isolation S3 - audio over shm, per-ticket slot formats, tuning

- Audio tickets join the process backend: render_audio_batch wire
  message, workers mix straight into shm slots (SLOT_FORMAT_AUDIO_F32),
  ShmAudio payload with release semantics, crash isolation covers audio
  renders; playback audio uses an async 4-chunk prefetch drained on the
  UI tick (also fixes the sub-60fps chunk truncation bug); oversized
  ranges and dispatcher outages fall back to in-process inline.
- Per-ticket slot formats: force_format is honored (exports request
  F32 slots, dropping the BGRA8 round-trip and its 8-bit quantization);
  segments grow on demand via worker-idle rebuild with generation
  handoff; the scheduler filters over-capacity tickets.
- Adaptive defaults: 128-256MB/worker segment budgets drive slots per
  worker, batch size follows workers/slots; bench_process example
  measures throughput and adjacent-frame completion deltas
  (e.g. 4 workers: 841 fps, 4.6ms mean delta).
This commit is contained in:
2026-08-19 00:42:03 +08:00
parent 194d761ade
commit adf2cef32c
18 changed files with 2156 additions and 185 deletions
+13
View File
@@ -733,6 +733,19 @@ pub fn render_audio(
sample_rate: samples.sample_rate,
channel_count: samples.channel_count,
}),
// M15 S3 process backend: the audio sits in a worker shm slot; copy
// it out and release the slot (the bytes must outlive the slot).
Ok(TicketPayload::ShmAudio(audio)) => {
let samples = audio.to_audio_samples();
if let Some(m) = RenderManager::global() {
m.release_audio_frame(&audio);
}
Ok(RenderedAudio {
data: samples.samples,
sample_rate: samples.sample_rate,
channel_count: samples.channel_count,
})
}
_ => Err("audio render produced no samples".to_string()),
}
}