xbintsc 0.5.31 → 0.5.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -10
- package/dist/src/binder/references.js +14 -1
- package/dist/src/binder/references.js.map +1 -1
- package/dist/src/cli/help.d.ts +1 -1
- package/dist/src/codegen/generator/module.d.ts +1 -0
- package/dist/src/codegen/generator/module.js +54 -0
- package/dist/src/codegen/generator/module.js.map +1 -1
- package/dist/src/codegen/generator/statements/variables.js +6 -4
- package/dist/src/codegen/generator/statements/variables.js.map +1 -1
- package/dist/src/driver/version.d.ts +1 -1
- package/dist/src/driver/version.js +1 -1
- package/dist/src/extensions/gui/css.d.ts +26 -0
- package/dist/src/extensions/gui/css.js +100 -0
- package/dist/src/extensions/gui/css.js.map +1 -0
- package/dist/src/extensions/gui/html.js +9 -2
- package/dist/src/extensions/gui/html.js.map +1 -1
- package/dist/src/extensions/gui/index.js +16 -2
- package/dist/src/extensions/gui/index.js.map +1 -1
- package/dist/src/extensions/gui/three.d.ts +16 -0
- package/dist/src/extensions/gui/three.js +22 -0
- package/dist/src/extensions/gui/three.js.map +1 -0
- package/dist/src/extensions/media/index.d.ts +6 -5
- package/dist/src/extensions/media/index.js +12 -14
- package/dist/src/extensions/media/index.js.map +1 -1
- package/dist/tests/e2e/compile-builtins.test.js +24 -0
- package/dist/tests/e2e/compile-builtins.test.js.map +1 -1
- package/dist/tests/e2e/compile-objects-classes.test.js +23 -0
- package/dist/tests/e2e/compile-objects-classes.test.js.map +1 -1
- package/dist/tests/e2e/gui-browser.test.js +1 -1
- package/dist/tests/e2e/gui-browser.test.js.map +1 -1
- package/dist/tests/e2e/gui-effects.test.d.ts +6 -0
- package/dist/tests/e2e/gui-effects.test.js +262 -0
- package/dist/tests/e2e/gui-effects.test.js.map +1 -0
- package/dist/tests/e2e/gui-example-webgl.test.d.ts +10 -0
- package/dist/tests/e2e/gui-example-webgl.test.js +75 -0
- package/dist/tests/e2e/gui-example-webgl.test.js.map +1 -0
- package/dist/tests/e2e/gui-example-webgl2.test.d.ts +8 -0
- package/dist/tests/e2e/gui-example-webgl2.test.js +72 -0
- package/dist/tests/e2e/gui-example-webgl2.test.js.map +1 -0
- package/dist/tests/e2e/gui-layout.test.js +48 -0
- package/dist/tests/e2e/gui-layout.test.js.map +1 -1
- package/dist/tests/e2e/gui-media.test.js +5 -4
- package/dist/tests/e2e/gui-media.test.js.map +1 -1
- package/dist/tests/e2e/gui-webgl.test.d.ts +11 -0
- package/dist/tests/e2e/gui-webgl.test.js +179 -0
- package/dist/tests/e2e/gui-webgl.test.js.map +1 -0
- package/dist/tests/e2e/gui-webgl2.test.d.ts +10 -0
- package/dist/tests/e2e/gui-webgl2.test.js +238 -0
- package/dist/tests/e2e/gui-webgl2.test.js.map +1 -0
- package/dist/tests/extensions/gui.test.js +41 -0
- package/dist/tests/extensions/gui.test.js.map +1 -1
- package/dist/tests/extensions/media.test.js +7 -3
- package/dist/tests/extensions/media.test.js.map +1 -1
- package/doc/ai/extensions.md +29 -9
- package/doc/ai/troubleshooting.md +12 -8
- package/doc/ai/zh-CN/extensions.md +26 -8
- package/doc/ai/zh-CN/troubleshooting.md +10 -6
- package/doc/gui/api.md +3 -2
- package/doc/gui/build.md +72 -16
- package/doc/gui/canvas.md +11 -3
- package/doc/gui/dom.md +33 -18
- package/doc/gui/known-issues.md +57 -24
- package/doc/gui/layout.md +18 -0
- package/doc/gui/media.md +17 -13
- package/doc/gui/rendering.md +50 -3
- package/doc/gui/webgl.md +256 -0
- package/doc/gui.md +108 -17
- package/doc/npm-package.md +6 -4
- package/doc/requirements.md +18 -9
- package/doc/zh-CN/gui/api.md +3 -2
- package/doc/zh-CN/gui/build.md +64 -15
- package/doc/zh-CN/gui/canvas.md +9 -2
- package/doc/zh-CN/gui/dom.md +20 -7
- package/doc/zh-CN/gui/known-issues.md +45 -19
- package/doc/zh-CN/gui/layout.md +14 -0
- package/doc/zh-CN/gui/media.md +15 -11
- package/doc/zh-CN/gui/rendering.md +41 -4
- package/doc/zh-CN/gui/webgl.md +115 -0
- package/doc/zh-CN/gui.md +89 -14
- package/doc/zh-CN/npm-package.md +9 -6
- package/doc/zh-CN/requirements.md +12 -6
- package/llms.txt +2 -0
- package/package.json +1 -1
- package/runtime/ext_gui/browser.cpp +39 -13
- package/runtime/ext_gui/canvas.cpp +3 -18
- package/runtime/ext_gui/canvas_internal.h +10 -0
- package/runtime/ext_gui/canvas_raster.cpp +60 -0
- package/runtime/ext_gui/clip_values.cpp +246 -0
- package/runtime/ext_gui/css.cpp +94 -0
- package/runtime/ext_gui/css.h +22 -1
- package/runtime/ext_gui/css_match.cpp +3 -0
- package/runtime/ext_gui/css_selector.cpp +9 -0
- package/runtime/ext_gui/css_sheet.cpp +89 -45
- package/runtime/ext_gui/document.cpp +4 -1
- package/runtime/ext_gui/document.h +2 -0
- package/runtime/ext_gui/dom.h +16 -0
- package/runtime/ext_gui/dom_api.cpp +1 -0
- package/runtime/ext_gui/dom_api_canvas.cpp +17 -80
- package/runtime/ext_gui/dom_api_canvas_extra.cpp +130 -1
- package/runtime/ext_gui/dom_api_canvas_pending.cpp +41 -0
- package/runtime/ext_gui/dom_api_internal.h +259 -0
- package/runtime/ext_gui/dom_api_webgl.cpp +376 -0
- package/runtime/ext_gui/dom_api_webgl2.cpp +434 -0
- package/runtime/ext_gui/dom_api_webgl2_draw.cpp +269 -0
- package/runtime/ext_gui/dom_api_webgl_buffer.cpp +212 -0
- package/runtime/ext_gui/dom_api_webgl_rt.h +30 -0
- package/runtime/ext_gui/dom_api_webgl_shader.cpp +443 -0
- package/runtime/ext_gui/dom_api_webgl_state.cpp +444 -0
- package/runtime/ext_gui/dom_api_webgl_texture.cpp +445 -0
- package/runtime/ext_gui/effect_values.cpp +312 -0
- package/runtime/ext_gui/gradient_values.cpp +476 -0
- package/runtime/ext_gui/grid_values.cpp +230 -0
- package/runtime/ext_gui/gui_canvas.cpp +50 -2
- package/runtime/ext_gui/gui_engine.h +27 -0
- package/runtime/ext_gui/gui_events.cpp +4 -1
- package/runtime/ext_gui/gui_media.cpp +1 -1
- package/runtime/ext_gui/gui_webgl.cpp +83 -0
- package/runtime/ext_gui/layout.cpp +21 -0
- package/runtime/ext_gui/layout_flow.cpp +81 -4
- package/runtime/ext_gui/layout_flow_internal.h +31 -0
- package/runtime/ext_gui/layout_grid.cpp +374 -0
- package/runtime/ext_gui/media.h +1 -1
- package/runtime/ext_gui/media_api.h +2 -2
- package/runtime/ext_gui/media_query.cpp +211 -0
- package/runtime/ext_gui/paint.cpp +111 -77
- package/runtime/ext_gui/paint.h +33 -3
- package/runtime/ext_gui/paint_background.cpp +229 -0
- package/runtime/ext_gui/paint_clip.cpp +268 -0
- package/runtime/ext_gui/paint_effects.cpp +324 -0
- package/runtime/ext_gui/paint_internal.h +85 -0
- package/runtime/ext_gui/renderer.cpp +8 -31
- package/runtime/ext_gui/renderer_clip.cpp +196 -0
- package/runtime/ext_gui/renderer_image.cpp +13 -8
- package/runtime/ext_gui/renderer_internal.h +15 -8
- package/runtime/ext_gui/renderer_text.cpp +6 -31
- package/runtime/ext_gui/style.cpp +343 -20
- package/runtime/ext_gui/style.h +144 -3
- package/runtime/ext_gui/style_print.cpp +134 -1
- package/runtime/ext_gui/style_values.cpp +152 -126
- package/runtime/ext_gui/style_values_internal.h +35 -0
- package/runtime/ext_gui/webgl.h +466 -0
- package/runtime/ext_gui/webgl2_constants.h +274 -0
- package/runtime/ext_gui/webgl_buffer.cpp +565 -0
- package/runtime/ext_gui/webgl_constants.h +317 -0
- package/runtime/ext_gui/webgl_context.cpp +466 -0
- package/runtime/ext_gui/webgl_draw.cpp +495 -0
- package/runtime/ext_gui/webgl_glsl.h +125 -0
- package/runtime/ext_gui/webgl_glsl_compile.cpp +431 -0
- package/runtime/ext_gui/webgl_glsl_rewrite.cpp +349 -0
- package/runtime/ext_gui/webgl_glsl_scan.cpp +581 -0
- package/runtime/ext_gui/webgl_msl.cpp +62 -0
- package/runtime/ext_gui/webgl_msl.h +33 -0
- package/runtime/ext_gui/webgl_pipeline.cpp +274 -0
- package/runtime/ext_gui/webgl_program_internal.h +18 -0
- package/runtime/ext_gui/webgl_shader.cpp +582 -0
- package/runtime/ext_gui/webgl_texture.cpp +293 -0
- package/runtime/ext_gui/webgl_uniform.cpp +167 -0
- package/runtime/ext_gui/webgl_webgl2.cpp +224 -0
- package/runtime/ext_media/media.cpp +1 -1
- package/runtime/ext_media/media_bridge.c +9 -3
- package/runtime/rt_internal.h +1 -0
- package/runtime/xt_containers/access.inc +8 -0
- package/runtime/xt_regex/api.inc +2 -0
- package/runtime/xt_regex/matcher.inc +16 -3
- package/runtime/xt_regex/parser.inc +8 -2
- package/runtime/xt_regex/types.inc +3 -0
- package/runtime/xt_stdlib2/regexp-match.inc +60 -21
- package/runtime/xt_stdlib2/regexp.inc +1 -0
- package/runtime/xt_typed_array.c +1 -1
- package/scripts/build-gui.ts +90 -3
- package/scripts/build-media.ts +323 -58
- package/scripts/setup-vs-toolchain.ps1 +152 -0
- package/src/binder/references.ts +13 -1
- package/src/codegen/generator/module.ts +50 -0
- package/src/codegen/generator/statements/variables.ts +6 -3
- package/src/driver/version.ts +1 -1
- package/src/extensions/gui/css.ts +113 -0
- package/src/extensions/gui/html.ts +9 -2
- package/src/extensions/gui/index.ts +16 -2
- package/src/extensions/gui/three.ts +25 -0
- package/src/extensions/media/index.ts +13 -16
package/doc/gui/webgl.md
ADDED
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
# WebGL (a `<canvas>` drawn on the GPU)
|
|
2
|
+
|
|
3
|
+
> Part of the [GUI extension](../gui.md); the engine overview, locked
|
|
4
|
+
> decisions and roadmap live there.
|
|
5
|
+
|
|
6
|
+
A `<canvas>` can ask for a WebGL context instead of the 2D one:
|
|
7
|
+
|
|
8
|
+
```ts
|
|
9
|
+
const canvas: any = document.getElementById("scene");
|
|
10
|
+
const gl: any = canvas.getContext("webgl2"); // or "webgl" / "experimental-webgl"
|
|
11
|
+
if (gl == null) {
|
|
12
|
+
// no GPU backend that can consume WebGL's shaders on this platform
|
|
13
|
+
}
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Unlike the 2D context, which rasterises into a CPU bitmap and uploads it as a
|
|
17
|
+
texture, a WebGL context **renders on the GPU**: vertex transform, lighting,
|
|
18
|
+
texture sampling, depth testing and blending all execute in the SDL_GPU
|
|
19
|
+
pipeline (Vulkan on Windows/Linux, Metal on macOS). The page composites the
|
|
20
|
+
context's colour texture directly, so no pixels are read back to the CPU for
|
|
21
|
+
display.
|
|
22
|
+
|
|
23
|
+
Both **WebGL 1.0** and **WebGL 2.0** are available. A canvas keeps the first
|
|
24
|
+
context kind it asks for: after `getContext("webgl2")` a later
|
|
25
|
+
`getContext("webgl")` answers `null`, and the other way round. A WebGL 2 context
|
|
26
|
+
also satisfies `instanceof WebGLRenderingContext` (its prototype inherits the
|
|
27
|
+
WebGL 1 one) and adds the WebGL 2 constants and methods.
|
|
28
|
+
|
|
29
|
+
## How a frame reaches the screen
|
|
30
|
+
|
|
31
|
+
- Each context owns one offscreen `R8G8B8A8_UNORM` colour texture (the drawing
|
|
32
|
+
buffer) and a `D32_FLOAT` depth texture, sized from the canvas's `width` /
|
|
33
|
+
`height` attributes. `canvas.width = …` recreates them and discards the
|
|
34
|
+
contents, like the DOM rule.
|
|
35
|
+
- The context records into its own SDL_GPU command buffer. `clear`/`draw*`
|
|
36
|
+
keep a render pass open; a buffer/texture upload or a framebuffer change ends
|
|
37
|
+
it and starts a new pass with `LOAD`, so the drawing buffer persists between
|
|
38
|
+
draws just like WebGL's.
|
|
39
|
+
- Once per frame, before the page's own render pass, the engine submits every
|
|
40
|
+
WebGL command buffer. The image pipeline then samples the colour texture as
|
|
41
|
+
an ordinary `PaintImage`, with no CPU copy.
|
|
42
|
+
- WebGL's origin is bottom-left while SDL_GPU render targets are top-left, so
|
|
43
|
+
the framebuffer is stored top-down: `viewport`/`scissor` are converted,
|
|
44
|
+
`readPixels` flips rows back, and the compositor sees an upright texture.
|
|
45
|
+
- A fixed-function state change (`blendFunc`, `depthFunc`, `cullFace`,
|
|
46
|
+
`colorMask`, …) changes which `SDL_GPUGraphicsPipeline` is needed, so
|
|
47
|
+
pipelines are created lazily per (program, vertex layout, state) and cached on
|
|
48
|
+
the program.
|
|
49
|
+
|
|
50
|
+
## Shaders: GLSL ES to SPIR-V (and on to MSL)
|
|
51
|
+
|
|
52
|
+
SDL_GPU cannot compile GLSL at run time, and each backend consumes its own
|
|
53
|
+
format, so the engine ships two statically linked translators:
|
|
54
|
+
|
|
55
|
+
- **glslang** compiles the rewritten GLSL to SPIR-V, which the Vulkan backend
|
|
56
|
+
consumes directly;
|
|
57
|
+
- **SPIRV-Cross** cross-compiles that same SPIR-V to Metal Shading Language text,
|
|
58
|
+
which the Metal backend compiles at run time.
|
|
59
|
+
|
|
60
|
+
Both live in `gui.a` / `gui.lib`; the Metal path reuses the SPIR-V module rather
|
|
61
|
+
than growing a second GLSL front end, so both backends accept exactly the same
|
|
62
|
+
shader subset. The path is:
|
|
63
|
+
|
|
64
|
+
1. `shaderSource` stores the GLSL ES text; `compileShader` translates it once
|
|
65
|
+
for `COMPILE_STATUS` / `getShaderInfoLog`.
|
|
66
|
+
2. `linkProgram` translates both stages again with one shared attribute and
|
|
67
|
+
varying location map, compiles them with glslang, and then creates the
|
|
68
|
+
`SDL_GPUShader` objects: from the SPIR-V on Vulkan, or from the MSL text
|
|
69
|
+
SPIRV-Cross produced on Metal.
|
|
70
|
+
3. The generated SPIR-V is reflected to obtain the exact std140 offsets, array
|
|
71
|
+
strides and matrix strides of the uniform block — the shader text may size an
|
|
72
|
+
array with a macro, but glslang has already resolved it. SPIRV-Cross keeps
|
|
73
|
+
those offsets in the MSL struct, so one uniform layout serves both backends.
|
|
74
|
+
|
|
75
|
+
The translator (`runtime/ext_gui/webgl_glsl*.cpp`) handles GLSL ES 1.00 and
|
|
76
|
+
3.00 sources:
|
|
77
|
+
|
|
78
|
+
| WebGL spelling | Rewritten to |
|
|
79
|
+
| --- | --- |
|
|
80
|
+
| `attribute vec3 a_pos` | `layout(location = N) in vec3 a_pos` |
|
|
81
|
+
| `varying vec2 v_uv` | `layout(location = N) out/in vec2 v_uv` (one shared name → location map) |
|
|
82
|
+
| `gl_FragColor` | `layout(location = 0) out highp vec4 xt_FragColor` |
|
|
83
|
+
| `texture2D`, `textureCube`, `texture2DProj` | `texture`, `texture`, `textureProj` |
|
|
84
|
+
| `texture2DLodEXT` / `textureCubeLodEXT` | `textureLod` |
|
|
85
|
+
| non-sampler uniforms | one `layout(std140) uniform XtUniforms { … }` block |
|
|
86
|
+
| `uniform sampler2D u_tex` | `layout(set = 2, binding = N) uniform sampler2D u_tex` (fragment) or set 0 (vertex) |
|
|
87
|
+
| `gl_FragData[0]` | `xt_FragColor` |
|
|
88
|
+
| a missing `#version` / `#version 100` | `#version 310 es` |
|
|
89
|
+
|
|
90
|
+
Non-sampler uniforms are merged across both stages and emitted as one block in
|
|
91
|
+
each stage (set 1 for the vertex shader, set 3 for the fragment shader), which
|
|
92
|
+
matches SDL_GPU's Vulkan descriptor layout. On Metal the same declarations
|
|
93
|
+
become `[[buffer(0)]]` and `[[texture(N)]]`/`[[sampler(N)]]`, the slots SDL_GPU's
|
|
94
|
+
Metal backend binds. `uniformMatrix4fv` writes column-major floats into the
|
|
95
|
+
reflected offsets; `uniform1i` on a sampler stores the texture unit. The block
|
|
96
|
+
is pushed with the dynamic uniform-buffer API on every draw.
|
|
97
|
+
|
|
98
|
+
Limits of the translator: struct-typed uniforms, user uniform blocks, uniform
|
|
99
|
+
arrays whose size is not resolved by the preprocessor, sampler arrays and cube
|
|
100
|
+
maps are rejected (the link/shader info log says so). Shader code inside
|
|
101
|
+
`#ifdef` is fine; non-sampler uniform declarations are moved to the enclosing
|
|
102
|
+
top-level position so the block stays unconditional.
|
|
103
|
+
|
|
104
|
+
### GLSL ES 3.00 (WebGL 2)
|
|
105
|
+
|
|
106
|
+
A `#version 300 es` source is accepted as-is apart from the version bump:
|
|
107
|
+
top-level `in`/`out` declarations become attributes/varyings, a named fragment
|
|
108
|
+
output (`out vec4 fragColor;`) becomes an `xt_FragColor`-style output, and
|
|
109
|
+
`texture()` / `textureLod()` already match the Vulkan dialect. Multiple fragment
|
|
110
|
+
outputs are given sequential locations, but the render pass has one colour
|
|
111
|
+
target, so only the first is written. `gl_VertexID` and `gl_InstanceID` are
|
|
112
|
+
available from GLSL ES 3.00, which is what the instanced example uses.
|
|
113
|
+
|
|
114
|
+
## Supported API
|
|
115
|
+
|
|
116
|
+
- **Context**: `getContext("webgl")`, `canvas`, `drawingBufferWidth/Height`,
|
|
117
|
+
`getParameter`, `getError`, `getSupportedExtensions`, `getExtension`,
|
|
118
|
+
`getContextAttributes`, `isContextLost`, `getShaderPrecisionFormat`, and the
|
|
119
|
+
stencil entry points (accepted; the depth target has no stencil attachment).
|
|
120
|
+
- **Shaders and programs**: `createShader`, `shaderSource`, `compileShader`,
|
|
121
|
+
`getShaderParameter`, `getShaderInfoLog`, `getShaderSource`, `deleteShader`,
|
|
122
|
+
`createProgram`, `attachShader`, `detachShader`, `linkProgram`,
|
|
123
|
+
`getProgramParameter`, `getProgramInfoLog`, `getAttachedShaders`,
|
|
124
|
+
`validateProgram`, `deleteProgram`, `useProgram`,
|
|
125
|
+
`getActiveUniform`/`getActiveAttrib`, `getUniformLocation`,
|
|
126
|
+
`getAttribLocation`, `bindAttribLocation`.
|
|
127
|
+
- **Uniforms**: `uniform1f`…`uniform4f`, `uniform1i`…`uniform4i`,
|
|
128
|
+
`uniform1fv`…`uniform4fv`, `uniform1iv`…`uniform4iv`,
|
|
129
|
+
`uniformMatrix2fv`/`3fv`/`4fv`, `getUniform`.
|
|
130
|
+
- **Buffers and attributes**: `createBuffer`, `bindBuffer`, `bufferData`,
|
|
131
|
+
`bufferSubData`, `deleteBuffer`, `getBufferParameter`,
|
|
132
|
+
`enableVertexAttribArray`, `disableVertexAttribArray`,
|
|
133
|
+
`vertexAttribPointer`, `vertexAttrib1f`…`4f` / `1fv`…`4fv`,
|
|
134
|
+
`getVertexAttrib`.
|
|
135
|
+
- **Drawing**: `drawArrays`, `drawElements` (UNSIGNED_BYTE, UNSIGNED_SHORT,
|
|
136
|
+
UNSIGNED_INT; `TRIANGLE_FAN` and `LINE_LOOP` are expanded to lists).
|
|
137
|
+
`POINTS`, `LINES`, `LINE_STRIP`, `TRIANGLES` and `TRIANGLE_STRIP` map to the
|
|
138
|
+
matching SDL primitive.
|
|
139
|
+
- **Textures**: `createTexture`, `bindTexture`, `activeTexture`,
|
|
140
|
+
`texParameteri`/`texParameterf`, `getTexParameter`, `texImage2D` (raw pixels,
|
|
141
|
+
`<img>`, `<canvas>` and `ImageData` sources), `texSubImage2D`,
|
|
142
|
+
`generateMipmap`, `deleteTexture`. `UNPACK_FLIP_Y_WEBGL` and
|
|
143
|
+
`UNPACK_PREMULTIPLY_ALPHA_WEBGL` are honoured. Everything is converted to
|
|
144
|
+
RGBA8; `RGBA`, `RGB`, `LUMINANCE`, `ALPHA` and `LUMINANCE_ALPHA` with
|
|
145
|
+
`UNSIGNED_BYTE` are accepted.
|
|
146
|
+
- **Framebuffers**: `createFramebuffer`, `bindFramebuffer`,
|
|
147
|
+
`framebufferTexture2D` (colour attachment), `checkFramebufferStatus`,
|
|
148
|
+
`createRenderbuffer`, `bindRenderbuffer`, `renderbufferStorage` (depth),
|
|
149
|
+
`framebufferRenderbuffer`, `delete*`. This is enough for render-to-texture,
|
|
150
|
+
shadow maps and post-processing passes.
|
|
151
|
+
- **State**: `enable`/`disable`/`isEnabled` for `BLEND`, `DEPTH_TEST`,
|
|
152
|
+
`CULL_FACE`, `SCISSOR_TEST` (stencil accepted but not applied),
|
|
153
|
+
`clearColor`/`clearDepth`/`clearStencil`, `clear`, `blendFunc`/
|
|
154
|
+
`blendFuncSeparate`, `blendEquation`/`blendEquationSeparate`, `depthFunc`,
|
|
155
|
+
`depthMask`, `colorMask`, `cullFace`, `frontFace`, `viewport`, `scissor`,
|
|
156
|
+
`pixelStorei`, `finish`.
|
|
157
|
+
- **Readback**: `readPixels` (RGBA/UNSIGNED_BYTE) from the default framebuffer
|
|
158
|
+
or a bound framebuffer. It blocks until the GPU finishes; use it for tests and
|
|
159
|
+
screenshots, not per frame.
|
|
160
|
+
|
|
161
|
+
WebGL 2 adds:
|
|
162
|
+
|
|
163
|
+
- **Vertex-array objects**: `createVertexArray`, `bindVertexArray`,
|
|
164
|
+
`deleteVertexArray`, `isVertexArray`. SDL_GPU has no VAO, so binding one
|
|
165
|
+
restores a saved copy of the attribute table and its element buffer.
|
|
166
|
+
- **Instancing**: `drawArraysInstanced`, `drawElementsInstanced`,
|
|
167
|
+
`drawRangeElements`, `vertexAttribDivisor`. A divisor of 1 maps to SDL's
|
|
168
|
+
per-instance vertex input rate; SDL 3.2 reserves larger step rates, so a
|
|
169
|
+
divisor above 1 is clamped to 1.
|
|
170
|
+
- **Integer attributes and uniforms**: `vertexAttribIPointer`, the
|
|
171
|
+
`vertexAttribI4*` family, `uniform1ui`…`uniform4ui`.
|
|
172
|
+
- **Sampler objects**: `createSampler`, `bindSampler`, `deleteSampler`,
|
|
173
|
+
`samplerParameteri/f`, `getSamplerParameter`; a bound sampler overrides the
|
|
174
|
+
texture's own filter/wrap state for that unit.
|
|
175
|
+
- **Immutable textures and buffer copies**: `texStorage2D` (the backend always
|
|
176
|
+
allocates the full mip chain), `copyBufferSubData`, `getBufferSubData`.
|
|
177
|
+
- **Clears**: `clearBufferfv`, `clearBufferiv`, `clearBufferuiv`,
|
|
178
|
+
`clearBufferfi`.
|
|
179
|
+
- **Queries and fences**: the objects and entry points exist
|
|
180
|
+
(`createQuery`/`beginQuery`/`endQuery`/`getQueryParameter`,
|
|
181
|
+
`fenceSync`/`clientWaitSync`/`waitSync`/`getSyncParameter`) and degrade
|
|
182
|
+
gracefully: a fence reports `ALREADY_SIGNALED` and query results are 0.
|
|
183
|
+
- **Uniform blocks**: `getUniformBlockIndex` answers `INVALID_INDEX` so a
|
|
184
|
+
library falls back to individual uniforms; the block entry points are no-ops.
|
|
185
|
+
- **Transform feedback, 3D textures and compressed formats**: the entry points
|
|
186
|
+
are present as no-ops so feature-probing libraries do not throw.
|
|
187
|
+
|
|
188
|
+
Textures are created with a full mip chain; sampling clamps to level 0 until
|
|
189
|
+
`generateMipmap` runs. Matrix vertex attributes consume the right number of
|
|
190
|
+
consecutive locations and read one column per location. A disabled attribute
|
|
191
|
+
is supplied from the last `vertexAttrib*f` value through a small constant
|
|
192
|
+
buffer.
|
|
193
|
+
|
|
194
|
+
## Not implemented
|
|
195
|
+
|
|
196
|
+
Uniform buffer objects in shader source, transform feedback (the entry points
|
|
197
|
+
are no-ops), cube maps, 3D/array textures, float/half textures, depth textures,
|
|
198
|
+
compressed textures, multiple render targets (only the first fragment output is
|
|
199
|
+
written), `blitFramebuffer`, MSAA/sample buffers, stencil operations (state is
|
|
200
|
+
accepted, the stencil buffer is not written), constant blend colours,
|
|
201
|
+
`drawingBufferStorage`, context loss, `bufferData` with a `usage` other than
|
|
202
|
+
static/dynamic (the hint is ignored), `texImage2D` for
|
|
203
|
+
`HTMLVideoElement`/`ImageBitmap` and scissored `clear` (a clear clears the whole
|
|
204
|
+
attachment). Shaders that use built-in blocks, user uniform blocks or
|
|
205
|
+
`gl_FragDepth` beyond the supported subset are rejected with a compile/link log.
|
|
206
|
+
|
|
207
|
+
The engine advertises zero vertex texture units, so a well-behaved WebGL 1
|
|
208
|
+
program will not try to sample a texture in a vertex shader.
|
|
209
|
+
|
|
210
|
+
## Platform
|
|
211
|
+
|
|
212
|
+
The pipeline is created with the shader format the SDL_GPU device accepts:
|
|
213
|
+
**SPIR-V** (`SDL_GPU_SHADERFORMAT_SPIRV`) on Vulkan, which is what Windows and
|
|
214
|
+
Linux select, or **MSL** (`SDL_GPU_SHADERFORMAT_MSL`) on Metal, which macOS
|
|
215
|
+
selects. Both backends go through the same GLSL front end, so a shader that
|
|
216
|
+
compiles on one compiles on the other. On a device whose backend accepts neither
|
|
217
|
+
format — Direct3D 12, which would need DXIL — `getContext("webgl")` and
|
|
218
|
+
`getContext("webgl2")` both answer `null`; the 2D canvas and the rest of the page
|
|
219
|
+
still work.
|
|
220
|
+
|
|
221
|
+
glslang and SPIRV-Cross are fetched and built by `npm run gui` and merged into
|
|
222
|
+
`gui.a` / `gui.lib` (see [Packaging and build](./build.md)); a program that only
|
|
223
|
+
uses the 2D canvas or the DOM pays no run-time cost beyond the archive size.
|
|
224
|
+
|
|
225
|
+
## Testing
|
|
226
|
+
|
|
227
|
+
- `tests/e2e/gui-webgl.test.ts` compiles GLSL, draws a textured and a
|
|
228
|
+
depth-tested quad, checks face culling and reads the pixels back.
|
|
229
|
+
- `tests/e2e/gui-webgl2.test.ts` covers the WebGL 2 additions: `#version 300 es`
|
|
230
|
+
shaders, a VAO round trip, instanced draws with a divisor, `texStorage2D`,
|
|
231
|
+
`clearBufferfv`, buffer copies, sampler objects and struct-uniform fields.
|
|
232
|
+
- `examples/gui/webgl-cube` is a spinning, lit, textured cube; it runs in a
|
|
233
|
+
browser unchanged and is covered by
|
|
234
|
+
`tests/e2e/gui-example-webgl.test.ts`.
|
|
235
|
+
- `examples/gui/webgl2-cubes` draws 64 instanced cubes with one draw call,
|
|
236
|
+
`#version 300 es` and a VAO; covered by
|
|
237
|
+
`tests/e2e/gui-example-webgl2.test.ts`.
|
|
238
|
+
|
|
239
|
+
These suites run against whichever backend the host selects: Vulkan on Linux
|
|
240
|
+
(and Windows), Metal on macOS, so the SPIRV-Cross -> MSL path is covered by the
|
|
241
|
+
same assertions as the SPIR-V one.
|
|
242
|
+
|
|
243
|
+
## three.js
|
|
244
|
+
|
|
245
|
+
The `.js` asset loader only patches three.js's shader unroller; `WebGLRenderer`
|
|
246
|
+
runs unchanged on this engine's real WebGL 2 backend, so **no Canvas2D fallback
|
|
247
|
+
is bundled any more**. Verified with three.js r160 through SDL_GPU:
|
|
248
|
+
`MeshBasicMaterial`, `MeshStandardMaterial` and `MeshPhongMaterial`,
|
|
249
|
+
`CanvasTexture`, linear fog, ambient/directional/point/spot/hemisphere lights,
|
|
250
|
+
`Sprite`, `Line`, `Points` and `InstancedMesh`.
|
|
251
|
+
|
|
252
|
+
Features outside this engine's subset still cannot be emulated: shadow maps
|
|
253
|
+
(depth textures), cube textures/environment maps, HDR/float render targets,
|
|
254
|
+
multiple render targets, transform feedback and compressed textures. A scene
|
|
255
|
+
that needs one of those will not render correctly; everything the previous
|
|
256
|
+
Canvas2D fallback could show now goes through the GPU.
|
package/doc/gui.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# xbintsc GUI extension (self-hosted HTML/CSS renderer)
|
|
2
2
|
|
|
3
|
-
Status: **
|
|
3
|
+
Status: **M19** — features (M1–M15) are complete: HTML parsing, CSS selector
|
|
4
4
|
matching, the cascade, computed styles and layout (block, inline, Flexbox and
|
|
5
5
|
CSS positioning) are
|
|
6
6
|
in place, and the engine *paints*: it builds a display list of rectangles, images
|
|
@@ -35,6 +35,12 @@ them) can be translated, scaled and rotated without reflowing anything — and
|
|
|
35
35
|
`transition: transform`, so those poses animate. See
|
|
36
36
|
[Layout](./gui/layout.md#transforms-m15) and
|
|
37
37
|
[Animation](./gui/animation.md#css-transforms-m15).
|
|
38
|
+
**M17** adds real **WebGL 1.0**, and **M18** adds **WebGL 2.0**: `<canvas>.getContext("webgl2")` accepts `#version 300 es` shaders, vertex-array objects, instanced draws and sampler objects, all compiled to SPIR-V by the bundled glslang (and to MSL by the bundled SPIRV-Cross on Metal) and rendered through SDL_GPU. Geometry, lighting, texture sampling and blending run on the GPU and the page composites the colour texture without a readback — see [WebGL](./gui/webgl.md).
|
|
39
|
+
**M19** fills in the decorative CSS layer: `@media` queries, generated content
|
|
40
|
+
(`::before`/`::after`), multi-layer linear/radial backgrounds, `text-shadow`,
|
|
41
|
+
`clip-path` and the `filter` colour/shadow effects. `backdrop-filter` and true
|
|
42
|
+
group blur need an offscreen compositor and remain documented approximations or
|
|
43
|
+
unsupported — see [Rendering](./gui/rendering.md#backgrounds-generated-content-and-effects-m19).
|
|
38
44
|
This overview records the locked decisions, the architecture, the milestone plan
|
|
39
45
|
and the current progress; the engine itself is documented by function in the
|
|
40
46
|
pages above.
|
|
@@ -174,21 +180,27 @@ engine were Rust.
|
|
|
174
180
|
- **M6b — transitions/animations** ✅ `transition` shorthand + longhands,
|
|
175
181
|
animated `background-color`/`color`/`border-color`/`border-radius`, retargeting
|
|
176
182
|
and `win.advance(ms)`. `@keyframes` remain.
|
|
177
|
-
7. **M7 — CI & releases** ✅ (Linux/macOS build) / 🚧 (run + Windows)
|
|
183
|
+
7. **M7 — CI & releases** ✅ (Linux/macOS/Windows x64 build) / 🚧 (run + Windows arm64)
|
|
178
184
|
- `compile-examples` builds `gui.a` and `media.a` on Linux and macOS
|
|
179
185
|
(required), then runs the examples and `tests/e2e/gui-*.test.ts` under
|
|
180
186
|
Xvfb + lavapipe on Linux (required). The macOS run is provisional until a
|
|
181
187
|
WindowServer is confirmed; it is guarded so a failure is logged without
|
|
182
188
|
annotating the run.
|
|
183
|
-
- The `package` job builds `gui.a` and `media.a` before
|
|
184
|
-
release, so both ship inside the existing runtime archive
|
|
185
|
-
(`package-release` copies all of `runtime/`).
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
`
|
|
190
|
-
|
|
191
|
-
|
|
189
|
+
- The `package` job builds `gui.a`/`gui.lib` and `media.a`/`media.lib` before
|
|
190
|
+
assembling the release, so both ship inside the existing runtime archive
|
|
191
|
+
(`package-release` copies all of `runtime/`). Windows x64 is included;
|
|
192
|
+
Windows arm64 still skips them.
|
|
193
|
+
- `vendor/` (SDL3/FreeType/HarfBuzz for the GUI archive, FFmpeg for `media`)
|
|
194
|
+
is cached per OS/arch, keyed by `scripts/build-gui.ts` /
|
|
195
|
+
`scripts/build-media.ts`. Windows x64 gets its own source cache plus the
|
|
196
|
+
installed `vendor/ffmpeg-build-msvc/dist` prefix.
|
|
197
|
+
- Windows x64 builds both archives in CI and links a `gui,media` program,
|
|
198
|
+
using the same Visual Studio `vcvarsall` + bundled LLVM toolchain as a
|
|
199
|
+
local build (`.github/actions/vs-toolchain`); the host has no GPU/Vulkan
|
|
200
|
+
driver, so *running* the GUI/media examples there remains provisional (a
|
|
201
|
+
failure is logged without annotating the run). The Windows arm64 job still
|
|
202
|
+
skips both archives (see
|
|
203
|
+
[Open questions](./gui/known-issues.md#open-questions)).
|
|
192
204
|
8. **M8 — interactive DOM** ✅
|
|
193
205
|
- Element/document handles with stable identity, read/write properties via
|
|
194
206
|
runtime accessors, traversal/attributes/queries, mutation with lazy
|
|
@@ -277,6 +289,54 @@ engine were Rust.
|
|
|
277
289
|
NanoSVG cache as an SVG file (`svg.{h,cpp}`); the markup cache is bounded
|
|
278
290
|
and a DOM mutation re-serializes on the next layout. e2e in
|
|
279
291
|
`tests/e2e/gui-inline-svg.test.ts`.
|
|
292
|
+
17. **M17 — WebGL** ✅
|
|
293
|
+
- `canvas.getContext("webgl")` creates a real GPU context
|
|
294
|
+
(`webgl.{h,cpp}`): an offscreen RGBA8 colour texture plus a depth texture,
|
|
295
|
+
its own SDL_GPU command buffer, and pipelines created lazily from the
|
|
296
|
+
program, vertex layout and fixed-function state. The page composites the
|
|
297
|
+
colour texture through the existing image path, with no CPU readback.
|
|
298
|
+
- `webgl_glsl*.cpp` rewrites GLSL ES 1.00/3.00 to Vulkan GLSL ES 3.10
|
|
299
|
+
(attribute/varying locations, `gl_FragColor`, `texture2D`, one std140
|
|
300
|
+
uniform block per stage, explicit sampler bindings), compiles it with a
|
|
301
|
+
statically bundled glslang, reflects the SPIR-V for uniform offsets, and
|
|
302
|
+
on Metal cross-compiles that same module to MSL with the bundled
|
|
303
|
+
SPIRV-Cross (`webgl_msl.cpp`).
|
|
304
|
+
- `dom_api_webgl*.cpp` exposes the WebGL 1.0 surface, including textures,
|
|
305
|
+
mipmaps, render-to-texture framebuffers and `readPixels`. See
|
|
306
|
+
[WebGL](./gui/webgl.md); e2e in `tests/e2e/gui-webgl.test.ts` and
|
|
307
|
+
`tests/e2e/gui-example-webgl.test.ts`, demo in
|
|
308
|
+
`examples/gui/webgl-cube`.
|
|
309
|
+
18. **M18 — WebGL 2** ✅
|
|
310
|
+
- `canvas.getContext("webgl2")` returns a context whose prototype extends
|
|
311
|
+
the WebGL 1 one, with the WebGL 2 constants and methods.
|
|
312
|
+
- GLSL ES 3.00 sources (`#version 300 es`, `in`/`out`, named fragment
|
|
313
|
+
outputs, `gl_InstanceID`) compile through the same rewriter.
|
|
314
|
+
- Vertex-array objects save/restore the attribute table, instanced draws use
|
|
315
|
+
SDL's per-instance input rate, and sampler objects override a texture
|
|
316
|
+
unit's filter/wrap state. `texStorage2D`, `copyBufferSubData`,
|
|
317
|
+
`getBufferSubData` and `clearBuffer*` are implemented; query/fence/UBO and
|
|
318
|
+
transform-feedback entry points exist and degrade gracefully. See
|
|
319
|
+
[WebGL](./gui/webgl.md); e2e in `tests/e2e/gui-webgl2.test.ts` and
|
|
320
|
+
`tests/e2e/gui-example-webgl2.test.ts`, demo in
|
|
321
|
+
`examples/gui/webgl2-cubes`.
|
|
322
|
+
19. **M19 — decorative CSS** ✅
|
|
323
|
+
- `@media` blocks are parsed recursively and evaluated against the viewport
|
|
324
|
+
(width/height ranges, orientation, hover/pointer and preference features);
|
|
325
|
+
`matchMedia()` uses the same evaluator.
|
|
326
|
+
- Generated content: `::before`/`::after` selectors, inherited pseudo styles,
|
|
327
|
+
`content` strings/escapes/`attr()`, and synthetic layout boxes that never
|
|
328
|
+
leak into DOM traversal.
|
|
329
|
+
- Multi-layer `background-image` with linear and radial gradients, painted
|
|
330
|
+
bottom-up as solid bands (18 strips / 32 concentric ellipses).
|
|
331
|
+
- `text-shadow` as shadow text runs, including a nine-tap blur approximate.
|
|
332
|
+
- `clip-path` polygons (`inset`/`circle`/`ellipse`/`polygon`) resolved to
|
|
333
|
+
device space, ear-clipped and intersected with shape geometry in
|
|
334
|
+
`renderer_clip.cpp` — no stencil/shader change.
|
|
335
|
+
- `filter` colour functions, nine-tap `blur()` and silhouette
|
|
336
|
+
`drop-shadow()`; `backdrop-filter` parses and cascades but needs an
|
|
337
|
+
offscreen backdrop pass (see [Known issues](./gui/known-issues.md)).
|
|
338
|
+
- E2E coverage in `tests/e2e/gui-effects.test.ts`; see
|
|
339
|
+
[Rendering](./gui/rendering.md#backgrounds-generated-content-and-effects-m19).
|
|
280
340
|
|
|
281
341
|
## Progress log
|
|
282
342
|
|
|
@@ -306,11 +366,12 @@ engine were Rust.
|
|
|
306
366
|
pixel size and cached by that size, so scaling and HiDPI stay crisp.
|
|
307
367
|
- **M6b** ✅ CSS transitions (parsing in `style.*`, an animation clock and
|
|
308
368
|
transition state in `document.*`, `advance`/`advance(ms)` hooks, e2e coverage).
|
|
309
|
-
- **M7** ✅ builds `gui.a`
|
|
310
|
-
(required) and runs the example plus the GUI e2e suite
|
|
311
|
-
`package` ships
|
|
312
|
-
|
|
313
|
-
|
|
369
|
+
- **M7** ✅ builds `gui.a`/`gui.lib` and `media.a`/`media.lib` in CI on Linux,
|
|
370
|
+
macOS and Windows x64 (required) and runs the example plus the GUI e2e suite
|
|
371
|
+
under Xvfb on Linux; `package` ships the archives (Windows x64 included),
|
|
372
|
+
`vendor/` is cached, and the `ar -M` merge works on GNU/Linux, macOS and
|
|
373
|
+
COFF/Windows. macOS runs, the Windows example *run* and Windows arm64 remain
|
|
374
|
+
provisional in CI.
|
|
314
375
|
- **M8** ✅ element/document handles (`dom_api.*`), DOM mutation with lazy
|
|
315
376
|
restyle/relayout (`document.*`, `xt_gui_flush_dom`), element event dispatch
|
|
316
377
|
with capture/bubble and `stopPropagation` (`dom_api.*`, `gui.cpp`), and e2e
|
|
@@ -347,7 +408,8 @@ engine were Rust.
|
|
|
347
408
|
every frame now runs in constant memory (see [Memory & GC](./gui/runtime.md#memory--gc)).
|
|
348
409
|
- **M13** ✅ `<video>` / `<audio>` support. The optional `media` extension
|
|
349
410
|
vendors and builds a minimal static FFmpeg (`scripts/build-media.ts`) and
|
|
350
|
-
merges it into `media.a
|
|
411
|
+
merges it into `media.a` (or `media.lib` from clang-cl/MSVC objects on
|
|
412
|
+
Windows); `runtime/ext_media/media.cpp` decodes video to RGBA
|
|
351
413
|
frames and audio to 48 kHz stereo PCM on the main thread,
|
|
352
414
|
`runtime/ext_gui/gui_media.cpp` owns the players, implements the SDL audio
|
|
353
415
|
sink and pumps the media clock and events each frame,
|
|
@@ -393,4 +455,33 @@ engine were Rust.
|
|
|
393
455
|
NanoSVG cache (`svg.{h,cpp}`, bounded LRU for markup). The `win.inlineSvg`
|
|
394
456
|
diagnostic exposes the serialized document, and `tests/e2e/gui-inline-svg.test.ts`
|
|
395
457
|
pins sizing, hit testing, gradients, CSS box styling and mutation.
|
|
458
|
+
- **M17** ✅ WebGL. `xtgui::WebGLContext` (`webgl.{h,cpp}`) owns the offscreen
|
|
459
|
+
colour/depth targets and the command buffer, `webgl_buffer/texture/draw/shader`
|
|
460
|
+
implement the GL object model, `webgl_glsl*.cpp` translate GLSL ES to SPIR-V
|
|
461
|
+
with the bundled glslang (`webgl_msl.cpp`/SPIRV-Cross turn that module into
|
|
462
|
+
MSL on Metal), and `dom_api_webgl*.cpp` bind the WebGL 1.0 API.
|
|
463
|
+
`renderer_image.cpp` returns the context's colour texture for a canvas id, so
|
|
464
|
+
the page composites GPU output directly. Demo: `examples/gui/webgl-cube`;
|
|
465
|
+
e2e: `tests/e2e/gui-webgl.test.ts`, `tests/e2e/gui-example-webgl.test.ts`.
|
|
466
|
+
- **M18** ✅ WebGL 2. `webgl2_proto()` extends the WebGL 1 prototype with the
|
|
467
|
+
WebGL 2 constants/methods; `webgl_webgl2.cpp` implements vertex-array objects
|
|
468
|
+
and sampler/query/sync handles, `webgl_draw.cpp` adds instanced draws (input
|
|
469
|
+
rate from `vertexAttribDivisor`) and integer attributes, and
|
|
470
|
+
`webgl_texture.cpp` adds `texStorage2D` and `clearBuffer*`. The shader
|
|
471
|
+
rewriter gives `#version 300 es` outputs sequential locations, and the block
|
|
472
|
+
reflection flattens struct fields for three.js lights. three.js r160 runs on
|
|
473
|
+
the real renderer (basic/standard/Phong materials, textures, lights, fog,
|
|
474
|
+
sprites, lines, points and instancing); the Canvas2D fallback was removed.
|
|
475
|
+
Demo: `examples/gui/webgl2-cubes` (64 cubes, one instanced draw call);
|
|
476
|
+
e2e: `tests/e2e/gui-webgl2.test.ts`, `tests/e2e/gui-example-webgl2.test.ts`.
|
|
477
|
+
- **M19** ✅ decorative CSS. `css_sheet.cpp` now parses nested `@media` blocks and
|
|
478
|
+
`media_query.cpp` evaluates them (and `matchMedia`) against the viewport;
|
|
479
|
+
`css_selector.cpp` understands `::before`/`::after`. `style.cpp` computes
|
|
480
|
+
pseudo styles into a per-restyle arena, resolves `content`, and layout inserts
|
|
481
|
+
their boxes before/after the DOM children. `gradient_values.cpp` models a
|
|
482
|
+
background layer list (linear/radial, shape/size/position/stops),
|
|
483
|
+
`paint_background.cpp` paints it, `paint_effects.cpp` applies filter colour
|
|
484
|
+
functions plus nine-tap blur/drop-shadow and emits `text-shadow` runs, and
|
|
485
|
+
`paint_clip.cpp`/`renderer_clip.cpp` clip geometry against triangulated
|
|
486
|
+
`clip-path` polygons. E2E: `tests/e2e/gui-effects.test.ts`.
|
|
396
487
|
|
package/doc/npm-package.md
CHANGED
|
@@ -358,8 +358,10 @@ jobs:
|
|
|
358
358
|
cannot poison a new build.
|
|
359
359
|
- xbintsc builds for the **host** platform. It is not a cross-compiler: use a CI
|
|
360
360
|
matrix (one job per OS/arch) to produce artifacts for several platforms.
|
|
361
|
-
- macOS runners already have Xcode Command Line Tools; Windows runners need
|
|
362
|
-
|
|
361
|
+
- macOS runners already have Xcode Command Line Tools; Windows runners need the
|
|
362
|
+
Visual Studio C++ build tools (MSVC + its bundled LLVM), and the binary is
|
|
363
|
+
`build\main.exe`. In a source checkout,
|
|
364
|
+
`pwsh -File scripts/setup-vs-toolchain.ps1` imports that toolchain explicitly.
|
|
363
365
|
|
|
364
366
|
## npm package or release archive?
|
|
365
367
|
|
|
@@ -367,7 +369,7 @@ jobs:
|
|
|
367
369
|
| --- | --- | --- |
|
|
368
370
|
| Needs Node.js | Yes, 22+ | No |
|
|
369
371
|
| First build | Compiles the C runtime from source | Links the prebuilt runtime |
|
|
370
|
-
| GUI / media extensions | Not included | Included in Linux/macOS archives |
|
|
372
|
+
| GUI / media extensions | Not included | Included in Linux/macOS and Windows x64 archives |
|
|
371
373
|
| Installation | `npm install` + lockfile / provenance | Download, verify `.sha256`, unpack |
|
|
372
374
|
| Programmatic API | Yes | No (CLI only) |
|
|
373
375
|
| Cross-compiles | No — host only | No — host only |
|
|
@@ -409,7 +411,7 @@ the same file under `node_modules/xbintsc/doc/ai/`.
|
|
|
409
411
|
| The first build takes a long time | Expected: the runtime C sources are compiled and cached. Later builds reuse `.xbintsc/`; `--time` confirms. Use a release archive if cold builds must be fast. |
|
|
410
412
|
| Permission errors writing `.xbintsc/` | Set `xbintsc_CACHE_DIR` to a writable directory, or run from a writable working directory. |
|
|
411
413
|
| `module 'fs' is provided by the 'node' extension` | Add `--ext node`, or `"extensions": ["node"]` in the config. |
|
|
412
|
-
| `GUI native library not found` / `media native library not found` | The npm package does not ship `gui.a`/`media.a`; use a Linux/macOS release archive or build them from a source checkout. |
|
|
414
|
+
| `GUI native library not found` / `media native library not found` | The npm package does not ship `gui.a`/`gui.lib` or `media.a`/`media.lib`; use a Linux/macOS/Windows x64 release archive or build them from a source checkout. |
|
|
413
415
|
| `require("xbintsc")` fails | The package is ESM-only; use `import` (or dynamic `import()`). |
|
|
414
416
|
| Windows link errors about missing MSVC libraries | Run from a Native Tools prompt, install the VS C++ build tools, and check `npx xbintsc doctor`. |
|
|
415
417
|
| `npm ci --omit=dev` then the build cannot find `xbintsc` | Install devDependencies for the build stage, or move `xbintsc` to `dependencies`. |
|
package/doc/requirements.md
CHANGED
|
@@ -124,22 +124,26 @@ Verify with `clang --version`. If xbintsc uses the wrong linker, set
|
|
|
124
124
|
`xbintsc_CLANG` to the clang you want and/or pass extra flags through
|
|
125
125
|
`xbintsc_LINKER_ARGS` (for example `-fuse-ld=lld`).
|
|
126
126
|
|
|
127
|
-
## Windows — install the MSVC C++ build tools (
|
|
127
|
+
## Windows — install the MSVC C++ build tools (with LLVM)
|
|
128
128
|
|
|
129
|
-
xbintsc targets the **MSVC ABI** on Windows.
|
|
130
|
-
|
|
129
|
+
xbintsc targets the **MSVC ABI** on Windows. One `winget` command installs the
|
|
130
|
+
Visual Studio C++ workload, MSBuild and the Clang component that the local build
|
|
131
|
+
scripts and CI use:
|
|
131
132
|
|
|
132
133
|
```powershell
|
|
133
|
-
winget install -e --id LLVM.LLVM
|
|
134
134
|
winget install -e --id Microsoft.VisualStudio.2022.BuildTools `
|
|
135
|
-
--override "--quiet --wait --add Microsoft.VisualStudio.Workload.VCTools --includeRecommended"
|
|
135
|
+
--override "--quiet --wait --add Microsoft.VisualStudio.Workload.VCTools --add Microsoft.VisualStudio.Component.VC.Llvm.Clang --includeRecommended"
|
|
136
136
|
```
|
|
137
137
|
|
|
138
138
|
The LLVM bundled with Visual Studio 2022
|
|
139
|
-
(`VC\Tools\Llvm\x64\bin\clang.exe`, version 19.1.5 in current installs) is
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
139
|
+
(`VC\Tools\Llvm\x64\bin\clang.exe`, version 19.1.5 in current installs) is what
|
|
140
|
+
`scripts/setup-vs-toolchain.ps1` selects. A standalone LLVM also works for
|
|
141
|
+
`xbintsc` itself (`winget install -e --id LLVM.LLVM`), but the GUI/media archive
|
|
142
|
+
builds and the CI setup use the Visual Studio one so one toolchain produces the
|
|
143
|
+
runtime, the archives and the final binary. Either way the compiler must target
|
|
144
|
+
the MSVC ABI (`Target: *-windows-msvc`): clang built for another Windows ABI
|
|
145
|
+
cannot link with the MSVC runtime, so `xbintsc` rejects it with an explicit
|
|
146
|
+
error.
|
|
143
147
|
|
|
144
148
|
A developer prompt is normally **not** required: `xbintsc` resolves the Visual
|
|
145
149
|
Studio LLVM by absolute path, and that clang locates the MSVC/SDK headers,
|
|
@@ -151,6 +155,11 @@ imported, run the build from an **x64 Native Tools Command Prompt for VS 2022**
|
|
|
151
155
|
& "$env:ProgramFiles\Microsoft Visual Studio\2022\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" x64
|
|
152
156
|
```
|
|
153
157
|
|
|
158
|
+
In a source checkout, `pwsh -File scripts/setup-vs-toolchain.ps1` does the same
|
|
159
|
+
and also pins `xbintsc_CLANG` to the LLVM bundled with that Visual Studio
|
|
160
|
+
installation. CI calls the same script, so a local build, the release archives
|
|
161
|
+
and CI use one Visual Studio toolchain.
|
|
162
|
+
|
|
154
163
|
Verify with `xbintsc doctor` (or `clang --version`); the report names the
|
|
155
164
|
resolved compiler, its version and its target.
|
|
156
165
|
|
package/doc/zh-CN/gui/api.md
CHANGED
|
@@ -55,7 +55,8 @@ requestAnimationFrame(frame);
|
|
|
55
55
|
| `localStorage` | 内存中的 `getItem` / `setItem` / `removeItem` / `clear` / `key` / `length` |
|
|
56
56
|
| `AudioContext`、`webkitAudioContext` | Web Audio 图构建器(见下) |
|
|
57
57
|
| `Event`、`CustomEvent`、`ProgressEvent` 等 | 事件构造器 |
|
|
58
|
-
| `HTMLCanvasElement`、`HTMLImageElement`、`
|
|
58
|
+
| `HTMLCanvasElement`、`HTMLImageElement`、`WebGLRenderingContext`、`WebGL2RenderingContext`、`WebGLBuffer`/`WebGLTexture`/`WebGLShader`/`WebGLProgram`/`WebGLFramebuffer`/`WebGLRenderbuffer`/`WebGLUniformLocation`/`WebGLActiveInfo`/`WebGLVertexArrayObject`/`WebGLSampler`/`WebGLQuery`/`WebGLSync`/`WebGLTransformFeedback` | 真实的构造函数值。`canvas.getContext("webgl")` 与 `getContext("webgl2")` 返回 GPU 上下文(见 [WebGL](./webgl.md))。 |
|
|
59
|
+
| `ImageBitmap`、`ImageData`、`OffscreenCanvas`、`XRWebGL*`、`Request`、`Headers`、`Response`、`ReadableStream`、`DOMParser` | `typeof` 探测返回 `"undefined"`(没有 XR/fetch/流式后端),让页面走自己的“不支持”分支,而不是调用空壳。Three.js 页面在本后端上使用真实渲染器(见[已知问题](./known-issues.md))。 |
|
|
59
60
|
| `requestAnimationFrame` / `cancelAnimationFrame` | 排入窗口的动画帧列表,见[运行时集成](./runtime.md) |
|
|
60
61
|
| `alert` / `confirm` / `prompt`、`matchMedia`、`getComputedStyle`、`escape` | 宿主实现(Annex B `escape` 按 UTF-16 码元编码,与 `decodeURIComponent(escape(bytes))` 一致) |
|
|
61
62
|
|
|
@@ -133,4 +134,4 @@ win.stats() // 引擎/运行时计数器(内存排
|
|
|
133
134
|
|
|
134
135
|
多窗口由对象模型自然得出:`createWindow` 返回一个原生对象句柄;每个句柄
|
|
135
136
|
拥有自己的 `SDL_Window`/GPU 表面与自己的 DOM 树。`run()` 驱动一个共享主循环,
|
|
136
|
-
它每帧 tick 所有窗口,并在最后一个窗口关闭时退出。
|
|
137
|
+
它每帧 tick 所有窗口,并在最后一个窗口关闭时退出。
|