xbintsc 0.5.45 → 0.5.52
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/AGENTS.md +1 -1
- package/README.md +5 -4
- package/README.zh-CN.md +4 -3
- package/dist/src/cli/extensions.d.ts +24 -0
- package/dist/src/cli/extensions.js +62 -0
- package/dist/src/cli/extensions.js.map +1 -0
- package/dist/src/cli/help.d.ts +1 -1
- package/dist/src/cli/help.js +3 -1
- package/dist/src/cli/help.js.map +1 -1
- package/dist/src/cli/hints.js +8 -3
- package/dist/src/cli/hints.js.map +1 -1
- package/dist/src/cli/main.js +21 -28
- package/dist/src/cli/main.js.map +1 -1
- package/dist/src/diagnostics/diagnostic.d.ts +3 -1
- package/dist/src/diagnostics/diagnostic.js +2 -0
- package/dist/src/diagnostics/diagnostic.js.map +1 -1
- package/dist/src/driver/build-key.d.ts +2 -0
- package/dist/src/driver/build-key.js +1 -0
- package/dist/src/driver/build-key.js.map +1 -1
- package/dist/src/driver/compiler.js +61 -8
- package/dist/src/driver/compiler.js.map +1 -1
- package/dist/src/driver/config.d.ts +4 -0
- package/dist/src/driver/config.js +2 -0
- package/dist/src/driver/config.js.map +1 -1
- package/dist/src/driver/link-features.d.ts +37 -0
- package/dist/src/driver/link-features.js +123 -0
- package/dist/src/driver/link-features.js.map +1 -0
- package/dist/src/driver/options.d.ts +10 -0
- package/dist/src/driver/runtime-objects.d.ts +5 -0
- package/dist/src/driver/runtime-objects.js +20 -1
- package/dist/src/driver/runtime-objects.js.map +1 -1
- package/dist/src/driver/usage.d.ts +23 -0
- package/dist/src/driver/usage.js +353 -0
- package/dist/src/driver/usage.js.map +1 -0
- package/dist/src/driver/version.d.ts +1 -1
- package/dist/src/driver/version.js +1 -1
- package/dist/src/extensions/catalog.js +1 -2
- package/dist/src/extensions/catalog.js.map +1 -1
- package/dist/src/extensions/gui/features.d.ts +34 -0
- package/dist/src/extensions/gui/features.js +165 -0
- package/dist/src/extensions/gui/features.js.map +1 -0
- package/dist/src/extensions/gui/index.js +10 -4
- package/dist/src/extensions/gui/index.js.map +1 -1
- package/dist/src/extensions/link-feature.d.ts +70 -0
- package/dist/src/extensions/link-feature.js +18 -0
- package/dist/src/extensions/link-feature.js.map +1 -0
- package/dist/src/extensions/registry.d.ts +24 -4
- package/dist/src/extensions/registry.js +26 -3
- package/dist/src/extensions/registry.js.map +1 -1
- package/dist/src/index.d.ts +3 -2
- package/dist/src/index.js +0 -1
- package/dist/src/index.js.map +1 -1
- package/dist/tests/cli/hints.test.js +5 -7
- package/dist/tests/cli/hints.test.js.map +1 -1
- package/dist/tests/driver/link-features.test.js +105 -0
- package/dist/tests/driver/link-features.test.js.map +1 -0
- package/dist/tests/driver/usage.test.d.ts +1 -0
- package/dist/tests/driver/usage.test.js +88 -0
- package/dist/tests/driver/usage.test.js.map +1 -0
- package/dist/tests/e2e/gui-audio.test.js +4 -4
- package/dist/tests/e2e/gui-audio.test.js.map +1 -1
- package/dist/tests/e2e/gui-css-coverage.test.d.ts +9 -0
- package/dist/tests/e2e/gui-css-coverage.test.js +333 -0
- package/dist/tests/e2e/gui-css-coverage.test.js.map +1 -0
- package/dist/tests/e2e/gui-css-features.test.d.ts +6 -0
- package/dist/tests/e2e/gui-css-features.test.js +270 -0
- package/dist/tests/e2e/gui-css-features.test.js.map +1 -0
- package/dist/tests/e2e/gui-effects.test.js +92 -11
- package/dist/tests/e2e/gui-effects.test.js.map +1 -1
- package/dist/tests/e2e/gui-feature-linking.test.d.ts +9 -0
- package/dist/tests/e2e/gui-feature-linking.test.js +68 -0
- package/dist/tests/e2e/gui-feature-linking.test.js.map +1 -0
- package/dist/tests/e2e/gui-font-face.test.d.ts +10 -0
- package/dist/tests/e2e/gui-font-face.test.js +142 -0
- package/dist/tests/e2e/gui-font-face.test.js.map +1 -0
- package/dist/tests/e2e/gui-fonts.test.d.ts +10 -0
- package/dist/tests/e2e/gui-fonts.test.js +150 -0
- package/dist/tests/e2e/gui-fonts.test.js.map +1 -0
- package/dist/tests/e2e/gui-helpers.d.ts +10 -1
- package/dist/tests/e2e/gui-helpers.js +6 -0
- package/dist/tests/e2e/gui-helpers.js.map +1 -1
- package/dist/tests/e2e/gui-layout.test.js +7 -3
- package/dist/tests/e2e/gui-layout.test.js.map +1 -1
- package/dist/tests/e2e/gui-media-disabled.test.d.ts +5 -4
- package/dist/tests/e2e/gui-media-disabled.test.js +7 -6
- package/dist/tests/e2e/gui-media-disabled.test.js.map +1 -1
- package/dist/tests/e2e/gui-media.test.d.ts +5 -4
- package/dist/tests/e2e/gui-media.test.js +9 -9
- package/dist/tests/e2e/gui-media.test.js.map +1 -1
- package/dist/tests/e2e/gui-paint.test.js +5 -2
- package/dist/tests/e2e/gui-paint.test.js.map +1 -1
- package/dist/tests/e2e/gui-shaping.test.d.ts +5 -0
- package/dist/tests/e2e/gui-shaping.test.js +47 -0
- package/dist/tests/e2e/gui-shaping.test.js.map +1 -0
- package/dist/tests/e2e/gui-track-sizing.test.d.ts +6 -0
- package/dist/tests/e2e/gui-track-sizing.test.js +173 -0
- package/dist/tests/e2e/gui-track-sizing.test.js.map +1 -0
- package/dist/tests/e2e/gui-transform.test.js +3 -2
- package/dist/tests/e2e/gui-transform.test.js.map +1 -1
- package/dist/tests/e2e/gui-webgl-pipeline-cache.test.d.ts +18 -0
- package/dist/tests/e2e/gui-webgl-pipeline-cache.test.js +120 -0
- package/dist/tests/e2e/gui-webgl-pipeline-cache.test.js.map +1 -0
- package/dist/tests/extensions/gui-features.test.d.ts +1 -0
- package/dist/tests/extensions/gui-features.test.js +175 -0
- package/dist/tests/extensions/gui-features.test.js.map +1 -0
- package/doc/ai/cli.md +5 -1
- package/doc/ai/extensions.md +56 -26
- package/doc/ai/troubleshooting.md +10 -7
- package/doc/ai/zh-CN/cli.md +5 -1
- package/doc/ai/zh-CN/extensions.md +48 -22
- package/doc/ai/zh-CN/troubleshooting.md +6 -5
- package/doc/gui/animation.md +39 -9
- package/doc/gui/api.md +2 -1
- package/doc/gui/build.md +137 -19
- package/doc/gui/canvas.md +1 -1
- package/doc/gui/dom.md +20 -4
- package/doc/gui/known-issues.md +63 -26
- package/doc/gui/layout.md +31 -8
- package/doc/gui/media.md +13 -7
- package/doc/gui/rendering.md +114 -39
- package/doc/gui/runtime.md +5 -0
- package/doc/gui/webgl.md +24 -6
- package/doc/gui.md +110 -47
- package/doc/implemented/cli.md +2 -0
- package/doc/implemented/extensions.md +9 -3
- package/doc/npm-package.md +4 -4
- package/doc/xbintsc.config.schema.json +10 -0
- package/doc/zh-CN/gui/animation.md +33 -10
- package/doc/zh-CN/gui/api.md +2 -1
- package/doc/zh-CN/gui/build.md +110 -16
- package/doc/zh-CN/gui/canvas.md +1 -1
- package/doc/zh-CN/gui/dom.md +16 -3
- package/doc/zh-CN/gui/known-issues.md +45 -15
- package/doc/zh-CN/gui/layout.md +23 -6
- package/doc/zh-CN/gui/media.md +11 -6
- package/doc/zh-CN/gui/rendering.md +84 -26
- package/doc/zh-CN/gui/runtime.md +3 -0
- package/doc/zh-CN/gui/webgl.md +3 -3
- package/doc/zh-CN/gui.md +92 -41
- package/doc/zh-CN/implemented/cli.md +2 -0
- package/doc/zh-CN/implemented/extensions.md +9 -3
- package/doc/zh-CN/npm-package.md +4 -3
- package/package.json +7 -7
- package/runtime/ext_gui/animation_values.cpp +425 -0
- package/runtime/ext_gui/animation_values.h +64 -0
- package/runtime/ext_gui/browser.cpp +22 -15
- package/runtime/ext_gui/browser_loop.cpp +13 -1
- package/runtime/ext_gui/canvas.h +1 -1
- package/runtime/ext_gui/canvas_raster.cpp +1 -1
- package/runtime/ext_gui/canvas_text.cpp +1 -1
- package/runtime/ext_gui/css.cpp +172 -21
- package/runtime/ext_gui/css.h +75 -4
- package/runtime/ext_gui/css_match.cpp +4 -0
- package/runtime/ext_gui/css_sheet.cpp +218 -2
- package/runtime/ext_gui/document.cpp +42 -192
- package/runtime/ext_gui/document.h +25 -12
- package/runtime/ext_gui/document_animation.cpp +428 -0
- package/runtime/ext_gui/dom_api_canvas.cpp +15 -8
- package/runtime/ext_gui/dom_api_canvas_extra.cpp +44 -20
- package/runtime/ext_gui/dom_api_canvas_image.cpp +3 -1
- package/runtime/ext_gui/dom_api_node_read.cpp +10 -0
- package/runtime/ext_gui/dom_api_offscreen.cpp +3 -1
- package/runtime/ext_gui/dom_api_style.cpp +7 -0
- package/runtime/ext_gui/dom_api_webgl_internal.h +4 -0
- package/runtime/ext_gui/dom_api_webgl_source.cpp +5 -2
- package/runtime/ext_gui/effect_values.cpp +245 -21
- package/runtime/ext_gui/gpu_bridge.c +28 -0
- package/runtime/ext_gui/gpu_feature.cpp +30 -0
- package/runtime/ext_gui/gpu_shader.cpp +22 -0
- package/runtime/ext_gui/gpu_shader_api.h +50 -0
- package/runtime/ext_gui/gradient_values.cpp +24 -0
- package/runtime/ext_gui/grid_values.cpp +23 -0
- package/runtime/ext_gui/gui.cpp +6 -37
- package/runtime/ext_gui/gui_canvas.cpp +14 -6
- package/runtime/ext_gui/gui_cursor.cpp +50 -0
- package/runtime/ext_gui/gui_engine.h +1 -18
- package/runtime/ext_gui/gui_events.cpp +19 -6
- package/runtime/ext_gui/gui_internal.h +3 -0
- package/runtime/ext_gui/gui_webgl.cpp +25 -10
- package/runtime/ext_gui/image_api.cpp +18 -0
- package/runtime/ext_gui/image_api.h +43 -0
- package/runtime/ext_gui/image_bitmap_browser.cpp +20 -11
- package/runtime/ext_gui/image_bridge.c +22 -0
- package/runtime/ext_gui/image_feature.cpp +107 -0
- package/runtime/ext_gui/inline_svg.cpp +95 -8
- package/runtime/ext_gui/inline_svg.h +5 -1
- package/runtime/ext_gui/layout.cpp +15 -9
- package/runtime/ext_gui/layout.h +8 -2
- package/runtime/ext_gui/layout_flex.cpp +134 -29
- package/runtime/ext_gui/layout_flow.cpp +58 -7
- package/runtime/ext_gui/layout_flow_internal.h +39 -4
- package/runtime/ext_gui/layout_grid.cpp +31 -0
- package/runtime/ext_gui/layout_inline.cpp +26 -2
- package/runtime/ext_gui/layout_vertical.cpp +196 -0
- package/runtime/ext_gui/media.cpp +4 -2
- package/runtime/ext_gui/media.h +3 -3
- package/runtime/ext_gui/media_api.h +7 -6
- package/runtime/ext_gui/paint.cpp +67 -9
- package/runtime/ext_gui/paint.h +61 -8
- package/runtime/ext_gui/paint_backdrop.cpp +211 -0
- package/runtime/ext_gui/paint_background.cpp +175 -97
- package/runtime/ext_gui/paint_effects.cpp +12 -6
- package/runtime/ext_gui/paint_internal.h +27 -0
- package/runtime/ext_gui/paint_outline.cpp +44 -0
- package/runtime/ext_gui/paint_shadow.cpp +368 -0
- package/runtime/ext_gui/renderer.cpp +15 -7
- package/runtime/ext_gui/renderer.h +11 -2
- package/runtime/ext_gui/renderer_backdrop.cpp +374 -0
- package/runtime/ext_gui/renderer_bitmap.cpp +82 -0
- package/runtime/ext_gui/renderer_gradient.cpp +51 -17
- package/runtime/ext_gui/renderer_image.cpp +19 -7
- package/runtime/ext_gui/renderer_internal.h +21 -0
- package/runtime/ext_gui/renderer_layer.cpp +37 -6
- package/runtime/ext_gui/renderer_text.cpp +2 -1
- package/runtime/ext_gui/stb_truetype.h +5077 -0
- package/runtime/ext_gui/style.cpp +62 -8
- package/runtime/ext_gui/style.h +111 -4
- package/runtime/ext_gui/style_cascade.cpp +83 -0
- package/runtime/ext_gui/style_internal.h +13 -1
- package/runtime/ext_gui/style_length.cpp +92 -0
- package/runtime/ext_gui/style_print.cpp +83 -2
- package/runtime/ext_gui/style_svg.cpp +40 -0
- package/runtime/ext_gui/style_text.cpp +302 -0
- package/runtime/ext_gui/style_ui.cpp +150 -0
- package/runtime/ext_gui/style_values.cpp +76 -62
- package/runtime/ext_gui/style_values_internal.h +23 -0
- package/runtime/ext_gui/text.cpp +27 -499
- package/runtime/ext_gui/text.h +18 -9
- package/runtime/ext_gui/text_api.h +45 -0
- package/runtime/ext_gui/text_bridge.c +23 -0
- package/runtime/ext_gui/text_cache.cpp +12 -3
- package/runtime/ext_gui/text_font_db.cpp +427 -0
- package/runtime/ext_gui/text_font_paths.cpp +250 -0
- package/runtime/ext_gui/text_font_paths.h +39 -0
- package/runtime/ext_gui/text_font_sfnt.cpp +396 -0
- package/runtime/ext_gui/text_font_sfnt.h +44 -0
- package/runtime/ext_gui/text_fonts.cpp +348 -0
- package/runtime/ext_gui/text_fonts.h +78 -0
- package/runtime/ext_gui/text_fonts_internal.h +77 -0
- package/runtime/ext_gui/text_glyph_cache.cpp +2 -2
- package/runtime/ext_gui/text_hb.cpp +438 -0
- package/runtime/ext_gui/text_stb.cpp +369 -0
- package/runtime/ext_gui/transform.cpp +107 -9
- package/runtime/ext_gui/transform.h +5 -0
- package/runtime/ext_gui/webgl_api.cpp +19 -0
- package/runtime/ext_gui/webgl_api.h +53 -0
- package/runtime/ext_gui/webgl_bridge.c +25 -0
- package/runtime/ext_gui/webgl_draw_setup.cpp +42 -1
- package/runtime/ext_gui/webgl_feature.cpp +82 -0
- package/runtime/ext_gui/webgl_feature.h +28 -0
- package/runtime/ext_gui/webgl_msl.cpp +41 -0
- package/runtime/ext_gui/webgl_msl.h +6 -0
- package/runtime/ext_gui/webgl_shader.cpp +40 -32
- package/runtime/ext_gui/window.cpp +7 -7
- package/runtime/ext_media/decode_audio.cpp +1 -1
- package/runtime/ext_media/media.cpp +1 -1
- package/runtime/ext_media/media_bridge.c +7 -7
- package/scripts/build-gui.ts +97 -98
- package/scripts/check-file-length.ts +1 -0
- package/scripts/gui-build-options.ts +122 -0
- package/src/cli/extensions.ts +72 -0
- package/src/cli/help.ts +3 -1
- package/src/cli/hints.ts +9 -3
- package/src/cli/main.ts +21 -27
- package/src/diagnostics/diagnostic.ts +2 -0
- package/src/driver/build-key.ts +3 -0
- package/src/driver/compiler.ts +63 -8
- package/src/driver/config.ts +6 -0
- package/src/driver/link-features.ts +163 -0
- package/src/driver/options.ts +10 -0
- package/src/driver/runtime-objects.ts +26 -1
- package/src/driver/usage.ts +376 -0
- package/src/driver/version.ts +1 -1
- package/src/extensions/catalog.ts +1 -2
- package/src/extensions/gui/features.ts +166 -0
- package/src/extensions/gui/index.ts +10 -4
- package/src/extensions/link-feature.ts +72 -0
- package/src/extensions/registry.ts +45 -4
- package/src/index.ts +3 -2
- package/dist/src/extensions/media/index.d.ts +0 -28
- package/dist/src/extensions/media/index.js +0 -59
- package/dist/src/extensions/media/index.js.map +0 -1
- package/dist/tests/extensions/media.test.js +0 -63
- package/dist/tests/extensions/media.test.js.map +0 -1
- package/src/extensions/media/index.ts +0 -65
- /package/dist/tests/{extensions/media.test.d.ts → driver/link-features.test.d.ts} +0 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* End-to-end test for the `gui` extension — WebGL pipeline cache reuse.
|
|
3
|
+
*
|
|
4
|
+
* A pipeline is a function of the program, the vertex *layout* and the
|
|
5
|
+
* fixed-function state. It is not a function of which buffer currently holds
|
|
6
|
+
* the data, nor of the monotonic counters the engine bumps when a VAO is bound
|
|
7
|
+
* or a framebuffer is switched. Keying the pipeline cache on those counters
|
|
8
|
+
* made every draw create a fresh `SDL_GPUGraphicsPipeline` once a frame bound
|
|
9
|
+
* more than one layout (three.js binds one VAO per geometry): a measured
|
|
10
|
+
* ~250 pipeline creations per frame, which cost more than the whole rest of
|
|
11
|
+
* the frame.
|
|
12
|
+
*
|
|
13
|
+
* This program draws two triangles whose layouts are identical and whose
|
|
14
|
+
* buffers differ, alternating the bound buffer every frame. The layout never
|
|
15
|
+
* changes, so after the first frame the pipeline must come from the cache:
|
|
16
|
+
* `webglPipelineMisses` may not grow. Before the fix it grew by two per frame.
|
|
17
|
+
*/
|
|
18
|
+
import { afterAll, beforeAll, describe, expect, it } from "vitest";
|
|
19
|
+
import { createGuiHarness, guiAvailable } from "./gui-helpers.js";
|
|
20
|
+
const harness = createGuiHarness();
|
|
21
|
+
const PAGE = `
|
|
22
|
+
<html><head><title>webgl pipeline cache</title></head>
|
|
23
|
+
<body style="margin:0">
|
|
24
|
+
<canvas id="c" width="64" height="64"></canvas>
|
|
25
|
+
</body></html>`;
|
|
26
|
+
describe.skipIf(!guiAvailable)("gui extension — WebGL pipeline cache", () => {
|
|
27
|
+
beforeAll(() => harness.setup());
|
|
28
|
+
afterAll(() => harness.cleanup());
|
|
29
|
+
it("reuses the pipeline when only the bound buffers change", () => {
|
|
30
|
+
const { value } = harness.compileAndRun("webgl-pipeline-cache", `
|
|
31
|
+
import { createWindow } from "gui";
|
|
32
|
+
import page from "./page.html";
|
|
33
|
+
|
|
34
|
+
const win = createWindow({ title: "pipeline cache", width: 320, height: 240 });
|
|
35
|
+
win.loadHTML(page);
|
|
36
|
+
const out = (name: string, value: any): void => console.log(name + "=" + value);
|
|
37
|
+
|
|
38
|
+
let gl: any = null;
|
|
39
|
+
let position = 0;
|
|
40
|
+
let buffers: any[] = [];
|
|
41
|
+
|
|
42
|
+
/* A triangle in its own buffer: same layout, different data. */
|
|
43
|
+
const makeBuffer = (center: number): any => {
|
|
44
|
+
const buffer: any = gl.createBuffer();
|
|
45
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
|
46
|
+
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
|
|
47
|
+
center - 0.4, -0.4, center + 0.4, -0.4, center, 0.5,
|
|
48
|
+
]), gl.STATIC_DRAW);
|
|
49
|
+
return buffer;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
let frame = 0;
|
|
53
|
+
let warm: any = null;
|
|
54
|
+
|
|
55
|
+
const tick = (): void => {
|
|
56
|
+
frame = frame + 1;
|
|
57
|
+
for (const buffer of buffers) {
|
|
58
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
|
59
|
+
gl.vertexAttribPointer(position, 2, gl.FLOAT, false, 0, 0);
|
|
60
|
+
gl.drawArrays(gl.TRIANGLES, 0, 3);
|
|
61
|
+
}
|
|
62
|
+
/* Frames 1-3 warm the cache (shader translation, the first pipelines and
|
|
63
|
+
* the one-time GPU setup). From there the layout never changes. */
|
|
64
|
+
if (frame === 3) warm = win.stats();
|
|
65
|
+
if (frame < 8) {
|
|
66
|
+
win.requestAnimationFrame(tick);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const now: any = win.stats();
|
|
70
|
+
out("misses.warm", now.webglPipelineMisses - warm.webglPipelineMisses);
|
|
71
|
+
out("draws.warm", now.webglDraws - warm.webglDraws);
|
|
72
|
+
out("misses.total", now.webglPipelineMisses);
|
|
73
|
+
out("frames", frame);
|
|
74
|
+
win.close();
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
win.on("ready", () => {
|
|
78
|
+
const canvas: any = document.getElementById("c");
|
|
79
|
+
gl = canvas.getContext("webgl");
|
|
80
|
+
out("webgl", gl != null);
|
|
81
|
+
if (gl == null) {
|
|
82
|
+
win.close();
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const vs: any = gl.createShader(gl.VERTEX_SHADER);
|
|
87
|
+
gl.shaderSource(vs, "attribute vec2 a_pos;" +
|
|
88
|
+
"void main() { gl_Position = vec4(a_pos, 0.0, 1.0); }");
|
|
89
|
+
gl.compileShader(vs);
|
|
90
|
+
const fs: any = gl.createShader(gl.FRAGMENT_SHADER);
|
|
91
|
+
gl.shaderSource(fs, "precision mediump float;" +
|
|
92
|
+
"void main() { gl_FragColor = vec4(0.2, 0.6, 1.0, 1.0); }");
|
|
93
|
+
gl.compileShader(fs);
|
|
94
|
+
|
|
95
|
+
const program: any = gl.createProgram();
|
|
96
|
+
gl.attachShader(program, vs);
|
|
97
|
+
gl.attachShader(program, fs);
|
|
98
|
+
gl.linkProgram(program);
|
|
99
|
+
out("link", gl.getProgramParameter(program, gl.LINK_STATUS));
|
|
100
|
+
gl.useProgram(program);
|
|
101
|
+
|
|
102
|
+
position = gl.getAttribLocation(program, "a_pos");
|
|
103
|
+
gl.enableVertexAttribArray(position);
|
|
104
|
+
buffers = [makeBuffer(-0.4), makeBuffer(0.4)];
|
|
105
|
+
win.requestAnimationFrame(tick);
|
|
106
|
+
});
|
|
107
|
+
win.on("close", () => console.log("closed"));
|
|
108
|
+
`, { files: { "page.html": PAGE }, autocloseMs: 15000, console: true });
|
|
109
|
+
expect(value("webgl")).toBe("true");
|
|
110
|
+
expect(value("link")).toBe("true");
|
|
111
|
+
expect(value("frames")).toBe("8");
|
|
112
|
+
/* The draw calls really happened. */
|
|
113
|
+
expect(Number(value("draws.warm"))).toBeGreaterThan(0);
|
|
114
|
+
/* ... and none of them built a pipeline: the layout is unchanged. */
|
|
115
|
+
expect(Number(value("misses.warm"))).toBe(0);
|
|
116
|
+
/* The cache stays bounded: a handful for the whole program. */
|
|
117
|
+
expect(Number(value("misses.total"))).toBeLessThan(8);
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
//# sourceMappingURL=gui-webgl-pipeline-cache.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gui-webgl-pipeline-cache.test.js","sourceRoot":"","sources":["../../../tests/e2e/gui-webgl-pipeline-cache.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAElE,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC;AAEnC,MAAM,IAAI,GAAG;;;;eAIE,CAAC;AAEhB,QAAQ,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,sCAAsC,EAAE,GAAG,EAAE;IAC1E,SAAS,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IACjC,QAAQ,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAElC,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,aAAa,CACrC,sBAAsB,EACtB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8EC,EACD,EAAE,KAAK,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,CACpE,CAAC;QAEF,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACpC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACnC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAClC,qCAAqC;QACrC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QACvD,qEAAqE;QACrE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC7C,+DAA+D;QAC/D,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
3
|
+
const mocks = vi.hoisted(() => ({ findRuntimeLibrary: vi.fn() }));
|
|
4
|
+
/* Keep the archive lookup deterministic so both the success and the
|
|
5
|
+
* "not built yet" branches of `nativeObjects` can be exercised. */
|
|
6
|
+
vi.mock("../../src/driver/runtime-lib.js", () => ({
|
|
7
|
+
findRuntimeLibrary: mocks.findRuntimeLibrary,
|
|
8
|
+
runtimeLibDir: () => "/tmp/runtime/lib/darwin-x64",
|
|
9
|
+
}));
|
|
10
|
+
vi.mock("../../src/driver/paths.js", () => ({
|
|
11
|
+
findRuntimeDir: () => "/tmp/runtime",
|
|
12
|
+
platformSlug: () => "darwin-x64",
|
|
13
|
+
}));
|
|
14
|
+
import { guiExtension } from "../../src/extensions/gui/index.js";
|
|
15
|
+
import { guiLinkFeatures, hasGpuUsage, hasImageUsage, hasMediaUsage, hasShapingUsage, hasWebglUsage, } from "../../src/extensions/gui/features.js";
|
|
16
|
+
afterEach(() => {
|
|
17
|
+
vi.restoreAllMocks();
|
|
18
|
+
mocks.findRuntimeLibrary.mockReset();
|
|
19
|
+
});
|
|
20
|
+
/** Build a usage record with the fields a matcher reads. */
|
|
21
|
+
function usage(overrides = {}) {
|
|
22
|
+
return {
|
|
23
|
+
strings: [],
|
|
24
|
+
identifiers: new Set(),
|
|
25
|
+
getContext: [],
|
|
26
|
+
dynamicMarkup: false,
|
|
27
|
+
...overrides,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/** The features in declaration order. */
|
|
31
|
+
const media = guiLinkFeatures.find((feature) => feature.name === "media");
|
|
32
|
+
const gpu = guiLinkFeatures.find((feature) => feature.name === "gpu");
|
|
33
|
+
const images = guiLinkFeatures.find((feature) => feature.name === "images");
|
|
34
|
+
const shaping = guiLinkFeatures.find((feature) => feature.name === "shaping");
|
|
35
|
+
const webgl = guiLinkFeatures.find((feature) => feature.name === "webgl");
|
|
36
|
+
describe("gui link features", () => {
|
|
37
|
+
it("declares media, gpu, images, shaping and webgl as optional halves of gui", () => {
|
|
38
|
+
expect(guiExtension.linkFeatures?.()).toBe(guiLinkFeatures);
|
|
39
|
+
expect(guiLinkFeatures.map((feature) => feature.name)).toEqual([
|
|
40
|
+
"media",
|
|
41
|
+
"gpu",
|
|
42
|
+
"images",
|
|
43
|
+
"shaping",
|
|
44
|
+
"webgl",
|
|
45
|
+
]);
|
|
46
|
+
expect(media.description).toMatch(/FFmpeg/);
|
|
47
|
+
expect(gpu.description).toMatch(/glslang|GLSL/);
|
|
48
|
+
expect(images.description).toMatch(/stb_image|NanoSVG/);
|
|
49
|
+
expect(shaping.description).toMatch(/HarfBuzz|FreeType/);
|
|
50
|
+
expect(webgl.requires).toEqual(["gpu"]);
|
|
51
|
+
});
|
|
52
|
+
it("links the media bridge and the prebuilt archive", () => {
|
|
53
|
+
mocks.findRuntimeLibrary.mockReturnValue("/tmp/media.a");
|
|
54
|
+
expect(media.runtimeSources?.()).toEqual([join("/tmp/runtime", "ext_media", "media_bridge.c")]);
|
|
55
|
+
expect(media.nativeObjects?.()).toEqual(["/tmp/media.a"]);
|
|
56
|
+
expect(mocks.findRuntimeLibrary).toHaveBeenCalledWith("media");
|
|
57
|
+
});
|
|
58
|
+
it("links the gpu bridge without an archive (the code is in gui.a)", () => {
|
|
59
|
+
expect(gpu.runtimeSources?.()).toEqual([join("/tmp/runtime", "ext_gui", "gpu_bridge.c")]);
|
|
60
|
+
expect(gpu.nativeObjects?.()).toBeUndefined();
|
|
61
|
+
});
|
|
62
|
+
it("links the images bridge without an archive", () => {
|
|
63
|
+
expect(images.runtimeSources?.()).toEqual([join("/tmp/runtime", "ext_gui", "image_bridge.c")]);
|
|
64
|
+
expect(images.nativeObjects?.()).toBeUndefined();
|
|
65
|
+
});
|
|
66
|
+
it("links the shaping bridge without an archive", () => {
|
|
67
|
+
expect(shaping.runtimeSources?.()).toEqual([join("/tmp/runtime", "ext_gui", "text_bridge.c")]);
|
|
68
|
+
expect(shaping.nativeObjects?.()).toBeUndefined();
|
|
69
|
+
});
|
|
70
|
+
it("links the webgl bridge without an archive", () => {
|
|
71
|
+
expect(webgl.runtimeSources?.()).toEqual([join("/tmp/runtime", "ext_gui", "webgl_bridge.c")]);
|
|
72
|
+
expect(webgl.nativeObjects?.()).toBeUndefined();
|
|
73
|
+
});
|
|
74
|
+
it("fails with an actionable message when the media archive is missing", () => {
|
|
75
|
+
mocks.findRuntimeLibrary.mockReturnValue(undefined);
|
|
76
|
+
expect(() => media.nativeObjects?.()).toThrow(/media native library not found/);
|
|
77
|
+
expect(() => media.nativeObjects?.()).toThrow(/npm run media/);
|
|
78
|
+
expect(() => media.nativeObjects?.()).toThrow(/darwin-x64/);
|
|
79
|
+
});
|
|
80
|
+
it("adds FFmpeg's Win32 libraries on Windows only", () => {
|
|
81
|
+
vi.spyOn(process, "platform", "get").mockReturnValue("win32");
|
|
82
|
+
expect(media.linkerFlags?.()).toEqual(["-lbcrypt", "-lole32", "-luser32"]);
|
|
83
|
+
vi.restoreAllMocks();
|
|
84
|
+
vi.spyOn(process, "platform", "get").mockReturnValue("darwin");
|
|
85
|
+
expect(media.linkerFlags?.()).toEqual(["-lm"]);
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
describe("media usage detection", () => {
|
|
89
|
+
it("recognises <video>/<audio> tags in HTML strings", () => {
|
|
90
|
+
expect(hasMediaUsage(usage({ strings: ['<html><video src="x.mp4"></video>'] }))).toBe(true);
|
|
91
|
+
expect(hasMediaUsage(usage({ strings: ["<audio controls></audio>"] }))).toBe(true);
|
|
92
|
+
});
|
|
93
|
+
it("recognises createElement tag names and the Audio constructor", () => {
|
|
94
|
+
expect(hasMediaUsage(usage({ strings: ["video"] }))).toBe(true);
|
|
95
|
+
expect(hasMediaUsage(usage({ identifiers: new Set(["Audio"]) }))).toBe(true);
|
|
96
|
+
expect(hasMediaUsage(usage({ identifiers: new Set(["HTMLVideoElement"]) }))).toBe(true);
|
|
97
|
+
expect(hasMediaUsage(usage({ identifiers: new Set(["decodeAudioData"]) }))).toBe(true);
|
|
98
|
+
});
|
|
99
|
+
it("stays off for a DOM-only page and turns on for dynamic markup", () => {
|
|
100
|
+
expect(hasMediaUsage(usage({ strings: ["<div>hi</div>"], identifiers: new Set(["document"]) }))).toBe(false);
|
|
101
|
+
expect(hasMediaUsage(usage({ dynamicMarkup: true }))).toBe(true);
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
describe("gpu usage detection", () => {
|
|
105
|
+
it("turns on for a WebGL context", () => {
|
|
106
|
+
expect(hasGpuUsage(usage({ getContext: ["webgl2"] }))).toBe(true);
|
|
107
|
+
expect(hasGpuUsage(usage({ getContext: ["experimental-webgl"] }))).toBe(true);
|
|
108
|
+
});
|
|
109
|
+
it("turns on for a context kind decided at run time", () => {
|
|
110
|
+
expect(hasGpuUsage(usage({ getContext: [undefined] }))).toBe(true);
|
|
111
|
+
});
|
|
112
|
+
it("turns on for mix-blend-mode/backdrop-filter in HTML/CSS or the style property", () => {
|
|
113
|
+
expect(hasGpuUsage(usage({ strings: ["style=\"mix-blend-mode: multiply\""] }))).toBe(true);
|
|
114
|
+
expect(hasGpuUsage(usage({ identifiers: new Set(["mixBlendMode"]) }))).toBe(true);
|
|
115
|
+
expect(hasGpuUsage(usage({ strings: ["backdrop-filter: blur(4px)"] }))).toBe(true);
|
|
116
|
+
expect(hasGpuUsage(usage({ identifiers: new Set(["backdropFilter"]) }))).toBe(true);
|
|
117
|
+
});
|
|
118
|
+
it("stays off for a 2D canvas and plain DOM", () => {
|
|
119
|
+
expect(hasGpuUsage(usage({ getContext: ["2d"] }))).toBe(false);
|
|
120
|
+
expect(hasGpuUsage(usage({ strings: ["<canvas id=c></canvas>"] }))).toBe(false);
|
|
121
|
+
});
|
|
122
|
+
it("turns on for dynamic markup", () => {
|
|
123
|
+
expect(hasGpuUsage(usage({ dynamicMarkup: true }))).toBe(true);
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
describe("webgl usage detection", () => {
|
|
127
|
+
it("turns on only for a WebGL context or a webgl string", () => {
|
|
128
|
+
expect(hasWebglUsage(usage({ getContext: ["webgl2"] }))).toBe(true);
|
|
129
|
+
expect(hasWebglUsage(usage({ strings: ["webgl2"] }))).toBe(true);
|
|
130
|
+
expect(hasWebglUsage(usage({ getContext: [undefined] }))).toBe(true);
|
|
131
|
+
});
|
|
132
|
+
it("stays off for a 2D canvas, blend-only CSS and plain DOM", () => {
|
|
133
|
+
expect(hasWebglUsage(usage({ getContext: ["2d"] }))).toBe(false);
|
|
134
|
+
expect(hasWebglUsage(usage({ strings: ["mix-blend-mode: multiply"] }))).toBe(false);
|
|
135
|
+
expect(hasWebglUsage(usage({ strings: ["<canvas id=c></canvas>"] }))).toBe(false);
|
|
136
|
+
});
|
|
137
|
+
it("turns on for dynamic markup", () => {
|
|
138
|
+
expect(hasWebglUsage(usage({ dynamicMarkup: true }))).toBe(true);
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
describe("image usage detection", () => {
|
|
142
|
+
it("turns on for <img>, CSS backgrounds, SVG and drawImage", () => {
|
|
143
|
+
expect(hasImageUsage(usage({ strings: ["<img src=a.png>"] }))).toBe(true);
|
|
144
|
+
expect(hasImageUsage(usage({ strings: ["background-image: url(a.png)"] }))).toBe(true);
|
|
145
|
+
expect(hasImageUsage(usage({ strings: ["<svg viewBox='0 0 10 10'></svg>"] }))).toBe(true);
|
|
146
|
+
expect(hasImageUsage(usage({ identifiers: new Set(["drawImage"]) }))).toBe(true);
|
|
147
|
+
});
|
|
148
|
+
it("stays off for text-only DOM", () => {
|
|
149
|
+
expect(hasImageUsage(usage({ strings: ["<div>Hello</div>"] }))).toBe(false);
|
|
150
|
+
expect(hasImageUsage(usage({ getContext: ["2d"] }))).toBe(false);
|
|
151
|
+
});
|
|
152
|
+
it("turns on for dynamic markup", () => {
|
|
153
|
+
expect(hasImageUsage(usage({ dynamicMarkup: true }))).toBe(true);
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
describe("shaping usage detection", () => {
|
|
157
|
+
it("turns on for non-ASCII text and escaped/encoded codepoints", () => {
|
|
158
|
+
expect(hasShapingUsage(usage({ strings: ["<p>中文测试</p>"] }))).toBe(true);
|
|
159
|
+
expect(hasShapingUsage(usage({ strings: ["café"] }))).toBe(true);
|
|
160
|
+
expect(hasShapingUsage(usage({ strings: ["\\u4e2d\\u6587"] }))).toBe(true);
|
|
161
|
+
expect(hasShapingUsage(usage({ strings: ["中文"] }))).toBe(true);
|
|
162
|
+
});
|
|
163
|
+
it("turns on for author @font-face rules (custom fonts may be CFF/OTF)", () => {
|
|
164
|
+
expect(hasShapingUsage(usage({
|
|
165
|
+
strings: ['@font-face { font-family: "X"; src: url("./x.otf"); }'],
|
|
166
|
+
}))).toBe(true);
|
|
167
|
+
});
|
|
168
|
+
it("stays off for ASCII-only text", () => {
|
|
169
|
+
expect(hasShapingUsage(usage({ strings: ["<div>Hello</div>"] }))).toBe(false);
|
|
170
|
+
});
|
|
171
|
+
it("turns on for dynamic markup", () => {
|
|
172
|
+
expect(hasShapingUsage(usage({ dynamicMarkup: true }))).toBe(true);
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
//# sourceMappingURL=gui-features.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gui-features.test.js","sourceRoot":"","sources":["../../../tests/extensions/gui-features.test.ts"],"names":[],"mappings":"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"}
|
package/doc/ai/cli.md
CHANGED
|
@@ -47,7 +47,9 @@ so restart it after installing a dependency.
|
|
|
47
47
|
--out <dir> Output directory (default: build/)
|
|
48
48
|
--emit <kind> exe | obj | ir (default: exe)
|
|
49
49
|
-O0 .. -O3 Optimization level passed to clang (default: -O2)
|
|
50
|
-
--ext <names> Enable bundled extensions, comma separated (e.g. node,gui
|
|
50
|
+
--ext <names> Enable bundled extensions, comma separated (e.g. node,gui)
|
|
51
|
+
--feature <names> Force optional link features on (media,gpu,images,shaping,webgl,all)
|
|
52
|
+
--no-feature <n> Keep optional link features out even when detected
|
|
51
53
|
--ext-native <m> Register a C++/Rust extension from a JSON manifest
|
|
52
54
|
(comma separated for several)
|
|
53
55
|
--config <path> Use this project config instead of discovering one
|
|
@@ -121,6 +123,8 @@ matching field. `--no-config` skips discovery entirely.
|
|
|
121
123
|
| `pgoDir` | string | Profile directory (default `<outDir>/pgo`) |
|
|
122
124
|
| `extensions` | string[] | Bundled extensions to enable, e.g. `["node"]` |
|
|
123
125
|
| `extNative` | string[] | Native extension manifest paths |
|
|
126
|
+
| `features` | string[] | Optional link features to force on, e.g. `["media"]` / `["all"]` |
|
|
127
|
+
| `noFeatures` | string[] | Optional link features to keep out even when detected |
|
|
124
128
|
| `force` | boolean | Ignore the incremental cache |
|
|
125
129
|
| `app.name` / `app.icon` / `app.bundle` / `app.bundleId` | | Application metadata ([icon.md](../icon.md)) |
|
|
126
130
|
|
package/doc/ai/extensions.md
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
# Extensions: Node modules, GUI,
|
|
1
|
+
# Extensions: Node modules, GUI, link features, C++/Rust libraries
|
|
2
2
|
|
|
3
3
|
The compiler core is platform-agnostic. Anything platform-specific — Node's
|
|
4
4
|
`fs`, an HTML/CSS renderer, your own C++ library — arrives as an **extension**
|
|
5
5
|
that contributes module bindings plus the C/C++ sources or objects to link.
|
|
6
|
+
Heavy optional halves of an extension (FFmpeg, glslang) are **link features**
|
|
7
|
+
selected from the program instead of separate extension flags.
|
|
6
8
|
|
|
7
9
|
## The rule that trips people up
|
|
8
10
|
|
|
@@ -74,8 +76,9 @@ blocks, because the runtime parser only reads inline `<style>`; and it rewrites
|
|
|
74
76
|
a bundled three.js module's `WebGLRenderer` to use the real WebGL 2 backend:
|
|
75
77
|
only its shader unroller is patched, and no Canvas2D fallback is bundled. It
|
|
76
78
|
ships as a per-platform prebuilt `gui.a`/`gui.lib` because it is C++. `<img>` decodes through the engine
|
|
77
|
-
itself; `<video>`/`<audio>`
|
|
78
|
-
|
|
79
|
+
itself; `<video>`/`<audio>` decoding (FFmpeg) and GLSL translation (glslang) are
|
|
80
|
+
**optional link features** selected from the program — see
|
|
81
|
+
[Optional link features](#optional-link-features-media-gpu-images-shaping-webgl). `<canvas>` is
|
|
79
82
|
supported too: `getContext("2d")` returns a context whose fills, paths,
|
|
80
83
|
gradients, text and `drawImage` are rasterised by a self-written CPU rasteriser
|
|
81
84
|
(plus line caps/joins, dashed strokes, `ellipse` and `roundRect`), and element
|
|
@@ -85,9 +88,13 @@ text, images and children in it) can be translated, scaled and rotated without
|
|
|
85
88
|
reflowing anything — animate it per frame from `requestAnimationFrame` or with
|
|
86
89
|
`transition: transform` (see `examples/gui/pelican-svg`). The CSS subset also
|
|
87
90
|
covers `@media`, `::before`/`::after` generated content, multi-layer linear/radial
|
|
88
|
-
backgrounds, `
|
|
89
|
-
`
|
|
90
|
-
|
|
91
|
+
backgrounds, `calc()`, `text-shadow`/`box-shadow` with a true Gaussian blur,
|
|
92
|
+
`clip-path`, `filter` colour effects, `backdrop-filter` compositing,
|
|
93
|
+
`@keyframes` and `transition`/`animation` timing functions, `letter-spacing`,
|
|
94
|
+
`text-transform`, inline-level `flex`/`grid`, `grid-area`, `aspect-ratio`, auto
|
|
95
|
+
margins, percentage `border-radius`, `outline`, tiled `background-size` for
|
|
96
|
+
`url()` layers, document CSS on SVG children and text-only vertical writing
|
|
97
|
+
mode. `filter: blur()` is still a documented approximation. If the archive is
|
|
91
98
|
missing for your platform, the build fails with an actionable message; design
|
|
92
99
|
and roadmap live in [../gui.md](../gui.md) (overview; the engine is documented by
|
|
93
100
|
function under [`doc/gui/`](../gui/)), and the scripting surface in
|
|
@@ -101,7 +108,7 @@ Pages written for the browser also get the browser globals they reach for —
|
|
|
101
108
|
(`AudioContext` with gain, oscillator, buffer-source, biquad, compressor,
|
|
102
109
|
stereo-panner, constant-source and delay nodes, a real 48 kHz mixer, per-sample
|
|
103
110
|
AudioParam automation, and `decodeAudioData` for WAV in-engine plus compressed
|
|
104
|
-
formats through `media`) — plus a frame pump that
|
|
111
|
+
formats through the `media` feature) — plus a frame pump that
|
|
105
112
|
starts at `loadHTML` and re-arms only while animation-frame callbacks remain, so
|
|
106
113
|
a page that never calls `run()` still paints and then exits. **WebGL 1.0 and 2.0 are implemented**: `canvas.getContext("webgl")` /
|
|
107
114
|
`"webgl2"` return a GPU context whose GLSL ES shaders are compiled to SPIR-V by
|
|
@@ -109,19 +116,47 @@ a bundled glslang — consumed by Vulkan, or cross-compiled to MSL by bundled
|
|
|
109
116
|
SPIRV-Cross on Metal — and drawn through SDL_GPU; the page composites the colour
|
|
110
117
|
texture without a CPU readback, and WebGL 2 adds VAOs, instancing, integer
|
|
111
118
|
attributes, sampler objects, `texStorage2D` and buffer copies (see
|
|
112
|
-
[../gui/webgl.md](../gui/webgl.md)). WebXR
|
|
113
|
-
`
|
|
114
|
-
|
|
119
|
+
[../gui/webgl.md](../gui/webgl.md)). WebXR and streaming are **not**
|
|
120
|
+
implemented: `typeof` answers `"undefined"` so a page takes its own fallback
|
|
121
|
+
branch. `fetch`
|
|
115
122
|
is **not** a GUI extension feature: the core runtime provides it (`http://`,
|
|
116
123
|
plus local `file://` and relative paths; no HTTPS or streaming), so GUI
|
|
117
124
|
programs can use it too. See [../implemented/fetch.md](../implemented/fetch.md).
|
|
118
125
|
|
|
119
|
-
### `media`
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
126
|
+
### Optional link features (`media`, `gpu`, `images`, `shaping`, `webgl`)
|
|
127
|
+
|
|
128
|
+
`gui` is one extension, but its heavy halves are optional **link features**. The
|
|
129
|
+
compiler scans the bundled HTML/CSS/TS (imported `.html` assets and their inlined
|
|
130
|
+
CSS are part of the bundle) and selects them per program; you do not pass an
|
|
131
|
+
extension flag:
|
|
132
|
+
|
|
133
|
+
- **`media`** — FFmpeg decoding for `<video>`/`<audio>` and compressed
|
|
134
|
+
`decodeAudioData`. Selected by a `<video>`/`<audio>` element,
|
|
135
|
+
`createElement("video"/"audio")`, `new Audio()`, `decodeAudioData`, or markup
|
|
136
|
+
built at run time. Links the FFmpeg-backed `media.a`/`media.lib`.
|
|
137
|
+
- **`gpu`** — the glslang/SPIRV-Cross GLSL translator shared by WebGL and
|
|
138
|
+
`mix-blend-mode`. Selected by `getContext("webgl"/"webgl2"/…)` (or a context
|
|
139
|
+
kind decided at run time), any `webgl` string, or `mix-blend-mode`.
|
|
140
|
+
- **`images`** — stb_image/NanoSVG decoding for `<img>`, inline `<svg>`, CSS
|
|
141
|
+
`background-image`/`url(...)`, `drawImage`/`createImageBitmap`/`Image`, and an
|
|
142
|
+
app icon. A text-only page links neither decoder.
|
|
143
|
+
- **`shaping`** — HarfBuzz + FreeType for full OpenType shaping (ligatures,
|
|
144
|
+
complex scripts) and CFF/OTF/variable fonts. Selected automatically for
|
|
145
|
+
non-ASCII text (or an escaped/entity codepoint) or an author `@font-face`
|
|
146
|
+
rule; a Latin-only page keeps the stb_truetype backend and links neither
|
|
147
|
+
library.
|
|
148
|
+
- **`webgl`** — the WebGL context and DOM bindings. Selected by a WebGL
|
|
149
|
+
`getContext(...)` or a `webgl` string; it requires `gpu`, so both activate
|
|
150
|
+
together. A page that never asks for WebGL links neither.
|
|
151
|
+
|
|
152
|
+
Override the scan with `--feature media,gpu,images,shaping,webgl` (or `all`) and keep a
|
|
153
|
+
feature out with `--no-feature media`. `--verbose` prints the selected set. A
|
|
154
|
+
program that only renders HTML/CSS/2D canvas links no FFmpeg, glslang, image
|
|
155
|
+
decoder, HarfBuzz/FreeType or WebGL context; a page that
|
|
156
|
+
builds HTML/CSS from runtime data should pass `--feature all` because the scan
|
|
157
|
+
cannot see it. If an auto-detected feature's archive is missing, the build warns
|
|
158
|
+
and the capability degrades at run time (media elements fire `error`); a forced
|
|
159
|
+
feature makes it an error.
|
|
125
160
|
|
|
126
161
|
The DOM API is the same as for any HTML media element: `play()` / `pause()` /
|
|
127
162
|
`load()`, the `paused` / `ended` / `duration` / `currentTime` / `volume` /
|
|
@@ -129,16 +164,11 @@ The DOM API is the same as for any HTML media element: `play()` / `pause()` /
|
|
|
129
164
|
`src` properties, and `loadedmetadata`/`play`/`pause`/`ended`/`timeupdate`/
|
|
130
165
|
`error` events. There are no built-in controls — draw your own chrome with
|
|
131
166
|
elements and CSS (see `examples/gui/media.ts`). Video frames and audio PCM are
|
|
132
|
-
decoded on the main thread; video goes through the image texture path.
|
|
133
|
-
the
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
needs a POSIX shell (Git for Windows' bundled bash) and a native GNU make
|
|
138
|
-
(Chocolatey `make`, or `xbintsc_MAKE`). See
|
|
139
|
-
[../gui/build.md](../gui/build.md). Without the archive, or on a host where
|
|
140
|
-
`npm run media` has not run, media elements report `error`; see
|
|
141
|
-
[../gui/known-issues.md](../gui/known-issues.md).
|
|
167
|
+
decoded on the main thread; video goes through the image texture path. Building
|
|
168
|
+
the archive on Windows needs a POSIX shell (Git for Windows' bundled bash) and a
|
|
169
|
+
native GNU make (Chocolatey `make`, or `xbintsc_MAKE`). See
|
|
170
|
+
[../gui/build.md](../gui/build.md) and
|
|
171
|
+
[../gui/media.md](../gui/media.md).
|
|
142
172
|
|
|
143
173
|
## Third-party npm packages
|
|
144
174
|
|
|
@@ -123,15 +123,18 @@ optional `@xbintsc/<os>-<arch>` npm package ships it (reinstall without
|
|
|
123
123
|
|
|
124
124
|
### `media native library not found at …`
|
|
125
125
|
|
|
126
|
-
`<video>`/`<audio>`
|
|
127
|
-
`media.lib` on Windows). The `@xbintsc/<os>-<arch>` npm
|
|
128
|
-
the release builds it; otherwise build it
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
126
|
+
`<video>`/`<audio>` decoding needs the optional `media` link feature and its
|
|
127
|
+
archive (`media.a`, or `media.lib` on Windows). The `@xbintsc/<os>-<arch>` npm
|
|
128
|
+
package ships it where the release builds it; otherwise build it with
|
|
129
|
+
`npm run media`. When the feature is selected automatically and the archive is
|
|
130
|
+
missing, the build prints a **warning** and continues; media elements then simply
|
|
131
|
+
fire `error`. An explicit `--feature media` (or the deprecated `--ext media`)
|
|
132
|
+
makes it a hard error instead. Use `--no-feature media` to opt out on purpose.
|
|
133
|
+
On Windows the FFmpeg build additionally needs
|
|
132
134
|
a POSIX shell (Git for Windows' bash) and a native GNU make (Chocolatey `make`,
|
|
133
135
|
or `xbintsc_MAKE`). The script names whichever is missing. See
|
|
134
|
-
[../gui/build.md](../gui/build.md)
|
|
136
|
+
[../gui/build.md](../gui/build.md) and
|
|
137
|
+
[../gui/build.md#link-features](../gui/build.md#link-features).
|
|
135
138
|
|
|
136
139
|
### `Icon file not found` / icon tools missing
|
|
137
140
|
|
package/doc/ai/zh-CN/cli.md
CHANGED
|
@@ -40,7 +40,9 @@
|
|
|
40
40
|
--out <dir> 输出目录(默认 build/)
|
|
41
41
|
--emit <kind> exe | obj | ir(默认 exe)
|
|
42
42
|
-O0 .. -O3 传给 clang 的优化级别(默认 -O2)
|
|
43
|
-
--ext <names> 开启内置扩展,逗号分隔(如 node,gui
|
|
43
|
+
--ext <names> 开启内置扩展,逗号分隔(如 node,gui)
|
|
44
|
+
--feature <names> 强制开启可选链接特性(media,gpu,images,shaping,webgl,all)
|
|
45
|
+
--no-feature <n> 即使检测到也不链接该可选特性
|
|
44
46
|
--ext-native <m> 通过 JSON 清单注册 C++/Rust 扩展(多个用逗号分隔)
|
|
45
47
|
--config <path> 使用指定项目配置,不做自动发现
|
|
46
48
|
--no-config 完全不读取项目配置
|
|
@@ -102,6 +104,8 @@ profile 数据可能独立于源码变化。
|
|
|
102
104
|
| `pgoDir` | string | Profile 目录(默认 `<outDir>/pgo`) |
|
|
103
105
|
| `extensions` | string[] | 开启的内置扩展,如 `["node"]` |
|
|
104
106
|
| `extNative` | string[] | 原生扩展清单路径 |
|
|
107
|
+
| `features` | string[] | 强制开启的可选链接特性,如 `["media"]` / `["all"]` |
|
|
108
|
+
| `noFeatures` | string[] | 即使检测到也保持关闭的可选链接特性 |
|
|
105
109
|
| `force` | boolean | 忽略增量缓存 |
|
|
106
110
|
| `app.name` / `app.icon` / `app.bundle` / `app.bundleId` | | 应用元信息([icon.md](../../zh-CN/icon.md)) |
|
|
107
111
|
|