@godot-scene-web/canvas 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/glyph-pass-DfQlp_IH.d.ts +882 -0
- package/dist/glyph-pass-DfQlp_IH.d.ts.map +1 -0
- package/dist/glyph-pass-hbgpu.d.ts +227 -0
- package/dist/glyph-pass-hbgpu.d.ts.map +1 -0
- package/dist/glyph-pass-hbgpu.js +387 -0
- package/dist/glyph-pass-hbgpu.js.map +1 -0
- package/dist/index.d.ts +1085 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4763 -0
- package/dist/index.js.map +1 -0
- package/package.json +49 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["COLOR_MATRIX_FLOATS","IDENTITY_COLOR_MATRIX"],"sources":["../src/color.ts","../src/draw-list.ts","../src/batcher.ts","../src/clip-stack.ts","../src/damage.ts","../src/replay.ts","../src/compiled-draw-list.ts","../src/nine-patch.ts","../src/polyline.ts","../src/executor-webgl.ts","../src/headless-effects.ts","../src/present.ts","../src/retained-surface.ts","../src/textures.ts"],"sourcesContent":["/**\n * Premultiplied colour composition — the arithmetic the batcher writes into an\n * instance and the fragment shader repeats on the GPU, in one place so the two\n * can be checked against each other (and against `html`'s CPU tint bake).\n *\n * TWO CONVENTIONS MEET HERE, and mixing them up is the classic renderer bug:\n *\n * - a **premultiplied** colour carries `(r·a, g·a, b·a, a)`. That is what the\n * draw-list's tints are, what every texture in {@link ./textures} is uploaded\n * as, what the fragment emits, and what the canvas is declared as. Composing\n * two premultiplied colours is a plain componentwise multiply.\n * - a **straight** colour carries `(r, g, b, a)` with the channels independent.\n * The only thing that wants straight colour is the 3x3 colour matrix, because\n * the matrix is defined on the texture's own RGB — multiply a premultiplied\n * colour by it and a 50%-alpha pixel is transformed as if it were half as\n * bright.\n *\n * Everything below is sRGB-domain: no linearization anywhere. That is not a\n * shortcut, it is the contract — the matrices come from Godot HSV materials that\n * Godot itself applies to sRGB texture bytes, and `html`'s\n * `applyColorMatrixToPixels` (the CPU bake of the same transform, used by the DOM\n * renderer) applies them to sRGB bytes too. Linearizing here would make the GPU\n * path disagree with the DOM path it is meant to replace.\n */\n\n/** Row-major 3x3 identity, the value slot 0 of a batch's matrix table holds. */\nexport const IDENTITY_COLOR_MATRIX: readonly number[] = [\n 1, 0, 0, 0, 1, 0, 0, 0, 1,\n];\n\n/** A straight or premultiplied RGBA colour, 0..1 per channel. */\nexport interface Rgba {\n r: number;\n g: number;\n b: number;\n a: number;\n}\n\nexport function createRgba(): Rgba {\n return { r: 1, g: 1, b: 1, a: 1 };\n}\n\nexport function clamp01(value: number): number {\n if (!(value > 0)) return 0; // also catches NaN\n return value < 1 ? value : 1;\n}\n\n/**\n * Straight `(r,g,b,a)` -> premultiplied, clamped. The shape a producer has (a\n * Godot `modulate` is straight) turned into the shape {@link QuadView} wants.\n */\nexport function premultiply(\n r: number,\n g: number,\n b: number,\n a: number,\n out: Rgba,\n): Rgba {\n const alpha = clamp01(a);\n out.r = clamp01(r) * alpha;\n out.g = clamp01(g) * alpha;\n out.b = clamp01(b) * alpha;\n out.a = alpha;\n return out;\n}\n\n/**\n * Premultiplied -> straight, with the `a === 0` hole filled with black. The\n * inverse of {@link premultiply} up to that hole (a fully transparent\n * premultiplied pixel has forgotten its colour, so nothing can recover it).\n */\nexport function unpremultiply(colour: Rgba, out: Rgba): Rgba {\n const a = colour.a;\n if (a <= 0) {\n out.r = 0;\n out.g = 0;\n out.b = 0;\n out.a = 0;\n return out;\n }\n out.r = colour.r / a;\n out.g = colour.g / a;\n out.b = colour.b / a;\n out.a = a;\n return out;\n}\n\n/**\n * Compose two PREMULTIPLIED colours — a texel times its quad's tint. A plain\n * componentwise multiply, which is the whole reason the premultiplied form is\n * worth keeping: with straight colours this would need the alpha handled apart\n * from the channels it has already scaled.\n */\nexport function modulatePremultiplied(\n source: Rgba,\n tint: Rgba,\n out: Rgba,\n): Rgba {\n out.r = source.r * tint.r;\n out.g = source.g * tint.g;\n out.b = source.b * tint.b;\n out.a = source.a * tint.a;\n return out;\n}\n\n/**\n * Apply a row-major 3x3 to STRAIGHT sRGB channels in 0..1, clamped — the float\n * twin of `html`'s `applyColorMatrixToPixels` (which works in 0..255 bytes and\n * clamps because it writes a `Uint8ClampedArray`) and of the colour-matrix branch\n * in the executor's fragment shader. All three must agree; `colour.test.ts`\n * asserts the first two against each other pixel for pixel.\n *\n * Alpha is untouched, exactly as `feColorMatrix` with only the RGB rows set.\n */\nexport function applyColorMatrix01(\n colour: Rgba,\n matrix: ArrayLike<number>,\n offset: number,\n out: Rgba,\n): Rgba {\n const r = colour.r;\n const g = colour.g;\n const b = colour.b;\n out.r = clamp01(\n matrix[offset] * r + matrix[offset + 1] * g + matrix[offset + 2] * b,\n );\n out.g = clamp01(\n matrix[offset + 3] * r + matrix[offset + 4] * g + matrix[offset + 5] * b,\n );\n out.b = clamp01(\n matrix[offset + 6] * r + matrix[offset + 7] * g + matrix[offset + 8] * b,\n );\n out.a = colour.a;\n return out;\n}\n\n/**\n * The full per-fragment colour law, on the CPU: a PREMULTIPLIED texel, its\n * optional colour matrix, and the quad's PREMULTIPLIED tint, in the order the\n * shader applies them (un-premultiply, transform, re-premultiply, modulate).\n *\n * This exists so a pixel test can state the number it expects from the same\n * expression the GPU evaluates rather than from a second, hand-derived one.\n */\nexport function shadeQuadPixel(\n texel: Rgba,\n matrix: ArrayLike<number> | null,\n matrixOffset: number,\n tint: Rgba,\n out: Rgba,\n): Rgba {\n if (matrix) {\n unpremultiply(texel, out);\n applyColorMatrix01(out, matrix, matrixOffset, out);\n out.r *= out.a;\n out.g *= out.a;\n out.b *= out.a;\n } else {\n out.r = texel.r;\n out.g = texel.g;\n out.b = texel.b;\n out.a = texel.a;\n }\n return modulatePremultiplied(out, tint, out);\n}\n\n/** True when the 9 floats at `offset` are the identity, i.e. a no-op slot. */\nexport function isIdentityColorMatrix(\n matrix: ArrayLike<number>,\n offset = 0,\n): boolean {\n for (let i = 0; i < 9; i += 1) {\n if (matrix[offset + i] !== IDENTITY_COLOR_MATRIX[i]) return false;\n }\n return true;\n}\n\n/**\n * True when the 9 floats at `a`/`b` are equal — the batcher's matrix-table\n * dedupe. EXACT equality, deliberately: the table's job is to notice that many\n * cards carry the same computed tint, and an epsilon would merge two tints a\n * scene meant to differ. The corollary is that a `Float32Array` and a plain\n * `number[]` holding \"the same\" value do not match (`0.3` and its f32 round-trip\n * are different numbers), so a caller that wants dedupe should keep one storage\n * width — which the draw-list and this package both do.\n */\nexport function colorMatricesEqual(\n a: ArrayLike<number>,\n aOffset: number,\n b: ArrayLike<number>,\n bOffset: number,\n): boolean {\n for (let i = 0; i < 9; i += 1) {\n if (a[aOffset + i] !== b[bOffset + i]) return false;\n }\n return true;\n}\n","import type { ColorMatrix } from \"@godot-scene-web/core\";\nimport type { DamageRect } from \"./damage\";\n\n/**\n * The draw-list IR for a Godot 2D scene: a flat, ordered recording of what one\n * frame paints, produced by walking `CanvasItem`s in draw order and consumed by\n * a GPU executor (a later wave). It is deliberately dumb — no scene concepts, no\n * nodes, no styles, just quads, indexed textured meshes, nine-patches,\n * polylines and clip pushes/pops in\n * the order they must hit the framebuffer.\n *\n * Storage is a set of pooled parallel typed arrays, not an array of command\n * objects:\n *\n * - `kinds` / `floatOffsets` / `intOffsets` are one entry per command,\n * - `floats` and `ints` are arenas that every command's numeric payload is\n * appended into (a quad writes 16 floats + 3 ints, a polyline writes a\n * 5-float header plus 2 floats per point, …),\n * - `colorMatrices` is a side arena for the rare 3x3 color transform,\n * - `textures` is the ONLY object side-array — a texture handle cannot live in\n * a typed array.\n *\n * That layout exists so a frame costs zero garbage: `reset()` rewinds the write\n * cursors and the same buffers are refilled next frame, and reading a command\n * back fills a caller-owned view instead of allocating one. Arrays grow on\n * demand (capacity doubling) and never shrink.\n *\n * All geometry is in DESIGN space (the scene's own coordinate system); mapping\n * design space to device pixels is the executor's job.\n */\n\n/** A textured/solid rectangle: the workhorse command. */\nexport const DRAW_QUAD = 0;\n/** A 9-sliced rectangle; the executor expands it to up to 9 quads. */\nexport const DRAW_NINE_PATCH = 1;\n/** A flattened, constant-width line strip. */\nexport const DRAW_POLYLINE = 2;\n/** Push a scissor/clip rect; every later command is clipped until the pop. */\nexport const DRAW_CLIP_PUSH = 3;\n/** Pop the most recent clip rect. */\nexport const DRAW_CLIP_POP = 4;\n/**\n * A run of glyphs from one face, at one size, in one colour.\n *\n * The ONLY command that is not reducible to a textured quad, which is why it\n * exists as its own kind rather than as sugar over `pushQuad`. Its glyphs are\n * outlines evaluated per fragment (see `@godot-scene-web/hb-gpu`), so they carry\n * an atlas slot id instead of a source rect and stay crisp under rotation and\n * scale — the whole reason for the kind. An executor with no glyph pass\n * installed skips it.\n */\nexport const DRAW_GLYPHS = 5;\n/** An arbitrary triangle list with one texture and per-mesh premultiplied tint. */\nexport const DRAW_TEXTURED_MESH = 6;\n/** A screen-dependent pass executed at this exact painter position. */\nexport const DRAW_SCREEN_EFFECT = 7;\n/** A caller-owned GPU pass executed directly into the current framebuffer. */\nexport const DRAW_EXTERNAL_EFFECT = 8;\n\nexport interface ScreenEffectDrawContext {\n readonly gl: WebGL2RenderingContext;\n readonly framebuffer: WebGLFramebuffer | null;\n readonly width: number;\n readonly height: number;\n readonly damage?: DamageRect;\n readonly scissor: Readonly<{\n x: number;\n y: number;\n width: number;\n height: number;\n }>;\n}\n\n/**\n * The live painter target handed to an external pass. Unlike a screen effect,\n * this pass does not imply a snapshot or read from the accumulated framebuffer.\n */\nexport interface ExternalEffectDrawContext {\n readonly gl: WebGL2RenderingContext;\n readonly framebuffer: WebGLFramebuffer | null;\n readonly width: number;\n readonly height: number;\n readonly damage?: DamageRect;\n readonly scissor: Readonly<{\n x: number;\n y: number;\n width: number;\n height: number;\n }>;\n}\n\n/** A DOM-free pass that snapshots the executor's accumulated current target. */\nexport interface ScreenEffectDrawCommand {\n readonly screenDependent: true;\n execute(context: ScreenEffectDrawContext): boolean;\n}\n\n/** A DOM-free pass that paints directly into the executor's current target. */\nexport interface ExternalEffectDrawCommand {\n execute(context: ExternalEffectDrawContext): boolean;\n}\n\nexport type DrawCommandKind =\n | typeof DRAW_QUAD\n | typeof DRAW_NINE_PATCH\n | typeof DRAW_POLYLINE\n | typeof DRAW_CLIP_PUSH\n | typeof DRAW_CLIP_POP\n | typeof DRAW_GLYPHS\n | typeof DRAW_TEXTURED_MESH\n | typeof DRAW_SCREEN_EFFECT\n | typeof DRAW_EXTERNAL_EFFECT;\n\nexport type DrawCommandName =\n | \"quad\"\n | \"ninePatch\"\n | \"polyline\"\n | \"clipPush\"\n | \"clipPop\"\n | \"glyphs\"\n | \"texturedMesh\"\n | \"screenEffect\"\n | \"externalEffect\";\n\n/** Indexed by {@link DrawCommandKind}; for debugging and test assertions. */\nexport const DRAW_COMMAND_NAMES: readonly DrawCommandName[] = [\n \"quad\",\n \"ninePatch\",\n \"polyline\",\n \"clipPush\",\n \"clipPop\",\n \"glyphs\",\n \"texturedMesh\",\n \"screenEffect\",\n \"externalEffect\",\n];\n\n/** Godot `CanvasItemMaterial.BLEND_MODE_MIX`: normal alpha compositing. */\nexport const BLEND_MIX = 0;\n/** Godot `BLEND_MODE_ADD`. */\nexport const BLEND_ADD = 1;\n/** Godot `BLEND_MODE_SUB`. */\nexport const BLEND_SUB = 2;\n/** Godot `BLEND_MODE_MUL`. */\nexport const BLEND_MUL = 3;\n\nexport type BlendMode =\n | typeof BLEND_MIX\n | typeof BLEND_ADD\n | typeof BLEND_SUB\n | typeof BLEND_MUL;\n\n/** Bit in a command's packed flags int: mirror the source rect horizontally. */\nexport const FLIP_H = 1;\n/** Bit in a command's packed flags int: mirror the source rect vertically. */\nexport const FLIP_V = 2;\n\n/**\n * A quad's numeric payload. Views are caller-owned and reusable: fill one and\n * hand it to `pushQuad`, or pass one to `readQuad` to have it filled in place.\n * Nothing here is retained by the list — the push copies into the arenas.\n */\nexport interface QuadView {\n /**\n * The 2x3 affine that maps the unit-ish quad into design space, in Godot\n * `Transform2D` order: `[xx, xy, yx, yy, originX, originY]`, i.e.\n * `x' = xx*x + yx*y + originX`, `y' = xy*x + yy*y + originY`. Length 6.\n */\n m: Float32Array;\n /** Destination width in design units, before `m` is applied. */\n w: number;\n /** Destination height in design units, before `m` is applied. */\n h: number;\n /** Source rect on the texture page, in page pixels (not normalized). */\n srcX: number;\n srcY: number;\n srcW: number;\n srcH: number;\n /** PREMULTIPLIED tint, linear 0..1 per channel (`rgb` already times `a`). */\n r: number;\n g: number;\n b: number;\n a: number;\n blend: BlendMode;\n flipH: boolean;\n flipV: boolean;\n /**\n * Whether {@link QuadView.colorMatrix} is meaningful. Most quads carry no\n * color transform at all (the field is the IR's \"null\"), so the matrix is\n * stored in a side arena and skipped entirely when this is `false`.\n */\n hasColorMatrix: boolean;\n /**\n * Row-major 3x3 linear RGB transform (`out_rgb = m * in_rgb`, alpha\n * untouched) — an HSV-style shader tint. Length 9. Ignored unless\n * `hasColorMatrix`.\n */\n colorMatrix: Float32Array;\n}\n\n/**\n * A nine-patch's payload: a quad plus the four stretch margins. `srcX..srcH` is\n * the patch REGION on the page; the margins are insets into that region, in\n * page pixels, exactly like Godot's `NinePatchRect.patch_margin_*`.\n */\nexport interface NinePatchView extends QuadView {\n marginLeft: number;\n marginTop: number;\n marginRight: number;\n marginBottom: number;\n}\n\n/** A polyline's payload: a flattened `x, y, x, y, …` strip with one width. */\nexport interface PolylineView {\n /**\n * Flattened point coordinates in design space. Length is at least\n * `pointCount * 2`; a longer buffer is allowed (and expected, since views are\n * reused), only the first `pointCount * 2` entries are read.\n */\n points: Float32Array;\n pointCount: number;\n /** Stroke width in design units. */\n width: number;\n /** PREMULTIPLIED stroke color, linear 0..1 per channel. */\n r: number;\n g: number;\n b: number;\n a: number;\n}\n\n/**\n * An indexed triangle list sampling one texture. Positions and UVs are paired\n * by vertex index; positions are local design-space coordinates and `m` maps\n * them to design space. UVs are normalized texture coordinates, intentionally\n * not a quad source rect: arbitrary mesh topology must not be forced through a\n * rectangle-shaped source contract.\n */\nexport interface TexturedMeshView {\n /** Godot `Transform2D` mapping local vertex positions into design space. */\n m: Float32Array;\n /** Flattened local `x, y` pairs. Only `vertexCount * 2` entries are read. */\n positions: Float32Array;\n /** Flattened normalized `u, v` pairs, one pair for every position. */\n uvs: Float32Array;\n vertexCount: number;\n /** Triangle-list vertex indices. Only `indexCount` entries are read. */\n indices: Uint32Array;\n indexCount: number;\n /** PREMULTIPLIED mesh tint, linear 0..1 per channel. */\n r: number;\n g: number;\n b: number;\n a: number;\n blend: BlendMode;\n}\n\n/**\n * A glyph run's payload: one face, one size, one colour, N positioned glyphs.\n *\n * THE SLOT IDS ARE HANDLES, NOT ADDRESSES, and that distinction is the whole\n * point of the indirection. A glyph atlas evicts — it is a fixed texture holding\n * an unbounded pool — so recording a glyph's atlas OFFSET into a list that may be\n * retained and repainted next frame is how you get a different glyph's outline\n * drawn at the right size, in the right place, perfectly antialiased. Unreadable\n * text that looks like working text. A slot id survives eviction because the\n * atlas re-resolves it (re-uploading the outline if it has to) at draw time.\n *\n * Shaping is NOT this package's job. `positions` are pen positions a shaper\n * produced; the list only records them.\n */\nexport interface GlyphsView {\n /**\n * The 2x3 affine that maps the run's local space into design space, in the\n * same Godot `Transform2D` order as {@link QuadView.m}. Length 6.\n *\n * ROTATION BELONGS HERE, NEVER IN `positions`. The glyph shader dilates each\n * outline by half a SCREEN pixel and works out how far that is by pushing the\n * quad's corner and its normal through this same matrix. Pen positions rotated\n * on the CPU would be dilated along the wrong axes — a rim of clipped\n * antialiasing on one side of every glyph.\n */\n m: Float32Array;\n /**\n * Design units per em: the font size in the run's local space.\n *\n * The rendered outline is resolution-independent, but its ANTIALIASING is not\n * unconditionally so: HarfBuzz's coverage shader takes a five-tap branch below\n * ppem 16, and measured against an 8x-downsampled reference that branch is\n * blurrier than a baked atlas at the same size. The ppem that matters is this\n * times the scale in {@link GlyphsView.m} times the device-pixel ratio: a\n * caller's zoom rides the matrix, and the shader sees it — see\n * `docs/text-rendering.md`.\n */\n pixelsPerEm: number;\n /** PREMULTIPLIED colour, linear 0..1 per channel, for the whole run. */\n r: number;\n g: number;\n b: number;\n a: number;\n /**\n * One atlas slot id per glyph. Length is at least {@link GlyphsView.glyphCount}\n * — a longer buffer is allowed and expected, since views are reused.\n */\n slots: Int32Array;\n /**\n * Pen positions, flattened `x, y, x, y, …`, in the run's local space and\n * BEFORE `m` is applied. Each is the glyph's em origin, i.e. a point on the\n * baseline. Length is at least `glyphCount * 2`.\n */\n positions: Float32Array;\n glyphCount: number;\n /**\n * Grow every glyph outward by this many design units before filling. `0` (the\n * default) is a plain fill.\n *\n * AN OUTLINED LABEL IS TWO RUNS, NOT ONE: the same glyphs and pens in the\n * outline colour with a spread, then again in the fill colour with none. This\n * kind carries one colour and one spread by design — merging them would need\n * two draw calls behind one command and would hide the ordering, which is the\n * part a caller has to get right (outline UNDER fill).\n *\n * A CENTRED `strokeText` OF WIDTH `W` REACHES `W / 2` OUTWARD, so a caller\n * matching one records `W / 2`. The arithmetic is the caller's: only it knows\n * whether the stroke it is reproducing is centred, inner or outer.\n *\n * THE DILATION FILLS THE INTERIOR AND A STROKE DOES NOT. Identical under an\n * opaque fill, which covers every pixel the two disagree about; visibly\n * different under a TRANSLUCENT one, where the outline colour shows through\n * the glyph's middle. Stated because it is a real limit of a coverage-max\n * dilation rather than a rounding difference — see `HbGpuRenderer.setSpread`.\n */\n spreadPx: number;\n /**\n * The exact local-space rectangle containing the run's unspread glyph ink.\n *\n * These are optional for source compatibility with older producers. Omitting\n * any one is deliberately an UNKNOWN bound, never an em-box estimate: a\n * retained surface must repaint fully rather than leave stale text behind.\n */\n localInkX?: number;\n localInkY?: number;\n localInkWidth?: number;\n localInkHeight?: number;\n /** Additional local-space reach for effects and antialiasing. The draw list\n * also adds its own `spreadPx`, so this is for reach beyond the unspread\n * outline (for example a shadow or caller-measured coverage fringe). */\n localInkOutset?: number;\n}\n\n/** A clip push's payload. */\nexport interface ClipRectView {\n /** Clip rect in design space. */\n x: number;\n y: number;\n w: number;\n h: number;\n /**\n * Corner radius in design units; `0` (the common case) is a plain rect and\n * lets the executor use a cheap scissor instead of a mask.\n */\n cornerRadius: number;\n /**\n * One-axis slack: widen the rect by `outsetX` on BOTH x edges, i.e. clip to\n * `[x - outsetX, x + w + outsetX]` while `y`/`h` stay exact. `0` (the common\n * case) clips to the rect itself. This exists because a re-laid-out scene can\n * legitimately paint slightly wider than the clip that Godot recorded, and\n * only ever on x.\n */\n outsetX: number;\n}\n\nexport interface DrawListOptions {\n /** Initial command capacity (entries, not bytes). Grows on demand. */\n commandCapacity?: number;\n /** Initial float-arena capacity. Grows on demand. */\n floatCapacity?: number;\n /** Initial int-arena capacity. Grows on demand. */\n intCapacity?: number;\n /** Initial color-matrix capacity, in matrices. Grows on demand. */\n colorMatrixCapacity?: number;\n /** Retained in-place patch records for compiled consumers. */\n patchJournalCapacity?: number;\n}\n\n/** Caller-owned, grow-only output for {@link DrawList.readPatchesSince}. */\nexport interface DrawListPatchView {\n readonly indices: readonly number[];\n readonly revision: number;\n readonly overflowed: boolean;\n}\n\n/**\n * A reusable, DOM- and GPU-ownership-free copy of a contiguous draw-list\n * range. A fragment owns its arena bytes and command references, so it remains\n * valid when the list it was captured from is reset, grows, or patched.\n *\n * Fragments deliberately retain texture and effect *references* rather than\n * attempting to clone them: those handles are executor-owned identities, not\n * draw-list data. Capturing and appending only copies the ordering and payload\n * that names them.\n */\nexport interface DrawListFragment<TTexture = unknown> {\n /** Number of commands in the captured half-open source range. */\n readonly count: number;\n /** Always zero for a valid standalone fragment. */\n readonly clipDepth: number;\n /** Deepest clip nesting within the captured range. */\n readonly maxClipDepth: number;\n /** Forget the captured range but retain all backing storage for reuse. */\n reset(): void;\n /**\n * Clone `[start, end)` from `source` into this fragment. The range must be\n * independently clip-balanced; an unmatched pop or push is rejected rather\n * than producing a fragment whose replay depends on hidden painter state.\n */\n capture(source: DrawList<TTexture>, start: number, end?: number): void;\n}\n\n/** One same-shaped retained-fragment replacement in a draw list. */\nexport interface DrawListFragmentPatch<TTexture = unknown> {\n /** First destination command index. Patches are supplied in painter order. */\n readonly start: number;\n /** Replacement command payloads, captured through createDrawListFragment. */\n readonly fragment: DrawListFragment<TTexture>;\n}\n\nexport function createDrawListPatchView(capacity = 16): DrawListPatchView {\n const indices: number[] = [];\n let marks = new Int32Array(Math.max(1, capacity));\n let generation = 0;\n let revision = 0;\n let overflowed = false;\n const view: DrawListPatchView = {\n get indices() {\n return indices;\n },\n get revision() {\n return revision;\n },\n get overflowed() {\n return overflowed;\n },\n };\n Object.assign(view as object, {\n begin(nextRevision: number) {\n indices.length = 0;\n generation += 1;\n if (generation === 0x7fffffff) {\n marks.fill(0);\n generation = 1;\n }\n revision = nextRevision;\n overflowed = false;\n },\n overflow() {\n overflowed = true;\n },\n add(index: number) {\n if (index >= marks.length) {\n let length = marks.length;\n while (length <= index) length *= 2;\n const next = new Int32Array(length);\n next.set(marks);\n marks = next;\n }\n if (marks[index] === generation) return;\n marks[index] = generation;\n indices.push(index);\n },\n });\n return view;\n}\n\ninterface MutableDrawListPatchView extends DrawListPatchView {\n begin(revision: number): void;\n overflow(): void;\n add(index: number): void;\n}\n\n/**\n * An ordered, poolable recording of one frame's draws.\n *\n * `TTexture` is whatever the executor's texture handle is (a `WebGLTexture`, a\n * `GPUTexture`, an atlas page id, …); the list only stores and returns it.\n */\nexport interface DrawList<TTexture = unknown> {\n /** Number of commands recorded since the last `reset()`. */\n readonly count: number;\n /** Clip pushes that are currently open (0 at a balanced end of frame). */\n readonly clipDepth: number;\n /** Deepest clip nesting seen since `reset()` — sizes an executor's stack. */\n readonly maxClipDepth: number;\n /** Changes when commands are appended, removed, or their layout changes. */\n readonly structuralRevision: number;\n /** Changes for every structural or in-place command patch. */\n readonly contentRevision: number;\n /** Per-command patch generation, for retained compiled consumers. */\n commandRevisionAt(index: number): number;\n /** Fill reusable `out` with patches after `revision`; overflow means rebuild. */\n readPatchesSince(revision: number, out: DrawListPatchView): DrawListPatchView;\n /**\n * The float arena. The identity of this array CHANGES when it grows, so an\n * executor must re-read it (never cache it across pushes).\n */\n readonly floats: Float32Array;\n /** The int arena. Same growth caveat as {@link DrawList.floats}. */\n readonly ints: Int32Array;\n /** The color-matrix arena, 9 floats per entry. Same growth caveat. */\n readonly colorMatrices: Float32Array;\n\n /** Rewind to an empty list, keeping (and reusing) the buffers. */\n reset(): void;\n\n /**\n * Append a previously captured fragment in painter order and return the\n * first destination command index. Empty fragments return `count` and do\n * not change revisions.\n */\n appendFragment(fragment: DrawListFragment<TTexture>): number;\n\n /**\n * Atomically overwrite a same-shaped recorded range from a retained\n * fragment. The fragment must fit at `start` and every command must retain\n * its kind, numeric payload lengths, object-side payload shape, clip\n * sequence, and colour-matrix presence. A mismatch leaves this list wholly\n * unchanged and returns `false`; successful overwrites preserve command\n * indices and structural revision while publishing ordinary content patches.\n *\n * An empty fragment is a successful no-op at any insertion index from `0`\n * through `count`.\n */\n patchFragment(start: number, fragment: DrawListFragment<TTexture>): boolean;\n\n /**\n * Atomically apply non-overlapping same-shaped fragments in painter order.\n * Every range is validated before any payload, reference, revision, or patch\n * journal entry changes. Starts must be nondecreasing and non-empty ranges\n * must not overlap.\n */\n patchFragments(patches: readonly DrawListFragmentPatch<TTexture>[]): boolean;\n\n kindAt(index: number): DrawCommandKind;\n kindNameAt(index: number): DrawCommandName;\n /** The command's texture handle, or `null` for untextured/geometry commands. */\n textureAt(index: number): TTexture | null;\n /** Screen-dependent pass recorded at index, if this is one. */\n screenEffectAt(index: number): ScreenEffectDrawCommand | null;\n /** Direct framebuffer pass recorded at index, if this is one. */\n externalEffectAt(index: number): ExternalEffectDrawCommand | null;\n /** Start of the command's payload in {@link DrawList.floats}. */\n floatOffsetAt(index: number): number;\n /** Start of the command's payload in {@link DrawList.ints}. */\n intOffsetAt(index: number): number;\n /**\n * Index of the command's color matrix in {@link DrawList.colorMatrices}\n * (multiply by 9 for the float offset), or `-1` when it has none.\n */\n colorMatrixIndexAt(index: number): number;\n\n /** Record a quad. Returns the command index. */\n pushQuad(quad: QuadView, texture?: TTexture | null): number;\n /** Record a nine-patch. Returns the command index. */\n pushNinePatch(patch: NinePatchView, texture?: TTexture | null): number;\n /** Record a polyline. Returns the command index. */\n pushPolyline(line: PolylineView): number;\n /** Record an indexed textured triangle mesh. Returns the command index. */\n pushTexturedMesh(mesh: TexturedMeshView, texture?: TTexture | null): number;\n /** Record a glyph run. Returns the command index. */\n pushGlyphs(run: GlyphsView): number;\n /** Record a pass that samples the accumulated framebuffer at this painter index. */\n pushScreenEffect(command: ScreenEffectDrawCommand): number;\n /** Record a direct framebuffer pass at this painter position. */\n pushExternalEffect(command: ExternalEffectDrawCommand): number;\n /** Open a clip rect. Returns the command index. */\n pushClipRect(clip: ClipRectView): number;\n /** Close the innermost clip rect. Returns the command index. */\n popClip(): number;\n\n /** Fill `out` from a `quad` command and return it. */\n readQuad(index: number, out: QuadView): QuadView;\n /** Fill `out` from a `ninePatch` command and return it. */\n readNinePatch(index: number, out: NinePatchView): NinePatchView;\n /**\n * Fill `out` from a `polyline` command and return it. `out.points` is\n * REPLACED by a larger buffer if it cannot hold the recorded points.\n */\n readPolyline(index: number, out: PolylineView): PolylineView;\n /** Fill `out` from a textured mesh, growing its caller-owned arrays if needed. */\n readTexturedMesh(index: number, out: TexturedMeshView): TexturedMeshView;\n /**\n * Fill `out` from a `glyphs` command and return it. `out.slots` and\n * `out.positions` are REPLACED by larger buffers if they cannot hold the run.\n */\n readGlyphs(index: number, out: GlyphsView): GlyphsView;\n /** Fill `out` from a `clipPush` command and return it. */\n readClipRect(index: number, out: ClipRectView): ClipRectView;\n\n /**\n * Overwrite a recorded quad's transform IN PLACE, leaving the rest of its\n * payload — size, source rect, colour, blend, flip flags, colour matrix —\n * exactly as it was pushed.\n *\n * This exists for consumers that rebuild a whole frame today only because one\n * node moved: they can keep last frame's list and repaint it, which is the\n * point of a list that owns its storage. `m` is read in the same\n * `Transform2D` order as {@link QuadView.m} and only its first 6 entries are\n * used.\n *\n * PATCH THROUGH THIS METHOD, NEVER THROUGH A CACHED `floats`. The arenas are\n * reallocated when they grow (see {@link DrawList.floats}), so a Float32Array\n * captured before a `push` may be a DEAD copy — writing into it changes\n * nothing that will be drawn, silently. The method re-reads the live arena on\n * every call.\n *\n * Accepts `quad` and `ninePatch` commands (a nine-patch's payload IS a quad\n * payload plus margins); anything else throws.\n */\n patchQuadTransform(index: number, m: ArrayLike<number>): void;\n /**\n * Overwrite a recorded quad's PREMULTIPLIED tint in place, leaving geometry,\n * source rect, blend, flip flags and colour matrix alone.\n *\n * `rgb` must already be multiplied by `a`, exactly as {@link QuadView} states\n * — this is a raw write into the arena, not a colour operation, so nothing\n * here will premultiply on the caller's behalf.\n *\n * The same cached-arena hazard as {@link DrawList.patchQuadTransform}\n * applies, and the same two kinds are accepted.\n */\n patchQuadColor(\n index: number,\n r: number,\n g: number,\n b: number,\n a: number,\n ): void;\n\n /**\n * Replace a quad-like command's texture and source rectangle without touching\n * its destination geometry, tint, blend state, flags or colour matrix.\n *\n * Like the other patch methods this re-reads the current arenas. In\n * particular, callers must not write source coordinates through a cached\n * `floats` view: a later push may have grown that arena and made the cached\n * view a detached copy.\n */\n patchQuadSource(\n index: number,\n texture: TTexture | null,\n srcX: number,\n srcY: number,\n srcW: number,\n srcH: number,\n ): void;\n\n /** Replace the local positions of a mesh without changing its topology. */\n patchTexturedMeshPositions(index: number, positions: Float32Array): void;\n /** Replace the normalized UV pairs of a mesh without changing its topology. */\n patchTexturedMeshUvs(index: number, uvs: Float32Array): void;\n /** Replace a mesh's texture handle without changing geometry or UVs. */\n patchTexturedMeshSource(index: number, texture: TTexture | null): void;\n /** Replace a mesh's local-to-design transform. */\n patchTexturedMeshTransform(index: number, m: ArrayLike<number>): void;\n /** Replace a mesh's premultiplied tint. */\n patchTexturedMeshColor(\n index: number,\n r: number,\n g: number,\n b: number,\n a: number,\n ): void;\n\n /**\n * Overwrite a recorded glyph run's transform in place, leaving its glyphs,\n * size and colour alone.\n *\n * The counterpart of {@link DrawList.patchQuadTransform}, and the reason the\n * glyph kind stores a transform at all instead of pre-transformed pen\n * positions: a label that translates every frame re-records nothing, and the\n * shader still sees the whole transform (which is what keeps its half-pixel\n * dilation on the right axes). The same cached-arena hazard applies — patch\n * through this method, never through a captured `floats`.\n */\n patchGlyphsTransform(index: number, m: ArrayLike<number>): void;\n /**\n * Overwrite a recorded glyph run's PREMULTIPLIED colour in place. `rgb` must\n * already be multiplied by `a`, exactly as {@link GlyphsView} states.\n */\n patchGlyphsColor(\n index: number,\n r: number,\n g: number,\n b: number,\n a: number,\n ): void;\n}\n\n// Payload strides. A quad writes: m[6], w, h, src[4], rgba[4] = 16 floats and\n// blend, flags, colorMatrixIndex = 3 ints. A nine-patch adds 4 margins.\nconst QUAD_FLOATS = 16;\nconst QUAD_INTS = 3;\nconst NINE_PATCH_FLOATS = QUAD_FLOATS + 4;\nconst NINE_PATCH_INTS = QUAD_INTS;\n// A polyline writes width + rgba, then the flattened points; the point count is\n// the one int.\nconst POLYLINE_HEADER_FLOATS = 5;\nconst POLYLINE_INTS = 1;\n// A mesh writes m[6], rgba, then local positions and normalized UV pairs. Its\n// int payload starts with vertex/index counts and blend, followed by indices.\nconst TEXTURED_MESH_HEADER_FLOATS = 10;\nconst TEXTURED_MESH_HEADER_INTS = 3;\n// A glyph run writes m[6], pixelsPerEm, rgba, spreadPx and optional local ink\n// bounds, then two pen floats per glyph; the glyph count is the first int and\n// the atlas slot ids follow it.\n// `spreadPx` remains at its original offset: `patchGlyphsTransform` writes\n// 0..5 and `patchGlyphsColor` 7..10, so appending the bound tuple leaves both\n// patchers' offsets exactly where they were.\nconst GLYPHS_SPREAD_OFFSET = 11;\nconst GLYPHS_INK_X_OFFSET = 12;\nconst GLYPHS_INK_Y_OFFSET = 13;\nconst GLYPHS_INK_WIDTH_OFFSET = 14;\nconst GLYPHS_INK_HEIGHT_OFFSET = 15;\nconst GLYPHS_INK_OUTSET_OFFSET = 16;\nconst GLYPHS_HEADER_FLOATS = 17;\nconst GLYPHS_HEADER_INTS = 1;\nconst CLIP_FLOATS = 6;\nconst COLOR_MATRIX_FLOATS = 9;\n\nconst DEFAULT_COMMAND_CAPACITY = 256;\nconst DEFAULT_FLOAT_CAPACITY = 256 * QUAD_FLOATS;\nconst DEFAULT_INT_CAPACITY = 256 * QUAD_INTS;\nconst DEFAULT_COLOR_MATRIX_CAPACITY = 8;\n\nconst IDENTITY_MATRIX_2D = [1, 0, 0, 1, 0, 0];\nconst IDENTITY_COLOR_MATRIX = [1, 0, 0, 0, 1, 0, 0, 0, 1];\n\n/** A fresh quad view: identity transform, opaque white, mix blend, no matrix. */\nexport function createQuadView(): QuadView {\n return {\n m: Float32Array.from(IDENTITY_MATRIX_2D),\n w: 0,\n h: 0,\n srcX: 0,\n srcY: 0,\n srcW: 0,\n srcH: 0,\n r: 1,\n g: 1,\n b: 1,\n a: 1,\n blend: BLEND_MIX,\n flipH: false,\n flipV: false,\n hasColorMatrix: false,\n colorMatrix: Float32Array.from(IDENTITY_COLOR_MATRIX),\n };\n}\n\n/** A fresh nine-patch view: a quad view with zero margins. */\nexport function createNinePatchView(): NinePatchView {\n return {\n ...createQuadView(),\n marginLeft: 0,\n marginTop: 0,\n marginRight: 0,\n marginBottom: 0,\n };\n}\n\n/** A fresh polyline view with room for `pointCapacity` points. */\nexport function createPolylineView(pointCapacity = 8): PolylineView {\n return {\n points: new Float32Array(Math.max(1, pointCapacity) * 2),\n pointCount: 0,\n width: 1,\n r: 1,\n g: 1,\n b: 1,\n a: 1,\n };\n}\n\n/** A reusable textured mesh view with room for the requested topology. */\nexport function createTexturedMeshView(\n vertexCapacity = 4,\n indexCapacity = 6,\n): TexturedMeshView {\n const vertices = Math.max(1, Math.floor(vertexCapacity));\n return {\n m: Float32Array.from(IDENTITY_MATRIX_2D),\n positions: new Float32Array(vertices * 2),\n uvs: new Float32Array(vertices * 2),\n vertexCount: 0,\n indices: new Uint32Array(Math.max(1, Math.floor(indexCapacity))),\n indexCount: 0,\n r: 1,\n g: 1,\n b: 1,\n a: 1,\n blend: BLEND_MIX,\n };\n}\n\n/** A fresh glyph-run view with room for `glyphCapacity` glyphs. */\nexport function createGlyphsView(glyphCapacity = 32): GlyphsView {\n const capacity = Math.max(1, glyphCapacity);\n return {\n m: Float32Array.from(IDENTITY_MATRIX_2D),\n pixelsPerEm: 16,\n r: 1,\n g: 1,\n b: 1,\n a: 1,\n slots: new Int32Array(capacity),\n positions: new Float32Array(capacity * 2),\n glyphCount: 0,\n spreadPx: 0,\n // Unknown is the safe default. A zero box would falsely tell retained\n // replay that a legacy producer's text paints nowhere.\n localInkX: Number.NaN,\n localInkY: Number.NaN,\n localInkWidth: Number.NaN,\n localInkHeight: Number.NaN,\n localInkOutset: Number.NaN,\n };\n}\n\n/** A fresh clip-rect view: empty rect, square corners, no outset. */\nexport function createClipRectView(): ClipRectView {\n return { x: 0, y: 0, w: 0, h: 0, cornerRadius: 0, outsetX: 0 };\n}\n\n/**\n * Copy an `html` {@link ColorMatrix} into a quad/nine-patch view and arm it.\n * Passing `null` disarms the view's matrix (leaving its contents alone), which\n * is the shape most callers have: a computed transform that is usually absent.\n */\nexport function setViewColorMatrix(\n view: QuadView,\n matrix: ColorMatrix | null | undefined,\n): void {\n if (!matrix) {\n view.hasColorMatrix = false;\n return;\n }\n const rows = matrix.rows;\n const out = view.colorMatrix;\n out[0] = rows[0][0];\n out[1] = rows[0][1];\n out[2] = rows[0][2];\n out[3] = rows[1][0];\n out[4] = rows[1][1];\n out[5] = rows[1][2];\n out[6] = rows[2][0];\n out[7] = rows[2][1];\n out[8] = rows[2][2];\n view.hasColorMatrix = true;\n}\n\nfunction grownFloats(current: Float32Array, needed: number): Float32Array {\n let capacity = Math.max(1, current.length);\n while (capacity < needed) capacity *= 2;\n const next = new Float32Array(capacity);\n next.set(current);\n return next;\n}\n\n/** Preserve an omitted optional producer field as an unknown IR value. */\nfunction finiteOrNaN(value: number | undefined): number {\n return typeof value === \"number\" && Number.isFinite(value)\n ? value\n : Number.NaN;\n}\n\nfunction grownInts(current: Int32Array, needed: number): Int32Array {\n let capacity = Math.max(1, current.length);\n while (capacity < needed) capacity *= 2;\n const next = new Int32Array(capacity);\n next.set(current);\n return next;\n}\n\nfunction grownObjects<T>(current: (T | null)[], needed: number): (T | null)[] {\n let capacity = Math.max(1, current.length);\n while (capacity < needed) capacity *= 2;\n const next: (T | null)[] = new Array(capacity).fill(null);\n for (let index = 0; index < current.length; index += 1) {\n next[index] = current[index];\n }\n return next;\n}\n\ninterface FragmentStorage<TTexture> {\n kinds: Int32Array;\n floatOffsets: Int32Array;\n intOffsets: Int32Array;\n textures: (TTexture | null)[];\n screenEffects: (ScreenEffectDrawCommand | null)[];\n externalEffects: (ExternalEffectDrawCommand | null)[];\n floats: Float32Array;\n ints: Int32Array;\n colorMatrices: Float32Array;\n /** Source matrix index for each locally stored matrix; reused as a tiny map. */\n sourceMatrixIndexes: Int32Array;\n count: number;\n floatLength: number;\n intLength: number;\n colorMatrixCount: number;\n maxClipDepth: number;\n}\n\nconst fragmentStorage = new WeakMap<object, FragmentStorage<unknown>>();\n\nfunction requireFragmentStorage<TTexture>(\n fragment: DrawListFragment<TTexture>,\n): FragmentStorage<TTexture> {\n const storage = fragmentStorage.get(fragment as object);\n if (!storage) {\n throw new TypeError(\n \"draw-list appendFragment() needs a fragment created by createDrawListFragment()\",\n );\n }\n return storage as FragmentStorage<TTexture>;\n}\n\ninterface PayloadLengths {\n floats: number;\n ints: number;\n}\n\nfunction fillFragmentPayloadLengths<TTexture>(\n list: DrawList<TTexture>,\n index: number,\n out: PayloadLengths,\n): void {\n const kind = list.kindAt(index);\n const intAt = list.intOffsetAt(index);\n const requireInt = (offset: number, label: string): number => {\n const value = list.ints[intAt + offset];\n if (!Number.isInteger(value) || value < 0) {\n throw new RangeError(\n `draw-list ${label} at command ${index} is malformed`,\n );\n }\n return value;\n };\n switch (kind) {\n case DRAW_QUAD:\n out.floats = QUAD_FLOATS;\n out.ints = QUAD_INTS;\n return;\n case DRAW_NINE_PATCH:\n out.floats = NINE_PATCH_FLOATS;\n out.ints = NINE_PATCH_INTS;\n return;\n case DRAW_POLYLINE: {\n const points = requireInt(0, \"polyline point count\");\n out.floats = POLYLINE_HEADER_FLOATS + points * 2;\n out.ints = POLYLINE_INTS;\n return;\n }\n case DRAW_CLIP_PUSH:\n out.floats = CLIP_FLOATS;\n out.ints = 0;\n return;\n case DRAW_CLIP_POP:\n case DRAW_SCREEN_EFFECT:\n case DRAW_EXTERNAL_EFFECT:\n out.floats = 0;\n out.ints = 0;\n return;\n case DRAW_GLYPHS: {\n const glyphs = requireInt(0, \"glyph count\");\n out.floats = GLYPHS_HEADER_FLOATS + glyphs * 2;\n out.ints = GLYPHS_HEADER_INTS + glyphs;\n return;\n }\n case DRAW_TEXTURED_MESH: {\n const vertices = requireInt(0, \"textured mesh vertex count\");\n const indexes = requireInt(1, \"textured mesh index count\");\n out.floats = TEXTURED_MESH_HEADER_FLOATS + vertices * 4;\n out.ints = TEXTURED_MESH_HEADER_INTS + indexes;\n return;\n }\n default:\n throw new RangeError(\n `draw-list command ${index} has an unknown kind ${kind}`,\n );\n }\n}\n\nfunction fillFragmentStoragePayloadLengths<TTexture>(\n storage: FragmentStorage<TTexture>,\n index: number,\n out: PayloadLengths,\n): void {\n if (!Number.isInteger(index) || index < 0 || index >= storage.count) {\n throw new RangeError(\n `draw-list fragment index ${index} out of range (count ${storage.count})`,\n );\n }\n const kind = storage.kinds[index] as DrawCommandKind;\n const intAt = storage.intOffsets[index];\n switch (kind) {\n case DRAW_QUAD:\n out.floats = QUAD_FLOATS;\n out.ints = QUAD_INTS;\n return;\n case DRAW_NINE_PATCH:\n out.floats = NINE_PATCH_FLOATS;\n out.ints = NINE_PATCH_INTS;\n return;\n case DRAW_POLYLINE: {\n const points = storage.ints[intAt];\n if (!Number.isInteger(points) || points < 0) {\n throw new RangeError(\n `draw-list fragment polyline point count at command ${index} is malformed`,\n );\n }\n out.floats = POLYLINE_HEADER_FLOATS + points * 2;\n out.ints = POLYLINE_INTS;\n return;\n }\n case DRAW_CLIP_PUSH:\n out.floats = CLIP_FLOATS;\n out.ints = 0;\n return;\n case DRAW_CLIP_POP:\n case DRAW_SCREEN_EFFECT:\n case DRAW_EXTERNAL_EFFECT:\n out.floats = 0;\n out.ints = 0;\n return;\n case DRAW_GLYPHS: {\n const glyphs = storage.ints[intAt];\n if (!Number.isInteger(glyphs) || glyphs < 0) {\n throw new RangeError(\n `draw-list fragment glyph count at command ${index} is malformed`,\n );\n }\n out.floats = GLYPHS_HEADER_FLOATS + glyphs * 2;\n out.ints = GLYPHS_HEADER_INTS + glyphs;\n return;\n }\n case DRAW_TEXTURED_MESH: {\n const vertices = storage.ints[intAt];\n const indexes = storage.ints[intAt + 1];\n if (!Number.isInteger(vertices) || vertices < 0) {\n throw new RangeError(\n `draw-list fragment textured mesh vertex count at command ${index} is malformed`,\n );\n }\n if (!Number.isInteger(indexes) || indexes < 0) {\n throw new RangeError(\n `draw-list fragment textured mesh index count at command ${index} is malformed`,\n );\n }\n out.floats = TEXTURED_MESH_HEADER_FLOATS + vertices * 4;\n out.ints = TEXTURED_MESH_HEADER_INTS + indexes;\n return;\n }\n default:\n throw new RangeError(\n `draw-list fragment command ${index} has an unknown kind ${kind}`,\n );\n }\n}\n\n/**\n * Create reusable storage for a retained command fragment. The fragment holds\n * only draw-list data and opaque caller references; it never creates or owns a\n * DOM node, a WebGL object, or an executor.\n */\nexport function createDrawListFragment<TTexture = unknown>(\n options: DrawListOptions = {},\n): DrawListFragment<TTexture> {\n const commandCapacity = Math.max(\n 1,\n options.commandCapacity ?? DEFAULT_COMMAND_CAPACITY,\n );\n const storage: FragmentStorage<TTexture> = {\n kinds: new Int32Array(commandCapacity),\n floatOffsets: new Int32Array(commandCapacity),\n intOffsets: new Int32Array(commandCapacity),\n textures: new Array<TTexture | null>(commandCapacity).fill(null),\n screenEffects: new Array<ScreenEffectDrawCommand | null>(\n commandCapacity,\n ).fill(null),\n externalEffects: new Array<ExternalEffectDrawCommand | null>(\n commandCapacity,\n ).fill(null),\n floats: new Float32Array(\n Math.max(1, options.floatCapacity ?? DEFAULT_FLOAT_CAPACITY),\n ),\n ints: new Int32Array(\n Math.max(1, options.intCapacity ?? DEFAULT_INT_CAPACITY),\n ),\n colorMatrices: new Float32Array(\n Math.max(\n 1,\n options.colorMatrixCapacity ?? DEFAULT_COLOR_MATRIX_CAPACITY,\n ) * COLOR_MATRIX_FLOATS,\n ),\n sourceMatrixIndexes: new Int32Array(\n Math.max(1, options.colorMatrixCapacity ?? DEFAULT_COLOR_MATRIX_CAPACITY),\n ),\n count: 0,\n floatLength: 0,\n intLength: 0,\n colorMatrixCount: 0,\n maxClipDepth: 0,\n };\n\n function reset(): void {\n for (let index = 0; index < storage.count; index += 1) {\n storage.textures[index] = null;\n storage.screenEffects[index] = null;\n storage.externalEffects[index] = null;\n }\n storage.count = 0;\n storage.floatLength = 0;\n storage.intLength = 0;\n storage.colorMatrixCount = 0;\n storage.maxClipDepth = 0;\n }\n\n function ensureCommand(needed: number): void {\n if (needed <= storage.kinds.length) return;\n const capacity = storage.kinds.length * 2;\n const nextKinds = new Int32Array(capacity);\n nextKinds.set(storage.kinds);\n storage.kinds = nextKinds;\n const nextFloatOffsets = new Int32Array(capacity);\n nextFloatOffsets.set(storage.floatOffsets);\n storage.floatOffsets = nextFloatOffsets;\n const nextIntOffsets = new Int32Array(capacity);\n nextIntOffsets.set(storage.intOffsets);\n storage.intOffsets = nextIntOffsets;\n storage.textures = grownObjects(storage.textures, needed);\n storage.screenEffects = grownObjects(storage.screenEffects, needed);\n storage.externalEffects = grownObjects(storage.externalEffects, needed);\n }\n\n function matrixIndexFor(\n source: DrawList<TTexture>,\n sourceIndex: number,\n ): number {\n for (let index = 0; index < storage.colorMatrixCount; index += 1) {\n if (storage.sourceMatrixIndexes[index] === sourceIndex) return index;\n }\n const sourceAt = sourceIndex * COLOR_MATRIX_FLOATS;\n if (\n sourceIndex < 0 ||\n sourceAt + COLOR_MATRIX_FLOATS > source.colorMatrices.length\n ) {\n throw new RangeError(\n `draw-list color matrix ${sourceIndex} is malformed`,\n );\n }\n const nextCount = storage.colorMatrixCount + 1;\n if (nextCount * COLOR_MATRIX_FLOATS > storage.colorMatrices.length) {\n storage.colorMatrices = grownFloats(\n storage.colorMatrices,\n nextCount * COLOR_MATRIX_FLOATS,\n );\n }\n if (nextCount > storage.sourceMatrixIndexes.length) {\n storage.sourceMatrixIndexes = grownInts(\n storage.sourceMatrixIndexes,\n nextCount,\n );\n }\n const target = storage.colorMatrixCount;\n const targetAt = target * COLOR_MATRIX_FLOATS;\n for (let offset = 0; offset < COLOR_MATRIX_FLOATS; offset += 1) {\n storage.colorMatrices[targetAt + offset] =\n source.colorMatrices[sourceAt + offset];\n }\n storage.sourceMatrixIndexes[target] = sourceIndex;\n storage.colorMatrixCount = nextCount;\n return target;\n }\n\n function capture(\n source: DrawList<TTexture>,\n start: number,\n end = source.count,\n ): void {\n if (\n !Number.isInteger(start) ||\n !Number.isInteger(end) ||\n start < 0 ||\n end < start ||\n end > source.count\n ) {\n throw new RangeError(\n `draw-list fragment range [${start}, ${end}) is outside count ${source.count}`,\n );\n }\n\n // Validate the whole range before dropping a useful cached fragment.\n const lengths: PayloadLengths = { floats: 0, ints: 0 };\n let depth = 0;\n let maxDepth = 0;\n for (let index = start; index < end; index += 1) {\n fillFragmentPayloadLengths(source, index, lengths);\n const floatAt = source.floatOffsetAt(index);\n const intAt = source.intOffsetAt(index);\n if (\n floatAt < 0 ||\n intAt < 0 ||\n floatAt + lengths.floats > source.floats.length ||\n intAt + lengths.ints > source.ints.length\n ) {\n throw new RangeError(\n `draw-list command ${index} has an invalid arena range`,\n );\n }\n const kind = source.kindAt(index);\n if (kind === DRAW_QUAD || kind === DRAW_NINE_PATCH) {\n const matrix = source.ints[intAt + 2];\n if (\n !Number.isInteger(matrix) ||\n matrix < -1 ||\n (matrix >= 0 &&\n (matrix + 1) * COLOR_MATRIX_FLOATS > source.colorMatrices.length)\n ) {\n throw new RangeError(\n `draw-list color matrix ${matrix} at command ${index} is malformed`,\n );\n }\n }\n if (kind === DRAW_CLIP_PUSH) {\n depth += 1;\n maxDepth = Math.max(maxDepth, depth);\n } else if (kind === DRAW_CLIP_POP) {\n depth -= 1;\n if (depth < 0) {\n throw new RangeError(\n `draw-list fragment range [${start}, ${end}) pops a clip it did not push`,\n );\n }\n }\n }\n if (depth !== 0) {\n throw new RangeError(\n `draw-list fragment range [${start}, ${end}) leaves ${depth} clip(s) open`,\n );\n }\n\n reset();\n for (let sourceIndex = start; sourceIndex < end; sourceIndex += 1) {\n fillFragmentPayloadLengths(source, sourceIndex, lengths);\n const index = storage.count;\n ensureCommand(index + 1);\n if (storage.floatLength + lengths.floats > storage.floats.length) {\n storage.floats = grownFloats(\n storage.floats,\n storage.floatLength + lengths.floats,\n );\n }\n if (storage.intLength + lengths.ints > storage.ints.length) {\n storage.ints = grownInts(\n storage.ints,\n storage.intLength + lengths.ints,\n );\n }\n storage.kinds[index] = source.kindAt(sourceIndex);\n storage.floatOffsets[index] = storage.floatLength;\n storage.intOffsets[index] = storage.intLength;\n storage.textures[index] = source.textureAt(sourceIndex);\n storage.screenEffects[index] = source.screenEffectAt(sourceIndex);\n storage.externalEffects[index] = source.externalEffectAt(sourceIndex);\n const sourceFloatAt = source.floatOffsetAt(sourceIndex);\n const sourceIntAt = source.intOffsetAt(sourceIndex);\n for (let offset = 0; offset < lengths.floats; offset += 1) {\n storage.floats[storage.floatLength + offset] =\n source.floats[sourceFloatAt + offset];\n }\n for (let offset = 0; offset < lengths.ints; offset += 1) {\n storage.ints[storage.intLength + offset] =\n source.ints[sourceIntAt + offset];\n }\n const kind = storage.kinds[index] as DrawCommandKind;\n if (kind === DRAW_QUAD || kind === DRAW_NINE_PATCH) {\n const matrix = storage.ints[storage.intLength + 2];\n if (matrix >= 0)\n storage.ints[storage.intLength + 2] = matrixIndexFor(source, matrix);\n }\n storage.count += 1;\n storage.floatLength += lengths.floats;\n storage.intLength += lengths.ints;\n }\n storage.maxClipDepth = maxDepth;\n }\n\n const fragment: DrawListFragment<TTexture> = {\n get count() {\n return storage.count;\n },\n get clipDepth() {\n return 0;\n },\n get maxClipDepth() {\n return storage.maxClipDepth;\n },\n reset,\n capture,\n };\n fragmentStorage.set(fragment as object, storage as FragmentStorage<unknown>);\n // The mutable arenas are closure-private and the public handle cannot be\n // forged or replaced. appendFragment therefore only receives storage that a\n // successful capture fully validated, before it touches destination state.\n return Object.freeze(fragment);\n}\n\n/**\n * Create an empty draw list. Capacities are only a starting point; every arena\n * grows on demand, so a list settles at the high-water mark of the frames it\n * has recorded and then allocates nothing.\n */\nexport function createDrawList<TTexture = unknown>(\n options: DrawListOptions = {},\n): DrawList<TTexture> {\n let kinds: Int32Array = new Int32Array(\n Math.max(1, options.commandCapacity ?? DEFAULT_COMMAND_CAPACITY),\n );\n let floatOffsets: Int32Array = new Int32Array(kinds.length);\n let intOffsets: Int32Array = new Int32Array(kinds.length);\n let textures: (TTexture | null)[] = new Array(kinds.length).fill(null);\n let screenEffects: (ScreenEffectDrawCommand | null)[] = new Array(\n kinds.length,\n ).fill(null);\n let externalEffects: (ExternalEffectDrawCommand | null)[] = new Array(\n kinds.length,\n ).fill(null);\n\n let floats: Float32Array = new Float32Array(\n Math.max(1, options.floatCapacity ?? DEFAULT_FLOAT_CAPACITY),\n );\n let ints: Int32Array = new Int32Array(\n Math.max(1, options.intCapacity ?? DEFAULT_INT_CAPACITY),\n );\n let colorMatrices: Float32Array = new Float32Array(\n Math.max(1, options.colorMatrixCapacity ?? DEFAULT_COLOR_MATRIX_CAPACITY) *\n COLOR_MATRIX_FLOATS,\n );\n\n let count = 0;\n let floatLength = 0;\n let intLength = 0;\n let colorMatrixCount = 0;\n let clipDepth = 0;\n let maxClipDepth = 0;\n let structuralRevision = 0;\n let contentRevision = 0;\n let commandRevisions = new Int32Array(kinds.length);\n const patchJournalCapacity = Math.max(1, options.patchJournalCapacity ?? 256);\n const patchJournalRevisions = new Int32Array(patchJournalCapacity);\n const patchJournalIndexes = new Int32Array(patchJournalCapacity);\n let patchJournalStart = 0;\n let patchJournalCount = 0;\n // Reused by appendFragment(): retained subtree flattening is a hot path and\n // must not allocate a tuple or scratch object per command or per append.\n const fragmentAppendLengths: PayloadLengths = { floats: 0, ints: 0 };\n // `fillFragmentPayloadLengths` intentionally consumes the public read\n // surface. Keep this tiny live adapter reusable so patch validation does not\n // allocate a façade for every command it examines.\n const fragmentPatchDestinationView = {\n kindAt(index: number) {\n return kinds[index] as DrawCommandKind;\n },\n intOffsetAt(index: number) {\n return intOffsets[index];\n },\n get ints() {\n return ints;\n },\n } as DrawList<TTexture>;\n\n function ensureCommandSlot(): void {\n if (count < kinds.length) return;\n const capacity = kinds.length * 2;\n const nextKinds = new Int32Array(capacity);\n nextKinds.set(kinds);\n kinds = nextKinds;\n const nextFloatOffsets = new Int32Array(capacity);\n nextFloatOffsets.set(floatOffsets);\n floatOffsets = nextFloatOffsets;\n const nextIntOffsets = new Int32Array(capacity);\n nextIntOffsets.set(intOffsets);\n intOffsets = nextIntOffsets;\n const nextRevisions = new Int32Array(capacity);\n nextRevisions.set(commandRevisions);\n commandRevisions = nextRevisions;\n const nextTextures: (TTexture | null)[] = new Array(capacity).fill(null);\n for (let i = 0; i < textures.length; i += 1) nextTextures[i] = textures[i];\n textures = nextTextures;\n const nextEffects: (ScreenEffectDrawCommand | null)[] = new Array(\n capacity,\n ).fill(null);\n for (let i = 0; i < screenEffects.length; i += 1)\n nextEffects[i] = screenEffects[i];\n screenEffects = nextEffects;\n const nextExternalEffects: (ExternalEffectDrawCommand | null)[] = new Array(\n capacity,\n ).fill(null);\n for (let i = 0; i < externalEffects.length; i += 1)\n nextExternalEffects[i] = externalEffects[i];\n externalEffects = nextExternalEffects;\n }\n\n function beginCommand(\n kind: DrawCommandKind,\n floatCount: number,\n intCount: number,\n texture: TTexture | null,\n ): number {\n ensureCommandSlot();\n if (floatLength + floatCount > floats.length) {\n floats = grownFloats(floats, floatLength + floatCount);\n }\n if (intLength + intCount > ints.length) {\n ints = grownInts(ints, intLength + intCount);\n }\n const index = count;\n kinds[index] = kind;\n floatOffsets[index] = floatLength;\n intOffsets[index] = intLength;\n textures[index] = texture;\n count += 1;\n contentRevision += 1;\n structuralRevision += 1;\n commandRevisions[index] = contentRevision;\n floatLength += floatCount;\n intLength += intCount;\n return index;\n }\n\n function storeColorMatrix(view: QuadView): number {\n if (!view.hasColorMatrix) return -1;\n const needed = (colorMatrixCount + 1) * COLOR_MATRIX_FLOATS;\n if (needed > colorMatrices.length) {\n colorMatrices = grownFloats(colorMatrices, needed);\n }\n const at = colorMatrixCount * COLOR_MATRIX_FLOATS;\n colorMatrices.set(view.colorMatrix.subarray(0, COLOR_MATRIX_FLOATS), at);\n colorMatrixCount += 1;\n return colorMatrixCount - 1;\n }\n\n function storeFragmentColorMatrix(\n matrices: Float32Array,\n matrixIndex: number,\n ): number {\n const from = matrixIndex * COLOR_MATRIX_FLOATS;\n if (matrixIndex < 0 || from + COLOR_MATRIX_FLOATS > matrices.length) {\n throw new RangeError(\n `draw-list fragment color matrix ${matrixIndex} is malformed`,\n );\n }\n const needed = (colorMatrixCount + 1) * COLOR_MATRIX_FLOATS;\n if (needed > colorMatrices.length) {\n colorMatrices = grownFloats(colorMatrices, needed);\n }\n const target = colorMatrixCount * COLOR_MATRIX_FLOATS;\n for (let offset = 0; offset < COLOR_MATRIX_FLOATS; offset += 1) {\n colorMatrices[target + offset] = matrices[from + offset];\n }\n colorMatrixCount += 1;\n return colorMatrixCount - 1;\n }\n\n function requireIndex(index: number): void {\n if (!Number.isInteger(index) || index < 0 || index >= count) {\n throw new RangeError(\n `draw-list index ${index} out of range (count ${count})`,\n );\n }\n }\n\n function requireKind(index: number, kind: DrawCommandKind): number {\n requireIndex(index);\n if (kinds[index] !== kind) {\n throw new TypeError(\n `draw-list command ${index} is \"${DRAW_COMMAND_NAMES[kinds[index]]}\", not \"${DRAW_COMMAND_NAMES[kind]}\"`,\n );\n }\n return index;\n }\n\n /**\n * The guard for the patch methods: both quad kinds are accepted because a\n * nine-patch stores a quad payload first and its margins after, so the\n * transform and colour slots are at the same offsets in both. Refusing\n * nine-patches would drop the feature exactly where a consumer needs it most\n * (a dialog fading out is nine-patch frames plus quads).\n */\n function requireQuadLike(index: number): number {\n requireIndex(index);\n const kind = kinds[index];\n if (kind !== DRAW_QUAD && kind !== DRAW_NINE_PATCH) {\n throw new TypeError(\n `draw-list command ${index} is \"${DRAW_COMMAND_NAMES[kind]}\", not a quad-like command (\"quad\" or \"ninePatch\")`,\n );\n }\n return index;\n }\n\n function requireTexturedMesh(index: number): number {\n return requireKind(index, DRAW_TEXTURED_MESH);\n }\n\n function markPatched(index: number): void {\n contentRevision += 1;\n commandRevisions[index] = contentRevision;\n const slot = (patchJournalStart + patchJournalCount) % patchJournalCapacity;\n patchJournalRevisions[slot] = contentRevision;\n patchJournalIndexes[slot] = index;\n if (patchJournalCount < patchJournalCapacity) patchJournalCount += 1;\n else patchJournalStart = (patchJournalStart + 1) % patchJournalCapacity;\n }\n\n function hasExpectedObjectPayload(\n kind: DrawCommandKind,\n texture: TTexture | null,\n screenEffect: ScreenEffectDrawCommand | null,\n externalEffect: ExternalEffectDrawCommand | null,\n ): boolean {\n switch (kind) {\n case DRAW_QUAD:\n case DRAW_NINE_PATCH:\n case DRAW_TEXTURED_MESH:\n return screenEffect === null && externalEffect === null;\n case DRAW_SCREEN_EFFECT:\n return (\n texture === null &&\n externalEffect === null &&\n screenEffect !== null &&\n screenEffect.screenDependent === true &&\n typeof screenEffect.execute === \"function\"\n );\n case DRAW_EXTERNAL_EFFECT:\n return (\n texture === null &&\n screenEffect === null &&\n externalEffect !== null &&\n typeof externalEffect.execute === \"function\"\n );\n default:\n return (\n texture === null && screenEffect === null && externalEffect === null\n );\n }\n }\n\n /**\n * Validate whether a captured range can overwrite the existing slots without\n * changing any command layout. This runs to completion before a byte or\n * reference is touched, which is the atomicity boundary for patchFragment.\n */\n function canPatchFragment(\n start: number,\n captured: FragmentStorage<TTexture>,\n ): boolean {\n if (\n !Number.isInteger(start) ||\n start < 0 ||\n start > count ||\n captured.count > count - start\n ) {\n return false;\n }\n if (captured.count === 0) return true;\n\n const destinationMatrices = new Map<number, number>();\n let sourceClipDepth = 0;\n let destinationClipDepth = 0;\n try {\n for (\n let sourceIndex = 0;\n sourceIndex < captured.count;\n sourceIndex += 1\n ) {\n const destinationIndex = start + sourceIndex;\n const sourceKind = captured.kinds[sourceIndex] as DrawCommandKind;\n if (kinds[destinationIndex] !== sourceKind) return false;\n\n const sourceFloatAt = captured.floatOffsets[sourceIndex];\n const sourceIntAt = captured.intOffsets[sourceIndex];\n const destinationFloatAt = floatOffsets[destinationIndex];\n const destinationIntAt = intOffsets[destinationIndex];\n fillFragmentStoragePayloadLengths(\n captured,\n sourceIndex,\n fragmentAppendLengths,\n );\n const sourceFloats = fragmentAppendLengths.floats;\n const sourceInts = fragmentAppendLengths.ints;\n if (\n sourceFloatAt < 0 ||\n sourceIntAt < 0 ||\n sourceFloatAt + sourceFloats > captured.floatLength ||\n sourceIntAt + sourceInts > captured.intLength ||\n destinationFloatAt < 0 ||\n destinationIntAt < 0 ||\n destinationFloatAt + sourceFloats > floatLength ||\n destinationIntAt + sourceInts > intLength\n ) {\n return false;\n }\n\n fillFragmentPayloadLengths(\n fragmentPatchDestinationView,\n destinationIndex,\n fragmentAppendLengths,\n );\n if (\n fragmentAppendLengths.floats !== sourceFloats ||\n fragmentAppendLengths.ints !== sourceInts\n ) {\n return false;\n }\n\n if (\n !hasExpectedObjectPayload(\n sourceKind,\n captured.textures[sourceIndex],\n captured.screenEffects[sourceIndex],\n captured.externalEffects[sourceIndex],\n ) ||\n !hasExpectedObjectPayload(\n sourceKind,\n textures[destinationIndex],\n screenEffects[destinationIndex],\n externalEffects[destinationIndex],\n )\n ) {\n return false;\n }\n\n if (sourceKind === DRAW_QUAD || sourceKind === DRAW_NINE_PATCH) {\n const sourceMatrix = captured.ints[sourceIntAt + 2];\n const destinationMatrix = ints[destinationIntAt + 2];\n const sourceHasMatrix = sourceMatrix >= 0;\n const destinationHasMatrix = destinationMatrix >= 0;\n if (sourceHasMatrix !== destinationHasMatrix) return false;\n if (sourceHasMatrix) {\n if (\n !Number.isInteger(sourceMatrix) ||\n !Number.isInteger(destinationMatrix) ||\n sourceMatrix >= captured.colorMatrixCount ||\n destinationMatrix >= colorMatrixCount ||\n (sourceMatrix + 1) * COLOR_MATRIX_FLOATS >\n captured.colorMatrices.length ||\n (destinationMatrix + 1) * COLOR_MATRIX_FLOATS >\n colorMatrices.length\n ) {\n return false;\n }\n const previousSource = destinationMatrices.get(destinationMatrix);\n if (\n previousSource !== undefined &&\n previousSource !== sourceMatrix\n ) {\n return false;\n }\n destinationMatrices.set(destinationMatrix, sourceMatrix);\n } else if (sourceMatrix !== -1 || destinationMatrix !== -1) {\n return false;\n }\n }\n\n if (sourceKind === DRAW_CLIP_PUSH) {\n sourceClipDepth += 1;\n destinationClipDepth += 1;\n } else if (sourceKind === DRAW_CLIP_POP) {\n sourceClipDepth -= 1;\n destinationClipDepth -= 1;\n if (sourceClipDepth < 0 || destinationClipDepth < 0) return false;\n }\n }\n } catch {\n // Public numeric arenas can be malformed. A retained patch must decline\n // rather than partly repairing a list it did not build.\n return false;\n }\n if (sourceClipDepth !== 0 || destinationClipDepth !== 0) return false;\n\n // Normal DrawList writes allocate a distinct matrix for each command. If a\n // caller has manually made one slot shared, changing it could alter an\n // unpatched command, so fail closed instead of breaking atomic locality.\n if (destinationMatrices.size > 0) {\n for (let index = 0; index < count; index += 1) {\n if (index >= start && index < start + captured.count) continue;\n const kind = kinds[index];\n if (kind !== DRAW_QUAD && kind !== DRAW_NINE_PATCH) continue;\n if (destinationMatrices.has(ints[intOffsets[index] + 2])) return false;\n }\n }\n return true;\n }\n\n function applyFragmentPatch(\n start: number,\n captured: FragmentStorage<TTexture>,\n ): void {\n // canPatchFragment() proved every span, matrix slot and object-side\n // payload valid before this loop starts. Nothing below can resize storage\n // or reject, preserving all-or-nothing mutation at the public boundary.\n for (let sourceIndex = 0; sourceIndex < captured.count; sourceIndex += 1) {\n const destinationIndex = start + sourceIndex;\n const kind = captured.kinds[sourceIndex] as DrawCommandKind;\n const sourceFloatAt = captured.floatOffsets[sourceIndex];\n const sourceIntAt = captured.intOffsets[sourceIndex];\n const destinationFloatAt = floatOffsets[destinationIndex];\n const destinationIntAt = intOffsets[destinationIndex];\n const destinationMatrix =\n kind === DRAW_QUAD || kind === DRAW_NINE_PATCH\n ? ints[destinationIntAt + 2]\n : -1;\n fillFragmentStoragePayloadLengths(\n captured,\n sourceIndex,\n fragmentAppendLengths,\n );\n floats.set(\n captured.floats.subarray(\n sourceFloatAt,\n sourceFloatAt + fragmentAppendLengths.floats,\n ),\n destinationFloatAt,\n );\n ints.set(\n captured.ints.subarray(\n sourceIntAt,\n sourceIntAt + fragmentAppendLengths.ints,\n ),\n destinationIntAt,\n );\n textures[destinationIndex] = captured.textures[sourceIndex];\n screenEffects[destinationIndex] = captured.screenEffects[sourceIndex];\n externalEffects[destinationIndex] = captured.externalEffects[sourceIndex];\n if (kind === DRAW_QUAD || kind === DRAW_NINE_PATCH) {\n const sourceMatrix = captured.ints[sourceIntAt + 2];\n if (sourceMatrix >= 0) {\n const sourceMatrixAt = sourceMatrix * COLOR_MATRIX_FLOATS;\n const destinationMatrixAt = destinationMatrix * COLOR_MATRIX_FLOATS;\n colorMatrices.set(\n captured.colorMatrices.subarray(\n sourceMatrixAt,\n sourceMatrixAt + COLOR_MATRIX_FLOATS,\n ),\n destinationMatrixAt,\n );\n // The copied fragment owns a compact matrix arena; the destination\n // keeps its existing slot so references outside its fragment stay\n // meaningful and compiled consumers see an in-place content delta.\n ints[destinationIntAt + 2] = destinationMatrix;\n }\n }\n }\n for (let index = start; index < start + captured.count; index += 1) {\n markPatched(index);\n }\n }\n\n function applyFragmentPatches(\n patches: readonly DrawListFragmentPatch<TTexture>[],\n ): boolean {\n if (!Array.isArray(patches)) return false;\n const validated: Array<{\n start: number;\n captured: FragmentStorage<TTexture>;\n }> = [];\n let previousStart = -1;\n let previousEnd = 0;\n for (const patch of patches) {\n if (!patch || !Number.isInteger(patch.start)) return false;\n const start = patch.start;\n if (start < previousStart) return false;\n let captured: FragmentStorage<TTexture>;\n try {\n captured = requireFragmentStorage(patch.fragment);\n } catch {\n return false;\n }\n if (start < previousEnd || !canPatchFragment(start, captured)) {\n return false;\n }\n validated.push({ start, captured });\n previousStart = start;\n previousEnd = Math.max(previousEnd, start + captured.count);\n }\n for (const patch of validated)\n applyFragmentPatch(patch.start, patch.captured);\n return true;\n }\n\n function writeQuadPayload(view: QuadView, at: number): void {\n floats[at] = view.m[0];\n floats[at + 1] = view.m[1];\n floats[at + 2] = view.m[2];\n floats[at + 3] = view.m[3];\n floats[at + 4] = view.m[4];\n floats[at + 5] = view.m[5];\n floats[at + 6] = view.w;\n floats[at + 7] = view.h;\n floats[at + 8] = view.srcX;\n floats[at + 9] = view.srcY;\n floats[at + 10] = view.srcW;\n floats[at + 11] = view.srcH;\n floats[at + 12] = view.r;\n floats[at + 13] = view.g;\n floats[at + 14] = view.b;\n floats[at + 15] = view.a;\n }\n\n function readQuadPayload(view: QuadView, at: number): void {\n view.m[0] = floats[at];\n view.m[1] = floats[at + 1];\n view.m[2] = floats[at + 2];\n view.m[3] = floats[at + 3];\n view.m[4] = floats[at + 4];\n view.m[5] = floats[at + 5];\n view.w = floats[at + 6];\n view.h = floats[at + 7];\n view.srcX = floats[at + 8];\n view.srcY = floats[at + 9];\n view.srcW = floats[at + 10];\n view.srcH = floats[at + 11];\n view.r = floats[at + 12];\n view.g = floats[at + 13];\n view.b = floats[at + 14];\n view.a = floats[at + 15];\n }\n\n function writeQuadInts(\n view: QuadView,\n at: number,\n matrixIndex: number,\n ): void {\n ints[at] = view.blend;\n ints[at + 1] = (view.flipH ? FLIP_H : 0) | (view.flipV ? FLIP_V : 0);\n ints[at + 2] = matrixIndex;\n }\n\n function readQuadInts(view: QuadView, at: number): void {\n view.blend = ints[at] as BlendMode;\n const flags = ints[at + 1];\n view.flipH = (flags & FLIP_H) !== 0;\n view.flipV = (flags & FLIP_V) !== 0;\n const matrixIndex = ints[at + 2];\n view.hasColorMatrix = matrixIndex >= 0;\n if (matrixIndex >= 0) {\n const from = matrixIndex * COLOR_MATRIX_FLOATS;\n for (let i = 0; i < COLOR_MATRIX_FLOATS; i += 1) {\n view.colorMatrix[i] = colorMatrices[from + i];\n }\n }\n }\n\n return {\n get count() {\n return count;\n },\n get clipDepth() {\n return clipDepth;\n },\n get maxClipDepth() {\n return maxClipDepth;\n },\n get structuralRevision() {\n return structuralRevision;\n },\n get contentRevision() {\n return contentRevision;\n },\n get floats() {\n return floats;\n },\n get ints() {\n return ints;\n },\n get colorMatrices() {\n return colorMatrices;\n },\n\n reset() {\n for (let i = 0; i < count; i += 1) {\n textures[i] = null;\n screenEffects[i] = null;\n externalEffects[i] = null;\n }\n count = 0;\n floatLength = 0;\n intLength = 0;\n colorMatrixCount = 0;\n clipDepth = 0;\n maxClipDepth = 0;\n contentRevision += 1;\n structuralRevision += 1;\n },\n\n appendFragment(fragment) {\n const captured = requireFragmentStorage(fragment);\n const start = count;\n for (\n let sourceIndex = 0;\n sourceIndex < captured.count;\n sourceIndex += 1\n ) {\n const kind = captured.kinds[sourceIndex] as DrawCommandKind;\n const floatAt = captured.floatOffsets[sourceIndex];\n const intAt = captured.intOffsets[sourceIndex];\n fillFragmentStoragePayloadLengths(\n captured,\n sourceIndex,\n fragmentAppendLengths,\n );\n if (\n floatAt < 0 ||\n intAt < 0 ||\n floatAt + fragmentAppendLengths.floats > captured.floatLength ||\n intAt + fragmentAppendLengths.ints > captured.intLength\n ) {\n throw new RangeError(\n `draw-list fragment command ${sourceIndex} has an invalid arena range`,\n );\n }\n const index = beginCommand(\n kind,\n fragmentAppendLengths.floats,\n fragmentAppendLengths.ints,\n captured.textures[sourceIndex],\n );\n const targetFloatAt = floatOffsets[index];\n const targetIntAt = intOffsets[index];\n for (\n let offset = 0;\n offset < fragmentAppendLengths.floats;\n offset += 1\n ) {\n floats[targetFloatAt + offset] = captured.floats[floatAt + offset];\n }\n for (let offset = 0; offset < fragmentAppendLengths.ints; offset += 1) {\n ints[targetIntAt + offset] = captured.ints[intAt + offset];\n }\n screenEffects[index] = captured.screenEffects[sourceIndex];\n externalEffects[index] = captured.externalEffects[sourceIndex];\n if (kind === DRAW_QUAD || kind === DRAW_NINE_PATCH) {\n const matrix = captured.ints[intAt + 2];\n if (matrix >= 0) {\n ints[targetIntAt + 2] = storeFragmentColorMatrix(\n captured.colorMatrices,\n matrix,\n );\n }\n }\n if (kind === DRAW_CLIP_PUSH) {\n clipDepth += 1;\n maxClipDepth = Math.max(maxClipDepth, clipDepth);\n } else if (kind === DRAW_CLIP_POP) {\n if (clipDepth <= 0) {\n throw new RangeError(\n \"draw-list fragment popClip() with no clip rect pushed\",\n );\n }\n clipDepth -= 1;\n }\n }\n return start;\n },\n\n patchFragment(start, fragment) {\n return applyFragmentPatches([{ start, fragment }]);\n },\n\n patchFragments(patches) {\n return applyFragmentPatches(patches);\n },\n\n kindAt(index) {\n requireIndex(index);\n return kinds[index] as DrawCommandKind;\n },\n\n commandRevisionAt(index) {\n requireIndex(index);\n return commandRevisions[index];\n },\n\n readPatchesSince(revision, out) {\n const mutable = out as MutableDrawListPatchView;\n mutable.begin(contentRevision);\n if (revision === contentRevision) return out;\n if (patchJournalCount === 0) {\n mutable.overflow();\n return out;\n }\n const oldest = patchJournalRevisions[patchJournalStart];\n if (revision < oldest - 1) {\n mutable.overflow();\n return out;\n }\n for (let offset = 0; offset < patchJournalCount; offset += 1) {\n const slot = (patchJournalStart + offset) % patchJournalCapacity;\n if (patchJournalRevisions[slot] > revision)\n mutable.add(patchJournalIndexes[slot]);\n }\n return out;\n },\n\n kindNameAt(index) {\n requireIndex(index);\n return DRAW_COMMAND_NAMES[kinds[index]];\n },\n\n textureAt(index) {\n requireIndex(index);\n return textures[index];\n },\n screenEffectAt(index) {\n requireIndex(index);\n return screenEffects[index];\n },\n externalEffectAt(index) {\n requireIndex(index);\n return externalEffects[index];\n },\n\n floatOffsetAt(index) {\n requireIndex(index);\n return floatOffsets[index];\n },\n\n intOffsetAt(index) {\n requireIndex(index);\n return intOffsets[index];\n },\n\n colorMatrixIndexAt(index) {\n requireIndex(index);\n const kind = kinds[index];\n if (kind !== DRAW_QUAD && kind !== DRAW_NINE_PATCH) return -1;\n return ints[intOffsets[index] + 2];\n },\n\n pushQuad(quad, texture = null) {\n const matrixIndex = storeColorMatrix(quad);\n const index = beginCommand(DRAW_QUAD, QUAD_FLOATS, QUAD_INTS, texture);\n writeQuadPayload(quad, floatOffsets[index]);\n writeQuadInts(quad, intOffsets[index], matrixIndex);\n return index;\n },\n\n pushNinePatch(patch, texture = null) {\n const matrixIndex = storeColorMatrix(patch);\n const index = beginCommand(\n DRAW_NINE_PATCH,\n NINE_PATCH_FLOATS,\n NINE_PATCH_INTS,\n texture,\n );\n const at = floatOffsets[index];\n writeQuadPayload(patch, at);\n floats[at + QUAD_FLOATS] = patch.marginLeft;\n floats[at + QUAD_FLOATS + 1] = patch.marginTop;\n floats[at + QUAD_FLOATS + 2] = patch.marginRight;\n floats[at + QUAD_FLOATS + 3] = patch.marginBottom;\n writeQuadInts(patch, intOffsets[index], matrixIndex);\n return index;\n },\n\n pushPolyline(line) {\n const pointCount = Math.max(0, Math.floor(line.pointCount));\n if (pointCount * 2 > line.points.length) {\n throw new RangeError(\n `polyline claims ${pointCount} points but its buffer holds ${Math.floor(line.points.length / 2)}`,\n );\n }\n const index = beginCommand(\n DRAW_POLYLINE,\n POLYLINE_HEADER_FLOATS + pointCount * 2,\n POLYLINE_INTS,\n null,\n );\n const at = floatOffsets[index];\n floats[at] = line.width;\n floats[at + 1] = line.r;\n floats[at + 2] = line.g;\n floats[at + 3] = line.b;\n floats[at + 4] = line.a;\n floats.set(\n line.points.subarray(0, pointCount * 2),\n at + POLYLINE_HEADER_FLOATS,\n );\n ints[intOffsets[index]] = pointCount;\n return index;\n },\n\n pushTexturedMesh(mesh, texture = null) {\n const vertexCount = Math.max(0, Math.floor(mesh.vertexCount));\n const indexCount = Math.max(0, Math.floor(mesh.indexCount));\n if (mesh.m.length < 6) {\n throw new RangeError(\n `textured mesh transform needs 6 entries, got ${mesh.m.length}`,\n );\n }\n if (vertexCount * 2 > mesh.positions.length) {\n throw new RangeError(\n `textured mesh claims ${vertexCount} vertices but its position buffer holds ${Math.floor(mesh.positions.length / 2)}`,\n );\n }\n if (vertexCount * 2 > mesh.uvs.length) {\n throw new RangeError(\n `textured mesh claims ${vertexCount} vertices but its UV buffer holds ${Math.floor(mesh.uvs.length / 2)}`,\n );\n }\n if (indexCount > mesh.indices.length) {\n throw new RangeError(\n `textured mesh claims ${indexCount} indices but its index buffer holds ${mesh.indices.length}`,\n );\n }\n if (indexCount % 3 !== 0) {\n throw new RangeError(\n `textured mesh index count ${indexCount} is not a triangle list`,\n );\n }\n for (let i = 0; i < indexCount; i += 1) {\n if (mesh.indices[i] >= vertexCount) {\n throw new RangeError(\n `textured mesh index ${mesh.indices[i]} at ${i} is outside ${vertexCount} vertices`,\n );\n }\n }\n const index = beginCommand(\n DRAW_TEXTURED_MESH,\n TEXTURED_MESH_HEADER_FLOATS + vertexCount * 4,\n TEXTURED_MESH_HEADER_INTS + indexCount,\n texture,\n );\n const at = floatOffsets[index];\n for (let i = 0; i < 6; i += 1) floats[at + i] = mesh.m[i];\n floats[at + 6] = mesh.r;\n floats[at + 7] = mesh.g;\n floats[at + 8] = mesh.b;\n floats[at + 9] = mesh.a;\n const positionsAt = at + TEXTURED_MESH_HEADER_FLOATS;\n for (let i = 0; i < vertexCount * 2; i += 1) {\n floats[positionsAt + i] = mesh.positions[i];\n floats[positionsAt + vertexCount * 2 + i] = mesh.uvs[i];\n }\n const intAt = intOffsets[index];\n ints[intAt] = vertexCount;\n ints[intAt + 1] = indexCount;\n ints[intAt + 2] = mesh.blend;\n for (let i = 0; i < indexCount; i += 1) {\n ints[intAt + TEXTURED_MESH_HEADER_INTS + i] = mesh.indices[i];\n }\n return index;\n },\n\n pushGlyphs(run) {\n const glyphCount = Math.max(0, Math.floor(run.glyphCount));\n if (glyphCount * 2 > run.positions.length) {\n throw new RangeError(\n `glyph run claims ${glyphCount} glyphs but its position buffer holds ${Math.floor(run.positions.length / 2)}`,\n );\n }\n if (glyphCount > run.slots.length) {\n throw new RangeError(\n `glyph run claims ${glyphCount} glyphs but its slot buffer holds ${run.slots.length}`,\n );\n }\n const index = beginCommand(\n DRAW_GLYPHS,\n GLYPHS_HEADER_FLOATS + glyphCount * 2,\n GLYPHS_HEADER_INTS + glyphCount,\n null,\n );\n const at = floatOffsets[index];\n floats[at] = run.m[0];\n floats[at + 1] = run.m[1];\n floats[at + 2] = run.m[2];\n floats[at + 3] = run.m[3];\n floats[at + 4] = run.m[4];\n floats[at + 5] = run.m[5];\n floats[at + 6] = run.pixelsPerEm;\n floats[at + 7] = run.r;\n floats[at + 8] = run.g;\n floats[at + 9] = run.b;\n floats[at + 10] = run.a;\n // NORMALISED, NOT COPIED, AND THAT IS ABOUT THE CONSUMERS RATHER THAN ABOUT TASTE. This\n // field is newer than the hand-maintained ambient `.d.ts` files that `../sts2-couch-coop`\n // and `../spirectl` resolve this package through (see `AGENTS.md`), and at least one of them\n // builds a `GlyphsView` field-for-field rather than through `createGlyphsView`. Such a caller\n // still TYPE-CHECKS — its own declaration has no `spreadPx` — and hands us `undefined`, which\n // a Float32Array stores as NaN. `HbGpuRenderer.setSpread` clamps that back to 0, so the\n // shipped path survives it; the IR would not, and `readGlyphs` would hand every other\n // `GlyphPass` implementation a NaN to multiply a quad corner by. Zero is what those callers\n // meant.\n floats[at + GLYPHS_SPREAD_OFFSET] = Number.isFinite(run.spreadPx)\n ? run.spreadPx\n : 0;\n // Preserve unknown rather than normalising it to an empty box. The\n // damage planner checks the whole tuple before accepting glyph bounds.\n floats[at + GLYPHS_INK_X_OFFSET] = finiteOrNaN(run.localInkX);\n floats[at + GLYPHS_INK_Y_OFFSET] = finiteOrNaN(run.localInkY);\n floats[at + GLYPHS_INK_WIDTH_OFFSET] = finiteOrNaN(run.localInkWidth);\n floats[at + GLYPHS_INK_HEIGHT_OFFSET] = finiteOrNaN(run.localInkHeight);\n floats[at + GLYPHS_INK_OUTSET_OFFSET] = finiteOrNaN(run.localInkOutset);\n floats.set(\n run.positions.subarray(0, glyphCount * 2),\n at + GLYPHS_HEADER_FLOATS,\n );\n const intAt = intOffsets[index];\n ints[intAt] = glyphCount;\n ints.set(run.slots.subarray(0, glyphCount), intAt + GLYPHS_HEADER_INTS);\n return index;\n },\n\n pushScreenEffect(command) {\n const index = beginCommand(DRAW_SCREEN_EFFECT, 0, 0, null);\n screenEffects[index] = command;\n return index;\n },\n\n pushExternalEffect(command) {\n const index = beginCommand(DRAW_EXTERNAL_EFFECT, 0, 0, null);\n externalEffects[index] = command;\n return index;\n },\n\n pushClipRect(clip) {\n const index = beginCommand(DRAW_CLIP_PUSH, CLIP_FLOATS, 0, null);\n const at = floatOffsets[index];\n floats[at] = clip.x;\n floats[at + 1] = clip.y;\n floats[at + 2] = clip.w;\n floats[at + 3] = clip.h;\n floats[at + 4] = clip.cornerRadius;\n floats[at + 5] = clip.outsetX;\n clipDepth += 1;\n if (clipDepth > maxClipDepth) maxClipDepth = clipDepth;\n return index;\n },\n\n popClip() {\n if (clipDepth === 0) {\n throw new RangeError(\"draw-list popClip() with no clip rect pushed\");\n }\n const index = beginCommand(DRAW_CLIP_POP, 0, 0, null);\n clipDepth -= 1;\n return index;\n },\n\n readQuad(index, out) {\n requireKind(index, DRAW_QUAD);\n readQuadPayload(out, floatOffsets[index]);\n readQuadInts(out, intOffsets[index]);\n return out;\n },\n\n readNinePatch(index, out) {\n requireKind(index, DRAW_NINE_PATCH);\n const at = floatOffsets[index];\n readQuadPayload(out, at);\n out.marginLeft = floats[at + QUAD_FLOATS];\n out.marginTop = floats[at + QUAD_FLOATS + 1];\n out.marginRight = floats[at + QUAD_FLOATS + 2];\n out.marginBottom = floats[at + QUAD_FLOATS + 3];\n readQuadInts(out, intOffsets[index]);\n return out;\n },\n\n readPolyline(index, out) {\n requireKind(index, DRAW_POLYLINE);\n const at = floatOffsets[index];\n out.width = floats[at];\n out.r = floats[at + 1];\n out.g = floats[at + 2];\n out.b = floats[at + 3];\n out.a = floats[at + 4];\n const pointCount = ints[intOffsets[index]];\n out.pointCount = pointCount;\n if (out.points.length < pointCount * 2) {\n out.points = new Float32Array(pointCount * 2);\n }\n const from = at + POLYLINE_HEADER_FLOATS;\n out.points.set(floats.subarray(from, from + pointCount * 2));\n return out;\n },\n\n readTexturedMesh(index, out) {\n requireTexturedMesh(index);\n const at = floatOffsets[index];\n const intAt = intOffsets[index];\n const vertexCount = ints[intAt];\n const indexCount = ints[intAt + 1];\n for (let i = 0; i < 6; i += 1) out.m[i] = floats[at + i];\n out.r = floats[at + 6];\n out.g = floats[at + 7];\n out.b = floats[at + 8];\n out.a = floats[at + 9];\n out.vertexCount = vertexCount;\n out.indexCount = indexCount;\n out.blend = ints[intAt + 2] as BlendMode;\n if (out.positions.length < vertexCount * 2) {\n out.positions = new Float32Array(vertexCount * 2);\n }\n if (out.uvs.length < vertexCount * 2) {\n out.uvs = new Float32Array(vertexCount * 2);\n }\n if (out.indices.length < indexCount) {\n out.indices = new Uint32Array(indexCount);\n }\n const positionsAt = at + TEXTURED_MESH_HEADER_FLOATS;\n for (let i = 0; i < vertexCount * 2; i += 1) {\n out.positions[i] = floats[positionsAt + i];\n out.uvs[i] = floats[positionsAt + vertexCount * 2 + i];\n }\n for (let i = 0; i < indexCount; i += 1) {\n out.indices[i] = ints[intAt + TEXTURED_MESH_HEADER_INTS + i];\n }\n return out;\n },\n\n readGlyphs(index, out) {\n requireKind(index, DRAW_GLYPHS);\n const at = floatOffsets[index];\n out.m[0] = floats[at];\n out.m[1] = floats[at + 1];\n out.m[2] = floats[at + 2];\n out.m[3] = floats[at + 3];\n out.m[4] = floats[at + 4];\n out.m[5] = floats[at + 5];\n out.pixelsPerEm = floats[at + 6];\n out.r = floats[at + 7];\n out.g = floats[at + 8];\n out.b = floats[at + 9];\n out.a = floats[at + 10];\n out.spreadPx = floats[at + GLYPHS_SPREAD_OFFSET];\n out.localInkX = floats[at + GLYPHS_INK_X_OFFSET];\n out.localInkY = floats[at + GLYPHS_INK_Y_OFFSET];\n out.localInkWidth = floats[at + GLYPHS_INK_WIDTH_OFFSET];\n out.localInkHeight = floats[at + GLYPHS_INK_HEIGHT_OFFSET];\n out.localInkOutset = floats[at + GLYPHS_INK_OUTSET_OFFSET];\n const intAt = intOffsets[index];\n const glyphCount = ints[intAt];\n out.glyphCount = glyphCount;\n if (out.slots.length < glyphCount) out.slots = new Int32Array(glyphCount);\n if (out.positions.length < glyphCount * 2) {\n out.positions = new Float32Array(glyphCount * 2);\n }\n out.slots.set(\n ints.subarray(intAt + GLYPHS_HEADER_INTS, intAt + 1 + glyphCount),\n );\n const from = at + GLYPHS_HEADER_FLOATS;\n out.positions.set(floats.subarray(from, from + glyphCount * 2));\n return out;\n },\n\n readClipRect(index, out) {\n requireKind(index, DRAW_CLIP_PUSH);\n const at = floatOffsets[index];\n out.x = floats[at];\n out.y = floats[at + 1];\n out.w = floats[at + 2];\n out.h = floats[at + 3];\n out.cornerRadius = floats[at + 4];\n out.outsetX = floats[at + 5];\n return out;\n },\n\n // The patch pair writes the same float slots `writeQuadPayload` does, and\n // touches nothing else: the ints (blend, flags, the colour-matrix INDEX) are\n // structural — a batch breaks on them — and `colorMatrices` is append-only,\n // so a patched command keeps whatever matrix it was pushed with.\n\n patchQuadTransform(index, m) {\n requireQuadLike(index);\n if (m.length < 6) {\n throw new RangeError(\n `draw-list patchQuadTransform needs 6 transform entries, got ${m.length}`,\n );\n }\n const at = floatOffsets[index];\n floats[at] = m[0];\n floats[at + 1] = m[1];\n floats[at + 2] = m[2];\n floats[at + 3] = m[3];\n floats[at + 4] = m[4];\n floats[at + 5] = m[5];\n markPatched(index);\n },\n\n patchQuadColor(index, r, g, b, a) {\n requireQuadLike(index);\n const at = floatOffsets[index];\n floats[at + 12] = r;\n floats[at + 13] = g;\n floats[at + 14] = b;\n floats[at + 15] = a;\n markPatched(index);\n },\n\n patchQuadSource(index, texture, srcX, srcY, srcW, srcH) {\n requireQuadLike(index);\n const at = floatOffsets[index];\n textures[index] = texture;\n floats[at + 8] = srcX;\n floats[at + 9] = srcY;\n floats[at + 10] = srcW;\n floats[at + 11] = srcH;\n markPatched(index);\n },\n\n patchTexturedMeshPositions(index, positions) {\n requireTexturedMesh(index);\n const intAt = intOffsets[index];\n const vertexCount = ints[intAt];\n if (positions.length < vertexCount * 2) {\n throw new RangeError(\n `textured mesh position patch needs ${vertexCount * 2} entries, got ${positions.length}`,\n );\n }\n const at = floatOffsets[index] + TEXTURED_MESH_HEADER_FLOATS;\n for (let i = 0; i < vertexCount * 2; i += 1) {\n floats[at + i] = positions[i];\n }\n markPatched(index);\n },\n\n patchTexturedMeshUvs(index, uvs) {\n requireTexturedMesh(index);\n const intAt = intOffsets[index];\n const vertexCount = ints[intAt];\n if (uvs.length < vertexCount * 2) {\n throw new RangeError(\n `textured mesh UV patch needs ${vertexCount * 2} entries, got ${uvs.length}`,\n );\n }\n const at =\n floatOffsets[index] + TEXTURED_MESH_HEADER_FLOATS + vertexCount * 2;\n for (let i = 0; i < vertexCount * 2; i += 1) {\n floats[at + i] = uvs[i];\n }\n markPatched(index);\n },\n\n patchTexturedMeshSource(index, texture) {\n requireTexturedMesh(index);\n textures[index] = texture;\n markPatched(index);\n },\n\n patchTexturedMeshTransform(index, m) {\n requireTexturedMesh(index);\n if (m.length < 6) {\n throw new RangeError(\n `draw-list patchTexturedMeshTransform needs 6 transform entries, got ${m.length}`,\n );\n }\n const at = floatOffsets[index];\n for (let i = 0; i < 6; i += 1) floats[at + i] = m[i];\n markPatched(index);\n },\n\n patchTexturedMeshColor(index, r, g, b, a) {\n requireTexturedMesh(index);\n const at = floatOffsets[index];\n floats[at + 6] = r;\n floats[at + 7] = g;\n floats[at + 8] = b;\n floats[at + 9] = a;\n markPatched(index);\n },\n\n patchGlyphsTransform(index, m) {\n requireKind(index, DRAW_GLYPHS);\n if (m.length < 6) {\n throw new RangeError(\n `draw-list patchGlyphsTransform needs 6 transform entries, got ${m.length}`,\n );\n }\n const at = floatOffsets[index];\n floats[at] = m[0];\n floats[at + 1] = m[1];\n floats[at + 2] = m[2];\n floats[at + 3] = m[3];\n floats[at + 4] = m[4];\n floats[at + 5] = m[5];\n markPatched(index);\n },\n\n patchGlyphsColor(index, r, g, b, a) {\n requireKind(index, DRAW_GLYPHS);\n const at = floatOffsets[index];\n floats[at + 7] = r;\n floats[at + 8] = g;\n floats[at + 9] = b;\n floats[at + 10] = a;\n markPatched(index);\n },\n };\n}\n","import { colorMatricesEqual, IDENTITY_COLOR_MATRIX } from \"./color\";\nimport { BLEND_MIX, type BlendMode } from \"./draw-list\";\n\n/**\n * The quad batcher: everything the executor knows about MERGING draws, with no\n * GL in it, so the flush decisions — the thing that decides whether a frame is 20\n * draw calls or 200 — are unit-testable rather than inferred from a profiler.\n *\n * WHY MULTI-TEXTURE BATCHING IS THE WHOLE POINT. Probing recorded scenes for\n * batch runs (a run = a maximal span of consecutive painting nodes sharing\n * texture + blend + clip + colour-matrix state) found combat at 152 runs over 183\n * painting nodes — 1.2 nodes per batch, i.e. essentially no batching — and 151 of\n * those 152 breaks were the TEXTURE alone. The map is the same story: 174 runs\n * over 825 nodes, 173 texture breaks. But the number of DISTINCT textures per\n * screen is only 24-65. So a batch that can hold many textures at once collapses\n * the run count towards the number of times the state that a batch CANNOT hold\n * changes — blend (0-16 per screen) and clip (0-26) — plus one flush per\n * texture-table refill. That is the difference between \"tens of draws\" and \"one\n * draw per node\", and it is why the slot table below is not an optimization to\n * add later.\n *\n * HOW A TEXTURE STOPS BREAKING A BATCH. Each batch binds up to\n * `maxTextureSlots` textures to consecutive texture units and each quad carries\n * the INDEX of the one it samples. The fragment shader turns that index back into\n * a sampler with a compiled `if` ladder (GLSL ES 3.00 forbids indexing a sampler\n * array with anything but a constant). A quad whose texture is not in the table\n * takes the next free slot; when the table is full the batch flushes and starts a\n * new table.\n *\n * COLOUR MATRICES GET THE SAME TREATMENT, for the same reason at a smaller scale:\n * the card screens carry 30-48 HSV-transformed quads, and one draw call each\n * would undo the texture win. A batch holds up to `maxColorMatrices` matrices in\n * a uniform array with the IDENTITY pinned at slot 0, so \"no matrix\" costs\n * nothing and needs no separate program. Identical matrices share a slot (the\n * table is deduped by value), which matters because those 30-48 quads are usually\n * a handful of distinct tints applied to many cards.\n *\n * ORDER IS NEVER REORDERED. Instances are drawn in the order they were pushed —\n * `drawArraysInstanced` rasterizes instance N before instance N+1, which is the\n * property a painter's-algorithm 2D renderer with no depth buffer depends on. So\n * this batcher only ever MERGES CONSECUTIVE commands; it never sorts, and it can\n * therefore be dropped in front of any draw list without changing what the frame\n * looks like. Bucketing non-adjacent commands by texture is a separate,\n * order-unsafe transformation that belongs to whoever BUILDS the list and knows\n * which spans are safe to permute.\n *\n * FOUR EXPLICIT CORNERS, NOT AN AFFINE BASIS. An instance carries `p0..p3`\n * outright (8 floats) rather than a 2x3 transform (6). The two extra floats buy\n * arbitrary quadrilaterals, which is what lets `./polyline`'s stroke segments AND\n * its join wedges (a triangle spelled as a quad with two coincident corners) ride\n * in the same buffer, the same shader and the same batch as every sprite. The\n * alternative — a second program and a mid-frame break for every polyline — costs\n * far more than 8 bytes per quad. The consequence to know about: UV interpolates\n * affinely per triangle, so a NON-parallelogram textured quad would show a seam\n * along the split diagonal. Nothing produces one (sprites and nine-patch bands\n * are affine images of a rect; the non-affine quads are untextured stroke\n * geometry), and if something ever does, the fix is to split it rather than to\n * make every quad pay for projective interpolation.\n */\n\n/** Floats per instance. See the field offsets below for the layout. */\nexport const INSTANCE_FLOATS = 18;\n/** Offset of `p0.x` — four `(x, y)` corners, in the unit-square order\n * `(0,0)`, `(1,0)`, `(1,1)`, `(0,1)`. Design space. */\nexport const INSTANCE_CORNERS_OFFSET = 0;\n/** Offset of the normalized source rect `(u0, v0, uSpan, vSpan)`. A span is\n * NEGATIVE for a flipped axis, which is how `FLIP_H`/`FLIP_V` are carried. */\nexport const INSTANCE_UV_OFFSET = 8;\n/** Offset of the PREMULTIPLIED tint, `(r, g, b, a)`. */\nexport const INSTANCE_COLOR_OFFSET = 12;\n/** Offset of `(textureSlot, colorMatrixSlot)`. Matrix slot 0 is the identity. */\nexport const INSTANCE_SLOTS_OFFSET = 16;\n\n/** Floats per colour-matrix slot. */\nexport const COLOR_MATRIX_FLOATS = 9;\n\n/** The most texture units this batcher will ever ask for, whatever the GPU\n * reports. Sixteen is the WebGL2 (GLES 3.0) guaranteed minimum for\n * `MAX_TEXTURE_IMAGE_UNITS`, so asking for more buys a shader that some\n * conformant device cannot link, in exchange for a batch boundary the measured\n * key counts (24-65 distinct textures per screen) would still hit. */\nexport const MAX_TEXTURE_SLOTS = 16;\n\n/** Default colour-matrix table size, including the identity at slot 0. */\nexport const DEFAULT_COLOR_MATRIX_SLOTS = 16;\n\n/** What a batch binds to a texture unit. Structural on purpose: the batcher only\n * needs the handle's IDENTITY to slot it, and a test can hand it a stand-in. */\nexport interface BatchTexture {\n readonly texture: WebGLTexture;\n}\n\n/**\n * The staging view a caller fills before {@link QuadBatcher.push}. Owned by the\n * batcher and reused, so a frame's worth of quads allocates nothing.\n */\nexport interface QuadInstance {\n /** Corner at unit-square `(0, 0)`, design space. */\n x0: number;\n y0: number;\n /** Corner at `(1, 0)`. */\n x1: number;\n y1: number;\n /** Corner at `(1, 1)`. */\n x2: number;\n y2: number;\n /** Corner at `(0, 1)`. */\n x3: number;\n y3: number;\n /** Normalized source origin (the texel under corner `(0, 0)`). */\n u0: number;\n v0: number;\n /** Normalized source span; negative mirrors the axis. */\n uSpan: number;\n vSpan: number;\n /** PREMULTIPLIED tint. */\n r: number;\n g: number;\n b: number;\n a: number;\n}\n\nexport function createQuadInstance(): QuadInstance {\n return {\n x0: 0,\n y0: 0,\n x1: 0,\n y1: 0,\n x2: 0,\n y2: 0,\n x3: 0,\n y3: 0,\n u0: 0,\n v0: 0,\n uSpan: 1,\n vSpan: 1,\n r: 1,\n g: 1,\n b: 1,\n a: 1,\n };\n}\n\nexport type BatchFlushReason =\n /** The texture table was full and the next quad wanted a texture not in it. */\n | \"textureSlots\"\n /** The colour-matrix table was full and the next quad wanted a new matrix. */\n | \"colorMatrices\"\n /** The blend mode changed; GL blend state is per-draw, not per-instance. */\n | \"blend\"\n /** The clip scope changed; the scissor box is per-draw too. */\n | \"clip\"\n /**\n * A glyph run interrupted the quads.\n *\n * Not a state change this batcher could hold: the glyph pass replaces the program and the vertex\n * array outright, so the pending batch has to be DRAWN under the executor's state before the\n * pass runs. Counted separately from `blend` and `clip` because it is the one break a consumer\n * can remove by moving text, and a frame whose batching regressed should say so by axis.\n */\n | \"glyphs\"\n /** A screen-dependent effect interrupted the instanced-quad program. */\n | \"effects\"\n /** An indexed mesh interrupted the instanced-quad program. */\n | \"meshes\"\n /** A retained compiled GPU run takes over after direct quad staging. */\n | \"compiled\"\n /** End of the draw list (or an explicit flush by the caller). */\n | \"end\";\n\n/**\n * One batch, handed to the sink. Every array is the batcher's own live storage —\n * valid only for the duration of the call, and only over the stated prefix.\n */\nexport interface Batch {\n /** Instance data: `quadCount * INSTANCE_FLOATS` floats from index 0. */\n readonly instances: Float32Array;\n readonly quadCount: number;\n /** Texture table. Entries `0 .. textureCount - 1` are the units to bind;\n * everything past that is a stale `null` slot and must not be read. */\n readonly textures: readonly (BatchTexture | null)[];\n readonly textureCount: number;\n /** `colorMatrixCount * COLOR_MATRIX_FLOATS` floats; slot 0 is the identity. */\n readonly colorMatrices: Float32Array;\n readonly colorMatrixCount: number;\n readonly blend: BlendMode;\n /** The clip scope this batch was accumulated under (see `./clip-stack`). */\n readonly clipEpoch: number;\n readonly reason: BatchFlushReason;\n}\n\nexport interface BatcherStats {\n /** Batches emitted, i.e. draw calls the executor issues for quads. */\n batches: number;\n /** Instances pushed. */\n quads: number;\n /** Texture-unit binds — `textureCount` summed over batches. */\n textureBinds: number;\n /** Largest single batch, in instances. */\n maxBatchQuads: number;\n /** Times the instance arena had to grow (should settle at zero). */\n arenaGrowths: number;\n flushes: Record<BatchFlushReason, number>;\n}\n\nexport interface QuadBatcherOptions {\n /** Where a finished batch goes. Called synchronously from `push`/`flush`. */\n draw(batch: Batch): void;\n /** Texture units per batch; clamped to `[1, MAX_TEXTURE_SLOTS]`. */\n maxTextureSlots?: number;\n /** Colour-matrix slots per batch INCLUDING the identity; at least 1. */\n maxColorMatrices?: number;\n /** Initial instance-arena capacity, in quads. */\n quadCapacity?: number;\n}\n\nexport interface QuadBatcher {\n readonly maxTextureSlots: number;\n readonly maxColorMatrices: number;\n /** Instances accumulated in the OPEN batch. */\n readonly quadCount: number;\n /** Texture slots taken in the open batch. */\n readonly textureCount: number;\n /** Colour-matrix slots taken in the open batch, including the identity. */\n readonly colorMatrixCount: number;\n readonly blend: BlendMode;\n readonly stats: BatcherStats;\n /** The reusable staging instance; fill it, then call {@link QuadBatcher.push}. */\n readonly quad: QuadInstance;\n /** Start a frame: drop any open batch WITHOUT drawing it, and zero the stats. */\n reset(): void;\n /** Flush first if the mode differs, then adopt it. */\n setBlend(blend: BlendMode): void;\n /** Flush first if the scope differs, then adopt it. */\n setClipEpoch(epoch: number): void;\n /**\n * Commit {@link QuadBatcher.quad}. `colorMatrix` is 9 row-major floats at\n * `colorMatrixOffset`, or `null` for the identity (which costs no slot).\n */\n push(\n texture: BatchTexture,\n colorMatrix?: ArrayLike<number> | null,\n colorMatrixOffset?: number,\n ): void;\n /** Emit the open batch, if it has anything in it. */\n flush(reason?: BatchFlushReason): void;\n}\n\nfunction emptyFlushCounts(): Record<BatchFlushReason, number> {\n return {\n textureSlots: 0,\n colorMatrices: 0,\n blend: 0,\n clip: 0,\n glyphs: 0,\n effects: 0,\n meshes: 0,\n compiled: 0,\n end: 0,\n };\n}\n\nfunction zeroFlushCounts(counts: Record<BatchFlushReason, number>): void {\n counts.textureSlots = 0;\n counts.colorMatrices = 0;\n counts.blend = 0;\n counts.clip = 0;\n counts.glyphs = 0;\n counts.effects = 0;\n counts.meshes = 0;\n counts.compiled = 0;\n counts.end = 0;\n}\n\nexport function createQuadBatcher(options: QuadBatcherOptions): QuadBatcher {\n const maxTextureSlots = Math.max(\n 1,\n Math.min(\n MAX_TEXTURE_SLOTS,\n Math.floor(options.maxTextureSlots ?? MAX_TEXTURE_SLOTS),\n ),\n );\n const maxColorMatrices = Math.max(\n 1,\n Math.floor(options.maxColorMatrices ?? DEFAULT_COLOR_MATRIX_SLOTS),\n );\n const draw = options.draw;\n\n let instances = new Float32Array(\n Math.max(1, Math.floor(options.quadCapacity ?? 512)) * INSTANCE_FLOATS,\n );\n let quadCount = 0;\n\n // Linear tables, not Maps: at 16 entries a scan beats a hash, and there is\n // nothing to clear between batches beyond a counter.\n const textures: (BatchTexture | null)[] = new Array(maxTextureSlots).fill(\n null,\n );\n let textureCount = 0;\n\n const colorMatrices = new Float32Array(\n maxColorMatrices * COLOR_MATRIX_FLOATS,\n );\n colorMatrices.set(IDENTITY_COLOR_MATRIX, 0);\n let colorMatrixCount = 1;\n\n let blend: BlendMode = BLEND_MIX;\n let clipEpoch = 0;\n\n const quad = createQuadInstance();\n const stats: BatcherStats = {\n batches: 0,\n quads: 0,\n textureBinds: 0,\n maxBatchQuads: 0,\n arenaGrowths: 0,\n flushes: emptyFlushCounts(),\n };\n\n // One reused payload object: a sink that keeps it past the call is reading\n // whatever the next batch put there, which is what the `Batch` doc says.\n const batch: {\n instances: Float32Array;\n quadCount: number;\n textures: readonly (BatchTexture | null)[];\n textureCount: number;\n colorMatrices: Float32Array;\n colorMatrixCount: number;\n blend: BlendMode;\n clipEpoch: number;\n reason: BatchFlushReason;\n } = {\n instances,\n quadCount: 0,\n textures,\n textureCount: 0,\n colorMatrices,\n colorMatrixCount: 1,\n blend,\n clipEpoch: 0,\n reason: \"end\" as BatchFlushReason,\n };\n\n function flush(reason: BatchFlushReason = \"end\"): void {\n if (quadCount === 0) {\n // Nothing drawn under the old state; the tables are already empty.\n return;\n }\n batch.instances = instances;\n batch.quadCount = quadCount;\n batch.textureCount = textureCount;\n batch.colorMatrixCount = colorMatrixCount;\n batch.blend = blend;\n batch.clipEpoch = clipEpoch;\n batch.reason = reason;\n stats.batches += 1;\n stats.textureBinds += textureCount;\n if (quadCount > stats.maxBatchQuads) stats.maxBatchQuads = quadCount;\n stats.flushes[reason] += 1;\n draw(batch);\n quadCount = 0;\n for (let i = 0; i < textureCount; i += 1) textures[i] = null;\n textureCount = 0;\n colorMatrixCount = 1;\n }\n\n /** The texture's slot in the open batch, or -1 when the table is full. */\n function slotFor(texture: BatchTexture): number {\n for (let i = 0; i < textureCount; i += 1) {\n if (textures[i] === texture) return i;\n }\n if (textureCount >= maxTextureSlots) return -1;\n textures[textureCount] = texture;\n textureCount += 1;\n return textureCount - 1;\n }\n\n /** The matrix's slot, deduped by value, or -1 when the table is full. */\n function matrixSlotFor(matrix: ArrayLike<number>, offset: number): number {\n for (let i = 0; i < colorMatrixCount; i += 1) {\n if (\n colorMatricesEqual(\n colorMatrices,\n i * COLOR_MATRIX_FLOATS,\n matrix,\n offset,\n )\n ) {\n return i;\n }\n }\n if (colorMatrixCount >= maxColorMatrices) return -1;\n const at = colorMatrixCount * COLOR_MATRIX_FLOATS;\n for (let i = 0; i < COLOR_MATRIX_FLOATS; i += 1) {\n colorMatrices[at + i] = matrix[offset + i];\n }\n colorMatrixCount += 1;\n return colorMatrixCount - 1;\n }\n\n function ensureCapacity(): void {\n const needed = (quadCount + 1) * INSTANCE_FLOATS;\n if (needed <= instances.length) return;\n let capacity = Math.max(INSTANCE_FLOATS, instances.length);\n while (capacity < needed) capacity *= 2;\n const grown = new Float32Array(capacity);\n grown.set(instances);\n instances = grown;\n stats.arenaGrowths += 1;\n }\n\n return {\n maxTextureSlots,\n maxColorMatrices,\n get quadCount() {\n return quadCount;\n },\n get textureCount() {\n return textureCount;\n },\n get colorMatrixCount() {\n return colorMatrixCount;\n },\n get blend() {\n return blend;\n },\n stats,\n quad,\n\n reset() {\n quadCount = 0;\n for (let i = 0; i < textureCount; i += 1) textures[i] = null;\n textureCount = 0;\n colorMatrixCount = 1;\n blend = BLEND_MIX;\n clipEpoch = 0;\n stats.batches = 0;\n stats.quads = 0;\n stats.textureBinds = 0;\n stats.maxBatchQuads = 0;\n stats.arenaGrowths = 0;\n zeroFlushCounts(stats.flushes);\n },\n\n setBlend(next) {\n if (next === blend) return;\n flush(\"blend\");\n blend = next;\n },\n\n setClipEpoch(epoch) {\n if (epoch === clipEpoch) return;\n flush(\"clip\");\n clipEpoch = epoch;\n },\n\n push(texture, colorMatrix = null, colorMatrixOffset = 0) {\n let slot = slotFor(texture);\n if (slot < 0) {\n flush(\"textureSlots\");\n slot = slotFor(texture);\n }\n let matrixSlot = 0;\n if (colorMatrix) {\n matrixSlot = matrixSlotFor(colorMatrix, colorMatrixOffset);\n if (matrixSlot < 0) {\n flush(\"colorMatrices\");\n // The texture table went with it, so the slot has to be retaken.\n slot = slotFor(texture);\n matrixSlot = matrixSlotFor(colorMatrix, colorMatrixOffset);\n // A one-slot table holds nothing but the identity, so a batcher\n // configured that way cannot carry matrices at all: draw untransformed\n // rather than index a slot that does not exist.\n if (matrixSlot < 0) matrixSlot = 0;\n }\n }\n ensureCapacity();\n const at = quadCount * INSTANCE_FLOATS;\n instances[at] = quad.x0;\n instances[at + 1] = quad.y0;\n instances[at + 2] = quad.x1;\n instances[at + 3] = quad.y1;\n instances[at + 4] = quad.x2;\n instances[at + 5] = quad.y2;\n instances[at + 6] = quad.x3;\n instances[at + 7] = quad.y3;\n instances[at + 8] = quad.u0;\n instances[at + 9] = quad.v0;\n instances[at + 10] = quad.uSpan;\n instances[at + 11] = quad.vSpan;\n instances[at + 12] = quad.r;\n instances[at + 13] = quad.g;\n instances[at + 14] = quad.b;\n instances[at + 15] = quad.a;\n instances[at + 16] = slot;\n instances[at + 17] = matrixSlot;\n quadCount += 1;\n stats.quads += 1;\n },\n\n flush,\n };\n}\n","import type { ClipRectView } from \"./draw-list\";\n\n/**\n * The executor's clip scope: a stack of design-space rects, resolved to a GL\n * scissor box and (for the rare rounded clip) to a pair of fragment uniforms.\n *\n * WHY DESIGN SPACE, INTERSECTED BEFORE INTEGERIZING. Each level's rect is\n * intersected with its parent as FLOATS, in the scene's own coordinates, and only\n * the final result is mapped to framebuffer pixels and snapped. Integerizing at\n * every level instead would round the same edge repeatedly, and rounding OUTWARDS\n * (which is what a clip must do — see below) compounds: three nested clips on the\n * same edge would leak up to three pixels.\n *\n * WHY `floor(min)` / `ceil(max)`. A scissor box is whole pixels; the clip it\n * approximates is not. Rounding outwards keeps every pixel the clip PARTIALLY\n * covers, so content is never sheared off by a sub-pixel; the cost is that up to\n * one pixel of overdraw survives on each edge. The other choice (round inwards)\n * eats a visible line off the edge of every scrolling list, which is the failure\n * a reader will actually notice.\n *\n * THE FLIPPED SCISSOR ORIGIN. `gl.scissor` measures Y from the BOTTOM of the\n * drawing buffer; the design space here — like every 2D scene — measures it from\n * the top. So the box's Y is `framebufferHeight - bottomEdge`, not `topEdge`, and\n * getting it wrong produces a clip that is correct in size, correct in X, and\n * mirrored about the middle of the screen — which looks like a layout bug rather\n * than a scissor bug. `clip-stack.test.ts` pins the algebra and the pixel test\n * `nested clips` pins it on a real GPU.\n *\n * ROUNDED CORNERS ARE FRAGMENT WORK, and only for the INNERMOST rounded clip. A\n * scissor cannot express a radius, and a stencil pass per rounded scope would\n * cost more than the feature is worth at the measured population (rounded clips\n * are a handful per screen, nested rounded clips none). So the stack tracks the\n * deepest rounded rect currently open and hands it to the shader as a rounded-rect\n * distance test; every ancestor still clips squarely through the scissor, which is\n * exact for all of them except an outer rounded one's four corners.\n *\n * NON-AXIS-ALIGNED CLIPS FALL BACK TO THEIR AABB. A scissor box is axis-aligned,\n * so a clip can only be exact while the design->framebuffer transform is a scale\n * and a translate. It always is today (see `./present`), and the measured\n * population of rotated clips across the recorded scenes is zero — so rather than\n * carry a stencil path for a case that does not occur, a transform with rotation\n * or skew clips to the transformed rect's bounding box and increments\n * {@link ClipStack.rotatedFallbacks}. A caller that ever sees that counter move\n * has found the case that justifies the stencil.\n */\n\n/** A resolved clip rect in DESIGN space. */\nexport interface ClipBounds {\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n}\n\n/** The innermost rounded clip, in DESIGN space; `radius <= 0` means none is open. */\nexport interface RoundedClip {\n centerX: number;\n centerY: number;\n halfWidth: number;\n halfHeight: number;\n radius: number;\n}\n\n/** A GL scissor box: framebuffer pixels, origin BOTTOM-LEFT. */\nexport interface ScissorBox {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/**\n * A design->framebuffer-pixel affine, in the draw-list's `Transform2D` order\n * `[xx, xy, yx, yy, originX, originY]`: `px = xx*x + yx*y + ox`, `py = xy*x +\n * yy*y + oy`, with `py` measured DOWN from the top of the buffer.\n */\nexport type PixelTransform = ArrayLike<number>;\n\nexport interface ClipStack {\n /** Open clip scopes. */\n readonly depth: number;\n /** Bumped by every push/pop/reset: the batcher's cheap \"did the scope change\". */\n readonly epoch: number;\n /** Clips that could not be expressed as an axis-aligned scissor (see the module note). */\n readonly rotatedFallbacks: number;\n /** The intersected clip in design space, or `null` when nothing is clipped. */\n bounds(): ClipBounds | null;\n /** The innermost rounded clip, or `null`. */\n rounded(): RoundedClip | null;\n push(clip: ClipRectView): void;\n pop(): void;\n /** Start a frame: drop every scope (a list may end unbalanced) AND the frame's\n * {@link ClipStack.rotatedFallbacks} count, which is per-frame like every\n * other executor statistic. */\n reset(): void;\n /**\n * The current clip as a scissor box against a `width`x`height` framebuffer,\n * written into `out`. With nothing clipped this is the whole framebuffer.\n */\n scissor(\n transform: PixelTransform,\n width: number,\n height: number,\n out: ScissorBox,\n ): ScissorBox;\n}\n\ninterface ClipEntry extends ClipBounds {\n roundedCenterX: number;\n roundedCenterY: number;\n roundedHalfWidth: number;\n roundedHalfHeight: number;\n roundedRadius: number;\n}\n\nfunction createEntry(): ClipEntry {\n return {\n minX: 0,\n minY: 0,\n maxX: 0,\n maxY: 0,\n roundedCenterX: 0,\n roundedCenterY: 0,\n roundedHalfWidth: 0,\n roundedHalfHeight: 0,\n roundedRadius: 0,\n };\n}\n\nexport function createScissorBox(): ScissorBox {\n return { x: 0, y: 0, width: 0, height: 0 };\n}\n\n/** True when `transform` is a pure scale + translate, i.e. a scissor can be exact. */\nexport function isAxisAligned(transform: PixelTransform): boolean {\n return transform[1] === 0 && transform[2] === 0;\n}\n\nexport function createClipStack(): ClipStack {\n const entries: ClipEntry[] = [];\n let depth = 0;\n let epoch = 0;\n let rotatedFallbacks = 0;\n const boundsOut: ClipBounds = { minX: 0, minY: 0, maxX: 0, maxY: 0 };\n const roundedOut: RoundedClip = {\n centerX: 0,\n centerY: 0,\n halfWidth: 0,\n halfHeight: 0,\n radius: 0,\n };\n\n return {\n get depth() {\n return depth;\n },\n get epoch() {\n return epoch;\n },\n get rotatedFallbacks() {\n return rotatedFallbacks;\n },\n\n bounds() {\n if (depth === 0) return null;\n const top = entries[depth - 1];\n boundsOut.minX = top.minX;\n boundsOut.minY = top.minY;\n boundsOut.maxX = top.maxX;\n boundsOut.maxY = top.maxY;\n return boundsOut;\n },\n\n rounded() {\n if (depth === 0) return null;\n const top = entries[depth - 1];\n if (!(top.roundedRadius > 0)) return null;\n roundedOut.centerX = top.roundedCenterX;\n roundedOut.centerY = top.roundedCenterY;\n roundedOut.halfWidth = top.roundedHalfWidth;\n roundedOut.halfHeight = top.roundedHalfHeight;\n roundedOut.radius = top.roundedRadius;\n return roundedOut;\n },\n\n push(clip) {\n while (entries.length <= depth) entries.push(createEntry());\n const entry = entries[depth];\n // The one-axis slack, applied BEFORE the intersection: a re-laid-out scene\n // can legitimately paint a little wider than the clip Godot recorded, and\n // only ever on x (see `ClipRectView.outsetX`).\n const outset = Math.max(0, clip.outsetX);\n let minX = clip.x - outset;\n let minY = clip.y;\n let maxX = clip.x + clip.w + outset;\n let maxY = clip.y + clip.h;\n const parent = depth > 0 ? entries[depth - 1] : null;\n if (parent) {\n if (parent.minX > minX) minX = parent.minX;\n if (parent.minY > minY) minY = parent.minY;\n if (parent.maxX < maxX) maxX = parent.maxX;\n if (parent.maxY < maxY) maxY = parent.maxY;\n }\n entry.minX = minX;\n entry.minY = minY;\n // An empty intersection stays empty rather than inverting.\n entry.maxX = Math.max(minX, maxX);\n entry.maxY = Math.max(minY, maxY);\n\n if (clip.cornerRadius > 0) {\n // The rounded test follows THIS rect's own corners (post-outset), not the\n // intersection's — the intersection's edges are already exact through the\n // scissor, and rounding them would round a corner the scene never had.\n const halfWidth = (clip.w + outset * 2) / 2;\n const halfHeight = clip.h / 2;\n entry.roundedCenterX = clip.x - outset + halfWidth;\n entry.roundedCenterY = clip.y + halfHeight;\n entry.roundedHalfWidth = Math.max(0, halfWidth);\n entry.roundedHalfHeight = Math.max(0, halfHeight);\n // A radius past half the shorter side is a capsule/circle, not a rect\n // with rounded corners; clamping matches how every rounded-rect SDF and\n // every CSS `border-radius` resolves the same overflow.\n entry.roundedRadius = Math.min(\n clip.cornerRadius,\n entry.roundedHalfWidth,\n entry.roundedHalfHeight,\n );\n } else if (parent) {\n entry.roundedCenterX = parent.roundedCenterX;\n entry.roundedCenterY = parent.roundedCenterY;\n entry.roundedHalfWidth = parent.roundedHalfWidth;\n entry.roundedHalfHeight = parent.roundedHalfHeight;\n entry.roundedRadius = parent.roundedRadius;\n } else {\n entry.roundedRadius = 0;\n }\n\n depth += 1;\n epoch += 1;\n },\n\n pop() {\n if (depth === 0) {\n throw new RangeError(\"clip stack pop with no clip pushed\");\n }\n depth -= 1;\n epoch += 1;\n },\n\n reset() {\n if (depth !== 0) epoch += 1;\n depth = 0;\n rotatedFallbacks = 0;\n },\n\n scissor(transform, width, height, out) {\n if (depth === 0) {\n out.x = 0;\n out.y = 0;\n out.width = Math.max(0, width);\n out.height = Math.max(0, height);\n return out;\n }\n const top = entries[depth - 1];\n const xx = transform[0];\n const xy = transform[1];\n const yx = transform[2];\n const yy = transform[3];\n const ox = transform[4];\n const oy = transform[5];\n if (xy !== 0 || yx !== 0) rotatedFallbacks += 1;\n\n // The transformed rect's four corners; under an axis-aligned transform two\n // of them are redundant and this is exactly a two-point map, so there is no\n // separate fast path to get wrong. Under a rotated one it is the AABB the\n // module note describes.\n let minPx = Number.POSITIVE_INFINITY;\n let minPy = Number.POSITIVE_INFINITY;\n let maxPx = Number.NEGATIVE_INFINITY;\n let maxPy = Number.NEGATIVE_INFINITY;\n for (let corner = 0; corner < 4; corner += 1) {\n const x = corner === 0 || corner === 3 ? top.minX : top.maxX;\n const y = corner < 2 ? top.minY : top.maxY;\n const px = xx * x + yx * y + ox;\n const py = xy * x + yy * y + oy;\n if (px < minPx) minPx = px;\n if (px > maxPx) maxPx = px;\n if (py < minPy) minPy = py;\n if (py > maxPy) maxPy = py;\n }\n\n const left = clampInt(Math.floor(minPx), 0, width);\n const right = clampInt(Math.ceil(maxPx), 0, width);\n const top_ = clampInt(Math.floor(minPy), 0, height);\n const bottom = clampInt(Math.ceil(maxPy), 0, height);\n out.x = left;\n out.width = Math.max(0, right - left);\n // The flip: GL measures the box from the BOTTOM of the drawing buffer.\n out.y = Math.max(0, height - bottom);\n out.height = Math.max(0, bottom - top_);\n return out;\n },\n };\n}\n\nfunction clampInt(value: number, low: number, high: number): number {\n if (!Number.isFinite(value)) return value < 0 ? low : high;\n return value < low ? low : value > high ? high : value;\n}\n","import {\n DRAW_CLIP_POP,\n DRAW_CLIP_PUSH,\n DRAW_EXTERNAL_EFFECT,\n DRAW_GLYPHS,\n DRAW_NINE_PATCH,\n DRAW_POLYLINE,\n DRAW_QUAD,\n DRAW_SCREEN_EFFECT,\n DRAW_TEXTURED_MESH,\n type DrawList,\n} from \"./draw-list\";\n\n/** A top-left-origin, axis-aligned rectangle. It is used in design or backing\n * pixel space; the caller decides which, and {@link transformDamageRect} moves\n * between them conservatively. */\nexport interface DamageRect {\n x: number;\n y: number;\n width: number;\n height: number;\n}\n\n/** Public retained-rendering vocabulary for a rectangle that needs repainting. */\nexport type DirtyRect = DamageRect;\n\n/** A conservative rectangle reported by one draw command when its extent is\n * known. `commandDamageBounds` returns `null` for a full/direct fallback. */\nexport type CommandBounds = DamageRect;\n\n/** A tile selected by {@link DamageTiles}. */\nexport interface DamageTile extends DamageRect {\n column: number;\n row: number;\n}\n\n/** A tile accumulator for retaining a backing surface without retaining an\n * unbounded list of tiny invalidations. */\nexport interface DamageTiles {\n readonly width: number;\n readonly height: number;\n /** Physical backing pixels in one tile. Retained callers use 64×64 tiles. */\n readonly tileWidth: number;\n readonly tileHeight: number;\n readonly columns: number;\n readonly rows: number;\n readonly tileCount: number;\n readonly dirtyCount: number;\n /** `dirtyCount / tileCount`, or zero for an empty surface. */\n readonly coverage: number;\n readonly dirty: boolean;\n resize(width: number, height: number): void;\n mark(rect: DamageRect | null): void;\n clear(): void;\n /** The exact backing-pixel tiles currently marked, in paint order. */\n tiles(): readonly DamageTile[];\n /**\n * Visit marked tiles without materialising `DamageTile` objects. The same\n * mutable tile view is passed each time, so read it synchronously and do not\n * retain it. This is the retained-frame hot path; `tiles()` is only a\n * diagnostics convenience.\n */\n forEach(callback: (tile: DamageTile) => void): void;\n /**\n * Visit an exact, non-overlapping rectangular cover of the marked tiles.\n * Horizontally adjacent tiles are joined, then identical row runs are joined\n * vertically. No clean pixel is included, so each region is safe to pass to\n * a scissored retained replay independently. As with {@link forEach}, the\n * rectangle is a reusable mutable view and must not be retained.\n */\n forEachRegion(callback: (region: DamageRect) => void): void;\n /** Return the marked tiles and clear the accumulator. */\n consume(): readonly DamageTile[];\n}\n\n/** Retained replay uses fixed physical-pixel tiles, never CSS pixels. */\nexport const RETAINED_DAMAGE_TILE_SIZE = 64;\n/** The largest tile coverage that is worth planning for retained replay. */\nexport const RETAINED_MAX_DAMAGE_COVERAGE = 0.2;\n\n/** A `Transform2D` mapping the rect's coordinates into another top-left space. */\nexport type DamageTransform = ArrayLike<number>;\n\nexport function createDamageRect(): DamageRect {\n return { x: 0, y: 0, width: 0, height: 0 };\n}\n\nexport function isDamageEmpty(rect: DamageRect): boolean {\n return !(rect.width > 0 && rect.height > 0);\n}\n\n/** Expand in the rectangle's own coordinate space without mutating inputs. */\nexport function outsetDamageRect(\n rect: DamageRect,\n outset: number,\n out: DamageRect = createDamageRect(),\n): DamageRect | null {\n if (!isFiniteDamageRect(rect) || !Number.isFinite(outset) || outset < 0) {\n return null;\n }\n out.x = rect.x - outset;\n out.y = rect.y - outset;\n out.width = rect.width + outset * 2;\n out.height = rect.height + outset * 2;\n return isFiniteDamageRect(out) ? out : null;\n}\n\n/** True when two half-open rectangles overlap. Touching edges do not repaint. */\nexport function damageIntersects(a: DamageRect, b: DamageRect): boolean {\n return (\n a.width > 0 &&\n a.height > 0 &&\n b.width > 0 &&\n b.height > 0 &&\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\n/** Expand `out` to cover both input rectangles. */\nexport function unionDamageRect(\n a: DamageRect,\n b: DamageRect,\n out: DamageRect = createDamageRect(),\n): DamageRect {\n if (isDamageEmpty(a)) {\n out.x = b.x;\n out.y = b.y;\n out.width = Math.max(0, b.width);\n out.height = Math.max(0, b.height);\n return out;\n }\n if (isDamageEmpty(b)) {\n out.x = a.x;\n out.y = a.y;\n out.width = Math.max(0, a.width);\n out.height = Math.max(0, a.height);\n return out;\n }\n const minX = Math.min(a.x, b.x);\n const minY = Math.min(a.y, b.y);\n const maxX = Math.max(a.x + a.width, b.x + b.width);\n const maxY = Math.max(a.y + a.height, b.y + b.height);\n out.x = minX;\n out.y = minY;\n out.width = Math.max(0, maxX - minX);\n out.height = Math.max(0, maxY - minY);\n return out;\n}\n\n/** Transform all four corners, returning the enclosing axis-aligned rectangle. */\nexport function transformDamageRect(\n rect: DamageRect,\n transform: DamageTransform,\n out: DamageRect = createDamageRect(),\n): DamageRect {\n return transformDamageValues(\n rect.x,\n rect.y,\n rect.width,\n rect.height,\n transform,\n out,\n );\n}\n\n/** Allocation-free coordinate form used by command bounds in retained loops. */\nfunction transformDamageValues(\n x0: number,\n y0: number,\n width: number,\n height: number,\n transform: DamageTransform,\n out: DamageRect,\n transformOffset = 0,\n): DamageRect {\n let minX = Number.POSITIVE_INFINITY;\n let minY = Number.POSITIVE_INFINITY;\n let maxX = Number.NEGATIVE_INFINITY;\n let maxY = Number.NEGATIVE_INFINITY;\n for (let corner = 0; corner < 4; corner += 1) {\n const x = corner === 0 || corner === 3 ? x0 : x0 + width;\n const y = corner < 2 ? y0 : y0 + height;\n const px =\n transform[transformOffset] * x +\n transform[transformOffset + 2] * y +\n transform[transformOffset + 4];\n const py =\n transform[transformOffset + 1] * x +\n transform[transformOffset + 3] * y +\n transform[transformOffset + 5];\n minX = Math.min(minX, px);\n minY = Math.min(minY, py);\n maxX = Math.max(maxX, px);\n maxY = Math.max(maxY, py);\n }\n out.x = minX;\n out.y = minY;\n out.width = Math.max(0, maxX - minX);\n out.height = Math.max(0, maxY - minY);\n return out;\n}\n\nfunction hasFiniteTransform(\n transform: ArrayLike<number>,\n transformOffset: number,\n): boolean {\n for (let index = 0; index < 6; index += 1) {\n if (!Number.isFinite(transform[transformOffset + index])) return false;\n }\n return true;\n}\n\nfunction isFiniteDamageRect(rect: DamageRect): boolean {\n return (\n Number.isFinite(rect.x) &&\n Number.isFinite(rect.y) &&\n Number.isFinite(rect.width) &&\n Number.isFinite(rect.height) &&\n rect.width >= 0 &&\n rect.height >= 0\n );\n}\n\n/**\n * Compute a conservative visual bound for one command. `null` means unknown,\n * which callers must treat as intersecting every damage region. Glyphs are\n * known only when their producer supplied explicit local ink bounds; guessing\n * from pen positions or em size could leave stale ink on a retained surface.\n */\nexport function commandDamageBounds<TTexture>(\n list: DrawList<TTexture>,\n index: number,\n out: DamageRect = createDamageRect(),\n): CommandBounds | null {\n const kind = list.kindAt(index);\n // A screen effect depends on every preceding pixel, so a partial retained\n // replay cannot safely plan around it.\n if (kind === DRAW_SCREEN_EFFECT || kind === DRAW_EXTERNAL_EFFECT) return null;\n if (kind === DRAW_QUAD || kind === DRAW_NINE_PATCH) {\n const at = list.floatOffsetAt(index);\n const floats = list.floats;\n const w = floats[at + 6];\n const h = floats[at + 7];\n if (\n !hasFiniteTransform(floats, at) ||\n !Number.isFinite(w) ||\n !Number.isFinite(h) ||\n w < 0 ||\n h < 0\n ) {\n return null;\n }\n transformDamageValues(0, 0, w, h, floats, out, at);\n return isFiniteDamageRect(out) ? out : null;\n }\n if (kind === DRAW_POLYLINE) {\n const at = list.floatOffsetAt(index);\n const ints = list.ints;\n const floats = list.floats;\n const count = ints[list.intOffsetAt(index)];\n if (count <= 0) {\n out.x = 0;\n out.y = 0;\n out.width = 0;\n out.height = 0;\n return out;\n }\n const width = floats[at];\n if (!Number.isFinite(width)) return null;\n const half = Math.abs(width) / 2;\n let minX = Number.POSITIVE_INFINITY;\n let minY = Number.POSITIVE_INFINITY;\n let maxX = Number.NEGATIVE_INFINITY;\n let maxY = Number.NEGATIVE_INFINITY;\n for (let point = 0; point < count; point += 1) {\n const x = floats[at + 5 + point * 2];\n const y = floats[at + 6 + point * 2];\n if (!Number.isFinite(x) || !Number.isFinite(y)) return null;\n minX = Math.min(minX, x - half);\n minY = Math.min(minY, y - half);\n maxX = Math.max(maxX, x + half);\n maxY = Math.max(maxY, y + half);\n }\n out.x = minX;\n out.y = minY;\n out.width = maxX - minX;\n out.height = maxY - minY;\n return isFiniteDamageRect(out) ? out : null;\n }\n if (kind === DRAW_TEXTURED_MESH) {\n const at = list.floatOffsetAt(index);\n const intAt = list.intOffsetAt(index);\n const floats = list.floats;\n const vertexCount = list.ints[intAt];\n if (vertexCount <= 0) {\n out.x = 0;\n out.y = 0;\n out.width = 0;\n out.height = 0;\n return out;\n }\n const xx = floats[at];\n const xy = floats[at + 1];\n const yx = floats[at + 2];\n const yy = floats[at + 3];\n const ox = floats[at + 4];\n const oy = floats[at + 5];\n const positionsAt = at + 10;\n if (!hasFiniteTransform(floats, at)) return null;\n let minX = Number.POSITIVE_INFINITY;\n let minY = Number.POSITIVE_INFINITY;\n let maxX = Number.NEGATIVE_INFINITY;\n let maxY = Number.NEGATIVE_INFINITY;\n // Bounds every VERTEX, not just the indexed subset: this remains safe if a\n // retained producer patches topology elsewhere, and the extra loop is tiny\n // beside a GPU mesh draw. Transforming each point is necessary for rotation\n // and skew; transforming a local AABB first would be less tight but still\n // misses nothing only when it includes all four derived corners.\n for (let vertex = 0; vertex < vertexCount; vertex += 1) {\n const x = floats[positionsAt + vertex * 2];\n const y = floats[positionsAt + vertex * 2 + 1];\n if (!Number.isFinite(x) || !Number.isFinite(y)) return null;\n const transformedX = xx * x + yx * y + ox;\n const transformedY = xy * x + yy * y + oy;\n minX = Math.min(minX, transformedX);\n minY = Math.min(minY, transformedY);\n maxX = Math.max(maxX, transformedX);\n maxY = Math.max(maxY, transformedY);\n }\n out.x = minX;\n out.y = minY;\n out.width = Math.max(0, maxX - minX);\n out.height = Math.max(0, maxY - minY);\n return isFiniteDamageRect(out) ? out : null;\n }\n if (kind === DRAW_GLYPHS) {\n const at = list.floatOffsetAt(index);\n const floats = list.floats;\n const x = floats[at + 12];\n const y = floats[at + 13];\n const width = floats[at + 14];\n const height = floats[at + 15];\n const effectOutset = floats[at + 16];\n if (\n !hasFiniteTransform(floats, at) ||\n !Number.isFinite(x) ||\n !Number.isFinite(y) ||\n !Number.isFinite(width) ||\n !Number.isFinite(height) ||\n !Number.isFinite(effectOutset) ||\n width < 0 ||\n height < 0 ||\n effectOutset < 0\n ) {\n return null;\n }\n // `spreadPx` is a local dilation owned by this command. The producer's\n // outset covers its additional effect/AA reach, so both are needed.\n const spread = Math.abs(floats[at + 11]);\n const outset = effectOutset + (Number.isFinite(spread) ? spread : 0);\n transformDamageValues(\n x - outset,\n y - outset,\n width + outset * 2,\n height + outset * 2,\n floats,\n out,\n at,\n );\n return isFiniteDamageRect(out) ? out : null;\n }\n if (kind === DRAW_CLIP_PUSH || kind === DRAW_CLIP_POP) {\n // Clip commands paint nothing themselves. Their scope is reconstructed by\n // the ordered replay iterator, never guessed from these empty bounds.\n out.x = 0;\n out.y = 0;\n out.width = 0;\n out.height = 0;\n return out;\n }\n // A newer IR kind must not silently look like invisible content. The direct\n // path's unknown-command diagnostic remains useful, but retained replay has\n // to decline before it clears pixels it cannot reconstruct.\n return null;\n}\n\nexport function createDamageTiles(\n width: number,\n height: number,\n tileWidth = RETAINED_DAMAGE_TILE_SIZE,\n tileHeight = tileWidth,\n): DamageTiles {\n const tileW = Number.isFinite(tileWidth)\n ? Math.max(1, Math.floor(tileWidth))\n : RETAINED_DAMAGE_TILE_SIZE;\n const tileH = Number.isFinite(tileHeight)\n ? Math.max(1, Math.floor(tileHeight))\n : tileW;\n let surfaceWidth = 0;\n let surfaceHeight = 0;\n let columns = 0;\n let rows = 0;\n let marked = new Uint8Array(0);\n let dirty = false;\n let dirtyCount = 0;\n // `forEachRegion` is the retained hot path. Keep its run planner and result\n // storage at their high-water mark instead of creating arrays per frame.\n let regionsStale = true;\n let regionCount = 0;\n const regionPool: DamageRect[] = [];\n let previousEnds = new Int32Array(0);\n let previousRegions = new Int32Array(0);\n let currentEnds = new Int32Array(0);\n let currentRegions = new Int32Array(0);\n const iterationTile: DamageTile = {\n column: 0,\n row: 0,\n x: 0,\n y: 0,\n width: 0,\n height: 0,\n };\n\n function resize(nextWidth: number, nextHeight: number): void {\n surfaceWidth = Number.isFinite(nextWidth)\n ? Math.max(0, Math.round(nextWidth))\n : 0;\n surfaceHeight = Number.isFinite(nextHeight)\n ? Math.max(0, Math.round(nextHeight))\n : 0;\n columns = Math.ceil(surfaceWidth / tileW);\n rows = Math.ceil(surfaceHeight / tileH);\n marked = new Uint8Array(columns * rows);\n dirty = false;\n dirtyCount = 0;\n regionsStale = true;\n previousEnds = new Int32Array(columns);\n previousRegions = new Int32Array(columns);\n currentEnds = new Int32Array(columns);\n currentRegions = new Int32Array(columns);\n }\n\n function mark(rect: DamageRect | null): void {\n if (surfaceWidth === 0 || surfaceHeight === 0) return;\n if (!rect || !isFiniteDamageRect(rect)) {\n marked.fill(1);\n dirty = marked.length > 0;\n dirtyCount = marked.length;\n regionsStale = true;\n return;\n }\n if (isDamageEmpty(rect)) return;\n const left = Math.max(0, Math.floor(rect.x / tileW));\n const top = Math.max(0, Math.floor(rect.y / tileH));\n const right = Math.min(columns, Math.ceil((rect.x + rect.width) / tileW));\n const bottom = Math.min(rows, Math.ceil((rect.y + rect.height) / tileH));\n for (let row = top; row < bottom; row += 1) {\n for (let column = left; column < right; column += 1) {\n const index = row * columns + column;\n if (marked[index] === 0) {\n marked[index] = 1;\n dirtyCount += 1;\n dirty = true;\n regionsStale = true;\n }\n }\n }\n }\n\n function tiles(): DamageTile[] {\n const result: DamageTile[] = [];\n for (let row = 0; row < rows; row += 1) {\n for (let column = 0; column < columns; column += 1) {\n if (marked[row * columns + column] === 0) continue;\n const x = column * tileW;\n const y = row * tileH;\n result.push({\n column,\n row,\n x,\n y,\n width: Math.min(tileW, surfaceWidth - x),\n height: Math.min(tileH, surfaceHeight - y),\n });\n }\n }\n return result;\n }\n\n function forEach(callback: (tile: DamageTile) => void): void {\n for (let row = 0; row < rows; row += 1) {\n for (let column = 0; column < columns; column += 1) {\n if (marked[row * columns + column] === 0) continue;\n const x = column * tileW;\n const y = row * tileH;\n iterationTile.column = column;\n iterationTile.row = row;\n iterationTile.x = x;\n iterationTile.y = y;\n iterationTile.width = Math.min(tileW, surfaceWidth - x);\n iterationTile.height = Math.min(tileH, surfaceHeight - y);\n callback(iterationTile);\n }\n }\n }\n\n /**\n * Build a maximal exact rectangular cover from the tile bitset. A row is\n * first reduced to horizontal runs; only a run with the same column span in\n * the immediately preceding row extends its existing rectangle. That rule\n * is what prevents a T/L-shaped set of tiles from filling its clean corner.\n */\n function rebuildRegions(): void {\n if (!regionsStale) return;\n regionsStale = false;\n regionCount = 0;\n previousEnds.fill(-1);\n previousRegions.fill(-1);\n\n for (let row = 0; row < rows; row += 1) {\n currentEnds.fill(-1);\n currentRegions.fill(-1);\n const y = row * tileH;\n const height = Math.min(tileH, surfaceHeight - y);\n for (let column = 0; column < columns; ) {\n if (marked[row * columns + column] === 0) {\n column += 1;\n continue;\n }\n const start = column;\n column += 1;\n while (column < columns && marked[row * columns + column] !== 0) {\n column += 1;\n }\n const end = column;\n let regionIndex = -1;\n if (previousEnds[start] === end) {\n regionIndex = previousRegions[start];\n }\n if (regionIndex >= 0) {\n // This row is directly below an identical horizontal run, so the\n // enlarged rectangle still covers exactly marked tiles.\n regionPool[regionIndex]!.height += height;\n } else {\n regionIndex = regionCount;\n regionCount += 1;\n const region = regionPool[regionIndex] ?? createDamageRect();\n region.x = start * tileW;\n region.y = y;\n region.width = Math.min(surfaceWidth, end * tileW) - region.x;\n region.height = height;\n regionPool[regionIndex] = region;\n }\n currentEnds[start] = end;\n currentRegions[start] = regionIndex;\n }\n [previousEnds, currentEnds] = [currentEnds, previousEnds];\n [previousRegions, currentRegions] = [currentRegions, previousRegions];\n }\n }\n\n function forEachRegion(callback: (region: DamageRect) => void): void {\n rebuildRegions();\n for (let index = 0; index < regionCount; index += 1) {\n callback(regionPool[index]!);\n }\n }\n\n resize(width, height);\n return {\n get width() {\n return surfaceWidth;\n },\n get height() {\n return surfaceHeight;\n },\n get tileWidth() {\n return tileW;\n },\n get tileHeight() {\n return tileH;\n },\n get columns() {\n return columns;\n },\n get rows() {\n return rows;\n },\n get tileCount() {\n return marked.length;\n },\n get dirtyCount() {\n return dirtyCount;\n },\n get coverage() {\n return marked.length === 0 ? 0 : dirtyCount / marked.length;\n },\n get dirty() {\n return dirty;\n },\n resize,\n mark,\n clear() {\n marked.fill(0);\n dirty = false;\n dirtyCount = 0;\n regionsStale = true;\n },\n tiles,\n forEach,\n forEachRegion,\n consume() {\n const result = tiles();\n marked.fill(0);\n dirty = false;\n dirtyCount = 0;\n regionsStale = true;\n return result;\n },\n };\n}\n","import {\n type CommandBounds,\n commandDamageBounds,\n type DamageRect,\n type DamageTransform,\n transformDamageRect,\n} from \"./damage\";\nimport {\n DRAW_CLIP_POP,\n DRAW_CLIP_PUSH,\n DRAW_EXTERNAL_EFFECT,\n DRAW_SCREEN_EFFECT,\n type DrawList,\n} from \"./draw-list\";\n\n/** A sparse ordered command selection. The executor walks the original list in\n * order, so batching and painter ordering remain exactly the direct path's. */\nexport interface CommandMask {\n readonly count: number;\n /** A screen-dependent command exists; partial retained replay must decline. */\n readonly requiresFullReplay?: boolean;\n includes(index: number): boolean;\n indices(): readonly number[];\n}\n\n/** Retained replay must stay below this fraction of the complete painter list. */\nexport const RETAINED_MAX_REPLAY_FRACTION = 0.4;\n\n/**\n * Largest command count that is strictly below the retained replay threshold.\n * Clip pushes/pops are commands too: omitting them would not restore the\n * original painter state, so they count against the same budget.\n */\nexport function maxPartialReplayCommands(commandCount: number): number {\n if (!Number.isFinite(commandCount) || commandCount <= 0) return 0;\n return Math.max(\n 0,\n Math.ceil(commandCount * RETAINED_MAX_REPLAY_FRACTION) - 1,\n );\n}\n\nconst REPLAY_MASK_SCRATCH = Symbol(\"ReplayMaskScratch\");\nconst replayMaskFrames = new WeakMap<\n object,\n { list: unknown; structuralRevision: number; contentRevision: number }\n>();\n\nexport interface ReplaySelectionOptions {\n /** Map design-space command bounds into the damage rectangle's space. */\n transform?: DamageTransform;\n /**\n * Final-damage-coordinate raster/effect reach added after `transform`.\n * Defaults to one final pixel so antialiasing/filtering still selects a\n * command whose geometry falls just beyond a tile edge. Use this for effects\n * whose reach is known in final coordinates; producer-local effects belong\n * in the command's own local bounds, not both places.\n */\n rasterOutset?: number;\n /** Optional cached bounds provider. `null` takes the unknown-bounds policy. */\n boundsAt?: (index: number, out: CommandBounds) => CommandBounds | null;\n /** Decline instead of returning an unboundedly large partial replay. */\n maxCommands?: number;\n /** Unknown visual bounds cannot safely seed a damaged tile. The default is a\n * full/direct fallback; `select` is available for callers that knowingly\n * prefer conservative overdraw. */\n unknownBounds?: \"fullReplay\" | \"select\";\n}\n\n/** Reusable storage for a replay selection. Its mask and `indices()` array keep\n * identity across calls; after high-water growth selecting a tile allocates no\n * arrays. A threshold/screen-effect decline clears the selection. */\nexport interface ReplayMaskScratch extends CommandMask {\n readonly thresholdExceeded: boolean;\n /** False until `select()` has validated this frame's complete list. */\n readonly selected: boolean;\n /** Internal nominal marker: only a validated selection may drive an FBO replay. */\n readonly [REPLAY_MASK_SCRATCH]: true;\n select<TTexture>(\n list: DrawList<TTexture>,\n damage: DamageRect,\n options?: ReplaySelectionOptions,\n ): ReplayMaskScratch;\n}\n\n/** True only for masks created by this module and safe for a partial FBO replay. */\nexport function isPartialReplayMask(\n mask: ReplayMaskScratch,\n list?: DrawList<unknown>,\n): mask is ReplayMaskScratch {\n const frame = replayMaskFrames.get(mask);\n return (\n mask[REPLAY_MASK_SCRATCH] === true &&\n mask.selected &&\n !mask.requiresFullReplay &&\n (list === undefined ||\n (frame?.list === list &&\n frame.structuralRevision === list.structuralRevision &&\n frame.contentRevision === list.contentRevision))\n );\n}\n\nfunction isFiniteBounds(bounds: DamageRect): boolean {\n return (\n Number.isFinite(bounds.x) &&\n Number.isFinite(bounds.y) &&\n Number.isFinite(bounds.width) &&\n Number.isFinite(bounds.height) &&\n bounds.width >= 0 &&\n bounds.height >= 0\n );\n}\n\n/** Intersect `bounds` after applying final-coordinate reach without mutating a\n * provider-owned cached rectangle. */\nfunction boundsIntersectsDamage(\n bounds: DamageRect,\n damage: DamageRect,\n outset: number,\n): boolean {\n const x = bounds.x - outset;\n const y = bounds.y - outset;\n const width = bounds.width + outset * 2;\n const height = bounds.height + outset * 2;\n return (\n width > 0 &&\n height > 0 &&\n damage.width > 0 &&\n damage.height > 0 &&\n x < damage.x + damage.width &&\n x + width > damage.x &&\n y < damage.y + damage.height &&\n y + height > damage.y\n );\n}\n\nexport function createReplayMaskScratch(capacity = 0): ReplayMaskScratch {\n let selected = new Uint8Array(Math.max(1, capacity));\n let open = new Int32Array(Math.max(1, capacity));\n let openCount = 0;\n const output: number[] = [];\n const bounds = { x: 0, y: 0, width: 0, height: 0 };\n const transformed = { x: 0, y: 0, width: 0, height: 0 };\n let requiresFullReplay = false;\n let thresholdExceeded = false;\n let selectedForFrame = false;\n let selectionLimit: number | undefined;\n\n function ensure(count: number): void {\n if (selected.length >= count) return;\n let size = selected.length;\n while (size < count) size *= 2;\n selected = new Uint8Array(size);\n open = new Int32Array(size);\n }\n\n function selectIndex(index: number, count: number): boolean {\n if (selected[index] !== 0) return true;\n selected[index] = 1;\n output.push(index);\n if (selectionLimit !== undefined && output.length > selectionLimit) {\n thresholdExceeded = true;\n // An empty partial mask would clear the damaged region. Threshold is a\n // decline, just like an unknown bound, so retained surfaces must take\n // their existing full/direct path.\n requiresFullReplay = true;\n output.length = 0;\n selected.fill(0, 0, count);\n return false;\n }\n return true;\n }\n\n function finish<TTexture>(list: DrawList<TTexture>): ReplayMaskScratch {\n selectedForFrame = true;\n replayMaskFrames.set(scratch, {\n list,\n structuralRevision: list.structuralRevision,\n contentRevision: list.contentRevision,\n });\n return scratch;\n }\n\n const scratch: ReplayMaskScratch = {\n get count() {\n return output.length;\n },\n get requiresFullReplay() {\n return requiresFullReplay;\n },\n get thresholdExceeded() {\n return thresholdExceeded;\n },\n get selected() {\n return selectedForFrame;\n },\n [REPLAY_MASK_SCRATCH]: true,\n includes(index) {\n return index >= 0 && index < selected.length && selected[index] !== 0;\n },\n indices() {\n return output;\n },\n select(list, damage, options) {\n ensure(list.count);\n selected.fill(0, 0, list.count);\n output.length = 0;\n openCount = 0;\n requiresFullReplay = false;\n thresholdExceeded = false;\n selectedForFrame = false;\n selectionLimit = options?.maxCommands;\n if (\n selectionLimit !== undefined &&\n (!Number.isFinite(selectionLimit) || selectionLimit < 0)\n ) {\n requiresFullReplay = true;\n return finish(list);\n }\n if (selectionLimit !== undefined) {\n selectionLimit = Math.floor(selectionLimit);\n }\n const rasterOutset = options?.rasterOutset ?? 1;\n if (!Number.isFinite(rasterOutset) || rasterOutset < 0) {\n requiresFullReplay = true;\n return finish(list);\n }\n\n selection: for (let index = 0; index < list.count; index += 1) {\n const kind = list.kindAt(index);\n if (kind === DRAW_SCREEN_EFFECT || kind === DRAW_EXTERNAL_EFFECT) {\n requiresFullReplay = true;\n output.length = 0;\n selected.fill(0, 0, list.count);\n break;\n }\n if (kind === DRAW_CLIP_PUSH) {\n open[openCount] = index;\n openCount += 1;\n continue;\n }\n if (kind === DRAW_CLIP_POP) {\n if (openCount === 0) {\n requiresFullReplay = true;\n output.length = 0;\n selected.fill(0, 0, list.count);\n break;\n }\n openCount -= 1;\n const push = open[openCount];\n if (selected[push] !== 0 && !selectIndex(index, list.count)) break;\n continue;\n }\n const commandBounds = options?.boundsAt\n ? options.boundsAt(index, bounds)\n : commandDamageBounds(list, index, bounds);\n const mapped =\n commandBounds && options?.transform\n ? transformDamageRect(commandBounds, options.transform, transformed)\n : commandBounds;\n if (mapped === null && options?.unknownBounds !== \"select\") {\n requiresFullReplay = true;\n output.length = 0;\n selected.fill(0, 0, list.count);\n break;\n }\n if (mapped !== null && !isFiniteBounds(mapped)) {\n requiresFullReplay = true;\n output.length = 0;\n selected.fill(0, 0, list.count);\n break;\n }\n // Do not mutate `mapped`: a boundsAt provider may intentionally return\n // its stable cached object instead of filling `bounds`. Scalar math\n // keeps the final-coordinate expansion allocation-free and cache-safe.\n if (\n mapped !== null &&\n !boundsIntersectsDamage(mapped, damage, rasterOutset)\n ) {\n continue;\n }\n for (let depth = 0; depth < openCount; depth += 1) {\n if (!selectIndex(open[depth], list.count)) break selection;\n }\n if (!selectIndex(index, list.count)) break;\n }\n if (openCount !== 0 && !requiresFullReplay) {\n // A structural clip imbalance might be invisible in the selected tile\n // today, but a replay beginning from an empty clip state has no sound\n // way to preserve it. Decline to the direct path.\n requiresFullReplay = true;\n output.length = 0;\n selected.fill(0, 0, list.count);\n }\n return finish(list);\n },\n };\n return scratch;\n}\n\n/**\n * Select just the commands that can change `damage`, preserving all clip pushes\n * and pops needed to replay them from an empty clip stack. Unknown bounds are\n * selected conservatively. This is deliberately a mask rather than a copied\n * command list: all reads stay in the original retained arenas.\n */\nexport function createReplayMask<TTexture>(\n list: DrawList<TTexture>,\n damage: DamageRect,\n options?: ReplaySelectionOptions,\n): ReplayMaskScratch {\n return createReplayMaskScratch(list.count).select(list, damage, options);\n}\n","import type { QuadInstance } from \"./batcher\";\nimport {\n commandDamageBounds,\n createDamageRect,\n type DamageRect,\n} from \"./damage\";\nimport {\n BLEND_MIX,\n type BlendMode,\n createDrawListPatchView,\n DRAW_CLIP_POP,\n DRAW_CLIP_PUSH,\n DRAW_QUAD,\n type DrawList,\n} from \"./draw-list\";\nimport {\n createReplayMaskScratch,\n type ReplayMaskScratch,\n type ReplaySelectionOptions,\n} from \"./replay\";\n\n/** A maximal run that can stay in the quad executor without a painter-order\n * barrier. Texture/matrix slots deliberately are not included: those limits are\n * context-specific and the live batcher remains their authority. */\nexport interface CompiledBatchDescriptor {\n readonly start: number;\n readonly end: number;\n readonly blend: BlendMode;\n readonly clipDepth: number;\n}\n\nexport interface CompiledDrawListDiagnostics {\n planBuilds: number;\n structuralInvalidations: number;\n planReuses: number;\n /** CPU template ranges refreshed after safe command patches. */\n templateRangeUpdates: number;\n reusedSelections: number;\n reusedBatches: number;\n}\n\nexport interface CompiledRefreshResult {\n readonly rebuilt: boolean;\n readonly rangeUpdates: number;\n /** Reused storage listing only commands patched since the prior refresh. */\n readonly changedCommands: readonly number[];\n /** Increments on every structural/overflow/context plan rebuild. */\n readonly planGeneration: number;\n /** Current DrawList content revision represented by this plan. */\n readonly contentRevision: number;\n /** Revision a cached consumer must match before applying this delta. */\n readonly deltaBaseRevision: number;\n}\n\n/**\n * A retained, allocation-free planning view of a stable draw list. It never\n * owns GL objects: the executor's grow-only instance buffer remains the single\n * GPU allocation authority. The WebGL executor may cache these templates in\n * plan-keyed GPU buffers. Quad templates remove transform/source/tint decoding from replay;\n * all non-quad commands deliberately take the direct executor path.\n */\nexport interface CompiledDrawList<TTexture = unknown> {\n readonly list: DrawList<TTexture>;\n readonly batches: readonly CompiledBatchDescriptor[];\n readonly diagnostics: CompiledDrawListDiagnostics;\n refresh(): CompiledRefreshResult;\n invalidate(): void;\n /** Fill the batcher's reusable staging instance from a cached quad template. */\n fillQuad(\n index: number,\n textureWidth: number,\n textureHeight: number,\n out: QuadInstance,\n ): boolean;\n /** Fill `out` with a cached conservative bound, or return null for unknown. */\n commandBounds(index: number, out: DamageRect): DamageRect | null;\n /** Reuse caller-owned selection storage and cached bounds. */\n select(\n damage: DamageRect,\n scratch: ReplayMaskScratch,\n options?: ReplaySelectionOptions,\n ): ReplayMaskScratch;\n}\n\nconst TEMPLATE_FLOATS = 16;\nconst NO_TEMPLATE = -1;\n\nexport function compileDrawList<TTexture>(\n list: DrawList<TTexture>,\n): CompiledDrawList<TTexture> {\n let seenStructural = -1;\n let seenContent = -1;\n let templateOffsets = new Int32Array(0);\n let templates = new Float32Array(0);\n let bounds = new Float32Array(0);\n let knownBounds = new Uint8Array(0);\n let batchDescriptors: CompiledBatchDescriptor[] = [];\n let invalidated = false;\n let planGeneration = 0;\n let deltaBaseRevision = 0;\n const patchView = createDrawListPatchView();\n const diagnostics: CompiledDrawListDiagnostics = {\n planBuilds: 0,\n structuralInvalidations: 0,\n planReuses: 0,\n templateRangeUpdates: 0,\n reusedSelections: 0,\n reusedBatches: 0,\n };\n const selectionOptions: ReplaySelectionOptions = {\n boundsAt(index, out) {\n return plan.commandBounds(index, out);\n },\n };\n const boundsScratch = createDamageRect();\n const changedCommands: number[] = [];\n const refreshResult: {\n rebuilt: boolean;\n rangeUpdates: number;\n changedCommands: readonly number[];\n planGeneration: number;\n contentRevision: number;\n deltaBaseRevision: number;\n } = {\n rebuilt: false,\n rangeUpdates: 0,\n changedCommands,\n planGeneration: 0,\n contentRevision: 0,\n deltaBaseRevision: 0,\n };\n\n function updateBounds(index: number): void {\n const value = commandDamageBounds(list, index, boundsScratch);\n const at = index * 4;\n if (!value) {\n knownBounds[index] = 0;\n return;\n }\n knownBounds[index] = 1;\n bounds[at] = value.x;\n bounds[at + 1] = value.y;\n bounds[at + 2] = value.width;\n bounds[at + 3] = value.height;\n }\n\n function updateQuadTemplate(index: number): void {\n const target = templateOffsets[index];\n if (target === NO_TEMPLATE) return;\n const source = list.floatOffsetAt(index);\n const floats = list.floats;\n const m0 = floats[source];\n const m1 = floats[source + 1];\n const m2 = floats[source + 2];\n const m3 = floats[source + 3];\n const m4 = floats[source + 4];\n const m5 = floats[source + 5];\n const w = floats[source + 6];\n const h = floats[source + 7];\n templates[target] = m4;\n templates[target + 1] = m5;\n templates[target + 2] = m0 * w + m4;\n templates[target + 3] = m1 * w + m5;\n templates[target + 4] = m0 * w + m2 * h + m4;\n templates[target + 5] = m1 * w + m3 * h + m5;\n templates[target + 6] = m2 * h + m4;\n templates[target + 7] = m3 * h + m5;\n templates[target + 8] = floats[source + 8];\n templates[target + 9] = floats[source + 9];\n templates[target + 10] = floats[source + 10];\n templates[target + 11] = floats[source + 11];\n templates[target + 12] = floats[source + 12];\n templates[target + 13] = floats[source + 13];\n templates[target + 14] = floats[source + 14];\n templates[target + 15] = floats[source + 15];\n }\n\n function rebuild(): void {\n const count = list.count;\n templateOffsets = new Int32Array(count);\n templateOffsets.fill(NO_TEMPLATE);\n templates = new Float32Array(count * TEMPLATE_FLOATS);\n bounds = new Float32Array(count * 4);\n knownBounds = new Uint8Array(count);\n batchDescriptors = [];\n let templateCount = 0;\n let clipDepth = 0;\n let runStart = -1;\n let runBlend: BlendMode = BLEND_MIX;\n let runClipDepth = 0;\n const closeRun = (end: number): void => {\n if (runStart < 0) return;\n batchDescriptors.push({\n start: runStart,\n end,\n blend: runBlend,\n clipDepth: runClipDepth,\n });\n runStart = -1;\n };\n for (let index = 0; index < count; index += 1) {\n const kind = list.kindAt(index);\n updateBounds(index);\n if (kind === DRAW_QUAD) {\n const blend = list.ints[list.intOffsetAt(index)] as BlendMode;\n if (runStart < 0 || runBlend !== blend || runClipDepth !== clipDepth) {\n closeRun(index);\n runStart = index;\n runBlend = blend;\n runClipDepth = clipDepth;\n }\n templateOffsets[index] = templateCount * TEMPLATE_FLOATS;\n templateCount += 1;\n updateQuadTemplate(index);\n } else {\n closeRun(index);\n if (kind === DRAW_CLIP_PUSH) clipDepth += 1;\n else if (kind === DRAW_CLIP_POP) clipDepth = Math.max(0, clipDepth - 1);\n }\n }\n closeRun(count);\n templates = templates.subarray(0, templateCount * TEMPLATE_FLOATS);\n seenStructural = list.structuralRevision;\n seenContent = list.contentRevision;\n deltaBaseRevision = seenContent;\n planGeneration += 1;\n invalidated = false;\n diagnostics.planBuilds += 1;\n }\n\n const plan: CompiledDrawList<TTexture> = {\n list,\n get batches() {\n return batchDescriptors;\n },\n diagnostics,\n refresh() {\n if (invalidated || seenStructural !== list.structuralRevision) {\n rebuild();\n changedCommands.length = 0;\n refreshResult.rebuilt = true;\n refreshResult.rangeUpdates = 0;\n refreshResult.planGeneration = planGeneration;\n refreshResult.contentRevision = seenContent;\n refreshResult.deltaBaseRevision = deltaBaseRevision;\n return refreshResult;\n }\n if (seenContent === list.contentRevision) {\n diagnostics.planReuses += 1;\n diagnostics.reusedBatches += batchDescriptors.length;\n refreshResult.rebuilt = false;\n refreshResult.rangeUpdates = 0;\n refreshResult.planGeneration = planGeneration;\n refreshResult.contentRevision = seenContent;\n refreshResult.deltaBaseRevision = deltaBaseRevision;\n return refreshResult;\n }\n const patches = list.readPatchesSince(seenContent, patchView);\n if (patches.overflowed) {\n rebuild();\n changedCommands.length = 0;\n refreshResult.rebuilt = true;\n refreshResult.rangeUpdates = 0;\n refreshResult.planGeneration = planGeneration;\n refreshResult.contentRevision = seenContent;\n refreshResult.deltaBaseRevision = deltaBaseRevision;\n return refreshResult;\n }\n let updates = 0;\n changedCommands.length = 0;\n for (let patch = 0; patch < patches.indices.length; patch += 1) {\n const index = patches.indices[patch];\n updateBounds(index);\n updateQuadTemplate(index);\n updates += 1;\n changedCommands.push(index);\n }\n deltaBaseRevision = seenContent;\n seenContent = list.contentRevision;\n diagnostics.planReuses += 1;\n diagnostics.reusedBatches += batchDescriptors.length;\n diagnostics.templateRangeUpdates += updates;\n refreshResult.rebuilt = false;\n refreshResult.rangeUpdates = updates;\n refreshResult.planGeneration = planGeneration;\n refreshResult.contentRevision = seenContent;\n refreshResult.deltaBaseRevision = deltaBaseRevision;\n return refreshResult;\n },\n invalidate() {\n invalidated = true;\n diagnostics.structuralInvalidations += 1;\n },\n fillQuad(index, textureWidth, textureHeight, out) {\n const at = templateOffsets[index];\n if (at === NO_TEMPLATE) return false;\n out.x0 = templates[at];\n out.y0 = templates[at + 1];\n out.x1 = templates[at + 2];\n out.y1 = templates[at + 3];\n out.x2 = templates[at + 4];\n out.y2 = templates[at + 5];\n out.x3 = templates[at + 6];\n out.y3 = templates[at + 7];\n const invWidth = 1 / Math.max(1, textureWidth);\n const invHeight = 1 / Math.max(1, textureHeight);\n out.u0 = templates[at + 8] * invWidth;\n out.v0 = templates[at + 9] * invHeight;\n out.uSpan = templates[at + 10] * invWidth;\n out.vSpan = templates[at + 11] * invHeight;\n out.r = templates[at + 12];\n out.g = templates[at + 13];\n out.b = templates[at + 14];\n out.a = templates[at + 15];\n const flags = list.ints[list.intOffsetAt(index) + 1];\n if ((flags & 1) !== 0) {\n out.u0 += out.uSpan;\n out.uSpan = -out.uSpan;\n }\n if ((flags & 2) !== 0) {\n out.v0 += out.vSpan;\n out.vSpan = -out.vSpan;\n }\n return true;\n },\n commandBounds(index, out) {\n if (index < 0 || index >= list.count || knownBounds[index] === 0)\n return null;\n const at = index * 4;\n out.x = bounds[at];\n out.y = bounds[at + 1];\n out.width = bounds[at + 2];\n out.height = bounds[at + 3];\n return out;\n },\n select(damage, scratch, options) {\n plan.refresh();\n diagnostics.reusedSelections += 1;\n selectionOptions.transform = options?.transform;\n selectionOptions.rasterOutset = options?.rasterOutset;\n selectionOptions.maxCommands = options?.maxCommands;\n selectionOptions.unknownBounds = options?.unknownBounds;\n return scratch.select(list, damage, selectionOptions);\n },\n };\n rebuild();\n return plan;\n}\n\n/** Convenience for consumers with no existing scratch. Retained loops should\n * create one scratch once and call `plan.select` instead. */\nexport function createCompiledReplayMask<TTexture>(\n plan: CompiledDrawList<TTexture>,\n damage: DamageRect,\n options?: ReplaySelectionOptions,\n): ReplayMaskScratch {\n return plan.select(damage, createReplayMaskScratch(plan.list.count), options);\n}\n","/**\n * Nine-patch band algebra: one `DRAW_NINE_PATCH` command -> up to nine plain\n * quads. Pure (no GL, no state), so the geometry can be unit-tested on its own —\n * it is the part of the executor most likely to be wrong by half a pixel and the\n * part least able to say so on screen.\n *\n * WHERE THE RULES COME FROM. Godot does not expand a nine-patch into quads at\n * all: it draws ONE quad and remaps each fragment's coordinate with\n * `map_ninepatch_axis` (`drivers/gles3/shaders/canvas.glsl`). That function is\n * this module's specification, per axis:\n *\n * - `pixel < margin_begin` -> source coordinate `pixel`, i.e. the leading corner\n * band is copied 1:1 at its native pixel size;\n * - `pixel >= draw_size - margin_end` -> source `tex_size - (draw_size - pixel)`,\n * the trailing corner band, also 1:1;\n * - otherwise the centre band, stretched from `[margin_begin, tex_size -\n * margin_end]` onto `[margin_begin, draw_size - margin_end]`.\n *\n * Expanding that into rects gives identical pixels for the STRETCH axis mode and\n * costs a handful of extra quads that batch with everything else — much cheaper\n * than the branchy per-fragment remap, and it keeps one shader for every command\n * kind. Godot's TILE / TILE_FIT modes are NOT reachable from the draw-list IR\n * (which carries no axis-stretch mode), so STRETCH — Godot's default — is what\n * this implements.\n *\n * DEGENERATE MARGINS FOLLOW THE SAME SPECIFICATION rather than a clamp. Note the\n * order of the branches above: when the two margins together exceed the\n * destination, the LEADING band wins the overlap and the trailing band keeps only\n * what is left. So this module truncates rather than rescaling the corners, which\n * is what the shader does. Bands that come out empty are dropped, so a patch\n * squeezed below its own margins expands to fewer than nine quads (down to one,\n * or to none at all when it has no area).\n *\n * A SOURCE centre that is empty or inverted (the margins meet or cross inside the\n * texture region) is dropped too. Godot's remap would produce a reversed source\n * range there — a mirrored smear — which is nobody's intent.\n */\n\n/** One expanded band: a destination rect in the command's LOCAL space (before the\n * quad's affine `m`), and the source rect it samples, in page pixels. */\nexport interface NinePatchBand {\n /** Destination, local space: x in `[0, w]`, y in `[0, h]`. */\n dstX: number;\n dstY: number;\n dstW: number;\n dstH: number;\n /** Source, page pixels — an absolute rect on the page, not relative to the region. */\n srcX: number;\n srcY: number;\n srcW: number;\n srcH: number;\n}\n\n/** The nine-patch inputs, matching `NinePatchView`'s fields. */\nexport interface NinePatchGeometry {\n /** Destination size in local units. */\n w: number;\n h: number;\n /** The patch REGION on the page, in page pixels. */\n srcX: number;\n srcY: number;\n srcW: number;\n srcH: number;\n /** Insets into the region, page pixels (Godot `patch_margin_*`). */\n marginLeft: number;\n marginTop: number;\n marginRight: number;\n marginBottom: number;\n}\n\nexport function createNinePatchBand(): NinePatchBand {\n return {\n dstX: 0,\n dstY: 0,\n dstW: 0,\n dstH: 0,\n srcX: 0,\n srcY: 0,\n srcW: 0,\n srcH: 0,\n };\n}\n\n/** A reusable output buffer: nine bands is the hard maximum, so it never grows. */\nexport function createNinePatchBands(): NinePatchBand[] {\n return Array.from({ length: 9 }, createNinePatchBand);\n}\n\n/** One axis's up-to-three spans: destination `[start, end]` and the source\n * `[start, end]` (relative to the region's origin) each maps from. */\ninterface AxisBands {\n dst: [number, number][];\n src: [number, number][];\n}\n\nfunction createAxisBands(): AxisBands {\n return {\n dst: [\n [0, 0],\n [0, 0],\n [0, 0],\n ],\n src: [\n [0, 0],\n [0, 0],\n [0, 0],\n ],\n };\n}\n\n// Module-scoped scratch, so an expansion allocates nothing. Safe because\n// `splitAxis` is only ever called from `expandNinePatch`, synchronously, once per\n// axis, and the values are consumed before the next call.\nconst H_BANDS = createAxisBands();\nconst V_BANDS = createAxisBands();\n\n/**\n * Split ONE axis into its leading / centre / trailing spans, in the shader's\n * branch order. `size` is the destination extent, `texSize` the source extent,\n * `begin`/`end` the two margins. Writes into `out` and returns the number of\n * non-empty spans.\n */\nfunction splitAxis(\n size: number,\n texSize: number,\n begin: number,\n end: number,\n out: AxisBands,\n): number {\n const marginBegin = Math.max(0, begin);\n const marginEnd = Math.max(0, end);\n // `pixel < margin_begin` — truncated by the destination, never past it.\n const leadEnd = Math.min(marginBegin, Math.max(0, size));\n // `pixel >= draw_size - margin_end`, but the leading branch was tested FIRST,\n // so the trailing band starts no earlier than where the leading one ended.\n const trailStart = Math.max(leadEnd, size - marginEnd);\n\n let count = 0;\n // Leading corner: 1:1 from the region's own start.\n if (leadEnd > 0) {\n out.dst[count][0] = 0;\n out.dst[count][1] = leadEnd;\n out.src[count][0] = 0;\n out.src[count][1] = Math.min(leadEnd, texSize);\n count += 1;\n }\n // Centre: the region's middle stretched over the destination's middle. Dropped\n // when either side of that mapping is empty or inverted.\n const centreSrcBegin = marginBegin;\n const centreSrcEnd = texSize - marginEnd;\n if (trailStart > leadEnd && centreSrcEnd > centreSrcBegin) {\n out.dst[count][0] = leadEnd;\n out.dst[count][1] = trailStart;\n out.src[count][0] = centreSrcBegin;\n out.src[count][1] = centreSrcEnd;\n count += 1;\n }\n // Trailing corner: 1:1, measured back from the region's own end.\n if (size > trailStart) {\n const span = size - trailStart;\n out.dst[count][0] = trailStart;\n out.dst[count][1] = size;\n out.src[count][0] = Math.max(0, texSize - span);\n out.src[count][1] = texSize;\n count += 1;\n }\n return count;\n}\n\n/**\n * Expand a nine-patch into its bands, filling `out` (use\n * {@link createNinePatchBands}, which is always big enough) and returning how\n * many are live. `out` entries past the return value are stale and must not be\n * read.\n *\n * Returns 0 for a patch with no area — a zero-size destination or a zero-size\n * region draws nothing at all, which is not the same as drawing one empty band.\n */\nexport function expandNinePatch(\n patch: NinePatchGeometry,\n out: NinePatchBand[],\n): number {\n const { w, h, srcW, srcH } = patch;\n if (!(w > 0) || !(h > 0) || !(srcW > 0) || !(srcH > 0)) return 0;\n\n const columns = splitAxis(\n w,\n srcW,\n patch.marginLeft,\n patch.marginRight,\n H_BANDS,\n );\n const rows = splitAxis(h, srcH, patch.marginTop, patch.marginBottom, V_BANDS);\n\n let count = 0;\n for (let row = 0; row < rows; row += 1) {\n const [dstTop, dstBottom] = V_BANDS.dst[row];\n const [srcTop, srcBottom] = V_BANDS.src[row];\n for (let column = 0; column < columns; column += 1) {\n const [dstLeft, dstRight] = H_BANDS.dst[column];\n const [srcLeft, srcRight] = H_BANDS.src[column];\n const band = out[count];\n band.dstX = dstLeft;\n band.dstY = dstTop;\n band.dstW = dstRight - dstLeft;\n band.dstH = dstBottom - dstTop;\n band.srcX = patch.srcX + srcLeft;\n band.srcY = patch.srcY + srcTop;\n band.srcW = srcRight - srcLeft;\n band.srcH = srcBottom - srcTop;\n count += 1;\n }\n }\n return count;\n}\n","/**\n * Constant-width polyline -> quads, so a `DRAW_POLYLINE` goes through the SAME\n * instance buffer, the same shader and the same batch as everything else instead\n * of forcing a second program and a mid-frame draw break.\n *\n * That is possible because the batcher's instance carries four EXPLICIT corners\n * rather than an affine basis (see `./batcher`): a quad instance is any\n * quadrilateral, and a quadrilateral with its last two corners coincident is a\n * triangle. So a stroke is emitted as\n *\n * - one parallelogram per segment (the segment offset by ±width/2 along its\n * normal), and\n * - one triangle per interior vertex, filling the notch on the OUTSIDE of the\n * turn.\n *\n * JOINS ARE BEVEL, CAPS ARE BUTT — the first pass the wave-1 brief allows, and a\n * deliberate choice rather than an oversight:\n *\n * - a MITER join needs the two segment edges extended to their intersection,\n * which runs away to infinity as the turn approaches a reversal and therefore\n * needs a miter limit that itself falls back to... a bevel. Two code paths for\n * a shape that differs from the bevel only inside a `width/2` disc.\n * - a ROUND join needs an arc, i.e. a fan of triangles whose count depends on the\n * turn angle and the on-screen width — the one thing in this file that would\n * make its output size unpredictable.\n *\n * The bevel differs from both only within half a stroke width of a vertex, and\n * the measured population of polylines in the recorded scenes this executor was\n * sized against is ZERO (the paint-source mix is texture/text/particles/spine/\n * solid). Upgrading to round joins is local to this file: emit a fan instead of\n * the single wedge triangle in the interior-vertex loop.\n *\n * Self-overlap: at a sharp turn the two segment parallelograms overlap near the\n * vertex, so a translucent stroke double-composites there. Godot's own\n * `draw_polyline` has the same artefact; fixing it needs a stencil or a\n * single-pass SDF, neither of which belongs in wave 1.\n */\n\n/** Floats per emitted quad: four `(x, y)` corners in draw-list local space. */\nexport const POLYLINE_QUAD_FLOATS = 8;\n\n/**\n * The most quads a `pointCount`-point stroke can produce: one per segment plus\n * one per interior vertex. Sizes a caller's output buffer exactly.\n */\nexport function polylineQuadCapacity(pointCount: number): number {\n if (pointCount < 2) return 0;\n return pointCount - 1 + Math.max(0, pointCount - 2);\n}\n\n/**\n * Tessellate `points` (flattened `x, y, x, y, …`, the draw-list's own layout)\n * into quads, writing `POLYLINE_QUAD_FLOATS` floats per quad into `out` from\n * `outOffset`. Returns the number of quads written.\n *\n * Corners are written in the batcher's unit-square order — `(0,0)`, `(1,0)`,\n * `(1,1)`, `(0,1)` — so a triangle is spelled by repeating the last corner.\n *\n * Zero-length segments are skipped (they have no direction to offset along, and\n * a duplicated point is a common artefact of a resampled path); a vertex whose\n * incoming or outgoing segment was skipped gets no join wedge, because there is\n * no notch to fill.\n */\nexport function expandPolyline(\n points: ArrayLike<number>,\n pointCount: number,\n width: number,\n out: Float32Array,\n outOffset = 0,\n): number {\n const half = width / 2;\n if (pointCount < 2 || !(half > 0)) return 0;\n\n let at = outOffset;\n let quads = 0;\n // The previous LIVE segment's unit normal, or null when there was none (start\n // of the stroke, or the previous segment was degenerate).\n let previousNormalX = 0;\n let previousNormalY = 0;\n let hasPrevious = false;\n let previousDirX = 0;\n let previousDirY = 0;\n\n for (let i = 0; i + 1 < pointCount; i += 1) {\n const ax = points[i * 2];\n const ay = points[i * 2 + 1];\n const bx = points[i * 2 + 2];\n const by = points[i * 2 + 3];\n const dx = bx - ax;\n const dy = by - ay;\n const length = Math.hypot(dx, dy);\n if (!(length > 0)) {\n hasPrevious = false;\n continue;\n }\n const dirX = dx / length;\n const dirY = dy / length;\n // The LEFT normal (the direction rotated a quarter turn), scaled to half the\n // stroke width, so `±normal` are the two edges of this segment.\n const normalX = -dirY * half;\n const normalY = dirX * half;\n\n if (hasPrevious) {\n // The notch sits on the OUTSIDE of the turn: `cross > 0` is a turn towards\n // the left normal, so the gap opens on `-normal`, and vice versa.\n const cross = previousDirX * dirY - previousDirY * dirX;\n if (cross !== 0) {\n const side = cross > 0 ? -1 : 1;\n // A triangle: the vertex, and the two segment edges that end/start on the\n // outside of the turn. Third corner repeated — see the module note.\n out[at] = ax;\n out[at + 1] = ay;\n out[at + 2] = ax + previousNormalX * side;\n out[at + 3] = ay + previousNormalY * side;\n out[at + 4] = ax + normalX * side;\n out[at + 5] = ay + normalY * side;\n out[at + 6] = ax + normalX * side;\n out[at + 7] = ay + normalY * side;\n at += POLYLINE_QUAD_FLOATS;\n quads += 1;\n }\n }\n\n out[at] = ax + normalX;\n out[at + 1] = ay + normalY;\n out[at + 2] = bx + normalX;\n out[at + 3] = by + normalY;\n out[at + 4] = bx - normalX;\n out[at + 5] = by - normalY;\n out[at + 6] = ax - normalX;\n out[at + 7] = ay - normalY;\n at += POLYLINE_QUAD_FLOATS;\n quads += 1;\n\n previousNormalX = normalX;\n previousNormalY = normalY;\n previousDirX = dirX;\n previousDirY = dirY;\n hasPrevious = true;\n }\n\n return quads;\n}\n","import {\n type Batch,\n type BatchFlushReason,\n COLOR_MATRIX_FLOATS,\n createQuadBatcher,\n createQuadInstance,\n INSTANCE_COLOR_OFFSET,\n INSTANCE_CORNERS_OFFSET,\n INSTANCE_FLOATS,\n INSTANCE_SLOTS_OFFSET,\n INSTANCE_UV_OFFSET,\n MAX_TEXTURE_SLOTS,\n type QuadBatcher,\n} from \"./batcher\";\nimport {\n type ClipStack,\n createClipStack,\n createScissorBox,\n type PixelTransform,\n type ScissorBox,\n} from \"./clip-stack\";\nimport { colorMatricesEqual, IDENTITY_COLOR_MATRIX } from \"./color\";\nimport type { CompiledDrawList } from \"./compiled-draw-list\";\nimport type { DamageRect } from \"./damage\";\nimport {\n BLEND_ADD,\n BLEND_MIX,\n BLEND_MUL,\n BLEND_SUB,\n type BlendMode,\n createClipRectView,\n createGlyphsView,\n createNinePatchView,\n createPolylineView,\n createQuadView,\n createTexturedMeshView,\n DRAW_CLIP_POP,\n DRAW_CLIP_PUSH,\n DRAW_EXTERNAL_EFFECT,\n DRAW_GLYPHS,\n DRAW_NINE_PATCH,\n DRAW_POLYLINE,\n DRAW_QUAD,\n DRAW_SCREEN_EFFECT,\n DRAW_TEXTURED_MESH,\n type DrawList,\n type GlyphsView,\n} from \"./draw-list\";\nimport type { GlyphPass } from \"./glyph-pass\";\nimport {\n createNinePatchBands,\n expandNinePatch,\n type NinePatchBand,\n} from \"./nine-patch\";\nimport { expandPolyline, POLYLINE_QUAD_FLOATS } from \"./polyline\";\nimport type { StageProjection } from \"./present\";\nimport type { CommandMask } from \"./replay\";\nimport type { CanvasTextureHandle } from \"./textures\";\n\n/**\n * The WebGL2 executor: a draw list in, GL draws out.\n *\n * ONE PROGRAM, ONE VERTEX FORMAT, ONE BUFFER for the whole scene. Every command\n * kind is reduced to the same instanced quad — a sprite is one, a nine-patch is\n * up to nine (`./nine-patch`), a polyline is one per segment plus one per join\n * (`./polyline`), a solid fill is one sampling a 1x1 white texel. That is what\n * lets `./batcher` merge across command kinds instead of only within them, and it\n * is why there is no \"solid\" shader, no \"line\" shader and no per-kind draw path\n * to keep in sync.\n *\n * WHAT BREAKS A BATCH, and what deliberately does not. GL state that lives on the\n * DRAW rather than on the instance has to break one: the blend mode, the scissor\n * box, and the rounded-clip uniforms. Everything else is per-instance data —\n * transform, source rect, tint, texture (an index into the batch's slot table),\n * colour matrix (an index into the batch's uniform table) — so it costs a few\n * floats instead of a draw call. See `./batcher`'s note for the measurement that\n * decided this.\n *\n * ORDER OF OPERATIONS AROUND A STATE CHANGE, which is the one genuinely subtle\n * thing in this file. A flush DRAWS with whatever GL state is currently set, so\n * the pending batch must be flushed BEFORE the new state is applied, never after.\n * Every state change here therefore reads: tell the batcher (which flushes the\n * old batch under the old GL state), then touch GL. Doing it the other way round\n * is invisible in a screenshot of a static scene and produces a one-frame-late\n * clip the moment anything moves.\n *\n * THE ONE COMMAND THAT IS NOT A QUAD. `glyphs` runs are outlines evaluated per fragment, which no\n * amount of instancing turns into the program above, so they are delegated to an injected\n * {@link GlyphPass} (`./glyph-pass`) and cost one draw call each. That makes them the only place\n * this file hands the context to somebody else mid-frame, and the order-of-operations rule above is\n * exactly what governs it: flush, then the pass, then rebind. `emitGlyphsCommand` is where that is\n * written down.\n *\n * THE ALPHA CONTRACT, end to end: textures upload premultiplied (`./textures`),\n * tints in the draw list are premultiplied, the fragment emits `vec4(rgb*a, a)`,\n * the MIX blend is `(ONE, ONE_MINUS_SRC_ALPHA)`, and the canvas is declared\n * `premultipliedAlpha: true` (`./present`). Any one of those five flipped on its\n * own is silent — nothing errors, the picture is just wrong — which is why they\n * are named together here.\n */\n\n/** A texture handle the executor can draw: the GL object and the size its source\n * rects are measured against. `CanvasTextureHandle` satisfies it. */\nexport type ExecutorTexture = CanvasTextureHandle;\n\n/** GL blend state for a Godot blend mode, as ENUM NAMES so the mapping is pure\n * and unit-testable (the same trick `html`'s `blendFactorsFor` uses). */\nexport interface BlendState {\n equationRgb: \"FUNC_ADD\" | \"FUNC_REVERSE_SUBTRACT\";\n equationAlpha: \"FUNC_ADD\";\n srcRgb: \"ONE\" | \"DST_COLOR\";\n dstRgb: \"ONE\" | \"ZERO\" | \"ONE_MINUS_SRC_ALPHA\";\n srcAlpha: \"ONE\" | \"DST_ALPHA\";\n dstAlpha: \"ONE\" | \"ZERO\" | \"ONE_MINUS_SRC_ALPHA\";\n}\n\nconst BLEND_STATES: Record<BlendMode, BlendState> = {\n // MIX, in its PREMULTIPLIED form: the source already carries `rgb*a`, so it\n // contributes unscaled and the destination is attenuated by the coverage the\n // source claims. Algebraically identical to `SRC_ALPHA / ONE_MINUS_SRC_ALPHA`\n // over a STRAIGHT source — the choice between the two is not arithmetic, it is\n // which contract the canvas is declared under.\n [BLEND_MIX]: {\n equationRgb: \"FUNC_ADD\",\n equationAlpha: \"FUNC_ADD\",\n srcRgb: \"ONE\",\n dstRgb: \"ONE_MINUS_SRC_ALPHA\",\n srcAlpha: \"ONE\",\n dstAlpha: \"ONE_MINUS_SRC_ALPHA\",\n },\n // ADD: light adds and nothing is attenuated. Coverage accumulates too, so a\n // stack of glows still reports itself as covering the pixel to the page.\n [BLEND_ADD]: {\n equationRgb: \"FUNC_ADD\",\n equationAlpha: \"FUNC_ADD\",\n srcRgb: \"ONE\",\n dstRgb: \"ONE\",\n srcAlpha: \"ONE\",\n dstAlpha: \"ONE\",\n },\n // SUB: `dst - src` on COLOUR only. The alpha equation stays `FUNC_ADD` — a\n // reverse-subtract on alpha would eat the destination's coverage as well, so a\n // dark smoke sprite would punch a transparent hole in the scene instead of\n // darkening it.\n [BLEND_SUB]: {\n equationRgb: \"FUNC_REVERSE_SUBTRACT\",\n equationAlpha: \"FUNC_ADD\",\n srcRgb: \"ONE\",\n dstRgb: \"ONE\",\n srcAlpha: \"ONE\",\n dstAlpha: \"ONE\",\n },\n // MUL: the destination times the source, with no additive term at all — hence\n // the ZERO destination factors. Separate alpha so coverage multiplies too.\n [BLEND_MUL]: {\n equationRgb: \"FUNC_ADD\",\n equationAlpha: \"FUNC_ADD\",\n srcRgb: \"DST_COLOR\",\n dstRgb: \"ZERO\",\n srcAlpha: \"DST_ALPHA\",\n dstAlpha: \"ZERO\",\n },\n};\n\n/** The GL blend state a Godot `CanvasItemMaterial.BlendMode` maps to. */\nexport function blendStateFor(blend: BlendMode): BlendState {\n return BLEND_STATES[blend] ?? BLEND_STATES[BLEND_MIX];\n}\n\nexport interface ExecutorStats {\n /** Draw-list commands read. */\n commands: number;\n /** Quad instances pushed, including expanded nine-patch bands and stroke quads. */\n quads: number;\n /** `drawArraysInstanced` calls — the number this executor exists to keep small. */\n batches: number;\n /** Texture-unit binds summed over batches. */\n textureBinds: number;\n /** Times the scissor box actually changed. */\n scissorChanges: number;\n /** Times GL blend state actually changed. */\n blendChanges: number;\n ninePatches: number;\n ninePatchQuads: number;\n polylines: number;\n polylineQuads: number;\n /** Indexed textured-mesh commands executed. */\n texturedMeshes: number;\n /** Triangle-list primitives submitted by textured meshes. */\n texturedMeshTriangles: number;\n /** `drawElements` calls issued by textured meshes. */\n texturedMeshDrawCalls: number;\n /** `glyphs` commands handed to the installed {@link CanvasExecutorOptions.glyphs} pass. */\n glyphRuns: number;\n /** Glyphs the pass reported drawing, summed over runs. Excludes ones it skipped. */\n glyphs: number;\n /** Draw calls the pass reported. One per run, for the reason {@link GlyphPass.drawRun} gives. */\n glyphDrawCalls: number;\n glyphRunBatches: number;\n glyphRunBatchFallbacks: number;\n /**\n * `glyphs` commands seen with NO pass installed.\n *\n * A NAMED NO-OP RATHER THAN A SILENT ONE. A list carrying text into an executor that cannot draw\n * text is a wiring mistake — the consumer forgot to pass `glyphs` — and its symptom is a page\n * that renders perfectly except for having no words on it. That is exactly the kind of failure\n * a screenshot review passes and a counter catches.\n */\n glyphRunsDropped: number;\n /** Screen-dependent passes executed at their recorded painter position. */\n screenEffects: number;\n /** Required screen passes that refused or failed at runtime. */\n screenEffectFailures: number;\n /** Direct external passes executed at their recorded painter position. */\n externalEffects: number;\n /** Required direct external passes that refused or failed at runtime. */\n externalEffectFailures: number;\n /** Clip rects that could not be an exact scissor (see `./clip-stack`). */\n rotatedClipFallbacks: number;\n /** `clipPop`s with nothing open — a malformed list, survived rather than thrown. */\n unbalancedClipPops: number;\n /**\n * Commands whose kind this executor does not handle.\n *\n * The dispatch switch had no `default` for its first five kinds, so a sixth added to the IR fell\n * through it silently while still counting in {@link ExecutorStats.commands} — a frame missing\n * every command of the new kind, reported as a frame that drew everything.\n */\n unknownCommands: number;\n /** Largest single batch, in instances. */\n maxBatchQuads: number;\n /** Why batches ended, so a regression in batching says which axis moved. */\n flushes: Record<BatchFlushReason, number>;\n /** Per-execution compiled-plan diagnostics; direct frames leave these zero. */\n compiledPlanBuilds: number;\n compiledPlanReuses: number;\n compiledTemplateRangeUpdates: number;\n reusedSelections: number;\n reusedBatches: number;\n compiledGpuFullUploads: number;\n compiledGpuRangeUploads: number;\n compiledCachedDrawCalls: number;\n}\n\nexport interface CanvasExecutorOptions {\n gl: WebGL2RenderingContext;\n /** The 1x1 white texel untextured quads sample. Defaults to one the executor\n * makes and owns; pass `CanvasTextureCache.white()` to share the cache's. */\n white?: ExecutorTexture;\n /**\n * Who draws `glyphs` commands. Omitted means the executor cannot draw text.\n *\n * INJECTED, exactly like {@link CanvasExecutorOptions.white}, and for the reason\n * {@link GlyphPass} states: the only implementation is backed by a glyph renderer that a scene\n * with no text should not have to load, and the main barrel's export surface is mirrored by hand\n * downstream. Import `@godot-scene-web/canvas/glyphs` and pass one when the scene has text.\n *\n * Leaving it out is not an error — plenty of draw lists have no glyph runs at all — but a list\n * that DOES carry one then counts it in {@link ExecutorStats.glyphRunsDropped} rather than\n * skipping it in silence.\n */\n glyphs?: GlyphPass;\n /**\n * Opt-in only: combine physically adjacent glyph commands when the injected pass exposes\n * `drawRuns`. This never crosses a clip, a command-mask gap, or any non-glyph command.\n */\n batchAdjacentGlyphRuns?: boolean;\n /** Texture units per batch. Clamped to the context's `MAX_TEXTURE_IMAGE_UNITS`\n * and to {@link MAX_TEXTURE_SLOTS}. */\n maxTextureSlots?: number;\n /** Colour-matrix slots per batch, including the identity at slot 0. */\n maxColorMatrices?: number;\n /** Initial instance-arena capacity, in quads. */\n quadCapacity?: number;\n}\n\nexport interface ExecuteOptions {\n /** Clear the framebuffer to transparent black before drawing. Default true. */\n clear?: boolean;\n /**\n * Replacement clear colour for a full-frame stage pass. It is intentionally\n * an execute option rather than a global GL mutation: retained FBO replays\n * keep their transparent clear while an opaque presenter can establish its\n * base pixels without a second fullscreen draw.\n */\n clearColor?: readonly [number, number, number, number];\n /**\n * Restrict both clearing and drawing to this top-left framebuffer-pixel\n * rectangle. It is the retained-surface seam, but is also useful to any\n * caller rendering into its own FBO; omitted keeps the direct full-frame\n * executor path byte-for-byte in shape.\n */\n damage?: DamageRect;\n /** Ordered replay selection. Clip closures are supplied by `createReplayMask`.\n * Omitted means every command is executed, as direct frames always have. */\n commandMask?: CommandMask;\n /** Opt-in retained plan. Omitted direct frames do no compilation work. */\n compiled?: CompiledDrawList<ExecutorTexture | null>;\n}\n\nexport interface CanvasExecutor {\n readonly gl: WebGL2RenderingContext;\n readonly stats: ExecutorStats;\n /** Texture units a batch can hold on THIS context. */\n readonly maxTextureSlots: number;\n /** Build the program and buffers now, off whatever critical path the caller\n * cares about. `execute` does it lazily otherwise — and reading a shader's\n * compile status BLOCKS on the driver (~100-250 ms on a phone), so paying it\n * during the first frame is a visible hitch. */\n warmUp(): boolean;\n /** Draw one frame. Returns false when the program could not be built. */\n execute(\n list: DrawList<ExecutorTexture | null>,\n projection: StageProjection,\n options?: ExecuteOptions,\n ): boolean;\n /** Release executor-owned cached GPU buffers for one compiled plan. */\n releaseCompiled(plan: CompiledDrawList<ExecutorTexture | null>): void;\n /** The context is GONE: drop every GL object without calling into GL. The next\n * `execute` rebuilds them. */\n invalidate(): void;\n /** Delete every GL object this executor owns. */\n dispose(): void;\n}\n\ninterface Program {\n program: WebGLProgram;\n vao: WebGLVertexArrayObject;\n cornerBuffer: WebGLBuffer;\n instanceBuffer: WebGLBuffer;\n instanceBytes: number;\n uProjection: WebGLUniformLocation | null;\n uColorMatrices: WebGLUniformLocation | null;\n uRoundedRect: WebGLUniformLocation | null;\n uRoundedRadius: WebGLUniformLocation | null;\n}\n\ninterface CachedGpuRun {\n start: number;\n end: number;\n blend: BlendMode;\n commands: Int32Array;\n textures: ExecutorTexture[];\n dimensions: Int32Array;\n itemsByTexture: number[][];\n colorMatrices: Float32Array;\n colorMatrixCount: number;\n instances: Float32Array;\n buffer: WebGLBuffer;\n vao: WebGLVertexArrayObject;\n}\n\ninterface CachedGpuPlan {\n plan: CompiledDrawList<ExecutorTexture | null>;\n generation: number;\n contentRevision: number;\n runs: CachedGpuRun[];\n runsAt: (CachedGpuRun | null)[];\n runsForCommand: (CachedGpuRun | null)[];\n itemsForCommand: Int32Array;\n}\n\n/** The deliberately separate program for indexed triangle meshes. Meshes are\n * not coerced into instanced quads: arbitrary topology needs indexed triangles\n * and per-vertex UV interpolation. */\ninterface MeshProgram {\n program: WebGLProgram;\n vao: WebGLVertexArrayObject;\n vertexBuffer: WebGLBuffer;\n indexBuffer: WebGLBuffer;\n vertexBytes: number;\n indexBytes: number;\n uProjection: WebGLUniformLocation | null;\n uTint: WebGLUniformLocation | null;\n uTexture: WebGLUniformLocation | null;\n}\n\nconst VERTEX_SRC = `#version 300 es\nlayout(location = 0) in vec2 a_corner; // unit-square corner, see INSTANCE_CORNERS_OFFSET\nlayout(location = 1) in vec4 a_p01; // p0 (0,0), p1 (1,0)\nlayout(location = 2) in vec4 a_p23; // p2 (1,1), p3 (0,1)\nlayout(location = 3) in vec4 a_uv; // u0, v0, uSpan, vSpan\nlayout(location = 4) in vec4 a_color; // PREMULTIPLIED tint\nlayout(location = 5) in vec2 a_slots; // texture slot, colour-matrix slot\nuniform vec4 u_projection; // design -> clip: scale.xy, translate.xy\nout vec2 v_uv;\nout vec4 v_color;\nout vec2 v_design;\nflat out int v_texture;\nflat out int v_matrix;\nvoid main() {\n // BILINEAR across four explicit corners rather than an affine basis: see the\n // note in ./batcher. For the affine case (every sprite) this is exactly the\n // affine map; for a stroke segment it is the quadrilateral itself.\n vec2 top = mix(a_p01.xy, a_p01.zw, a_corner.x);\n vec2 bottom = mix(a_p23.zw, a_p23.xy, a_corner.x);\n vec2 design = mix(top, bottom, a_corner.y);\n gl_Position = vec4(design * u_projection.xy + u_projection.zw, 0.0, 1.0);\n v_uv = a_uv.xy + a_uv.zw * a_corner;\n v_color = a_color;\n v_design = design;\n v_texture = int(a_slots.x);\n v_matrix = int(a_slots.y);\n}`;\n\nconst TEXTURED_MESH_VERTEX_SRC = `#version 300 es\nlayout(location = 0) in vec2 a_position;\nlayout(location = 1) in vec2 a_uv;\nuniform vec4 u_projection;\nout vec2 v_uv;\nvoid main() {\n gl_Position = vec4(a_position * u_projection.xy + u_projection.zw, 0.0, 1.0);\n v_uv = a_uv;\n}`;\n\nconst TEXTURED_MESH_FRAGMENT_SRC = `#version 300 es\nprecision highp float;\nuniform sampler2D u_texture;\nuniform vec4 u_tint;\nin vec2 v_uv;\nout vec4 fragColor;\nvoid main() {\n // Both the uploaded texel and tint are premultiplied, so ordinary component\n // multiplication remains premultiplied for the shared blend contract.\n fragColor = texture(u_texture, v_uv) * u_tint;\n}`;\n\n/**\n * The fragment shader, generated for the slot counts THIS context supports.\n *\n * The `if` ladder is not laziness: GLSL ES 3.00 allows a sampler array to be\n * indexed only by a constant expression, so a dynamic slot has to be resolved by\n * comparison. (The colour-matrix array next to it is a plain uniform array, which\n * dynamic indexing IS allowed on.)\n *\n * `precision highp int` is load-bearing. The default integer precision is `highp`\n * in the vertex stage and `mediump` in the fragment stage, and a cross-stage\n * variable whose precision disagrees fails to LINK — silently, in the sense that\n * the only symptom is a program that does not exist and therefore a canvas that\n * draws nothing. `highp float` matters for a different reason: `mediump` carries\n * ~10 bits of mantissa, which cannot address a texel on a 4096-wide atlas page.\n */\nfunction fragmentSource(textureSlots: number, colorMatrices: number): string {\n const ladder: string[] = [];\n for (let i = 0; i < textureSlots; i += 1) {\n ladder.push(\n ` ${i === 0 ? \"if\" : \"} else if\"} (slot == ${i}) {\\n return texture(u_textures[${i}], uv);`,\n );\n }\n ladder.push(\" }\");\n return `#version 300 es\nprecision highp float;\nprecision highp int;\nprecision highp sampler2D;\nuniform sampler2D u_textures[${textureSlots}];\nuniform mat3 u_colorMatrices[${colorMatrices}];\nuniform vec4 u_roundedRect; // centre.xy, half-extent.xy, DESIGN units\nuniform float u_roundedRadius; // <= 0 disables the rounded test entirely\nin vec2 v_uv;\nin vec4 v_color;\nin vec2 v_design;\nflat in int v_texture;\nflat in int v_matrix;\nout vec4 fragColor;\n\nvec4 sampleSlot(int slot, vec2 uv) {\n${ladder.join(\"\\n\")}\n return vec4(0.0);\n}\n\nvoid main() {\n if (u_roundedRadius > 0.0) {\n // Standard rounded-rect distance: shrink the box by the radius, take the\n // distance to that box, subtract the radius back.\n vec2 d = abs(v_design - u_roundedRect.xy) - (u_roundedRect.zw - vec2(u_roundedRadius));\n if (length(max(d, vec2(0.0))) - u_roundedRadius > 0.0) {\n discard;\n }\n }\n vec4 texel = sampleSlot(v_texture, v_uv);\n if (v_matrix != 0) {\n // The matrix is defined on the texture's OWN colour, so it has to see\n // straight (un-premultiplied) sRGB — apply it to premultiplied channels and a\n // half-transparent pixel is transformed as if it were half as bright. No\n // linearization: the same sRGB-domain transform html's applyColorMatrixToPixels\n // performs on the CPU, clamped for the same reason (it writes clamped bytes).\n float alpha = texel.a;\n vec3 straight = alpha > 0.0 ? texel.rgb / alpha : vec3(0.0);\n straight = clamp(u_colorMatrices[v_matrix] * straight, 0.0, 1.0);\n texel = vec4(straight * alpha, alpha);\n }\n // Two PREMULTIPLIED colours compose with a plain multiply, and the result is\n // premultiplied — which is what the blend factors and the canvas expect.\n fragColor = texel * v_color;\n}`;\n}\n\nfunction compileShader(\n gl: WebGL2RenderingContext,\n type: number,\n source: string,\n): WebGLShader | null {\n const shader = gl.createShader(type);\n if (!shader) return null;\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n return shader;\n}\n\n// A local compile+link rather than `html/webgl/shared-gl`'s: that module's\n// helpers are not on its package's public barrel, and widening the barrel to\n// reach them would change a checked-in export surface for thirty lines. Same\n// failure reporting: a link failure over a shader that did not compile is\n// reported as the COMPILE failure it is, with the shader's own log.\nfunction linkProgram(\n gl: WebGL2RenderingContext,\n vertexSrc: string,\n fragmentSrc: string,\n): WebGLProgram | null {\n const vs = compileShader(gl, gl.VERTEX_SHADER, vertexSrc);\n const fs = compileShader(gl, gl.FRAGMENT_SHADER, fragmentSrc);\n if (!vs || !fs) {\n if (vs) gl.deleteShader(vs);\n if (fs) gl.deleteShader(fs);\n return null;\n }\n const program = gl.createProgram();\n if (!program) {\n gl.deleteShader(vs);\n gl.deleteShader(fs);\n return null;\n }\n gl.attachShader(program, vs);\n gl.attachShader(program, fs);\n gl.linkProgram(program);\n const linked = gl.getProgramParameter(program, gl.LINK_STATUS);\n if (!linked) {\n let compileFailed = false;\n for (const shader of [vs, fs]) {\n if (gl.getShaderParameter(shader, gl.COMPILE_STATUS)) continue;\n compileFailed = true;\n console.warn(\n \"[gsw canvas] shader compile failed:\",\n gl.getShaderInfoLog(shader),\n );\n }\n if (!compileFailed) {\n console.warn(\n \"[gsw canvas] program link failed:\",\n gl.getProgramInfoLog(program),\n );\n }\n gl.deleteProgram(program);\n }\n gl.deleteShader(vs);\n gl.deleteShader(fs);\n return linked ? program : null;\n}\n\n/** `[x, y]` per corner, in TRIANGLE_STRIP order: `(0,0) (1,0) (0,1) (1,1)`, whose\n * two triangles are `p0 p1 p3` and `p1 p3 p2`. A quad with `p2 === p3` therefore\n * degenerates to exactly the triangle `p0 p1 p3` — how `./polyline` spells a join\n * wedge without a second draw path. */\nconst CORNERS = new Float32Array([0, 0, 1, 0, 0, 1, 1, 1]);\nconst NO_CHANGED_COMMANDS: readonly number[] = [];\n\ninterface InstanceAttribute {\n location: number;\n size: number;\n offset: number;\n}\n\nconst INSTANCE_ATTRIBUTES: InstanceAttribute[] = [\n { location: 1, size: 4, offset: INSTANCE_CORNERS_OFFSET },\n { location: 2, size: 4, offset: INSTANCE_CORNERS_OFFSET + 4 },\n { location: 3, size: 4, offset: INSTANCE_UV_OFFSET },\n { location: 4, size: 4, offset: INSTANCE_COLOR_OFFSET },\n { location: 5, size: 2, offset: INSTANCE_SLOTS_OFFSET },\n];\n\nexport function createCanvasExecutor(\n options: CanvasExecutorOptions,\n): CanvasExecutor {\n const gl = options.gl;\n const contextUnits = Number(gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS)) || 8;\n const maxTextureSlots = Math.max(\n 1,\n Math.min(\n MAX_TEXTURE_SLOTS,\n contextUnits,\n Math.floor(options.maxTextureSlots ?? MAX_TEXTURE_SLOTS),\n ),\n );\n const maxColorMatrices = Math.max(\n 2,\n Math.floor(options.maxColorMatrices ?? 16),\n );\n\n let program: Program | null = null;\n let meshProgram: MeshProgram | null = null;\n let ownedWhite: ExecutorTexture | null = null;\n const suppliedWhite = options.white ?? null;\n const glyphPass = options.glyphs ?? null;\n\n const stats: ExecutorStats = {\n commands: 0,\n quads: 0,\n batches: 0,\n textureBinds: 0,\n scissorChanges: 0,\n blendChanges: 0,\n ninePatches: 0,\n ninePatchQuads: 0,\n polylines: 0,\n polylineQuads: 0,\n texturedMeshes: 0,\n texturedMeshTriangles: 0,\n texturedMeshDrawCalls: 0,\n glyphRuns: 0,\n glyphs: 0,\n glyphDrawCalls: 0,\n glyphRunBatches: 0,\n glyphRunBatchFallbacks: 0,\n glyphRunsDropped: 0,\n screenEffects: 0,\n screenEffectFailures: 0,\n externalEffects: 0,\n externalEffectFailures: 0,\n rotatedClipFallbacks: 0,\n unbalancedClipPops: 0,\n unknownCommands: 0,\n maxBatchQuads: 0,\n flushes: {\n textureSlots: 0,\n colorMatrices: 0,\n blend: 0,\n clip: 0,\n glyphs: 0,\n effects: 0,\n meshes: 0,\n compiled: 0,\n end: 0,\n },\n compiledPlanBuilds: 0,\n compiledPlanReuses: 0,\n compiledTemplateRangeUpdates: 0,\n reusedSelections: 0,\n reusedBatches: 0,\n compiledGpuFullUploads: 0,\n compiledGpuRangeUploads: 0,\n compiledCachedDrawCalls: 0,\n };\n\n const clipStack: ClipStack = createClipStack();\n const scissor: ScissorBox = createScissorBox();\n const damageScissor: ScissorBox = createScissorBox();\n const appliedScissor: ScissorBox = createScissorBox();\n let appliedRoundedRadius = -1;\n /** The rounded-clip rect last uploaded: centre.xy, half-extent.xy. */\n const appliedRounded = new Float32Array(4);\n let appliedBlend: BlendMode | null = null;\n\n const quadView = createQuadView();\n const patchView = createNinePatchView();\n const lineView = createPolylineView(64);\n const clipView = createClipRectView();\n const glyphsView = createGlyphsView(64);\n // `readGlyphs` fills caller-owned views. Keep a grow-only pool so an adjacent-run batch does\n // not turn a retained replay into per-frame garbage.\n const glyphRunViewPool: GlyphsView[] = [];\n const glyphRunViews: GlyphsView[] = [];\n const texturedMeshView = createTexturedMeshView(64, 96);\n const bands: NinePatchBand[] = createNinePatchBands();\n let strokeQuads = new Float32Array(256 * POLYLINE_QUAD_FLOATS);\n // `x, y, u, v` per vertex, transformed into design space before upload. It is\n // grow-only like the batcher's arena, so retained replay settles at zero\n // allocations after its largest mesh has been seen.\n let meshVertices = new Float32Array(64 * 4);\n\n const batcher: QuadBatcher = createQuadBatcher({\n maxTextureSlots,\n maxColorMatrices,\n quadCapacity: options.quadCapacity,\n draw: drawBatch,\n });\n const compiledGpuPlans = new WeakMap<\n CompiledDrawList<ExecutorTexture | null>,\n CachedGpuPlan\n >();\n const liveCompiledGpuPlans = new Set<CachedGpuPlan>();\n const cachedQuad = createQuadInstance();\n\n function whiteTexture(): ExecutorTexture {\n if (suppliedWhite) return suppliedWhite;\n if (ownedWhite) return ownedWhite;\n const texture = gl.createTexture();\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);\n gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);\n gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);\n gl.texImage2D(\n gl.TEXTURE_2D,\n 0,\n gl.RGBA,\n 1,\n 1,\n 0,\n gl.RGBA,\n gl.UNSIGNED_BYTE,\n new Uint8Array([255, 255, 255, 255]),\n );\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n ownedWhite = { texture, width: 1, height: 1 };\n return ownedWhite;\n }\n\n function ensureProgram(): Program | null {\n if (program) return program;\n const linked = linkProgram(\n gl,\n VERTEX_SRC,\n fragmentSource(maxTextureSlots, maxColorMatrices),\n );\n if (!linked) return null;\n const vao = gl.createVertexArray();\n const cornerBuffer = gl.createBuffer();\n const instanceBuffer = gl.createBuffer();\n gl.bindVertexArray(vao);\n gl.bindBuffer(gl.ARRAY_BUFFER, cornerBuffer);\n gl.bufferData(gl.ARRAY_BUFFER, CORNERS, gl.STATIC_DRAW);\n gl.enableVertexAttribArray(0);\n gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);\n gl.vertexAttribDivisor(0, 0);\n gl.bindBuffer(gl.ARRAY_BUFFER, instanceBuffer);\n const strideBytes = INSTANCE_FLOATS * 4;\n for (const attribute of INSTANCE_ATTRIBUTES) {\n gl.enableVertexAttribArray(attribute.location);\n gl.vertexAttribPointer(\n attribute.location,\n attribute.size,\n gl.FLOAT,\n false,\n strideBytes,\n attribute.offset * 4,\n );\n gl.vertexAttribDivisor(attribute.location, 1);\n }\n gl.bindVertexArray(null);\n\n gl.useProgram(linked);\n // The sampler uniforms are set ONCE: slot i is always unit i, for the life of\n // the program. Only the BINDINGS change per batch.\n const units = new Int32Array(maxTextureSlots);\n for (let i = 0; i < maxTextureSlots; i += 1) units[i] = i;\n const uTextures = gl.getUniformLocation(linked, \"u_textures[0]\");\n if (uTextures) gl.uniform1iv(uTextures, units);\n\n program = {\n program: linked,\n vao,\n cornerBuffer,\n instanceBuffer,\n instanceBytes: 0,\n uProjection: gl.getUniformLocation(linked, \"u_projection\"),\n uColorMatrices: gl.getUniformLocation(linked, \"u_colorMatrices[0]\"),\n uRoundedRect: gl.getUniformLocation(linked, \"u_roundedRect\"),\n uRoundedRadius: gl.getUniformLocation(linked, \"u_roundedRadius\"),\n };\n return program;\n }\n\n function ensureMeshProgram(): MeshProgram | null {\n if (meshProgram) return meshProgram;\n const linked = linkProgram(\n gl,\n TEXTURED_MESH_VERTEX_SRC,\n TEXTURED_MESH_FRAGMENT_SRC,\n );\n if (!linked) return null;\n const vao = gl.createVertexArray();\n const vertexBuffer = gl.createBuffer();\n const indexBuffer = gl.createBuffer();\n gl.bindVertexArray(vao);\n gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);\n gl.enableVertexAttribArray(0);\n gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 16, 0);\n gl.enableVertexAttribArray(1);\n gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 16, 8);\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);\n gl.bindVertexArray(null);\n gl.useProgram(linked);\n const uTexture = gl.getUniformLocation(linked, \"u_texture\");\n if (uTexture) gl.uniform1i(uTexture, 0);\n meshProgram = {\n program: linked,\n vao,\n vertexBuffer,\n indexBuffer,\n vertexBytes: 0,\n indexBytes: 0,\n uProjection: gl.getUniformLocation(linked, \"u_projection\"),\n uTint: gl.getUniformLocation(linked, \"u_tint\"),\n uTexture,\n };\n return meshProgram;\n }\n\n function drawBatch(batch: Batch): void {\n const current = program;\n if (!current) return;\n const floats = batch.quadCount * INSTANCE_FLOATS;\n const bytes = floats * 4;\n gl.bindBuffer(gl.ARRAY_BUFFER, current.instanceBuffer);\n if (current.instanceBytes < bytes) {\n // Grow-only, and orphaning: a fresh `bufferData` also tells the driver the\n // old contents are dead, so it never has to wait for the previous draw to\n // finish reading them.\n gl.bufferData(gl.ARRAY_BUFFER, bytes, gl.DYNAMIC_DRAW);\n current.instanceBytes = bytes;\n }\n gl.bufferSubData(gl.ARRAY_BUFFER, 0, batch.instances, 0, floats);\n\n for (let slot = 0; slot < batch.textureCount; slot += 1) {\n const entry = batch.textures[slot];\n gl.activeTexture(gl.TEXTURE0 + slot);\n gl.bindTexture(gl.TEXTURE_2D, entry ? entry.texture : null);\n }\n if (batch.colorMatrixCount > 1 && current.uColorMatrices) {\n // `transpose = true`: the draw list stores matrices ROW-major and GLSL reads\n // them column-major, so `m * v` only means what it reads as if the upload\n // transposes. (WebGL2 permits a true transpose; WebGL1 did not.)\n gl.uniformMatrix3fv(\n current.uColorMatrices,\n true,\n batch.colorMatrices,\n 0,\n batch.colorMatrixCount * COLOR_MATRIX_FLOATS,\n );\n }\n gl.drawArraysInstanced(gl.TRIANGLE_STRIP, 0, 4, batch.quadCount);\n stats.batches += 1;\n stats.textureBinds += batch.textureCount;\n if (batch.quadCount > stats.maxBatchQuads) {\n stats.maxBatchQuads = batch.quadCount;\n }\n stats.flushes[batch.reason] += 1;\n }\n\n function releaseGpuPlan(cache: CachedGpuPlan, deleteGl: boolean): void {\n if (deleteGl) {\n for (const run of cache.runs) {\n gl.deleteBuffer(run.buffer);\n gl.deleteVertexArray(run.vao);\n }\n }\n compiledGpuPlans.delete(cache.plan);\n liveCompiledGpuPlans.delete(cache);\n }\n\n function makeCachedVao(\n current: Program,\n buffer: WebGLBuffer,\n ): WebGLVertexArrayObject | null {\n const vao = gl.createVertexArray();\n if (!vao) return null;\n gl.bindVertexArray(vao);\n gl.bindBuffer(gl.ARRAY_BUFFER, current.cornerBuffer);\n gl.enableVertexAttribArray(0);\n gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);\n gl.vertexAttribDivisor(0, 0);\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n const strideBytes = INSTANCE_FLOATS * 4;\n for (const attribute of INSTANCE_ATTRIBUTES) {\n gl.enableVertexAttribArray(attribute.location);\n gl.vertexAttribPointer(\n attribute.location,\n attribute.size,\n gl.FLOAT,\n false,\n strideBytes,\n attribute.offset * 4,\n );\n gl.vertexAttribDivisor(attribute.location, 1);\n }\n gl.bindVertexArray(current.vao);\n return vao;\n }\n\n function matrixSlot(\n matrices: Float32Array,\n count: number,\n source: Float32Array,\n sourceOffset: number,\n ): number {\n for (let slot = 0; slot < count; slot += 1) {\n if (\n colorMatricesEqual(\n matrices,\n slot * COLOR_MATRIX_FLOATS,\n source,\n sourceOffset,\n )\n )\n return slot;\n }\n return -1;\n }\n\n function writeCachedQuad(\n run: CachedGpuRun,\n item: number,\n index: number,\n plan: CompiledDrawList<ExecutorTexture | null>,\n textureSlot: number,\n matrixSlotIndex: number,\n ): void {\n const texture = run.textures[textureSlot];\n plan.fillQuad(index, texture.width, texture.height, cachedQuad);\n const at = item * INSTANCE_FLOATS;\n run.instances[at] = cachedQuad.x0;\n run.instances[at + 1] = cachedQuad.y0;\n run.instances[at + 2] = cachedQuad.x1;\n run.instances[at + 3] = cachedQuad.y1;\n run.instances[at + 4] = cachedQuad.x2;\n run.instances[at + 5] = cachedQuad.y2;\n run.instances[at + 6] = cachedQuad.x3;\n run.instances[at + 7] = cachedQuad.y3;\n run.instances[at + 8] = cachedQuad.u0;\n run.instances[at + 9] = cachedQuad.v0;\n run.instances[at + 10] = cachedQuad.uSpan;\n run.instances[at + 11] = cachedQuad.vSpan;\n run.instances[at + 12] = cachedQuad.r;\n run.instances[at + 13] = cachedQuad.g;\n run.instances[at + 14] = cachedQuad.b;\n run.instances[at + 15] = cachedQuad.a;\n run.instances[at + 16] = textureSlot;\n run.instances[at + 17] = matrixSlotIndex;\n }\n\n function buildGpuPlan(\n plan: CompiledDrawList<ExecutorTexture | null>,\n current: Program,\n generation: number,\n contentRevision: number,\n ): CachedGpuPlan | null {\n const list = plan.list;\n const runs: CachedGpuRun[] = [];\n const runsAt: (CachedGpuRun | null)[] = new Array(list.count).fill(null);\n const runsForCommand: (CachedGpuRun | null)[] = new Array(list.count).fill(\n null,\n );\n const itemsForCommand = new Int32Array(list.count);\n const discardPartial = (): void => {\n for (const run of runs) {\n gl.deleteBuffer(run.buffer);\n gl.deleteVertexArray(run.vao);\n }\n };\n for (const descriptor of plan.batches) {\n let cursor = descriptor.start;\n while (cursor < descriptor.end) {\n const commandIndexes: number[] = [];\n const textures: ExecutorTexture[] = [];\n const matrices = new Float32Array(\n maxColorMatrices * COLOR_MATRIX_FLOATS,\n );\n matrices.set(IDENTITY_COLOR_MATRIX);\n let matrixCount = 1;\n while (cursor < descriptor.end) {\n const texture = list.textureAt(cursor) ?? whiteTexture();\n let textureSlot = textures.indexOf(texture);\n if (textureSlot < 0 && textures.length >= maxTextureSlots) break;\n const matrixIndex = list.colorMatrixIndexAt(cursor);\n let slot = 0;\n if (matrixIndex >= 0) {\n slot = matrixSlot(\n matrices,\n matrixCount,\n list.colorMatrices,\n matrixIndex * COLOR_MATRIX_FLOATS,\n );\n if (slot < 0 && matrixCount >= maxColorMatrices) break;\n }\n if (textureSlot < 0) {\n textureSlot = textures.length;\n textures.push(texture);\n }\n if (matrixIndex >= 0 && slot < 0) {\n slot = matrixCount;\n matrices.set(\n list.colorMatrices.subarray(\n matrixIndex * COLOR_MATRIX_FLOATS,\n (matrixIndex + 1) * COLOR_MATRIX_FLOATS,\n ),\n slot * COLOR_MATRIX_FLOATS,\n );\n matrixCount += 1;\n }\n commandIndexes.push(cursor);\n cursor += 1;\n }\n const buffer = gl.createBuffer();\n if (!buffer) {\n discardPartial();\n return null;\n }\n const vao = makeCachedVao(current, buffer);\n if (!vao) {\n gl.deleteBuffer(buffer);\n discardPartial();\n return null;\n }\n const commands = Int32Array.from(commandIndexes);\n const run: CachedGpuRun = {\n start: commands[0],\n end: commands[commands.length - 1] + 1,\n blend: descriptor.blend,\n commands,\n textures,\n dimensions: new Int32Array(textures.length * 2),\n itemsByTexture: textures.map(() => []),\n colorMatrices: matrices.subarray(\n 0,\n matrixCount * COLOR_MATRIX_FLOATS,\n ),\n colorMatrixCount: matrixCount,\n instances: new Float32Array(commands.length * INSTANCE_FLOATS),\n buffer,\n vao,\n };\n for (let item = 0; item < commands.length; item += 1) {\n const index = commands[item];\n const textureSlot = textures.indexOf(\n list.textureAt(index) ?? whiteTexture(),\n );\n const matrixIndex = list.colorMatrixIndexAt(index);\n const slot =\n matrixIndex < 0\n ? 0\n : matrixSlot(\n run.colorMatrices,\n matrixCount,\n list.colorMatrices,\n matrixIndex * COLOR_MATRIX_FLOATS,\n );\n writeCachedQuad(run, item, index, plan, textureSlot, slot);\n run.itemsByTexture[textureSlot].push(item);\n }\n for (let slot = 0; slot < textures.length; slot += 1) {\n run.dimensions[slot * 2] = textures[slot].width;\n run.dimensions[slot * 2 + 1] = textures[slot].height;\n }\n gl.bindBuffer(gl.ARRAY_BUFFER, buffer);\n gl.bufferData(gl.ARRAY_BUFFER, run.instances, gl.DYNAMIC_DRAW);\n stats.compiledGpuFullUploads += 1;\n runs.push(run);\n runsAt[run.start] = run;\n for (let item = 0; item < run.commands.length; item += 1) {\n const index = run.commands[item];\n runsForCommand[index] = run;\n itemsForCommand[index] = item;\n }\n }\n }\n gl.bindVertexArray(current.vao);\n const cache = {\n plan,\n generation,\n contentRevision,\n runs,\n runsAt,\n runsForCommand,\n itemsForCommand,\n };\n compiledGpuPlans.set(plan, cache);\n liveCompiledGpuPlans.add(cache);\n return cache;\n }\n\n function updateGpuPlan(\n cache: CachedGpuPlan,\n current: Program,\n changedCommands: readonly number[],\n contentRevision: number,\n ): CachedGpuPlan | null {\n const list = cache.plan.list;\n const updateItem = (run: CachedGpuRun, item: number): boolean => {\n const index = run.commands[item];\n const texture = list.textureAt(index) ?? whiteTexture();\n const textureSlot = run.textures.indexOf(texture);\n if (textureSlot < 0) return false;\n // A source can switch to a texture that is already resident in this run.\n // The slot table still changed for this item, and its old membership list\n // would miss later dimension changes, so rebuild the cache conservatively.\n if (\n run.instances[item * INSTANCE_FLOATS + INSTANCE_SLOTS_OFFSET] !==\n textureSlot\n )\n return false;\n const matrixIndex = list.colorMatrixIndexAt(index);\n const matrixSlotIndex =\n matrixIndex < 0\n ? 0\n : matrixSlot(\n run.colorMatrices,\n run.colorMatrixCount,\n list.colorMatrices,\n matrixIndex * COLOR_MATRIX_FLOATS,\n );\n if (matrixSlotIndex < 0) return false;\n writeCachedQuad(\n run,\n item,\n index,\n cache.plan,\n textureSlot,\n matrixSlotIndex,\n );\n gl.bindBuffer(gl.ARRAY_BUFFER, run.buffer);\n gl.bufferSubData(\n gl.ARRAY_BUFFER,\n item * INSTANCE_FLOATS * 4,\n run.instances,\n item * INSTANCE_FLOATS,\n INSTANCE_FLOATS,\n );\n stats.compiledGpuRangeUploads += 1;\n return true;\n };\n for (const index of changedCommands) {\n const run = cache.runsForCommand[index];\n if (!run) continue;\n if (!updateItem(run, cache.itemsForCommand[index])) {\n releaseGpuPlan(cache, true);\n return buildGpuPlan(\n cache.plan,\n current,\n cache.generation,\n contentRevision,\n );\n }\n }\n // Texture dimensions can change outside DrawList patch APIs. This walks only\n // the distinct textures in each cached run, then touches their recorded items.\n for (const run of cache.runs) {\n for (let slot = 0; slot < run.textures.length; slot += 1) {\n const texture = run.textures[slot];\n if (\n run.dimensions[slot * 2] === texture.width &&\n run.dimensions[slot * 2 + 1] === texture.height\n )\n continue;\n run.dimensions[slot * 2] = texture.width;\n run.dimensions[slot * 2 + 1] = texture.height;\n for (const item of run.itemsByTexture[slot]) {\n if (!updateItem(run, item)) {\n releaseGpuPlan(cache, true);\n return buildGpuPlan(\n cache.plan,\n current,\n cache.generation,\n contentRevision,\n );\n }\n }\n }\n }\n gl.bindVertexArray(current.vao);\n cache.contentRevision = contentRevision;\n return cache;\n }\n\n function drawCachedRange(\n run: CachedGpuRun,\n first: number,\n count: number,\n current: Program,\n ): void {\n applyBlend(run.blend);\n gl.bindVertexArray(run.vao);\n gl.bindBuffer(gl.ARRAY_BUFFER, run.buffer);\n const strideBytes = INSTANCE_FLOATS * 4;\n for (const attribute of INSTANCE_ATTRIBUTES) {\n gl.vertexAttribPointer(\n attribute.location,\n attribute.size,\n gl.FLOAT,\n false,\n strideBytes,\n first * strideBytes + attribute.offset * 4,\n );\n }\n for (let slot = 0; slot < run.textures.length; slot += 1) {\n gl.activeTexture(gl.TEXTURE0 + slot);\n gl.bindTexture(gl.TEXTURE_2D, run.textures[slot].texture);\n }\n if (run.colorMatrixCount > 1 && current.uColorMatrices) {\n gl.uniformMatrix3fv(\n current.uColorMatrices,\n true,\n run.colorMatrices,\n 0,\n run.colorMatrixCount * COLOR_MATRIX_FLOATS,\n );\n }\n gl.drawArraysInstanced(gl.TRIANGLE_STRIP, 0, 4, count);\n stats.batches += 1;\n stats.textureBinds += run.textures.length;\n stats.quads += count;\n stats.maxBatchQuads = Math.max(stats.maxBatchQuads, count);\n stats.compiledCachedDrawCalls += 1;\n gl.bindVertexArray(current.vao);\n }\n\n /**\n * Forget everything this executor believes about the GL state it set.\n *\n * TWO CALLERS, ONE RULE: it does not own the context. `execute` calls it on entry because\n * something else may have drawn into the context since the last frame, and the glyph pass path\n * calls it on the way back because something else just did, in the middle of this one. Every\n * cached value here guards a GL call that would otherwise be skipped, so a stale cache is not a\n * redundant call — it is a call that never happens and state that is silently somebody else's.\n *\n * `appliedBlend` is the one that bites hardest today: `@godot-scene-web/hb-gpu` sets the\n * NON-separate `blendEquation`/`blendFunc`, which write both the RGB and the alpha halves, so\n * without this the next quad keeps the glyph pass's blend and nothing errors.\n */\n function invalidateAppliedState(): void {\n appliedBlend = null;\n appliedRoundedRadius = -1;\n appliedScissor.x = -1;\n appliedScissor.y = -1;\n appliedScissor.width = -1;\n appliedScissor.height = -1;\n }\n\n function applyBlend(blend: BlendMode): void {\n if (blend === appliedBlend) return;\n batcher.setBlend(blend);\n const state = blendStateFor(blend);\n gl.blendEquationSeparate(\n gl[state.equationRgb] as number,\n gl[state.equationAlpha] as number,\n );\n gl.blendFuncSeparate(\n gl[state.srcRgb] as number,\n gl[state.dstRgb] as number,\n gl[state.srcAlpha] as number,\n gl[state.dstAlpha] as number,\n );\n appliedBlend = blend;\n stats.blendChanges += 1;\n }\n\n function applyClip(\n transform: PixelTransform,\n width: number,\n height: number,\n damage?: DamageRect,\n ): void {\n clipStack.scissor(transform, width, height, scissor);\n if (damage) {\n const left = Math.max(0, Math.min(width, Math.floor(damage.x)));\n const right = Math.max(\n left,\n Math.min(width, Math.ceil(damage.x + damage.width)),\n );\n const top = Math.max(0, Math.min(height, Math.floor(damage.y)));\n const bottom = Math.max(\n top,\n Math.min(height, Math.ceil(damage.y + damage.height)),\n );\n damageScissor.x = left;\n damageScissor.y = height - bottom;\n damageScissor.width = right - left;\n damageScissor.height = bottom - top;\n const clippedRight = Math.min(scissor.x + scissor.width, right);\n const clippedTop = Math.max(scissor.y, damageScissor.y);\n const clippedBottom = Math.min(\n scissor.y + scissor.height,\n damageScissor.y + damageScissor.height,\n );\n scissor.x = Math.max(scissor.x, left);\n scissor.y = clippedTop;\n scissor.width = Math.max(0, clippedRight - scissor.x);\n scissor.height = Math.max(0, clippedBottom - clippedTop);\n }\n if (\n scissor.x !== appliedScissor.x ||\n scissor.y !== appliedScissor.y ||\n scissor.width !== appliedScissor.width ||\n scissor.height !== appliedScissor.height\n ) {\n gl.scissor(scissor.x, scissor.y, scissor.width, scissor.height);\n appliedScissor.x = scissor.x;\n appliedScissor.y = scissor.y;\n appliedScissor.width = scissor.width;\n appliedScissor.height = scissor.height;\n stats.scissorChanges += 1;\n }\n const current = program;\n if (!current) return;\n const rounded = clipStack.rounded();\n const radius = rounded ? rounded.radius : 0;\n const centerX = rounded ? rounded.centerX : 0;\n const centerY = rounded ? rounded.centerY : 0;\n const halfWidth = rounded ? rounded.halfWidth : 0;\n const halfHeight = rounded ? rounded.halfHeight : 0;\n if (\n radius === appliedRoundedRadius &&\n centerX === appliedRounded[0] &&\n centerY === appliedRounded[1] &&\n halfWidth === appliedRounded[2] &&\n halfHeight === appliedRounded[3]\n ) {\n return;\n }\n if (current.uRoundedRadius) gl.uniform1f(current.uRoundedRadius, radius);\n if (current.uRoundedRect) {\n gl.uniform4f(\n current.uRoundedRect,\n centerX,\n centerY,\n halfWidth,\n halfHeight,\n );\n }\n appliedRoundedRadius = radius;\n appliedRounded[0] = centerX;\n appliedRounded[1] = centerY;\n appliedRounded[2] = halfWidth;\n appliedRounded[3] = halfHeight;\n }\n\n // ---- per-command emission -------------------------------------------------\n //\n // All of these write through the batcher's ONE staging instance, so a frame of\n // any size allocates nothing after the arenas have settled.\n\n /**\n * Emit one rect of a command: `localX..localH` is the destination in the\n * command's own local space (`0..w` by `0..h`), which `m` maps into design\n * space; `srcX..srcH` is the source in page pixels.\n */\n function emitRect(\n m: Float32Array,\n localX: number,\n localY: number,\n localW: number,\n localH: number,\n srcX: number,\n srcY: number,\n srcW: number,\n srcH: number,\n texture: ExecutorTexture,\n flipH: boolean,\n flipV: boolean,\n r: number,\n g: number,\n b: number,\n a: number,\n colorMatrix: ArrayLike<number> | null,\n colorMatrixOffset: number,\n ): void {\n const quad = batcher.quad;\n const x1 = localX + localW;\n const y1 = localY + localH;\n const xx = m[0];\n const xy = m[1];\n const yx = m[2];\n const yy = m[3];\n const ox = m[4];\n const oy = m[5];\n quad.x0 = xx * localX + yx * localY + ox;\n quad.y0 = xy * localX + yy * localY + oy;\n quad.x1 = xx * x1 + yx * localY + ox;\n quad.y1 = xy * x1 + yy * localY + oy;\n quad.x2 = xx * x1 + yx * y1 + ox;\n quad.y2 = xy * x1 + yy * y1 + oy;\n quad.x3 = xx * localX + yx * y1 + ox;\n quad.y3 = xy * localX + yy * y1 + oy;\n\n // Page pixels -> normalized. A ZERO-span source is left alone rather than\n // widened to the whole texture: it means \"stretch this one texel\", which is\n // exactly what an untextured solid fill on the white texel wants.\n const invW = 1 / Math.max(1, texture.width);\n const invH = 1 / Math.max(1, texture.height);\n let u0 = srcX * invW;\n let v0 = srcY * invH;\n let uSpan = srcW * invW;\n let vSpan = srcH * invH;\n if (flipH) {\n u0 += uSpan;\n uSpan = -uSpan;\n }\n if (flipV) {\n v0 += vSpan;\n vSpan = -vSpan;\n }\n quad.u0 = u0;\n quad.v0 = v0;\n quad.uSpan = uSpan;\n quad.vSpan = vSpan;\n quad.r = r;\n quad.g = g;\n quad.b = b;\n quad.a = a;\n batcher.push(texture, colorMatrix, colorMatrixOffset);\n stats.quads += 1;\n }\n\n function emitQuadCommand(\n list: DrawList<ExecutorTexture | null>,\n index: number,\n compiled: CompiledDrawList<ExecutorTexture | null> | undefined,\n ): void {\n const texture = list.textureAt(index) ?? whiteTexture();\n if (\n compiled?.fillQuad(index, texture.width, texture.height, batcher.quad)\n ) {\n applyBlend(list.ints[list.intOffsetAt(index)] as BlendMode);\n const matrixIndex = list.colorMatrixIndexAt(index);\n batcher.push(\n texture,\n matrixIndex >= 0 ? list.colorMatrices : null,\n matrixIndex >= 0 ? matrixIndex * COLOR_MATRIX_FLOATS : 0,\n );\n stats.quads += 1;\n return;\n }\n list.readQuad(index, quadView);\n applyBlend(quadView.blend);\n emitRect(\n quadView.m,\n 0,\n 0,\n quadView.w,\n quadView.h,\n quadView.srcX,\n quadView.srcY,\n quadView.srcW,\n quadView.srcH,\n texture,\n quadView.flipH,\n quadView.flipV,\n quadView.r,\n quadView.g,\n quadView.b,\n quadView.a,\n quadView.hasColorMatrix ? quadView.colorMatrix : null,\n 0,\n );\n }\n\n function emitNinePatchCommand(\n list: DrawList<ExecutorTexture | null>,\n index: number,\n ): void {\n list.readNinePatch(index, patchView);\n applyBlend(patchView.blend);\n const texture = list.textureAt(index) ?? whiteTexture();\n const count = expandNinePatch(patchView, bands);\n stats.ninePatches += 1;\n stats.ninePatchQuads += count;\n for (let i = 0; i < count; i += 1) {\n const band = bands[i];\n // A horizontal flip mirrors the PATCH, so both the band's place in the\n // destination and its own source have to turn over; mirroring only the\n // source would flip each band inside itself and leave the corners where\n // they were. (For a plain quad the same expression is a no-op, which is why\n // there is one code path.)\n const localX = patchView.flipH\n ? patchView.w - band.dstX - band.dstW\n : band.dstX;\n const localY = patchView.flipV\n ? patchView.h - band.dstY - band.dstH\n : band.dstY;\n emitRect(\n patchView.m,\n localX,\n localY,\n band.dstW,\n band.dstH,\n band.srcX,\n band.srcY,\n band.srcW,\n band.srcH,\n texture,\n patchView.flipH,\n patchView.flipV,\n patchView.r,\n patchView.g,\n patchView.b,\n patchView.a,\n patchView.hasColorMatrix ? patchView.colorMatrix : null,\n 0,\n );\n }\n }\n\n function emitPolylineCommand(\n list: DrawList<ExecutorTexture | null>,\n index: number,\n ): void {\n list.readPolyline(index, lineView);\n // The IR gives a polyline no blend mode of its own; a stroke is normal alpha\n // compositing, which is what Godot's `draw_polyline` does too.\n applyBlend(BLEND_MIX);\n const white = whiteTexture();\n const needed =\n Math.max(0, 2 * lineView.pointCount - 3) * POLYLINE_QUAD_FLOATS;\n if (strokeQuads.length < needed) {\n strokeQuads = new Float32Array(Math.max(needed, strokeQuads.length * 2));\n }\n const count = expandPolyline(\n lineView.points,\n lineView.pointCount,\n lineView.width,\n strokeQuads,\n 0,\n );\n stats.polylines += 1;\n stats.polylineQuads += count;\n const quad = batcher.quad;\n for (let i = 0; i < count; i += 1) {\n const at = i * POLYLINE_QUAD_FLOATS;\n // Stroke geometry is already in DESIGN space, so it bypasses `emitRect`'s\n // local->design map rather than being handed an identity transform.\n quad.x0 = strokeQuads[at];\n quad.y0 = strokeQuads[at + 1];\n quad.x1 = strokeQuads[at + 2];\n quad.y1 = strokeQuads[at + 3];\n quad.x2 = strokeQuads[at + 4];\n quad.y2 = strokeQuads[at + 5];\n quad.x3 = strokeQuads[at + 6];\n quad.y3 = strokeQuads[at + 7];\n quad.u0 = 0;\n quad.v0 = 0;\n quad.uSpan = 0;\n quad.vSpan = 0;\n quad.r = lineView.r;\n quad.g = lineView.g;\n quad.b = lineView.b;\n quad.a = lineView.a;\n batcher.push(white, null, 0);\n stats.quads += 1;\n }\n }\n\n /**\n * Execute one true indexed mesh between quad batches. The flush is before any\n * state mutation, preserving painter order. The mesh then borrows the context\n * only long enough to upload its pooled data and draw; program and VAO are\n * rebound to the quad executor before returning, while blend/scissor remain\n * the executor's own known state for the next command.\n */\n function emitTexturedMeshCommand(\n list: DrawList<ExecutorTexture | null>,\n index: number,\n projection: StageProjection,\n current: Program,\n ): void {\n batcher.flush(\"meshes\");\n list.readTexturedMesh(index, texturedMeshView);\n applyBlend(texturedMeshView.blend);\n stats.texturedMeshes += 1;\n if (texturedMeshView.indexCount === 0) return;\n const mesh = ensureMeshProgram();\n if (!mesh) return;\n const vertexFloats = texturedMeshView.vertexCount * 4;\n if (meshVertices.length < vertexFloats) {\n meshVertices = new Float32Array(\n Math.max(vertexFloats, meshVertices.length * 2),\n );\n }\n const m = texturedMeshView.m;\n for (let vertex = 0; vertex < texturedMeshView.vertexCount; vertex += 1) {\n const source = vertex * 2;\n const target = vertex * 4;\n const x = texturedMeshView.positions[source];\n const y = texturedMeshView.positions[source + 1];\n meshVertices[target] = m[0] * x + m[2] * y + m[4];\n meshVertices[target + 1] = m[1] * x + m[3] * y + m[5];\n meshVertices[target + 2] = texturedMeshView.uvs[source];\n meshVertices[target + 3] = texturedMeshView.uvs[source + 1];\n }\n gl.bindVertexArray(mesh.vao);\n gl.useProgram(mesh.program);\n if (mesh.uProjection) {\n gl.uniform4f(\n mesh.uProjection,\n projection.toClip[0],\n projection.toClip[1],\n projection.toClip[2],\n projection.toClip[3],\n );\n }\n if (mesh.uTint) {\n gl.uniform4f(\n mesh.uTint,\n texturedMeshView.r,\n texturedMeshView.g,\n texturedMeshView.b,\n texturedMeshView.a,\n );\n }\n const vertexBytes = vertexFloats * 4;\n gl.bindBuffer(gl.ARRAY_BUFFER, mesh.vertexBuffer);\n if (mesh.vertexBytes < vertexBytes) {\n gl.bufferData(gl.ARRAY_BUFFER, vertexBytes, gl.DYNAMIC_DRAW);\n mesh.vertexBytes = vertexBytes;\n }\n gl.bufferSubData(gl.ARRAY_BUFFER, 0, meshVertices, 0, vertexFloats);\n const indexBytes = texturedMeshView.indexCount * 4;\n gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, mesh.indexBuffer);\n if (mesh.indexBytes < indexBytes) {\n gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indexBytes, gl.DYNAMIC_DRAW);\n mesh.indexBytes = indexBytes;\n }\n gl.bufferSubData(\n gl.ELEMENT_ARRAY_BUFFER,\n 0,\n texturedMeshView.indices,\n 0,\n texturedMeshView.indexCount,\n );\n const texture = list.textureAt(index) ?? whiteTexture();\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, texture.texture);\n gl.drawElements(\n gl.TRIANGLES,\n texturedMeshView.indexCount,\n gl.UNSIGNED_INT,\n 0,\n );\n stats.texturedMeshTriangles += texturedMeshView.indexCount / 3;\n stats.texturedMeshDrawCalls += 1;\n // Mesh setup replaces both bindings, just like a glyph pass. The quad\n // program's blend/scissor state deliberately stays live and cached.\n gl.bindVertexArray(current.vao);\n gl.useProgram(current.program);\n }\n\n /**\n * Hand one glyph run to the installed pass, then put the context back the way it was.\n *\n * THE ORDER IS THE MODULE'S OWN RULE (see the note at the top of this file): a flush DRAWS with\n * whatever GL state is live, so the pending batch has to go out BEFORE the pass replaces the\n * program and the vertex array — never after. Doing it the other way round draws this frame's\n * quads through a glyph shader, which is a blank rectangle rather than anything that reads as an\n * ordering bug.\n *\n * WHAT IS RESTORED, AND WHY EACH ONE IS NEEDED. `drawBatch` re-binds `ARRAY_BUFFER` and its\n * textures per batch, so those look after themselves; the VAO and the program are bound ONCE per\n * frame, and a pass that leaves the VAO unbound (hb-gpu's `end` does exactly that, deliberately,\n * because WebGL2 has no cheap read-back of the binding) would make the next `drawArraysInstanced`\n * read attributes from nothing. The cached state goes through\n * {@link invalidateAppliedState} rather than being re-applied eagerly, so a run followed by\n * nothing costs no GL calls at all.\n *\n * NOT restored, because the pass is forbidden to touch it: `SCISSOR_TEST`, the scissor box and\n * the viewport. That is what makes a clip rect clip a glyph run.\n */\n function emitGlyphsCommand(\n list: DrawList<ExecutorTexture | null>,\n index: number,\n projection: StageProjection,\n current: Program,\n ): void {\n if (!glyphPass) {\n // NOT a flush. With no pass, nothing is drawn and no GL state moves, so breaking the batch\n // here would cost a draw call to accomplish nothing. The run is counted instead.\n stats.glyphRunsDropped += 1;\n return;\n }\n batcher.flush(\"glyphs\");\n list.readGlyphs(index, glyphsView);\n const drawn = glyphPass.drawRun(glyphsView, projection);\n stats.glyphRuns += 1;\n stats.glyphs += drawn.glyphs;\n stats.glyphDrawCalls += drawn.drawCalls;\n gl.bindVertexArray(current.vao);\n gl.useProgram(current.program);\n // hb-gpu deliberately does not touch the executor-owned scissor or its rounded-clip\n // uniform; renderer tests pin that boundary. It does replace blend state, so invalidate only\n // the cache which would otherwise suppress the required restoration.\n appliedBlend = null;\n }\n\n function emitAdjacentGlyphCommands(\n list: DrawList<ExecutorTexture | null>,\n firstIndex: number,\n projection: StageProjection,\n current: Program,\n commandMask: CommandMask | undefined,\n ): number {\n if (!glyphPass || !options.batchAdjacentGlyphRuns || !glyphPass.drawRuns) {\n emitGlyphsCommand(list, firstIndex, projection, current);\n return firstIndex;\n }\n\n let count = 0;\n for (let index = firstIndex; index < list.count; index += 1) {\n // A mask gap is a painter-order boundary for retained replay: the skipped command has not\n // been selected for this dirty region, so do not silently make two remaining commands look\n // adjacent. Clips/masks and every other kind fail this same exact test.\n if (\n list.kindAt(index) !== DRAW_GLYPHS ||\n (commandMask && !commandMask.includes(index))\n ) {\n break;\n }\n let view = glyphRunViewPool[count];\n if (!view) {\n view = createGlyphsView(64);\n glyphRunViewPool.push(view);\n }\n list.readGlyphs(index, view);\n count += 1;\n }\n if (count < 2) {\n emitGlyphsCommand(list, firstIndex, projection, current);\n return firstIndex;\n }\n\n glyphRunViews.length = count;\n for (let i = 0; i < count; i += 1) glyphRunViews[i] = glyphRunViewPool[i]!;\n if (glyphPass.canBatchRuns && !glyphPass.canBatchRuns(glyphRunViews)) {\n stats.glyphRunBatchFallbacks += 1;\n emitGlyphsCommand(list, firstIndex, projection, current);\n return firstIndex;\n }\n batcher.flush(\"glyphs\");\n const drawn = glyphPass.drawRuns(glyphRunViews, projection);\n stats.glyphRuns += count;\n stats.glyphs += drawn.glyphs;\n stats.glyphDrawCalls += drawn.drawCalls;\n stats.glyphRunBatches += 1;\n gl.bindVertexArray(current.vao);\n gl.useProgram(current.program);\n appliedBlend = null;\n return firstIndex + count - 1;\n }\n\n function emitScreenEffectCommand(\n list: DrawList<ExecutorTexture | null>,\n index: number,\n projection: StageProjection,\n damage: DamageRect | undefined,\n current: Program,\n ): boolean {\n const effect = list.screenEffectAt(index);\n if (!effect) {\n stats.unknownCommands += 1;\n return false;\n }\n batcher.flush(\"effects\");\n const framebuffer = gl.getParameter(\n gl.DRAW_FRAMEBUFFER_BINDING,\n ) as WebGLFramebuffer | null;\n const succeeded = effect.execute({\n gl,\n framebuffer,\n width: projection.framebufferWidth,\n height: projection.framebufferHeight,\n damage,\n scissor: appliedScissor,\n });\n if (succeeded) stats.screenEffects += 1;\n else stats.screenEffectFailures += 1;\n // The pass may replace every binding/state. Resume exactly as the executor's\n // next command expects; active clip and damage are reapplied, not guessed.\n gl.bindVertexArray(current.vao);\n gl.useProgram(current.program);\n gl.viewport(\n 0,\n 0,\n projection.framebufferWidth,\n projection.framebufferHeight,\n );\n gl.enable(gl.SCISSOR_TEST);\n invalidateAppliedState();\n applyClip(\n projection.toFramebuffer,\n projection.framebufferWidth,\n projection.framebufferHeight,\n damage,\n );\n applyBlend(BLEND_MIX);\n return succeeded;\n }\n\n function emitExternalEffectCommand(\n list: DrawList<ExecutorTexture | null>,\n index: number,\n projection: StageProjection,\n damage: DamageRect | undefined,\n current: Program,\n ): boolean {\n const effect = list.externalEffectAt(index);\n if (!effect) {\n stats.unknownCommands += 1;\n return false;\n }\n batcher.flush(\"effects\");\n const framebuffer = gl.getParameter(\n gl.DRAW_FRAMEBUFFER_BINDING,\n ) as WebGLFramebuffer | null;\n const succeeded = effect.execute({\n gl,\n framebuffer,\n width: projection.framebufferWidth,\n height: projection.framebufferHeight,\n damage,\n scissor: appliedScissor,\n });\n if (succeeded) stats.externalEffects += 1;\n else stats.externalEffectFailures += 1;\n // An external pass owns every mutable GL binding while it paints. The next\n // canvas command must resume the executor contract, never its leftovers.\n gl.bindVertexArray(current.vao);\n gl.useProgram(current.program);\n gl.viewport(\n 0,\n 0,\n projection.framebufferWidth,\n projection.framebufferHeight,\n );\n gl.enable(gl.SCISSOR_TEST);\n invalidateAppliedState();\n applyClip(\n projection.toFramebuffer,\n projection.framebufferWidth,\n projection.framebufferHeight,\n damage,\n );\n applyBlend(BLEND_MIX);\n return succeeded;\n }\n\n return {\n gl,\n stats,\n maxTextureSlots,\n\n warmUp() {\n return ensureProgram() !== null && ensureMeshProgram() !== null;\n },\n\n releaseCompiled(plan) {\n const cache = compiledGpuPlans.get(plan);\n if (cache) releaseGpuPlan(cache, true);\n },\n\n execute(list, projection, executeOptions) {\n const current = ensureProgram();\n if (!current) return false;\n\n stats.commands = 0;\n stats.quads = 0;\n stats.batches = 0;\n stats.textureBinds = 0;\n stats.scissorChanges = 0;\n stats.blendChanges = 0;\n stats.ninePatches = 0;\n stats.ninePatchQuads = 0;\n stats.polylines = 0;\n stats.polylineQuads = 0;\n stats.texturedMeshes = 0;\n stats.texturedMeshTriangles = 0;\n stats.texturedMeshDrawCalls = 0;\n stats.glyphRuns = 0;\n stats.glyphs = 0;\n stats.glyphDrawCalls = 0;\n stats.glyphRunBatches = 0;\n stats.glyphRunBatchFallbacks = 0;\n stats.glyphRunsDropped = 0;\n stats.screenEffects = 0;\n stats.screenEffectFailures = 0;\n stats.externalEffects = 0;\n stats.externalEffectFailures = 0;\n stats.rotatedClipFallbacks = 0;\n stats.unbalancedClipPops = 0;\n stats.unknownCommands = 0;\n stats.maxBatchQuads = 0;\n stats.flushes.textureSlots = 0;\n stats.flushes.colorMatrices = 0;\n stats.flushes.blend = 0;\n stats.flushes.clip = 0;\n stats.flushes.glyphs = 0;\n stats.flushes.effects = 0;\n stats.flushes.meshes = 0;\n stats.flushes.compiled = 0;\n stats.flushes.end = 0;\n stats.compiledPlanBuilds = 0;\n stats.compiledPlanReuses = 0;\n stats.compiledTemplateRangeUpdates = 0;\n stats.reusedSelections = 0;\n stats.reusedBatches = 0;\n stats.compiledGpuFullUploads = 0;\n stats.compiledGpuRangeUploads = 0;\n stats.compiledCachedDrawCalls = 0;\n\n const compiled =\n executeOptions?.compiled?.list === list\n ? executeOptions.compiled\n : undefined;\n let gpuCache: CachedGpuPlan | null = null;\n if (compiled) {\n const refresh = compiled.refresh();\n stats.compiledPlanBuilds = refresh.rebuilt ? 1 : 0;\n stats.compiledPlanReuses = refresh.rebuilt ? 0 : 1;\n stats.compiledTemplateRangeUpdates = refresh.rangeUpdates;\n // Selection is caller-owned (`plan.select`); execute never allocates or\n // rebuilds one behind a direct frame's back.\n stats.reusedSelections = 0;\n stats.reusedBatches = refresh.rebuilt ? 0 : compiled.batches.length;\n const existing = compiledGpuPlans.get(compiled);\n if (\n existing &&\n (existing.generation !== refresh.planGeneration ||\n (existing.contentRevision !== refresh.contentRevision &&\n existing.contentRevision !== refresh.deltaBaseRevision))\n ) {\n releaseGpuPlan(existing, true);\n }\n const currentCache = compiledGpuPlans.get(compiled);\n gpuCache = currentCache\n ? currentCache.contentRevision === refresh.contentRevision\n ? updateGpuPlan(\n currentCache,\n current,\n NO_CHANGED_COMMANDS,\n refresh.contentRevision,\n )\n : updateGpuPlan(\n currentCache,\n current,\n refresh.changedCommands,\n refresh.contentRevision,\n )\n : buildGpuPlan(\n compiled,\n current,\n refresh.planGeneration,\n refresh.contentRevision,\n );\n }\n\n clipStack.reset();\n batcher.reset();\n\n const width = projection.framebufferWidth;\n const height = projection.framebufferHeight;\n gl.bindVertexArray(current.vao);\n gl.useProgram(current.program);\n gl.viewport(0, 0, width, height);\n if (current.uProjection) {\n gl.uniform4f(\n current.uProjection,\n projection.toClip[0],\n projection.toClip[1],\n projection.toClip[2],\n projection.toClip[3],\n );\n }\n gl.disable(gl.DEPTH_TEST);\n gl.disable(gl.CULL_FACE);\n gl.enable(gl.BLEND);\n gl.enable(gl.SCISSOR_TEST);\n // Force every cached state to be re-applied: this executor does not own the\n // context and cannot assume anything about what else drew into it.\n invalidateAppliedState();\n applyClip(\n projection.toFramebuffer,\n width,\n height,\n executeOptions?.damage,\n );\n applyBlend(BLEND_MIX);\n\n if (executeOptions?.clear !== false) {\n const clearColor = executeOptions?.clearColor;\n gl.clearColor(\n clearColor?.[0] ?? 0,\n clearColor?.[1] ?? 0,\n clearColor?.[2] ?? 0,\n clearColor?.[3] ?? 0,\n );\n gl.clear(gl.COLOR_BUFFER_BIT);\n }\n\n let clipSerial = 0;\n let screenEffectFailed = false;\n const count = list.count;\n for (let index = 0; index < count; index += 1) {\n if (screenEffectFailed) break;\n if (\n executeOptions?.commandMask &&\n !executeOptions.commandMask.includes(index)\n ) {\n continue;\n }\n const cached = executeOptions?.commandMask\n ? gpuCache?.runsForCommand[index]\n : gpuCache?.runsAt[index];\n if (cached) {\n const first = executeOptions?.commandMask\n ? (gpuCache?.itemsForCommand[index] ?? 0)\n : 0;\n let cachedCount = 1;\n if (!executeOptions?.commandMask)\n cachedCount = cached.commands.length;\n else {\n while (\n first + cachedCount < cached.commands.length &&\n executeOptions.commandMask.includes(\n cached.commands[first + cachedCount],\n )\n ) {\n cachedCount += 1;\n }\n }\n batcher.flush(\"compiled\");\n drawCachedRange(cached, first, cachedCount, current);\n stats.commands += cachedCount;\n index = cached.commands[first + cachedCount - 1];\n continue;\n }\n stats.commands += 1;\n switch (list.kindAt(index)) {\n case DRAW_QUAD:\n emitQuadCommand(list, index, compiled);\n break;\n case DRAW_NINE_PATCH:\n emitNinePatchCommand(list, index);\n break;\n case DRAW_POLYLINE:\n emitPolylineCommand(list, index);\n break;\n case DRAW_GLYPHS:\n index = emitAdjacentGlyphCommands(\n list,\n index,\n projection,\n current,\n executeOptions?.commandMask,\n );\n break;\n case DRAW_TEXTURED_MESH:\n emitTexturedMeshCommand(list, index, projection, current);\n break;\n case DRAW_SCREEN_EFFECT:\n screenEffectFailed = !emitScreenEffectCommand(\n list,\n index,\n projection,\n executeOptions?.damage,\n current,\n );\n break;\n case DRAW_EXTERNAL_EFFECT:\n screenEffectFailed = !emitExternalEffectCommand(\n list,\n index,\n projection,\n executeOptions?.damage,\n current,\n );\n break;\n case DRAW_CLIP_PUSH: {\n list.readClipRect(index, clipView);\n // Flush the pending batch FIRST, under the clip it was drawn with —\n // see the module note on the order of operations.\n clipSerial += 1;\n batcher.setClipEpoch(clipSerial);\n clipStack.push(clipView);\n applyClip(\n projection.toFramebuffer,\n width,\n height,\n executeOptions?.damage,\n );\n break;\n }\n case DRAW_CLIP_POP: {\n if (clipStack.depth === 0) {\n stats.unbalancedClipPops += 1;\n break;\n }\n clipSerial += 1;\n batcher.setClipEpoch(clipSerial);\n clipStack.pop();\n applyClip(\n projection.toFramebuffer,\n width,\n height,\n executeOptions?.damage,\n );\n break;\n }\n // THE GUARD THIS SWITCH DID NOT HAVE. Without it a kind the IR grew and this file did\n // not learn falls straight through, uncounted except in `stats.commands` — a frame\n // missing everything of that kind, reporting as a frame that drew all of it.\n default:\n stats.unknownCommands += 1;\n break;\n }\n }\n\n batcher.flush(\"end\");\n stats.rotatedClipFallbacks = clipStack.rotatedFallbacks;\n gl.bindVertexArray(null);\n gl.disable(gl.SCISSOR_TEST);\n return !screenEffectFailed;\n },\n\n invalidate() {\n // No deletes: after a context loss the names are already invalid, and\n // asking a dead context to free them is a stream of GL errors at best.\n program = null;\n meshProgram = null;\n ownedWhite = null;\n appliedBlend = null;\n appliedRoundedRadius = -1;\n for (const cache of [...liveCompiledGpuPlans])\n releaseGpuPlan(cache, false);\n },\n\n dispose() {\n for (const cache of [...liveCompiledGpuPlans])\n releaseGpuPlan(cache, true);\n if (program) {\n gl.deleteProgram(program.program);\n gl.deleteVertexArray(program.vao);\n gl.deleteBuffer(program.cornerBuffer);\n gl.deleteBuffer(program.instanceBuffer);\n program = null;\n }\n if (ownedWhite) {\n gl.deleteTexture(ownedWhite.texture);\n ownedWhite = null;\n }\n if (meshProgram) {\n gl.deleteProgram(meshProgram.program);\n gl.deleteVertexArray(meshProgram.vao);\n gl.deleteBuffer(meshProgram.vertexBuffer);\n gl.deleteBuffer(meshProgram.indexBuffer);\n meshProgram = null;\n }\n },\n };\n}\n","/** DrawList adapters for the DOM-free canvas-effects WebGL stage. */\n\nimport type {\n HeadlessGodotParticleDirectPass,\n HeadlessGodotParticleDirectRenderInput,\n HeadlessShaderProducer,\n HeadlessShaderRenderInput,\n} from \"@godot-scene-web/canvas-effects/webgl\";\nimport type {\n ExternalEffectDrawCommand,\n ExternalEffectDrawContext,\n ScreenEffectDrawCommand,\n ScreenEffectDrawContext,\n} from \"./draw-list\";\n\n/** Bind a GPU screen producer at one DrawList painter position. */\nexport function createHeadlessScreenEffectCommand(\n producer: HeadlessShaderProducer,\n input: HeadlessShaderRenderInput,\n): ScreenEffectDrawCommand {\n return {\n screenDependent: true,\n execute(context: ScreenEffectDrawContext) {\n return producer.renderScreen(input, context).ok;\n },\n };\n}\n\n/** Bind a direct GPU particle pass at one DrawList painter position. */\nexport function createHeadlessGodotParticleDirectEffect(\n pass: HeadlessGodotParticleDirectPass,\n input: HeadlessGodotParticleDirectRenderInput,\n): ExternalEffectDrawCommand {\n return {\n execute(context: ExternalEffectDrawContext) {\n return pass.draw(input, context).ok;\n },\n };\n}\n","/**\n * The stage: a WebGL2 context of its OWN on a caller-supplied canvas, its exact\n * backing-store size, the design->screen projection every other module in this\n * package reads, and the context-loss plumbing.\n *\n * THE ONLY MODULE IN `@godot-scene-web/canvas` THAT TOUCHES A CANVAS. Everything\n * else takes a `WebGL2RenderingContext` and does arithmetic; keeping the DOM\n * surface to one file is what makes the rest of the package testable without a\n * browser and reusable off the main thread.\n *\n * ITS OWN CONTEXT, not `html`'s shared one. The shared context exists so that N\n * per-node effect canvases on one page do not each burn one of the browser's ~16\n * live contexts; it renders offscreen and BLITS onto each node. The stage is the\n * opposite shape — ONE canvas for the whole scene, presented directly — so it\n * neither needs the blit nor wants to share a drawing buffer that is sized,\n * cleared and grown by two other runtimes on their own schedule.\n *\n * THE CONTEXT ATTRIBUTES, and why each one:\n *\n * - `alpha: true` — the stage composites over whatever the page puts behind it\n * (letterbox bars, a background layer), so it must carry real transparency.\n * - `premultipliedAlpha: true` — the contract stated end to end: textures upload\n * premultiplied (`./textures`), tints are premultiplied (the draw-list's own\n * documentation), every fragment emits `vec4(rgb*a, a)`, the MIX blend is\n * `(ONE, ONE_MINUS_SRC_ALPHA)`. This flag changes no byte in the drawing\n * buffer; it tells the compositor how to READ them. Declare it wrong and\n * nothing errors — the page simply multiplies by alpha a second time and every\n * translucent pixel comes out dark. `html/webgl/shared-gl.ts` has the long\n * version of this note and the bug that produced it.\n * - `stencil: false`, `depth: false` — a painter's-algorithm 2D renderer uses\n * neither, and both cost drawing-buffer memory on every device.\n * - `antialias: false` — there is no geometry to multisample: every edge in the\n * scene is a texture's own alpha, which LINEAR filtering already smooths. MSAA\n * here would allocate a multisample buffer and resolve it every frame to change\n * nothing.\n * - `preserveDrawingBuffer: false` — the stage clears and repaints every frame,\n * and preserving forces the implementation to keep a copy. Measurement trap\n * that follows: once the stage is idle, a JS-side readback (`toDataURL`,\n * `drawImage` of the canvas) returns an EMPTY image while the composited\n * frame on screen is correct — the drawing buffer is gone after present, by\n * design. Judge presentation only by compositor capture (a real screenshot\n * of the tab), never by reading the canvas back.\n * - `desynchronized` is deliberately NOT set. It can cut latency by letting the\n * canvas bypass the compositor, but it also makes readback and screenshot\n * behaviour implementation-defined — which is exactly what the pixel tests\n * assert on — and on several drivers it silently disables the alpha compositing\n * path the point above depends on. A latency measurement can turn it on later,\n * with a test that proves the composite still holds.\n */\n\n/** The subset of a canvas the stage needs. Structural so that both an\n * `HTMLCanvasElement` and an `OffscreenCanvas` satisfy it. */\nexport interface StageCanvas {\n width: number;\n height: number;\n getContext(\n contextId: \"webgl2\",\n options?: WebGLContextAttributes,\n ): WebGL2RenderingContext | null;\n addEventListener(type: string, listener: (event: Event) => void): void;\n removeEventListener(type: string, listener: (event: Event) => void): void;\n}\n\n/** How design coordinates reach the screen, in the two forms consumers need. */\nexport interface StageProjection {\n /** Exact scene coordinate extent, independent of float32 matrix rounding. */\n readonly designWidth: number;\n readonly designHeight: number;\n /**\n * Design -> clip space as `(scaleX, scaleY, translateX, translateY)`:\n * `clip = design * scale + translate`. `scaleY` is NEGATIVE — design space\n * measures Y downwards and clip space upwards.\n */\n readonly toClip: Float32Array;\n /**\n * Design -> framebuffer pixels as a 2x3 in the draw-list's `Transform2D` order\n * `[xx, xy, yx, yy, originX, originY]`, with Y measured DOWN from the top. This\n * is what `./clip-stack` turns into a scissor box.\n */\n readonly toFramebuffer: Float32Array;\n /** The drawing buffer's REAL size — see {@link CanvasStage.setStageSize}. */\n readonly framebufferWidth: number;\n readonly framebufferHeight: number;\n}\n\nexport interface CanvasStageOptions {\n canvas: StageCanvas;\n /** The scene's own coordinate extent, e.g. 1920x1080. */\n designWidth: number;\n designHeight: number;\n /**\n * Request an alpha-capable drawing buffer. Omitted preserves the stage's\n * compositing default (`true`); an opaque scene may opt out when it paints\n * every output pixel itself.\n */\n alpha?: boolean;\n /**\n * Called after `webglcontextlost`. Every GL object the caller holds is dead:\n * drop programs, buffers and textures (`CanvasTextureCache.reset`,\n * `CanvasExecutor.invalidate`) without calling into GL to free them.\n */\n onContextLost?(): void;\n /** Called after `webglcontextrestored`: rebuild programs, buffers, textures. */\n onContextRestored?(): void;\n}\n\nexport interface CanvasStage {\n readonly canvas: StageCanvas;\n readonly gl: WebGL2RenderingContext;\n readonly designWidth: number;\n readonly designHeight: number;\n /** The drawing buffer's real width/height, which may be smaller than asked. */\n readonly stageWidth: number;\n readonly stageHeight: number;\n /** True between `webglcontextlost` and `webglcontextrestored`. */\n readonly contextLost: boolean;\n /**\n * Whether the context actually has an alpha channel. This is read from the\n * created context when available, rather than assuming the request won.\n */\n readonly alpha: boolean;\n /**\n * Size the backing store EXACTLY. Not grow-only: a stage that kept the largest\n * size it had ever been asked for would keep a 4K drawing buffer alive after a\n * window shrank, and would leave `gl.viewport` and the projection describing a\n * buffer bigger than the one being presented. Re-reads the ACHIEVED size\n * afterwards, because setting `canvas.width` only REQUESTS an allocation — an\n * implementation may return a smaller buffer, and trusting the attribute over\n * the buffer is how a renderer ends up drawing into rows that do not exist.\n */\n setStageSize(width: number, height: number): void;\n /** Change the design extent (a scene that re-lays-out for a new aspect). */\n setDesignSize(width: number, height: number): void;\n /** The current projection. The returned object is reused; read it, don't keep it. */\n projection(): StageProjection;\n /** Set `gl.viewport` to the whole drawing buffer. */\n applyViewport(): void;\n /** Detach the context-loss listeners. Does not delete the context. */\n dispose(): void;\n}\n\nconst CONTEXT_ATTRIBUTES: WebGLContextAttributes = {\n alpha: true,\n premultipliedAlpha: true,\n stencil: false,\n depth: false,\n antialias: false,\n preserveDrawingBuffer: false,\n};\n\n/** The attributes the stage asks for, exported so a test can assert the contract\n * rather than restate it. */\nexport const STAGE_CONTEXT_ATTRIBUTES: Readonly<WebGLContextAttributes> =\n CONTEXT_ATTRIBUTES;\n\n/**\n * Create a stage on `canvas`, or `null` when the browser gives no WebGL2 context.\n *\n * Note what is NOT here: no software-renderer refusal. `html`'s shared context\n * declines SwiftShader/llvmpipe because running full-screen procedural fragment\n * shaders on a CPU rasterizer costs more than the CSS fallback it has. The stage\n * has no fallback to fall back TO — it is the renderer — and its fragment shader\n * is a texture fetch and a multiply, which software GL runs perfectly well. The\n * decision of whether this device should use the canvas renderer at all belongs\n * to the consumer, one level up, where the alternative is known.\n */\nexport function createCanvasStage(\n options: CanvasStageOptions,\n): CanvasStage | null {\n const canvas = options.canvas;\n // Do not mutate the exported default object: callers and tests use it as the\n // package-wide transparent-stage contract. The opaque request is one stage's\n // private getContext dictionary.\n const contextAttributes =\n options.alpha === undefined\n ? CONTEXT_ATTRIBUTES\n : { ...CONTEXT_ATTRIBUTES, alpha: options.alpha };\n let gl: WebGL2RenderingContext | null = null;\n try {\n gl = canvas.getContext(\"webgl2\", contextAttributes);\n } catch {\n gl = null;\n }\n if (!gl) return null;\n const context = gl;\n const alpha =\n context.getContextAttributes?.()?.alpha ?? contextAttributes.alpha ?? true;\n\n let designWidth = Math.max(1, options.designWidth);\n let designHeight = Math.max(1, options.designHeight);\n let stageWidth = 0;\n let stageHeight = 0;\n let contextLost = false;\n\n const projection: {\n designWidth: number;\n designHeight: number;\n toClip: Float32Array;\n toFramebuffer: Float32Array;\n framebufferWidth: number;\n framebufferHeight: number;\n } = {\n designWidth,\n designHeight,\n toClip: new Float32Array(4),\n toFramebuffer: new Float32Array([1, 0, 0, 1, 0, 0]),\n framebufferWidth: 0,\n framebufferHeight: 0,\n };\n\n function readBackingSize(): void {\n // The ACHIEVED buffer, not the requested attribute. A context that came back\n // short still reports the truth here, and every rect this stage produces has\n // to be measured against the truth.\n const width = context.drawingBufferWidth || canvas.width;\n const height = context.drawingBufferHeight || canvas.height;\n stageWidth = Math.max(1, width);\n stageHeight = Math.max(1, height);\n }\n\n function refreshProjection(): void {\n projection.designWidth = designWidth;\n projection.designHeight = designHeight;\n projection.toClip[0] = 2 / designWidth;\n projection.toClip[1] = -2 / designHeight;\n projection.toClip[2] = -1;\n projection.toClip[3] = 1;\n projection.toFramebuffer[0] = stageWidth / designWidth;\n projection.toFramebuffer[1] = 0;\n projection.toFramebuffer[2] = 0;\n projection.toFramebuffer[3] = stageHeight / designHeight;\n projection.toFramebuffer[4] = 0;\n projection.toFramebuffer[5] = 0;\n projection.framebufferWidth = stageWidth;\n projection.framebufferHeight = stageHeight;\n }\n\n readBackingSize();\n refreshProjection();\n\n const onLost = (event: Event): void => {\n // WITHOUT `preventDefault` the browser never fires `webglcontextrestored` —\n // the canvas is simply dead for the rest of the page's life.\n event.preventDefault();\n contextLost = true;\n options.onContextLost?.();\n };\n const onRestored = (): void => {\n contextLost = false;\n // The context OBJECT survives a restore; only its resources are gone. So\n // there is nothing to re-`getContext`, but the drawing buffer was\n // reallocated and has to be re-measured.\n readBackingSize();\n refreshProjection();\n options.onContextRestored?.();\n };\n canvas.addEventListener(\"webglcontextlost\", onLost);\n canvas.addEventListener(\"webglcontextrestored\", onRestored);\n\n return {\n canvas,\n gl: context,\n get designWidth() {\n return designWidth;\n },\n get designHeight() {\n return designHeight;\n },\n get stageWidth() {\n return stageWidth;\n },\n get stageHeight() {\n return stageHeight;\n },\n get contextLost() {\n return contextLost;\n },\n get alpha() {\n return alpha;\n },\n\n setStageSize(width, height) {\n const w = Math.max(1, Math.floor(width));\n const h = Math.max(1, Math.floor(height));\n // Guarded because ASSIGNING `canvas.width` reallocates and clears the\n // drawing buffer even when the value is unchanged — a resize handler that\n // fires on every scroll would otherwise blank the stage.\n if (canvas.width !== w) canvas.width = w;\n if (canvas.height !== h) canvas.height = h;\n readBackingSize();\n refreshProjection();\n },\n\n setDesignSize(width, height) {\n designWidth = Math.max(1, width);\n designHeight = Math.max(1, height);\n refreshProjection();\n },\n\n projection() {\n return projection;\n },\n\n applyViewport() {\n context.viewport(0, 0, stageWidth, stageHeight);\n },\n\n dispose() {\n canvas.removeEventListener(\"webglcontextlost\", onLost);\n canvas.removeEventListener(\"webglcontextrestored\", onRestored);\n },\n };\n}\n","import type { DamageRect } from \"./damage\";\nimport type { DrawList } from \"./draw-list\";\nimport type {\n CanvasExecutor,\n ExecuteOptions,\n ExecutorTexture,\n} from \"./executor-webgl\";\nimport type { StageProjection } from \"./present\";\nimport { isPartialReplayMask, type ReplayMaskScratch } from \"./replay\";\n\n/** An RGBA8 framebuffer that retains scene pixels between frames. */\nexport interface RetainedSurface {\n readonly gl: WebGL2RenderingContext;\n /** The achieved, integer backing dimensions. Zero means unallocated. */\n readonly width: number;\n readonly height: number;\n /** GPU allocation is live. It says nothing about whether it contains a frame. */\n readonly allocated: boolean;\n /** True only after a full replay; `present` refuses unseeded pixels. */\n readonly contentValid: boolean;\n /**\n * Allocate an RGBA8 texture/FBO at the exact snapped requested size. A size\n * change discards old pixels, so callers must replay a full frame afterwards.\n */\n resize(width: number, height: number): boolean;\n /**\n * Replay into the retained target. `damage` is top-left framebuffer pixels;\n * passing it restricts both clear and draw to that region. This operation is\n * explicit: direct `CanvasExecutor.execute` calls can neither seed this FBO\n * nor present it.\n */\n replay(\n executor: CanvasExecutor,\n list: DrawList<ExecutorTexture | null>,\n projection: StageProjection,\n options?: RetainedReplayOptions,\n ): boolean;\n /**\n * Replay a prevalidated exact cover into one retained target binding. Every\n * region keeps its own damage scissor and clip-complete mask, so painter\n * order, clips and blend modes are identical to individual partial replays.\n * The whole set is validated before its first clear; any failure invalidates\n * retained content and a caller must seed rather than present it.\n */\n replayRegions(\n executor: CanvasExecutor,\n list: DrawList<ExecutorTexture | null>,\n projection: StageProjection,\n regions: readonly RetainedReplayRegion[],\n options?: RetainedReplayRegionsOptions,\n ): boolean;\n /** Blit the retained texture once, 1:1, to the default framebuffer. */\n present(): boolean;\n /** Forget retained pixels while keeping the allocated FBO for the next seed. */\n invalidateContent(): void;\n /** Drop dead context handles without calling GL after a context loss. */\n invalidate(): void;\n /** Delete owned GL resources while the context is live. */\n dispose(): void;\n}\n\nexport interface RetainedReplayOptions {\n /**\n * A physical-pixel damage region. Partial retained replay deliberately\n * requires one; an unbounded replay is a seed and therefore renders the\n * complete list without a mask.\n */\n damage?: DamageRect;\n /**\n * A validated, clip-complete selection from `createReplayMaskScratch` or a\n * compiled draw-list. A generic `CommandMask` is intentionally not accepted:\n * it could omit an unknown or screen-dependent command and leave stale FBO\n * pixels that `present()` would otherwise expose.\n */\n mask?: ReplayMaskScratch;\n /** Forwarded only for rare custom executor behaviour; clear defaults to true. */\n execute?: Omit<ExecuteOptions, \"clear\" | \"damage\" | \"commandMask\">;\n}\n\n/** One independently scissored, clip-complete member of a retained replay set. */\nexport interface RetainedReplayRegion {\n damage: DamageRect;\n mask: ReplayMaskScratch;\n}\n\n/** Shared executor options for every region in one retained replay set. */\nexport interface RetainedReplayRegionsOptions {\n execute?: Omit<ExecuteOptions, \"clear\" | \"damage\" | \"commandMask\">;\n}\n\n/** Snap a CSS/device calculation once at the allocation boundary. */\nexport function snapRetainedSize(value: number): number {\n return Number.isFinite(value) ? Math.max(1, Math.round(value)) : 1;\n}\n\nfunction isValidDamage(\n damage: DamageRect,\n width: number,\n height: number,\n): boolean {\n return (\n Number.isFinite(damage.x) &&\n Number.isFinite(damage.y) &&\n Number.isFinite(damage.width) &&\n Number.isFinite(damage.height) &&\n damage.width > 0 &&\n damage.height > 0 &&\n damage.x >= 0 &&\n damage.y >= 0 &&\n damage.x + damage.width <= width &&\n damage.y + damage.height <= height\n );\n}\n\n/**\n * Create a retained RGBA8 texture/FBO. It deliberately does not create a\n * canvas or context — a stage owns that DOM-facing concern — and it does not\n * monkey-patch an executor. Retention is opt-in per replay/present call.\n */\nexport function createRetainedSurface(\n gl: WebGL2RenderingContext,\n): RetainedSurface {\n let texture: WebGLTexture | null = null;\n let framebuffer: WebGLFramebuffer | null = null;\n let width = 0;\n let height = 0;\n let contentValid = false;\n\n function discard(callGl: boolean): void {\n if (callGl) {\n if (framebuffer) gl.deleteFramebuffer(framebuffer);\n if (texture) gl.deleteTexture(texture);\n }\n framebuffer = null;\n texture = null;\n width = 0;\n height = 0;\n contentValid = false;\n }\n\n function resize(requestedWidth: number, requestedHeight: number): boolean {\n const nextWidth = snapRetainedSize(requestedWidth);\n const nextHeight = snapRetainedSize(requestedHeight);\n if (\n texture &&\n framebuffer &&\n width === nextWidth &&\n height === nextHeight\n ) {\n return true;\n }\n const nextTexture = gl.createTexture();\n const nextFramebuffer = gl.createFramebuffer();\n if (!nextTexture || !nextFramebuffer) {\n if (nextTexture) gl.deleteTexture(nextTexture);\n if (nextFramebuffer) gl.deleteFramebuffer(nextFramebuffer);\n return false;\n }\n gl.bindTexture(gl.TEXTURE_2D, nextTexture);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n gl.texImage2D(\n gl.TEXTURE_2D,\n 0,\n gl.RGBA8,\n nextWidth,\n nextHeight,\n 0,\n gl.RGBA,\n gl.UNSIGNED_BYTE,\n null,\n );\n gl.bindFramebuffer(gl.FRAMEBUFFER, nextFramebuffer);\n gl.framebufferTexture2D(\n gl.FRAMEBUFFER,\n gl.COLOR_ATTACHMENT0,\n gl.TEXTURE_2D,\n nextTexture,\n 0,\n );\n const complete =\n gl.checkFramebufferStatus(gl.FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE;\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n if (!complete) {\n gl.deleteFramebuffer(nextFramebuffer);\n gl.deleteTexture(nextTexture);\n return false;\n }\n discard(true);\n texture = nextTexture;\n framebuffer = nextFramebuffer;\n width = nextWidth;\n height = nextHeight;\n // A texture allocation starts undefined. Never present it and never let a\n // partial replay pretend its untouched pixels belong to this frame.\n contentValid = false;\n return true;\n }\n\n return {\n gl,\n get width() {\n return width;\n },\n get height() {\n return height;\n },\n get allocated() {\n return texture !== null && framebuffer !== null;\n },\n get contentValid() {\n return contentValid;\n },\n resize,\n\n replay(executor, list, projection, options) {\n if (!texture || !framebuffer) return false;\n const partial =\n options?.damage !== undefined || options?.mask !== undefined;\n // A masked draw is always partial, even if its current indices happen to\n // cover every command. A full seed has no damage and no mask; partial\n // replay requires the module-owned, fail-closed selection plus a bounded\n // physical-pixel region.\n if (\n partial &&\n (!options?.damage ||\n !options.mask ||\n !isValidDamage(options.damage, width, height) ||\n !isPartialReplayMask(options.mask, list))\n ) {\n return false;\n }\n if (partial && !contentValid) return false;\n // The retained target has no scaling policy. A mismatched projection would\n // draw to one size and blit a different one, leaving stale border pixels.\n if (\n projection.framebufferWidth !== width ||\n projection.framebufferHeight !== height\n ) {\n return false;\n }\n gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);\n const execute: ExecuteOptions = {\n ...options?.execute,\n clear: true,\n damage: options?.damage,\n commandMask: options?.mask,\n };\n try {\n const replayed = executor.execute(list, projection, execute);\n if (!replayed) {\n // A lazy shader/glyph pass may have touched some pixels before it\n // declines. The next frame must seed, never blit a half-reconstructed\n // retained image.\n contentValid = false;\n return false;\n }\n if (!partial) contentValid = true;\n return replayed;\n } catch (error) {\n contentValid = false;\n throw error;\n } finally {\n // A lazy executor can decline its program. Do not strand the FBO as the\n // draw target: a later direct frame must still reach the stage canvas.\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n }\n },\n\n replayRegions(executor, list, projection, regions, options) {\n // Unlike one-region `replay`, this operation owns an atomic multi-pass\n // contract: reject the complete set before the first clear, and never\n // leave a partly reconstructed target eligible for `present`.\n if (\n !texture ||\n !framebuffer ||\n !contentValid ||\n regions.length === 0 ||\n projection.framebufferWidth !== width ||\n projection.framebufferHeight !== height\n ) {\n contentValid = false;\n return false;\n }\n for (const region of regions) {\n if (\n !isValidDamage(region.damage, width, height) ||\n !isPartialReplayMask(region.mask, list)\n ) {\n contentValid = false;\n return false;\n }\n }\n gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);\n try {\n for (const region of regions) {\n const replayed = executor.execute(list, projection, {\n ...options?.execute,\n clear: true,\n damage: region.damage,\n commandMask: region.mask,\n });\n if (!replayed) {\n contentValid = false;\n return false;\n }\n }\n return true;\n } catch (error) {\n contentValid = false;\n throw error;\n } finally {\n // Keep the direct path aimed at the stage even after a later region\n // refuses a lazy shader/glyph pass.\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n }\n },\n\n present() {\n if (!texture || !framebuffer || !contentValid) return false;\n // Scissor is context state. A damage replay can leave it tight, and a\n // raster-path blit obeying that state would present only the dirty tile.\n gl.disable(gl.SCISSOR_TEST);\n gl.bindFramebuffer(gl.READ_FRAMEBUFFER, framebuffer);\n gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);\n gl.blitFramebuffer(\n 0,\n 0,\n width,\n height,\n 0,\n 0,\n width,\n height,\n gl.COLOR_BUFFER_BIT,\n gl.NEAREST,\n );\n gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);\n return true;\n },\n\n invalidateContent() {\n // This is intentionally separate from `invalidate()`: an unrelated\n // direct executor frame may make its own program stale, but it must not\n // deallocate the retained target or turn a later explicit present into a\n // hidden allocation churn.\n contentValid = false;\n },\n\n invalidate() {\n discard(false);\n },\n dispose() {\n discard(true);\n },\n };\n}\n","/**\n * The executor's texture cache — PER CONTEXT, and its own rather than a\n * generalization of `@godot-scene-web/html`'s.\n *\n * WHY NOT REUSE `html/webgl/shared-gl`'s CACHE. That module opens with a note\n * saying its single context and its single module-scoped texture map are\n * load-bearing: both live runtimes (shaders and particles) must share ONE\n * WebGL2 context, because a page with many cards would otherwise walk into the\n * browser's ~16-live-context limit, and ONE cache, so identical urls upload once.\n * Threading a context parameter through it would turn a documented singleton into\n * a keyed registry — a real change to an invariant two shipping runtimes rest on,\n * to serve a consumer that wants DIFFERENT pixels anyway:\n *\n * - a `WebGLTexture` belongs to the context that made it and cannot be bound in\n * another, so the stage's own context could not use those entries even if it\n * could see them;\n * - shared-gl uploads STRAIGHT alpha (`UNPACK_PREMULTIPLY_ALPHA_WEBGL` false),\n * because its shaders do Godot's multiply themselves; this cache uploads\n * PREMULTIPLIED (see below), which is a different byte in every texel;\n * - shared-gl's entries are immortal and url-keyed with a load listener; a stage\n * that paints hundreds of megabytes of card atlas needs refcounts and a\n * `reset()` for context loss.\n *\n * So this is option (b) from the brief: a small cache of its own, ~150 lines, no\n * change to a package two runtimes depend on.\n *\n * PREMULTIPLIED UPLOAD IS THE POINT, not a detail. `LINEAR` filtering blends\n * texels; blending STRAIGHT colour weights a fully transparent texel's (usually\n * black, or garbage) RGB equally with its opaque neighbour's, so every sprite\n * edge gets a dark fringe and every atlas region bleeds its padding. Blending\n * PREMULTIPLIED colour weights each texel's contribution by its own alpha, which\n * is the arithmetic filtering is supposed to be doing. It also means a texel and\n * the quad's tint compose with one componentwise multiply, and it is the same\n * convention the stage canvas is declared with — one statement of the rule from\n * the PNG to the compositor.\n *\n * SOURCES MUST BE READY. This module never decodes: it uploads what it is handed.\n * A half-loaded `HTMLImageElement` uploads as nothing useful, so the caller\n * decodes (`decode()`, `createImageBitmap`, a canvas it drew itself) and hands\n * over a finished source. That keeps the whole package clear of DOM lifecycle —\n * reading `.width` off an object someone else created is the only thing here that\n * touches a DOM-shaped value.\n */\n\n/** Anything WebGL can upload directly. */\nexport type CanvasTextureSource = TexImageSource;\n\n/** A cached texture. `width`/`height` are the UPLOADED pixel dimensions, which is\n * what normalizes a draw-list's page-pixel source rect into UVs. */\nexport interface CanvasTextureHandle {\n readonly texture: WebGLTexture;\n readonly width: number;\n readonly height: number;\n}\n\nexport interface TextureCacheStats {\n /** Live entries. */\n entries: number;\n /** Pixel uploads made: `texImage2D` calls plus the `texSubImage2D` re-uploads\n * {@link CanvasTextureCache.update} does into storage that already fits. */\n uploads: number;\n /** Of those, the ones that had to RE-SPECIFY the texture's storage — a first\n * upload, or an `update` whose source changed size. The difference between\n * this and `uploads` is how often the re-upload fast path was taken, which is\n * the number a consumer that streams into one key wants to watch. */\n respecs: number;\n /** Entries deleted because their last reference was released. */\n evictions: number;\n /** Resident RGBA bytes, including every generated mip level. */\n bytes: number;\n}\n\n/** Sampling and source-alpha options shared by texture acquisition methods.\n *\n * Mipmaps make minification stable, but their filtered levels can sample pixels\n * outside an atlas rect. Use them only for standalone images or padded atlases.\n */\nexport interface CanvasTextureOptions {\n /** `true` when the source already contains `rgb * a`. Defaults to false. */\n premultiplied?: boolean;\n /** Generate a complete mip chain. Not suitable for unpadded atlas pages. */\n mipmap?: boolean;\n /** Minification filter. Defaults to LINEAR, or LINEAR_MIPMAP_LINEAR with mips. */\n minFilter?: number;\n /** Magnification filter. Defaults to LINEAR; NEAREST is supported. */\n magFilter?: number;\n}\n\nexport interface CanvasTextureCache {\n readonly stats: TextureCacheStats;\n /** The 1x1 opaque-white texel every untextured quad samples, so a solid fill\n * needs no second shader and no special slot. */\n white(): CanvasTextureHandle;\n /** Look up without uploading or retaining. */\n peek(key: string): CanvasTextureHandle | undefined;\n /**\n * Upload `source` under `key` and take a reference. A key already present is\n * NOT re-uploaded (that is the decode-once guarantee) — only referenced again;\n * use {@link CanvasTextureCache.update} to replace its pixels.\n */\n acquire(\n key: string,\n source: CanvasTextureSource,\n options?: CanvasTextureOptions,\n ): CanvasTextureHandle;\n /**\n * Same, from raw RGBA bytes. `premultiplied` says whether `pixels` already\n * carries `rgb*a`; when it does not, the multiply happens HERE in JS rather\n * than through `UNPACK_PREMULTIPLY_ALPHA_WEBGL`, whose behaviour over an\n * `ArrayBufferView` is not worth depending on.\n */\n acquireBytes(\n key: string,\n pixels: Uint8Array | Uint8ClampedArray,\n width: number,\n height: number,\n options?: CanvasTextureOptions,\n ): CanvasTextureHandle;\n /** Take another reference to an existing key. Throws when it is not present. */\n retain(key: string): CanvasTextureHandle;\n /** Drop a reference; the entry is deleted when the last one goes. */\n release(key: string): void;\n /**\n * Replace an existing (or create a new) entry's pixels, keeping its refcount.\n *\n * A source the same size as what the entry already holds is re-uploaded with\n * `texSubImage2D`, INTO the storage that is already there; only a size change\n * re-specifies it with `texImage2D`. That matters for a consumer streaming a\n * live surface into one key every frame, which is the shape this method exists\n * for: a re-spec frees the old mip level and allocates a new one on every call,\n * so a same-size stream would churn a few megabytes of driver allocation per\n * frame to write the same number of texels. See `stats.respecs`.\n */\n update(key: string, source: CanvasTextureSource): CanvasTextureHandle;\n /**\n * Write `source` into an EXISTING entry's storage at `(x, y)`, leaving the rest\n * of it untouched. Nothing is allocated, nothing is re-specified, the refcount\n * does not move, and the sampler parameters are not re-set.\n *\n * This is the ATLAS PAGE case, and it is why {@link CanvasTextureCache.update}\n * is not enough for it. A page is one texture that many small sources are\n * written into over time; `update` can only replace the whole thing, so a\n * consumer holding a 1024x1024 page would have to re-upload all four megabytes\n * every time one 40x18 label changed — which on a phone is tens of milliseconds\n * for a few kilobytes of new pixels. Writing just the region is proportional to\n * what actually changed.\n *\n * REFUSED, with `null` and no GL call at all, when the key is unknown or when\n * the rect does not lie wholly inside the entry's real storage (see\n * `Entry.storageW`, which is not always the entry's claimed size). Both would\n * otherwise be a silent `INVALID_VALUE` on the context — an error the caller\n * cannot see and the next draw cannot explain. A refusal is a fact the caller\n * is expected to handle (re-allocate, or fall back), not an exception.\n *\n * Counted as one `uploads` and never a `respec`, which is the distinction the\n * stat exists to make.\n */\n updateRegion(\n key: string,\n source: CanvasTextureSource,\n x: number,\n y: number,\n ): CanvasTextureHandle | null;\n /** The context was lost: forget every entry WITHOUT touching the dead driver. */\n reset(): void;\n /** Delete every texture and empty the cache. */\n dispose(): void;\n}\n\ninterface Entry {\n texture: WebGLTexture;\n width: number;\n height: number;\n refs: number;\n /** What the texture's STORAGE was really specified at by the last\n * `texImage2D`, which is not always `width`/`height`: those are clamped up to\n * 1 (see {@link sourceSize}), so a source that reported 0x0 leaves an entry\n * claiming 1x1 over a mip level that is 0x0 or absent. `update`'s fast path\n * writes into existing storage, so it has to test the storage rather than the\n * claim — otherwise that entry's next same-size update would be a\n * `texSubImage2D` past the end of a level that is not there. */\n storageW: number;\n storageH: number;\n mipmap: boolean;\n minFilter: number;\n magFilter: number;\n premultiplied: boolean;\n}\n\nfunction textureBytes(width: number, height: number, mipmap: boolean): number {\n if (width <= 0 || height <= 0) return 0;\n let bytes = 0;\n while (true) {\n bytes += width * height * 4;\n if (!mipmap || (width === 1 && height === 1)) return bytes;\n width = Math.max(1, width >> 1);\n height = Math.max(1, height >> 1);\n }\n}\n\n/** Exact `round(channel * alpha / 255)` for all byte pairs. */\nfunction premultiplyByte(channel: number, alpha: number): number {\n const t = channel * alpha + 0x80;\n return (t + (t >> 8)) >> 8;\n}\n\n/** Pixel dimensions of an upload source, as the source itself reports them —\n * 0 included. */\nfunction rawSourceSize(source: CanvasTextureSource): {\n width: number;\n height: number;\n} {\n const any = source as {\n naturalWidth?: number;\n naturalHeight?: number;\n videoWidth?: number;\n videoHeight?: number;\n width?: number;\n height?: number;\n };\n return {\n width: any.naturalWidth || any.videoWidth || any.width || 0,\n height: any.naturalHeight || any.videoHeight || any.height || 0,\n };\n}\n\n/** The same, clamped to at least 1x1 — what an entry records and what UV\n * normalization divides by, neither of which may be zero. */\nfunction sourceSize(source: CanvasTextureSource): {\n width: number;\n height: number;\n} {\n const raw = rawSourceSize(source);\n return {\n width: Math.max(1, raw.width),\n height: Math.max(1, raw.height),\n };\n}\n\nexport function createTextureCache(\n gl: WebGL2RenderingContext,\n): CanvasTextureCache {\n const entries = new Map<string, Entry>();\n let whiteEntry: Entry | null = null;\n let premultiplyScratch = new Uint8Array(0);\n const stats: TextureCacheStats = {\n entries: 0,\n uploads: 0,\n respecs: 0,\n evictions: 0,\n bytes: 0,\n };\n\n function resolvedOptions(\n options: CanvasTextureOptions = {},\n ): Required<CanvasTextureOptions> {\n const mipmap = options.mipmap ?? false;\n return {\n premultiplied: options.premultiplied ?? false,\n mipmap,\n minFilter:\n options.minFilter ?? (mipmap ? gl.LINEAR_MIPMAP_LINEAR : gl.LINEAR),\n magFilter: options.magFilter ?? gl.LINEAR,\n };\n }\n\n // CLAMP_TO_EDGE avoids wrapping across a page edge. Mipmaps themselves still\n // interpolate adjacent atlas regions, hence the public padded-atlas warning.\n function configure(entry: Entry): void {\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, entry.minFilter);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, entry.magFilter);\n }\n\n // The unpack state both source uploads run under, stated once so the fast path\n // below cannot drift from the full one. Row 0 of the source lands at V=0, i.e.\n // the top-left origin the draw-list's page-pixel source rects are expressed in\n // — a FLIP_Y upload would render every sprite upside down while every UV still\n // looked right — and PREMULTIPLY is the package's contract (see the header).\n function unpackForSource(premultiplied: boolean): void {\n gl.pixelStorei(gl.UNPACK_ALIGNMENT, 4);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);\n gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, !premultiplied);\n }\n\n function regenerateMipmap(entry: Entry): void {\n if (entry.mipmap && entry.storageW > 0 && entry.storageH > 0) {\n gl.generateMipmap(gl.TEXTURE_2D);\n }\n }\n\n function uploadSource(entry: Entry, source: CanvasTextureSource): void {\n const raw = rawSourceSize(source);\n gl.bindTexture(gl.TEXTURE_2D, entry.texture);\n unpackForSource(entry.premultiplied);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);\n configure(entry);\n entry.storageW = raw.width;\n entry.storageH = raw.height;\n regenerateMipmap(entry);\n stats.uploads += 1;\n stats.respecs += 1;\n }\n\n /** Re-upload over storage that is ALREADY the source's size. No `texImage2D`,\n * so no reallocation; no `configure()` either, because sampler parameters live\n * on the texture object and nothing here touches them. */\n function reuploadSource(entry: Entry, source: CanvasTextureSource): void {\n gl.bindTexture(gl.TEXTURE_2D, entry.texture);\n unpackForSource(entry.premultiplied);\n gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, source);\n regenerateMipmap(entry);\n stats.uploads += 1;\n }\n\n /** Write a source into part of storage that is already there. Like\n * {@link reuploadSource} it neither allocates nor re-configures; unlike it, the\n * destination offset is the caller's. */\n function uploadRegion(\n entry: Entry,\n source: CanvasTextureSource,\n x: number,\n y: number,\n ): void {\n gl.bindTexture(gl.TEXTURE_2D, entry.texture);\n unpackForSource(entry.premultiplied);\n gl.texSubImage2D(gl.TEXTURE_2D, 0, x, y, gl.RGBA, gl.UNSIGNED_BYTE, source);\n regenerateMipmap(entry);\n stats.uploads += 1;\n }\n\n function uploadBytes(\n entry: Entry,\n pixels: Uint8Array | Uint8ClampedArray,\n width: number,\n height: number,\n premultiplied: boolean,\n ): void {\n let data =\n pixels instanceof Uint8Array\n ? pixels\n : new Uint8Array(pixels.buffer, pixels.byteOffset, pixels.byteLength);\n if (!premultiplied) {\n if (premultiplyScratch.length < data.length) {\n premultiplyScratch = new Uint8Array(data.length);\n }\n const premultipliedData = premultiplyScratch.subarray(0, data.length);\n for (let i = 0; i < data.length; i += 4) {\n const a = data[i + 3];\n premultipliedData[i] = premultiplyByte(data[i], a);\n premultipliedData[i + 1] = premultiplyByte(data[i + 1], a);\n premultipliedData[i + 2] = premultiplyByte(data[i + 2], a);\n premultipliedData[i + 3] = a;\n }\n data = premultipliedData;\n }\n gl.bindTexture(gl.TEXTURE_2D, entry.texture);\n gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);\n gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);\n gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);\n gl.texImage2D(\n gl.TEXTURE_2D,\n 0,\n gl.RGBA,\n width,\n height,\n 0,\n gl.RGBA,\n gl.UNSIGNED_BYTE,\n data,\n );\n configure(entry);\n entry.storageW = width;\n entry.storageH = height;\n regenerateMipmap(entry);\n stats.uploads += 1;\n stats.respecs += 1;\n }\n\n function track(entry: Entry, width: number, height: number): void {\n stats.bytes +=\n textureBytes(width, height, entry.mipmap) -\n textureBytes(entry.width, entry.height, entry.mipmap);\n entry.width = width;\n entry.height = height;\n }\n\n function makeEntry(\n width: number,\n height: number,\n options: CanvasTextureOptions = {},\n ): Entry {\n const resolved = resolvedOptions(options);\n const entry: Entry = {\n texture: gl.createTexture(),\n width: 0,\n height: 0,\n refs: 0,\n // No storage yet: the upload that follows every `makeEntry` sets these.\n // Until it does, nothing can match, so nothing can take the fast path.\n storageW: -1,\n storageH: -1,\n mipmap: resolved.mipmap,\n minFilter: resolved.minFilter,\n magFilter: resolved.magFilter,\n premultiplied: resolved.premultiplied,\n };\n track(entry, width, height);\n stats.entries += 1;\n return entry;\n }\n\n return {\n stats,\n\n white() {\n if (whiteEntry) return whiteEntry;\n const entry = makeEntry(1, 1);\n uploadBytes(entry, new Uint8Array([255, 255, 255, 255]), 1, 1, true);\n // Never released: it is a single texel and every solid fill on the page\n // samples it.\n entry.refs = 1;\n whiteEntry = entry;\n return entry;\n },\n\n peek(key) {\n return entries.get(key);\n },\n\n acquire(key, source, options) {\n const existing = entries.get(key);\n if (existing) {\n existing.refs += 1;\n return existing;\n }\n const { width, height } = sourceSize(source);\n const entry = makeEntry(width, height, options);\n uploadSource(entry, source);\n entry.refs = 1;\n entries.set(key, entry);\n return entry;\n },\n\n acquireBytes(key, pixels, width, height, options) {\n const existing = entries.get(key);\n if (existing) {\n existing.refs += 1;\n return existing;\n }\n const entry = makeEntry(Math.max(1, width), Math.max(1, height), options);\n uploadBytes(\n entry,\n pixels,\n entry.width,\n entry.height,\n options?.premultiplied ?? false,\n );\n entry.refs = 1;\n entries.set(key, entry);\n return entry;\n },\n\n retain(key) {\n const entry = entries.get(key);\n if (!entry) {\n throw new Error(`texture cache: retain of unknown key \"${key}\"`);\n }\n entry.refs += 1;\n return entry;\n },\n\n release(key) {\n const entry = entries.get(key);\n if (!entry) return;\n entry.refs -= 1;\n if (entry.refs > 0) return;\n gl.deleteTexture(entry.texture);\n entries.delete(key);\n stats.entries -= 1;\n stats.evictions += 1;\n stats.bytes -= textureBytes(entry.width, entry.height, entry.mipmap);\n },\n\n update(key, source) {\n const raw = rawSourceSize(source);\n const entry = entries.get(key);\n // Same storage, same source size: write over the level that is already\n // there. This is the streaming case — one key, a new frame every tick —\n // and it is why the entry remembers what its storage really is rather than\n // what it claims (see `Entry.storageW`).\n if (\n entry &&\n entry.storageW === raw.width &&\n entry.storageH === raw.height\n ) {\n reuploadSource(entry, source);\n return entry;\n }\n const width = Math.max(1, raw.width);\n const height = Math.max(1, raw.height);\n if (!entry) {\n const created = makeEntry(width, height);\n created.refs = 1;\n entries.set(key, created);\n uploadSource(created, source);\n return created;\n }\n track(entry, width, height);\n uploadSource(entry, source);\n return entry;\n },\n\n updateRegion(key, source, x, y) {\n const entry = entries.get(key);\n if (!entry || entry.mipmap) return null;\n const raw = rawSourceSize(source);\n // The whole rect must be inside the storage that really exists. `raw` and\n // not `sourceSize` on purpose: a 0-sized source would write nothing, and\n // clamping it up to 1 here would claim it wrote a texel it did not.\n if (\n !Number.isInteger(x) ||\n !Number.isInteger(y) ||\n x < 0 ||\n y < 0 ||\n raw.width <= 0 ||\n raw.height <= 0 ||\n x + raw.width > entry.storageW ||\n y + raw.height > entry.storageH\n ) {\n return null;\n }\n uploadRegion(entry, source, x, y);\n return entry;\n },\n\n reset() {\n // No `deleteTexture`: after a context loss every name is already invalid and\n // asking the dead context to free them is at best a no-op and at worst a\n // stream of GL errors on the next restore.\n entries.clear();\n whiteEntry = null;\n stats.entries = 0;\n stats.bytes = 0;\n },\n\n dispose() {\n for (const entry of entries.values()) gl.deleteTexture(entry.texture);\n if (whiteEntry) gl.deleteTexture(whiteEntry.texture);\n entries.clear();\n whiteEntry = null;\n stats.entries = 0;\n stats.bytes = 0;\n },\n };\n}\n"],"mappings":"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"}
|