canvas-ultrafast 1.0.3 → 1.0.4
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/README.md
CHANGED
|
@@ -100,6 +100,7 @@ api.fillText('hello', 20, 80);
|
|
|
100
100
|
| `submitBatch(commands)` | Execute commands into the write FBO, swap write ↔ ready |
|
|
101
101
|
| `startDisplay()` / `stopDisplay()` | Control the RAF display loop |
|
|
102
102
|
| `setBackgroundColor(r, g, b)` | Set the opaque clear color (values in [0, 1]) |
|
|
103
|
+
| `getBackgroundColor()` | Get the current background color as `[r, g, b]` floats |
|
|
103
104
|
| `getReadyTexture()` | Return the ready FBO's texture for external rendering |
|
|
104
105
|
| `getGL()` | Access the underlying `WebGL2RenderingContext` |
|
|
105
106
|
| `getCanvas()` / `getCanvasSize()` | Canvas element and dimensions |
|
|
@@ -112,15 +113,13 @@ The WebGL context is created with `alpha: false` and `desynchronized: true`. Thi
|
|
|
112
113
|
|
|
113
114
|
**Why:** `alpha: false` tells the GPU to skip per-pixel alpha blending in the compositor, saving significant bandwidth on mobile GPUs (2-4ms/frame on Adreno 3xx/4xx, Mali-T6xx at 1080p). `desynchronized: true` enables direct-to-display rendering, eliminating an additional frame of latency and reducing CPU overhead from compositor wake-ups. Together, these can be the difference between hitting 60fps and dropping frames on low-end hardware.
|
|
114
115
|
|
|
115
|
-
**Tradeoff:** `clearRect()` produces the configured background color (
|
|
116
|
+
**Tradeoff:** `clearRect()` produces the configured background color rather than transparency. The constructor auto-detects the background by walking the canvas's DOM ancestors for a non-transparent `backgroundColor` (fallback: white), so no manual configuration is needed in most cases. Use `setBackgroundColor(r, g, b)` to override:
|
|
116
117
|
|
|
117
118
|
```ts
|
|
118
119
|
const renderer = new UltrafastRenderer(canvas);
|
|
119
120
|
renderer.setBackgroundColor(0.16, 0.22, 0.35); // dark blue, values in [0, 1]
|
|
120
121
|
```
|
|
121
122
|
|
|
122
|
-
[maalata](https://github.com/emansom/maalata) auto-detects the background color from the canvas element's DOM ancestors, so no manual configuration is needed in most cases.
|
|
123
|
-
|
|
124
123
|
## Extension points
|
|
125
124
|
|
|
126
125
|
canvas-ultrafast is designed to be taken over by a downstream consumer. The pattern:
|
|
@@ -1275,6 +1275,7 @@ class UltrafastRenderer {
|
|
|
1275
1275
|
);
|
|
1276
1276
|
this._initQuadVBO();
|
|
1277
1277
|
this._clearAllFBOs();
|
|
1278
|
+
this._resolveBackgroundColor();
|
|
1278
1279
|
this.startDisplay();
|
|
1279
1280
|
}
|
|
1280
1281
|
// -------------------------------------------------------------------------
|
|
@@ -1336,6 +1337,10 @@ class UltrafastRenderer {
|
|
|
1336
1337
|
this._bgColor[2] = b;
|
|
1337
1338
|
this._shim.setBackgroundColor(r, g, b);
|
|
1338
1339
|
}
|
|
1340
|
+
/** Returns the current background color as [r, g, b] floats in [0, 1]. */
|
|
1341
|
+
getBackgroundColor() {
|
|
1342
|
+
return [this._bgColor[0], this._bgColor[1], this._bgColor[2]];
|
|
1343
|
+
}
|
|
1339
1344
|
/** Clean up all WebGL resources. */
|
|
1340
1345
|
destroy() {
|
|
1341
1346
|
this.stopDisplay();
|
|
@@ -1420,6 +1425,23 @@ class UltrafastRenderer {
|
|
|
1420
1425
|
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
1421
1426
|
return { _fbo: fbo, _texture: texture };
|
|
1422
1427
|
}
|
|
1428
|
+
_resolveBackgroundColor() {
|
|
1429
|
+
let el = this._canvas.parentElement;
|
|
1430
|
+
while (el) {
|
|
1431
|
+
const bg = getComputedStyle(el).backgroundColor;
|
|
1432
|
+
if (bg && bg !== "transparent" && bg !== "rgba(0, 0, 0, 0)") {
|
|
1433
|
+
const c = parseColor(bg);
|
|
1434
|
+
if (c[3] > 0) {
|
|
1435
|
+
this.setBackgroundColor(c[0], c[1], c[2]);
|
|
1436
|
+
this._clearAllFBOs();
|
|
1437
|
+
return;
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
1440
|
+
el = el.parentElement;
|
|
1441
|
+
}
|
|
1442
|
+
this.setBackgroundColor(1, 1, 1);
|
|
1443
|
+
this._clearAllFBOs();
|
|
1444
|
+
}
|
|
1423
1445
|
_clearAllFBOs() {
|
|
1424
1446
|
const gl = this._gl;
|
|
1425
1447
|
const bg = this._bgColor;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"canvas-ultrafast.es.js","sources":["../src/canvas-api.ts","../src/matrix-stack.ts","../src/color-parser.ts","../src/shaders.ts","../src/canvas2d-shim.ts","../src/renderer.ts"],"sourcesContent":["/**\n * Canvas API Wrapper\n *\n * Provides a Canvas 2D API that records commands locally without await.\n * Commands are batched and sent to the worker for execution.\n */\n\ntype CanvasPropertyMap = {\n fillStyle: string | CanvasGradient | CanvasPattern;\n strokeStyle: string | CanvasGradient | CanvasPattern;\n lineWidth: number;\n lineCap: CanvasLineCap;\n lineJoin: CanvasLineJoin;\n miterLimit: number;\n lineDashOffset: number;\n font: string;\n textAlign: CanvasTextAlign;\n textBaseline: CanvasTextBaseline;\n globalAlpha: number;\n globalCompositeOperation: GlobalCompositeOperation;\n shadowBlur: number;\n shadowColor: string;\n shadowOffsetX: number;\n shadowOffsetY: number;\n imageSmoothingEnabled: boolean;\n letterSpacing: string;\n};\n\nexport type CanvasCommand =\n | { type: 'property'; name: string; value: unknown }\n | { type: 'method'; name: string; args: unknown[] };\n\nexport class CanvasAPI {\n private _c: CanvasCommand[] = [];\n private _cp: Partial<CanvasPropertyMap> = {};\n\n private _m(n: string, ...a: unknown[]): void {\n this._c.push({ type: 'method', name: n, args: a });\n }\n\n private _p<K extends keyof CanvasPropertyMap>(n: K, v: CanvasPropertyMap[K]): void {\n this._cp[n] = v;\n this._c.push({ type: 'property', name: n, value: v });\n }\n\n /**\n * Drain and return all buffered commands.\n * No _ prefix: called cross-file from pipeline, must survive mangleProps.\n */\n takeCommands(): CanvasCommand[] {\n if (this._c.length === 0) return [];\n const cmds = this._c;\n this._c = [];\n return cmds;\n }\n\n // Canvas 2D API methods\n\n // State\n save(): void { this._m('save'); }\n restore(): void { this._m('restore'); }\n\n // Transform\n scale(x: number, y: number): void { this._m('scale', x, y); }\n rotate(angle: number): void { this._m('rotate', angle); }\n translate(x: number, y: number): void { this._m('translate', x, y); }\n transform(a: number, b: number, c: number, d: number, e: number, f: number): void { this._m('transform', a, b, c, d, e, f); }\n setTransform(a: number, b: number, c: number, d: number, e: number, f: number): void { this._m('setTransform', a, b, c, d, e, f); }\n resetTransform(): void { this._m('resetTransform'); }\n\n // Rectangles\n clearRect(x: number, y: number, width: number, height: number): void { this._m('clearRect', x, y, width, height); }\n fillRect(x: number, y: number, width: number, height: number): void { this._m('fillRect', x, y, width, height); }\n strokeRect(x: number, y: number, width: number, height: number): void { this._m('strokeRect', x, y, width, height); }\n\n // Text\n fillText(text: string, x: number, y: number, maxWidth?: number): void {\n this._m('fillText', ...(maxWidth !== undefined ? [text, x, y, maxWidth] : [text, x, y]));\n }\n\n strokeText(text: string, x: number, y: number, maxWidth?: number): void {\n this._m('strokeText', ...(maxWidth !== undefined ? [text, x, y, maxWidth] : [text, x, y]));\n }\n\n /** Synchronous text measurement — cannot go through the async command pipeline. */\n private _measureCtx: OffscreenCanvasRenderingContext2D | null = null;\n\n measureText(text: string): TextMetrics {\n if (!this._measureCtx) {\n this._measureCtx = new OffscreenCanvas(1, 1).getContext('2d')!;\n }\n this._measureCtx.font = this.font;\n return this._measureCtx.measureText(text);\n }\n\n // Line drawing\n beginPath(): void { this._m('beginPath'); }\n closePath(): void { this._m('closePath'); }\n moveTo(x: number, y: number): void { this._m('moveTo', x, y); }\n lineTo(x: number, y: number): void { this._m('lineTo', x, y); }\n\n bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number): void {\n this._m('bezierCurveTo', cp1x, cp1y, cp2x, cp2y, x, y);\n }\n\n quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void { this._m('quadraticCurveTo', cpx, cpy, x, y); }\n\n arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, counterclockwise?: boolean): void {\n this._m('arc', ...(counterclockwise !== undefined ? [x, y, radius, startAngle, endAngle, counterclockwise] : [x, y, radius, startAngle, endAngle]));\n }\n\n arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): void { this._m('arcTo', x1, y1, x2, y2, radius); }\n\n ellipse(x: number, y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, counterclockwise?: boolean): void {\n this._m('ellipse', ...(counterclockwise !== undefined ? [x, y, radiusX, radiusY, rotation, startAngle, endAngle, counterclockwise] : [x, y, radiusX, radiusY, rotation, startAngle, endAngle]));\n }\n\n rect(x: number, y: number, width: number, height: number): void { this._m('rect', x, y, width, height); }\n\n // Images\n drawImage(image: CanvasImageSource, dx: number, dy: number): void;\n drawImage(image: CanvasImageSource, dx: number, dy: number, dw: number, dh: number): void;\n drawImage(image: CanvasImageSource, sx: number, sy: number, sw: number, sh: number, dx: number, dy: number, dw: number, dh: number): void;\n drawImage(...args: [CanvasImageSource, ...number[]]): void {\n this._m('drawImage', ...args);\n }\n\n // Fill and stroke\n fill(): void { this._m('fill'); }\n stroke(): void { this._m('stroke'); }\n clip(): void { this._m('clip'); }\n\n // Properties (setters)\n set fillStyle(value: string | CanvasGradient | CanvasPattern) { this._p('fillStyle', value); }\n set strokeStyle(value: string | CanvasGradient | CanvasPattern) { this._p('strokeStyle', value); }\n set lineWidth(value: number) { this._p('lineWidth', value); }\n set lineCap(value: CanvasLineCap) { this._p('lineCap', value); }\n set lineJoin(value: CanvasLineJoin) { this._p('lineJoin', value); }\n set miterLimit(value: number) { this._p('miterLimit', value); }\n set lineDashOffset(value: number) { this._p('lineDashOffset', value); }\n set font(value: string) { this._p('font', value); }\n set textAlign(value: CanvasTextAlign) { this._p('textAlign', value); }\n set textBaseline(value: CanvasTextBaseline) { this._p('textBaseline', value); }\n set globalAlpha(value: number) { this._p('globalAlpha', value); }\n set globalCompositeOperation(value: GlobalCompositeOperation) { this._p('globalCompositeOperation', value); }\n set shadowBlur(value: number) { this._p('shadowBlur', value); }\n set shadowColor(value: string) { this._p('shadowColor', value); }\n set shadowOffsetX(value: number) { this._p('shadowOffsetX', value); }\n set shadowOffsetY(value: number) { this._p('shadowOffsetY', value); }\n set imageSmoothingEnabled(value: boolean) { this._p('imageSmoothingEnabled', value); }\n set letterSpacing(value: string) { this._p('letterSpacing', value); }\n\n // Property getters (return local cached values)\n get fillStyle() { return this._cp['fillStyle'] ?? '#000'; }\n get strokeStyle() { return this._cp['strokeStyle'] ?? '#000'; }\n get lineWidth() { return this._cp['lineWidth'] ?? 1; }\n get lineCap() { return this._cp['lineCap'] ?? 'butt'; }\n get lineJoin() { return this._cp['lineJoin'] ?? 'miter'; }\n get miterLimit() { return this._cp['miterLimit'] ?? 10; }\n get lineDashOffset() { return this._cp['lineDashOffset'] ?? 0; }\n get font() { return this._cp['font'] ?? '10px sans-serif'; }\n get textAlign() { return this._cp['textAlign'] ?? 'start'; }\n get textBaseline() { return this._cp['textBaseline'] ?? 'alphabetic'; }\n get globalAlpha() { return this._cp['globalAlpha'] ?? 1; }\n get globalCompositeOperation() { return this._cp['globalCompositeOperation'] ?? 'source-over'; }\n get shadowBlur() { return this._cp['shadowBlur'] ?? 0; }\n get shadowColor() { return this._cp['shadowColor'] ?? 'rgba(0, 0, 0, 0)'; }\n get shadowOffsetX() { return this._cp['shadowOffsetX'] ?? 0; }\n get shadowOffsetY() { return this._cp['shadowOffsetY'] ?? 0; }\n get imageSmoothingEnabled() { return this._cp['imageSmoothingEnabled'] ?? true; }\n get letterSpacing() { return this._cp['letterSpacing'] ?? ''; }\n}","/**\n * 3×3 Affine Transform Matrix Stack\n *\n * Replicates Canvas 2D's save()/restore()/translate()/rotate()/scale()\n * as a matrix stack for WebGL uniform upload.\n *\n * Matrices are 3×3 column-major (for gl.uniformMatrix3fv), representing\n * 2D affine transforms. The base matrix includes an orthographic projection\n * that maps canvas pixel coordinates (top-left origin, Y-down) to WebGL\n * clip space ([-1,1], Y-up).\n *\n * Column-major layout of a 3×3 affine matrix:\n * [0] [3] [6] a c tx\n * [1] [4] [7] = b d ty\n * [2] [5] [8] 0 0 1\n */\n\nexport class MatrixStack {\n private _stack: Float32Array[] = [];\n private _current: Float32Array;\n private _projection: Float32Array;\n\n /**\n * @param width Canvas width in pixels\n * @param height Canvas height in pixels\n */\n constructor(width: number, height: number) {\n this._projection = _ortho(width, height);\n this._current = new Float32Array(this._projection);\n }\n\n /** Push current matrix onto the stack. No _ prefix: cross-file. */\n save(): void {\n this._stack.push(new Float32Array(this._current));\n }\n\n /** Pop and restore the top matrix. No _ prefix: cross-file. */\n restore(): void {\n if (this._stack.length > 0) {\n this._current = this._stack.pop()!;\n }\n }\n\n /** Translate the current matrix. No _ prefix: cross-file. */\n translate(x: number, y: number): void {\n // Multiply current matrix by translation:\n // 1 0 tx\n // 0 1 ty\n // 0 0 1\n // In column-major: m[6] += m[0]*tx + m[3]*ty\n // m[7] += m[1]*tx + m[4]*ty\n const m = this._current;\n m[6] += m[0] * x + m[3] * y;\n m[7] += m[1] * x + m[4] * y;\n }\n\n /** Rotate the current matrix by angle (radians). No _ prefix: cross-file. */\n rotate(angle: number): void {\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n const m = this._current;\n const m0 = m[0], m1 = m[1], m3 = m[3], m4 = m[4];\n m[0] = m0 * c + m3 * s;\n m[1] = m1 * c + m4 * s;\n m[3] = m0 * -s + m3 * c;\n m[4] = m1 * -s + m4 * c;\n }\n\n /** Scale the current matrix. No _ prefix: cross-file. */\n scale(x: number, y: number): void {\n const m = this._current;\n m[0] *= x; m[1] *= x;\n m[3] *= y; m[4] *= y;\n }\n\n /**\n * Multiply current matrix by an arbitrary 2D affine transform.\n * Canvas 2D transform(a, b, c, d, e, f) matrix:\n * a c e\n * b d f\n * 0 0 1\n * No _ prefix: cross-file.\n */\n transform(a: number, b: number, c: number, d: number, e: number, f: number): void {\n const m = this._current;\n const m0 = m[0], m1 = m[1], m3 = m[3], m4 = m[4], m6 = m[6], m7 = m[7];\n m[0] = m0 * a + m3 * b;\n m[1] = m1 * a + m4 * b;\n m[3] = m0 * c + m3 * d;\n m[4] = m1 * c + m4 * d;\n m[6] = m0 * e + m3 * f + m6;\n m[7] = m1 * e + m4 * f + m7;\n }\n\n /**\n * Reset to projection then apply the given affine transform.\n * Canvas 2D setTransform(a, b, c, d, e, f).\n * No _ prefix: cross-file.\n */\n setTransform(a: number, b: number, c: number, d: number, e: number, f: number): void {\n this._current.set(this._projection);\n this.transform(a, b, c, d, e, f);\n }\n\n /** Reset to the base orthographic projection. No _ prefix: cross-file. */\n resetTransform(): void {\n this._current.set(this._projection);\n }\n\n /**\n * Update canvas dimensions (e.g., on resize).\n * Recomputes the projection and resets the current matrix.\n * No _ prefix: cross-file.\n */\n resize(width: number, height: number): void {\n this._projection = _ortho(width, height);\n this._current = new Float32Array(this._projection);\n this._stack = [];\n }\n\n /**\n * Returns the current 3×3 matrix for gl.uniformMatrix3fv.\n * No _ prefix: cross-file.\n */\n getMatrix(): Float32Array {\n return this._current;\n }\n}\n\n/**\n * Create an orthographic projection matrix that maps:\n * Canvas coords (0,0)=top-left, (w,h)=bottom-right, Y-down\n * → Clip space (-1,-1)=bottom-left, (1,1)=top-right, Y-up\n *\n * The transform is:\n * x_clip = x * 2/w - 1\n * y_clip = -(y * 2/h - 1) = 1 - y * 2/h\n *\n * Column-major 3×3:\n * 2/w 0 -1\n * 0 -2/h 1\n * 0 0 1\n */\nfunction _ortho(w: number, h: number): Float32Array {\n return new Float32Array([\n 2 / w, 0, 0, // column 0\n 0, -2 / h, 0, // column 1\n -1, 1, 1, // column 2\n ]);\n}\n","/**\n * CSS Color Parser\n *\n * Converts CSS color strings to Float32Array [r, g, b, a] in [0, 1] range\n * for use as WebGL uniform values.\n *\n * Supported formats:\n * - Hex: #rgb, #rrggbb, #rrggbbaa\n * - Functional: rgb(r, g, b), rgba(r, g, b, a)\n * - Named: basic CSS color keywords\n *\n * Includes a cache for repeated lookups (the demo reuses ~10 colors).\n */\n\nconst _NAMED_COLORS: Record<string, number> = {\n black: 0x000000ff,\n white: 0xffffffff,\n red: 0xff0000ff,\n green: 0x008000ff,\n blue: 0x0000ffff,\n yellow: 0xffff00ff,\n cyan: 0x00ffffff,\n magenta: 0xff00ffff,\n orange: 0xffa500ff,\n transparent: 0x00000000,\n};\n\nconst _cache = new Map<string, Float32Array>();\n\n/**\n * Parse a CSS color string into [r, g, b, a] floats in [0, 1].\n * Returns a cached Float32Array — do NOT mutate the result.\n *\n * No _ prefix: called cross-file from canvas2d-shim.\n */\nexport function parseColor(css: string): Float32Array {\n const cached = _cache.get(css);\n if (cached) return cached;\n\n const result = _parse(css);\n _cache.set(css, result);\n return result;\n}\n\nfunction _parse(css: string): Float32Array {\n const s = css.trim();\n\n // #hex\n if (s.charCodeAt(0) === 0x23) { // '#'\n return _parseHex(s);\n }\n\n // rgb() / rgba()\n if (s.charCodeAt(0) === 0x72) { // 'r'\n return _parseRgb(s);\n }\n\n // Named color\n const named = _NAMED_COLORS[s.toLowerCase()];\n if (named !== undefined) {\n return new Float32Array([\n ((named >>> 24) & 0xff) / 255,\n ((named >>> 16) & 0xff) / 255,\n ((named >>> 8) & 0xff) / 255,\n (named & 0xff) / 255,\n ]);\n }\n\n // Fallback: opaque black\n return new Float32Array([0, 0, 0, 1]);\n}\n\nfunction _parseHex(s: string): Float32Array {\n const len = s.length;\n\n if (len === 4) {\n // #rgb → expand to #rrggbb\n const r = parseInt(s[1], 16);\n const g = parseInt(s[2], 16);\n const b = parseInt(s[3], 16);\n return new Float32Array([\n (r * 17) / 255,\n (g * 17) / 255,\n (b * 17) / 255,\n 1,\n ]);\n }\n\n if (len === 7) {\n // #rrggbb\n const r = parseInt(s.slice(1, 3), 16);\n const g = parseInt(s.slice(3, 5), 16);\n const b = parseInt(s.slice(5, 7), 16);\n return new Float32Array([r / 255, g / 255, b / 255, 1]);\n }\n\n if (len === 9) {\n // #rrggbbaa\n const r = parseInt(s.slice(1, 3), 16);\n const g = parseInt(s.slice(3, 5), 16);\n const b = parseInt(s.slice(5, 7), 16);\n const a = parseInt(s.slice(7, 9), 16);\n return new Float32Array([r / 255, g / 255, b / 255, a / 255]);\n }\n\n // #rgba (4-digit with alpha)\n if (len === 5) {\n const r = parseInt(s[1], 16);\n const g = parseInt(s[2], 16);\n const b = parseInt(s[3], 16);\n const a = parseInt(s[4], 16);\n return new Float32Array([\n (r * 17) / 255,\n (g * 17) / 255,\n (b * 17) / 255,\n (a * 17) / 255,\n ]);\n }\n\n return new Float32Array([0, 0, 0, 1]);\n}\n\nfunction _parseRgb(s: string): Float32Array {\n // Match both rgb(...) and rgba(...)\n // Extract the numeric values between parentheses\n const start = s.indexOf('(');\n const end = s.lastIndexOf(')');\n if (start === -1 || end === -1) return new Float32Array([0, 0, 0, 1]);\n\n const parts = s.slice(start + 1, end).split(',');\n const r = parseFloat(parts[0]) / 255;\n const g = parseFloat(parts[1]) / 255;\n const b = parseFloat(parts[2]) / 255;\n const a = parts.length >= 4 ? parseFloat(parts[3]) : 1;\n\n return new Float32Array([r, g, b, a]);\n}\n","/**\n * GLSL Shader Sources for canvas-ultrafast\n *\n * Content shaders (flat-color, textured) plus a passthrough display shader.\n * CRT post-processing shaders live in the maalata package.\n *\n * Coordinate convention:\n * - Content shaders use a 3x3 affine matrix (u_matrix) that maps\n * canvas pixel coordinates (top-left origin, Y-down) to clip space.\n * - Passthrough shader uses a fullscreen quad in [0,1] mapped to [-1,1] clip space.\n */\n\n// ---------------------------------------------------------------------------\n// Flat-color shader: rectangles, line quads, clear regions\n// ---------------------------------------------------------------------------\n\nexport const FLAT_VERTEX_SRC = `\n attribute vec2 a_position;\n uniform mat3 u_matrix;\n void main() {\n vec3 pos = u_matrix * vec3(a_position, 1.0);\n gl_Position = vec4(pos.xy, 0.0, 1.0);\n }\n`;\n\nexport const FLAT_FRAGMENT_SRC = `\n precision mediump float;\n uniform vec4 u_color;\n void main() {\n gl_FragColor = u_color;\n }\n`;\n\n// ---------------------------------------------------------------------------\n// Textured quad shader: text rendering via OffscreenCanvas glyph upload\n// ---------------------------------------------------------------------------\n\nexport const TEXTURED_VERTEX_SRC = `\n attribute vec2 a_position;\n attribute vec2 a_texCoord;\n uniform mat3 u_matrix;\n varying vec2 v_texCoord;\n void main() {\n vec3 pos = u_matrix * vec3(a_position, 1.0);\n gl_Position = vec4(pos.xy, 0.0, 1.0);\n v_texCoord = a_texCoord;\n }\n`;\n\nexport const TEXTURED_FRAGMENT_SRC = `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D u_texture;\n uniform vec4 u_color;\n void main() {\n vec4 texel = texture2D(u_texture, v_texCoord);\n gl_FragColor = texel * u_color;\n }\n`;\n\n// ---------------------------------------------------------------------------\n// Passthrough display shader: fullscreen quad, reads FBO texture\n// ---------------------------------------------------------------------------\n\n/**\n * Vertex shader: fullscreen quad [0,1] → clip space [-1,1].\n * FBO textures are already in GL-native bottom-left origin (the orthographic\n * projection in matrix-stack.ts handles the canvas Y-down → GL Y-up flip),\n * so tex coords pass through without Y-flip.\n */\nexport const PASSTHROUGH_VERTEX_SRC = `\n attribute vec2 a_position;\n varying vec2 v_texCoord;\n void main() {\n v_texCoord = a_position;\n gl_Position = vec4(a_position * 2.0 - 1.0, 0, 1);\n }\n`;\n\n/**\n * Passthrough fragment shader: blit FBO texture to screen without effects.\n */\nexport const PASSTHROUGH_FRAGMENT_SRC = `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D u_texture;\n void main() {\n gl_FragColor = texture2D(u_texture, v_texCoord);\n }\n`;\n","/**\n * Canvas 2D → WebGL Command Shim\n *\n * Translates CanvasCommand[] (recorded by CanvasAPI) into WebGL draw calls.\n * Handles the subset of Canvas 2D API used by the demo, plus reasonable\n * extensions. Operations not yet implemented log a warning and no-op.\n *\n * Rendering approach per command type:\n * - clearRect: gl.scissor + gl.clear\n * - fillRect: unit quad VBO + flat shader + transform uniform\n * - strokeRect: four thin quads (one per edge)\n * - fillText: render to OffscreenCanvas 2D → texImage2D → textured quad\n * - stroke(): expand line segments to quads on CPU, flat shader\n * - save/restore: matrix + state stack\n *\n * Text rendering uses an OffscreenCanvas with a 2D context as a glyph\n * rendering surface. At 8 FPS with ~5 text draws per frame, per-string\n * rendering (not glyph caching) is appropriate — texImage2D(OffscreenCanvas)\n * is a fast GPU upload path.\n */\n\nimport { CanvasCommand } from './canvas-api';\nimport { MatrixStack } from './matrix-stack';\nimport { parseColor } from './color-parser';\nimport {\n FLAT_VERTEX_SRC, FLAT_FRAGMENT_SRC,\n TEXTURED_VERTEX_SRC, TEXTURED_FRAGMENT_SRC,\n} from './shaders';\n\ninterface _DrawState {\n _fillColor: Float32Array;\n _strokeColor: Float32Array;\n _lineWidth: number;\n _globalAlpha: number;\n _font: string;\n _textAlign: CanvasTextAlign;\n _textBaseline: CanvasTextBaseline;\n _lineCap: CanvasLineCap;\n _lineJoin: CanvasLineJoin;\n _imageSmoothingEnabled: boolean;\n _letterSpacing: string;\n _clipActive: boolean;\n _clipRect: [number, number, number, number] | null;\n}\n\ninterface _ProgramInfo {\n _program: WebGLProgram;\n _matrixLoc: WebGLUniformLocation | null;\n _colorLoc: WebGLUniformLocation | null;\n _textureLoc: WebGLUniformLocation | null;\n _positionLoc: number;\n _texCoordLoc: number;\n}\n\nexport class Canvas2DShim {\n private _gl: WebGLRenderingContext;\n private _width: number;\n private _height: number;\n\n // Transform\n private _matrix: MatrixStack;\n\n // State\n private _fillColor: Float32Array = new Float32Array([0, 0, 0, 1]);\n private _strokeColor: Float32Array = new Float32Array([0, 0, 0, 1]);\n private _lineWidth = 1;\n private _globalAlpha = 1;\n private _font = '10px sans-serif';\n private _textAlign: CanvasTextAlign = 'start';\n private _textBaseline: CanvasTextBaseline = 'alphabetic';\n private _lineCap: CanvasLineCap = 'butt';\n private _lineJoin: CanvasLineJoin = 'miter';\n private _imageSmoothingEnabled = true;\n private _letterSpacing = '';\n private _clipActive = false;\n private _clipRect: [number, number, number, number] | null = null;\n private _pendingClipRect: [number, number, number, number] | null = null;\n private _imageTexCache = new WeakMap<object, { _tex: WebGLTexture; _isImage: boolean }>();\n private _stateStack: _DrawState[] = [];\n\n // Path state\n private _pathSegments: number[] = []; // flat: x0,y0,x1,y1,...\n private _currentX = 0;\n private _currentY = 0;\n private _subpathStartX = 0;\n private _subpathStartY = 0;\n\n // WebGL resources\n private _flat: _ProgramInfo;\n private _textured: _ProgramInfo;\n private _unitQuadVBO: WebGLBuffer;\n private _dynamicVBO: WebGLBuffer;\n private _texturedVBO: WebGLBuffer;\n private _textTexture: WebGLTexture;\n\n // Text rendering surface\n private _textCanvas: OffscreenCanvas;\n private _textCtx: OffscreenCanvasRenderingContext2D;\n\n // Background color for opaque canvas clear\n private _bgColor = new Float32Array([0, 0, 0]);\n\n // Temp arrays to avoid allocation in hot path\n private _tmpColor = new Float32Array(4);\n\n constructor(gl: WebGLRenderingContext, width: number, height: number) {\n this._gl = gl;\n this._width = width;\n this._height = height;\n this._matrix = new MatrixStack(width, height);\n\n // Compile shader programs\n this._flat = this._createProgram(\n FLAT_VERTEX_SRC, FLAT_FRAGMENT_SRC, false\n );\n this._textured = this._createProgram(\n TEXTURED_VERTEX_SRC, TEXTURED_FRAGMENT_SRC, true\n );\n\n // Unit quad VBO: two triangles covering [0,0]-[1,1]\n // Used for fillRect (scaled via matrix) and fullscreen blits\n this._unitQuadVBO = gl.createBuffer()!;\n gl.bindBuffer(gl.ARRAY_BUFFER, this._unitQuadVBO);\n gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([\n 0, 0, 1, 0, 0, 1,\n 0, 1, 1, 0, 1, 1,\n ]), gl.STATIC_DRAW);\n\n // Dynamic VBO for line quads — uses orphaning for double-buffer\n this._dynamicVBO = gl.createBuffer()!;\n\n // Textured quad VBO: position + texcoord interleaved\n this._texturedVBO = gl.createBuffer()!;\n\n // Text rendering texture\n this._textTexture = gl.createTexture()!;\n gl.bindTexture(gl.TEXTURE_2D, this._textTexture);\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\n // OffscreenCanvas for text glyph rendering\n this._textCanvas = new OffscreenCanvas(512, 128);\n this._textCtx = this._textCanvas.getContext('2d')!;\n\n // Enable blending for standard source-over compositing\n gl.enable(gl.BLEND);\n gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\n }\n\n /**\n * Execute a batch of Canvas 2D commands as WebGL draw calls.\n * No _ prefix: called cross-file from webgl-renderer.\n */\n executeBatch(commands: CanvasCommand[]): void {\n for (const cmd of commands) {\n if (cmd.type === 'property') {\n this._setProperty(cmd.name, cmd.value);\n } else {\n this._callMethod(cmd.name, cmd.args);\n }\n }\n }\n\n /**\n * Set the opaque clear color for clearRect.\n * No _ prefix: called cross-file from renderer.\n */\n setBackgroundColor(r: number, g: number, b: number): void {\n this._bgColor[0] = r;\n this._bgColor[1] = g;\n this._bgColor[2] = b;\n }\n\n /**\n * Update canvas dimensions on resize.\n * No _ prefix: called cross-file.\n */\n resize(width: number, height: number): void {\n this._width = width;\n this._height = height;\n this._matrix.resize(width, height);\n }\n\n /**\n * Clean up WebGL resources.\n * No _ prefix: called cross-file.\n */\n destroy(): void {\n const gl = this._gl;\n gl.deleteBuffer(this._unitQuadVBO);\n gl.deleteBuffer(this._dynamicVBO);\n gl.deleteBuffer(this._texturedVBO);\n gl.deleteTexture(this._textTexture);\n gl.deleteProgram(this._flat._program);\n gl.deleteProgram(this._textured._program);\n }\n\n // -------------------------------------------------------------------------\n // Private: property handling\n // -------------------------------------------------------------------------\n\n private _setProperty(name: string, value: unknown): void {\n switch (name) {\n case 'fillStyle':\n this._fillColor = parseColor(value as string);\n break;\n case 'strokeStyle':\n this._strokeColor = parseColor(value as string);\n break;\n case 'lineWidth':\n this._lineWidth = value as number;\n break;\n case 'globalAlpha':\n this._globalAlpha = value as number;\n break;\n case 'font':\n this._font = value as string;\n break;\n case 'textAlign':\n this._textAlign = value as CanvasTextAlign;\n break;\n case 'textBaseline':\n this._textBaseline = value as CanvasTextBaseline;\n break;\n case 'lineCap':\n this._lineCap = value as CanvasLineCap;\n break;\n case 'lineJoin':\n this._lineJoin = value as CanvasLineJoin;\n break;\n case 'imageSmoothingEnabled':\n this._imageSmoothingEnabled = value as boolean;\n break;\n case 'letterSpacing':\n this._letterSpacing = value as string;\n break;\n default:\n // Unsupported properties: silently ignore\n break;\n }\n }\n\n // -------------------------------------------------------------------------\n // Private: method dispatch\n // -------------------------------------------------------------------------\n\n private _callMethod(name: string, args: unknown[]): void {\n switch (name) {\n // Rectangles\n case 'clearRect':\n this._clearRect(args[0] as number, args[1] as number, args[2] as number, args[3] as number);\n break;\n case 'fillRect':\n this._fillRect(args[0] as number, args[1] as number, args[2] as number, args[3] as number);\n break;\n case 'strokeRect':\n this._strokeRect(args[0] as number, args[1] as number, args[2] as number, args[3] as number);\n break;\n\n // Text\n case 'fillText':\n this._fillText(args[0] as string, args[1] as number, args[2] as number);\n break;\n case 'strokeText':\n this._strokeText(args[0] as string, args[1] as number, args[2] as number);\n break;\n\n // Images\n case 'drawImage':\n this._drawImage(args);\n break;\n\n // Path\n case 'beginPath':\n this._pathSegments = [];\n this._pendingClipRect = null;\n break;\n case 'closePath':\n if (this._currentX !== this._subpathStartX || this._currentY !== this._subpathStartY) {\n this._pathSegments.push(\n this._currentX, this._currentY,\n this._subpathStartX, this._subpathStartY\n );\n this._currentX = this._subpathStartX;\n this._currentY = this._subpathStartY;\n }\n break;\n case 'moveTo':\n this._currentX = this._subpathStartX = args[0] as number;\n this._currentY = this._subpathStartY = args[1] as number;\n break;\n case 'lineTo': {\n const x = args[0] as number;\n const y = args[1] as number;\n this._pathSegments.push(this._currentX, this._currentY, x, y);\n this._currentX = x;\n this._currentY = y;\n break;\n }\n case 'rect': {\n const rx = args[0] as number, ry = args[1] as number;\n const rw = args[2] as number, rh = args[3] as number;\n // Store as pending clip rect (used if clip() follows)\n this._pendingClipRect = [rx, ry, rw, rh];\n // Also add 4 line segments to path for potential stroke()\n this._pathSegments.push(\n rx, ry, rx + rw, ry, // top\n rx + rw, ry, rx + rw, ry + rh, // right\n rx + rw, ry + rh, rx, ry + rh, // bottom\n rx, ry + rh, rx, ry, // left\n );\n break;\n }\n case 'clip':\n this._applyClip();\n break;\n case 'stroke':\n this._strokePath();\n break;\n case 'fill':\n // Convex fill only — not heavily used in demo beyond fillRect\n break;\n\n // State\n case 'save':\n this._save();\n break;\n case 'restore':\n this._restore();\n break;\n\n // Transforms\n case 'translate':\n this._matrix.translate(args[0] as number, args[1] as number);\n break;\n case 'rotate':\n this._matrix.rotate(args[0] as number);\n break;\n case 'scale':\n this._matrix.scale(args[0] as number, args[1] as number);\n break;\n case 'transform':\n this._matrix.transform(\n args[0] as number, args[1] as number, args[2] as number,\n args[3] as number, args[4] as number, args[5] as number\n );\n break;\n case 'setTransform':\n this._matrix.setTransform(\n args[0] as number, args[1] as number, args[2] as number,\n args[3] as number, args[4] as number, args[5] as number\n );\n break;\n case 'resetTransform':\n this._matrix.resetTransform();\n break;\n\n default:\n // Unsupported methods: silently ignore (arc, bezierCurveTo, etc.)\n break;\n }\n }\n\n // -------------------------------------------------------------------------\n // Private: drawing operations\n // -------------------------------------------------------------------------\n\n private _clearRect(x: number, y: number, w: number, h: number): void {\n const gl = this._gl;\n const bg = this._bgColor;\n // WebGL scissor uses bottom-left origin, canvas uses top-left\n gl.enable(gl.SCISSOR_TEST);\n gl.scissor(x, this._height - y - h, w, h);\n gl.clearColor(bg[0], bg[1], bg[2], 1);\n gl.clear(gl.COLOR_BUFFER_BIT);\n gl.disable(gl.SCISSOR_TEST);\n }\n\n private _fillRect(x: number, y: number, w: number, h: number): void {\n const gl = this._gl;\n const prog = this._flat;\n\n gl.useProgram(prog._program);\n\n // Build transform: current matrix × translate(x,y) × scale(w,h)\n // Applied to unit quad [0,1]×[0,1] → fills [x,y,x+w,y+h]\n this._matrix.save();\n this._matrix.translate(x, y);\n this._matrix.scale(w, h);\n\n gl.uniformMatrix3fv(prog._matrixLoc, false, this._matrix.getMatrix());\n this._setColorUniform(prog._colorLoc!, this._fillColor, this._globalAlpha);\n\n this._matrix.restore();\n\n // Draw unit quad\n gl.bindBuffer(gl.ARRAY_BUFFER, this._unitQuadVBO);\n gl.enableVertexAttribArray(prog._positionLoc);\n gl.vertexAttribPointer(prog._positionLoc, 2, gl.FLOAT, false, 0, 0);\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n }\n\n private _strokeRect(x: number, y: number, w: number, h: number): void {\n // Draw four edges as thin quads\n const lw = this._lineWidth;\n const hlw = lw / 2;\n\n // Top edge\n this._fillRectWithColor(x - hlw, y - hlw, w + lw, lw, this._strokeColor);\n // Bottom edge\n this._fillRectWithColor(x - hlw, y + h - hlw, w + lw, lw, this._strokeColor);\n // Left edge\n this._fillRectWithColor(x - hlw, y + hlw, lw, h - lw, this._strokeColor);\n // Right edge\n this._fillRectWithColor(x + w - hlw, y + hlw, lw, h - lw, this._strokeColor);\n }\n\n /** Internal: draw a filled rect with a specific color (used by strokeRect). */\n private _fillRectWithColor(x: number, y: number, w: number, h: number, color: Float32Array): void {\n const gl = this._gl;\n const prog = this._flat;\n\n gl.useProgram(prog._program);\n\n this._matrix.save();\n this._matrix.translate(x, y);\n this._matrix.scale(w, h);\n\n gl.uniformMatrix3fv(prog._matrixLoc, false, this._matrix.getMatrix());\n this._setColorUniform(prog._colorLoc!, color, this._globalAlpha);\n\n this._matrix.restore();\n\n gl.bindBuffer(gl.ARRAY_BUFFER, this._unitQuadVBO);\n gl.enableVertexAttribArray(prog._positionLoc);\n gl.vertexAttribPointer(prog._positionLoc, 2, gl.FLOAT, false, 0, 0);\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n }\n\n private _strokePath(): void {\n const segs = this._pathSegments;\n if (segs.length === 0) return;\n\n const gl = this._gl;\n const prog = this._flat;\n const halfW = Math.max(this._lineWidth / 2, 0.5);\n\n // Expand line segments to quads on CPU\n // Each segment (x0,y0,x1,y1) → 6 vertices (2 triangles)\n const segCount = segs.length / 4;\n const vertices = new Float32Array(segCount * 12); // 6 vertices × 2 coords\n\n for (let i = 0, vi = 0; i < segs.length; i += 4) {\n const x0 = segs[i], y0 = segs[i + 1], x1 = segs[i + 2], y1 = segs[i + 3];\n const dx = x1 - x0;\n const dy = y1 - y0;\n const len = Math.sqrt(dx * dx + dy * dy);\n\n if (len < 0.001) continue; // Skip degenerate segments\n\n // Normal perpendicular to line direction\n const nx = (-dy / len) * halfW;\n const ny = (dx / len) * halfW;\n\n // Four corners of the quad\n const ax = x0 + nx, ay = y0 + ny; // top-left\n const bx = x0 - nx, by = y0 - ny; // bottom-left\n const cx = x1 + nx, cy = y1 + ny; // top-right\n const dx2 = x1 - nx, dy2 = y1 - ny; // bottom-right\n\n // Triangle 1: A, B, C\n vertices[vi++] = ax; vertices[vi++] = ay;\n vertices[vi++] = bx; vertices[vi++] = by;\n vertices[vi++] = cx; vertices[vi++] = cy;\n // Triangle 2: B, D, C\n vertices[vi++] = bx; vertices[vi++] = by;\n vertices[vi++] = dx2; vertices[vi++] = dy2;\n vertices[vi++] = cx; vertices[vi++] = cy;\n }\n\n // Upload to dynamic VBO using orphaning (bufferData null pattern)\n gl.bindBuffer(gl.ARRAY_BUFFER, this._dynamicVBO);\n gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.DYNAMIC_DRAW);\n\n gl.useProgram(prog._program);\n gl.uniformMatrix3fv(prog._matrixLoc, false, this._matrix.getMatrix());\n this._setColorUniform(prog._colorLoc!, this._strokeColor, this._globalAlpha);\n\n gl.enableVertexAttribArray(prog._positionLoc);\n gl.vertexAttribPointer(prog._positionLoc, 2, gl.FLOAT, false, 0, 0);\n gl.drawArrays(gl.TRIANGLES, 0, segCount * 6);\n }\n\n private _drawImage(args: unknown[]): void {\n const gl = this._gl;\n const image = args[0] as CanvasImageSource;\n\n let sx: number, sy: number, sw: number, sh: number;\n let dx: number, dy: number, dw: number, dh: number;\n\n // Get image dimensions\n const imgW = _getImageWidth(image);\n const imgH = _getImageHeight(image);\n\n if (args.length === 3) {\n // drawImage(image, dx, dy)\n sx = 0; sy = 0; sw = imgW; sh = imgH;\n dx = args[1] as number; dy = args[2] as number;\n dw = imgW; dh = imgH;\n } else if (args.length === 5) {\n // drawImage(image, dx, dy, dw, dh)\n sx = 0; sy = 0; sw = imgW; sh = imgH;\n dx = args[1] as number; dy = args[2] as number;\n dw = args[3] as number; dh = args[4] as number;\n } else {\n // drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)\n sx = args[1] as number; sy = args[2] as number;\n sw = args[3] as number; sh = args[4] as number;\n dx = args[5] as number; dy = args[6] as number;\n dw = args[7] as number; dh = args[8] as number;\n }\n\n // Get or create texture for this image source\n const tex = this._getOrUploadTexture(image, imgW, imgH);\n\n // Set filtering based on imageSmoothingEnabled\n const filter = this._imageSmoothingEnabled ? gl.LINEAR : gl.NEAREST;\n gl.bindTexture(gl.TEXTURE_2D, tex);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filter);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filter);\n\n // Compute UV coordinates for source sub-rect\n const uMin = sx / imgW;\n const vMin = sy / imgH;\n const uMax = (sx + sw) / imgW;\n const vMax = (sy + sh) / imgH;\n\n // Draw textured quad with interleaved position + texcoord\n const prog = this._textured;\n const verts = new Float32Array([\n dx, dy, uMin, vMin,\n dx + dw, dy, uMax, vMin,\n dx, dy + dh, uMin, vMax,\n dx, dy + dh, uMin, vMax,\n dx + dw, dy, uMax, vMin,\n dx + dw, dy + dh, uMax, vMax,\n ]);\n\n gl.bindBuffer(gl.ARRAY_BUFFER, this._texturedVBO);\n gl.bufferData(gl.ARRAY_BUFFER, verts, gl.DYNAMIC_DRAW);\n\n gl.useProgram(prog._program);\n gl.uniformMatrix3fv(prog._matrixLoc, false, this._matrix.getMatrix());\n // White color tint with globalAlpha — no color modification, just alpha\n gl.uniform4f(prog._colorLoc!, 1, 1, 1, this._globalAlpha);\n\n // Standard alpha blending (not premultiplied for image textures)\n const stride = 16; // 4 floats × 4 bytes\n gl.enableVertexAttribArray(prog._positionLoc);\n gl.vertexAttribPointer(prog._positionLoc, 2, gl.FLOAT, false, stride, 0);\n gl.enableVertexAttribArray(prog._texCoordLoc);\n gl.vertexAttribPointer(prog._texCoordLoc, 2, gl.FLOAT, false, stride, 8);\n\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, tex);\n gl.uniform1i(prog._textureLoc, 0);\n\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n\n // Disable texcoord attrib to avoid interfering with flat shader\n gl.disableVertexAttribArray(prog._texCoordLoc);\n }\n\n private _getOrUploadTexture(image: CanvasImageSource, imgW: number, imgH: number): WebGLTexture {\n const gl = this._gl;\n const key = image as unknown as object;\n const cached = this._imageTexCache.get(key);\n\n // HTMLImageElement/SVGImageElement: upload once, cache permanently\n // HTMLCanvasElement/OffscreenCanvas: always re-upload (content may change)\n const isImage = (image instanceof HTMLImageElement) || (image instanceof SVGImageElement);\n\n if (cached) {\n if (cached._isImage) {\n // Static image — reuse cached texture\n return cached._tex;\n }\n // Canvas source — re-upload to existing texture\n gl.bindTexture(gl.TEXTURE_2D, cached._tex);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image as TexImageSource);\n return cached._tex;\n }\n\n // Create new texture\n const tex = gl.createTexture()!;\n gl.bindTexture(gl.TEXTURE_2D, tex);\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\n // Detect if we need to handle alpha properly\n // For canvas sources, use standard upload; for images, avoid premultiply\n if (imgW > 0 && imgH > 0) {\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image as TexImageSource);\n }\n\n this._imageTexCache.set(key, { _tex: tex, _isImage: isImage });\n return tex;\n }\n\n private _applyClip(): void {\n const gl = this._gl;\n if (this._pendingClipRect) {\n const [x, y, w, h] = this._pendingClipRect;\n gl.enable(gl.SCISSOR_TEST);\n // Convert canvas coords (top-left origin) to GL coords (bottom-left origin)\n gl.scissor(x, this._height - y - h, w, h);\n this._clipActive = true;\n this._clipRect = [x, y, w, h];\n }\n }\n\n private _fillText(text: string, x: number, y: number): void {\n this._renderText(text, x, y, 'fill');\n }\n\n private _strokeText(text: string, x: number, y: number): void {\n this._renderText(text, x, y, 'stroke');\n }\n\n private _renderText(text: string, x: number, y: number, mode: 'fill' | 'stroke'): void {\n const gl = this._gl;\n const tCtx = this._textCtx;\n\n // Configure text rendering context\n tCtx.font = this._font;\n tCtx.textAlign = 'left'; // Always render left-aligned, position via WebGL\n tCtx.textBaseline = 'top'; // Always render from top, adjust Y via offset\n if (this._letterSpacing) {\n tCtx.letterSpacing = this._letterSpacing;\n }\n\n // Measure text\n const metrics = tCtx.measureText(text);\n const textWidth = Math.ceil(metrics.width) + 4; // +4 for antialiasing padding\n const fontSize = _parseFontSize(this._font);\n const textHeight = Math.ceil(fontSize * 1.5) + 4; // approximate height with descenders\n\n if (textWidth <= 0 || textHeight <= 0) return;\n\n // Resize text canvas if needed\n if (this._textCanvas.width < textWidth || this._textCanvas.height < textHeight) {\n this._textCanvas.width = Math.max(this._textCanvas.width, textWidth);\n this._textCanvas.height = Math.max(this._textCanvas.height, textHeight);\n // Re-set font after resize (context is reset)\n tCtx.font = this._font;\n tCtx.textAlign = 'left';\n tCtx.textBaseline = 'top';\n }\n\n // Clear and render text\n tCtx.clearRect(0, 0, this._textCanvas.width, this._textCanvas.height);\n\n if (mode === 'fill') {\n tCtx.fillStyle = 'white'; // White text, tinted by WebGL uniform\n tCtx.fillText(text, 2, 2); // +2 padding offset\n } else {\n tCtx.strokeStyle = 'white';\n tCtx.lineWidth = this._lineWidth;\n tCtx.strokeText(text, 2, 2);\n }\n\n // Upload text canvas to texture\n gl.bindTexture(gl.TEXTURE_2D, this._textTexture);\n gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 1);\n gl.texImage2D(\n gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE,\n this._textCanvas\n );\n gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 0);\n\n // Compute text position adjustments\n const color = mode === 'fill' ? this._fillColor : this._strokeColor;\n let drawX = x - 2; // compensate for padding\n let drawY = y - 2;\n\n // Adjust for textAlign\n switch (this._textAlign) {\n case 'center': drawX -= textWidth / 2; break;\n case 'right':\n case 'end': drawX -= textWidth; break;\n }\n\n // Adjust for textBaseline\n switch (this._textBaseline) {\n case 'top': /* drawY stays */ break;\n case 'middle': drawY -= textHeight / 2; break;\n case 'alphabetic':\n case 'ideographic': drawY -= fontSize; break;\n case 'bottom':\n case 'hanging': drawY -= textHeight; break;\n }\n\n // Draw textured quad\n this._drawTexturedQuad(\n drawX, drawY, textWidth, textHeight,\n textWidth / this._textCanvas.width,\n textHeight / this._textCanvas.height,\n color\n );\n }\n\n private _drawTexturedQuad(\n x: number, y: number, w: number, h: number,\n uMax: number, vMax: number,\n color: Float32Array\n ): void {\n const gl = this._gl;\n const prog = this._textured;\n\n // Interleaved position + texcoord (x, y, u, v)\n const verts = new Float32Array([\n x, y, 0, 0,\n x + w, y, uMax, 0,\n x, y + h, 0, vMax,\n x, y + h, 0, vMax,\n x + w, y, uMax, 0,\n x + w, y + h, uMax, vMax,\n ]);\n\n gl.bindBuffer(gl.ARRAY_BUFFER, this._texturedVBO);\n gl.bufferData(gl.ARRAY_BUFFER, verts, gl.DYNAMIC_DRAW);\n\n gl.useProgram(prog._program);\n gl.uniformMatrix3fv(prog._matrixLoc, false, this._matrix.getMatrix());\n this._setColorUniform(prog._colorLoc!, color, this._globalAlpha);\n\n // Use premultiplied alpha blending for text\n gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n\n const stride = 16; // 4 floats × 4 bytes\n gl.enableVertexAttribArray(prog._positionLoc);\n gl.vertexAttribPointer(prog._positionLoc, 2, gl.FLOAT, false, stride, 0);\n gl.enableVertexAttribArray(prog._texCoordLoc);\n gl.vertexAttribPointer(prog._texCoordLoc, 2, gl.FLOAT, false, stride, 8);\n\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, this._textTexture);\n gl.uniform1i(prog._textureLoc, 0);\n\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n\n // Restore standard blending\n gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\n\n // Disable texcoord attrib to avoid interfering with flat shader\n gl.disableVertexAttribArray(prog._texCoordLoc);\n }\n\n // -------------------------------------------------------------------------\n // Private: state management\n // -------------------------------------------------------------------------\n\n private _save(): void {\n this._matrix.save();\n this._stateStack.push({\n _fillColor: new Float32Array(this._fillColor),\n _strokeColor: new Float32Array(this._strokeColor),\n _lineWidth: this._lineWidth,\n _globalAlpha: this._globalAlpha,\n _font: this._font,\n _textAlign: this._textAlign,\n _textBaseline: this._textBaseline,\n _lineCap: this._lineCap,\n _lineJoin: this._lineJoin,\n _imageSmoothingEnabled: this._imageSmoothingEnabled,\n _letterSpacing: this._letterSpacing,\n _clipActive: this._clipActive,\n _clipRect: this._clipRect ? [...this._clipRect] as [number, number, number, number] : null,\n });\n }\n\n private _restore(): void {\n this._matrix.restore();\n const gl = this._gl;\n const state = this._stateStack.pop();\n if (state) {\n this._fillColor = state._fillColor;\n this._strokeColor = state._strokeColor;\n this._lineWidth = state._lineWidth;\n this._globalAlpha = state._globalAlpha;\n this._font = state._font;\n this._textAlign = state._textAlign;\n this._textBaseline = state._textBaseline;\n this._lineCap = state._lineCap;\n this._lineJoin = state._lineJoin;\n this._imageSmoothingEnabled = state._imageSmoothingEnabled;\n this._letterSpacing = state._letterSpacing;\n this._clipActive = state._clipActive;\n this._clipRect = state._clipRect;\n\n // Restore scissor state\n if (this._clipActive && this._clipRect) {\n const [x, y, w, h] = this._clipRect;\n gl.enable(gl.SCISSOR_TEST);\n gl.scissor(x, this._height - y - h, w, h);\n } else {\n gl.disable(gl.SCISSOR_TEST);\n }\n }\n }\n\n // -------------------------------------------------------------------------\n // Private: WebGL helpers\n // -------------------------------------------------------------------------\n\n private _setColorUniform(loc: WebGLUniformLocation, color: Float32Array, alpha: number): void {\n // Premultiply globalAlpha into the color's alpha channel\n const a = color[3] * alpha;\n this._gl.uniform4f(loc, color[0], color[1], color[2], a);\n }\n\n private _createProgram(vSrc: string, fSrc: string, hasTexCoord: boolean): _ProgramInfo {\n const gl = this._gl;\n const vs = this._compileShader(gl.VERTEX_SHADER, vSrc);\n const fs = this._compileShader(gl.FRAGMENT_SHADER, fSrc);\n\n const program = gl.createProgram()!;\n gl.attachShader(program, vs);\n gl.attachShader(program, fs);\n gl.linkProgram(program);\n\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n throw new Error('Shader link failed: ' + gl.getProgramInfoLog(program));\n }\n\n // Delete shaders after linking (they're embedded in the program now)\n gl.deleteShader(vs);\n gl.deleteShader(fs);\n\n return {\n _program: program,\n _matrixLoc: gl.getUniformLocation(program, 'u_matrix'),\n _colorLoc: gl.getUniformLocation(program, 'u_color'),\n _textureLoc: hasTexCoord ? gl.getUniformLocation(program, 'u_texture') : null,\n _positionLoc: gl.getAttribLocation(program, 'a_position'),\n _texCoordLoc: hasTexCoord ? gl.getAttribLocation(program, 'a_texCoord') : -1,\n };\n }\n\n private _compileShader(type: number, source: string): WebGLShader {\n const gl = this._gl;\n const shader = gl.createShader(type)!;\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n const info = gl.getShaderInfoLog(shader);\n gl.deleteShader(shader);\n throw new Error('Shader compile failed: ' + info);\n }\n return shader;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Utility\n// ---------------------------------------------------------------------------\n\n/** Extract numeric font size from a CSS font string like \"bold 20px monospace\". */\nfunction _parseFontSize(font: string): number {\n const match = font.match(/(\\d+(?:\\.\\d+)?)\\s*px/);\n return match ? parseFloat(match[1]) : 10;\n}\n\n/** Get width of a CanvasImageSource (handles HTMLImageElement, HTMLCanvasElement, OffscreenCanvas, etc.) */\nfunction _getImageWidth(img: CanvasImageSource): number {\n if ('naturalWidth' in img) return (img as HTMLImageElement).naturalWidth;\n return (img as HTMLCanvasElement | OffscreenCanvas).width;\n}\n\n/** Get height of a CanvasImageSource. */\nfunction _getImageHeight(img: CanvasImageSource): number {\n if ('naturalHeight' in img) return (img as HTMLImageElement).naturalHeight;\n return (img as HTMLCanvasElement | OffscreenCanvas).height;\n}\n","/**\n * UltrafastRenderer — WebGL2 Triple-Buffered Canvas 2D Renderer\n *\n * A standalone WebGL-accelerated Canvas 2D rendering engine. Provides a\n * CanvasAPI for recording draw commands and a triple-buffered FBO pipeline\n * that displays them via a passthrough shader at vsync rate.\n *\n * Triple buffer scheme (all on main thread, lock-free via JS single-threading):\n *\n * Content submission:\n * submitBatch(commands)\n * → bind writeFBO\n * → Canvas2DShim executes commands as WebGL draw calls\n * → swap: writeFBO ↔ readyFBO\n *\n * Display loop (vsync rate via RAF):\n * RAF callback\n * → auto-flush: drain CanvasAPI commands → submitBatch\n * → bind default framebuffer (display canvas)\n * → read readyFBO texture → passthrough blit → screen\n *\n * Extension points for downstream consumers (e.g. maalata CRT display):\n * - getGL(): access the WebGL2 context\n * - getReadyTexture(): read the latest rendered frame as a texture\n * - stopDisplay() / startDisplay(): take over the display loop\n */\n\nimport { CanvasAPI, type CanvasCommand } from './canvas-api';\nimport { Canvas2DShim } from './canvas2d-shim';\nimport {\n PASSTHROUGH_VERTEX_SRC,\n PASSTHROUGH_FRAGMENT_SRC,\n} from './shaders';\n\ninterface _FBO {\n _fbo: WebGLFramebuffer;\n _texture: WebGLTexture;\n}\n\nexport class UltrafastRenderer {\n private _gl: WebGL2RenderingContext;\n private _canvas: HTMLCanvasElement;\n private _shim: Canvas2DShim;\n private _api: CanvasAPI;\n private _rafId: number | null = null;\n\n // Triple buffer: three FBOs with color texture attachments\n private _fbos!: [_FBO, _FBO, _FBO];\n private _writeIdx = 0;\n private _readyIdx = 1;\n private _displayIdx = 2;\n private _hasContent = false;\n\n // Background color for opaque canvas clear (default: black, backwards compatible)\n private _bgColor = new Float32Array([0, 0, 0]);\n\n // Display program\n private _passthroughProgram: WebGLProgram;\n\n // Fullscreen quad VBO\n private _quadVBO!: WebGLBuffer;\n private _quadPositionLoc = -1;\n\n constructor(canvas: HTMLCanvasElement) {\n this._canvas = canvas;\n this._api = new CanvasAPI();\n\n // Create WebGL2 context with optimizations\n const gl = canvas.getContext('webgl2', {\n alpha: false,\n antialias: false,\n desynchronized: true,\n preserveDrawingBuffer: true,\n powerPreference: 'high-performance',\n });\n\n if (!gl) {\n throw new Error('WebGL2 not supported');\n }\n this._gl = gl;\n\n gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);\n\n // Initialize triple buffer FBOs\n this._initFBOs();\n\n // Initialize Canvas 2D shim (uses same GL context)\n this._shim = new Canvas2DShim(gl, canvas.width, canvas.height);\n\n // Initialize passthrough display program\n this._passthroughProgram = this._createShaderProgram(\n PASSTHROUGH_VERTEX_SRC, PASSTHROUGH_FRAGMENT_SRC\n );\n\n // Initialize fullscreen quad VBO for display pass\n this._initQuadVBO();\n\n // Clear all FBOs to black initially\n this._clearAllFBOs();\n\n // Auto-start display loop\n this.startDisplay();\n }\n\n // -------------------------------------------------------------------------\n // Public API (no _ prefix: cross-file access safe from mangleProps)\n // -------------------------------------------------------------------------\n\n /** Get the CanvasAPI for recording draw commands. */\n getCanvasAPI(): CanvasAPI {\n return this._api;\n }\n\n /**\n * Submit a batch of Canvas 2D commands to be rendered into the write FBO.\n * After rendering, the write and ready FBOs are swapped so the display\n * loop picks up the latest frame.\n */\n submitBatch(commands: CanvasCommand[]): void {\n if (commands.length === 0) return;\n const gl = this._gl;\n\n // Bind write FBO as render target\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._fbos[this._writeIdx]._fbo);\n gl.viewport(0, 0, this._canvas.width, this._canvas.height);\n\n // Execute Canvas 2D commands as WebGL draw calls\n this._shim.executeBatch(commands);\n\n // Swap write ↔ ready (new frame becomes available for display)\n const tmp = this._writeIdx;\n this._writeIdx = this._readyIdx;\n this._readyIdx = tmp;\n this._hasContent = true;\n }\n\n /** Start the passthrough RAF display loop with auto-flush. */\n startDisplay(): void {\n if (this._rafId !== null) return;\n this._displayLoop();\n }\n\n /** Stop the passthrough RAF display loop. Last frame persists (preserveDrawingBuffer). */\n stopDisplay(): void {\n if (this._rafId !== null) {\n cancelAnimationFrame(this._rafId);\n this._rafId = null;\n }\n }\n\n /** Returns the display canvas element. */\n getCanvas(): HTMLCanvasElement {\n return this._canvas;\n }\n\n /** Get canvas dimensions. */\n getCanvasSize(): { width: number; height: number } {\n return { width: this._canvas.width, height: this._canvas.height };\n }\n\n /** Capture the current displayed frame as an ImageBitmap. */\n screenshot(): Promise<ImageBitmap> {\n this._renderDisplay();\n return createImageBitmap(this._canvas);\n }\n\n /**\n * Set the opaque clear color used by clearRect and FBO initialization.\n * With alpha: false, cleared areas are opaque — this controls what color\n * they appear as instead of black. Values are in [0, 1] range.\n */\n setBackgroundColor(r: number, g: number, b: number): void {\n this._bgColor[0] = r;\n this._bgColor[1] = g;\n this._bgColor[2] = b;\n this._shim.setBackgroundColor(r, g, b);\n }\n\n /** Clean up all WebGL resources. */\n destroy(): void {\n this.stopDisplay();\n const gl = this._gl;\n\n this._shim.destroy();\n\n for (const fbo of this._fbos) {\n gl.deleteFramebuffer(fbo._fbo);\n gl.deleteTexture(fbo._texture);\n }\n\n gl.deleteProgram(this._passthroughProgram);\n gl.deleteBuffer(this._quadVBO);\n\n const ext = gl.getExtension('WEBGL_lose_context');\n if (ext) ext.loseContext();\n }\n\n // -------------------------------------------------------------------------\n // Extension points (used by maalata CRT display)\n // -------------------------------------------------------------------------\n\n /** Returns the WebGL2 context for external rendering (e.g. CRT shader). */\n getGL(): WebGL2RenderingContext {\n return this._gl;\n }\n\n /** Returns the ready FBO's texture — the latest fully rendered frame. */\n getReadyTexture(): WebGLTexture {\n return this._fbos[this._readyIdx]._texture;\n }\n\n // -------------------------------------------------------------------------\n // Private: display loop\n // -------------------------------------------------------------------------\n\n private _displayLoop(): void {\n this._rafId = requestAnimationFrame(() => this._displayLoop());\n\n // Auto-flush: drain any pending CanvasAPI commands into the pipeline\n const cmds = this._api.takeCommands();\n if (cmds.length) this.submitBatch(cmds);\n\n this._renderDisplay();\n }\n\n /**\n * Render the ready FBO to the display canvas via passthrough shader.\n * Called at vsync rate by RAF, or once synchronously for screenshots.\n */\n private _renderDisplay(): void {\n if (!this._hasContent) return;\n\n const gl = this._gl;\n\n // Bind default framebuffer (display canvas backbuffer)\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n gl.viewport(0, 0, this._canvas.width, this._canvas.height);\n\n // Bind the ready FBO's texture as input\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, this._fbos[this._readyIdx]._texture);\n\n gl.useProgram(this._passthroughProgram);\n\n // Draw fullscreen quad\n gl.bindBuffer(gl.ARRAY_BUFFER, this._quadVBO);\n gl.enableVertexAttribArray(this._quadPositionLoc);\n gl.vertexAttribPointer(this._quadPositionLoc, 2, gl.FLOAT, false, 0, 0);\n\n gl.disable(gl.BLEND);\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n gl.enable(gl.BLEND);\n }\n\n // -------------------------------------------------------------------------\n // Private: initialization\n // -------------------------------------------------------------------------\n\n private _initFBOs(): void {\n this._fbos = [\n this._createFBO(),\n this._createFBO(),\n this._createFBO(),\n ];\n }\n\n private _createFBO(): _FBO {\n const gl = this._gl;\n const w = this._canvas.width;\n const h = this._canvas.height;\n\n const fbo = gl.createFramebuffer()!;\n gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);\n\n const texture = gl.createTexture()!;\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA8, w, h);\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\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);\n\n const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);\n if (status !== gl.FRAMEBUFFER_COMPLETE) {\n throw new Error('Framebuffer incomplete: 0x' + status.toString(16));\n }\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n return { _fbo: fbo, _texture: texture };\n }\n\n private _clearAllFBOs(): void {\n const gl = this._gl;\n const bg = this._bgColor;\n for (const fbo of this._fbos) {\n gl.bindFramebuffer(gl.FRAMEBUFFER, fbo._fbo);\n gl.clearColor(bg[0], bg[1], bg[2], 1);\n gl.clear(gl.COLOR_BUFFER_BIT);\n }\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n gl.clearColor(bg[0], bg[1], bg[2], 1);\n gl.clear(gl.COLOR_BUFFER_BIT);\n }\n\n private _initQuadVBO(): void {\n const gl = this._gl;\n\n this._quadVBO = gl.createBuffer()!;\n gl.bindBuffer(gl.ARRAY_BUFFER, this._quadVBO);\n gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([\n 0, 0, 1, 0, 0, 1,\n 0, 1, 1, 0, 1, 1,\n ]), gl.STATIC_DRAW);\n\n this._quadPositionLoc = gl.getAttribLocation(this._passthroughProgram, 'a_position');\n }\n\n // -------------------------------------------------------------------------\n // Private: shader helpers\n // -------------------------------------------------------------------------\n\n private _createShaderProgram(vSrc: string, fSrc: string): WebGLProgram {\n const gl = this._gl;\n const vs = this._compileShader(gl.VERTEX_SHADER, vSrc);\n const fs = this._compileShader(gl.FRAGMENT_SHADER, fSrc);\n\n const program = gl.createProgram()!;\n gl.attachShader(program, vs);\n gl.attachShader(program, fs);\n gl.linkProgram(program);\n\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n throw new Error('Shader link failed: ' + gl.getProgramInfoLog(program));\n }\n\n gl.deleteShader(vs);\n gl.deleteShader(fs);\n\n return program;\n }\n\n private _compileShader(type: number, source: string): WebGLShader {\n const gl = this._gl;\n const shader = gl.createShader(type)!;\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n const info = gl.getShaderInfoLog(shader);\n gl.deleteShader(shader);\n throw new Error('Shader compile failed: ' + info);\n }\n return shader;\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"canvas-ultrafast.es.js","sources":["../src/canvas-api.ts","../src/matrix-stack.ts","../src/color-parser.ts","../src/shaders.ts","../src/canvas2d-shim.ts","../src/renderer.ts"],"sourcesContent":["/**\n * Canvas API Wrapper\n *\n * Provides a Canvas 2D API that records commands locally without await.\n * Commands are batched and sent to the worker for execution.\n */\n\ntype CanvasPropertyMap = {\n fillStyle: string | CanvasGradient | CanvasPattern;\n strokeStyle: string | CanvasGradient | CanvasPattern;\n lineWidth: number;\n lineCap: CanvasLineCap;\n lineJoin: CanvasLineJoin;\n miterLimit: number;\n lineDashOffset: number;\n font: string;\n textAlign: CanvasTextAlign;\n textBaseline: CanvasTextBaseline;\n globalAlpha: number;\n globalCompositeOperation: GlobalCompositeOperation;\n shadowBlur: number;\n shadowColor: string;\n shadowOffsetX: number;\n shadowOffsetY: number;\n imageSmoothingEnabled: boolean;\n letterSpacing: string;\n};\n\nexport type CanvasCommand =\n | { type: 'property'; name: string; value: unknown }\n | { type: 'method'; name: string; args: unknown[] };\n\nexport class CanvasAPI {\n private _c: CanvasCommand[] = [];\n private _cp: Partial<CanvasPropertyMap> = {};\n\n private _m(n: string, ...a: unknown[]): void {\n this._c.push({ type: 'method', name: n, args: a });\n }\n\n private _p<K extends keyof CanvasPropertyMap>(n: K, v: CanvasPropertyMap[K]): void {\n this._cp[n] = v;\n this._c.push({ type: 'property', name: n, value: v });\n }\n\n /**\n * Drain and return all buffered commands.\n * No _ prefix: called cross-file from pipeline, must survive mangleProps.\n */\n takeCommands(): CanvasCommand[] {\n if (this._c.length === 0) return [];\n const cmds = this._c;\n this._c = [];\n return cmds;\n }\n\n // Canvas 2D API methods\n\n // State\n save(): void { this._m('save'); }\n restore(): void { this._m('restore'); }\n\n // Transform\n scale(x: number, y: number): void { this._m('scale', x, y); }\n rotate(angle: number): void { this._m('rotate', angle); }\n translate(x: number, y: number): void { this._m('translate', x, y); }\n transform(a: number, b: number, c: number, d: number, e: number, f: number): void { this._m('transform', a, b, c, d, e, f); }\n setTransform(a: number, b: number, c: number, d: number, e: number, f: number): void { this._m('setTransform', a, b, c, d, e, f); }\n resetTransform(): void { this._m('resetTransform'); }\n\n // Rectangles\n clearRect(x: number, y: number, width: number, height: number): void { this._m('clearRect', x, y, width, height); }\n fillRect(x: number, y: number, width: number, height: number): void { this._m('fillRect', x, y, width, height); }\n strokeRect(x: number, y: number, width: number, height: number): void { this._m('strokeRect', x, y, width, height); }\n\n // Text\n fillText(text: string, x: number, y: number, maxWidth?: number): void {\n this._m('fillText', ...(maxWidth !== undefined ? [text, x, y, maxWidth] : [text, x, y]));\n }\n\n strokeText(text: string, x: number, y: number, maxWidth?: number): void {\n this._m('strokeText', ...(maxWidth !== undefined ? [text, x, y, maxWidth] : [text, x, y]));\n }\n\n /** Synchronous text measurement — cannot go through the async command pipeline. */\n private _measureCtx: OffscreenCanvasRenderingContext2D | null = null;\n\n measureText(text: string): TextMetrics {\n if (!this._measureCtx) {\n this._measureCtx = new OffscreenCanvas(1, 1).getContext('2d')!;\n }\n this._measureCtx.font = this.font;\n return this._measureCtx.measureText(text);\n }\n\n // Line drawing\n beginPath(): void { this._m('beginPath'); }\n closePath(): void { this._m('closePath'); }\n moveTo(x: number, y: number): void { this._m('moveTo', x, y); }\n lineTo(x: number, y: number): void { this._m('lineTo', x, y); }\n\n bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number): void {\n this._m('bezierCurveTo', cp1x, cp1y, cp2x, cp2y, x, y);\n }\n\n quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void { this._m('quadraticCurveTo', cpx, cpy, x, y); }\n\n arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, counterclockwise?: boolean): void {\n this._m('arc', ...(counterclockwise !== undefined ? [x, y, radius, startAngle, endAngle, counterclockwise] : [x, y, radius, startAngle, endAngle]));\n }\n\n arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): void { this._m('arcTo', x1, y1, x2, y2, radius); }\n\n ellipse(x: number, y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, counterclockwise?: boolean): void {\n this._m('ellipse', ...(counterclockwise !== undefined ? [x, y, radiusX, radiusY, rotation, startAngle, endAngle, counterclockwise] : [x, y, radiusX, radiusY, rotation, startAngle, endAngle]));\n }\n\n rect(x: number, y: number, width: number, height: number): void { this._m('rect', x, y, width, height); }\n\n // Images\n drawImage(image: CanvasImageSource, dx: number, dy: number): void;\n drawImage(image: CanvasImageSource, dx: number, dy: number, dw: number, dh: number): void;\n drawImage(image: CanvasImageSource, sx: number, sy: number, sw: number, sh: number, dx: number, dy: number, dw: number, dh: number): void;\n drawImage(...args: [CanvasImageSource, ...number[]]): void {\n this._m('drawImage', ...args);\n }\n\n // Fill and stroke\n fill(): void { this._m('fill'); }\n stroke(): void { this._m('stroke'); }\n clip(): void { this._m('clip'); }\n\n // Properties (setters)\n set fillStyle(value: string | CanvasGradient | CanvasPattern) { this._p('fillStyle', value); }\n set strokeStyle(value: string | CanvasGradient | CanvasPattern) { this._p('strokeStyle', value); }\n set lineWidth(value: number) { this._p('lineWidth', value); }\n set lineCap(value: CanvasLineCap) { this._p('lineCap', value); }\n set lineJoin(value: CanvasLineJoin) { this._p('lineJoin', value); }\n set miterLimit(value: number) { this._p('miterLimit', value); }\n set lineDashOffset(value: number) { this._p('lineDashOffset', value); }\n set font(value: string) { this._p('font', value); }\n set textAlign(value: CanvasTextAlign) { this._p('textAlign', value); }\n set textBaseline(value: CanvasTextBaseline) { this._p('textBaseline', value); }\n set globalAlpha(value: number) { this._p('globalAlpha', value); }\n set globalCompositeOperation(value: GlobalCompositeOperation) { this._p('globalCompositeOperation', value); }\n set shadowBlur(value: number) { this._p('shadowBlur', value); }\n set shadowColor(value: string) { this._p('shadowColor', value); }\n set shadowOffsetX(value: number) { this._p('shadowOffsetX', value); }\n set shadowOffsetY(value: number) { this._p('shadowOffsetY', value); }\n set imageSmoothingEnabled(value: boolean) { this._p('imageSmoothingEnabled', value); }\n set letterSpacing(value: string) { this._p('letterSpacing', value); }\n\n // Property getters (return local cached values)\n get fillStyle() { return this._cp['fillStyle'] ?? '#000'; }\n get strokeStyle() { return this._cp['strokeStyle'] ?? '#000'; }\n get lineWidth() { return this._cp['lineWidth'] ?? 1; }\n get lineCap() { return this._cp['lineCap'] ?? 'butt'; }\n get lineJoin() { return this._cp['lineJoin'] ?? 'miter'; }\n get miterLimit() { return this._cp['miterLimit'] ?? 10; }\n get lineDashOffset() { return this._cp['lineDashOffset'] ?? 0; }\n get font() { return this._cp['font'] ?? '10px sans-serif'; }\n get textAlign() { return this._cp['textAlign'] ?? 'start'; }\n get textBaseline() { return this._cp['textBaseline'] ?? 'alphabetic'; }\n get globalAlpha() { return this._cp['globalAlpha'] ?? 1; }\n get globalCompositeOperation() { return this._cp['globalCompositeOperation'] ?? 'source-over'; }\n get shadowBlur() { return this._cp['shadowBlur'] ?? 0; }\n get shadowColor() { return this._cp['shadowColor'] ?? 'rgba(0, 0, 0, 0)'; }\n get shadowOffsetX() { return this._cp['shadowOffsetX'] ?? 0; }\n get shadowOffsetY() { return this._cp['shadowOffsetY'] ?? 0; }\n get imageSmoothingEnabled() { return this._cp['imageSmoothingEnabled'] ?? true; }\n get letterSpacing() { return this._cp['letterSpacing'] ?? ''; }\n}","/**\n * 3×3 Affine Transform Matrix Stack\n *\n * Replicates Canvas 2D's save()/restore()/translate()/rotate()/scale()\n * as a matrix stack for WebGL uniform upload.\n *\n * Matrices are 3×3 column-major (for gl.uniformMatrix3fv), representing\n * 2D affine transforms. The base matrix includes an orthographic projection\n * that maps canvas pixel coordinates (top-left origin, Y-down) to WebGL\n * clip space ([-1,1], Y-up).\n *\n * Column-major layout of a 3×3 affine matrix:\n * [0] [3] [6] a c tx\n * [1] [4] [7] = b d ty\n * [2] [5] [8] 0 0 1\n */\n\nexport class MatrixStack {\n private _stack: Float32Array[] = [];\n private _current: Float32Array;\n private _projection: Float32Array;\n\n /**\n * @param width Canvas width in pixels\n * @param height Canvas height in pixels\n */\n constructor(width: number, height: number) {\n this._projection = _ortho(width, height);\n this._current = new Float32Array(this._projection);\n }\n\n /** Push current matrix onto the stack. No _ prefix: cross-file. */\n save(): void {\n this._stack.push(new Float32Array(this._current));\n }\n\n /** Pop and restore the top matrix. No _ prefix: cross-file. */\n restore(): void {\n if (this._stack.length > 0) {\n this._current = this._stack.pop()!;\n }\n }\n\n /** Translate the current matrix. No _ prefix: cross-file. */\n translate(x: number, y: number): void {\n // Multiply current matrix by translation:\n // 1 0 tx\n // 0 1 ty\n // 0 0 1\n // In column-major: m[6] += m[0]*tx + m[3]*ty\n // m[7] += m[1]*tx + m[4]*ty\n const m = this._current;\n m[6] += m[0] * x + m[3] * y;\n m[7] += m[1] * x + m[4] * y;\n }\n\n /** Rotate the current matrix by angle (radians). No _ prefix: cross-file. */\n rotate(angle: number): void {\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n const m = this._current;\n const m0 = m[0], m1 = m[1], m3 = m[3], m4 = m[4];\n m[0] = m0 * c + m3 * s;\n m[1] = m1 * c + m4 * s;\n m[3] = m0 * -s + m3 * c;\n m[4] = m1 * -s + m4 * c;\n }\n\n /** Scale the current matrix. No _ prefix: cross-file. */\n scale(x: number, y: number): void {\n const m = this._current;\n m[0] *= x; m[1] *= x;\n m[3] *= y; m[4] *= y;\n }\n\n /**\n * Multiply current matrix by an arbitrary 2D affine transform.\n * Canvas 2D transform(a, b, c, d, e, f) matrix:\n * a c e\n * b d f\n * 0 0 1\n * No _ prefix: cross-file.\n */\n transform(a: number, b: number, c: number, d: number, e: number, f: number): void {\n const m = this._current;\n const m0 = m[0], m1 = m[1], m3 = m[3], m4 = m[4], m6 = m[6], m7 = m[7];\n m[0] = m0 * a + m3 * b;\n m[1] = m1 * a + m4 * b;\n m[3] = m0 * c + m3 * d;\n m[4] = m1 * c + m4 * d;\n m[6] = m0 * e + m3 * f + m6;\n m[7] = m1 * e + m4 * f + m7;\n }\n\n /**\n * Reset to projection then apply the given affine transform.\n * Canvas 2D setTransform(a, b, c, d, e, f).\n * No _ prefix: cross-file.\n */\n setTransform(a: number, b: number, c: number, d: number, e: number, f: number): void {\n this._current.set(this._projection);\n this.transform(a, b, c, d, e, f);\n }\n\n /** Reset to the base orthographic projection. No _ prefix: cross-file. */\n resetTransform(): void {\n this._current.set(this._projection);\n }\n\n /**\n * Update canvas dimensions (e.g., on resize).\n * Recomputes the projection and resets the current matrix.\n * No _ prefix: cross-file.\n */\n resize(width: number, height: number): void {\n this._projection = _ortho(width, height);\n this._current = new Float32Array(this._projection);\n this._stack = [];\n }\n\n /**\n * Returns the current 3×3 matrix for gl.uniformMatrix3fv.\n * No _ prefix: cross-file.\n */\n getMatrix(): Float32Array {\n return this._current;\n }\n}\n\n/**\n * Create an orthographic projection matrix that maps:\n * Canvas coords (0,0)=top-left, (w,h)=bottom-right, Y-down\n * → Clip space (-1,-1)=bottom-left, (1,1)=top-right, Y-up\n *\n * The transform is:\n * x_clip = x * 2/w - 1\n * y_clip = -(y * 2/h - 1) = 1 - y * 2/h\n *\n * Column-major 3×3:\n * 2/w 0 -1\n * 0 -2/h 1\n * 0 0 1\n */\nfunction _ortho(w: number, h: number): Float32Array {\n return new Float32Array([\n 2 / w, 0, 0, // column 0\n 0, -2 / h, 0, // column 1\n -1, 1, 1, // column 2\n ]);\n}\n","/**\n * CSS Color Parser\n *\n * Converts CSS color strings to Float32Array [r, g, b, a] in [0, 1] range\n * for use as WebGL uniform values.\n *\n * Supported formats:\n * - Hex: #rgb, #rrggbb, #rrggbbaa\n * - Functional: rgb(r, g, b), rgba(r, g, b, a)\n * - Named: basic CSS color keywords\n *\n * Includes a cache for repeated lookups (the demo reuses ~10 colors).\n */\n\nconst _NAMED_COLORS: Record<string, number> = {\n black: 0x000000ff,\n white: 0xffffffff,\n red: 0xff0000ff,\n green: 0x008000ff,\n blue: 0x0000ffff,\n yellow: 0xffff00ff,\n cyan: 0x00ffffff,\n magenta: 0xff00ffff,\n orange: 0xffa500ff,\n transparent: 0x00000000,\n};\n\nconst _cache = new Map<string, Float32Array>();\n\n/**\n * Parse a CSS color string into [r, g, b, a] floats in [0, 1].\n * Returns a cached Float32Array — do NOT mutate the result.\n *\n * No _ prefix: called cross-file from canvas2d-shim.\n */\nexport function parseColor(css: string): Float32Array {\n const cached = _cache.get(css);\n if (cached) return cached;\n\n const result = _parse(css);\n _cache.set(css, result);\n return result;\n}\n\nfunction _parse(css: string): Float32Array {\n const s = css.trim();\n\n // #hex\n if (s.charCodeAt(0) === 0x23) { // '#'\n return _parseHex(s);\n }\n\n // rgb() / rgba()\n if (s.charCodeAt(0) === 0x72) { // 'r'\n return _parseRgb(s);\n }\n\n // Named color\n const named = _NAMED_COLORS[s.toLowerCase()];\n if (named !== undefined) {\n return new Float32Array([\n ((named >>> 24) & 0xff) / 255,\n ((named >>> 16) & 0xff) / 255,\n ((named >>> 8) & 0xff) / 255,\n (named & 0xff) / 255,\n ]);\n }\n\n // Fallback: opaque black\n return new Float32Array([0, 0, 0, 1]);\n}\n\nfunction _parseHex(s: string): Float32Array {\n const len = s.length;\n\n if (len === 4) {\n // #rgb → expand to #rrggbb\n const r = parseInt(s[1], 16);\n const g = parseInt(s[2], 16);\n const b = parseInt(s[3], 16);\n return new Float32Array([\n (r * 17) / 255,\n (g * 17) / 255,\n (b * 17) / 255,\n 1,\n ]);\n }\n\n if (len === 7) {\n // #rrggbb\n const r = parseInt(s.slice(1, 3), 16);\n const g = parseInt(s.slice(3, 5), 16);\n const b = parseInt(s.slice(5, 7), 16);\n return new Float32Array([r / 255, g / 255, b / 255, 1]);\n }\n\n if (len === 9) {\n // #rrggbbaa\n const r = parseInt(s.slice(1, 3), 16);\n const g = parseInt(s.slice(3, 5), 16);\n const b = parseInt(s.slice(5, 7), 16);\n const a = parseInt(s.slice(7, 9), 16);\n return new Float32Array([r / 255, g / 255, b / 255, a / 255]);\n }\n\n // #rgba (4-digit with alpha)\n if (len === 5) {\n const r = parseInt(s[1], 16);\n const g = parseInt(s[2], 16);\n const b = parseInt(s[3], 16);\n const a = parseInt(s[4], 16);\n return new Float32Array([\n (r * 17) / 255,\n (g * 17) / 255,\n (b * 17) / 255,\n (a * 17) / 255,\n ]);\n }\n\n return new Float32Array([0, 0, 0, 1]);\n}\n\nfunction _parseRgb(s: string): Float32Array {\n // Match both rgb(...) and rgba(...)\n // Extract the numeric values between parentheses\n const start = s.indexOf('(');\n const end = s.lastIndexOf(')');\n if (start === -1 || end === -1) return new Float32Array([0, 0, 0, 1]);\n\n const parts = s.slice(start + 1, end).split(',');\n const r = parseFloat(parts[0]) / 255;\n const g = parseFloat(parts[1]) / 255;\n const b = parseFloat(parts[2]) / 255;\n const a = parts.length >= 4 ? parseFloat(parts[3]) : 1;\n\n return new Float32Array([r, g, b, a]);\n}\n","/**\n * GLSL Shader Sources for canvas-ultrafast\n *\n * Content shaders (flat-color, textured) plus a passthrough display shader.\n * CRT post-processing shaders live in the maalata package.\n *\n * Coordinate convention:\n * - Content shaders use a 3x3 affine matrix (u_matrix) that maps\n * canvas pixel coordinates (top-left origin, Y-down) to clip space.\n * - Passthrough shader uses a fullscreen quad in [0,1] mapped to [-1,1] clip space.\n */\n\n// ---------------------------------------------------------------------------\n// Flat-color shader: rectangles, line quads, clear regions\n// ---------------------------------------------------------------------------\n\nexport const FLAT_VERTEX_SRC = `\n attribute vec2 a_position;\n uniform mat3 u_matrix;\n void main() {\n vec3 pos = u_matrix * vec3(a_position, 1.0);\n gl_Position = vec4(pos.xy, 0.0, 1.0);\n }\n`;\n\nexport const FLAT_FRAGMENT_SRC = `\n precision mediump float;\n uniform vec4 u_color;\n void main() {\n gl_FragColor = u_color;\n }\n`;\n\n// ---------------------------------------------------------------------------\n// Textured quad shader: text rendering via OffscreenCanvas glyph upload\n// ---------------------------------------------------------------------------\n\nexport const TEXTURED_VERTEX_SRC = `\n attribute vec2 a_position;\n attribute vec2 a_texCoord;\n uniform mat3 u_matrix;\n varying vec2 v_texCoord;\n void main() {\n vec3 pos = u_matrix * vec3(a_position, 1.0);\n gl_Position = vec4(pos.xy, 0.0, 1.0);\n v_texCoord = a_texCoord;\n }\n`;\n\nexport const TEXTURED_FRAGMENT_SRC = `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D u_texture;\n uniform vec4 u_color;\n void main() {\n vec4 texel = texture2D(u_texture, v_texCoord);\n gl_FragColor = texel * u_color;\n }\n`;\n\n// ---------------------------------------------------------------------------\n// Passthrough display shader: fullscreen quad, reads FBO texture\n// ---------------------------------------------------------------------------\n\n/**\n * Vertex shader: fullscreen quad [0,1] → clip space [-1,1].\n * FBO textures are already in GL-native bottom-left origin (the orthographic\n * projection in matrix-stack.ts handles the canvas Y-down → GL Y-up flip),\n * so tex coords pass through without Y-flip.\n */\nexport const PASSTHROUGH_VERTEX_SRC = `\n attribute vec2 a_position;\n varying vec2 v_texCoord;\n void main() {\n v_texCoord = a_position;\n gl_Position = vec4(a_position * 2.0 - 1.0, 0, 1);\n }\n`;\n\n/**\n * Passthrough fragment shader: blit FBO texture to screen without effects.\n */\nexport const PASSTHROUGH_FRAGMENT_SRC = `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D u_texture;\n void main() {\n gl_FragColor = texture2D(u_texture, v_texCoord);\n }\n`;\n","/**\n * Canvas 2D → WebGL Command Shim\n *\n * Translates CanvasCommand[] (recorded by CanvasAPI) into WebGL draw calls.\n * Handles the subset of Canvas 2D API used by the demo, plus reasonable\n * extensions. Operations not yet implemented log a warning and no-op.\n *\n * Rendering approach per command type:\n * - clearRect: gl.scissor + gl.clear\n * - fillRect: unit quad VBO + flat shader + transform uniform\n * - strokeRect: four thin quads (one per edge)\n * - fillText: render to OffscreenCanvas 2D → texImage2D → textured quad\n * - stroke(): expand line segments to quads on CPU, flat shader\n * - save/restore: matrix + state stack\n *\n * Text rendering uses an OffscreenCanvas with a 2D context as a glyph\n * rendering surface. At 8 FPS with ~5 text draws per frame, per-string\n * rendering (not glyph caching) is appropriate — texImage2D(OffscreenCanvas)\n * is a fast GPU upload path.\n */\n\nimport { CanvasCommand } from './canvas-api';\nimport { MatrixStack } from './matrix-stack';\nimport { parseColor } from './color-parser';\nimport {\n FLAT_VERTEX_SRC, FLAT_FRAGMENT_SRC,\n TEXTURED_VERTEX_SRC, TEXTURED_FRAGMENT_SRC,\n} from './shaders';\n\ninterface _DrawState {\n _fillColor: Float32Array;\n _strokeColor: Float32Array;\n _lineWidth: number;\n _globalAlpha: number;\n _font: string;\n _textAlign: CanvasTextAlign;\n _textBaseline: CanvasTextBaseline;\n _lineCap: CanvasLineCap;\n _lineJoin: CanvasLineJoin;\n _imageSmoothingEnabled: boolean;\n _letterSpacing: string;\n _clipActive: boolean;\n _clipRect: [number, number, number, number] | null;\n}\n\ninterface _ProgramInfo {\n _program: WebGLProgram;\n _matrixLoc: WebGLUniformLocation | null;\n _colorLoc: WebGLUniformLocation | null;\n _textureLoc: WebGLUniformLocation | null;\n _positionLoc: number;\n _texCoordLoc: number;\n}\n\nexport class Canvas2DShim {\n private _gl: WebGLRenderingContext;\n private _width: number;\n private _height: number;\n\n // Transform\n private _matrix: MatrixStack;\n\n // State\n private _fillColor: Float32Array = new Float32Array([0, 0, 0, 1]);\n private _strokeColor: Float32Array = new Float32Array([0, 0, 0, 1]);\n private _lineWidth = 1;\n private _globalAlpha = 1;\n private _font = '10px sans-serif';\n private _textAlign: CanvasTextAlign = 'start';\n private _textBaseline: CanvasTextBaseline = 'alphabetic';\n private _lineCap: CanvasLineCap = 'butt';\n private _lineJoin: CanvasLineJoin = 'miter';\n private _imageSmoothingEnabled = true;\n private _letterSpacing = '';\n private _clipActive = false;\n private _clipRect: [number, number, number, number] | null = null;\n private _pendingClipRect: [number, number, number, number] | null = null;\n private _imageTexCache = new WeakMap<object, { _tex: WebGLTexture; _isImage: boolean }>();\n private _stateStack: _DrawState[] = [];\n\n // Path state\n private _pathSegments: number[] = []; // flat: x0,y0,x1,y1,...\n private _currentX = 0;\n private _currentY = 0;\n private _subpathStartX = 0;\n private _subpathStartY = 0;\n\n // WebGL resources\n private _flat: _ProgramInfo;\n private _textured: _ProgramInfo;\n private _unitQuadVBO: WebGLBuffer;\n private _dynamicVBO: WebGLBuffer;\n private _texturedVBO: WebGLBuffer;\n private _textTexture: WebGLTexture;\n\n // Text rendering surface\n private _textCanvas: OffscreenCanvas;\n private _textCtx: OffscreenCanvasRenderingContext2D;\n\n // Background color for opaque canvas clear\n private _bgColor = new Float32Array([0, 0, 0]);\n\n // Temp arrays to avoid allocation in hot path\n private _tmpColor = new Float32Array(4);\n\n constructor(gl: WebGLRenderingContext, width: number, height: number) {\n this._gl = gl;\n this._width = width;\n this._height = height;\n this._matrix = new MatrixStack(width, height);\n\n // Compile shader programs\n this._flat = this._createProgram(\n FLAT_VERTEX_SRC, FLAT_FRAGMENT_SRC, false\n );\n this._textured = this._createProgram(\n TEXTURED_VERTEX_SRC, TEXTURED_FRAGMENT_SRC, true\n );\n\n // Unit quad VBO: two triangles covering [0,0]-[1,1]\n // Used for fillRect (scaled via matrix) and fullscreen blits\n this._unitQuadVBO = gl.createBuffer()!;\n gl.bindBuffer(gl.ARRAY_BUFFER, this._unitQuadVBO);\n gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([\n 0, 0, 1, 0, 0, 1,\n 0, 1, 1, 0, 1, 1,\n ]), gl.STATIC_DRAW);\n\n // Dynamic VBO for line quads — uses orphaning for double-buffer\n this._dynamicVBO = gl.createBuffer()!;\n\n // Textured quad VBO: position + texcoord interleaved\n this._texturedVBO = gl.createBuffer()!;\n\n // Text rendering texture\n this._textTexture = gl.createTexture()!;\n gl.bindTexture(gl.TEXTURE_2D, this._textTexture);\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\n // OffscreenCanvas for text glyph rendering\n this._textCanvas = new OffscreenCanvas(512, 128);\n this._textCtx = this._textCanvas.getContext('2d')!;\n\n // Enable blending for standard source-over compositing\n gl.enable(gl.BLEND);\n gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\n }\n\n /**\n * Execute a batch of Canvas 2D commands as WebGL draw calls.\n * No _ prefix: called cross-file from webgl-renderer.\n */\n executeBatch(commands: CanvasCommand[]): void {\n for (const cmd of commands) {\n if (cmd.type === 'property') {\n this._setProperty(cmd.name, cmd.value);\n } else {\n this._callMethod(cmd.name, cmd.args);\n }\n }\n }\n\n /**\n * Set the opaque clear color for clearRect.\n * No _ prefix: called cross-file from renderer.\n */\n setBackgroundColor(r: number, g: number, b: number): void {\n this._bgColor[0] = r;\n this._bgColor[1] = g;\n this._bgColor[2] = b;\n }\n\n /**\n * Update canvas dimensions on resize.\n * No _ prefix: called cross-file.\n */\n resize(width: number, height: number): void {\n this._width = width;\n this._height = height;\n this._matrix.resize(width, height);\n }\n\n /**\n * Clean up WebGL resources.\n * No _ prefix: called cross-file.\n */\n destroy(): void {\n const gl = this._gl;\n gl.deleteBuffer(this._unitQuadVBO);\n gl.deleteBuffer(this._dynamicVBO);\n gl.deleteBuffer(this._texturedVBO);\n gl.deleteTexture(this._textTexture);\n gl.deleteProgram(this._flat._program);\n gl.deleteProgram(this._textured._program);\n }\n\n // -------------------------------------------------------------------------\n // Private: property handling\n // -------------------------------------------------------------------------\n\n private _setProperty(name: string, value: unknown): void {\n switch (name) {\n case 'fillStyle':\n this._fillColor = parseColor(value as string);\n break;\n case 'strokeStyle':\n this._strokeColor = parseColor(value as string);\n break;\n case 'lineWidth':\n this._lineWidth = value as number;\n break;\n case 'globalAlpha':\n this._globalAlpha = value as number;\n break;\n case 'font':\n this._font = value as string;\n break;\n case 'textAlign':\n this._textAlign = value as CanvasTextAlign;\n break;\n case 'textBaseline':\n this._textBaseline = value as CanvasTextBaseline;\n break;\n case 'lineCap':\n this._lineCap = value as CanvasLineCap;\n break;\n case 'lineJoin':\n this._lineJoin = value as CanvasLineJoin;\n break;\n case 'imageSmoothingEnabled':\n this._imageSmoothingEnabled = value as boolean;\n break;\n case 'letterSpacing':\n this._letterSpacing = value as string;\n break;\n default:\n // Unsupported properties: silently ignore\n break;\n }\n }\n\n // -------------------------------------------------------------------------\n // Private: method dispatch\n // -------------------------------------------------------------------------\n\n private _callMethod(name: string, args: unknown[]): void {\n switch (name) {\n // Rectangles\n case 'clearRect':\n this._clearRect(args[0] as number, args[1] as number, args[2] as number, args[3] as number);\n break;\n case 'fillRect':\n this._fillRect(args[0] as number, args[1] as number, args[2] as number, args[3] as number);\n break;\n case 'strokeRect':\n this._strokeRect(args[0] as number, args[1] as number, args[2] as number, args[3] as number);\n break;\n\n // Text\n case 'fillText':\n this._fillText(args[0] as string, args[1] as number, args[2] as number);\n break;\n case 'strokeText':\n this._strokeText(args[0] as string, args[1] as number, args[2] as number);\n break;\n\n // Images\n case 'drawImage':\n this._drawImage(args);\n break;\n\n // Path\n case 'beginPath':\n this._pathSegments = [];\n this._pendingClipRect = null;\n break;\n case 'closePath':\n if (this._currentX !== this._subpathStartX || this._currentY !== this._subpathStartY) {\n this._pathSegments.push(\n this._currentX, this._currentY,\n this._subpathStartX, this._subpathStartY\n );\n this._currentX = this._subpathStartX;\n this._currentY = this._subpathStartY;\n }\n break;\n case 'moveTo':\n this._currentX = this._subpathStartX = args[0] as number;\n this._currentY = this._subpathStartY = args[1] as number;\n break;\n case 'lineTo': {\n const x = args[0] as number;\n const y = args[1] as number;\n this._pathSegments.push(this._currentX, this._currentY, x, y);\n this._currentX = x;\n this._currentY = y;\n break;\n }\n case 'rect': {\n const rx = args[0] as number, ry = args[1] as number;\n const rw = args[2] as number, rh = args[3] as number;\n // Store as pending clip rect (used if clip() follows)\n this._pendingClipRect = [rx, ry, rw, rh];\n // Also add 4 line segments to path for potential stroke()\n this._pathSegments.push(\n rx, ry, rx + rw, ry, // top\n rx + rw, ry, rx + rw, ry + rh, // right\n rx + rw, ry + rh, rx, ry + rh, // bottom\n rx, ry + rh, rx, ry, // left\n );\n break;\n }\n case 'clip':\n this._applyClip();\n break;\n case 'stroke':\n this._strokePath();\n break;\n case 'fill':\n // Convex fill only — not heavily used in demo beyond fillRect\n break;\n\n // State\n case 'save':\n this._save();\n break;\n case 'restore':\n this._restore();\n break;\n\n // Transforms\n case 'translate':\n this._matrix.translate(args[0] as number, args[1] as number);\n break;\n case 'rotate':\n this._matrix.rotate(args[0] as number);\n break;\n case 'scale':\n this._matrix.scale(args[0] as number, args[1] as number);\n break;\n case 'transform':\n this._matrix.transform(\n args[0] as number, args[1] as number, args[2] as number,\n args[3] as number, args[4] as number, args[5] as number\n );\n break;\n case 'setTransform':\n this._matrix.setTransform(\n args[0] as number, args[1] as number, args[2] as number,\n args[3] as number, args[4] as number, args[5] as number\n );\n break;\n case 'resetTransform':\n this._matrix.resetTransform();\n break;\n\n default:\n // Unsupported methods: silently ignore (arc, bezierCurveTo, etc.)\n break;\n }\n }\n\n // -------------------------------------------------------------------------\n // Private: drawing operations\n // -------------------------------------------------------------------------\n\n private _clearRect(x: number, y: number, w: number, h: number): void {\n const gl = this._gl;\n const bg = this._bgColor;\n // WebGL scissor uses bottom-left origin, canvas uses top-left\n gl.enable(gl.SCISSOR_TEST);\n gl.scissor(x, this._height - y - h, w, h);\n gl.clearColor(bg[0], bg[1], bg[2], 1);\n gl.clear(gl.COLOR_BUFFER_BIT);\n gl.disable(gl.SCISSOR_TEST);\n }\n\n private _fillRect(x: number, y: number, w: number, h: number): void {\n const gl = this._gl;\n const prog = this._flat;\n\n gl.useProgram(prog._program);\n\n // Build transform: current matrix × translate(x,y) × scale(w,h)\n // Applied to unit quad [0,1]×[0,1] → fills [x,y,x+w,y+h]\n this._matrix.save();\n this._matrix.translate(x, y);\n this._matrix.scale(w, h);\n\n gl.uniformMatrix3fv(prog._matrixLoc, false, this._matrix.getMatrix());\n this._setColorUniform(prog._colorLoc!, this._fillColor, this._globalAlpha);\n\n this._matrix.restore();\n\n // Draw unit quad\n gl.bindBuffer(gl.ARRAY_BUFFER, this._unitQuadVBO);\n gl.enableVertexAttribArray(prog._positionLoc);\n gl.vertexAttribPointer(prog._positionLoc, 2, gl.FLOAT, false, 0, 0);\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n }\n\n private _strokeRect(x: number, y: number, w: number, h: number): void {\n // Draw four edges as thin quads\n const lw = this._lineWidth;\n const hlw = lw / 2;\n\n // Top edge\n this._fillRectWithColor(x - hlw, y - hlw, w + lw, lw, this._strokeColor);\n // Bottom edge\n this._fillRectWithColor(x - hlw, y + h - hlw, w + lw, lw, this._strokeColor);\n // Left edge\n this._fillRectWithColor(x - hlw, y + hlw, lw, h - lw, this._strokeColor);\n // Right edge\n this._fillRectWithColor(x + w - hlw, y + hlw, lw, h - lw, this._strokeColor);\n }\n\n /** Internal: draw a filled rect with a specific color (used by strokeRect). */\n private _fillRectWithColor(x: number, y: number, w: number, h: number, color: Float32Array): void {\n const gl = this._gl;\n const prog = this._flat;\n\n gl.useProgram(prog._program);\n\n this._matrix.save();\n this._matrix.translate(x, y);\n this._matrix.scale(w, h);\n\n gl.uniformMatrix3fv(prog._matrixLoc, false, this._matrix.getMatrix());\n this._setColorUniform(prog._colorLoc!, color, this._globalAlpha);\n\n this._matrix.restore();\n\n gl.bindBuffer(gl.ARRAY_BUFFER, this._unitQuadVBO);\n gl.enableVertexAttribArray(prog._positionLoc);\n gl.vertexAttribPointer(prog._positionLoc, 2, gl.FLOAT, false, 0, 0);\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n }\n\n private _strokePath(): void {\n const segs = this._pathSegments;\n if (segs.length === 0) return;\n\n const gl = this._gl;\n const prog = this._flat;\n const halfW = Math.max(this._lineWidth / 2, 0.5);\n\n // Expand line segments to quads on CPU\n // Each segment (x0,y0,x1,y1) → 6 vertices (2 triangles)\n const segCount = segs.length / 4;\n const vertices = new Float32Array(segCount * 12); // 6 vertices × 2 coords\n\n for (let i = 0, vi = 0; i < segs.length; i += 4) {\n const x0 = segs[i], y0 = segs[i + 1], x1 = segs[i + 2], y1 = segs[i + 3];\n const dx = x1 - x0;\n const dy = y1 - y0;\n const len = Math.sqrt(dx * dx + dy * dy);\n\n if (len < 0.001) continue; // Skip degenerate segments\n\n // Normal perpendicular to line direction\n const nx = (-dy / len) * halfW;\n const ny = (dx / len) * halfW;\n\n // Four corners of the quad\n const ax = x0 + nx, ay = y0 + ny; // top-left\n const bx = x0 - nx, by = y0 - ny; // bottom-left\n const cx = x1 + nx, cy = y1 + ny; // top-right\n const dx2 = x1 - nx, dy2 = y1 - ny; // bottom-right\n\n // Triangle 1: A, B, C\n vertices[vi++] = ax; vertices[vi++] = ay;\n vertices[vi++] = bx; vertices[vi++] = by;\n vertices[vi++] = cx; vertices[vi++] = cy;\n // Triangle 2: B, D, C\n vertices[vi++] = bx; vertices[vi++] = by;\n vertices[vi++] = dx2; vertices[vi++] = dy2;\n vertices[vi++] = cx; vertices[vi++] = cy;\n }\n\n // Upload to dynamic VBO using orphaning (bufferData null pattern)\n gl.bindBuffer(gl.ARRAY_BUFFER, this._dynamicVBO);\n gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.DYNAMIC_DRAW);\n\n gl.useProgram(prog._program);\n gl.uniformMatrix3fv(prog._matrixLoc, false, this._matrix.getMatrix());\n this._setColorUniform(prog._colorLoc!, this._strokeColor, this._globalAlpha);\n\n gl.enableVertexAttribArray(prog._positionLoc);\n gl.vertexAttribPointer(prog._positionLoc, 2, gl.FLOAT, false, 0, 0);\n gl.drawArrays(gl.TRIANGLES, 0, segCount * 6);\n }\n\n private _drawImage(args: unknown[]): void {\n const gl = this._gl;\n const image = args[0] as CanvasImageSource;\n\n let sx: number, sy: number, sw: number, sh: number;\n let dx: number, dy: number, dw: number, dh: number;\n\n // Get image dimensions\n const imgW = _getImageWidth(image);\n const imgH = _getImageHeight(image);\n\n if (args.length === 3) {\n // drawImage(image, dx, dy)\n sx = 0; sy = 0; sw = imgW; sh = imgH;\n dx = args[1] as number; dy = args[2] as number;\n dw = imgW; dh = imgH;\n } else if (args.length === 5) {\n // drawImage(image, dx, dy, dw, dh)\n sx = 0; sy = 0; sw = imgW; sh = imgH;\n dx = args[1] as number; dy = args[2] as number;\n dw = args[3] as number; dh = args[4] as number;\n } else {\n // drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)\n sx = args[1] as number; sy = args[2] as number;\n sw = args[3] as number; sh = args[4] as number;\n dx = args[5] as number; dy = args[6] as number;\n dw = args[7] as number; dh = args[8] as number;\n }\n\n // Get or create texture for this image source\n const tex = this._getOrUploadTexture(image, imgW, imgH);\n\n // Set filtering based on imageSmoothingEnabled\n const filter = this._imageSmoothingEnabled ? gl.LINEAR : gl.NEAREST;\n gl.bindTexture(gl.TEXTURE_2D, tex);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filter);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filter);\n\n // Compute UV coordinates for source sub-rect\n const uMin = sx / imgW;\n const vMin = sy / imgH;\n const uMax = (sx + sw) / imgW;\n const vMax = (sy + sh) / imgH;\n\n // Draw textured quad with interleaved position + texcoord\n const prog = this._textured;\n const verts = new Float32Array([\n dx, dy, uMin, vMin,\n dx + dw, dy, uMax, vMin,\n dx, dy + dh, uMin, vMax,\n dx, dy + dh, uMin, vMax,\n dx + dw, dy, uMax, vMin,\n dx + dw, dy + dh, uMax, vMax,\n ]);\n\n gl.bindBuffer(gl.ARRAY_BUFFER, this._texturedVBO);\n gl.bufferData(gl.ARRAY_BUFFER, verts, gl.DYNAMIC_DRAW);\n\n gl.useProgram(prog._program);\n gl.uniformMatrix3fv(prog._matrixLoc, false, this._matrix.getMatrix());\n // White color tint with globalAlpha — no color modification, just alpha\n gl.uniform4f(prog._colorLoc!, 1, 1, 1, this._globalAlpha);\n\n // Standard alpha blending (not premultiplied for image textures)\n const stride = 16; // 4 floats × 4 bytes\n gl.enableVertexAttribArray(prog._positionLoc);\n gl.vertexAttribPointer(prog._positionLoc, 2, gl.FLOAT, false, stride, 0);\n gl.enableVertexAttribArray(prog._texCoordLoc);\n gl.vertexAttribPointer(prog._texCoordLoc, 2, gl.FLOAT, false, stride, 8);\n\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, tex);\n gl.uniform1i(prog._textureLoc, 0);\n\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n\n // Disable texcoord attrib to avoid interfering with flat shader\n gl.disableVertexAttribArray(prog._texCoordLoc);\n }\n\n private _getOrUploadTexture(image: CanvasImageSource, imgW: number, imgH: number): WebGLTexture {\n const gl = this._gl;\n const key = image as unknown as object;\n const cached = this._imageTexCache.get(key);\n\n // HTMLImageElement/SVGImageElement: upload once, cache permanently\n // HTMLCanvasElement/OffscreenCanvas: always re-upload (content may change)\n const isImage = (image instanceof HTMLImageElement) || (image instanceof SVGImageElement);\n\n if (cached) {\n if (cached._isImage) {\n // Static image — reuse cached texture\n return cached._tex;\n }\n // Canvas source — re-upload to existing texture\n gl.bindTexture(gl.TEXTURE_2D, cached._tex);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image as TexImageSource);\n return cached._tex;\n }\n\n // Create new texture\n const tex = gl.createTexture()!;\n gl.bindTexture(gl.TEXTURE_2D, tex);\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\n // Detect if we need to handle alpha properly\n // For canvas sources, use standard upload; for images, avoid premultiply\n if (imgW > 0 && imgH > 0) {\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image as TexImageSource);\n }\n\n this._imageTexCache.set(key, { _tex: tex, _isImage: isImage });\n return tex;\n }\n\n private _applyClip(): void {\n const gl = this._gl;\n if (this._pendingClipRect) {\n const [x, y, w, h] = this._pendingClipRect;\n gl.enable(gl.SCISSOR_TEST);\n // Convert canvas coords (top-left origin) to GL coords (bottom-left origin)\n gl.scissor(x, this._height - y - h, w, h);\n this._clipActive = true;\n this._clipRect = [x, y, w, h];\n }\n }\n\n private _fillText(text: string, x: number, y: number): void {\n this._renderText(text, x, y, 'fill');\n }\n\n private _strokeText(text: string, x: number, y: number): void {\n this._renderText(text, x, y, 'stroke');\n }\n\n private _renderText(text: string, x: number, y: number, mode: 'fill' | 'stroke'): void {\n const gl = this._gl;\n const tCtx = this._textCtx;\n\n // Configure text rendering context\n tCtx.font = this._font;\n tCtx.textAlign = 'left'; // Always render left-aligned, position via WebGL\n tCtx.textBaseline = 'top'; // Always render from top, adjust Y via offset\n if (this._letterSpacing) {\n tCtx.letterSpacing = this._letterSpacing;\n }\n\n // Measure text\n const metrics = tCtx.measureText(text);\n const textWidth = Math.ceil(metrics.width) + 4; // +4 for antialiasing padding\n const fontSize = _parseFontSize(this._font);\n const textHeight = Math.ceil(fontSize * 1.5) + 4; // approximate height with descenders\n\n if (textWidth <= 0 || textHeight <= 0) return;\n\n // Resize text canvas if needed\n if (this._textCanvas.width < textWidth || this._textCanvas.height < textHeight) {\n this._textCanvas.width = Math.max(this._textCanvas.width, textWidth);\n this._textCanvas.height = Math.max(this._textCanvas.height, textHeight);\n // Re-set font after resize (context is reset)\n tCtx.font = this._font;\n tCtx.textAlign = 'left';\n tCtx.textBaseline = 'top';\n }\n\n // Clear and render text\n tCtx.clearRect(0, 0, this._textCanvas.width, this._textCanvas.height);\n\n if (mode === 'fill') {\n tCtx.fillStyle = 'white'; // White text, tinted by WebGL uniform\n tCtx.fillText(text, 2, 2); // +2 padding offset\n } else {\n tCtx.strokeStyle = 'white';\n tCtx.lineWidth = this._lineWidth;\n tCtx.strokeText(text, 2, 2);\n }\n\n // Upload text canvas to texture\n gl.bindTexture(gl.TEXTURE_2D, this._textTexture);\n gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 1);\n gl.texImage2D(\n gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE,\n this._textCanvas\n );\n gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 0);\n\n // Compute text position adjustments\n const color = mode === 'fill' ? this._fillColor : this._strokeColor;\n let drawX = x - 2; // compensate for padding\n let drawY = y - 2;\n\n // Adjust for textAlign\n switch (this._textAlign) {\n case 'center': drawX -= textWidth / 2; break;\n case 'right':\n case 'end': drawX -= textWidth; break;\n }\n\n // Adjust for textBaseline\n switch (this._textBaseline) {\n case 'top': /* drawY stays */ break;\n case 'middle': drawY -= textHeight / 2; break;\n case 'alphabetic':\n case 'ideographic': drawY -= fontSize; break;\n case 'bottom':\n case 'hanging': drawY -= textHeight; break;\n }\n\n // Draw textured quad\n this._drawTexturedQuad(\n drawX, drawY, textWidth, textHeight,\n textWidth / this._textCanvas.width,\n textHeight / this._textCanvas.height,\n color\n );\n }\n\n private _drawTexturedQuad(\n x: number, y: number, w: number, h: number,\n uMax: number, vMax: number,\n color: Float32Array\n ): void {\n const gl = this._gl;\n const prog = this._textured;\n\n // Interleaved position + texcoord (x, y, u, v)\n const verts = new Float32Array([\n x, y, 0, 0,\n x + w, y, uMax, 0,\n x, y + h, 0, vMax,\n x, y + h, 0, vMax,\n x + w, y, uMax, 0,\n x + w, y + h, uMax, vMax,\n ]);\n\n gl.bindBuffer(gl.ARRAY_BUFFER, this._texturedVBO);\n gl.bufferData(gl.ARRAY_BUFFER, verts, gl.DYNAMIC_DRAW);\n\n gl.useProgram(prog._program);\n gl.uniformMatrix3fv(prog._matrixLoc, false, this._matrix.getMatrix());\n this._setColorUniform(prog._colorLoc!, color, this._globalAlpha);\n\n // Use premultiplied alpha blending for text\n gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n\n const stride = 16; // 4 floats × 4 bytes\n gl.enableVertexAttribArray(prog._positionLoc);\n gl.vertexAttribPointer(prog._positionLoc, 2, gl.FLOAT, false, stride, 0);\n gl.enableVertexAttribArray(prog._texCoordLoc);\n gl.vertexAttribPointer(prog._texCoordLoc, 2, gl.FLOAT, false, stride, 8);\n\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, this._textTexture);\n gl.uniform1i(prog._textureLoc, 0);\n\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n\n // Restore standard blending\n gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\n\n // Disable texcoord attrib to avoid interfering with flat shader\n gl.disableVertexAttribArray(prog._texCoordLoc);\n }\n\n // -------------------------------------------------------------------------\n // Private: state management\n // -------------------------------------------------------------------------\n\n private _save(): void {\n this._matrix.save();\n this._stateStack.push({\n _fillColor: new Float32Array(this._fillColor),\n _strokeColor: new Float32Array(this._strokeColor),\n _lineWidth: this._lineWidth,\n _globalAlpha: this._globalAlpha,\n _font: this._font,\n _textAlign: this._textAlign,\n _textBaseline: this._textBaseline,\n _lineCap: this._lineCap,\n _lineJoin: this._lineJoin,\n _imageSmoothingEnabled: this._imageSmoothingEnabled,\n _letterSpacing: this._letterSpacing,\n _clipActive: this._clipActive,\n _clipRect: this._clipRect ? [...this._clipRect] as [number, number, number, number] : null,\n });\n }\n\n private _restore(): void {\n this._matrix.restore();\n const gl = this._gl;\n const state = this._stateStack.pop();\n if (state) {\n this._fillColor = state._fillColor;\n this._strokeColor = state._strokeColor;\n this._lineWidth = state._lineWidth;\n this._globalAlpha = state._globalAlpha;\n this._font = state._font;\n this._textAlign = state._textAlign;\n this._textBaseline = state._textBaseline;\n this._lineCap = state._lineCap;\n this._lineJoin = state._lineJoin;\n this._imageSmoothingEnabled = state._imageSmoothingEnabled;\n this._letterSpacing = state._letterSpacing;\n this._clipActive = state._clipActive;\n this._clipRect = state._clipRect;\n\n // Restore scissor state\n if (this._clipActive && this._clipRect) {\n const [x, y, w, h] = this._clipRect;\n gl.enable(gl.SCISSOR_TEST);\n gl.scissor(x, this._height - y - h, w, h);\n } else {\n gl.disable(gl.SCISSOR_TEST);\n }\n }\n }\n\n // -------------------------------------------------------------------------\n // Private: WebGL helpers\n // -------------------------------------------------------------------------\n\n private _setColorUniform(loc: WebGLUniformLocation, color: Float32Array, alpha: number): void {\n // Premultiply globalAlpha into the color's alpha channel\n const a = color[3] * alpha;\n this._gl.uniform4f(loc, color[0], color[1], color[2], a);\n }\n\n private _createProgram(vSrc: string, fSrc: string, hasTexCoord: boolean): _ProgramInfo {\n const gl = this._gl;\n const vs = this._compileShader(gl.VERTEX_SHADER, vSrc);\n const fs = this._compileShader(gl.FRAGMENT_SHADER, fSrc);\n\n const program = gl.createProgram()!;\n gl.attachShader(program, vs);\n gl.attachShader(program, fs);\n gl.linkProgram(program);\n\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n throw new Error('Shader link failed: ' + gl.getProgramInfoLog(program));\n }\n\n // Delete shaders after linking (they're embedded in the program now)\n gl.deleteShader(vs);\n gl.deleteShader(fs);\n\n return {\n _program: program,\n _matrixLoc: gl.getUniformLocation(program, 'u_matrix'),\n _colorLoc: gl.getUniformLocation(program, 'u_color'),\n _textureLoc: hasTexCoord ? gl.getUniformLocation(program, 'u_texture') : null,\n _positionLoc: gl.getAttribLocation(program, 'a_position'),\n _texCoordLoc: hasTexCoord ? gl.getAttribLocation(program, 'a_texCoord') : -1,\n };\n }\n\n private _compileShader(type: number, source: string): WebGLShader {\n const gl = this._gl;\n const shader = gl.createShader(type)!;\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n const info = gl.getShaderInfoLog(shader);\n gl.deleteShader(shader);\n throw new Error('Shader compile failed: ' + info);\n }\n return shader;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Utility\n// ---------------------------------------------------------------------------\n\n/** Extract numeric font size from a CSS font string like \"bold 20px monospace\". */\nfunction _parseFontSize(font: string): number {\n const match = font.match(/(\\d+(?:\\.\\d+)?)\\s*px/);\n return match ? parseFloat(match[1]) : 10;\n}\n\n/** Get width of a CanvasImageSource (handles HTMLImageElement, HTMLCanvasElement, OffscreenCanvas, etc.) */\nfunction _getImageWidth(img: CanvasImageSource): number {\n if ('naturalWidth' in img) return (img as HTMLImageElement).naturalWidth;\n return (img as HTMLCanvasElement | OffscreenCanvas).width;\n}\n\n/** Get height of a CanvasImageSource. */\nfunction _getImageHeight(img: CanvasImageSource): number {\n if ('naturalHeight' in img) return (img as HTMLImageElement).naturalHeight;\n return (img as HTMLCanvasElement | OffscreenCanvas).height;\n}\n","/**\n * UltrafastRenderer — WebGL2 Triple-Buffered Canvas 2D Renderer\n *\n * A standalone WebGL-accelerated Canvas 2D rendering engine. Provides a\n * CanvasAPI for recording draw commands and a triple-buffered FBO pipeline\n * that displays them via a passthrough shader at vsync rate.\n *\n * Triple buffer scheme (all on main thread, lock-free via JS single-threading):\n *\n * Content submission:\n * submitBatch(commands)\n * → bind writeFBO\n * → Canvas2DShim executes commands as WebGL draw calls\n * → swap: writeFBO ↔ readyFBO\n *\n * Display loop (vsync rate via RAF):\n * RAF callback\n * → auto-flush: drain CanvasAPI commands → submitBatch\n * → bind default framebuffer (display canvas)\n * → read readyFBO texture → passthrough blit → screen\n *\n * Extension points for downstream consumers (e.g. maalata CRT display):\n * - getGL(): access the WebGL2 context\n * - getReadyTexture(): read the latest rendered frame as a texture\n * - stopDisplay() / startDisplay(): take over the display loop\n */\n\nimport { CanvasAPI, type CanvasCommand } from './canvas-api';\nimport { Canvas2DShim } from './canvas2d-shim';\nimport { parseColor } from './color-parser';\nimport {\n PASSTHROUGH_VERTEX_SRC,\n PASSTHROUGH_FRAGMENT_SRC,\n} from './shaders';\n\ninterface _FBO {\n _fbo: WebGLFramebuffer;\n _texture: WebGLTexture;\n}\n\nexport class UltrafastRenderer {\n private _gl: WebGL2RenderingContext;\n private _canvas: HTMLCanvasElement;\n private _shim: Canvas2DShim;\n private _api: CanvasAPI;\n private _rafId: number | null = null;\n\n // Triple buffer: three FBOs with color texture attachments\n private _fbos!: [_FBO, _FBO, _FBO];\n private _writeIdx = 0;\n private _readyIdx = 1;\n private _displayIdx = 2;\n private _hasContent = false;\n\n // Background color for opaque canvas clear (default: black, backwards compatible)\n private _bgColor = new Float32Array([0, 0, 0]);\n\n // Display program\n private _passthroughProgram: WebGLProgram;\n\n // Fullscreen quad VBO\n private _quadVBO!: WebGLBuffer;\n private _quadPositionLoc = -1;\n\n constructor(canvas: HTMLCanvasElement) {\n this._canvas = canvas;\n this._api = new CanvasAPI();\n\n // Create WebGL2 context with optimizations\n const gl = canvas.getContext('webgl2', {\n alpha: false,\n antialias: false,\n desynchronized: true,\n preserveDrawingBuffer: true,\n powerPreference: 'high-performance',\n });\n\n if (!gl) {\n throw new Error('WebGL2 not supported');\n }\n this._gl = gl;\n\n gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);\n\n // Initialize triple buffer FBOs\n this._initFBOs();\n\n // Initialize Canvas 2D shim (uses same GL context)\n this._shim = new Canvas2DShim(gl, canvas.width, canvas.height);\n\n // Initialize passthrough display program\n this._passthroughProgram = this._createShaderProgram(\n PASSTHROUGH_VERTEX_SRC, PASSTHROUGH_FRAGMENT_SRC\n );\n\n // Initialize fullscreen quad VBO for display pass\n this._initQuadVBO();\n\n // Clear all FBOs initially\n this._clearAllFBOs();\n\n // Auto-detect background color from DOM ancestors\n this._resolveBackgroundColor();\n\n // Auto-start display loop\n this.startDisplay();\n }\n\n // -------------------------------------------------------------------------\n // Public API (no _ prefix: cross-file access safe from mangleProps)\n // -------------------------------------------------------------------------\n\n /** Get the CanvasAPI for recording draw commands. */\n getCanvasAPI(): CanvasAPI {\n return this._api;\n }\n\n /**\n * Submit a batch of Canvas 2D commands to be rendered into the write FBO.\n * After rendering, the write and ready FBOs are swapped so the display\n * loop picks up the latest frame.\n */\n submitBatch(commands: CanvasCommand[]): void {\n if (commands.length === 0) return;\n const gl = this._gl;\n\n // Bind write FBO as render target\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._fbos[this._writeIdx]._fbo);\n gl.viewport(0, 0, this._canvas.width, this._canvas.height);\n\n // Execute Canvas 2D commands as WebGL draw calls\n this._shim.executeBatch(commands);\n\n // Swap write ↔ ready (new frame becomes available for display)\n const tmp = this._writeIdx;\n this._writeIdx = this._readyIdx;\n this._readyIdx = tmp;\n this._hasContent = true;\n }\n\n /** Start the passthrough RAF display loop with auto-flush. */\n startDisplay(): void {\n if (this._rafId !== null) return;\n this._displayLoop();\n }\n\n /** Stop the passthrough RAF display loop. Last frame persists (preserveDrawingBuffer). */\n stopDisplay(): void {\n if (this._rafId !== null) {\n cancelAnimationFrame(this._rafId);\n this._rafId = null;\n }\n }\n\n /** Returns the display canvas element. */\n getCanvas(): HTMLCanvasElement {\n return this._canvas;\n }\n\n /** Get canvas dimensions. */\n getCanvasSize(): { width: number; height: number } {\n return { width: this._canvas.width, height: this._canvas.height };\n }\n\n /** Capture the current displayed frame as an ImageBitmap. */\n screenshot(): Promise<ImageBitmap> {\n this._renderDisplay();\n return createImageBitmap(this._canvas);\n }\n\n /**\n * Set the opaque clear color used by clearRect and FBO initialization.\n * With alpha: false, cleared areas are opaque — this controls what color\n * they appear as instead of black. Values are in [0, 1] range.\n */\n setBackgroundColor(r: number, g: number, b: number): void {\n this._bgColor[0] = r;\n this._bgColor[1] = g;\n this._bgColor[2] = b;\n this._shim.setBackgroundColor(r, g, b);\n }\n\n /** Returns the current background color as [r, g, b] floats in [0, 1]. */\n getBackgroundColor(): [number, number, number] {\n return [this._bgColor[0], this._bgColor[1], this._bgColor[2]];\n }\n\n /** Clean up all WebGL resources. */\n destroy(): void {\n this.stopDisplay();\n const gl = this._gl;\n\n this._shim.destroy();\n\n for (const fbo of this._fbos) {\n gl.deleteFramebuffer(fbo._fbo);\n gl.deleteTexture(fbo._texture);\n }\n\n gl.deleteProgram(this._passthroughProgram);\n gl.deleteBuffer(this._quadVBO);\n\n const ext = gl.getExtension('WEBGL_lose_context');\n if (ext) ext.loseContext();\n }\n\n // -------------------------------------------------------------------------\n // Extension points (used by maalata CRT display)\n // -------------------------------------------------------------------------\n\n /** Returns the WebGL2 context for external rendering (e.g. CRT shader). */\n getGL(): WebGL2RenderingContext {\n return this._gl;\n }\n\n /** Returns the ready FBO's texture — the latest fully rendered frame. */\n getReadyTexture(): WebGLTexture {\n return this._fbos[this._readyIdx]._texture;\n }\n\n // -------------------------------------------------------------------------\n // Private: display loop\n // -------------------------------------------------------------------------\n\n private _displayLoop(): void {\n this._rafId = requestAnimationFrame(() => this._displayLoop());\n\n // Auto-flush: drain any pending CanvasAPI commands into the pipeline\n const cmds = this._api.takeCommands();\n if (cmds.length) this.submitBatch(cmds);\n\n this._renderDisplay();\n }\n\n /**\n * Render the ready FBO to the display canvas via passthrough shader.\n * Called at vsync rate by RAF, or once synchronously for screenshots.\n */\n private _renderDisplay(): void {\n if (!this._hasContent) return;\n\n const gl = this._gl;\n\n // Bind default framebuffer (display canvas backbuffer)\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n gl.viewport(0, 0, this._canvas.width, this._canvas.height);\n\n // Bind the ready FBO's texture as input\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, this._fbos[this._readyIdx]._texture);\n\n gl.useProgram(this._passthroughProgram);\n\n // Draw fullscreen quad\n gl.bindBuffer(gl.ARRAY_BUFFER, this._quadVBO);\n gl.enableVertexAttribArray(this._quadPositionLoc);\n gl.vertexAttribPointer(this._quadPositionLoc, 2, gl.FLOAT, false, 0, 0);\n\n gl.disable(gl.BLEND);\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n gl.enable(gl.BLEND);\n }\n\n // -------------------------------------------------------------------------\n // Private: initialization\n // -------------------------------------------------------------------------\n\n private _initFBOs(): void {\n this._fbos = [\n this._createFBO(),\n this._createFBO(),\n this._createFBO(),\n ];\n }\n\n private _createFBO(): _FBO {\n const gl = this._gl;\n const w = this._canvas.width;\n const h = this._canvas.height;\n\n const fbo = gl.createFramebuffer()!;\n gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);\n\n const texture = gl.createTexture()!;\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA8, w, h);\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\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);\n\n const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);\n if (status !== gl.FRAMEBUFFER_COMPLETE) {\n throw new Error('Framebuffer incomplete: 0x' + status.toString(16));\n }\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n return { _fbo: fbo, _texture: texture };\n }\n\n private _resolveBackgroundColor(): void {\n let el: HTMLElement | null = this._canvas.parentElement;\n while (el) {\n const bg = getComputedStyle(el).backgroundColor;\n if (bg && bg !== 'transparent' && bg !== 'rgba(0, 0, 0, 0)') {\n const c = parseColor(bg);\n if (c[3] > 0) {\n this.setBackgroundColor(c[0], c[1], c[2]);\n this._clearAllFBOs();\n return;\n }\n }\n el = el.parentElement;\n }\n\n // Fallback: white (browser default page background)\n this.setBackgroundColor(1, 1, 1);\n this._clearAllFBOs();\n }\n\n private _clearAllFBOs(): void {\n const gl = this._gl;\n const bg = this._bgColor;\n for (const fbo of this._fbos) {\n gl.bindFramebuffer(gl.FRAMEBUFFER, fbo._fbo);\n gl.clearColor(bg[0], bg[1], bg[2], 1);\n gl.clear(gl.COLOR_BUFFER_BIT);\n }\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n gl.clearColor(bg[0], bg[1], bg[2], 1);\n gl.clear(gl.COLOR_BUFFER_BIT);\n }\n\n private _initQuadVBO(): void {\n const gl = this._gl;\n\n this._quadVBO = gl.createBuffer()!;\n gl.bindBuffer(gl.ARRAY_BUFFER, this._quadVBO);\n gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([\n 0, 0, 1, 0, 0, 1,\n 0, 1, 1, 0, 1, 1,\n ]), gl.STATIC_DRAW);\n\n this._quadPositionLoc = gl.getAttribLocation(this._passthroughProgram, 'a_position');\n }\n\n // -------------------------------------------------------------------------\n // Private: shader helpers\n // -------------------------------------------------------------------------\n\n private _createShaderProgram(vSrc: string, fSrc: string): WebGLProgram {\n const gl = this._gl;\n const vs = this._compileShader(gl.VERTEX_SHADER, vSrc);\n const fs = this._compileShader(gl.FRAGMENT_SHADER, fSrc);\n\n const program = gl.createProgram()!;\n gl.attachShader(program, vs);\n gl.attachShader(program, fs);\n gl.linkProgram(program);\n\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n throw new Error('Shader link failed: ' + gl.getProgramInfoLog(program));\n }\n\n gl.deleteShader(vs);\n gl.deleteShader(fs);\n\n return program;\n }\n\n private _compileShader(type: number, source: string): WebGLShader {\n const gl = this._gl;\n const shader = gl.createShader(type)!;\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n const info = gl.getShaderInfoLog(shader);\n gl.deleteShader(shader);\n throw new Error('Shader compile failed: ' + info);\n }\n return shader;\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1279,6 +1279,7 @@
|
|
|
1279
1279
|
);
|
|
1280
1280
|
this._initQuadVBO();
|
|
1281
1281
|
this._clearAllFBOs();
|
|
1282
|
+
this._resolveBackgroundColor();
|
|
1282
1283
|
this.startDisplay();
|
|
1283
1284
|
}
|
|
1284
1285
|
// -------------------------------------------------------------------------
|
|
@@ -1340,6 +1341,10 @@
|
|
|
1340
1341
|
this._bgColor[2] = b;
|
|
1341
1342
|
this._shim.setBackgroundColor(r, g, b);
|
|
1342
1343
|
}
|
|
1344
|
+
/** Returns the current background color as [r, g, b] floats in [0, 1]. */
|
|
1345
|
+
getBackgroundColor() {
|
|
1346
|
+
return [this._bgColor[0], this._bgColor[1], this._bgColor[2]];
|
|
1347
|
+
}
|
|
1343
1348
|
/** Clean up all WebGL resources. */
|
|
1344
1349
|
destroy() {
|
|
1345
1350
|
this.stopDisplay();
|
|
@@ -1424,6 +1429,23 @@
|
|
|
1424
1429
|
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
1425
1430
|
return { _fbo: fbo, _texture: texture };
|
|
1426
1431
|
}
|
|
1432
|
+
_resolveBackgroundColor() {
|
|
1433
|
+
let el = this._canvas.parentElement;
|
|
1434
|
+
while (el) {
|
|
1435
|
+
const bg = getComputedStyle(el).backgroundColor;
|
|
1436
|
+
if (bg && bg !== "transparent" && bg !== "rgba(0, 0, 0, 0)") {
|
|
1437
|
+
const c = parseColor(bg);
|
|
1438
|
+
if (c[3] > 0) {
|
|
1439
|
+
this.setBackgroundColor(c[0], c[1], c[2]);
|
|
1440
|
+
this._clearAllFBOs();
|
|
1441
|
+
return;
|
|
1442
|
+
}
|
|
1443
|
+
}
|
|
1444
|
+
el = el.parentElement;
|
|
1445
|
+
}
|
|
1446
|
+
this.setBackgroundColor(1, 1, 1);
|
|
1447
|
+
this._clearAllFBOs();
|
|
1448
|
+
}
|
|
1427
1449
|
_clearAllFBOs() {
|
|
1428
1450
|
const gl = this._gl;
|
|
1429
1451
|
const bg = this._bgColor;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"canvas-ultrafast.umd.js","sources":["../src/canvas-api.ts","../src/matrix-stack.ts","../src/color-parser.ts","../src/shaders.ts","../src/canvas2d-shim.ts","../src/renderer.ts"],"sourcesContent":["/**\n * Canvas API Wrapper\n *\n * Provides a Canvas 2D API that records commands locally without await.\n * Commands are batched and sent to the worker for execution.\n */\n\ntype CanvasPropertyMap = {\n fillStyle: string | CanvasGradient | CanvasPattern;\n strokeStyle: string | CanvasGradient | CanvasPattern;\n lineWidth: number;\n lineCap: CanvasLineCap;\n lineJoin: CanvasLineJoin;\n miterLimit: number;\n lineDashOffset: number;\n font: string;\n textAlign: CanvasTextAlign;\n textBaseline: CanvasTextBaseline;\n globalAlpha: number;\n globalCompositeOperation: GlobalCompositeOperation;\n shadowBlur: number;\n shadowColor: string;\n shadowOffsetX: number;\n shadowOffsetY: number;\n imageSmoothingEnabled: boolean;\n letterSpacing: string;\n};\n\nexport type CanvasCommand =\n | { type: 'property'; name: string; value: unknown }\n | { type: 'method'; name: string; args: unknown[] };\n\nexport class CanvasAPI {\n private _c: CanvasCommand[] = [];\n private _cp: Partial<CanvasPropertyMap> = {};\n\n private _m(n: string, ...a: unknown[]): void {\n this._c.push({ type: 'method', name: n, args: a });\n }\n\n private _p<K extends keyof CanvasPropertyMap>(n: K, v: CanvasPropertyMap[K]): void {\n this._cp[n] = v;\n this._c.push({ type: 'property', name: n, value: v });\n }\n\n /**\n * Drain and return all buffered commands.\n * No _ prefix: called cross-file from pipeline, must survive mangleProps.\n */\n takeCommands(): CanvasCommand[] {\n if (this._c.length === 0) return [];\n const cmds = this._c;\n this._c = [];\n return cmds;\n }\n\n // Canvas 2D API methods\n\n // State\n save(): void { this._m('save'); }\n restore(): void { this._m('restore'); }\n\n // Transform\n scale(x: number, y: number): void { this._m('scale', x, y); }\n rotate(angle: number): void { this._m('rotate', angle); }\n translate(x: number, y: number): void { this._m('translate', x, y); }\n transform(a: number, b: number, c: number, d: number, e: number, f: number): void { this._m('transform', a, b, c, d, e, f); }\n setTransform(a: number, b: number, c: number, d: number, e: number, f: number): void { this._m('setTransform', a, b, c, d, e, f); }\n resetTransform(): void { this._m('resetTransform'); }\n\n // Rectangles\n clearRect(x: number, y: number, width: number, height: number): void { this._m('clearRect', x, y, width, height); }\n fillRect(x: number, y: number, width: number, height: number): void { this._m('fillRect', x, y, width, height); }\n strokeRect(x: number, y: number, width: number, height: number): void { this._m('strokeRect', x, y, width, height); }\n\n // Text\n fillText(text: string, x: number, y: number, maxWidth?: number): void {\n this._m('fillText', ...(maxWidth !== undefined ? [text, x, y, maxWidth] : [text, x, y]));\n }\n\n strokeText(text: string, x: number, y: number, maxWidth?: number): void {\n this._m('strokeText', ...(maxWidth !== undefined ? [text, x, y, maxWidth] : [text, x, y]));\n }\n\n /** Synchronous text measurement — cannot go through the async command pipeline. */\n private _measureCtx: OffscreenCanvasRenderingContext2D | null = null;\n\n measureText(text: string): TextMetrics {\n if (!this._measureCtx) {\n this._measureCtx = new OffscreenCanvas(1, 1).getContext('2d')!;\n }\n this._measureCtx.font = this.font;\n return this._measureCtx.measureText(text);\n }\n\n // Line drawing\n beginPath(): void { this._m('beginPath'); }\n closePath(): void { this._m('closePath'); }\n moveTo(x: number, y: number): void { this._m('moveTo', x, y); }\n lineTo(x: number, y: number): void { this._m('lineTo', x, y); }\n\n bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number): void {\n this._m('bezierCurveTo', cp1x, cp1y, cp2x, cp2y, x, y);\n }\n\n quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void { this._m('quadraticCurveTo', cpx, cpy, x, y); }\n\n arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, counterclockwise?: boolean): void {\n this._m('arc', ...(counterclockwise !== undefined ? [x, y, radius, startAngle, endAngle, counterclockwise] : [x, y, radius, startAngle, endAngle]));\n }\n\n arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): void { this._m('arcTo', x1, y1, x2, y2, radius); }\n\n ellipse(x: number, y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, counterclockwise?: boolean): void {\n this._m('ellipse', ...(counterclockwise !== undefined ? [x, y, radiusX, radiusY, rotation, startAngle, endAngle, counterclockwise] : [x, y, radiusX, radiusY, rotation, startAngle, endAngle]));\n }\n\n rect(x: number, y: number, width: number, height: number): void { this._m('rect', x, y, width, height); }\n\n // Images\n drawImage(image: CanvasImageSource, dx: number, dy: number): void;\n drawImage(image: CanvasImageSource, dx: number, dy: number, dw: number, dh: number): void;\n drawImage(image: CanvasImageSource, sx: number, sy: number, sw: number, sh: number, dx: number, dy: number, dw: number, dh: number): void;\n drawImage(...args: [CanvasImageSource, ...number[]]): void {\n this._m('drawImage', ...args);\n }\n\n // Fill and stroke\n fill(): void { this._m('fill'); }\n stroke(): void { this._m('stroke'); }\n clip(): void { this._m('clip'); }\n\n // Properties (setters)\n set fillStyle(value: string | CanvasGradient | CanvasPattern) { this._p('fillStyle', value); }\n set strokeStyle(value: string | CanvasGradient | CanvasPattern) { this._p('strokeStyle', value); }\n set lineWidth(value: number) { this._p('lineWidth', value); }\n set lineCap(value: CanvasLineCap) { this._p('lineCap', value); }\n set lineJoin(value: CanvasLineJoin) { this._p('lineJoin', value); }\n set miterLimit(value: number) { this._p('miterLimit', value); }\n set lineDashOffset(value: number) { this._p('lineDashOffset', value); }\n set font(value: string) { this._p('font', value); }\n set textAlign(value: CanvasTextAlign) { this._p('textAlign', value); }\n set textBaseline(value: CanvasTextBaseline) { this._p('textBaseline', value); }\n set globalAlpha(value: number) { this._p('globalAlpha', value); }\n set globalCompositeOperation(value: GlobalCompositeOperation) { this._p('globalCompositeOperation', value); }\n set shadowBlur(value: number) { this._p('shadowBlur', value); }\n set shadowColor(value: string) { this._p('shadowColor', value); }\n set shadowOffsetX(value: number) { this._p('shadowOffsetX', value); }\n set shadowOffsetY(value: number) { this._p('shadowOffsetY', value); }\n set imageSmoothingEnabled(value: boolean) { this._p('imageSmoothingEnabled', value); }\n set letterSpacing(value: string) { this._p('letterSpacing', value); }\n\n // Property getters (return local cached values)\n get fillStyle() { return this._cp['fillStyle'] ?? '#000'; }\n get strokeStyle() { return this._cp['strokeStyle'] ?? '#000'; }\n get lineWidth() { return this._cp['lineWidth'] ?? 1; }\n get lineCap() { return this._cp['lineCap'] ?? 'butt'; }\n get lineJoin() { return this._cp['lineJoin'] ?? 'miter'; }\n get miterLimit() { return this._cp['miterLimit'] ?? 10; }\n get lineDashOffset() { return this._cp['lineDashOffset'] ?? 0; }\n get font() { return this._cp['font'] ?? '10px sans-serif'; }\n get textAlign() { return this._cp['textAlign'] ?? 'start'; }\n get textBaseline() { return this._cp['textBaseline'] ?? 'alphabetic'; }\n get globalAlpha() { return this._cp['globalAlpha'] ?? 1; }\n get globalCompositeOperation() { return this._cp['globalCompositeOperation'] ?? 'source-over'; }\n get shadowBlur() { return this._cp['shadowBlur'] ?? 0; }\n get shadowColor() { return this._cp['shadowColor'] ?? 'rgba(0, 0, 0, 0)'; }\n get shadowOffsetX() { return this._cp['shadowOffsetX'] ?? 0; }\n get shadowOffsetY() { return this._cp['shadowOffsetY'] ?? 0; }\n get imageSmoothingEnabled() { return this._cp['imageSmoothingEnabled'] ?? true; }\n get letterSpacing() { return this._cp['letterSpacing'] ?? ''; }\n}","/**\n * 3×3 Affine Transform Matrix Stack\n *\n * Replicates Canvas 2D's save()/restore()/translate()/rotate()/scale()\n * as a matrix stack for WebGL uniform upload.\n *\n * Matrices are 3×3 column-major (for gl.uniformMatrix3fv), representing\n * 2D affine transforms. The base matrix includes an orthographic projection\n * that maps canvas pixel coordinates (top-left origin, Y-down) to WebGL\n * clip space ([-1,1], Y-up).\n *\n * Column-major layout of a 3×3 affine matrix:\n * [0] [3] [6] a c tx\n * [1] [4] [7] = b d ty\n * [2] [5] [8] 0 0 1\n */\n\nexport class MatrixStack {\n private _stack: Float32Array[] = [];\n private _current: Float32Array;\n private _projection: Float32Array;\n\n /**\n * @param width Canvas width in pixels\n * @param height Canvas height in pixels\n */\n constructor(width: number, height: number) {\n this._projection = _ortho(width, height);\n this._current = new Float32Array(this._projection);\n }\n\n /** Push current matrix onto the stack. No _ prefix: cross-file. */\n save(): void {\n this._stack.push(new Float32Array(this._current));\n }\n\n /** Pop and restore the top matrix. No _ prefix: cross-file. */\n restore(): void {\n if (this._stack.length > 0) {\n this._current = this._stack.pop()!;\n }\n }\n\n /** Translate the current matrix. No _ prefix: cross-file. */\n translate(x: number, y: number): void {\n // Multiply current matrix by translation:\n // 1 0 tx\n // 0 1 ty\n // 0 0 1\n // In column-major: m[6] += m[0]*tx + m[3]*ty\n // m[7] += m[1]*tx + m[4]*ty\n const m = this._current;\n m[6] += m[0] * x + m[3] * y;\n m[7] += m[1] * x + m[4] * y;\n }\n\n /** Rotate the current matrix by angle (radians). No _ prefix: cross-file. */\n rotate(angle: number): void {\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n const m = this._current;\n const m0 = m[0], m1 = m[1], m3 = m[3], m4 = m[4];\n m[0] = m0 * c + m3 * s;\n m[1] = m1 * c + m4 * s;\n m[3] = m0 * -s + m3 * c;\n m[4] = m1 * -s + m4 * c;\n }\n\n /** Scale the current matrix. No _ prefix: cross-file. */\n scale(x: number, y: number): void {\n const m = this._current;\n m[0] *= x; m[1] *= x;\n m[3] *= y; m[4] *= y;\n }\n\n /**\n * Multiply current matrix by an arbitrary 2D affine transform.\n * Canvas 2D transform(a, b, c, d, e, f) matrix:\n * a c e\n * b d f\n * 0 0 1\n * No _ prefix: cross-file.\n */\n transform(a: number, b: number, c: number, d: number, e: number, f: number): void {\n const m = this._current;\n const m0 = m[0], m1 = m[1], m3 = m[3], m4 = m[4], m6 = m[6], m7 = m[7];\n m[0] = m0 * a + m3 * b;\n m[1] = m1 * a + m4 * b;\n m[3] = m0 * c + m3 * d;\n m[4] = m1 * c + m4 * d;\n m[6] = m0 * e + m3 * f + m6;\n m[7] = m1 * e + m4 * f + m7;\n }\n\n /**\n * Reset to projection then apply the given affine transform.\n * Canvas 2D setTransform(a, b, c, d, e, f).\n * No _ prefix: cross-file.\n */\n setTransform(a: number, b: number, c: number, d: number, e: number, f: number): void {\n this._current.set(this._projection);\n this.transform(a, b, c, d, e, f);\n }\n\n /** Reset to the base orthographic projection. No _ prefix: cross-file. */\n resetTransform(): void {\n this._current.set(this._projection);\n }\n\n /**\n * Update canvas dimensions (e.g., on resize).\n * Recomputes the projection and resets the current matrix.\n * No _ prefix: cross-file.\n */\n resize(width: number, height: number): void {\n this._projection = _ortho(width, height);\n this._current = new Float32Array(this._projection);\n this._stack = [];\n }\n\n /**\n * Returns the current 3×3 matrix for gl.uniformMatrix3fv.\n * No _ prefix: cross-file.\n */\n getMatrix(): Float32Array {\n return this._current;\n }\n}\n\n/**\n * Create an orthographic projection matrix that maps:\n * Canvas coords (0,0)=top-left, (w,h)=bottom-right, Y-down\n * → Clip space (-1,-1)=bottom-left, (1,1)=top-right, Y-up\n *\n * The transform is:\n * x_clip = x * 2/w - 1\n * y_clip = -(y * 2/h - 1) = 1 - y * 2/h\n *\n * Column-major 3×3:\n * 2/w 0 -1\n * 0 -2/h 1\n * 0 0 1\n */\nfunction _ortho(w: number, h: number): Float32Array {\n return new Float32Array([\n 2 / w, 0, 0, // column 0\n 0, -2 / h, 0, // column 1\n -1, 1, 1, // column 2\n ]);\n}\n","/**\n * CSS Color Parser\n *\n * Converts CSS color strings to Float32Array [r, g, b, a] in [0, 1] range\n * for use as WebGL uniform values.\n *\n * Supported formats:\n * - Hex: #rgb, #rrggbb, #rrggbbaa\n * - Functional: rgb(r, g, b), rgba(r, g, b, a)\n * - Named: basic CSS color keywords\n *\n * Includes a cache for repeated lookups (the demo reuses ~10 colors).\n */\n\nconst _NAMED_COLORS: Record<string, number> = {\n black: 0x000000ff,\n white: 0xffffffff,\n red: 0xff0000ff,\n green: 0x008000ff,\n blue: 0x0000ffff,\n yellow: 0xffff00ff,\n cyan: 0x00ffffff,\n magenta: 0xff00ffff,\n orange: 0xffa500ff,\n transparent: 0x00000000,\n};\n\nconst _cache = new Map<string, Float32Array>();\n\n/**\n * Parse a CSS color string into [r, g, b, a] floats in [0, 1].\n * Returns a cached Float32Array — do NOT mutate the result.\n *\n * No _ prefix: called cross-file from canvas2d-shim.\n */\nexport function parseColor(css: string): Float32Array {\n const cached = _cache.get(css);\n if (cached) return cached;\n\n const result = _parse(css);\n _cache.set(css, result);\n return result;\n}\n\nfunction _parse(css: string): Float32Array {\n const s = css.trim();\n\n // #hex\n if (s.charCodeAt(0) === 0x23) { // '#'\n return _parseHex(s);\n }\n\n // rgb() / rgba()\n if (s.charCodeAt(0) === 0x72) { // 'r'\n return _parseRgb(s);\n }\n\n // Named color\n const named = _NAMED_COLORS[s.toLowerCase()];\n if (named !== undefined) {\n return new Float32Array([\n ((named >>> 24) & 0xff) / 255,\n ((named >>> 16) & 0xff) / 255,\n ((named >>> 8) & 0xff) / 255,\n (named & 0xff) / 255,\n ]);\n }\n\n // Fallback: opaque black\n return new Float32Array([0, 0, 0, 1]);\n}\n\nfunction _parseHex(s: string): Float32Array {\n const len = s.length;\n\n if (len === 4) {\n // #rgb → expand to #rrggbb\n const r = parseInt(s[1], 16);\n const g = parseInt(s[2], 16);\n const b = parseInt(s[3], 16);\n return new Float32Array([\n (r * 17) / 255,\n (g * 17) / 255,\n (b * 17) / 255,\n 1,\n ]);\n }\n\n if (len === 7) {\n // #rrggbb\n const r = parseInt(s.slice(1, 3), 16);\n const g = parseInt(s.slice(3, 5), 16);\n const b = parseInt(s.slice(5, 7), 16);\n return new Float32Array([r / 255, g / 255, b / 255, 1]);\n }\n\n if (len === 9) {\n // #rrggbbaa\n const r = parseInt(s.slice(1, 3), 16);\n const g = parseInt(s.slice(3, 5), 16);\n const b = parseInt(s.slice(5, 7), 16);\n const a = parseInt(s.slice(7, 9), 16);\n return new Float32Array([r / 255, g / 255, b / 255, a / 255]);\n }\n\n // #rgba (4-digit with alpha)\n if (len === 5) {\n const r = parseInt(s[1], 16);\n const g = parseInt(s[2], 16);\n const b = parseInt(s[3], 16);\n const a = parseInt(s[4], 16);\n return new Float32Array([\n (r * 17) / 255,\n (g * 17) / 255,\n (b * 17) / 255,\n (a * 17) / 255,\n ]);\n }\n\n return new Float32Array([0, 0, 0, 1]);\n}\n\nfunction _parseRgb(s: string): Float32Array {\n // Match both rgb(...) and rgba(...)\n // Extract the numeric values between parentheses\n const start = s.indexOf('(');\n const end = s.lastIndexOf(')');\n if (start === -1 || end === -1) return new Float32Array([0, 0, 0, 1]);\n\n const parts = s.slice(start + 1, end).split(',');\n const r = parseFloat(parts[0]) / 255;\n const g = parseFloat(parts[1]) / 255;\n const b = parseFloat(parts[2]) / 255;\n const a = parts.length >= 4 ? parseFloat(parts[3]) : 1;\n\n return new Float32Array([r, g, b, a]);\n}\n","/**\n * GLSL Shader Sources for canvas-ultrafast\n *\n * Content shaders (flat-color, textured) plus a passthrough display shader.\n * CRT post-processing shaders live in the maalata package.\n *\n * Coordinate convention:\n * - Content shaders use a 3x3 affine matrix (u_matrix) that maps\n * canvas pixel coordinates (top-left origin, Y-down) to clip space.\n * - Passthrough shader uses a fullscreen quad in [0,1] mapped to [-1,1] clip space.\n */\n\n// ---------------------------------------------------------------------------\n// Flat-color shader: rectangles, line quads, clear regions\n// ---------------------------------------------------------------------------\n\nexport const FLAT_VERTEX_SRC = `\n attribute vec2 a_position;\n uniform mat3 u_matrix;\n void main() {\n vec3 pos = u_matrix * vec3(a_position, 1.0);\n gl_Position = vec4(pos.xy, 0.0, 1.0);\n }\n`;\n\nexport const FLAT_FRAGMENT_SRC = `\n precision mediump float;\n uniform vec4 u_color;\n void main() {\n gl_FragColor = u_color;\n }\n`;\n\n// ---------------------------------------------------------------------------\n// Textured quad shader: text rendering via OffscreenCanvas glyph upload\n// ---------------------------------------------------------------------------\n\nexport const TEXTURED_VERTEX_SRC = `\n attribute vec2 a_position;\n attribute vec2 a_texCoord;\n uniform mat3 u_matrix;\n varying vec2 v_texCoord;\n void main() {\n vec3 pos = u_matrix * vec3(a_position, 1.0);\n gl_Position = vec4(pos.xy, 0.0, 1.0);\n v_texCoord = a_texCoord;\n }\n`;\n\nexport const TEXTURED_FRAGMENT_SRC = `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D u_texture;\n uniform vec4 u_color;\n void main() {\n vec4 texel = texture2D(u_texture, v_texCoord);\n gl_FragColor = texel * u_color;\n }\n`;\n\n// ---------------------------------------------------------------------------\n// Passthrough display shader: fullscreen quad, reads FBO texture\n// ---------------------------------------------------------------------------\n\n/**\n * Vertex shader: fullscreen quad [0,1] → clip space [-1,1].\n * FBO textures are already in GL-native bottom-left origin (the orthographic\n * projection in matrix-stack.ts handles the canvas Y-down → GL Y-up flip),\n * so tex coords pass through without Y-flip.\n */\nexport const PASSTHROUGH_VERTEX_SRC = `\n attribute vec2 a_position;\n varying vec2 v_texCoord;\n void main() {\n v_texCoord = a_position;\n gl_Position = vec4(a_position * 2.0 - 1.0, 0, 1);\n }\n`;\n\n/**\n * Passthrough fragment shader: blit FBO texture to screen without effects.\n */\nexport const PASSTHROUGH_FRAGMENT_SRC = `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D u_texture;\n void main() {\n gl_FragColor = texture2D(u_texture, v_texCoord);\n }\n`;\n","/**\n * Canvas 2D → WebGL Command Shim\n *\n * Translates CanvasCommand[] (recorded by CanvasAPI) into WebGL draw calls.\n * Handles the subset of Canvas 2D API used by the demo, plus reasonable\n * extensions. Operations not yet implemented log a warning and no-op.\n *\n * Rendering approach per command type:\n * - clearRect: gl.scissor + gl.clear\n * - fillRect: unit quad VBO + flat shader + transform uniform\n * - strokeRect: four thin quads (one per edge)\n * - fillText: render to OffscreenCanvas 2D → texImage2D → textured quad\n * - stroke(): expand line segments to quads on CPU, flat shader\n * - save/restore: matrix + state stack\n *\n * Text rendering uses an OffscreenCanvas with a 2D context as a glyph\n * rendering surface. At 8 FPS with ~5 text draws per frame, per-string\n * rendering (not glyph caching) is appropriate — texImage2D(OffscreenCanvas)\n * is a fast GPU upload path.\n */\n\nimport { CanvasCommand } from './canvas-api';\nimport { MatrixStack } from './matrix-stack';\nimport { parseColor } from './color-parser';\nimport {\n FLAT_VERTEX_SRC, FLAT_FRAGMENT_SRC,\n TEXTURED_VERTEX_SRC, TEXTURED_FRAGMENT_SRC,\n} from './shaders';\n\ninterface _DrawState {\n _fillColor: Float32Array;\n _strokeColor: Float32Array;\n _lineWidth: number;\n _globalAlpha: number;\n _font: string;\n _textAlign: CanvasTextAlign;\n _textBaseline: CanvasTextBaseline;\n _lineCap: CanvasLineCap;\n _lineJoin: CanvasLineJoin;\n _imageSmoothingEnabled: boolean;\n _letterSpacing: string;\n _clipActive: boolean;\n _clipRect: [number, number, number, number] | null;\n}\n\ninterface _ProgramInfo {\n _program: WebGLProgram;\n _matrixLoc: WebGLUniformLocation | null;\n _colorLoc: WebGLUniformLocation | null;\n _textureLoc: WebGLUniformLocation | null;\n _positionLoc: number;\n _texCoordLoc: number;\n}\n\nexport class Canvas2DShim {\n private _gl: WebGLRenderingContext;\n private _width: number;\n private _height: number;\n\n // Transform\n private _matrix: MatrixStack;\n\n // State\n private _fillColor: Float32Array = new Float32Array([0, 0, 0, 1]);\n private _strokeColor: Float32Array = new Float32Array([0, 0, 0, 1]);\n private _lineWidth = 1;\n private _globalAlpha = 1;\n private _font = '10px sans-serif';\n private _textAlign: CanvasTextAlign = 'start';\n private _textBaseline: CanvasTextBaseline = 'alphabetic';\n private _lineCap: CanvasLineCap = 'butt';\n private _lineJoin: CanvasLineJoin = 'miter';\n private _imageSmoothingEnabled = true;\n private _letterSpacing = '';\n private _clipActive = false;\n private _clipRect: [number, number, number, number] | null = null;\n private _pendingClipRect: [number, number, number, number] | null = null;\n private _imageTexCache = new WeakMap<object, { _tex: WebGLTexture; _isImage: boolean }>();\n private _stateStack: _DrawState[] = [];\n\n // Path state\n private _pathSegments: number[] = []; // flat: x0,y0,x1,y1,...\n private _currentX = 0;\n private _currentY = 0;\n private _subpathStartX = 0;\n private _subpathStartY = 0;\n\n // WebGL resources\n private _flat: _ProgramInfo;\n private _textured: _ProgramInfo;\n private _unitQuadVBO: WebGLBuffer;\n private _dynamicVBO: WebGLBuffer;\n private _texturedVBO: WebGLBuffer;\n private _textTexture: WebGLTexture;\n\n // Text rendering surface\n private _textCanvas: OffscreenCanvas;\n private _textCtx: OffscreenCanvasRenderingContext2D;\n\n // Background color for opaque canvas clear\n private _bgColor = new Float32Array([0, 0, 0]);\n\n // Temp arrays to avoid allocation in hot path\n private _tmpColor = new Float32Array(4);\n\n constructor(gl: WebGLRenderingContext, width: number, height: number) {\n this._gl = gl;\n this._width = width;\n this._height = height;\n this._matrix = new MatrixStack(width, height);\n\n // Compile shader programs\n this._flat = this._createProgram(\n FLAT_VERTEX_SRC, FLAT_FRAGMENT_SRC, false\n );\n this._textured = this._createProgram(\n TEXTURED_VERTEX_SRC, TEXTURED_FRAGMENT_SRC, true\n );\n\n // Unit quad VBO: two triangles covering [0,0]-[1,1]\n // Used for fillRect (scaled via matrix) and fullscreen blits\n this._unitQuadVBO = gl.createBuffer()!;\n gl.bindBuffer(gl.ARRAY_BUFFER, this._unitQuadVBO);\n gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([\n 0, 0, 1, 0, 0, 1,\n 0, 1, 1, 0, 1, 1,\n ]), gl.STATIC_DRAW);\n\n // Dynamic VBO for line quads — uses orphaning for double-buffer\n this._dynamicVBO = gl.createBuffer()!;\n\n // Textured quad VBO: position + texcoord interleaved\n this._texturedVBO = gl.createBuffer()!;\n\n // Text rendering texture\n this._textTexture = gl.createTexture()!;\n gl.bindTexture(gl.TEXTURE_2D, this._textTexture);\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\n // OffscreenCanvas for text glyph rendering\n this._textCanvas = new OffscreenCanvas(512, 128);\n this._textCtx = this._textCanvas.getContext('2d')!;\n\n // Enable blending for standard source-over compositing\n gl.enable(gl.BLEND);\n gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\n }\n\n /**\n * Execute a batch of Canvas 2D commands as WebGL draw calls.\n * No _ prefix: called cross-file from webgl-renderer.\n */\n executeBatch(commands: CanvasCommand[]): void {\n for (const cmd of commands) {\n if (cmd.type === 'property') {\n this._setProperty(cmd.name, cmd.value);\n } else {\n this._callMethod(cmd.name, cmd.args);\n }\n }\n }\n\n /**\n * Set the opaque clear color for clearRect.\n * No _ prefix: called cross-file from renderer.\n */\n setBackgroundColor(r: number, g: number, b: number): void {\n this._bgColor[0] = r;\n this._bgColor[1] = g;\n this._bgColor[2] = b;\n }\n\n /**\n * Update canvas dimensions on resize.\n * No _ prefix: called cross-file.\n */\n resize(width: number, height: number): void {\n this._width = width;\n this._height = height;\n this._matrix.resize(width, height);\n }\n\n /**\n * Clean up WebGL resources.\n * No _ prefix: called cross-file.\n */\n destroy(): void {\n const gl = this._gl;\n gl.deleteBuffer(this._unitQuadVBO);\n gl.deleteBuffer(this._dynamicVBO);\n gl.deleteBuffer(this._texturedVBO);\n gl.deleteTexture(this._textTexture);\n gl.deleteProgram(this._flat._program);\n gl.deleteProgram(this._textured._program);\n }\n\n // -------------------------------------------------------------------------\n // Private: property handling\n // -------------------------------------------------------------------------\n\n private _setProperty(name: string, value: unknown): void {\n switch (name) {\n case 'fillStyle':\n this._fillColor = parseColor(value as string);\n break;\n case 'strokeStyle':\n this._strokeColor = parseColor(value as string);\n break;\n case 'lineWidth':\n this._lineWidth = value as number;\n break;\n case 'globalAlpha':\n this._globalAlpha = value as number;\n break;\n case 'font':\n this._font = value as string;\n break;\n case 'textAlign':\n this._textAlign = value as CanvasTextAlign;\n break;\n case 'textBaseline':\n this._textBaseline = value as CanvasTextBaseline;\n break;\n case 'lineCap':\n this._lineCap = value as CanvasLineCap;\n break;\n case 'lineJoin':\n this._lineJoin = value as CanvasLineJoin;\n break;\n case 'imageSmoothingEnabled':\n this._imageSmoothingEnabled = value as boolean;\n break;\n case 'letterSpacing':\n this._letterSpacing = value as string;\n break;\n default:\n // Unsupported properties: silently ignore\n break;\n }\n }\n\n // -------------------------------------------------------------------------\n // Private: method dispatch\n // -------------------------------------------------------------------------\n\n private _callMethod(name: string, args: unknown[]): void {\n switch (name) {\n // Rectangles\n case 'clearRect':\n this._clearRect(args[0] as number, args[1] as number, args[2] as number, args[3] as number);\n break;\n case 'fillRect':\n this._fillRect(args[0] as number, args[1] as number, args[2] as number, args[3] as number);\n break;\n case 'strokeRect':\n this._strokeRect(args[0] as number, args[1] as number, args[2] as number, args[3] as number);\n break;\n\n // Text\n case 'fillText':\n this._fillText(args[0] as string, args[1] as number, args[2] as number);\n break;\n case 'strokeText':\n this._strokeText(args[0] as string, args[1] as number, args[2] as number);\n break;\n\n // Images\n case 'drawImage':\n this._drawImage(args);\n break;\n\n // Path\n case 'beginPath':\n this._pathSegments = [];\n this._pendingClipRect = null;\n break;\n case 'closePath':\n if (this._currentX !== this._subpathStartX || this._currentY !== this._subpathStartY) {\n this._pathSegments.push(\n this._currentX, this._currentY,\n this._subpathStartX, this._subpathStartY\n );\n this._currentX = this._subpathStartX;\n this._currentY = this._subpathStartY;\n }\n break;\n case 'moveTo':\n this._currentX = this._subpathStartX = args[0] as number;\n this._currentY = this._subpathStartY = args[1] as number;\n break;\n case 'lineTo': {\n const x = args[0] as number;\n const y = args[1] as number;\n this._pathSegments.push(this._currentX, this._currentY, x, y);\n this._currentX = x;\n this._currentY = y;\n break;\n }\n case 'rect': {\n const rx = args[0] as number, ry = args[1] as number;\n const rw = args[2] as number, rh = args[3] as number;\n // Store as pending clip rect (used if clip() follows)\n this._pendingClipRect = [rx, ry, rw, rh];\n // Also add 4 line segments to path for potential stroke()\n this._pathSegments.push(\n rx, ry, rx + rw, ry, // top\n rx + rw, ry, rx + rw, ry + rh, // right\n rx + rw, ry + rh, rx, ry + rh, // bottom\n rx, ry + rh, rx, ry, // left\n );\n break;\n }\n case 'clip':\n this._applyClip();\n break;\n case 'stroke':\n this._strokePath();\n break;\n case 'fill':\n // Convex fill only — not heavily used in demo beyond fillRect\n break;\n\n // State\n case 'save':\n this._save();\n break;\n case 'restore':\n this._restore();\n break;\n\n // Transforms\n case 'translate':\n this._matrix.translate(args[0] as number, args[1] as number);\n break;\n case 'rotate':\n this._matrix.rotate(args[0] as number);\n break;\n case 'scale':\n this._matrix.scale(args[0] as number, args[1] as number);\n break;\n case 'transform':\n this._matrix.transform(\n args[0] as number, args[1] as number, args[2] as number,\n args[3] as number, args[4] as number, args[5] as number\n );\n break;\n case 'setTransform':\n this._matrix.setTransform(\n args[0] as number, args[1] as number, args[2] as number,\n args[3] as number, args[4] as number, args[5] as number\n );\n break;\n case 'resetTransform':\n this._matrix.resetTransform();\n break;\n\n default:\n // Unsupported methods: silently ignore (arc, bezierCurveTo, etc.)\n break;\n }\n }\n\n // -------------------------------------------------------------------------\n // Private: drawing operations\n // -------------------------------------------------------------------------\n\n private _clearRect(x: number, y: number, w: number, h: number): void {\n const gl = this._gl;\n const bg = this._bgColor;\n // WebGL scissor uses bottom-left origin, canvas uses top-left\n gl.enable(gl.SCISSOR_TEST);\n gl.scissor(x, this._height - y - h, w, h);\n gl.clearColor(bg[0], bg[1], bg[2], 1);\n gl.clear(gl.COLOR_BUFFER_BIT);\n gl.disable(gl.SCISSOR_TEST);\n }\n\n private _fillRect(x: number, y: number, w: number, h: number): void {\n const gl = this._gl;\n const prog = this._flat;\n\n gl.useProgram(prog._program);\n\n // Build transform: current matrix × translate(x,y) × scale(w,h)\n // Applied to unit quad [0,1]×[0,1] → fills [x,y,x+w,y+h]\n this._matrix.save();\n this._matrix.translate(x, y);\n this._matrix.scale(w, h);\n\n gl.uniformMatrix3fv(prog._matrixLoc, false, this._matrix.getMatrix());\n this._setColorUniform(prog._colorLoc!, this._fillColor, this._globalAlpha);\n\n this._matrix.restore();\n\n // Draw unit quad\n gl.bindBuffer(gl.ARRAY_BUFFER, this._unitQuadVBO);\n gl.enableVertexAttribArray(prog._positionLoc);\n gl.vertexAttribPointer(prog._positionLoc, 2, gl.FLOAT, false, 0, 0);\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n }\n\n private _strokeRect(x: number, y: number, w: number, h: number): void {\n // Draw four edges as thin quads\n const lw = this._lineWidth;\n const hlw = lw / 2;\n\n // Top edge\n this._fillRectWithColor(x - hlw, y - hlw, w + lw, lw, this._strokeColor);\n // Bottom edge\n this._fillRectWithColor(x - hlw, y + h - hlw, w + lw, lw, this._strokeColor);\n // Left edge\n this._fillRectWithColor(x - hlw, y + hlw, lw, h - lw, this._strokeColor);\n // Right edge\n this._fillRectWithColor(x + w - hlw, y + hlw, lw, h - lw, this._strokeColor);\n }\n\n /** Internal: draw a filled rect with a specific color (used by strokeRect). */\n private _fillRectWithColor(x: number, y: number, w: number, h: number, color: Float32Array): void {\n const gl = this._gl;\n const prog = this._flat;\n\n gl.useProgram(prog._program);\n\n this._matrix.save();\n this._matrix.translate(x, y);\n this._matrix.scale(w, h);\n\n gl.uniformMatrix3fv(prog._matrixLoc, false, this._matrix.getMatrix());\n this._setColorUniform(prog._colorLoc!, color, this._globalAlpha);\n\n this._matrix.restore();\n\n gl.bindBuffer(gl.ARRAY_BUFFER, this._unitQuadVBO);\n gl.enableVertexAttribArray(prog._positionLoc);\n gl.vertexAttribPointer(prog._positionLoc, 2, gl.FLOAT, false, 0, 0);\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n }\n\n private _strokePath(): void {\n const segs = this._pathSegments;\n if (segs.length === 0) return;\n\n const gl = this._gl;\n const prog = this._flat;\n const halfW = Math.max(this._lineWidth / 2, 0.5);\n\n // Expand line segments to quads on CPU\n // Each segment (x0,y0,x1,y1) → 6 vertices (2 triangles)\n const segCount = segs.length / 4;\n const vertices = new Float32Array(segCount * 12); // 6 vertices × 2 coords\n\n for (let i = 0, vi = 0; i < segs.length; i += 4) {\n const x0 = segs[i], y0 = segs[i + 1], x1 = segs[i + 2], y1 = segs[i + 3];\n const dx = x1 - x0;\n const dy = y1 - y0;\n const len = Math.sqrt(dx * dx + dy * dy);\n\n if (len < 0.001) continue; // Skip degenerate segments\n\n // Normal perpendicular to line direction\n const nx = (-dy / len) * halfW;\n const ny = (dx / len) * halfW;\n\n // Four corners of the quad\n const ax = x0 + nx, ay = y0 + ny; // top-left\n const bx = x0 - nx, by = y0 - ny; // bottom-left\n const cx = x1 + nx, cy = y1 + ny; // top-right\n const dx2 = x1 - nx, dy2 = y1 - ny; // bottom-right\n\n // Triangle 1: A, B, C\n vertices[vi++] = ax; vertices[vi++] = ay;\n vertices[vi++] = bx; vertices[vi++] = by;\n vertices[vi++] = cx; vertices[vi++] = cy;\n // Triangle 2: B, D, C\n vertices[vi++] = bx; vertices[vi++] = by;\n vertices[vi++] = dx2; vertices[vi++] = dy2;\n vertices[vi++] = cx; vertices[vi++] = cy;\n }\n\n // Upload to dynamic VBO using orphaning (bufferData null pattern)\n gl.bindBuffer(gl.ARRAY_BUFFER, this._dynamicVBO);\n gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.DYNAMIC_DRAW);\n\n gl.useProgram(prog._program);\n gl.uniformMatrix3fv(prog._matrixLoc, false, this._matrix.getMatrix());\n this._setColorUniform(prog._colorLoc!, this._strokeColor, this._globalAlpha);\n\n gl.enableVertexAttribArray(prog._positionLoc);\n gl.vertexAttribPointer(prog._positionLoc, 2, gl.FLOAT, false, 0, 0);\n gl.drawArrays(gl.TRIANGLES, 0, segCount * 6);\n }\n\n private _drawImage(args: unknown[]): void {\n const gl = this._gl;\n const image = args[0] as CanvasImageSource;\n\n let sx: number, sy: number, sw: number, sh: number;\n let dx: number, dy: number, dw: number, dh: number;\n\n // Get image dimensions\n const imgW = _getImageWidth(image);\n const imgH = _getImageHeight(image);\n\n if (args.length === 3) {\n // drawImage(image, dx, dy)\n sx = 0; sy = 0; sw = imgW; sh = imgH;\n dx = args[1] as number; dy = args[2] as number;\n dw = imgW; dh = imgH;\n } else if (args.length === 5) {\n // drawImage(image, dx, dy, dw, dh)\n sx = 0; sy = 0; sw = imgW; sh = imgH;\n dx = args[1] as number; dy = args[2] as number;\n dw = args[3] as number; dh = args[4] as number;\n } else {\n // drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)\n sx = args[1] as number; sy = args[2] as number;\n sw = args[3] as number; sh = args[4] as number;\n dx = args[5] as number; dy = args[6] as number;\n dw = args[7] as number; dh = args[8] as number;\n }\n\n // Get or create texture for this image source\n const tex = this._getOrUploadTexture(image, imgW, imgH);\n\n // Set filtering based on imageSmoothingEnabled\n const filter = this._imageSmoothingEnabled ? gl.LINEAR : gl.NEAREST;\n gl.bindTexture(gl.TEXTURE_2D, tex);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filter);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filter);\n\n // Compute UV coordinates for source sub-rect\n const uMin = sx / imgW;\n const vMin = sy / imgH;\n const uMax = (sx + sw) / imgW;\n const vMax = (sy + sh) / imgH;\n\n // Draw textured quad with interleaved position + texcoord\n const prog = this._textured;\n const verts = new Float32Array([\n dx, dy, uMin, vMin,\n dx + dw, dy, uMax, vMin,\n dx, dy + dh, uMin, vMax,\n dx, dy + dh, uMin, vMax,\n dx + dw, dy, uMax, vMin,\n dx + dw, dy + dh, uMax, vMax,\n ]);\n\n gl.bindBuffer(gl.ARRAY_BUFFER, this._texturedVBO);\n gl.bufferData(gl.ARRAY_BUFFER, verts, gl.DYNAMIC_DRAW);\n\n gl.useProgram(prog._program);\n gl.uniformMatrix3fv(prog._matrixLoc, false, this._matrix.getMatrix());\n // White color tint with globalAlpha — no color modification, just alpha\n gl.uniform4f(prog._colorLoc!, 1, 1, 1, this._globalAlpha);\n\n // Standard alpha blending (not premultiplied for image textures)\n const stride = 16; // 4 floats × 4 bytes\n gl.enableVertexAttribArray(prog._positionLoc);\n gl.vertexAttribPointer(prog._positionLoc, 2, gl.FLOAT, false, stride, 0);\n gl.enableVertexAttribArray(prog._texCoordLoc);\n gl.vertexAttribPointer(prog._texCoordLoc, 2, gl.FLOAT, false, stride, 8);\n\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, tex);\n gl.uniform1i(prog._textureLoc, 0);\n\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n\n // Disable texcoord attrib to avoid interfering with flat shader\n gl.disableVertexAttribArray(prog._texCoordLoc);\n }\n\n private _getOrUploadTexture(image: CanvasImageSource, imgW: number, imgH: number): WebGLTexture {\n const gl = this._gl;\n const key = image as unknown as object;\n const cached = this._imageTexCache.get(key);\n\n // HTMLImageElement/SVGImageElement: upload once, cache permanently\n // HTMLCanvasElement/OffscreenCanvas: always re-upload (content may change)\n const isImage = (image instanceof HTMLImageElement) || (image instanceof SVGImageElement);\n\n if (cached) {\n if (cached._isImage) {\n // Static image — reuse cached texture\n return cached._tex;\n }\n // Canvas source — re-upload to existing texture\n gl.bindTexture(gl.TEXTURE_2D, cached._tex);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image as TexImageSource);\n return cached._tex;\n }\n\n // Create new texture\n const tex = gl.createTexture()!;\n gl.bindTexture(gl.TEXTURE_2D, tex);\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\n // Detect if we need to handle alpha properly\n // For canvas sources, use standard upload; for images, avoid premultiply\n if (imgW > 0 && imgH > 0) {\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image as TexImageSource);\n }\n\n this._imageTexCache.set(key, { _tex: tex, _isImage: isImage });\n return tex;\n }\n\n private _applyClip(): void {\n const gl = this._gl;\n if (this._pendingClipRect) {\n const [x, y, w, h] = this._pendingClipRect;\n gl.enable(gl.SCISSOR_TEST);\n // Convert canvas coords (top-left origin) to GL coords (bottom-left origin)\n gl.scissor(x, this._height - y - h, w, h);\n this._clipActive = true;\n this._clipRect = [x, y, w, h];\n }\n }\n\n private _fillText(text: string, x: number, y: number): void {\n this._renderText(text, x, y, 'fill');\n }\n\n private _strokeText(text: string, x: number, y: number): void {\n this._renderText(text, x, y, 'stroke');\n }\n\n private _renderText(text: string, x: number, y: number, mode: 'fill' | 'stroke'): void {\n const gl = this._gl;\n const tCtx = this._textCtx;\n\n // Configure text rendering context\n tCtx.font = this._font;\n tCtx.textAlign = 'left'; // Always render left-aligned, position via WebGL\n tCtx.textBaseline = 'top'; // Always render from top, adjust Y via offset\n if (this._letterSpacing) {\n tCtx.letterSpacing = this._letterSpacing;\n }\n\n // Measure text\n const metrics = tCtx.measureText(text);\n const textWidth = Math.ceil(metrics.width) + 4; // +4 for antialiasing padding\n const fontSize = _parseFontSize(this._font);\n const textHeight = Math.ceil(fontSize * 1.5) + 4; // approximate height with descenders\n\n if (textWidth <= 0 || textHeight <= 0) return;\n\n // Resize text canvas if needed\n if (this._textCanvas.width < textWidth || this._textCanvas.height < textHeight) {\n this._textCanvas.width = Math.max(this._textCanvas.width, textWidth);\n this._textCanvas.height = Math.max(this._textCanvas.height, textHeight);\n // Re-set font after resize (context is reset)\n tCtx.font = this._font;\n tCtx.textAlign = 'left';\n tCtx.textBaseline = 'top';\n }\n\n // Clear and render text\n tCtx.clearRect(0, 0, this._textCanvas.width, this._textCanvas.height);\n\n if (mode === 'fill') {\n tCtx.fillStyle = 'white'; // White text, tinted by WebGL uniform\n tCtx.fillText(text, 2, 2); // +2 padding offset\n } else {\n tCtx.strokeStyle = 'white';\n tCtx.lineWidth = this._lineWidth;\n tCtx.strokeText(text, 2, 2);\n }\n\n // Upload text canvas to texture\n gl.bindTexture(gl.TEXTURE_2D, this._textTexture);\n gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 1);\n gl.texImage2D(\n gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE,\n this._textCanvas\n );\n gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 0);\n\n // Compute text position adjustments\n const color = mode === 'fill' ? this._fillColor : this._strokeColor;\n let drawX = x - 2; // compensate for padding\n let drawY = y - 2;\n\n // Adjust for textAlign\n switch (this._textAlign) {\n case 'center': drawX -= textWidth / 2; break;\n case 'right':\n case 'end': drawX -= textWidth; break;\n }\n\n // Adjust for textBaseline\n switch (this._textBaseline) {\n case 'top': /* drawY stays */ break;\n case 'middle': drawY -= textHeight / 2; break;\n case 'alphabetic':\n case 'ideographic': drawY -= fontSize; break;\n case 'bottom':\n case 'hanging': drawY -= textHeight; break;\n }\n\n // Draw textured quad\n this._drawTexturedQuad(\n drawX, drawY, textWidth, textHeight,\n textWidth / this._textCanvas.width,\n textHeight / this._textCanvas.height,\n color\n );\n }\n\n private _drawTexturedQuad(\n x: number, y: number, w: number, h: number,\n uMax: number, vMax: number,\n color: Float32Array\n ): void {\n const gl = this._gl;\n const prog = this._textured;\n\n // Interleaved position + texcoord (x, y, u, v)\n const verts = new Float32Array([\n x, y, 0, 0,\n x + w, y, uMax, 0,\n x, y + h, 0, vMax,\n x, y + h, 0, vMax,\n x + w, y, uMax, 0,\n x + w, y + h, uMax, vMax,\n ]);\n\n gl.bindBuffer(gl.ARRAY_BUFFER, this._texturedVBO);\n gl.bufferData(gl.ARRAY_BUFFER, verts, gl.DYNAMIC_DRAW);\n\n gl.useProgram(prog._program);\n gl.uniformMatrix3fv(prog._matrixLoc, false, this._matrix.getMatrix());\n this._setColorUniform(prog._colorLoc!, color, this._globalAlpha);\n\n // Use premultiplied alpha blending for text\n gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n\n const stride = 16; // 4 floats × 4 bytes\n gl.enableVertexAttribArray(prog._positionLoc);\n gl.vertexAttribPointer(prog._positionLoc, 2, gl.FLOAT, false, stride, 0);\n gl.enableVertexAttribArray(prog._texCoordLoc);\n gl.vertexAttribPointer(prog._texCoordLoc, 2, gl.FLOAT, false, stride, 8);\n\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, this._textTexture);\n gl.uniform1i(prog._textureLoc, 0);\n\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n\n // Restore standard blending\n gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\n\n // Disable texcoord attrib to avoid interfering with flat shader\n gl.disableVertexAttribArray(prog._texCoordLoc);\n }\n\n // -------------------------------------------------------------------------\n // Private: state management\n // -------------------------------------------------------------------------\n\n private _save(): void {\n this._matrix.save();\n this._stateStack.push({\n _fillColor: new Float32Array(this._fillColor),\n _strokeColor: new Float32Array(this._strokeColor),\n _lineWidth: this._lineWidth,\n _globalAlpha: this._globalAlpha,\n _font: this._font,\n _textAlign: this._textAlign,\n _textBaseline: this._textBaseline,\n _lineCap: this._lineCap,\n _lineJoin: this._lineJoin,\n _imageSmoothingEnabled: this._imageSmoothingEnabled,\n _letterSpacing: this._letterSpacing,\n _clipActive: this._clipActive,\n _clipRect: this._clipRect ? [...this._clipRect] as [number, number, number, number] : null,\n });\n }\n\n private _restore(): void {\n this._matrix.restore();\n const gl = this._gl;\n const state = this._stateStack.pop();\n if (state) {\n this._fillColor = state._fillColor;\n this._strokeColor = state._strokeColor;\n this._lineWidth = state._lineWidth;\n this._globalAlpha = state._globalAlpha;\n this._font = state._font;\n this._textAlign = state._textAlign;\n this._textBaseline = state._textBaseline;\n this._lineCap = state._lineCap;\n this._lineJoin = state._lineJoin;\n this._imageSmoothingEnabled = state._imageSmoothingEnabled;\n this._letterSpacing = state._letterSpacing;\n this._clipActive = state._clipActive;\n this._clipRect = state._clipRect;\n\n // Restore scissor state\n if (this._clipActive && this._clipRect) {\n const [x, y, w, h] = this._clipRect;\n gl.enable(gl.SCISSOR_TEST);\n gl.scissor(x, this._height - y - h, w, h);\n } else {\n gl.disable(gl.SCISSOR_TEST);\n }\n }\n }\n\n // -------------------------------------------------------------------------\n // Private: WebGL helpers\n // -------------------------------------------------------------------------\n\n private _setColorUniform(loc: WebGLUniformLocation, color: Float32Array, alpha: number): void {\n // Premultiply globalAlpha into the color's alpha channel\n const a = color[3] * alpha;\n this._gl.uniform4f(loc, color[0], color[1], color[2], a);\n }\n\n private _createProgram(vSrc: string, fSrc: string, hasTexCoord: boolean): _ProgramInfo {\n const gl = this._gl;\n const vs = this._compileShader(gl.VERTEX_SHADER, vSrc);\n const fs = this._compileShader(gl.FRAGMENT_SHADER, fSrc);\n\n const program = gl.createProgram()!;\n gl.attachShader(program, vs);\n gl.attachShader(program, fs);\n gl.linkProgram(program);\n\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n throw new Error('Shader link failed: ' + gl.getProgramInfoLog(program));\n }\n\n // Delete shaders after linking (they're embedded in the program now)\n gl.deleteShader(vs);\n gl.deleteShader(fs);\n\n return {\n _program: program,\n _matrixLoc: gl.getUniformLocation(program, 'u_matrix'),\n _colorLoc: gl.getUniformLocation(program, 'u_color'),\n _textureLoc: hasTexCoord ? gl.getUniformLocation(program, 'u_texture') : null,\n _positionLoc: gl.getAttribLocation(program, 'a_position'),\n _texCoordLoc: hasTexCoord ? gl.getAttribLocation(program, 'a_texCoord') : -1,\n };\n }\n\n private _compileShader(type: number, source: string): WebGLShader {\n const gl = this._gl;\n const shader = gl.createShader(type)!;\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n const info = gl.getShaderInfoLog(shader);\n gl.deleteShader(shader);\n throw new Error('Shader compile failed: ' + info);\n }\n return shader;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Utility\n// ---------------------------------------------------------------------------\n\n/** Extract numeric font size from a CSS font string like \"bold 20px monospace\". */\nfunction _parseFontSize(font: string): number {\n const match = font.match(/(\\d+(?:\\.\\d+)?)\\s*px/);\n return match ? parseFloat(match[1]) : 10;\n}\n\n/** Get width of a CanvasImageSource (handles HTMLImageElement, HTMLCanvasElement, OffscreenCanvas, etc.) */\nfunction _getImageWidth(img: CanvasImageSource): number {\n if ('naturalWidth' in img) return (img as HTMLImageElement).naturalWidth;\n return (img as HTMLCanvasElement | OffscreenCanvas).width;\n}\n\n/** Get height of a CanvasImageSource. */\nfunction _getImageHeight(img: CanvasImageSource): number {\n if ('naturalHeight' in img) return (img as HTMLImageElement).naturalHeight;\n return (img as HTMLCanvasElement | OffscreenCanvas).height;\n}\n","/**\n * UltrafastRenderer — WebGL2 Triple-Buffered Canvas 2D Renderer\n *\n * A standalone WebGL-accelerated Canvas 2D rendering engine. Provides a\n * CanvasAPI for recording draw commands and a triple-buffered FBO pipeline\n * that displays them via a passthrough shader at vsync rate.\n *\n * Triple buffer scheme (all on main thread, lock-free via JS single-threading):\n *\n * Content submission:\n * submitBatch(commands)\n * → bind writeFBO\n * → Canvas2DShim executes commands as WebGL draw calls\n * → swap: writeFBO ↔ readyFBO\n *\n * Display loop (vsync rate via RAF):\n * RAF callback\n * → auto-flush: drain CanvasAPI commands → submitBatch\n * → bind default framebuffer (display canvas)\n * → read readyFBO texture → passthrough blit → screen\n *\n * Extension points for downstream consumers (e.g. maalata CRT display):\n * - getGL(): access the WebGL2 context\n * - getReadyTexture(): read the latest rendered frame as a texture\n * - stopDisplay() / startDisplay(): take over the display loop\n */\n\nimport { CanvasAPI, type CanvasCommand } from './canvas-api';\nimport { Canvas2DShim } from './canvas2d-shim';\nimport {\n PASSTHROUGH_VERTEX_SRC,\n PASSTHROUGH_FRAGMENT_SRC,\n} from './shaders';\n\ninterface _FBO {\n _fbo: WebGLFramebuffer;\n _texture: WebGLTexture;\n}\n\nexport class UltrafastRenderer {\n private _gl: WebGL2RenderingContext;\n private _canvas: HTMLCanvasElement;\n private _shim: Canvas2DShim;\n private _api: CanvasAPI;\n private _rafId: number | null = null;\n\n // Triple buffer: three FBOs with color texture attachments\n private _fbos!: [_FBO, _FBO, _FBO];\n private _writeIdx = 0;\n private _readyIdx = 1;\n private _displayIdx = 2;\n private _hasContent = false;\n\n // Background color for opaque canvas clear (default: black, backwards compatible)\n private _bgColor = new Float32Array([0, 0, 0]);\n\n // Display program\n private _passthroughProgram: WebGLProgram;\n\n // Fullscreen quad VBO\n private _quadVBO!: WebGLBuffer;\n private _quadPositionLoc = -1;\n\n constructor(canvas: HTMLCanvasElement) {\n this._canvas = canvas;\n this._api = new CanvasAPI();\n\n // Create WebGL2 context with optimizations\n const gl = canvas.getContext('webgl2', {\n alpha: false,\n antialias: false,\n desynchronized: true,\n preserveDrawingBuffer: true,\n powerPreference: 'high-performance',\n });\n\n if (!gl) {\n throw new Error('WebGL2 not supported');\n }\n this._gl = gl;\n\n gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);\n\n // Initialize triple buffer FBOs\n this._initFBOs();\n\n // Initialize Canvas 2D shim (uses same GL context)\n this._shim = new Canvas2DShim(gl, canvas.width, canvas.height);\n\n // Initialize passthrough display program\n this._passthroughProgram = this._createShaderProgram(\n PASSTHROUGH_VERTEX_SRC, PASSTHROUGH_FRAGMENT_SRC\n );\n\n // Initialize fullscreen quad VBO for display pass\n this._initQuadVBO();\n\n // Clear all FBOs to black initially\n this._clearAllFBOs();\n\n // Auto-start display loop\n this.startDisplay();\n }\n\n // -------------------------------------------------------------------------\n // Public API (no _ prefix: cross-file access safe from mangleProps)\n // -------------------------------------------------------------------------\n\n /** Get the CanvasAPI for recording draw commands. */\n getCanvasAPI(): CanvasAPI {\n return this._api;\n }\n\n /**\n * Submit a batch of Canvas 2D commands to be rendered into the write FBO.\n * After rendering, the write and ready FBOs are swapped so the display\n * loop picks up the latest frame.\n */\n submitBatch(commands: CanvasCommand[]): void {\n if (commands.length === 0) return;\n const gl = this._gl;\n\n // Bind write FBO as render target\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._fbos[this._writeIdx]._fbo);\n gl.viewport(0, 0, this._canvas.width, this._canvas.height);\n\n // Execute Canvas 2D commands as WebGL draw calls\n this._shim.executeBatch(commands);\n\n // Swap write ↔ ready (new frame becomes available for display)\n const tmp = this._writeIdx;\n this._writeIdx = this._readyIdx;\n this._readyIdx = tmp;\n this._hasContent = true;\n }\n\n /** Start the passthrough RAF display loop with auto-flush. */\n startDisplay(): void {\n if (this._rafId !== null) return;\n this._displayLoop();\n }\n\n /** Stop the passthrough RAF display loop. Last frame persists (preserveDrawingBuffer). */\n stopDisplay(): void {\n if (this._rafId !== null) {\n cancelAnimationFrame(this._rafId);\n this._rafId = null;\n }\n }\n\n /** Returns the display canvas element. */\n getCanvas(): HTMLCanvasElement {\n return this._canvas;\n }\n\n /** Get canvas dimensions. */\n getCanvasSize(): { width: number; height: number } {\n return { width: this._canvas.width, height: this._canvas.height };\n }\n\n /** Capture the current displayed frame as an ImageBitmap. */\n screenshot(): Promise<ImageBitmap> {\n this._renderDisplay();\n return createImageBitmap(this._canvas);\n }\n\n /**\n * Set the opaque clear color used by clearRect and FBO initialization.\n * With alpha: false, cleared areas are opaque — this controls what color\n * they appear as instead of black. Values are in [0, 1] range.\n */\n setBackgroundColor(r: number, g: number, b: number): void {\n this._bgColor[0] = r;\n this._bgColor[1] = g;\n this._bgColor[2] = b;\n this._shim.setBackgroundColor(r, g, b);\n }\n\n /** Clean up all WebGL resources. */\n destroy(): void {\n this.stopDisplay();\n const gl = this._gl;\n\n this._shim.destroy();\n\n for (const fbo of this._fbos) {\n gl.deleteFramebuffer(fbo._fbo);\n gl.deleteTexture(fbo._texture);\n }\n\n gl.deleteProgram(this._passthroughProgram);\n gl.deleteBuffer(this._quadVBO);\n\n const ext = gl.getExtension('WEBGL_lose_context');\n if (ext) ext.loseContext();\n }\n\n // -------------------------------------------------------------------------\n // Extension points (used by maalata CRT display)\n // -------------------------------------------------------------------------\n\n /** Returns the WebGL2 context for external rendering (e.g. CRT shader). */\n getGL(): WebGL2RenderingContext {\n return this._gl;\n }\n\n /** Returns the ready FBO's texture — the latest fully rendered frame. */\n getReadyTexture(): WebGLTexture {\n return this._fbos[this._readyIdx]._texture;\n }\n\n // -------------------------------------------------------------------------\n // Private: display loop\n // -------------------------------------------------------------------------\n\n private _displayLoop(): void {\n this._rafId = requestAnimationFrame(() => this._displayLoop());\n\n // Auto-flush: drain any pending CanvasAPI commands into the pipeline\n const cmds = this._api.takeCommands();\n if (cmds.length) this.submitBatch(cmds);\n\n this._renderDisplay();\n }\n\n /**\n * Render the ready FBO to the display canvas via passthrough shader.\n * Called at vsync rate by RAF, or once synchronously for screenshots.\n */\n private _renderDisplay(): void {\n if (!this._hasContent) return;\n\n const gl = this._gl;\n\n // Bind default framebuffer (display canvas backbuffer)\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n gl.viewport(0, 0, this._canvas.width, this._canvas.height);\n\n // Bind the ready FBO's texture as input\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, this._fbos[this._readyIdx]._texture);\n\n gl.useProgram(this._passthroughProgram);\n\n // Draw fullscreen quad\n gl.bindBuffer(gl.ARRAY_BUFFER, this._quadVBO);\n gl.enableVertexAttribArray(this._quadPositionLoc);\n gl.vertexAttribPointer(this._quadPositionLoc, 2, gl.FLOAT, false, 0, 0);\n\n gl.disable(gl.BLEND);\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n gl.enable(gl.BLEND);\n }\n\n // -------------------------------------------------------------------------\n // Private: initialization\n // -------------------------------------------------------------------------\n\n private _initFBOs(): void {\n this._fbos = [\n this._createFBO(),\n this._createFBO(),\n this._createFBO(),\n ];\n }\n\n private _createFBO(): _FBO {\n const gl = this._gl;\n const w = this._canvas.width;\n const h = this._canvas.height;\n\n const fbo = gl.createFramebuffer()!;\n gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);\n\n const texture = gl.createTexture()!;\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA8, w, h);\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\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);\n\n const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);\n if (status !== gl.FRAMEBUFFER_COMPLETE) {\n throw new Error('Framebuffer incomplete: 0x' + status.toString(16));\n }\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n return { _fbo: fbo, _texture: texture };\n }\n\n private _clearAllFBOs(): void {\n const gl = this._gl;\n const bg = this._bgColor;\n for (const fbo of this._fbos) {\n gl.bindFramebuffer(gl.FRAMEBUFFER, fbo._fbo);\n gl.clearColor(bg[0], bg[1], bg[2], 1);\n gl.clear(gl.COLOR_BUFFER_BIT);\n }\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n gl.clearColor(bg[0], bg[1], bg[2], 1);\n gl.clear(gl.COLOR_BUFFER_BIT);\n }\n\n private _initQuadVBO(): void {\n const gl = this._gl;\n\n this._quadVBO = gl.createBuffer()!;\n gl.bindBuffer(gl.ARRAY_BUFFER, this._quadVBO);\n gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([\n 0, 0, 1, 0, 0, 1,\n 0, 1, 1, 0, 1, 1,\n ]), gl.STATIC_DRAW);\n\n this._quadPositionLoc = gl.getAttribLocation(this._passthroughProgram, 'a_position');\n }\n\n // -------------------------------------------------------------------------\n // Private: shader helpers\n // -------------------------------------------------------------------------\n\n private _createShaderProgram(vSrc: string, fSrc: string): WebGLProgram {\n const gl = this._gl;\n const vs = this._compileShader(gl.VERTEX_SHADER, vSrc);\n const fs = this._compileShader(gl.FRAGMENT_SHADER, fSrc);\n\n const program = gl.createProgram()!;\n gl.attachShader(program, vs);\n gl.attachShader(program, fs);\n gl.linkProgram(program);\n\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n throw new Error('Shader link failed: ' + gl.getProgramInfoLog(program));\n }\n\n gl.deleteShader(vs);\n gl.deleteShader(fs);\n\n return program;\n }\n\n private _compileShader(type: number, source: string): WebGLShader {\n const gl = this._gl;\n const shader = gl.createShader(type)!;\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n const info = gl.getShaderInfoLog(shader);\n gl.deleteShader(shader);\n throw new Error('Shader compile failed: ' + info);\n }\n return shader;\n }\n}\n"],"names":["exports"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"canvas-ultrafast.umd.js","sources":["../src/canvas-api.ts","../src/matrix-stack.ts","../src/color-parser.ts","../src/shaders.ts","../src/canvas2d-shim.ts","../src/renderer.ts"],"sourcesContent":["/**\n * Canvas API Wrapper\n *\n * Provides a Canvas 2D API that records commands locally without await.\n * Commands are batched and sent to the worker for execution.\n */\n\ntype CanvasPropertyMap = {\n fillStyle: string | CanvasGradient | CanvasPattern;\n strokeStyle: string | CanvasGradient | CanvasPattern;\n lineWidth: number;\n lineCap: CanvasLineCap;\n lineJoin: CanvasLineJoin;\n miterLimit: number;\n lineDashOffset: number;\n font: string;\n textAlign: CanvasTextAlign;\n textBaseline: CanvasTextBaseline;\n globalAlpha: number;\n globalCompositeOperation: GlobalCompositeOperation;\n shadowBlur: number;\n shadowColor: string;\n shadowOffsetX: number;\n shadowOffsetY: number;\n imageSmoothingEnabled: boolean;\n letterSpacing: string;\n};\n\nexport type CanvasCommand =\n | { type: 'property'; name: string; value: unknown }\n | { type: 'method'; name: string; args: unknown[] };\n\nexport class CanvasAPI {\n private _c: CanvasCommand[] = [];\n private _cp: Partial<CanvasPropertyMap> = {};\n\n private _m(n: string, ...a: unknown[]): void {\n this._c.push({ type: 'method', name: n, args: a });\n }\n\n private _p<K extends keyof CanvasPropertyMap>(n: K, v: CanvasPropertyMap[K]): void {\n this._cp[n] = v;\n this._c.push({ type: 'property', name: n, value: v });\n }\n\n /**\n * Drain and return all buffered commands.\n * No _ prefix: called cross-file from pipeline, must survive mangleProps.\n */\n takeCommands(): CanvasCommand[] {\n if (this._c.length === 0) return [];\n const cmds = this._c;\n this._c = [];\n return cmds;\n }\n\n // Canvas 2D API methods\n\n // State\n save(): void { this._m('save'); }\n restore(): void { this._m('restore'); }\n\n // Transform\n scale(x: number, y: number): void { this._m('scale', x, y); }\n rotate(angle: number): void { this._m('rotate', angle); }\n translate(x: number, y: number): void { this._m('translate', x, y); }\n transform(a: number, b: number, c: number, d: number, e: number, f: number): void { this._m('transform', a, b, c, d, e, f); }\n setTransform(a: number, b: number, c: number, d: number, e: number, f: number): void { this._m('setTransform', a, b, c, d, e, f); }\n resetTransform(): void { this._m('resetTransform'); }\n\n // Rectangles\n clearRect(x: number, y: number, width: number, height: number): void { this._m('clearRect', x, y, width, height); }\n fillRect(x: number, y: number, width: number, height: number): void { this._m('fillRect', x, y, width, height); }\n strokeRect(x: number, y: number, width: number, height: number): void { this._m('strokeRect', x, y, width, height); }\n\n // Text\n fillText(text: string, x: number, y: number, maxWidth?: number): void {\n this._m('fillText', ...(maxWidth !== undefined ? [text, x, y, maxWidth] : [text, x, y]));\n }\n\n strokeText(text: string, x: number, y: number, maxWidth?: number): void {\n this._m('strokeText', ...(maxWidth !== undefined ? [text, x, y, maxWidth] : [text, x, y]));\n }\n\n /** Synchronous text measurement — cannot go through the async command pipeline. */\n private _measureCtx: OffscreenCanvasRenderingContext2D | null = null;\n\n measureText(text: string): TextMetrics {\n if (!this._measureCtx) {\n this._measureCtx = new OffscreenCanvas(1, 1).getContext('2d')!;\n }\n this._measureCtx.font = this.font;\n return this._measureCtx.measureText(text);\n }\n\n // Line drawing\n beginPath(): void { this._m('beginPath'); }\n closePath(): void { this._m('closePath'); }\n moveTo(x: number, y: number): void { this._m('moveTo', x, y); }\n lineTo(x: number, y: number): void { this._m('lineTo', x, y); }\n\n bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number): void {\n this._m('bezierCurveTo', cp1x, cp1y, cp2x, cp2y, x, y);\n }\n\n quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void { this._m('quadraticCurveTo', cpx, cpy, x, y); }\n\n arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, counterclockwise?: boolean): void {\n this._m('arc', ...(counterclockwise !== undefined ? [x, y, radius, startAngle, endAngle, counterclockwise] : [x, y, radius, startAngle, endAngle]));\n }\n\n arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): void { this._m('arcTo', x1, y1, x2, y2, radius); }\n\n ellipse(x: number, y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, counterclockwise?: boolean): void {\n this._m('ellipse', ...(counterclockwise !== undefined ? [x, y, radiusX, radiusY, rotation, startAngle, endAngle, counterclockwise] : [x, y, radiusX, radiusY, rotation, startAngle, endAngle]));\n }\n\n rect(x: number, y: number, width: number, height: number): void { this._m('rect', x, y, width, height); }\n\n // Images\n drawImage(image: CanvasImageSource, dx: number, dy: number): void;\n drawImage(image: CanvasImageSource, dx: number, dy: number, dw: number, dh: number): void;\n drawImage(image: CanvasImageSource, sx: number, sy: number, sw: number, sh: number, dx: number, dy: number, dw: number, dh: number): void;\n drawImage(...args: [CanvasImageSource, ...number[]]): void {\n this._m('drawImage', ...args);\n }\n\n // Fill and stroke\n fill(): void { this._m('fill'); }\n stroke(): void { this._m('stroke'); }\n clip(): void { this._m('clip'); }\n\n // Properties (setters)\n set fillStyle(value: string | CanvasGradient | CanvasPattern) { this._p('fillStyle', value); }\n set strokeStyle(value: string | CanvasGradient | CanvasPattern) { this._p('strokeStyle', value); }\n set lineWidth(value: number) { this._p('lineWidth', value); }\n set lineCap(value: CanvasLineCap) { this._p('lineCap', value); }\n set lineJoin(value: CanvasLineJoin) { this._p('lineJoin', value); }\n set miterLimit(value: number) { this._p('miterLimit', value); }\n set lineDashOffset(value: number) { this._p('lineDashOffset', value); }\n set font(value: string) { this._p('font', value); }\n set textAlign(value: CanvasTextAlign) { this._p('textAlign', value); }\n set textBaseline(value: CanvasTextBaseline) { this._p('textBaseline', value); }\n set globalAlpha(value: number) { this._p('globalAlpha', value); }\n set globalCompositeOperation(value: GlobalCompositeOperation) { this._p('globalCompositeOperation', value); }\n set shadowBlur(value: number) { this._p('shadowBlur', value); }\n set shadowColor(value: string) { this._p('shadowColor', value); }\n set shadowOffsetX(value: number) { this._p('shadowOffsetX', value); }\n set shadowOffsetY(value: number) { this._p('shadowOffsetY', value); }\n set imageSmoothingEnabled(value: boolean) { this._p('imageSmoothingEnabled', value); }\n set letterSpacing(value: string) { this._p('letterSpacing', value); }\n\n // Property getters (return local cached values)\n get fillStyle() { return this._cp['fillStyle'] ?? '#000'; }\n get strokeStyle() { return this._cp['strokeStyle'] ?? '#000'; }\n get lineWidth() { return this._cp['lineWidth'] ?? 1; }\n get lineCap() { return this._cp['lineCap'] ?? 'butt'; }\n get lineJoin() { return this._cp['lineJoin'] ?? 'miter'; }\n get miterLimit() { return this._cp['miterLimit'] ?? 10; }\n get lineDashOffset() { return this._cp['lineDashOffset'] ?? 0; }\n get font() { return this._cp['font'] ?? '10px sans-serif'; }\n get textAlign() { return this._cp['textAlign'] ?? 'start'; }\n get textBaseline() { return this._cp['textBaseline'] ?? 'alphabetic'; }\n get globalAlpha() { return this._cp['globalAlpha'] ?? 1; }\n get globalCompositeOperation() { return this._cp['globalCompositeOperation'] ?? 'source-over'; }\n get shadowBlur() { return this._cp['shadowBlur'] ?? 0; }\n get shadowColor() { return this._cp['shadowColor'] ?? 'rgba(0, 0, 0, 0)'; }\n get shadowOffsetX() { return this._cp['shadowOffsetX'] ?? 0; }\n get shadowOffsetY() { return this._cp['shadowOffsetY'] ?? 0; }\n get imageSmoothingEnabled() { return this._cp['imageSmoothingEnabled'] ?? true; }\n get letterSpacing() { return this._cp['letterSpacing'] ?? ''; }\n}","/**\n * 3×3 Affine Transform Matrix Stack\n *\n * Replicates Canvas 2D's save()/restore()/translate()/rotate()/scale()\n * as a matrix stack for WebGL uniform upload.\n *\n * Matrices are 3×3 column-major (for gl.uniformMatrix3fv), representing\n * 2D affine transforms. The base matrix includes an orthographic projection\n * that maps canvas pixel coordinates (top-left origin, Y-down) to WebGL\n * clip space ([-1,1], Y-up).\n *\n * Column-major layout of a 3×3 affine matrix:\n * [0] [3] [6] a c tx\n * [1] [4] [7] = b d ty\n * [2] [5] [8] 0 0 1\n */\n\nexport class MatrixStack {\n private _stack: Float32Array[] = [];\n private _current: Float32Array;\n private _projection: Float32Array;\n\n /**\n * @param width Canvas width in pixels\n * @param height Canvas height in pixels\n */\n constructor(width: number, height: number) {\n this._projection = _ortho(width, height);\n this._current = new Float32Array(this._projection);\n }\n\n /** Push current matrix onto the stack. No _ prefix: cross-file. */\n save(): void {\n this._stack.push(new Float32Array(this._current));\n }\n\n /** Pop and restore the top matrix. No _ prefix: cross-file. */\n restore(): void {\n if (this._stack.length > 0) {\n this._current = this._stack.pop()!;\n }\n }\n\n /** Translate the current matrix. No _ prefix: cross-file. */\n translate(x: number, y: number): void {\n // Multiply current matrix by translation:\n // 1 0 tx\n // 0 1 ty\n // 0 0 1\n // In column-major: m[6] += m[0]*tx + m[3]*ty\n // m[7] += m[1]*tx + m[4]*ty\n const m = this._current;\n m[6] += m[0] * x + m[3] * y;\n m[7] += m[1] * x + m[4] * y;\n }\n\n /** Rotate the current matrix by angle (radians). No _ prefix: cross-file. */\n rotate(angle: number): void {\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n const m = this._current;\n const m0 = m[0], m1 = m[1], m3 = m[3], m4 = m[4];\n m[0] = m0 * c + m3 * s;\n m[1] = m1 * c + m4 * s;\n m[3] = m0 * -s + m3 * c;\n m[4] = m1 * -s + m4 * c;\n }\n\n /** Scale the current matrix. No _ prefix: cross-file. */\n scale(x: number, y: number): void {\n const m = this._current;\n m[0] *= x; m[1] *= x;\n m[3] *= y; m[4] *= y;\n }\n\n /**\n * Multiply current matrix by an arbitrary 2D affine transform.\n * Canvas 2D transform(a, b, c, d, e, f) matrix:\n * a c e\n * b d f\n * 0 0 1\n * No _ prefix: cross-file.\n */\n transform(a: number, b: number, c: number, d: number, e: number, f: number): void {\n const m = this._current;\n const m0 = m[0], m1 = m[1], m3 = m[3], m4 = m[4], m6 = m[6], m7 = m[7];\n m[0] = m0 * a + m3 * b;\n m[1] = m1 * a + m4 * b;\n m[3] = m0 * c + m3 * d;\n m[4] = m1 * c + m4 * d;\n m[6] = m0 * e + m3 * f + m6;\n m[7] = m1 * e + m4 * f + m7;\n }\n\n /**\n * Reset to projection then apply the given affine transform.\n * Canvas 2D setTransform(a, b, c, d, e, f).\n * No _ prefix: cross-file.\n */\n setTransform(a: number, b: number, c: number, d: number, e: number, f: number): void {\n this._current.set(this._projection);\n this.transform(a, b, c, d, e, f);\n }\n\n /** Reset to the base orthographic projection. No _ prefix: cross-file. */\n resetTransform(): void {\n this._current.set(this._projection);\n }\n\n /**\n * Update canvas dimensions (e.g., on resize).\n * Recomputes the projection and resets the current matrix.\n * No _ prefix: cross-file.\n */\n resize(width: number, height: number): void {\n this._projection = _ortho(width, height);\n this._current = new Float32Array(this._projection);\n this._stack = [];\n }\n\n /**\n * Returns the current 3×3 matrix for gl.uniformMatrix3fv.\n * No _ prefix: cross-file.\n */\n getMatrix(): Float32Array {\n return this._current;\n }\n}\n\n/**\n * Create an orthographic projection matrix that maps:\n * Canvas coords (0,0)=top-left, (w,h)=bottom-right, Y-down\n * → Clip space (-1,-1)=bottom-left, (1,1)=top-right, Y-up\n *\n * The transform is:\n * x_clip = x * 2/w - 1\n * y_clip = -(y * 2/h - 1) = 1 - y * 2/h\n *\n * Column-major 3×3:\n * 2/w 0 -1\n * 0 -2/h 1\n * 0 0 1\n */\nfunction _ortho(w: number, h: number): Float32Array {\n return new Float32Array([\n 2 / w, 0, 0, // column 0\n 0, -2 / h, 0, // column 1\n -1, 1, 1, // column 2\n ]);\n}\n","/**\n * CSS Color Parser\n *\n * Converts CSS color strings to Float32Array [r, g, b, a] in [0, 1] range\n * for use as WebGL uniform values.\n *\n * Supported formats:\n * - Hex: #rgb, #rrggbb, #rrggbbaa\n * - Functional: rgb(r, g, b), rgba(r, g, b, a)\n * - Named: basic CSS color keywords\n *\n * Includes a cache for repeated lookups (the demo reuses ~10 colors).\n */\n\nconst _NAMED_COLORS: Record<string, number> = {\n black: 0x000000ff,\n white: 0xffffffff,\n red: 0xff0000ff,\n green: 0x008000ff,\n blue: 0x0000ffff,\n yellow: 0xffff00ff,\n cyan: 0x00ffffff,\n magenta: 0xff00ffff,\n orange: 0xffa500ff,\n transparent: 0x00000000,\n};\n\nconst _cache = new Map<string, Float32Array>();\n\n/**\n * Parse a CSS color string into [r, g, b, a] floats in [0, 1].\n * Returns a cached Float32Array — do NOT mutate the result.\n *\n * No _ prefix: called cross-file from canvas2d-shim.\n */\nexport function parseColor(css: string): Float32Array {\n const cached = _cache.get(css);\n if (cached) return cached;\n\n const result = _parse(css);\n _cache.set(css, result);\n return result;\n}\n\nfunction _parse(css: string): Float32Array {\n const s = css.trim();\n\n // #hex\n if (s.charCodeAt(0) === 0x23) { // '#'\n return _parseHex(s);\n }\n\n // rgb() / rgba()\n if (s.charCodeAt(0) === 0x72) { // 'r'\n return _parseRgb(s);\n }\n\n // Named color\n const named = _NAMED_COLORS[s.toLowerCase()];\n if (named !== undefined) {\n return new Float32Array([\n ((named >>> 24) & 0xff) / 255,\n ((named >>> 16) & 0xff) / 255,\n ((named >>> 8) & 0xff) / 255,\n (named & 0xff) / 255,\n ]);\n }\n\n // Fallback: opaque black\n return new Float32Array([0, 0, 0, 1]);\n}\n\nfunction _parseHex(s: string): Float32Array {\n const len = s.length;\n\n if (len === 4) {\n // #rgb → expand to #rrggbb\n const r = parseInt(s[1], 16);\n const g = parseInt(s[2], 16);\n const b = parseInt(s[3], 16);\n return new Float32Array([\n (r * 17) / 255,\n (g * 17) / 255,\n (b * 17) / 255,\n 1,\n ]);\n }\n\n if (len === 7) {\n // #rrggbb\n const r = parseInt(s.slice(1, 3), 16);\n const g = parseInt(s.slice(3, 5), 16);\n const b = parseInt(s.slice(5, 7), 16);\n return new Float32Array([r / 255, g / 255, b / 255, 1]);\n }\n\n if (len === 9) {\n // #rrggbbaa\n const r = parseInt(s.slice(1, 3), 16);\n const g = parseInt(s.slice(3, 5), 16);\n const b = parseInt(s.slice(5, 7), 16);\n const a = parseInt(s.slice(7, 9), 16);\n return new Float32Array([r / 255, g / 255, b / 255, a / 255]);\n }\n\n // #rgba (4-digit with alpha)\n if (len === 5) {\n const r = parseInt(s[1], 16);\n const g = parseInt(s[2], 16);\n const b = parseInt(s[3], 16);\n const a = parseInt(s[4], 16);\n return new Float32Array([\n (r * 17) / 255,\n (g * 17) / 255,\n (b * 17) / 255,\n (a * 17) / 255,\n ]);\n }\n\n return new Float32Array([0, 0, 0, 1]);\n}\n\nfunction _parseRgb(s: string): Float32Array {\n // Match both rgb(...) and rgba(...)\n // Extract the numeric values between parentheses\n const start = s.indexOf('(');\n const end = s.lastIndexOf(')');\n if (start === -1 || end === -1) return new Float32Array([0, 0, 0, 1]);\n\n const parts = s.slice(start + 1, end).split(',');\n const r = parseFloat(parts[0]) / 255;\n const g = parseFloat(parts[1]) / 255;\n const b = parseFloat(parts[2]) / 255;\n const a = parts.length >= 4 ? parseFloat(parts[3]) : 1;\n\n return new Float32Array([r, g, b, a]);\n}\n","/**\n * GLSL Shader Sources for canvas-ultrafast\n *\n * Content shaders (flat-color, textured) plus a passthrough display shader.\n * CRT post-processing shaders live in the maalata package.\n *\n * Coordinate convention:\n * - Content shaders use a 3x3 affine matrix (u_matrix) that maps\n * canvas pixel coordinates (top-left origin, Y-down) to clip space.\n * - Passthrough shader uses a fullscreen quad in [0,1] mapped to [-1,1] clip space.\n */\n\n// ---------------------------------------------------------------------------\n// Flat-color shader: rectangles, line quads, clear regions\n// ---------------------------------------------------------------------------\n\nexport const FLAT_VERTEX_SRC = `\n attribute vec2 a_position;\n uniform mat3 u_matrix;\n void main() {\n vec3 pos = u_matrix * vec3(a_position, 1.0);\n gl_Position = vec4(pos.xy, 0.0, 1.0);\n }\n`;\n\nexport const FLAT_FRAGMENT_SRC = `\n precision mediump float;\n uniform vec4 u_color;\n void main() {\n gl_FragColor = u_color;\n }\n`;\n\n// ---------------------------------------------------------------------------\n// Textured quad shader: text rendering via OffscreenCanvas glyph upload\n// ---------------------------------------------------------------------------\n\nexport const TEXTURED_VERTEX_SRC = `\n attribute vec2 a_position;\n attribute vec2 a_texCoord;\n uniform mat3 u_matrix;\n varying vec2 v_texCoord;\n void main() {\n vec3 pos = u_matrix * vec3(a_position, 1.0);\n gl_Position = vec4(pos.xy, 0.0, 1.0);\n v_texCoord = a_texCoord;\n }\n`;\n\nexport const TEXTURED_FRAGMENT_SRC = `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D u_texture;\n uniform vec4 u_color;\n void main() {\n vec4 texel = texture2D(u_texture, v_texCoord);\n gl_FragColor = texel * u_color;\n }\n`;\n\n// ---------------------------------------------------------------------------\n// Passthrough display shader: fullscreen quad, reads FBO texture\n// ---------------------------------------------------------------------------\n\n/**\n * Vertex shader: fullscreen quad [0,1] → clip space [-1,1].\n * FBO textures are already in GL-native bottom-left origin (the orthographic\n * projection in matrix-stack.ts handles the canvas Y-down → GL Y-up flip),\n * so tex coords pass through without Y-flip.\n */\nexport const PASSTHROUGH_VERTEX_SRC = `\n attribute vec2 a_position;\n varying vec2 v_texCoord;\n void main() {\n v_texCoord = a_position;\n gl_Position = vec4(a_position * 2.0 - 1.0, 0, 1);\n }\n`;\n\n/**\n * Passthrough fragment shader: blit FBO texture to screen without effects.\n */\nexport const PASSTHROUGH_FRAGMENT_SRC = `\n precision mediump float;\n varying vec2 v_texCoord;\n uniform sampler2D u_texture;\n void main() {\n gl_FragColor = texture2D(u_texture, v_texCoord);\n }\n`;\n","/**\n * Canvas 2D → WebGL Command Shim\n *\n * Translates CanvasCommand[] (recorded by CanvasAPI) into WebGL draw calls.\n * Handles the subset of Canvas 2D API used by the demo, plus reasonable\n * extensions. Operations not yet implemented log a warning and no-op.\n *\n * Rendering approach per command type:\n * - clearRect: gl.scissor + gl.clear\n * - fillRect: unit quad VBO + flat shader + transform uniform\n * - strokeRect: four thin quads (one per edge)\n * - fillText: render to OffscreenCanvas 2D → texImage2D → textured quad\n * - stroke(): expand line segments to quads on CPU, flat shader\n * - save/restore: matrix + state stack\n *\n * Text rendering uses an OffscreenCanvas with a 2D context as a glyph\n * rendering surface. At 8 FPS with ~5 text draws per frame, per-string\n * rendering (not glyph caching) is appropriate — texImage2D(OffscreenCanvas)\n * is a fast GPU upload path.\n */\n\nimport { CanvasCommand } from './canvas-api';\nimport { MatrixStack } from './matrix-stack';\nimport { parseColor } from './color-parser';\nimport {\n FLAT_VERTEX_SRC, FLAT_FRAGMENT_SRC,\n TEXTURED_VERTEX_SRC, TEXTURED_FRAGMENT_SRC,\n} from './shaders';\n\ninterface _DrawState {\n _fillColor: Float32Array;\n _strokeColor: Float32Array;\n _lineWidth: number;\n _globalAlpha: number;\n _font: string;\n _textAlign: CanvasTextAlign;\n _textBaseline: CanvasTextBaseline;\n _lineCap: CanvasLineCap;\n _lineJoin: CanvasLineJoin;\n _imageSmoothingEnabled: boolean;\n _letterSpacing: string;\n _clipActive: boolean;\n _clipRect: [number, number, number, number] | null;\n}\n\ninterface _ProgramInfo {\n _program: WebGLProgram;\n _matrixLoc: WebGLUniformLocation | null;\n _colorLoc: WebGLUniformLocation | null;\n _textureLoc: WebGLUniformLocation | null;\n _positionLoc: number;\n _texCoordLoc: number;\n}\n\nexport class Canvas2DShim {\n private _gl: WebGLRenderingContext;\n private _width: number;\n private _height: number;\n\n // Transform\n private _matrix: MatrixStack;\n\n // State\n private _fillColor: Float32Array = new Float32Array([0, 0, 0, 1]);\n private _strokeColor: Float32Array = new Float32Array([0, 0, 0, 1]);\n private _lineWidth = 1;\n private _globalAlpha = 1;\n private _font = '10px sans-serif';\n private _textAlign: CanvasTextAlign = 'start';\n private _textBaseline: CanvasTextBaseline = 'alphabetic';\n private _lineCap: CanvasLineCap = 'butt';\n private _lineJoin: CanvasLineJoin = 'miter';\n private _imageSmoothingEnabled = true;\n private _letterSpacing = '';\n private _clipActive = false;\n private _clipRect: [number, number, number, number] | null = null;\n private _pendingClipRect: [number, number, number, number] | null = null;\n private _imageTexCache = new WeakMap<object, { _tex: WebGLTexture; _isImage: boolean }>();\n private _stateStack: _DrawState[] = [];\n\n // Path state\n private _pathSegments: number[] = []; // flat: x0,y0,x1,y1,...\n private _currentX = 0;\n private _currentY = 0;\n private _subpathStartX = 0;\n private _subpathStartY = 0;\n\n // WebGL resources\n private _flat: _ProgramInfo;\n private _textured: _ProgramInfo;\n private _unitQuadVBO: WebGLBuffer;\n private _dynamicVBO: WebGLBuffer;\n private _texturedVBO: WebGLBuffer;\n private _textTexture: WebGLTexture;\n\n // Text rendering surface\n private _textCanvas: OffscreenCanvas;\n private _textCtx: OffscreenCanvasRenderingContext2D;\n\n // Background color for opaque canvas clear\n private _bgColor = new Float32Array([0, 0, 0]);\n\n // Temp arrays to avoid allocation in hot path\n private _tmpColor = new Float32Array(4);\n\n constructor(gl: WebGLRenderingContext, width: number, height: number) {\n this._gl = gl;\n this._width = width;\n this._height = height;\n this._matrix = new MatrixStack(width, height);\n\n // Compile shader programs\n this._flat = this._createProgram(\n FLAT_VERTEX_SRC, FLAT_FRAGMENT_SRC, false\n );\n this._textured = this._createProgram(\n TEXTURED_VERTEX_SRC, TEXTURED_FRAGMENT_SRC, true\n );\n\n // Unit quad VBO: two triangles covering [0,0]-[1,1]\n // Used for fillRect (scaled via matrix) and fullscreen blits\n this._unitQuadVBO = gl.createBuffer()!;\n gl.bindBuffer(gl.ARRAY_BUFFER, this._unitQuadVBO);\n gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([\n 0, 0, 1, 0, 0, 1,\n 0, 1, 1, 0, 1, 1,\n ]), gl.STATIC_DRAW);\n\n // Dynamic VBO for line quads — uses orphaning for double-buffer\n this._dynamicVBO = gl.createBuffer()!;\n\n // Textured quad VBO: position + texcoord interleaved\n this._texturedVBO = gl.createBuffer()!;\n\n // Text rendering texture\n this._textTexture = gl.createTexture()!;\n gl.bindTexture(gl.TEXTURE_2D, this._textTexture);\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\n // OffscreenCanvas for text glyph rendering\n this._textCanvas = new OffscreenCanvas(512, 128);\n this._textCtx = this._textCanvas.getContext('2d')!;\n\n // Enable blending for standard source-over compositing\n gl.enable(gl.BLEND);\n gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\n }\n\n /**\n * Execute a batch of Canvas 2D commands as WebGL draw calls.\n * No _ prefix: called cross-file from webgl-renderer.\n */\n executeBatch(commands: CanvasCommand[]): void {\n for (const cmd of commands) {\n if (cmd.type === 'property') {\n this._setProperty(cmd.name, cmd.value);\n } else {\n this._callMethod(cmd.name, cmd.args);\n }\n }\n }\n\n /**\n * Set the opaque clear color for clearRect.\n * No _ prefix: called cross-file from renderer.\n */\n setBackgroundColor(r: number, g: number, b: number): void {\n this._bgColor[0] = r;\n this._bgColor[1] = g;\n this._bgColor[2] = b;\n }\n\n /**\n * Update canvas dimensions on resize.\n * No _ prefix: called cross-file.\n */\n resize(width: number, height: number): void {\n this._width = width;\n this._height = height;\n this._matrix.resize(width, height);\n }\n\n /**\n * Clean up WebGL resources.\n * No _ prefix: called cross-file.\n */\n destroy(): void {\n const gl = this._gl;\n gl.deleteBuffer(this._unitQuadVBO);\n gl.deleteBuffer(this._dynamicVBO);\n gl.deleteBuffer(this._texturedVBO);\n gl.deleteTexture(this._textTexture);\n gl.deleteProgram(this._flat._program);\n gl.deleteProgram(this._textured._program);\n }\n\n // -------------------------------------------------------------------------\n // Private: property handling\n // -------------------------------------------------------------------------\n\n private _setProperty(name: string, value: unknown): void {\n switch (name) {\n case 'fillStyle':\n this._fillColor = parseColor(value as string);\n break;\n case 'strokeStyle':\n this._strokeColor = parseColor(value as string);\n break;\n case 'lineWidth':\n this._lineWidth = value as number;\n break;\n case 'globalAlpha':\n this._globalAlpha = value as number;\n break;\n case 'font':\n this._font = value as string;\n break;\n case 'textAlign':\n this._textAlign = value as CanvasTextAlign;\n break;\n case 'textBaseline':\n this._textBaseline = value as CanvasTextBaseline;\n break;\n case 'lineCap':\n this._lineCap = value as CanvasLineCap;\n break;\n case 'lineJoin':\n this._lineJoin = value as CanvasLineJoin;\n break;\n case 'imageSmoothingEnabled':\n this._imageSmoothingEnabled = value as boolean;\n break;\n case 'letterSpacing':\n this._letterSpacing = value as string;\n break;\n default:\n // Unsupported properties: silently ignore\n break;\n }\n }\n\n // -------------------------------------------------------------------------\n // Private: method dispatch\n // -------------------------------------------------------------------------\n\n private _callMethod(name: string, args: unknown[]): void {\n switch (name) {\n // Rectangles\n case 'clearRect':\n this._clearRect(args[0] as number, args[1] as number, args[2] as number, args[3] as number);\n break;\n case 'fillRect':\n this._fillRect(args[0] as number, args[1] as number, args[2] as number, args[3] as number);\n break;\n case 'strokeRect':\n this._strokeRect(args[0] as number, args[1] as number, args[2] as number, args[3] as number);\n break;\n\n // Text\n case 'fillText':\n this._fillText(args[0] as string, args[1] as number, args[2] as number);\n break;\n case 'strokeText':\n this._strokeText(args[0] as string, args[1] as number, args[2] as number);\n break;\n\n // Images\n case 'drawImage':\n this._drawImage(args);\n break;\n\n // Path\n case 'beginPath':\n this._pathSegments = [];\n this._pendingClipRect = null;\n break;\n case 'closePath':\n if (this._currentX !== this._subpathStartX || this._currentY !== this._subpathStartY) {\n this._pathSegments.push(\n this._currentX, this._currentY,\n this._subpathStartX, this._subpathStartY\n );\n this._currentX = this._subpathStartX;\n this._currentY = this._subpathStartY;\n }\n break;\n case 'moveTo':\n this._currentX = this._subpathStartX = args[0] as number;\n this._currentY = this._subpathStartY = args[1] as number;\n break;\n case 'lineTo': {\n const x = args[0] as number;\n const y = args[1] as number;\n this._pathSegments.push(this._currentX, this._currentY, x, y);\n this._currentX = x;\n this._currentY = y;\n break;\n }\n case 'rect': {\n const rx = args[0] as number, ry = args[1] as number;\n const rw = args[2] as number, rh = args[3] as number;\n // Store as pending clip rect (used if clip() follows)\n this._pendingClipRect = [rx, ry, rw, rh];\n // Also add 4 line segments to path for potential stroke()\n this._pathSegments.push(\n rx, ry, rx + rw, ry, // top\n rx + rw, ry, rx + rw, ry + rh, // right\n rx + rw, ry + rh, rx, ry + rh, // bottom\n rx, ry + rh, rx, ry, // left\n );\n break;\n }\n case 'clip':\n this._applyClip();\n break;\n case 'stroke':\n this._strokePath();\n break;\n case 'fill':\n // Convex fill only — not heavily used in demo beyond fillRect\n break;\n\n // State\n case 'save':\n this._save();\n break;\n case 'restore':\n this._restore();\n break;\n\n // Transforms\n case 'translate':\n this._matrix.translate(args[0] as number, args[1] as number);\n break;\n case 'rotate':\n this._matrix.rotate(args[0] as number);\n break;\n case 'scale':\n this._matrix.scale(args[0] as number, args[1] as number);\n break;\n case 'transform':\n this._matrix.transform(\n args[0] as number, args[1] as number, args[2] as number,\n args[3] as number, args[4] as number, args[5] as number\n );\n break;\n case 'setTransform':\n this._matrix.setTransform(\n args[0] as number, args[1] as number, args[2] as number,\n args[3] as number, args[4] as number, args[5] as number\n );\n break;\n case 'resetTransform':\n this._matrix.resetTransform();\n break;\n\n default:\n // Unsupported methods: silently ignore (arc, bezierCurveTo, etc.)\n break;\n }\n }\n\n // -------------------------------------------------------------------------\n // Private: drawing operations\n // -------------------------------------------------------------------------\n\n private _clearRect(x: number, y: number, w: number, h: number): void {\n const gl = this._gl;\n const bg = this._bgColor;\n // WebGL scissor uses bottom-left origin, canvas uses top-left\n gl.enable(gl.SCISSOR_TEST);\n gl.scissor(x, this._height - y - h, w, h);\n gl.clearColor(bg[0], bg[1], bg[2], 1);\n gl.clear(gl.COLOR_BUFFER_BIT);\n gl.disable(gl.SCISSOR_TEST);\n }\n\n private _fillRect(x: number, y: number, w: number, h: number): void {\n const gl = this._gl;\n const prog = this._flat;\n\n gl.useProgram(prog._program);\n\n // Build transform: current matrix × translate(x,y) × scale(w,h)\n // Applied to unit quad [0,1]×[0,1] → fills [x,y,x+w,y+h]\n this._matrix.save();\n this._matrix.translate(x, y);\n this._matrix.scale(w, h);\n\n gl.uniformMatrix3fv(prog._matrixLoc, false, this._matrix.getMatrix());\n this._setColorUniform(prog._colorLoc!, this._fillColor, this._globalAlpha);\n\n this._matrix.restore();\n\n // Draw unit quad\n gl.bindBuffer(gl.ARRAY_BUFFER, this._unitQuadVBO);\n gl.enableVertexAttribArray(prog._positionLoc);\n gl.vertexAttribPointer(prog._positionLoc, 2, gl.FLOAT, false, 0, 0);\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n }\n\n private _strokeRect(x: number, y: number, w: number, h: number): void {\n // Draw four edges as thin quads\n const lw = this._lineWidth;\n const hlw = lw / 2;\n\n // Top edge\n this._fillRectWithColor(x - hlw, y - hlw, w + lw, lw, this._strokeColor);\n // Bottom edge\n this._fillRectWithColor(x - hlw, y + h - hlw, w + lw, lw, this._strokeColor);\n // Left edge\n this._fillRectWithColor(x - hlw, y + hlw, lw, h - lw, this._strokeColor);\n // Right edge\n this._fillRectWithColor(x + w - hlw, y + hlw, lw, h - lw, this._strokeColor);\n }\n\n /** Internal: draw a filled rect with a specific color (used by strokeRect). */\n private _fillRectWithColor(x: number, y: number, w: number, h: number, color: Float32Array): void {\n const gl = this._gl;\n const prog = this._flat;\n\n gl.useProgram(prog._program);\n\n this._matrix.save();\n this._matrix.translate(x, y);\n this._matrix.scale(w, h);\n\n gl.uniformMatrix3fv(prog._matrixLoc, false, this._matrix.getMatrix());\n this._setColorUniform(prog._colorLoc!, color, this._globalAlpha);\n\n this._matrix.restore();\n\n gl.bindBuffer(gl.ARRAY_BUFFER, this._unitQuadVBO);\n gl.enableVertexAttribArray(prog._positionLoc);\n gl.vertexAttribPointer(prog._positionLoc, 2, gl.FLOAT, false, 0, 0);\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n }\n\n private _strokePath(): void {\n const segs = this._pathSegments;\n if (segs.length === 0) return;\n\n const gl = this._gl;\n const prog = this._flat;\n const halfW = Math.max(this._lineWidth / 2, 0.5);\n\n // Expand line segments to quads on CPU\n // Each segment (x0,y0,x1,y1) → 6 vertices (2 triangles)\n const segCount = segs.length / 4;\n const vertices = new Float32Array(segCount * 12); // 6 vertices × 2 coords\n\n for (let i = 0, vi = 0; i < segs.length; i += 4) {\n const x0 = segs[i], y0 = segs[i + 1], x1 = segs[i + 2], y1 = segs[i + 3];\n const dx = x1 - x0;\n const dy = y1 - y0;\n const len = Math.sqrt(dx * dx + dy * dy);\n\n if (len < 0.001) continue; // Skip degenerate segments\n\n // Normal perpendicular to line direction\n const nx = (-dy / len) * halfW;\n const ny = (dx / len) * halfW;\n\n // Four corners of the quad\n const ax = x0 + nx, ay = y0 + ny; // top-left\n const bx = x0 - nx, by = y0 - ny; // bottom-left\n const cx = x1 + nx, cy = y1 + ny; // top-right\n const dx2 = x1 - nx, dy2 = y1 - ny; // bottom-right\n\n // Triangle 1: A, B, C\n vertices[vi++] = ax; vertices[vi++] = ay;\n vertices[vi++] = bx; vertices[vi++] = by;\n vertices[vi++] = cx; vertices[vi++] = cy;\n // Triangle 2: B, D, C\n vertices[vi++] = bx; vertices[vi++] = by;\n vertices[vi++] = dx2; vertices[vi++] = dy2;\n vertices[vi++] = cx; vertices[vi++] = cy;\n }\n\n // Upload to dynamic VBO using orphaning (bufferData null pattern)\n gl.bindBuffer(gl.ARRAY_BUFFER, this._dynamicVBO);\n gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.DYNAMIC_DRAW);\n\n gl.useProgram(prog._program);\n gl.uniformMatrix3fv(prog._matrixLoc, false, this._matrix.getMatrix());\n this._setColorUniform(prog._colorLoc!, this._strokeColor, this._globalAlpha);\n\n gl.enableVertexAttribArray(prog._positionLoc);\n gl.vertexAttribPointer(prog._positionLoc, 2, gl.FLOAT, false, 0, 0);\n gl.drawArrays(gl.TRIANGLES, 0, segCount * 6);\n }\n\n private _drawImage(args: unknown[]): void {\n const gl = this._gl;\n const image = args[0] as CanvasImageSource;\n\n let sx: number, sy: number, sw: number, sh: number;\n let dx: number, dy: number, dw: number, dh: number;\n\n // Get image dimensions\n const imgW = _getImageWidth(image);\n const imgH = _getImageHeight(image);\n\n if (args.length === 3) {\n // drawImage(image, dx, dy)\n sx = 0; sy = 0; sw = imgW; sh = imgH;\n dx = args[1] as number; dy = args[2] as number;\n dw = imgW; dh = imgH;\n } else if (args.length === 5) {\n // drawImage(image, dx, dy, dw, dh)\n sx = 0; sy = 0; sw = imgW; sh = imgH;\n dx = args[1] as number; dy = args[2] as number;\n dw = args[3] as number; dh = args[4] as number;\n } else {\n // drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)\n sx = args[1] as number; sy = args[2] as number;\n sw = args[3] as number; sh = args[4] as number;\n dx = args[5] as number; dy = args[6] as number;\n dw = args[7] as number; dh = args[8] as number;\n }\n\n // Get or create texture for this image source\n const tex = this._getOrUploadTexture(image, imgW, imgH);\n\n // Set filtering based on imageSmoothingEnabled\n const filter = this._imageSmoothingEnabled ? gl.LINEAR : gl.NEAREST;\n gl.bindTexture(gl.TEXTURE_2D, tex);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filter);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filter);\n\n // Compute UV coordinates for source sub-rect\n const uMin = sx / imgW;\n const vMin = sy / imgH;\n const uMax = (sx + sw) / imgW;\n const vMax = (sy + sh) / imgH;\n\n // Draw textured quad with interleaved position + texcoord\n const prog = this._textured;\n const verts = new Float32Array([\n dx, dy, uMin, vMin,\n dx + dw, dy, uMax, vMin,\n dx, dy + dh, uMin, vMax,\n dx, dy + dh, uMin, vMax,\n dx + dw, dy, uMax, vMin,\n dx + dw, dy + dh, uMax, vMax,\n ]);\n\n gl.bindBuffer(gl.ARRAY_BUFFER, this._texturedVBO);\n gl.bufferData(gl.ARRAY_BUFFER, verts, gl.DYNAMIC_DRAW);\n\n gl.useProgram(prog._program);\n gl.uniformMatrix3fv(prog._matrixLoc, false, this._matrix.getMatrix());\n // White color tint with globalAlpha — no color modification, just alpha\n gl.uniform4f(prog._colorLoc!, 1, 1, 1, this._globalAlpha);\n\n // Standard alpha blending (not premultiplied for image textures)\n const stride = 16; // 4 floats × 4 bytes\n gl.enableVertexAttribArray(prog._positionLoc);\n gl.vertexAttribPointer(prog._positionLoc, 2, gl.FLOAT, false, stride, 0);\n gl.enableVertexAttribArray(prog._texCoordLoc);\n gl.vertexAttribPointer(prog._texCoordLoc, 2, gl.FLOAT, false, stride, 8);\n\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, tex);\n gl.uniform1i(prog._textureLoc, 0);\n\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n\n // Disable texcoord attrib to avoid interfering with flat shader\n gl.disableVertexAttribArray(prog._texCoordLoc);\n }\n\n private _getOrUploadTexture(image: CanvasImageSource, imgW: number, imgH: number): WebGLTexture {\n const gl = this._gl;\n const key = image as unknown as object;\n const cached = this._imageTexCache.get(key);\n\n // HTMLImageElement/SVGImageElement: upload once, cache permanently\n // HTMLCanvasElement/OffscreenCanvas: always re-upload (content may change)\n const isImage = (image instanceof HTMLImageElement) || (image instanceof SVGImageElement);\n\n if (cached) {\n if (cached._isImage) {\n // Static image — reuse cached texture\n return cached._tex;\n }\n // Canvas source — re-upload to existing texture\n gl.bindTexture(gl.TEXTURE_2D, cached._tex);\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image as TexImageSource);\n return cached._tex;\n }\n\n // Create new texture\n const tex = gl.createTexture()!;\n gl.bindTexture(gl.TEXTURE_2D, tex);\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\n // Detect if we need to handle alpha properly\n // For canvas sources, use standard upload; for images, avoid premultiply\n if (imgW > 0 && imgH > 0) {\n gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image as TexImageSource);\n }\n\n this._imageTexCache.set(key, { _tex: tex, _isImage: isImage });\n return tex;\n }\n\n private _applyClip(): void {\n const gl = this._gl;\n if (this._pendingClipRect) {\n const [x, y, w, h] = this._pendingClipRect;\n gl.enable(gl.SCISSOR_TEST);\n // Convert canvas coords (top-left origin) to GL coords (bottom-left origin)\n gl.scissor(x, this._height - y - h, w, h);\n this._clipActive = true;\n this._clipRect = [x, y, w, h];\n }\n }\n\n private _fillText(text: string, x: number, y: number): void {\n this._renderText(text, x, y, 'fill');\n }\n\n private _strokeText(text: string, x: number, y: number): void {\n this._renderText(text, x, y, 'stroke');\n }\n\n private _renderText(text: string, x: number, y: number, mode: 'fill' | 'stroke'): void {\n const gl = this._gl;\n const tCtx = this._textCtx;\n\n // Configure text rendering context\n tCtx.font = this._font;\n tCtx.textAlign = 'left'; // Always render left-aligned, position via WebGL\n tCtx.textBaseline = 'top'; // Always render from top, adjust Y via offset\n if (this._letterSpacing) {\n tCtx.letterSpacing = this._letterSpacing;\n }\n\n // Measure text\n const metrics = tCtx.measureText(text);\n const textWidth = Math.ceil(metrics.width) + 4; // +4 for antialiasing padding\n const fontSize = _parseFontSize(this._font);\n const textHeight = Math.ceil(fontSize * 1.5) + 4; // approximate height with descenders\n\n if (textWidth <= 0 || textHeight <= 0) return;\n\n // Resize text canvas if needed\n if (this._textCanvas.width < textWidth || this._textCanvas.height < textHeight) {\n this._textCanvas.width = Math.max(this._textCanvas.width, textWidth);\n this._textCanvas.height = Math.max(this._textCanvas.height, textHeight);\n // Re-set font after resize (context is reset)\n tCtx.font = this._font;\n tCtx.textAlign = 'left';\n tCtx.textBaseline = 'top';\n }\n\n // Clear and render text\n tCtx.clearRect(0, 0, this._textCanvas.width, this._textCanvas.height);\n\n if (mode === 'fill') {\n tCtx.fillStyle = 'white'; // White text, tinted by WebGL uniform\n tCtx.fillText(text, 2, 2); // +2 padding offset\n } else {\n tCtx.strokeStyle = 'white';\n tCtx.lineWidth = this._lineWidth;\n tCtx.strokeText(text, 2, 2);\n }\n\n // Upload text canvas to texture\n gl.bindTexture(gl.TEXTURE_2D, this._textTexture);\n gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 1);\n gl.texImage2D(\n gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE,\n this._textCanvas\n );\n gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 0);\n\n // Compute text position adjustments\n const color = mode === 'fill' ? this._fillColor : this._strokeColor;\n let drawX = x - 2; // compensate for padding\n let drawY = y - 2;\n\n // Adjust for textAlign\n switch (this._textAlign) {\n case 'center': drawX -= textWidth / 2; break;\n case 'right':\n case 'end': drawX -= textWidth; break;\n }\n\n // Adjust for textBaseline\n switch (this._textBaseline) {\n case 'top': /* drawY stays */ break;\n case 'middle': drawY -= textHeight / 2; break;\n case 'alphabetic':\n case 'ideographic': drawY -= fontSize; break;\n case 'bottom':\n case 'hanging': drawY -= textHeight; break;\n }\n\n // Draw textured quad\n this._drawTexturedQuad(\n drawX, drawY, textWidth, textHeight,\n textWidth / this._textCanvas.width,\n textHeight / this._textCanvas.height,\n color\n );\n }\n\n private _drawTexturedQuad(\n x: number, y: number, w: number, h: number,\n uMax: number, vMax: number,\n color: Float32Array\n ): void {\n const gl = this._gl;\n const prog = this._textured;\n\n // Interleaved position + texcoord (x, y, u, v)\n const verts = new Float32Array([\n x, y, 0, 0,\n x + w, y, uMax, 0,\n x, y + h, 0, vMax,\n x, y + h, 0, vMax,\n x + w, y, uMax, 0,\n x + w, y + h, uMax, vMax,\n ]);\n\n gl.bindBuffer(gl.ARRAY_BUFFER, this._texturedVBO);\n gl.bufferData(gl.ARRAY_BUFFER, verts, gl.DYNAMIC_DRAW);\n\n gl.useProgram(prog._program);\n gl.uniformMatrix3fv(prog._matrixLoc, false, this._matrix.getMatrix());\n this._setColorUniform(prog._colorLoc!, color, this._globalAlpha);\n\n // Use premultiplied alpha blending for text\n gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);\n\n const stride = 16; // 4 floats × 4 bytes\n gl.enableVertexAttribArray(prog._positionLoc);\n gl.vertexAttribPointer(prog._positionLoc, 2, gl.FLOAT, false, stride, 0);\n gl.enableVertexAttribArray(prog._texCoordLoc);\n gl.vertexAttribPointer(prog._texCoordLoc, 2, gl.FLOAT, false, stride, 8);\n\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, this._textTexture);\n gl.uniform1i(prog._textureLoc, 0);\n\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n\n // Restore standard blending\n gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);\n\n // Disable texcoord attrib to avoid interfering with flat shader\n gl.disableVertexAttribArray(prog._texCoordLoc);\n }\n\n // -------------------------------------------------------------------------\n // Private: state management\n // -------------------------------------------------------------------------\n\n private _save(): void {\n this._matrix.save();\n this._stateStack.push({\n _fillColor: new Float32Array(this._fillColor),\n _strokeColor: new Float32Array(this._strokeColor),\n _lineWidth: this._lineWidth,\n _globalAlpha: this._globalAlpha,\n _font: this._font,\n _textAlign: this._textAlign,\n _textBaseline: this._textBaseline,\n _lineCap: this._lineCap,\n _lineJoin: this._lineJoin,\n _imageSmoothingEnabled: this._imageSmoothingEnabled,\n _letterSpacing: this._letterSpacing,\n _clipActive: this._clipActive,\n _clipRect: this._clipRect ? [...this._clipRect] as [number, number, number, number] : null,\n });\n }\n\n private _restore(): void {\n this._matrix.restore();\n const gl = this._gl;\n const state = this._stateStack.pop();\n if (state) {\n this._fillColor = state._fillColor;\n this._strokeColor = state._strokeColor;\n this._lineWidth = state._lineWidth;\n this._globalAlpha = state._globalAlpha;\n this._font = state._font;\n this._textAlign = state._textAlign;\n this._textBaseline = state._textBaseline;\n this._lineCap = state._lineCap;\n this._lineJoin = state._lineJoin;\n this._imageSmoothingEnabled = state._imageSmoothingEnabled;\n this._letterSpacing = state._letterSpacing;\n this._clipActive = state._clipActive;\n this._clipRect = state._clipRect;\n\n // Restore scissor state\n if (this._clipActive && this._clipRect) {\n const [x, y, w, h] = this._clipRect;\n gl.enable(gl.SCISSOR_TEST);\n gl.scissor(x, this._height - y - h, w, h);\n } else {\n gl.disable(gl.SCISSOR_TEST);\n }\n }\n }\n\n // -------------------------------------------------------------------------\n // Private: WebGL helpers\n // -------------------------------------------------------------------------\n\n private _setColorUniform(loc: WebGLUniformLocation, color: Float32Array, alpha: number): void {\n // Premultiply globalAlpha into the color's alpha channel\n const a = color[3] * alpha;\n this._gl.uniform4f(loc, color[0], color[1], color[2], a);\n }\n\n private _createProgram(vSrc: string, fSrc: string, hasTexCoord: boolean): _ProgramInfo {\n const gl = this._gl;\n const vs = this._compileShader(gl.VERTEX_SHADER, vSrc);\n const fs = this._compileShader(gl.FRAGMENT_SHADER, fSrc);\n\n const program = gl.createProgram()!;\n gl.attachShader(program, vs);\n gl.attachShader(program, fs);\n gl.linkProgram(program);\n\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n throw new Error('Shader link failed: ' + gl.getProgramInfoLog(program));\n }\n\n // Delete shaders after linking (they're embedded in the program now)\n gl.deleteShader(vs);\n gl.deleteShader(fs);\n\n return {\n _program: program,\n _matrixLoc: gl.getUniformLocation(program, 'u_matrix'),\n _colorLoc: gl.getUniformLocation(program, 'u_color'),\n _textureLoc: hasTexCoord ? gl.getUniformLocation(program, 'u_texture') : null,\n _positionLoc: gl.getAttribLocation(program, 'a_position'),\n _texCoordLoc: hasTexCoord ? gl.getAttribLocation(program, 'a_texCoord') : -1,\n };\n }\n\n private _compileShader(type: number, source: string): WebGLShader {\n const gl = this._gl;\n const shader = gl.createShader(type)!;\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n const info = gl.getShaderInfoLog(shader);\n gl.deleteShader(shader);\n throw new Error('Shader compile failed: ' + info);\n }\n return shader;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Utility\n// ---------------------------------------------------------------------------\n\n/** Extract numeric font size from a CSS font string like \"bold 20px monospace\". */\nfunction _parseFontSize(font: string): number {\n const match = font.match(/(\\d+(?:\\.\\d+)?)\\s*px/);\n return match ? parseFloat(match[1]) : 10;\n}\n\n/** Get width of a CanvasImageSource (handles HTMLImageElement, HTMLCanvasElement, OffscreenCanvas, etc.) */\nfunction _getImageWidth(img: CanvasImageSource): number {\n if ('naturalWidth' in img) return (img as HTMLImageElement).naturalWidth;\n return (img as HTMLCanvasElement | OffscreenCanvas).width;\n}\n\n/** Get height of a CanvasImageSource. */\nfunction _getImageHeight(img: CanvasImageSource): number {\n if ('naturalHeight' in img) return (img as HTMLImageElement).naturalHeight;\n return (img as HTMLCanvasElement | OffscreenCanvas).height;\n}\n","/**\n * UltrafastRenderer — WebGL2 Triple-Buffered Canvas 2D Renderer\n *\n * A standalone WebGL-accelerated Canvas 2D rendering engine. Provides a\n * CanvasAPI for recording draw commands and a triple-buffered FBO pipeline\n * that displays them via a passthrough shader at vsync rate.\n *\n * Triple buffer scheme (all on main thread, lock-free via JS single-threading):\n *\n * Content submission:\n * submitBatch(commands)\n * → bind writeFBO\n * → Canvas2DShim executes commands as WebGL draw calls\n * → swap: writeFBO ↔ readyFBO\n *\n * Display loop (vsync rate via RAF):\n * RAF callback\n * → auto-flush: drain CanvasAPI commands → submitBatch\n * → bind default framebuffer (display canvas)\n * → read readyFBO texture → passthrough blit → screen\n *\n * Extension points for downstream consumers (e.g. maalata CRT display):\n * - getGL(): access the WebGL2 context\n * - getReadyTexture(): read the latest rendered frame as a texture\n * - stopDisplay() / startDisplay(): take over the display loop\n */\n\nimport { CanvasAPI, type CanvasCommand } from './canvas-api';\nimport { Canvas2DShim } from './canvas2d-shim';\nimport { parseColor } from './color-parser';\nimport {\n PASSTHROUGH_VERTEX_SRC,\n PASSTHROUGH_FRAGMENT_SRC,\n} from './shaders';\n\ninterface _FBO {\n _fbo: WebGLFramebuffer;\n _texture: WebGLTexture;\n}\n\nexport class UltrafastRenderer {\n private _gl: WebGL2RenderingContext;\n private _canvas: HTMLCanvasElement;\n private _shim: Canvas2DShim;\n private _api: CanvasAPI;\n private _rafId: number | null = null;\n\n // Triple buffer: three FBOs with color texture attachments\n private _fbos!: [_FBO, _FBO, _FBO];\n private _writeIdx = 0;\n private _readyIdx = 1;\n private _displayIdx = 2;\n private _hasContent = false;\n\n // Background color for opaque canvas clear (default: black, backwards compatible)\n private _bgColor = new Float32Array([0, 0, 0]);\n\n // Display program\n private _passthroughProgram: WebGLProgram;\n\n // Fullscreen quad VBO\n private _quadVBO!: WebGLBuffer;\n private _quadPositionLoc = -1;\n\n constructor(canvas: HTMLCanvasElement) {\n this._canvas = canvas;\n this._api = new CanvasAPI();\n\n // Create WebGL2 context with optimizations\n const gl = canvas.getContext('webgl2', {\n alpha: false,\n antialias: false,\n desynchronized: true,\n preserveDrawingBuffer: true,\n powerPreference: 'high-performance',\n });\n\n if (!gl) {\n throw new Error('WebGL2 not supported');\n }\n this._gl = gl;\n\n gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);\n\n // Initialize triple buffer FBOs\n this._initFBOs();\n\n // Initialize Canvas 2D shim (uses same GL context)\n this._shim = new Canvas2DShim(gl, canvas.width, canvas.height);\n\n // Initialize passthrough display program\n this._passthroughProgram = this._createShaderProgram(\n PASSTHROUGH_VERTEX_SRC, PASSTHROUGH_FRAGMENT_SRC\n );\n\n // Initialize fullscreen quad VBO for display pass\n this._initQuadVBO();\n\n // Clear all FBOs initially\n this._clearAllFBOs();\n\n // Auto-detect background color from DOM ancestors\n this._resolveBackgroundColor();\n\n // Auto-start display loop\n this.startDisplay();\n }\n\n // -------------------------------------------------------------------------\n // Public API (no _ prefix: cross-file access safe from mangleProps)\n // -------------------------------------------------------------------------\n\n /** Get the CanvasAPI for recording draw commands. */\n getCanvasAPI(): CanvasAPI {\n return this._api;\n }\n\n /**\n * Submit a batch of Canvas 2D commands to be rendered into the write FBO.\n * After rendering, the write and ready FBOs are swapped so the display\n * loop picks up the latest frame.\n */\n submitBatch(commands: CanvasCommand[]): void {\n if (commands.length === 0) return;\n const gl = this._gl;\n\n // Bind write FBO as render target\n gl.bindFramebuffer(gl.FRAMEBUFFER, this._fbos[this._writeIdx]._fbo);\n gl.viewport(0, 0, this._canvas.width, this._canvas.height);\n\n // Execute Canvas 2D commands as WebGL draw calls\n this._shim.executeBatch(commands);\n\n // Swap write ↔ ready (new frame becomes available for display)\n const tmp = this._writeIdx;\n this._writeIdx = this._readyIdx;\n this._readyIdx = tmp;\n this._hasContent = true;\n }\n\n /** Start the passthrough RAF display loop with auto-flush. */\n startDisplay(): void {\n if (this._rafId !== null) return;\n this._displayLoop();\n }\n\n /** Stop the passthrough RAF display loop. Last frame persists (preserveDrawingBuffer). */\n stopDisplay(): void {\n if (this._rafId !== null) {\n cancelAnimationFrame(this._rafId);\n this._rafId = null;\n }\n }\n\n /** Returns the display canvas element. */\n getCanvas(): HTMLCanvasElement {\n return this._canvas;\n }\n\n /** Get canvas dimensions. */\n getCanvasSize(): { width: number; height: number } {\n return { width: this._canvas.width, height: this._canvas.height };\n }\n\n /** Capture the current displayed frame as an ImageBitmap. */\n screenshot(): Promise<ImageBitmap> {\n this._renderDisplay();\n return createImageBitmap(this._canvas);\n }\n\n /**\n * Set the opaque clear color used by clearRect and FBO initialization.\n * With alpha: false, cleared areas are opaque — this controls what color\n * they appear as instead of black. Values are in [0, 1] range.\n */\n setBackgroundColor(r: number, g: number, b: number): void {\n this._bgColor[0] = r;\n this._bgColor[1] = g;\n this._bgColor[2] = b;\n this._shim.setBackgroundColor(r, g, b);\n }\n\n /** Returns the current background color as [r, g, b] floats in [0, 1]. */\n getBackgroundColor(): [number, number, number] {\n return [this._bgColor[0], this._bgColor[1], this._bgColor[2]];\n }\n\n /** Clean up all WebGL resources. */\n destroy(): void {\n this.stopDisplay();\n const gl = this._gl;\n\n this._shim.destroy();\n\n for (const fbo of this._fbos) {\n gl.deleteFramebuffer(fbo._fbo);\n gl.deleteTexture(fbo._texture);\n }\n\n gl.deleteProgram(this._passthroughProgram);\n gl.deleteBuffer(this._quadVBO);\n\n const ext = gl.getExtension('WEBGL_lose_context');\n if (ext) ext.loseContext();\n }\n\n // -------------------------------------------------------------------------\n // Extension points (used by maalata CRT display)\n // -------------------------------------------------------------------------\n\n /** Returns the WebGL2 context for external rendering (e.g. CRT shader). */\n getGL(): WebGL2RenderingContext {\n return this._gl;\n }\n\n /** Returns the ready FBO's texture — the latest fully rendered frame. */\n getReadyTexture(): WebGLTexture {\n return this._fbos[this._readyIdx]._texture;\n }\n\n // -------------------------------------------------------------------------\n // Private: display loop\n // -------------------------------------------------------------------------\n\n private _displayLoop(): void {\n this._rafId = requestAnimationFrame(() => this._displayLoop());\n\n // Auto-flush: drain any pending CanvasAPI commands into the pipeline\n const cmds = this._api.takeCommands();\n if (cmds.length) this.submitBatch(cmds);\n\n this._renderDisplay();\n }\n\n /**\n * Render the ready FBO to the display canvas via passthrough shader.\n * Called at vsync rate by RAF, or once synchronously for screenshots.\n */\n private _renderDisplay(): void {\n if (!this._hasContent) return;\n\n const gl = this._gl;\n\n // Bind default framebuffer (display canvas backbuffer)\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n gl.viewport(0, 0, this._canvas.width, this._canvas.height);\n\n // Bind the ready FBO's texture as input\n gl.activeTexture(gl.TEXTURE0);\n gl.bindTexture(gl.TEXTURE_2D, this._fbos[this._readyIdx]._texture);\n\n gl.useProgram(this._passthroughProgram);\n\n // Draw fullscreen quad\n gl.bindBuffer(gl.ARRAY_BUFFER, this._quadVBO);\n gl.enableVertexAttribArray(this._quadPositionLoc);\n gl.vertexAttribPointer(this._quadPositionLoc, 2, gl.FLOAT, false, 0, 0);\n\n gl.disable(gl.BLEND);\n gl.drawArrays(gl.TRIANGLES, 0, 6);\n gl.enable(gl.BLEND);\n }\n\n // -------------------------------------------------------------------------\n // Private: initialization\n // -------------------------------------------------------------------------\n\n private _initFBOs(): void {\n this._fbos = [\n this._createFBO(),\n this._createFBO(),\n this._createFBO(),\n ];\n }\n\n private _createFBO(): _FBO {\n const gl = this._gl;\n const w = this._canvas.width;\n const h = this._canvas.height;\n\n const fbo = gl.createFramebuffer()!;\n gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);\n\n const texture = gl.createTexture()!;\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA8, w, h);\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\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);\n\n const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);\n if (status !== gl.FRAMEBUFFER_COMPLETE) {\n throw new Error('Framebuffer incomplete: 0x' + status.toString(16));\n }\n\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n return { _fbo: fbo, _texture: texture };\n }\n\n private _resolveBackgroundColor(): void {\n let el: HTMLElement | null = this._canvas.parentElement;\n while (el) {\n const bg = getComputedStyle(el).backgroundColor;\n if (bg && bg !== 'transparent' && bg !== 'rgba(0, 0, 0, 0)') {\n const c = parseColor(bg);\n if (c[3] > 0) {\n this.setBackgroundColor(c[0], c[1], c[2]);\n this._clearAllFBOs();\n return;\n }\n }\n el = el.parentElement;\n }\n\n // Fallback: white (browser default page background)\n this.setBackgroundColor(1, 1, 1);\n this._clearAllFBOs();\n }\n\n private _clearAllFBOs(): void {\n const gl = this._gl;\n const bg = this._bgColor;\n for (const fbo of this._fbos) {\n gl.bindFramebuffer(gl.FRAMEBUFFER, fbo._fbo);\n gl.clearColor(bg[0], bg[1], bg[2], 1);\n gl.clear(gl.COLOR_BUFFER_BIT);\n }\n gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n gl.clearColor(bg[0], bg[1], bg[2], 1);\n gl.clear(gl.COLOR_BUFFER_BIT);\n }\n\n private _initQuadVBO(): void {\n const gl = this._gl;\n\n this._quadVBO = gl.createBuffer()!;\n gl.bindBuffer(gl.ARRAY_BUFFER, this._quadVBO);\n gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([\n 0, 0, 1, 0, 0, 1,\n 0, 1, 1, 0, 1, 1,\n ]), gl.STATIC_DRAW);\n\n this._quadPositionLoc = gl.getAttribLocation(this._passthroughProgram, 'a_position');\n }\n\n // -------------------------------------------------------------------------\n // Private: shader helpers\n // -------------------------------------------------------------------------\n\n private _createShaderProgram(vSrc: string, fSrc: string): WebGLProgram {\n const gl = this._gl;\n const vs = this._compileShader(gl.VERTEX_SHADER, vSrc);\n const fs = this._compileShader(gl.FRAGMENT_SHADER, fSrc);\n\n const program = gl.createProgram()!;\n gl.attachShader(program, vs);\n gl.attachShader(program, fs);\n gl.linkProgram(program);\n\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n throw new Error('Shader link failed: ' + gl.getProgramInfoLog(program));\n }\n\n gl.deleteShader(vs);\n gl.deleteShader(fs);\n\n return program;\n }\n\n private _compileShader(type: number, source: string): WebGLShader {\n const gl = this._gl;\n const shader = gl.createShader(type)!;\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n const info = gl.getShaderInfoLog(shader);\n gl.deleteShader(shader);\n throw new Error('Shader compile failed: ' + info);\n }\n return shader;\n }\n}\n"],"names":["exports"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -223,6 +223,8 @@ export declare class UltrafastRenderer {
|
|
|
223
223
|
* they appear as instead of black. Values are in [0, 1] range.
|
|
224
224
|
*/
|
|
225
225
|
setBackgroundColor(r: number, g: number, b: number): void;
|
|
226
|
+
/** Returns the current background color as [r, g, b] floats in [0, 1]. */
|
|
227
|
+
getBackgroundColor(): [number, number, number];
|
|
226
228
|
/** Clean up all WebGL resources. */
|
|
227
229
|
destroy(): void;
|
|
228
230
|
/** Returns the WebGL2 context for external rendering (e.g. CRT shader). */
|
|
@@ -237,6 +239,7 @@ export declare class UltrafastRenderer {
|
|
|
237
239
|
private _renderDisplay;
|
|
238
240
|
private _initFBOs;
|
|
239
241
|
private _createFBO;
|
|
242
|
+
private _resolveBackgroundColor;
|
|
240
243
|
private _clearAllFBOs;
|
|
241
244
|
private _initQuadVBO;
|
|
242
245
|
private _createShaderProgram;
|