paintOnce()
Wait for one Prism-owned paint pass.
paintOnce() waits for a Prism-owned paint pass. It does not export image data.
await document.fonts.ready;
await runtime.paintOnce();
const blob = await new Promise<Blob | null>((resolve) => {
canvas.toBlob(resolve, "image/png");
});Use it when you need a deterministic readiness point before calling normal canvas APIs such as toBlob() or toDataURL().
paintOnce() works without starting the runtime loop.
Multiple pending paintOnce() calls resolve from the same completed paint pass.
If paintOnce() is called during onPaint(), it waits for the next paint pass. It does not resolve from the pass already in progress.
Pending paintOnce() waiters reject if a paint handler throws or the runtime is destroyed.
stop() stops animation but does not cancel pending one-shot paints. Native paints
can reject with PrismNativeError code paint-timeout after their visible-time
budget expires. Hidden time pauses that budget without resetting it, and paints
completed while hidden still resolve. A late event cannot revive rejected callers.
Timers and visibility listeners are removed when the request settles or the
runtime is destroyed. nativePaintTimeoutMs defaults provisionally to 2000 ms;
this is a diagnostic threshold, not a scheduling guarantee.
Only pending paintOnce() callers own this deadline. invalidate() without a
waiting caller does not time out; a caller joining its outstanding native request
starts the budget then. Further invalidation or coalesced callers do not reset it.
Catching a native drawSurface() failure inside onPaint() cannot turn that pass
into success. Its waiters still reject with the original PrismNativeError, and
native diagnostics retain the failure. A later successful pass can restore health.
Prism