fix(render): cap the playback pre-render window to the slot headroom
Pressing play froze the app: the 120-frame pre-render window could hold every shm slot in the pool (e.g. 8 workers x 3 F32 slots = 24 < 120). Once the wall-clock playhead outran the renders, the UI's synchronous frame wait had no credit to dispatch, and the slot-releasing cleanup runs on that same blocked UI thread — a hard deadlock. The window is now capped to (workers x slots - workers), reserving one slot per worker so interactive (seek/sync display) and audio tickets always dispatch. preview_window_capacity is exposed through JobDispatch; a unit test pins the reserve math.
This commit is contained in:
@@ -1609,6 +1609,15 @@ impl RealEngine {
|
||||
|
||||
let forward = config_get_int(CONFIG_KEY_PREVIEW_WINDOW, DEFAULT_PREVIEW_WINDOW_FORWARD)
|
||||
.clamp(8, 1200);
|
||||
// Cap the window to the pool's slot headroom: a window that can
|
||||
// hold every slot starves interactive (this frame's synchronous
|
||||
// render) and audio tickets of credit, and since the slot-releasing
|
||||
// cleanup runs on this same UI thread, a synchronous wait then
|
||||
// deadlocks playback. Keep one slot per worker in reserve.
|
||||
let forward = match m.dispatch.preview_window_capacity() {
|
||||
Some(capacity) => forward.min(capacity as i64).max(1),
|
||||
None => forward,
|
||||
};
|
||||
let end = length.max(playhead).min(playhead + forward);
|
||||
|
||||
// Reset / rebuild when the node changed or an invalidation bumped the
|
||||
|
||||
Reference in New Issue
Block a user