WebGPU timestamp queries resolve to nanoseconds (BigInt64Array values
read back from the resolve buffer). The renderer's budgets and every other
timing surface in this codebase (FrameStats.timestamp via
performance.now()) are in milliseconds, so every raw pair gets converted
through this one function.
Takes bigint (the actual readback type) so a caller cannot accidentally
pass an already-lossy Number(timestamp) of a value that may exceed
Number.MAX_SAFE_INTEGER (a query set can hold timestamps for a
long-running session; ~104 days of nanoseconds overflows a JS number).
The subtraction happens in bigint space and only the final, small
(sub-second, in practice sub-100ms) millisecond duration is converted to
number.
Clamps a negative delta (endNs < startNs) to 0 rather than returning
a physically impossible negative duration. This is reachable: GPU
timestamps are not guaranteed monotonic across a device reset (see this
module's own doc above). 0 is the honest floor — a duration cannot be
negative, and unlike a raw negative number it cannot silently drag a
min/mean computed downstream into nonsense. This is the guard's one
choke point: frameTotalMs/passDurationsMs (frame-timing.ts) sum
this function's output directly, without ever routing it through
computeDurationStats, so a guard placed only in computeDurationStats
would miss that summation entirely. Use isNegativeDelta alongside this
function where the caller wants to know a clamp happened.
WebGPU timestamp queries resolve to nanoseconds (
BigInt64Arrayvalues read back from the resolve buffer). The renderer's budgets and every other timing surface in this codebase (FrameStats.timestampviaperformance.now()) are in milliseconds, so every raw pair gets converted through this one function.Takes
bigint(the actual readback type) so a caller cannot accidentally pass an already-lossyNumber(timestamp)of a value that may exceedNumber.MAX_SAFE_INTEGER(a query set can hold timestamps for a long-running session; ~104 days of nanoseconds overflows a JS number). The subtraction happens inbigintspace and only the final, small (sub-second, in practice sub-100ms) millisecond duration is converted tonumber.Clamps a negative delta (
endNs < startNs) to0rather than returning a physically impossible negative duration. This is reachable: GPU timestamps are not guaranteed monotonic across a device reset (see this module's own doc above).0is the honest floor — a duration cannot be negative, and unlike a raw negative number it cannot silently drag amin/meancomputed downstream into nonsense. This is the guard's one choke point:frameTotalMs/passDurationsMs(frame-timing.ts) sum this function's output directly, without ever routing it throughcomputeDurationStats, so a guard placed only incomputeDurationStatswould miss that summation entirely. UseisNegativeDeltaalongside this function where the caller wants to know a clamp happened.