xbintsc 0.5.38 → 0.5.41

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 (117) hide show
  1. package/dist/src/cli/help.d.ts +1 -1
  2. package/dist/src/codegen/generator/module.js +23 -7
  3. package/dist/src/codegen/generator/module.js.map +1 -1
  4. package/dist/src/driver/version.d.ts +1 -1
  5. package/dist/src/driver/version.js +1 -1
  6. package/dist/src/extensions/gui/html.js +9 -2
  7. package/dist/src/extensions/gui/html.js.map +1 -1
  8. package/dist/tests/codegen/closures.test.js +7 -0
  9. package/dist/tests/codegen/closures.test.js.map +1 -1
  10. package/dist/tests/e2e/compile-objects-classes.test.js +31 -0
  11. package/dist/tests/e2e/compile-objects-classes.test.js.map +1 -1
  12. package/dist/tests/e2e/gui-canvas-state.test.d.ts +9 -0
  13. package/dist/tests/e2e/gui-canvas-state.test.js +297 -0
  14. package/dist/tests/e2e/gui-canvas-state.test.js.map +1 -0
  15. package/dist/tests/e2e/gui-draw-perf.test.d.ts +22 -0
  16. package/dist/tests/e2e/gui-draw-perf.test.js +405 -0
  17. package/dist/tests/e2e/gui-draw-perf.test.js.map +1 -0
  18. package/dist/tests/e2e/gui-perf.test.d.ts +23 -0
  19. package/dist/tests/e2e/gui-perf.test.js +283 -0
  20. package/dist/tests/e2e/gui-perf.test.js.map +1 -0
  21. package/dist/tests/e2e/gui-script-import-order.test.js +9 -1
  22. package/dist/tests/e2e/gui-script-import-order.test.js.map +1 -1
  23. package/dist/tests/e2e/gui-webgl.test.js +4 -4
  24. package/dist/tests/e2e/gui-webgl.test.js.map +1 -1
  25. package/dist/tests/e2e/gui-webgl2-shadow-sampler.test.d.ts +8 -0
  26. package/dist/tests/e2e/gui-webgl2-shadow-sampler.test.js +336 -0
  27. package/dist/tests/e2e/gui-webgl2-shadow-sampler.test.js.map +1 -0
  28. package/dist/tests/extensions/gui.test.js +23 -0
  29. package/dist/tests/extensions/gui.test.js.map +1 -1
  30. package/doc/gui/api.md +28 -2
  31. package/doc/gui/canvas.md +110 -27
  32. package/doc/gui/known-issues.md +32 -10
  33. package/doc/gui/rendering.md +77 -0
  34. package/doc/gui/runtime.md +18 -3
  35. package/doc/gui/webgl.md +38 -19
  36. package/doc/gui.md +33 -1
  37. package/doc/zh-CN/gui/api.md +25 -2
  38. package/doc/zh-CN/gui/canvas.md +95 -26
  39. package/doc/zh-CN/gui/known-issues.md +21 -4
  40. package/doc/zh-CN/gui/rendering.md +59 -0
  41. package/doc/zh-CN/gui/runtime.md +13 -3
  42. package/doc/zh-CN/gui/webgl.md +27 -5
  43. package/doc/zh-CN/gui.md +25 -2
  44. package/package.json +7 -7
  45. package/runtime/ext_gui/browser.cpp +3 -1
  46. package/runtime/ext_gui/canvas.cpp +135 -89
  47. package/runtime/ext_gui/canvas.h +116 -0
  48. package/runtime/ext_gui/canvas_clip.cpp +143 -0
  49. package/runtime/ext_gui/canvas_composite.cpp +241 -0
  50. package/runtime/ext_gui/canvas_coverage.cpp +241 -0
  51. package/runtime/ext_gui/canvas_gradient.cpp +41 -4
  52. package/runtime/ext_gui/canvas_image_data.cpp +4 -0
  53. package/runtime/ext_gui/canvas_internal.h +34 -9
  54. package/runtime/ext_gui/canvas_raster.cpp +207 -178
  55. package/runtime/ext_gui/canvas_shadow.cpp +161 -0
  56. package/runtime/ext_gui/canvas_stroke.cpp +37 -9
  57. package/runtime/ext_gui/canvas_style.cpp +59 -0
  58. package/runtime/ext_gui/canvas_text.cpp +140 -0
  59. package/runtime/ext_gui/css.h +7 -0
  60. package/runtime/ext_gui/css_sheet.cpp +22 -0
  61. package/runtime/ext_gui/document.cpp +25 -1
  62. package/runtime/ext_gui/document.h +8 -0
  63. package/runtime/ext_gui/dom_api_canvas.cpp +16 -1
  64. package/runtime/ext_gui/dom_api_canvas_image.cpp +9 -0
  65. package/runtime/ext_gui/dom_api_canvas_state.cpp +217 -0
  66. package/runtime/ext_gui/dom_api_internal.h +36 -37
  67. package/runtime/ext_gui/dom_api_offscreen.cpp +213 -0
  68. package/runtime/ext_gui/dom_api_proto.cpp +18 -0
  69. package/runtime/ext_gui/dom_api_webgl.cpp +19 -9
  70. package/runtime/ext_gui/dom_api_webgl_internal.h +58 -0
  71. package/runtime/ext_gui/dom_api_webgl_source.cpp +18 -0
  72. package/runtime/ext_gui/gradient_values.cpp +12 -1
  73. package/runtime/ext_gui/gui.cpp +5 -0
  74. package/runtime/ext_gui/gui_canvas.cpp +4 -0
  75. package/runtime/ext_gui/gui_engine.h +30 -0
  76. package/runtime/ext_gui/gui_events.cpp +182 -58
  77. package/runtime/ext_gui/gui_media.cpp +3 -0
  78. package/runtime/ext_gui/image.cpp +69 -0
  79. package/runtime/ext_gui/image_bitmap_browser.cpp +11 -0
  80. package/runtime/ext_gui/layout.cpp +4 -0
  81. package/runtime/ext_gui/paint.cpp +19 -0
  82. package/runtime/ext_gui/paint_background.cpp +18 -1
  83. package/runtime/ext_gui/perf.cpp +171 -0
  84. package/runtime/ext_gui/perf.h +127 -0
  85. package/runtime/ext_gui/renderer.cpp +109 -41
  86. package/runtime/ext_gui/renderer.h +33 -9
  87. package/runtime/ext_gui/renderer_image.cpp +135 -65
  88. package/runtime/ext_gui/renderer_internal.h +15 -3
  89. package/runtime/ext_gui/renderer_text.cpp +24 -12
  90. package/runtime/ext_gui/style.cpp +101 -30
  91. package/runtime/ext_gui/style.h +6 -3
  92. package/runtime/ext_gui/style_print.cpp +7 -1
  93. package/runtime/ext_gui/text.cpp +23 -4
  94. package/runtime/ext_gui/text.h +29 -0
  95. package/runtime/ext_gui/text_cache.cpp +118 -0
  96. package/runtime/ext_gui/text_glyph_cache.cpp +100 -0
  97. package/runtime/ext_gui/webgl.h +48 -146
  98. package/runtime/ext_gui/webgl_blit.cpp +12 -1
  99. package/runtime/ext_gui/webgl_blit_depth.cpp +270 -0
  100. package/runtime/ext_gui/webgl_buffer.cpp +59 -1
  101. package/runtime/ext_gui/webgl_buffer_objects.cpp +106 -9
  102. package/runtime/ext_gui/webgl_clear.cpp +3 -0
  103. package/runtime/ext_gui/webgl_context.cpp +29 -3
  104. package/runtime/ext_gui/webgl_draw.cpp +75 -270
  105. package/runtime/ext_gui/webgl_draw_buffers.cpp +1 -0
  106. package/runtime/ext_gui/webgl_draw_setup.cpp +321 -0
  107. package/runtime/ext_gui/webgl_draw_state.h +130 -0
  108. package/runtime/ext_gui/webgl_glsl_scan.cpp +3 -8
  109. package/runtime/ext_gui/webgl_objects.h +148 -0
  110. package/runtime/ext_gui/webgl_pipeline.cpp +8 -8
  111. package/runtime/ext_gui/webgl_program_internal.h +35 -0
  112. package/runtime/ext_gui/webgl_shader.cpp +22 -30
  113. package/runtime/ext_gui/webgl_webgl2.cpp +36 -0
  114. package/runtime/ext_gui/window.cpp +56 -1
  115. package/src/codegen/generator/module.ts +22 -7
  116. package/src/driver/version.ts +1 -1
  117. package/src/extensions/gui/html.ts +9 -2
