type GL = WebGL2RenderingContext | WebGLRenderingContext; export interface ManagedBuffer { buffer: WebGLBuffer; byteCapacity: number; } export declare class BufferPool { private _gl; private _buffers; private _totalCapacity; private _maxCapacity; constructor(gl: GL); get totalCapacity(): number; get maxCapacity(): number; set maxCapacity(cap: number); ensureCapacity(totalRows: number): void; /** * Read-only lookup by name. Returns the existing managed buffer, or * `undefined` if no buffer has been allocated under that name yet. * * Render-path callers that bind buffers for `drawArrays` / * `drawArraysInstanced` MUST use this rather than `getOrCreate`: * the latter recreates (zero-initialized) when `_totalCapacity` has * grown past the current `byteCapacity`. That recreate is desired * during `upload` (where `bufferSubData` immediately writes the * actual data) but catastrophic during render — it wipes the * previous draw's vertex data, leaving `drawArrays` to issue * against zeros and produce no visible glyphs (a one-frame blank * plot area while gridlines/chrome remain correct). * * Specifically, `ensureBufferCapacity(totalRows)` from a pending * draw updates `_totalCapacity` *before* its matching `uploadChunk` * has run; a pan/zoom-induced render landing in that window would * otherwise see `requiredBytes > byteCapacity` and recreate. */ peek(name: string): ManagedBuffer | undefined; getOrCreate(name: string, componentsPerVertex: number, bytesPerElement: number): ManagedBuffer; /** * Upload `data` into the named GPU buffer at `byteOffset`. The * buffer is sized lazily by `getOrCreate` to * `_totalCapacity × componentsPerVertex × data.BYTES_PER_ELEMENT`. * Callers MUST keep `byteOffset + data.byteLength` within that * capacity — `bufferSubData` raises `INVALID_VALUE` on overflow * and the upload is silently dropped at the GL layer. * * Common pitfall: passing a module-level scratch typed array whose * `length` exceeds the current frame's valid-data count. Scratch * buffers in chart impls grow monotonically across frames; the * GPU buffer is sized to the *current* `_totalCapacity`. After a * renderer-session reset (e.g. plugin disconnect/reconnect) the * GPU buffer is fresh while the scratch retains its historical- * peak length, and the upload writes past the buffer end. Always * pass `data.subarray(0, n × componentsPerVertex)` when uploading * from a scratch. * * Set `BUFFER_POOL_STRICT = true` in `config.ts` to convert * overflows from opaque GL errors into descriptive throws at the * offending stack frame. */ upload(name: string, data: Float32Array | Int32Array, byteOffset: number, componentsPerVertex?: number): WebGLBuffer; releaseAll(): void; } export {};