@oh-just-another/renderer-canvas 0.57.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/LICENSE +21 -0
  3. package/README.md +36 -0
  4. package/dist/.tsbuildinfo +1 -0
  5. package/dist/canvas-target.d.ts +83 -0
  6. package/dist/canvas-target.d.ts.map +1 -0
  7. package/dist/canvas-target.js +208 -0
  8. package/dist/canvas-target.js.map +1 -0
  9. package/dist/canvas-text-shaper.d.ts +11 -0
  10. package/dist/canvas-text-shaper.d.ts.map +1 -0
  11. package/dist/canvas-text-shaper.js +56 -0
  12. package/dist/canvas-text-shaper.js.map +1 -0
  13. package/dist/constants.d.ts +52 -0
  14. package/dist/constants.d.ts.map +1 -0
  15. package/dist/constants.js +52 -0
  16. package/dist/constants.js.map +1 -0
  17. package/dist/hi-dpi.d.ts +26 -0
  18. package/dist/hi-dpi.d.ts.map +1 -0
  19. package/dist/hi-dpi.js +62 -0
  20. package/dist/hi-dpi.js.map +1 -0
  21. package/dist/image-source.d.ts +3 -0
  22. package/dist/image-source.d.ts.map +1 -0
  23. package/dist/image-source.js +65 -0
  24. package/dist/image-source.js.map +1 -0
  25. package/dist/index.d.ts +15 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +24 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/layered-canvas.d.ts +46 -0
  30. package/dist/layered-canvas.d.ts.map +1 -0
  31. package/dist/layered-canvas.js +95 -0
  32. package/dist/layered-canvas.js.map +1 -0
  33. package/dist/layered-surface.d.ts +75 -0
  34. package/dist/layered-surface.d.ts.map +1 -0
  35. package/dist/layered-surface.js +262 -0
  36. package/dist/layered-surface.js.map +1 -0
  37. package/dist/offscreen.d.ts +30 -0
  38. package/dist/offscreen.d.ts.map +1 -0
  39. package/dist/offscreen.js +50 -0
  40. package/dist/offscreen.js.map +1 -0
  41. package/dist/recording-target.d.ts +203 -0
  42. package/dist/recording-target.d.ts.map +1 -0
  43. package/dist/recording-target.js +260 -0
  44. package/dist/recording-target.js.map +1 -0
  45. package/dist/render-worker.d.ts +2 -0
  46. package/dist/render-worker.d.ts.map +1 -0
  47. package/dist/render-worker.js +112 -0
  48. package/dist/render-worker.js.map +1 -0
  49. package/dist/tile-compositor.d.ts +44 -0
  50. package/dist/tile-compositor.d.ts.map +1 -0
  51. package/dist/tile-compositor.js +110 -0
  52. package/dist/tile-compositor.js.map +1 -0
  53. package/dist/webgl2-color.d.ts +13 -0
  54. package/dist/webgl2-color.d.ts.map +1 -0
  55. package/dist/webgl2-color.js +26 -0
  56. package/dist/webgl2-color.js.map +1 -0
  57. package/dist/webgl2-curve.d.ts +46 -0
  58. package/dist/webgl2-curve.d.ts.map +1 -0
  59. package/dist/webgl2-curve.js +162 -0
  60. package/dist/webgl2-curve.js.map +1 -0
  61. package/dist/webgl2-ellipse.d.ts +52 -0
  62. package/dist/webgl2-ellipse.d.ts.map +1 -0
  63. package/dist/webgl2-ellipse.js +171 -0
  64. package/dist/webgl2-ellipse.js.map +1 -0
  65. package/dist/webgl2-msdf-text.d.ts +84 -0
  66. package/dist/webgl2-msdf-text.d.ts.map +1 -0
  67. package/dist/webgl2-msdf-text.js +306 -0
  68. package/dist/webgl2-msdf-text.js.map +1 -0
  69. package/dist/webgl2-stroke.d.ts +52 -0
  70. package/dist/webgl2-stroke.d.ts.map +1 -0
  71. package/dist/webgl2-stroke.js +318 -0
  72. package/dist/webgl2-stroke.js.map +1 -0
  73. package/dist/webgl2-target.d.ts +311 -0
  74. package/dist/webgl2-target.d.ts.map +1 -0
  75. package/dist/webgl2-target.js +1368 -0
  76. package/dist/webgl2-target.js.map +1 -0
  77. package/dist/webgpu-detect.d.ts +30 -0
  78. package/dist/webgpu-detect.d.ts.map +1 -0
  79. package/dist/webgpu-detect.js +74 -0
  80. package/dist/webgpu-detect.js.map +1 -0
  81. package/package.json +67 -0