@@ -0,0 +1,297 @@
1
+ /**
2
+ * End-to-end tests for the Canvas2D features added after the first canvas
3
+ * slice: clipping, compositing, shadows, hit testing, smoothing, data-URL
4
+ * backgrounds and `OffscreenCanvas`.
5
+ *
6
+ * They run the real rasteriser and read pixels back with `getImageData`, so a
7
+ * regression in coverage/alpha math shows up as a concrete colour.
8
+ */
9
+ import { afterAll, beforeAll, describe, expect, it } from "vitest";
10
+ import { createGuiHarness, guiAvailable } from "./gui-helpers.js";
11
+ const harness = createGuiHarness();
12
+ const PAGE = `
13
+ <html><head><style>body { margin: 0; }</style></head><body>
14
+ <canvas id="c" width="120" height="120"></canvas>
15
+ <canvas id="src" width="20" height="20"></canvas>
16
+ <canvas id="transferred" width="20" height="20"></canvas>
17
+ <div id="bg" style="width:40px;height:40px"></div>
18
+ </body></html>`;
19
+ describe.skipIf(!guiAvailable)("gui extension — canvas state, clip and offscreen", () => {
20
+ beforeAll(() => harness.setup());
21
+ afterAll(() => harness.cleanup());
22
+ it("clips drawing and composites with the Porter-Duff operators", () => {
23
+ const { value } = harness.compileAndRun("canvas-clip-composite", `
24
+ import { createWindow, run } from "gui";
25
+
26
+ const win = createWindow({ title: "clip", width: 400, height: 300 });
27
+ win.on("ready", () => {
28
+ const canvas: any = document.getElementById("c");
29
+ const ctx: any = canvas.getContext("2d");
30
+ const px = (x: number, y: number): string => {
31
+ const d = ctx.getImageData(x, y, 1, 1).data;
32
+ return d[0] + "," + d[1] + "," + d[2] + "," + d[3];
33
+ };
34
+
35
+ ctx.fillStyle = "#ffffff";
36
+ ctx.fillRect(0, 0, 120, 120);
37
+
38
+ // A rectangular clip keeps a red fill inside (0,0)-(50,50).
39
+ ctx.save();
40
+ ctx.beginPath();
41
+ ctx.rect(0, 0, 50, 50);
42
+ ctx.clip();
43
+ ctx.fillStyle = "#ff0000";
44
+ ctx.fillRect(0, 0, 120, 120);
45
+ ctx.restore();
46
+ console.log("clip-in=" + px(25, 25));
47
+ console.log("clip-out=" + px(75, 25));
48
+ // restore() brings the unclipped region back.
49
+ ctx.fillStyle = "#00ff00";
50
+ ctx.fillRect(75, 75, 20, 20);
51
+ console.log("after-restore=" + px(80, 80));
52
+
53
+ // A Path2D clip.
54
+ const path: any = new Path2D();
55
+ path.rect(60, 0, 20, 20);
56
+ ctx.save();
57
+ ctx.clip(path);
58
+ ctx.fillStyle = "#0000ff";
59
+ ctx.fillRect(60, 0, 20, 20);
60
+ ctx.restore();
61
+ console.log("path-clip=" + px(65, 5));
62
+
63
+ // destination-out clears the covered pixels to transparent.
64
+ ctx.globalCompositeOperation = "destination-out";
65
+ ctx.fillStyle = "#000000";
66
+ ctx.fillRect(0, 0, 20, 20);
67
+ console.log("composite=" + ctx.globalCompositeOperation);
68
+ console.log("dest-out=" + px(10, 10));
69
+ ctx.globalCompositeOperation = "source-over";
70
+
71
+ // isPointInPath / isPointInStroke use the current path and transform.
72
+ ctx.beginPath();
73
+ ctx.rect(10, 10, 20, 20);
74
+ console.log("point-in=" + ctx.isPointInPath(15, 15));
75
+ console.log("point-out=" + ctx.isPointInPath(50, 50));
76
+ ctx.lineWidth = 6;
77
+ ctx.beginPath();
78
+ ctx.moveTo(80, 80);
79
+ ctx.lineTo(110, 80);
80
+ console.log("stroke-in=" + ctx.isPointInStroke(95, 81));
81
+ console.log("stroke-out=" + ctx.isPointInStroke(95, 95));
82
+ win.close();
83
+ });
84
+ win.loadHTML(\`${PAGE}\`);
85
+ run();
86
+ `);
87
+ expect(value("clip-in")).toBe("255,0,0,255");
88
+ expect(value("clip-out")).toBe("255,255,255,255");
89
+ expect(value("after-restore")).toBe("0,255,0,255");
90
+ expect(value("path-clip")).toBe("0,0,255,255");
91
+ expect(value("composite")).toBe("destination-out");
92
+ // destination-out on an opaque white pixel leaves transparent black.
93
+ expect(value("dest-out")).toBe("0,0,0,0");
94
+ expect(value("point-in")).toBe("true");
95
+ expect(value("point-out")).toBe("false");
96
+ expect(value("stroke-in")).toBe("true");
97
+ expect(value("stroke-out")).toBe("false");
98
+ });
99
+ it("paints offset shadows under the shape", () => {
100
+ const { value } = harness.compileAndRun("canvas-shadow", `
101
+ import { createWindow, run } from "gui";
102
+
103
+ const win = createWindow({ title: "shadow", width: 400, height: 300 });
104
+ win.on("ready", () => {
105
+ const canvas: any = document.getElementById("c");
106
+ const ctx: any = canvas.getContext("2d");
107
+ const px = (x: number, y: number): string => {
108
+ const d = ctx.getImageData(x, y, 1, 1).data;
109
+ return d[0] + "," + d[1] + "," + d[2] + "," + d[3];
110
+ };
111
+
112
+ ctx.shadowColor = "#000000";
113
+ ctx.shadowBlur = 0;
114
+ ctx.shadowOffsetX = 10;
115
+ ctx.shadowOffsetY = 10;
116
+ ctx.fillStyle = "#ff0000";
117
+ ctx.fillRect(10, 10, 20, 20);
118
+ console.log("color=" + ctx.shadowColor);
119
+ console.log("offsets=" + ctx.shadowOffsetX + "," + ctx.shadowOffsetY);
120
+ console.log("shape=" + px(20, 20));
121
+ console.log("shadow=" + px(35, 35));
122
+ console.log("outside=" + px(5, 5));
123
+
124
+ // The shadow is not part of clearRect, and a transparent shadow
125
+ // colour disables it again.
126
+ ctx.shadowColor = "rgba(0,0,0,0)";
127
+ ctx.fillStyle = "#0000ff";
128
+ ctx.fillRect(60, 10, 10, 10);
129
+ console.log("no-shadow=" + px(75, 15));
130
+ win.close();
131
+ });
132
+ win.loadHTML(\`${PAGE}\`);
133
+ run();
134
+ `);
135
+ expect(value("color")).toBe("#000000");
136
+ expect(value("offsets")).toBe("10,10");
137
+ expect(value("shape")).toBe("255,0,0,255");
138
+ expect(value("shadow")).toBe("0,0,0,255");
139
+ expect(value("outside")).toBe("0,0,0,0");
140
+ expect(value("no-shadow")).toBe("0,0,0,0");
141
+ });
142
+ it("honours image smoothing and the inner radial circle", () => {
143
+ const { value } = harness.compileAndRun("canvas-smoothing-radial", `
144
+ import { createWindow, run } from "gui";
145
+
146
+ const win = createWindow({ title: "smoothing", width: 400, height: 300 });
147
+ win.on("ready", () => {
148
+ const canvas: any = document.getElementById("c");
149
+ const ctx: any = canvas.getContext("2d");
150
+ const px = (x: number, y: number): string => {
151
+ const d = ctx.getImageData(x, y, 1, 1).data;
152
+ return d[0] + "," + d[1] + "," + d[2] + "," + d[3];
153
+ };
154
+
155
+ // A 2x2 source (red left, blue right), blown up to 40x40.
156
+ const source: any = new OffscreenCanvas(2, 2);
157
+ const sctx: any = source.getContext("2d");
158
+ sctx.putImageData({ width: 2, height: 2, data: [
159
+ 255, 0, 0, 255, 0, 0, 255, 255,
160
+ 255, 0, 0, 255, 0, 0, 255, 255] }, 0, 0);
161
+
162
+ console.log("smoothing-default=" + ctx.imageSmoothingEnabled);
163
+ ctx.drawImage(source, 0, 0, 40, 40);
164
+ console.log("smooth=" + px(20, 20));
165
+ ctx.clearRect(0, 0, 120, 120);
166
+ ctx.imageSmoothingEnabled = false;
167
+ console.log("smoothing-off=" + ctx.imageSmoothingEnabled);
168
+ ctx.drawImage(source, 0, 0, 40, 40);
169
+ console.log("blocky=" + px(20, 20));
170
+ ctx.imageSmoothingQuality = "high";
171
+ console.log("quality=" + ctx.imageSmoothingQuality);
172
+
173
+ // A radial gradient whose inner circle is off-centre: the point at the
174
+ // inner centre is white, the outer circle black. (A concentric
175
+ // implementation would make both black.)
176
+ const radial = ctx.createRadialGradient(20, 50, 0, 50, 50, 30);
177
+ radial.addColorStop(0, "#ffffff");
178
+ radial.addColorStop(1, "#000000");
179
+ ctx.fillStyle = radial;
180
+ ctx.fillRect(0, 30, 100, 40);
181
+ console.log("radial-inner=" + px(20, 50));
182
+ console.log("radial-outer=" + px(80, 50));
183
+ win.close();
184
+ });
185
+ win.loadHTML(\`${PAGE}\`);
186
+ run();
187
+ `);
188
+ expect(value("smoothing-default")).toBe("true");
189
+ // Bilinear samples between the red and blue texels.
190
+ const smooth = value("smooth").split(",").map(Number);
191
+ expect(smooth[0]).toBeGreaterThan(20);
192
+ expect(smooth[2]).toBeGreaterThan(20);
193
+ expect(value("smoothing-off")).toBe("false");
194
+ expect(value("blocky")).toBe("0,0,255,255");
195
+ expect(value("quality")).toBe("high");
196
+ const radialInner = value("radial-inner").split(",").map(Number);
197
+ expect(radialInner[0]).toBeGreaterThan(245);
198
+ expect(value("radial-outer")).toBe("0,0,0,255");
199
+ });
200
+ it("supports OffscreenCanvas and transferControlToOffscreen", () => {
201
+ const { value } = harness.compileAndRun("canvas-offscreen", `
202
+ import { createWindow, run } from "gui";
203
+
204
+ const win = createWindow({ title: "offscreen", width: 400, height: 300 });
205
+ win.on("ready", () => {
206
+ const canvas: any = document.getElementById("c");
207
+ const ctx: any = canvas.getContext("2d");
208
+ const px = (x: number, y: number): string => {
209
+ const d = ctx.getImageData(x, y, 1, 1).data;
210
+ return d[0] + "," + d[1] + "," + d[2] + "," + d[3];
211
+ };
212
+
213
+ const off: any = new OffscreenCanvas(20, 10);
214
+ console.log("size=" + off.width + "x" + off.height);
215
+ console.log("instanceof=" + (off instanceof OffscreenCanvas));
216
+ const octx: any = off.getContext("2d");
217
+ console.log("ctx=" + (octx != null) + "," + (off.getContext("2d") === octx) + "," +
218
+ (octx.canvas === off));
219
+ octx.fillStyle = "#00ff00";
220
+ octx.fillRect(0, 0, 20, 10);
221
+ ctx.drawImage(off, 0, 0);
222
+ console.log("drawn=" + px(10, 5));
223
+
224
+ const bitmap: any = off.transferToImageBitmap();
225
+ console.log("bitmap=" + bitmap.width + "x" + bitmap.height);
226
+
227
+ // alpha:false starts as opaque black, like a DOM canvas.
228
+ const opaque: any = new OffscreenCanvas(4, 4);
229
+ const opaqueCtx: any = opaque.getContext("2d", { alpha: false });
230
+ const opaquePixel = opaqueCtx.getImageData(0, 0, 1, 1).data;
231
+ console.log("opaque=" + opaqueCtx.getContextAttributes().alpha + "," +
232
+ opaquePixel[0] + "," + opaquePixel[1] + "," + opaquePixel[2] + "," + opaquePixel[3]);
233
+
234
+ // Transfer a live element: the element loses its context, the returned
235
+ // OffscreenCanvas keeps drawing into the same bitmap.
236
+ const element: any = document.getElementById("transferred");
237
+ const transferred: any = element.transferControlToOffscreen();
238
+ console.log("transferred=" + (transferred != null));
239
+ console.log("element-ctx=" + (element.getContext("2d") == null));
240
+ const tctx: any = transferred.getContext("2d");
241
+ tctx.fillStyle = "#ff00ff";
242
+ tctx.fillRect(0, 0, 20, 20);
243
+ ctx.drawImage(transferred, 50, 50);
244
+ console.log("transfer-draw=" + px(60, 60));
245
+
246
+ // convertToBlob resolves to a PNG blob.
247
+ off.convertToBlob().then((blob: any): void => {
248
+ console.log("blob=" + blob.type + "," + (blob.size > 0));
249
+ win.close();
250
+ });
251
+ });
252
+ win.loadHTML(\`${PAGE}\`);
253
+ run();
254
+ `, { autocloseMs: 2000 });
255
+ expect(value("size")).toBe("20x10");
256
+ expect(value("instanceof")).toBe("true");
257
+ expect(value("ctx")).toBe("true,true,true");
258
+ expect(value("drawn")).toBe("0,255,0,255");
259
+ expect(value("bitmap")).toBe("20x10");
260
+ expect(value("opaque")).toBe("false,0,0,0,255");
261
+ expect(value("transferred")).toBe("true");
262
+ expect(value("element-ctx")).toBe("true");
263
+ expect(value("transfer-draw")).toBe("255,0,255,255");
264
+ expect(value("blob")).toBe("image/png,true");
265
+ });
266
+ it("paints a canvas data URL as a CSS background-image", () => {
267
+ const { value } = harness.compileAndRun("canvas-background-image", `
268
+ import { createWindow, run } from "gui";
269
+
270
+ const win = createWindow({ title: "bg", width: 400, height: 300 });
271
+ win.on("ready", () => {
272
+ const source: any = document.getElementById("src");
273
+ const sctx: any = source.getContext("2d");
274
+ sctx.fillStyle = "#ff00ff";
275
+ sctx.fillRect(0, 0, 20, 20);
276
+ const url: string = source.toDataURL();
277
+ const bg: any = document.getElementById("bg");
278
+ bg.style.backgroundImage = "url(" + url + ")";
279
+ const list: string = win.paintList();
280
+ console.log("has-image=" + (list.indexOf("src=data:image/png;base64,") >= 0));
281
+ const computed: string = getComputedStyle(bg).backgroundImage;
282
+ console.log("inline=" + (bg.style.backgroundImage.indexOf("url(") === 0));
283
+ console.log("computed-width=" + getComputedStyle(bg).width);
284
+ console.log("computed-head=" + computed.substring(0, 24));
285
+ console.log("computed=" + (computed.indexOf("url(data:image/png") === 0));
286
+ win.close();
287
+ });
288
+ win.loadHTML(\`${PAGE}\`);
289
+ run();
290
+ `);
291
+ expect(value("has-image")).toBe("true");
292
+ expect(value("inline")).toBe("true");
293
+ expect(value("computed-width")).toBe("40px");
294
+ expect(value("computed")).toBe("true");
295
+ });
296
+ });
297
+ //# sourceMappingURL=gui-canvas-state.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gui-canvas-state.test.js","sourceRoot":"","sources":["../../../tests/e2e/gui-canvas-state.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * End-to-end benchmark for the two immediate-mode drawing surfaces.
3
+ *
4
+ * The `gui-perf` suite measures the retained DOM pipeline (restyle/layout/paint
5
+ * runs). This one measures the two APIs a multi-element scene actually calls
6
+ * thousands of times per frame:
7
+ *
8
+ * - `<canvas>` 2D: solid `fillRect`, multi-segment `stroke`, repeated
9
+ * `fillText` and 1:1 `drawImage`, drawn into a 1280x720 bitmap;
10
+ * - WebGL: 2000 `drawElements` calls with a per-draw matrix, plus a 64 KB
11
+ * `bufferSubData` into a 4 MB buffer.
12
+ *
13
+ * The programs print wall-clock milliseconds per scene (informational: CI may
14
+ * run on a software GPU) and the engine counters that a regression would move:
15
+ * `canvasDraws`/`canvasUploads`/`canvasUploadBytes` and
16
+ * `webglDraws`/`webglPasses`/`webglPipelineMisses`/`webglBufferUploadBytes`
17
+ * from `win.stats()` (see `runtime/ext_gui/perf.h`).
18
+ *
19
+ * The counters are asserted (deterministic). Timings are printed and, on a
20
+ * developer machine, can be bounded with `XBINTSC_GUI_DRAW_PERF_STRICT_MS`.
21
+ */
22
+ export {};