Stage a depth-sort permutation (the SortWorker's back-to-front
ordering, depth-sorting Phase 2). Returns count when the ordering is
staged, or 0 when it is rejected (truncated or oversized ordering,
non-positive/non-integer count, malformed buffer pair).
The ordering is never written to the buffer being drawn. It streams
into the INACTIVE one and the slot flips when that buffer holds the
WHOLE permutation (depth-sorting spec §2.1 tier 3), so every rendered
frame samples a complete ordering. There is no size threshold and no
single-shot branch: one path, and a half-applied ordering — which is
not a reordering but a corrupt permutation, drawing elements twice
and omitting as many — is structurally impossible.
This call only STAGES: pumpSortedIndexOrderingApply (driven by
the coordinator's per-frame callback) owns every slice and the flip.
That costs nothing in latency — a resolve lands between frames, so the
first slice still rides the very next render — and it keeps the
per-frame upload bound strict.
A newer ordering arriving mid-stream is HELD (at most one; latest
wins) and started after the current stream completes, rather than
restarting it: under a continuous orbit a restart-on-arrival never
converges. The coordinator's generation guard ensures only
current-generation orderings reach this writer.
The optional callbacks bind a lifecycle to this specific ordering
(the coordinator's 'Depth Sort' profiler session — issue #713). They
fire ONLY when the ordering is accepted (this call returns > 0):
exactly one of onApplied (post-render acknowledgement after its buffer
flips in) or onAbandoned (dropped before that draw). A rejected write
(returns 0) fires
neither, leaving lifecycle ownership with the caller.
Stage a depth-sort permutation (the SortWorker's back-to-front ordering, depth-sorting Phase 2). Returns
countwhen the ordering is staged, or 0 when it is rejected (truncated or oversized ordering, non-positive/non-integer count, malformed buffer pair).The ordering is never written to the buffer being drawn. It streams into the INACTIVE one and the slot flips when that buffer holds the WHOLE permutation (depth-sorting spec §2.1 tier 3), so every rendered frame samples a complete ordering. There is no size threshold and no single-shot branch: one path, and a half-applied ordering — which is not a reordering but a corrupt permutation, drawing elements twice and omitting as many — is structurally impossible.
This call only STAGES: pumpSortedIndexOrderingApply (driven by the coordinator's per-frame callback) owns every slice and the flip. That costs nothing in latency — a resolve lands between frames, so the first slice still rides the very next render — and it keeps the per-frame upload bound strict.
A newer ordering arriving mid-stream is HELD (at most one; latest wins) and started after the current stream completes, rather than restarting it: under a continuous orbit a restart-on-arrival never converges. The coordinator's generation guard ensures only current-generation orderings reach this writer.
The optional
callbacksbind a lifecycle to this specific ordering (the coordinator's 'Depth Sort' profiler session — issue #713). They fire ONLY when the ordering is accepted (this call returns > 0): exactly one ofonApplied(post-render acknowledgement after its buffer flips in) oronAbandoned(dropped before that draw). A rejected write (returns 0) fires neither, leaving lifecycle ownership with the caller.