@@ -0,0 +1,262 @@
1
+ import { LAYER_ORDER } from "@oh-just-another/renderer-core";
2
+ import { LayeredCanvas } from "./layered-canvas.js";
3
+ import { WebGL2Target } from "./webgl2-target.js";
4
+ import { RecordingTarget } from "./recording-target.js";
5
+ import { setupHiDpiNoContext } from "./hi-dpi.js";
6
+ /**
7
+ * Factory entry point. Picks the right backend implementation, builds
8
+ * it, and returns the common `LayeredSurface` interface. Canvas2D is
9
+ * always safe; WebGL2 throws if the browser doesn't expose
10
+ * `getContext("webgl2")`; Offscreen throws if either `OffscreenCanvas`
11
+ * or `transferControlToOffscreen` is missing.
12
+ *
13
+ * The host (DiagramRoot) catches errors and falls back to `canvas2d`
14
+ * automatically when an opt-in backend isn't supported.
15
+ */
16
+ export const createLayeredSurface = (host, width, height, options = {}) => {
17
+ const backend = options.backend ?? "canvas2d";
18
+ switch (backend) {
19
+ case "canvas2d":
20
+ return new Canvas2DLayeredSurface(host, width, height);
21
+ case "webgl2":
22
+ return new WebGL2LayeredSurface(host, width, height);
23
+ case "offscreen":
24
+ if (!options.workerFactory) {
25
+ throw new Error("createLayeredSurface: workerFactory is required for the offscreen backend");
26
+ }
27
+ return new OffscreenLayeredSurface(host, width, height, options.workerFactory);
28
+ }
29
+ };
30
+ /**
31
+ * Build the requested surface and fall back to `canvas2d` if the
32
+ * opt-in backend throws (no WebGL2 / no OffscreenCanvas / per-page
33
+ * WebGL context limit hit). On fallback, `onFallback` is invoked
34
+ * with the original error so the host can surface a toast / log.
35
+ *
36
+ * Use this when the backend is user-controlled (demo dropdown,
37
+ * URL param) so a misclick doesn't crash the React tree. Hosts
38
+ * that want hard failures should call `createLayeredSurface`
39
+ * directly and handle the throw themselves.
40
+ */
41
+ export const createLayeredSurfaceWithFallback = (host, width, height, options = {}, onFallback) => {
42
+ const requested = options.backend ?? "canvas2d";
43
+ try {
44
+ return { surface: createLayeredSurface(host, width, height, options), effectiveBackend: requested };
45
+ }
46
+ catch (err) {
47
+ if (requested === "canvas2d")
48
+ throw err;
49
+ onFallback?.(requested, err);
50
+ return {
51
+ surface: createLayeredSurface(host, width, height, { ...options, backend: "canvas2d" }),
52
+ effectiveBackend: "canvas2d",
53
+ };
54
+ }
55
+ };
56
+ /** Canvas2D surface — wraps `LayeredCanvas` (3× Canvas2DTarget). */
57
+ class Canvas2DLayeredSurface {
58
+ backend = "canvas2d";
59
+ inner;
60
+ constructor(host, width, height) {
61
+ this.inner = new LayeredCanvas(host, width, height);
62
+ }
63
+ get(name) {
64
+ return this.inner.get(name);
65
+ }
66
+ getCanvas(name) {
67
+ return this.inner.getCanvas(name);
68
+ }
69
+ resize(width, height) {
70
+ this.inner.resize(width, height);
71
+ }
72
+ get size() {
73
+ return this.inner.size;
74
+ }
75
+ present() {
76
+ // No-op — Canvas2D paints synchronously.
77
+ }
78
+ dispose() {
79
+ this.inner.dispose();
80
+ }
81
+ }
82
+ /**
83
+ * WebGL2 surface — hybrid: GPU only for the heavy `main` layer;
84
+ * `overlay` / `background` stay on Canvas2D.
85
+ *
86
+ * Overlay paints handles / selection halo / port hints — a few dozen
87
+ * primitives per frame, trivially fast in Canvas2D. Background paints
88
+ * the grid — a repeating rect, also Canvas2D-cheap. Giving each its own
89
+ * WebGL2 context would triple GL state churn, triple GPU memory, and
90
+ * triple the chance of hitting the browser's per-page WebGL context cap
91
+ * (~16 in Chrome).
92
+ */
93
+ class WebGL2LayeredSurface {
94
+ backend = "webgl2";
95
+ /** Canvas2D layered for overlay + background. */
96
+ base;
97
+ /** WebGL2 only for `main`. */
98
+ mainCanvas;
99
+ mainTarget;
100
+ _width;
101
+ _height;
102
+ constructor(host, width, height) {
103
+ this._width = width;
104
+ this._height = height;
105
+ // Build the Canvas2D layers first; the WebGL2 main canvas is
106
+ // spliced into the same stack between background and overlay.
107
+ this.base = new LayeredCanvas(host, width, height, {
108
+ layers: LAYER_ORDER.filter((name) => name !== "main"),
109
+ });
110
+ const overlay = this.base.getCanvas("overlay");
111
+ const canvas = host.ownerDocument.createElement("canvas");
112
+ canvas.dataset.layer = "main";
113
+ canvas.dataset.backend = "webgl2";
114
+ canvas.style.position = "absolute";
115
+ canvas.style.inset = "0";
116
+ canvas.style.pointerEvents = "none";
117
+ // Insert main before overlay so overlay sits on top in z-order.
118
+ host.insertBefore(canvas, overlay);
119
+ // Never call `getContext("2d")` on this canvas: the WebGL2 slot is
120
+ // exclusive — one canvas, one context kind, for the life of the
121
+ // element. `setupHiDpiNoContext` sizes the bitmap without touching
122
+ // the context.
123
+ setupHiDpiNoContext(canvas, width, height);
124
+ try {
125
+ this.mainCanvas = canvas;
126
+ this.mainTarget = new WebGL2Target(canvas, width, height);
127
+ }
128
+ catch (err) {
129
+ canvas.remove();
130
+ this.base.dispose();
131
+ throw err;
132
+ }
133
+ }
134
+ get(name) {
135
+ if (name === "main")
136
+ return this.mainTarget;
137
+ return this.base.get(name);
138
+ }
139
+ getCanvas(name) {
140
+ if (name === "main")
141
+ return this.mainCanvas;
142
+ return this.base.getCanvas(name);
143
+ }
144
+ resize(width, height) {
145
+ if (this._width === width && this._height === height)
146
+ return;
147
+ this._width = width;
148
+ this._height = height;
149
+ this.base.resize(width, height);
150
+ setupHiDpiNoContext(this.mainCanvas, width, height);
151
+ this.mainTarget.resize(width, height);
152
+ }
153
+ get size() {
154
+ return { width: this._width, height: this._height };
155
+ }
156
+ present() {
157
+ // Canvas2D + WebGL2 both paint synchronously — nothing to flush.
158
+ }
159
+ dispose() {
160
+ this.mainTarget.dispose();
161
+ this.mainCanvas.remove();
162
+ this.base.dispose();
163
+ }
164
+ }
165
+ /**
166
+ * Offscreen surface — main-thread `RecordingTarget` per layer + a
167
+ * dedicated worker per layer that owns the transferred OffscreenCanvas
168
+ * and replays the buffered command stream on each `present()`.
169
+ *
170
+ * Trade-offs:
171
+ * • Latency: every `present()` posts one message per layer; on
172
+ * desktop browsers this is sub-millisecond, but interactive
173
+ * overlay (pointer-following handles) sees one rAF of delay
174
+ * because the worker draws after the main thread yields.
175
+ * • Memory: 3× workers, each owning a DPR-sized OffscreenCanvas.
176
+ * • drawImage is silently skipped — see `RecordingTarget` docs.
177
+ */
178
+ class OffscreenLayeredSurface {
179
+ backend = "offscreen";
180
+ canvases = new Map();
181
+ targets = new Map();
182
+ workers = new Map();
183
+ _width;
184
+ _height;
185
+ dpr;
186
+ constructor(host, width, height, workerFactory) {
187
+ this._width = width;
188
+ this._height = height;
189
+ this.dpr = typeof window !== "undefined" ? window.devicePixelRatio || 1 : 1;
190
+ if (getComputedStyle(host).position === "static") {
191
+ host.style.position = "relative";
192
+ }
193
+ try {
194
+ for (const name of LAYER_ORDER) {
195
+ const canvas = host.ownerDocument.createElement("canvas");
196
+ canvas.dataset.layer = name;
197
+ canvas.dataset.backend = "offscreen";
198
+ canvas.style.position = "absolute";
199
+ canvas.style.inset = "0";
200
+ canvas.style.pointerEvents = name === "overlay" ? "auto" : "none";
201
+ canvas.style.width = `${width}px`;
202
+ canvas.style.height = `${height}px`;
203
+ host.appendChild(canvas);
204
+ const worker = workerFactory();
205
+ const offscreen = canvas.transferControlToOffscreen();
206
+ worker.postMessage({ type: "init", canvas: offscreen, width, height, dpr: this.dpr }, [offscreen]);
207
+ this.canvases.set(name, canvas);
208
+ this.workers.set(name, worker);
209
+ this.targets.set(name, new RecordingTarget(width, height));
210
+ }
211
+ }
212
+ catch (err) {
213
+ this.dispose();
214
+ throw err;
215
+ }
216
+ }
217
+ get(name) {
218
+ const t = this.targets.get(name);
219
+ if (!t)
220
+ throw new Error(`Layer not created: ${name}`);
221
+ return t;
222
+ }
223
+ getCanvas(name) {
224
+ const c = this.canvases.get(name);
225
+ if (!c)
226
+ throw new Error(`Layer not created: ${name}`);
227
+ return c;
228
+ }
229
+ resize(width, height) {
230
+ if (this._width === width && this._height === height)
231
+ return;
232
+ this._width = width;
233
+ this._height = height;
234
+ for (const [name, canvas] of this.canvases) {
235
+ canvas.style.width = `${width}px`;
236
+ canvas.style.height = `${height}px`;
237
+ this.targets.get(name)?.resize(width, height);
238
+ this.workers.get(name)?.postMessage({ type: "resize", width, height });
239
+ }
240
+ }
241
+ get size() {
242
+ return { width: this._width, height: this._height };
243
+ }
244
+ present() {
245
+ for (const [name, target] of this.targets) {
246
+ const cmds = target.flush();
247
+ if (cmds.length === 0)
248
+ continue;
249
+ this.workers.get(name)?.postMessage({ type: "replay", commands: cmds });
250
+ }
251
+ }
252
+ dispose() {
253
+ for (const worker of this.workers.values())
254
+ worker.terminate();
255
+ for (const canvas of this.canvases.values())
256
+ canvas.remove();
257
+ this.workers.clear();
258
+ this.canvases.clear();
259
+ this.targets.clear();
260
+ }
261
+ }
262
+ //# sourceMappingURL=layered-surface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layered-surface.js","sourceRoot":"","sources":["../src/layered-surface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAqC,MAAM,gCAAgC,CAAC;AAChG,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAiDlD;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAClC,IAAiB,EACjB,KAAa,EACb,MAAc,EACd,UAAuC,EAAE,EACzB,EAAE;IAClB,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,UAAU,CAAC;IAC9C,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,UAAU;YACb,OAAO,IAAI,sBAAsB,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QACzD,KAAK,QAAQ;YACX,OAAO,IAAI,oBAAoB,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QACvD,KAAK,WAAW;YACd,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;gBAC3B,MAAM,IAAI,KAAK,CACb,2EAA2E,CAC5E,CAAC;YACJ,CAAC;YACD,OAAO,IAAI,uBAAuB,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;IACnF,CAAC;AACH,CAAC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,gCAAgC,GAAG,CAC9C,IAAiB,EACjB,KAAa,EACb,MAAc,EACd,UAAuC,EAAE,EACzC,UAA+D,EACC,EAAE;IAClE,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,IAAI,UAAU,CAAC;IAChD,IAAI,CAAC;QACH,OAAO,EAAE,OAAO,EAAE,oBAAoB,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,EAAE,SAAS,EAAE,CAAC;IACtG,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,SAAS,KAAK,UAAU;YAAE,MAAM,GAAG,CAAC;QACxC,UAAU,EAAE,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;QAC7B,OAAO;YACL,OAAO,EAAE,oBAAoB,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC;YACvF,gBAAgB,EAAE,UAAU;SAC7B,CAAC;IACJ,CAAC;AACH,CAAC,CAAC;AAEF,oEAAoE;AACpE,MAAM,sBAAsB;IACjB,OAAO,GAAG,UAAmB,CAAC;IACtB,KAAK,CAAgB;IAEtC,YAAY,IAAiB,EAAE,KAAa,EAAE,MAAc;QAC1D,IAAI,CAAC,KAAK,GAAG,IAAI,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACtD,CAAC;IAED,GAAG,CAAC,IAAe;QACjB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IACD,SAAS,CAAC,IAAe;QACvB,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;IACD,MAAM,CAAC,KAAa,EAAE,MAAc;QAClC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACnC,CAAC;IACD,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;IACzB,CAAC;IACD,OAAO;QACL,yCAAyC;IAC3C,CAAC;IACD,OAAO;QACL,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;IACvB,CAAC;CACF;AAED;;;;;;;;;;GAUG;AACH,MAAM,oBAAoB;IACf,OAAO,GAAG,QAAiB,CAAC;IACrC,iDAAiD;IAChC,IAAI,CAAgB;IACrC,8BAA8B;IACb,UAAU,CAAoB;IAC9B,UAAU,CAAe;IAClC,MAAM,CAAS;IACf,OAAO,CAAS;IAExB,YAAY,IAAiB,EAAE,KAAa,EAAE,MAAc;QAC1D,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,6DAA6D;QAC7D,8DAA8D;QAC9D,IAAI,CAAC,IAAI,GAAG,IAAI,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE;YACjD,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,IAAI,EAAoC,EAAE,CAAC,IAAI,KAAK,MAAM,CAAC;SACxF,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC1D,MAAM,CAAC,OAAO,CAAC,KAAK,GAAG,MAAM,CAAC;QAC9B,MAAM,CAAC,OAAO,CAAC,OAAO,GAAG,QAAQ,CAAC;QAClC,MAAM,CAAC,KAAK,CAAC,QAAQ,GAAG,UAAU,CAAC;QACnC,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC;QACzB,MAAM,CAAC,KAAK,CAAC,aAAa,GAAG,MAAM,CAAC;QACpC,gEAAgE;QAChE,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACnC,mEAAmE;QACnE,gEAAgE;QAChE,mEAAmE;QACnE,eAAe;QACf,mBAAmB,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QAC3C,IAAI,CAAC;YACH,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC;YACzB,IAAI,CAAC,UAAU,GAAG,IAAI,YAAY,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QAC5D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED,GAAG,CAAC,IAAe;QACjB,IAAI,IAAI,KAAK,MAAM;YAAE,OAAO,IAAI,CAAC,UAAU,CAAC;QAC5C,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IACD,SAAS,CAAC,IAAe;QACvB,IAAI,IAAI,KAAK,MAAM;YAAE,OAAO,IAAI,CAAC,UAAU,CAAC;QAC5C,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC;IACD,MAAM,CAAC,KAAa,EAAE,MAAc;QAClC,IAAI,IAAI,CAAC,MAAM,KAAK,KAAK,IAAI,IAAI,CAAC,OAAO,KAAK,MAAM;YAAE,OAAO;QAC7D,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAChC,mBAAmB,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QACpD,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACxC,CAAC;IACD,IAAI,IAAI;QACN,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC;IACtD,CAAC;IACD,OAAO;QACL,iEAAiE;IACnE,CAAC;IACD,OAAO;QACL,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;QAC1B,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;IACtB,CAAC;CACF;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,uBAAuB;IAClB,OAAO,GAAG,WAAoB,CAAC;IACvB,QAAQ,GAAG,IAAI,GAAG,EAAgC,CAAC;IACnD,OAAO,GAAG,IAAI,GAAG,EAA8B,CAAC;IAChD,OAAO,GAAG,IAAI,GAAG,EAAqB,CAAC;IAChD,MAAM,CAAS;IACf,OAAO,CAAS;IACP,GAAG,CAAS;IAE7B,YACE,IAAiB,EACjB,KAAa,EACb,MAAc,EACd,aAA2B;QAE3B,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,IAAI,CAAC,GAAG,GAAG,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,gBAAgB,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAE5E,IAAI,gBAAgB,CAAC,IAAI,CAAC,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACjD,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,UAAU,CAAC;QACnC,CAAC;QAED,IAAI,CAAC;YACH,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;gBAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;gBAC1D,MAAM,CAAC,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;gBAC5B,MAAM,CAAC,OAAO,CAAC,OAAO,GAAG,WAAW,CAAC;gBACrC,MAAM,CAAC,KAAK,CAAC,QAAQ,GAAG,UAAU,CAAC;gBACnC,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC;gBACzB,MAAM,CAAC,KAAK,CAAC,aAAa,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;gBAClE,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,KAAK,IAAI,CAAC;gBAClC,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC;gBACpC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;gBAEzB,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;gBAC/B,MAAM,SAAS,GAAG,MAAM,CAAC,0BAA0B,EAAE,CAAC;gBACtD,MAAM,CAAC,WAAW,CAChB,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,EACjE,CAAC,SAAS,CAAC,CACZ,CAAC;gBAEF,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBAChC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBAC/B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;YAC7D,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED,GAAG,CAAC,IAAe;QACjB,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACjC,IAAI,CAAC,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,IAAI,EAAE,CAAC,CAAC;QACtD,OAAO,CAAC,CAAC;IACX,CAAC;IACD,SAAS,CAAC,IAAe;QACvB,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,CAAC,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,IAAI,EAAE,CAAC,CAAC;QACtD,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,CAAC,KAAa,EAAE,MAAc;QAClC,IAAI,IAAI,CAAC,MAAM,KAAK,KAAK,IAAI,IAAI,CAAC,OAAO,KAAK,MAAM;YAAE,OAAO;QAC7D,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC3C,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,KAAK,IAAI,CAAC;YAClC,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC;YACpC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAC9C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;IACD,IAAI,IAAI;QACN,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC;IACtD,CAAC;IACD,OAAO;QACL,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAC1C,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;YAC5B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAS;YAChC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1E,CAAC;IACH,CAAC;IACD,OAAO;QACL,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE;YAAE,MAAM,CAAC,SAAS,EAAE,CAAC;QAC/D,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE;YAAE,MAAM,CAAC,MAAM,EAAE,CAAC;QAC7D,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACrB,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;CACF"}
@@ -0,0 +1,30 @@
1
+ import { Canvas2DTarget } from "./canvas-target.js";
2
+ /**
3
+ * Browser-feature detection. `true` when both `OffscreenCanvas` and the
4
+ * `transferControlToOffscreen` upgrade path on `HTMLCanvasElement` are
5
+ * available. False in Safari < 16.4 and in test environments without a
6
+ * canvas implementation — callers should fall back to the on-main
7
+ * `Canvas2DTarget` in that case.
8
+ */
9
+ export declare const supportsOffscreenCanvas: () => boolean;
10
+ /**
11
+ * Build a `Canvas2DTarget` backed by a fresh `OffscreenCanvas`. The CSS
12
+ * dimensions match the bitmap (no DPR scaling here — callers that want
13
+ * crisp output on hi-DPI displays should size the bitmap by `dpr` and
14
+ * pass a pre-scaled transform to draw calls).
15
+ */
16
+ export declare const createOffscreenCanvas2DTarget: (width: number, height: number) => {
17
+ readonly canvas: OffscreenCanvas;
18
+ readonly target: Canvas2DTarget;
19
+ };
20
+ /**
21
+ * Transfer a canvas's rendering ownership to a worker. The returned
22
+ * `OffscreenCanvas` is now controlled by the worker (the host can no
23
+ * longer get a 2D context on the same element). Posts the offscreen
24
+ * to the worker via `worker.postMessage(msg, [offscreen])`.
25
+ *
26
+ * Throws when offscreen is unsupported — guard with
27
+ * `supportsOffscreenCanvas()` before calling.
28
+ */
29
+ export declare const transferCanvasToWorker: (canvas: HTMLCanvasElement, worker: Worker, initMessage?: Record<string, unknown>) => OffscreenCanvas;
30
+ //# sourceMappingURL=offscreen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"offscreen.d.ts","sourceRoot":"","sources":["../src/offscreen.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,QAAO,OAI1C,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B,GACxC,OAAO,MAAM,EACb,QAAQ,MAAM,KACb;IAAE,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAA;CASrE,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,GACjC,QAAQ,iBAAiB,EACzB,QAAQ,MAAM,EACd,cAAa,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,KACxC,eAOF,CAAC"}
@@ -0,0 +1,50 @@
1
+ import { Canvas2DTarget } from "./canvas-target.js";
2
+ /**
3
+ * Browser-feature detection. `true` when both `OffscreenCanvas` and the
4
+ * `transferControlToOffscreen` upgrade path on `HTMLCanvasElement` are
5
+ * available. False in Safari < 16.4 and in test environments without a
6
+ * canvas implementation — callers should fall back to the on-main
7
+ * `Canvas2DTarget` in that case.
8
+ */
9
+ export const supportsOffscreenCanvas = () => {
10
+ if (typeof OffscreenCanvas === "undefined")
11
+ return false;
12
+ if (typeof HTMLCanvasElement === "undefined")
13
+ return false;
14
+ return typeof HTMLCanvasElement.prototype.transferControlToOffscreen === "function";
15
+ };
16
+ /**
17
+ * Build a `Canvas2DTarget` backed by a fresh `OffscreenCanvas`. The CSS
18
+ * dimensions match the bitmap (no DPR scaling here — callers that want
19
+ * crisp output on hi-DPI displays should size the bitmap by `dpr` and
20
+ * pass a pre-scaled transform to draw calls).
21
+ */
22
+ export const createOffscreenCanvas2DTarget = (width, height) => {
23
+ const canvas = new OffscreenCanvas(width, height);
24
+ const ctx = canvas.getContext("2d");
25
+ if (!ctx)
26
+ throw new Error("OffscreenCanvas 2D context unavailable");
27
+ // The OffscreenCanvasRenderingContext2D API is a superset of the
28
+ // 2D path / state / text methods Canvas2DTarget calls, so the cast
29
+ // relies on structural compatibility.
30
+ const target = new Canvas2DTarget(ctx, width, height);
31
+ return { canvas, target };
32
+ };
33
+ /**
34
+ * Transfer a canvas's rendering ownership to a worker. The returned
35
+ * `OffscreenCanvas` is now controlled by the worker (the host can no
36
+ * longer get a 2D context on the same element). Posts the offscreen
37
+ * to the worker via `worker.postMessage(msg, [offscreen])`.
38
+ *
39
+ * Throws when offscreen is unsupported — guard with
40
+ * `supportsOffscreenCanvas()` before calling.
41
+ */
42
+ export const transferCanvasToWorker = (canvas, worker, initMessage = {}) => {
43
+ if (!supportsOffscreenCanvas()) {
44
+ throw new Error("OffscreenCanvas not supported in this environment");
45
+ }
46
+ const offscreen = canvas.transferControlToOffscreen();
47
+ worker.postMessage({ type: "init", canvas: offscreen, ...initMessage }, [offscreen]);
48
+ return offscreen;
49
+ };
50
+ //# sourceMappingURL=offscreen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"offscreen.js","sourceRoot":"","sources":["../src/offscreen.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAY,EAAE;IACnD,IAAI,OAAO,eAAe,KAAK,WAAW;QAAE,OAAO,KAAK,CAAC;IACzD,IAAI,OAAO,iBAAiB,KAAK,WAAW;QAAE,OAAO,KAAK,CAAC;IAC3D,OAAO,OAAO,iBAAiB,CAAC,SAAS,CAAC,0BAA0B,KAAK,UAAU,CAAC;AACtF,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAC3C,KAAa,EACb,MAAc,EACyD,EAAE;IACzE,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAClD,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IACpC,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;IACpE,iEAAiE;IACjE,mEAAmE;IACnE,sCAAsC;IACtC,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC,GAA0C,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAC7F,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAC5B,CAAC,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CACpC,MAAyB,EACzB,MAAc,EACd,cAAuC,EAAE,EACxB,EAAE;IACnB,IAAI,CAAC,uBAAuB,EAAE,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACvE,CAAC;IACD,MAAM,SAAS,GAAG,MAAM,CAAC,0BAA0B,EAAE,CAAC;IACtD,MAAM,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,WAAW,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;IACrF,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC"}
@@ -0,0 +1,203 @@
1
+ import type { Bounds, Color, Transform } from "@oh-just-another/types";
2
+ import type { FillRule, LineCap, LineJoin, RenderTarget, TextAlign, TextBaseline } from "@oh-just-another/renderer-core";
3
+ /**
4
+ * Backend-agnostic RenderTarget that captures every method call as a
5
+ * structured command. Powers the "offscreen" pipeline: the main thread
6
+ * renders into a RecordingTarget, the resulting buffer is shipped to a
7
+ * worker via postMessage, and the worker replays the commands onto its
8
+ * OffscreenCanvas.
9
+ *
10
+ * Commands are a tagged union of primitive payloads (no class
11
+ * instances) so they survive `structuredClone` cleanly across the
12
+ * worker boundary. `flush()` returns the buffered commands and resets
13
+ * the internal log.
14
+ */
15
+ export type RenderCommand = {
16
+ readonly k: "setFill";
17
+ readonly color: Color | null;
18
+ } | {
19
+ readonly k: "setStroke";
20
+ readonly color: Color | null;
21
+ } | {
22
+ readonly k: "setStrokeWidth";
23
+ readonly w: number;
24
+ } | {
25
+ readonly k: "setOpacity";
26
+ readonly a: number;
27
+ } | {
28
+ readonly k: "setLineCap";
29
+ readonly cap: LineCap;
30
+ } | {
31
+ readonly k: "setLineJoin";
32
+ readonly join: LineJoin;
33
+ } | {
34
+ readonly k: "setDashArray";
35
+ readonly dash: readonly number[] | null;
36
+ } | {
37
+ readonly k: "setFont";
38
+ readonly family: string;
39
+ readonly size: number;
40
+ readonly options?: {
41
+ readonly weight?: "normal" | "bold";
42
+ readonly style?: "normal" | "italic";
43
+ };
44
+ } | {
45
+ readonly k: "setTextAlign";
46
+ readonly align: TextAlign;
47
+ } | {
48
+ readonly k: "setTextBaseline";
49
+ readonly baseline: TextBaseline;
50
+ } | {
51
+ readonly k: "save";
52
+ } | {
53
+ readonly k: "restore";
54
+ } | {
55
+ readonly k: "translate";
56
+ readonly x: number;
57
+ readonly y: number;
58
+ } | {
59
+ readonly k: "rotate";
60
+ readonly r: number;
61
+ } | {
62
+ readonly k: "scale";
63
+ readonly sx: number;
64
+ readonly sy: number;
65
+ } | {
66
+ readonly k: "setTransform";
67
+ readonly t: Transform;
68
+ } | {
69
+ readonly k: "resetTransform";
70
+ } | {
71
+ readonly k: "beginPath";
72
+ } | {
73
+ readonly k: "closePath";
74
+ } | {
75
+ readonly k: "moveTo";
76
+ readonly x: number;
77
+ readonly y: number;
78
+ } | {
79
+ readonly k: "lineTo";
80
+ readonly x: number;
81
+ readonly y: number;
82
+ } | {
83
+ readonly k: "quadraticCurveTo";
84
+ readonly cx: number;
85
+ readonly cy: number;
86
+ readonly x: number;
87
+ readonly y: number;
88
+ } | {
89
+ readonly k: "bezierCurveTo";
90
+ readonly c1x: number;
91
+ readonly c1y: number;
92
+ readonly c2x: number;
93
+ readonly c2y: number;
94
+ readonly x: number;
95
+ readonly y: number;
96
+ } | {
97
+ readonly k: "rect";
98
+ readonly x: number;
99
+ readonly y: number;
100
+ readonly w: number;
101
+ readonly h: number;
102
+ } | {
103
+ readonly k: "ellipse";
104
+ readonly cx: number;
105
+ readonly cy: number;
106
+ readonly rx: number;
107
+ readonly ry: number;
108
+ } | {
109
+ readonly k: "fill";
110
+ readonly rule?: FillRule;
111
+ } | {
112
+ readonly k: "stroke";
113
+ } | {
114
+ readonly k: "fillText";
115
+ readonly text: string;
116
+ readonly x: number;
117
+ readonly y: number;
118
+ readonly maxWidth?: number;
119
+ } | {
120
+ readonly k: "clear";
121
+ readonly bounds?: Bounds;
122
+ } | {
123
+ readonly k: "markDirty";
124
+ readonly bounds: Bounds;
125
+ } | {
126
+ readonly k: "resize";
127
+ readonly w: number;
128
+ readonly h: number;
129
+ };
130
+ /**
131
+ * `drawImage` is NOT serialisable through this command stream — image
132
+ * sources (HTMLImageElement, ImageBitmap, HTMLCanvasElement) either
133
+ * can't cross the postMessage boundary cleanly or require expensive
134
+ * transfers. The recording target silently skips `drawImage` calls and
135
+ * counts them in `skippedImageDraws` so the host UI can warn (or fall
136
+ * back to main-thread compositing for image-heavy scenes).
137
+ *
138
+ * `measureText` returns a synchronous heuristic — the worker has the
139
+ * authoritative measurement, but routing per-call is too chatty. Hosts
140
+ * that care about pixel-perfect text in offscreen mode should
141
+ * pre-measure on a sidecar text shaper.
142
+ */
143
+ export declare class RecordingTarget implements RenderTarget {
144
+ private commands;
145
+ private _width;
146
+ private _height;
147
+ /** Counter so hosts can warn when images are silently skipped. */
148
+ skippedImageDraws: number;
149
+ constructor(width: number, height: number);
150
+ get size(): {
151
+ readonly width: number;
152
+ readonly height: number;
153
+ };
154
+ resize(width: number, height: number): void;
155
+ /** Pop the buffered commands and clear the internal log. */
156
+ flush(): readonly RenderCommand[];
157
+ /** Snapshot of the buffered commands without clearing. */
158
+ peek(): readonly RenderCommand[];
159
+ setFill(color: Color | null): void;
160
+ setStroke(color: Color | null): void;
161
+ setStrokeWidth(w: number): void;
162
+ setOpacity(a: number): void;
163
+ setLineCap(cap: LineCap): void;
164
+ setLineJoin(join: LineJoin): void;
165
+ setDashArray(dash: readonly number[] | null): void;
166
+ setFont(family: string, size: number, options?: {
167
+ weight?: "normal" | "bold";
168
+ style?: "normal" | "italic";
169
+ }): void;
170
+ setTextAlign(align: TextAlign): void;
171
+ setTextBaseline(baseline: TextBaseline): void;
172
+ save(): void;
173
+ restore(): void;
174
+ translate(x: number, y: number): void;
175
+ rotate(r: number): void;
176
+ scale(sx: number, sy: number): void;
177
+ setTransform(t: Transform): void;
178
+ resetTransform(): void;
179
+ beginPath(): void;
180
+ closePath(): void;
181
+ moveTo(x: number, y: number): void;
182
+ lineTo(x: number, y: number): void;
183
+ quadraticCurveTo(cx: number, cy: number, x: number, y: number): void;
184
+ bezierCurveTo(c1x: number, c1y: number, c2x: number, c2y: number, x: number, y: number): void;
185
+ rect(x: number, y: number, w: number, h: number): void;
186
+ ellipse(cx: number, cy: number, rx: number, ry: number): void;
187
+ fill(rule?: FillRule): void;
188
+ stroke(): void;
189
+ fillText(text: string, x: number, y: number, maxWidth?: number): void;
190
+ measureText(text: string): {
191
+ width: number;
192
+ };
193
+ drawImage(_image: unknown, _dx: number, _dy: number, _dw: number, _dh: number): void;
194
+ clear(bounds?: Bounds): void;
195
+ markDirty(bounds: Bounds): void;
196
+ }
197
+ /**
198
+ * Replay a previously-flushed command buffer onto a real RenderTarget.
199
+ * Used by the worker entry point to apply commands shipped from the
200
+ * main thread.
201
+ */
202
+ export declare const replayCommands: (target: RenderTarget, commands: readonly RenderCommand[]) => void;
203
+ //# sourceMappingURL=recording-target.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recording-target.d.ts","sourceRoot":"","sources":["../src/recording-target.ts"],"names":[],"mappings":"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"}