import type { WebGLContextManager } from "../webgl/context-manager"; /** * Request a coalesced render of `glManager` whose body is * `fullRender`. Returns a promise that resolves when this entry's * Phase 2 (`awaitGpuFence` + `endFrame`) completes. * * If a request is already pending for the same glManager, the new * call's `fullRender` closure replaces the prior one (latest call * wins; closures read chart state lazily so this is functionally a * no-op, but keeps the closure fresh) and the returned promise * resolves alongside the existing waiters. */ export declare function requestRender(glManager: WebGLContextManager, fullRender: () => void): Promise; /** * Run `op` synchronously if no drain `present()` is currently active * for `glManager`. Otherwise queue `op` to run as soon as that * glManager's in-flight `present()` completes (after `endFrame`, * after the resolved/rejected waiters). * * Used by canvas-mutating callers — `WorkerRenderer.resize`, * `WorkerRenderer.clear` — to avoid wiping the offscreen between * Phase 1 paint and Phase 2 `endFrame`. `glManager.resize` setting * `canvas.width = N` clears the drawing buffer immediately * (per the WebGL spec, out-of-band from the GL command queue), and * a clear that lands in Phase 2's fence-wait yield window corrupts * the bitmap that `transferToImageBitmap` ships, producing a blank * frame on the host. * * Deferred ops execute in `present()`'s `finally` clause, so they * land *after* the in-flight drain's bitmap has been shipped and * before the next drain starts. If a deferred op itself triggers a * `requestRender`, the resulting entry queues into `pending` and * the drain's tail check (`pending.size > 0 → scheduleFrame(drain)`) * picks it up for the next RAF. */ export declare function deferIfDraining(glManager: WebGLContextManager, op: () => void): void; /** * Test-only: clear pending state. Production callers must not use * this — outstanding waiters are silently dropped. */ export declare function _resetForTest(): void;