//#region src/main/private/SharedFrameMemAddressSlotPool.d.ts declare enum MemAddressSlotState { Free = 0, Writing = 1, Ready = 2, Processing = 3 } interface FrameMemAddressSlot { index: number; address: number; view: Uint8ClampedArray; } interface SharedFrameMemAddressSlotPoolBuffers { stateSharedBuffer: SharedArrayBuffer; addressSharedBuffer: SharedArrayBuffer; heapBuffer: SharedArrayBuffer; memAddressSlotByteLength: number; } interface CreateSharedFrameMemAddressSlotPoolOptions { memAddressSlotCount: number; memAddressSlotByteLength: number; allocateUint8Array: (length: number) => number; /** * Returns the CURRENT WASM heap buffer. Must be a provider, not a captured SharedArrayBuffer: * memory growth mints a new SAB (the old object's byteLength is frozen forever), and even the * pool's own slot allocations can trigger growth. The worker passes `() => Module.HEAPU8.buffer` * so its views always track the live heap. */ getHeapBuffer: () => SharedArrayBuffer; } /** * A fixed-size pool of frame memAddressSlots in the shared WASM heap, with an Atomics-backed per-memAddressSlot state * machine (FREE -> WRITING -> READY -> PROCESSING -> FREE) so the main thread and the worker can * hand frames back and forth without copying or transferring them. * * A memAddressSlot's *address* is not reusable: once handed to the engine (`ImageBufferFrameSource::outputFrame`), * ownership of that memory transfers to the engine, which frees it whenever it's done — on its own * schedule, possibly after this pool would otherwise have recycled it. So `release()` always retires * the address a memAddressSlot held and requires a fresh replacement address to refill it; only the *memAddressSlot slab* * (the fixed set of indices/state entries) is reused, never a specific address. * * Two instances can observe the same live pool from different threads: `create()` (worker-side; does * the actual WASM allocation) and `attach()` (main-thread side; wraps the buffers `create()` produced, * without needing `allocateUint8Array`). * * WASM memory growth: each `memory.grow()` mints a NEW SharedArrayBuffer object; SAB objects obtained * earlier keep their byteLength frozen forever (they still alias the same backing store, up to their * length). The `create()` side reads the live heap through a provider so its views always fit. The * `attach()` side can only ever see the clone it was handed at negotiation time, so a replacement * address allocated after growth can land beyond it — `claimFreeMemAddressSlot` detects that, refuses * the claim without throwing or stranding the memAddressSlot, and reports it via `hasStaleAddresses` * so the owner can renegotiate a replacement pool (which re-clones the current, larger heap). */ declare class SharedFrameMemAddressSlotPool { private readonly getHeapBuffer; private readonly memAddressSlotByteLength; private readonly stateBuffer; private readonly addressBuffer; private _staleAddressDetected; private constructor(); static create(options: CreateSharedFrameMemAddressSlotPoolOptions): SharedFrameMemAddressSlotPool; static attach(buffers: SharedFrameMemAddressSlotPoolBuffers): SharedFrameMemAddressSlotPool; /** * True once a memAddressSlot's address was found to lie beyond this instance's heap buffer — the * WASM heap grew past the buffer captured at negotiation time. The pool is permanently compromised * for this instance (replacement addresses will keep landing higher): stop claiming and negotiate a * replacement pool. */ get hasStaleAddresses(): boolean; get memAddressSlotCount(): number; /** * The shared buffers backing this pool, to be handed (once) to the other thread via `attach()`. * `heapBuffer` is read from the provider at call time, so the hand-off carries the freshest heap * SAB — including one minted by growth that this pool's own slot allocations triggered. */ get buffers(): SharedFrameMemAddressSlotPoolBuffers; private viewFor; /** * Claims the first FREE memAddressSlot, atomically moving it to WRITING. Returns null if every * memAddressSlot is busy — or if a FREE memAddressSlot's address lies beyond this instance's heap * buffer (the WASM heap grew past the SAB captured at negotiation time; see the class doc). In the * stale case the memAddressSlot is put back to FREE (never stranded), `hasStaleAddresses` flips * sticky-true, and no in-bounds fallback is attempted: replacement addresses will keep landing * beyond the captured buffer, so the pool must be replaced, not limped along. */ claimFreeMemAddressSlot(): FrameMemAddressSlot | null; /** Called by the writer once pixel data has been written into the claimed memAddressSlot's view. */ markReady(index: number): void; /** * Called by the claiming thread when a claimed memAddressSlot is dropped before `markReady` (e.g. the * capture is discarded, a frame handler skips it, or an exception occurs) so it doesn't strand the * memAddressSlot forever. Safe because the claiming thread is the only possible holder of WRITING and * the address hasn't been handed to anyone else yet - nothing else can be reading or writing it. */ abandon(index: number): void; /** * Called by the consumer (worker) when it receives a "memAddressSlot ready" message. Returns null rather * than throwing when the memAddressSlot isn't READY, so a stale or duplicate message can be safely ignored. */ beginProcessing(index: number): FrameMemAddressSlot | null; /** * Called by the consumer once it has retired the memAddressSlot's address (handed it off to a new owner * that will free it on its own schedule, e.g. the engine). `replacementAddress` refills the memAddressSlot * so it can be claimed again; the retired address must never be read or written by this pool again. */ release(index: number, replacementAddress: number): void; /** Frees every memAddressSlot's current backing allocation. Callers must ensure no memAddressSlot is mid-flight (PROCESSING). */ dispose(deleteUint8Array: (address: number) => void): void; } //#endregion export { SharedFrameMemAddressSlotPoolBuffers as a, SharedFrameMemAddressSlotPool as i, FrameMemAddressSlot as n, MemAddressSlotState as r, CreateSharedFrameMemAddressSlotPoolOptions as t };