xbintsc 0.5.32 → 0.5.36
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 +10 -7
- package/README.zh-CN.md +10 -8
- package/dist/scripts/check-version.d.ts +27 -0
- package/dist/scripts/check-version.js +71 -0
- package/dist/scripts/check-version.js.map +1 -0
- package/dist/scripts/package-platform.d.ts +58 -0
- package/dist/scripts/package-platform.js +142 -0
- package/dist/scripts/package-platform.js.map +1 -0
- package/dist/scripts/verify-platform-package.d.ts +34 -0
- package/dist/scripts/verify-platform-package.js +161 -0
- package/dist/scripts/verify-platform-package.js.map +1 -0
- package/dist/src/cli/help.d.ts +1 -1
- package/dist/src/cli/main.js +3 -1
- package/dist/src/cli/main.js.map +1 -1
- package/dist/src/driver/runtime-lib.d.ts +29 -4
- package/dist/src/driver/runtime-lib.js +68 -10
- package/dist/src/driver/runtime-lib.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/index.js +6 -5
- package/dist/src/extensions/gui/index.js.map +1 -1
- package/dist/src/extensions/media/index.js +4 -3
- package/dist/src/extensions/media/index.js.map +1 -1
- package/dist/src/parser/context.d.ts +41 -0
- package/dist/src/parser/context.js +89 -4
- package/dist/src/parser/context.js.map +1 -1
- package/dist/src/parser/literals.js +6 -12
- package/dist/src/parser/literals.js.map +1 -1
- package/dist/tests/driver/platform-package.test.d.ts +1 -0
- package/dist/tests/driver/platform-package.test.js +49 -0
- package/dist/tests/driver/platform-package.test.js.map +1 -0
- package/dist/tests/driver/runtime-lib.test.js +51 -4
- package/dist/tests/driver/runtime-lib.test.js.map +1 -1
- package/dist/tests/e2e/gui-audio.test.d.ts +14 -0
- package/dist/tests/e2e/gui-audio.test.js +287 -0
- package/dist/tests/e2e/gui-audio.test.js.map +1 -0
- package/dist/tests/e2e/gui-helpers.d.ts +7 -0
- package/dist/tests/e2e/gui-helpers.js +1 -0
- package/dist/tests/e2e/gui-helpers.js.map +1 -1
- package/dist/tests/e2e/gui-media.test.js +78 -0
- package/dist/tests/e2e/gui-media.test.js.map +1 -1
- package/dist/tests/e2e/gui-style.test.js +55 -0
- package/dist/tests/e2e/gui-style.test.js.map +1 -1
- package/dist/tests/e2e/gui-webgl.test.js +258 -0
- package/dist/tests/e2e/gui-webgl.test.js.map +1 -1
- package/dist/tests/e2e/gui-webgl2-3d.test.d.ts +4 -0
- package/dist/tests/e2e/gui-webgl2-3d.test.js +264 -0
- package/dist/tests/e2e/gui-webgl2-3d.test.js.map +1 -0
- package/dist/tests/e2e/gui-webgl2-blit.test.d.ts +10 -0
- package/dist/tests/e2e/gui-webgl2-blit.test.js +262 -0
- package/dist/tests/e2e/gui-webgl2-blit.test.js.map +1 -0
- package/dist/tests/e2e/gui-webgl2-formats.test.d.ts +6 -0
- package/dist/tests/e2e/gui-webgl2-formats.test.js +395 -0
- package/dist/tests/e2e/gui-webgl2-formats.test.js.map +1 -0
- package/dist/tests/e2e/gui-webgl2-mrt.test.d.ts +4 -0
- package/dist/tests/e2e/gui-webgl2-mrt.test.js +105 -0
- package/dist/tests/e2e/gui-webgl2-mrt.test.js.map +1 -0
- package/dist/tests/e2e/gui-webgl2-ubo.test.d.ts +8 -0
- package/dist/tests/e2e/gui-webgl2-ubo.test.js +112 -0
- package/dist/tests/e2e/gui-webgl2-ubo.test.js.map +1 -0
- package/dist/tests/e2e/gui-webgl2.test.js +45 -1
- package/dist/tests/e2e/gui-webgl2.test.js.map +1 -1
- package/dist/tests/extensions/gui-index.test.js +1 -0
- package/dist/tests/extensions/gui-index.test.js.map +1 -1
- package/dist/tests/extensions/media.test.js +1 -0
- package/dist/tests/extensions/media.test.js.map +1 -1
- package/dist/tests/parser/expressions.test.js +30 -0
- package/dist/tests/parser/expressions.test.js.map +1 -1
- package/dist/tests/platform-tarball.test.d.ts +1 -0
- package/dist/tests/platform-tarball.test.js +111 -0
- package/dist/tests/platform-tarball.test.js.map +1 -0
- package/dist/tests/version.test.js +6 -0
- package/dist/tests/version.test.js.map +1 -1
- package/doc/ai/contributing.md +11 -0
- package/doc/ai/extensions.md +7 -4
- package/doc/ai/troubleshooting.md +7 -5
- package/doc/ai/zh-CN/contributing.md +9 -0
- package/doc/ai/zh-CN/extensions.md +4 -2
- package/doc/ai/zh-CN/troubleshooting.md +5 -3
- package/doc/gui/api.md +61 -13
- package/doc/gui/build.md +11 -4
- package/doc/gui/dom.md +6 -3
- package/doc/gui/media.md +4 -0
- package/doc/gui/webgl.md +105 -46
- package/doc/gui.md +7 -3
- package/doc/npm-package.md +55 -27
- package/doc/requirements.md +6 -2
- package/doc/zh-CN/gui/api.md +51 -10
- package/doc/zh-CN/gui/build.md +7 -2
- package/doc/zh-CN/gui/dom.md +3 -1
- package/doc/zh-CN/gui/media.md +3 -0
- package/doc/zh-CN/gui/webgl.md +22 -16
- package/doc/zh-CN/gui.md +3 -2
- package/doc/zh-CN/npm-package.md +44 -23
- package/doc/zh-CN/requirements.md +4 -1
- package/package.json +17 -1
- package/runtime/ext_gui/audio.cpp +365 -153
- package/runtime/ext_gui/audio_buffer.cpp +166 -0
- package/runtime/ext_gui/audio_buffer.h +37 -0
- package/runtime/ext_gui/audio_decode.cpp +219 -0
- package/runtime/ext_gui/audio_decode.h +39 -0
- package/runtime/ext_gui/audio_device.cpp +87 -0
- package/runtime/ext_gui/audio_effects.cpp +163 -0
- package/runtime/ext_gui/audio_effects.h +25 -0
- package/runtime/ext_gui/audio_internal.h +30 -0
- package/runtime/ext_gui/audio_mixer.cpp +494 -0
- package/runtime/ext_gui/audio_mixer.h +238 -0
- package/runtime/ext_gui/audio_param.cpp +104 -0
- package/runtime/ext_gui/audio_param_object.cpp +155 -0
- package/runtime/ext_gui/browser.cpp +11 -1
- package/runtime/ext_gui/css_selector.cpp +21 -3
- package/runtime/ext_gui/dom_api_internal.h +16 -0
- package/runtime/ext_gui/dom_api_webgl.cpp +7 -0
- package/runtime/ext_gui/dom_api_webgl2.cpp +151 -36
- package/runtime/ext_gui/dom_api_webgl2_draw.cpp +3 -3
- package/runtime/ext_gui/dom_api_webgl_buffer.cpp +6 -2
- package/runtime/ext_gui/dom_api_webgl_compressed.cpp +167 -0
- package/runtime/ext_gui/dom_api_webgl_framebuffer.cpp +160 -0
- package/runtime/ext_gui/dom_api_webgl_shader.cpp +4 -4
- package/runtime/ext_gui/dom_api_webgl_source.cpp +161 -0
- package/runtime/ext_gui/dom_api_webgl_state.cpp +169 -23
- package/runtime/ext_gui/dom_api_webgl_texture.cpp +276 -236
- package/runtime/ext_gui/dom_api_webgl_ubo.cpp +81 -0
- package/runtime/ext_gui/gui.cpp +44 -9
- package/runtime/ext_gui/gui_engine.h +9 -4
- package/runtime/ext_gui/image_bitmap.cpp +28 -0
- package/runtime/ext_gui/image_bitmap.h +26 -0
- package/runtime/ext_gui/image_bitmap_browser.cpp +136 -0
- package/runtime/ext_gui/media.cpp +32 -0
- package/runtime/ext_gui/media.h +13 -0
- package/runtime/ext_gui/media_api.h +23 -0
- package/runtime/ext_gui/webgl.h +152 -18
- package/runtime/ext_gui/webgl_blit.cpp +95 -0
- package/runtime/ext_gui/webgl_buffer.cpp +178 -263
- package/runtime/ext_gui/webgl_buffer_objects.cpp +270 -0
- package/runtime/ext_gui/webgl_clear.cpp +142 -0
- package/runtime/ext_gui/webgl_compressed.cpp +180 -0
- package/runtime/ext_gui/webgl_context.cpp +241 -156
- package/runtime/ext_gui/webgl_draw.cpp +68 -3
- package/runtime/ext_gui/webgl_draw_buffers.cpp +75 -0
- package/runtime/ext_gui/webgl_glsl.h +40 -0
- package/runtime/ext_gui/webgl_glsl_compile.cpp +6 -0
- package/runtime/ext_gui/webgl_glsl_rewrite.cpp +18 -0
- package/runtime/ext_gui/webgl_glsl_scan.cpp +20 -11
- package/runtime/ext_gui/webgl_glsl_scan_block.cpp +126 -0
- package/runtime/ext_gui/webgl_glsl_tokens.h +28 -0
- package/runtime/ext_gui/webgl_pipeline.cpp +71 -19
- package/runtime/ext_gui/webgl_program_blocks.cpp +58 -0
- package/runtime/ext_gui/webgl_program_internal.h +6 -0
- package/runtime/ext_gui/webgl_shader.cpp +13 -1
- package/runtime/ext_gui/webgl_state.cpp +228 -0
- package/runtime/ext_gui/webgl_texture.cpp +144 -17
- package/runtime/ext_gui/webgl_texture_3d.cpp +215 -0
- package/runtime/ext_gui/webgl_uniform_block.h +31 -0
- package/runtime/ext_gui/webgl_webgl2.cpp +58 -5
- package/runtime/ext_media/decode_audio.cpp +308 -0
- package/runtime/ext_media/media_bridge.c +2 -0
- package/runtime/rt.h +17 -0
- package/runtime/xt_array_buffer.c +30 -0
- package/runtime/xt_typed_array/elements.inc +13 -0
- package/scripts/build-media.ts +14 -6
- package/scripts/build-runtime.ts +21 -16
- package/scripts/check-version.ts +39 -9
- package/scripts/package-platform.ts +183 -0
- package/scripts/set-platform-version.ts +62 -0
- package/scripts/verify-platform-package.ts +182 -0
- package/src/cli/main.ts +5 -1
- package/src/driver/runtime-lib.ts +73 -9
- package/src/driver/version.ts +1 -1
- package/src/extensions/gui/index.ts +6 -5
- package/src/extensions/media/index.ts +4 -3
- package/src/parser/context.ts +99 -4
- package/src/parser/literals.ts +6 -12
package/doc/gui/dom.md
CHANGED
|
@@ -14,9 +14,12 @@ close rules (`li`, `dt`/`dd`, `option`, `p`, headings, table cells/rows).
|
|
|
14
14
|
**CSS parser** (`runtime/ext_gui/css.{h,cpp}`): comments are stripped; `@media`
|
|
15
15
|
blocks are parsed recursively (nested queries combine with `and`, and a comma
|
|
16
16
|
list distributes over the inner query) while other at-rules are skipped. Rules
|
|
17
|
-
support multiple selectors and declarations
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
support multiple selectors and declarations; a selector list may be formatted
|
|
18
|
+
across any number of lines (line breaks are ordinary whitespace, so a wrapped
|
|
19
|
+
combinator stays a combinator), and a quoted attribute value may contain
|
|
20
|
+
commas, brackets or parentheses without splitting the list. Selectors: type,
|
|
21
|
+
`.class`, `#id`, attribute (`=`, `~=`, `|=`, `^=`, `$=`, `*=`), the four
|
|
22
|
+
combinators (descendant, child, adjacent and general sibling), the pseudo-classes
|
|
20
23
|
`:first-child`, `:last-child`, `:only-child`, `:empty`, `:root`, `:not(...)`,
|
|
21
24
|
`:nth-child(an+b)`, `:disabled`, `:checked`, plus the stateful `:hover` and
|
|
22
25
|
`:focus` (see [Input](./input.md)), and the pseudo-elements `::before`/`::after`
|
package/doc/gui/media.md
CHANGED
|
@@ -112,6 +112,10 @@ platform media framework in the path either way.
|
|
|
112
112
|
- **Threading.** The engine is single-threaded and not thread-aware, so all
|
|
113
113
|
decoding happens on the main thread inside `xt_gui_media_tick` — no decode
|
|
114
114
|
thread, no cross-thread GC exposure.
|
|
115
|
+
- **`decodeAudioData`.** The same FFmpeg build also decodes an in-memory audio
|
|
116
|
+
file for `AudioContext.decodeAudioData` (`runtime/ext_media/decode_audio.cpp`,
|
|
117
|
+
through the media table); WAV is handled by the GUI engine itself
|
|
118
|
+
(`audio_decode.cpp`), so only compressed formats need this extension.
|
|
115
119
|
- **DOM API.** Element handles expose the media surface directly (see
|
|
116
120
|
`runtime/ext_gui/dom_api_media.cpp` and the prototype in
|
|
117
121
|
`dom_api_proto.cpp`): `play()` / `pause()` / `load()`, and the
|
package/doc/gui/webgl.md
CHANGED
|
@@ -96,8 +96,7 @@ reflected offsets; `uniform1i` on a sampler stores the texture unit. The block
|
|
|
96
96
|
is pushed with the dynamic uniform-buffer API on every draw.
|
|
97
97
|
|
|
98
98
|
Limits of the translator: struct-typed uniforms, user uniform blocks, uniform
|
|
99
|
-
arrays whose size is not resolved by the preprocessor, sampler arrays
|
|
100
|
-
maps are rejected (the link/shader info log says so). Shader code inside
|
|
99
|
+
arrays whose size is not resolved by the preprocessor, sampler arrays are rejected (the link/shader info log says so). Shader code inside
|
|
101
100
|
`#ifdef` is fine; non-sampler uniform declarations are moved to the enclosing
|
|
102
101
|
top-level position so the block stays unconditional.
|
|
103
102
|
|
|
@@ -115,8 +114,11 @@ available from GLSL ES 3.00, which is what the instanced example uses.
|
|
|
115
114
|
|
|
116
115
|
- **Context**: `getContext("webgl")`, `canvas`, `drawingBufferWidth/Height`,
|
|
117
116
|
`getParameter`, `getError`, `getSupportedExtensions`, `getExtension`,
|
|
118
|
-
`getContextAttributes`, `isContextLost`, `getShaderPrecisionFormat`, and
|
|
119
|
-
stencil
|
|
117
|
+
`getContextAttributes`, `isContextLost`, `getShaderPrecisionFormat`, and an
|
|
118
|
+
8-bit stencil buffer (`getContextAttributes().stencil` is `true`,
|
|
119
|
+
`STENCIL_BITS` is 8). `WEBGL_lose_context`'s `loseContext`/`restoreContext`
|
|
120
|
+
really drop and rebuild the context (every object becomes invalid) and
|
|
121
|
+
dispatch `webglcontextlost`/`webglcontextrestored`.
|
|
120
122
|
- **Shaders and programs**: `createShader`, `shaderSource`, `compileShader`,
|
|
121
123
|
`getShaderParameter`, `getShaderInfoLog`, `getShaderSource`, `deleteShader`,
|
|
122
124
|
`createProgram`, `attachShader`, `detachShader`, `linkProgram`,
|
|
@@ -131,7 +133,9 @@ available from GLSL ES 3.00, which is what the instanced example uses.
|
|
|
131
133
|
`bufferSubData`, `deleteBuffer`, `getBufferParameter`,
|
|
132
134
|
`enableVertexAttribArray`, `disableVertexAttribArray`,
|
|
133
135
|
`vertexAttribPointer`, `vertexAttrib1f`…`4f` / `1fv`…`4fv`,
|
|
134
|
-
`getVertexAttrib`.
|
|
136
|
+
`getVertexAttrib`. The `usage` hint from `bufferData`
|
|
137
|
+
(`STREAM_DRAW`/`STATIC_DRAW`/`DYNAMIC_DRAW`) is recorded and reported by
|
|
138
|
+
`getBufferParameter(…, BUFFER_USAGE)`.
|
|
135
139
|
- **Drawing**: `drawArrays`, `drawElements` (UNSIGNED_BYTE, UNSIGNED_SHORT,
|
|
136
140
|
UNSIGNED_INT; `TRIANGLE_FAN` and `LINE_LOOP` are expanded to lists).
|
|
137
141
|
`POINTS`, `LINES`, `LINE_STRIP`, `TRIANGLES` and `TRIANGLE_STRIP` map to the
|
|
@@ -140,22 +144,50 @@ available from GLSL ES 3.00, which is what the instanced example uses.
|
|
|
140
144
|
`texParameteri`/`texParameterf`, `getTexParameter`, `texImage2D` (raw pixels,
|
|
141
145
|
`<img>`, `<canvas>` and `ImageData` sources), `texSubImage2D`,
|
|
142
146
|
`generateMipmap`, `deleteTexture`. `UNPACK_FLIP_Y_WEBGL` and
|
|
143
|
-
`UNPACK_PREMULTIPLY_ALPHA_WEBGL` are honoured.
|
|
144
|
-
RGBA8; `RGBA`, `RGB`, `LUMINANCE`, `ALPHA` and
|
|
145
|
-
`UNSIGNED_BYTE` are accepted.
|
|
146
|
-
|
|
147
|
-
`
|
|
148
|
-
`
|
|
149
|
-
`
|
|
150
|
-
|
|
147
|
+
`UNPACK_PREMULTIPLY_ALPHA_WEBGL` are honoured. By default source data is
|
|
148
|
+
converted to RGBA8; `RGBA`, `RGB`, `LUMINANCE`, `ALPHA` and
|
|
149
|
+
`LUMINANCE_ALPHA` with `UNSIGNED_BYTE` are accepted. Float textures
|
|
150
|
+
(`RGBA32F`, `RGBA16F`, `RGB32F`, `RGB16F`, `RG32F`/`RG16F`, `R32F`/`R16F`
|
|
151
|
+
with `FLOAT` or `HALF_FLOAT` data, plus WebGL 1's
|
|
152
|
+
`OES_texture_float`/`OES_texture_half_float`) map to SDL's RGBA32F/RGBA16F,
|
|
153
|
+
and depth textures (`DEPTH_COMPONENT16/24/32F`, `DEPTH_STENCIL`,
|
|
154
|
+
`DEPTH24_STENCIL8`) map to `D32_FLOAT`/`D32_FLOAT_S8_UINT` and can be sampled
|
|
155
|
+
or used as depth attachments. Compressed textures upload through
|
|
156
|
+
`compressedTexImage2D`/`compressedTexSubImage2D` with
|
|
157
|
+
`WEBGL_compressed_texture_s3tc` (BC1/BC2/BC3),
|
|
158
|
+
`WEBGL_compressed_texture_s3tc_srgb` and `WEBGL_compressed_texture_astc`;
|
|
159
|
+
each extension is published only when the device can sample its formats.
|
|
160
|
+
`texImage2D` also accepts the latest decoded `<video>` frame and an
|
|
161
|
+
`ImageBitmap` produced by `createImageBitmap`. Cube maps
|
|
162
|
+
(`bindTexture(TEXTURE_CUBE_MAP)` plus six `texImage2D` faces) and 3D/array
|
|
163
|
+
textures (`texImage3D`/`texStorage3D`) are sampled through `samplerCube`,
|
|
164
|
+
`sampler3D` and `sampler2DArray`; `texSubImage3D` updates a sub-volume and
|
|
165
|
+
`framebufferTextureLayer` renders one array/cube layer as a colour
|
|
166
|
+
attachment.
|
|
167
|
+
- **Framebuffers**: `createFramebuffer`, `bindFramebuffer`
|
|
168
|
+
(`FRAMEBUFFER`/`READ_FRAMEBUFFER`/`DRAW_FRAMEBUFFER`),
|
|
169
|
+
`framebufferTexture2D` (`COLOR_ATTACHMENT0`, `DEPTH_ATTACHMENT`,
|
|
170
|
+
`DEPTH_STENCIL_ATTACHMENT`), `checkFramebufferStatus`, `createRenderbuffer`,
|
|
171
|
+
`bindRenderbuffer`, `renderbufferStorage` (depth or depth-stencil),
|
|
172
|
+
`framebufferRenderbuffer`, `delete*`, and `blitFramebuffer` (colour
|
|
173
|
+
attachment; depth/stencil bits are accepted but not copied). This is enough
|
|
174
|
+
for render-to-texture, shadow maps and post-processing passes.
|
|
151
175
|
- **State**: `enable`/`disable`/`isEnabled` for `BLEND`, `DEPTH_TEST`,
|
|
152
|
-
`CULL_FACE`, `SCISSOR_TEST`
|
|
153
|
-
`clearColor`/`clearDepth`/`clearStencil`, `clear
|
|
154
|
-
|
|
155
|
-
`
|
|
156
|
-
`
|
|
176
|
+
`CULL_FACE`, `SCISSOR_TEST` and `STENCIL_TEST`,
|
|
177
|
+
`clearColor`/`clearDepth`/`clearStencil`, `clear` (with `SCISSOR_TEST` it
|
|
178
|
+
clears only the scissor rectangle, for colour, depth and stencil), `blendColor`,
|
|
179
|
+
`blendFunc`/`blendFuncSeparate`,
|
|
180
|
+
`blendEquation`/`blendEquationSeparate`, `depthFunc`,
|
|
181
|
+
`depthMask`, `colorMask`, `stencilFunc`/`stencilFuncSeparate`,
|
|
182
|
+
`stencilOp`/`stencilOpSeparate`, `stencilMask`/`stencilMaskSeparate`,
|
|
183
|
+
`cullFace`, `frontFace`, `viewport`, `scissor`,
|
|
184
|
+
`pixelStorei`, `finish`. The stencil test takes part in rasterisation and
|
|
185
|
+
`clear(STENCIL_BUFFER_BIT)` clears the stencil attachment; SDL_GPU exposes
|
|
186
|
+
one reference and one compare/write mask for both faces, so a front/back
|
|
187
|
+
pair that differs uses the front value.
|
|
157
188
|
- **Readback**: `readPixels` (RGBA/UNSIGNED_BYTE) from the default framebuffer
|
|
158
|
-
or a bound framebuffer
|
|
189
|
+
or a bound RGBA8 framebuffer; a float/depth attachment is sampled into an
|
|
190
|
+
RGBA8 target first. It blocks until the GPU finishes; use it for tests and
|
|
159
191
|
screenshots, not per frame.
|
|
160
192
|
|
|
161
193
|
WebGL 2 adds:
|
|
@@ -174,38 +206,46 @@ WebGL 2 adds:
|
|
|
174
206
|
texture's own filter/wrap state for that unit.
|
|
175
207
|
- **Immutable textures and buffer copies**: `texStorage2D` (the backend always
|
|
176
208
|
allocates the full mip chain), `copyBufferSubData`, `getBufferSubData`.
|
|
209
|
+
- **Drawing buffer**: `drawingBufferStorage(width, height)` fixes the drawing
|
|
210
|
+
buffer size; `canvas.width`/`canvas.height` no longer rebuild it afterwards.
|
|
177
211
|
- **Clears**: `clearBufferfv`, `clearBufferiv`, `clearBufferuiv`,
|
|
178
212
|
`clearBufferfi`.
|
|
213
|
+
- **Multiple render targets**: `drawBuffers` addresses up to four colour
|
|
214
|
+
attachments and `readBuffer` selects the attachment `readPixels` reads;
|
|
215
|
+
`framebufferTexture2D` accepts `COLOR_ATTACHMENT0`…`3`, and a fragment
|
|
216
|
+
shader's multiple `out` variables are written in order.
|
|
179
217
|
- **Queries and fences**: the objects and entry points exist
|
|
180
218
|
(`createQuery`/`beginQuery`/`endQuery`/`getQueryParameter`,
|
|
181
219
|
`fenceSync`/`clientWaitSync`/`waitSync`/`getSyncParameter`) and degrade
|
|
182
220
|
gracefully: a fence reports `ALREADY_SIGNALED` and query results are 0.
|
|
183
|
-
- **Uniform blocks**: `getUniformBlockIndex
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
221
|
+
- **Uniform blocks**: `getUniformBlockIndex`,
|
|
222
|
+
`getActiveUniformBlockParameter`, `getActiveUniformBlockName`,
|
|
223
|
+
`uniformBlockBinding`, `bindBufferBase`/`bindBufferRange` and
|
|
224
|
+
`getIndexedParameter`. Members are merged into the engine's single std140
|
|
225
|
+
block and copied from the bound buffer at draw time; scalars, vectors,
|
|
226
|
+
matrices and fixed-size arrays work, nested structs, sampler members and
|
|
227
|
+
blocks without an instance name are rejected.
|
|
228
|
+
- **Transform feedback**: the entry points are present as no-ops so
|
|
229
|
+
feature-probing libraries do not throw.
|
|
187
230
|
|
|
188
231
|
Textures are created with a full mip chain; sampling clamps to level 0 until
|
|
189
232
|
`generateMipmap` runs. Matrix vertex attributes consume the right number of
|
|
190
233
|
consecutive locations and read one column per location. A disabled attribute
|
|
191
234
|
is supplied from the last `vertexAttrib*f` value through a small constant
|
|
192
|
-
buffer.
|
|
235
|
+
buffer. A vertex shader can sample textures just like a fragment shader:
|
|
236
|
+
`MAX_VERTEX_TEXTURE_IMAGE_UNITS` reports 16, vertex samplers live in set 0 and
|
|
237
|
+
are bound with `SDL_BindGPUVertexSamplers` on every draw. Depth values use the
|
|
238
|
+
backend's `[0, 1]` clip space rather than GL's `[-1, 1] → [0, 1]` remap:
|
|
239
|
+
`gl_Position.z = 0.5` stores depth `0.5` (real WebGL stores `0.75`).
|
|
193
240
|
|
|
194
241
|
## Not implemented
|
|
195
242
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
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.
|
|
243
|
+
Transform feedback (the entry points are no-ops) and MSAA/sample buffers
|
|
244
|
+
(SDL_GPU's Metal multisample resolve returns undefined pixels with scissor
|
|
245
|
+
tests and instanced draws, so contexts stay single-sampled). `blitFramebuffer`
|
|
246
|
+
copies the colour attachment only; depth/stencil bits are accepted but not
|
|
247
|
+
copied. Shaders that use built-in blocks or `gl_FragDepth` are rejected with a
|
|
248
|
+
compile/link log.
|
|
209
249
|
|
|
210
250
|
## Platform
|
|
211
251
|
|
|
@@ -225,10 +265,27 @@ uses the 2D canvas or the DOM pays no run-time cost beyond the archive size.
|
|
|
225
265
|
## Testing
|
|
226
266
|
|
|
227
267
|
- `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
|
-
|
|
230
|
-
|
|
231
|
-
|
|
268
|
+
depth-tested quad, checks face culling and reads the pixels back; it also
|
|
269
|
+
covers blend constants, dynamic buffer usage, vertex-shader texture sampling,
|
|
270
|
+
`gl_FragDepth` diagnostics, context loss/restore and cube maps.
|
|
271
|
+
- `tests/e2e/gui-webgl2.test.ts` covers the WebGL 2 shader/state additions:
|
|
272
|
+
`#version 300 es` shaders, a VAO round trip, instanced draws with a divisor,
|
|
273
|
+
`texStorage2D`, `clearBufferfv`, buffer copies, sampler objects, struct-uniform
|
|
274
|
+
fields and `drawingBufferStorage`.
|
|
275
|
+
- `tests/e2e/gui-webgl2-formats.test.ts` covers stencil, float/depth textures,
|
|
276
|
+
compressed textures and `ImageBitmap`.
|
|
277
|
+
- `tests/e2e/gui-webgl2-blit.test.ts` covers scissored colour/depth clears,
|
|
278
|
+
framebuffer blits, and the pixels around a partial blit that must survive
|
|
279
|
+
(a destination load-op that discards them fails there on Metal).
|
|
280
|
+
- `tests/e2e/gui-media.test.ts` also uploads the latest decoded `<video>` frame
|
|
281
|
+
as a texture and reads it back.
|
|
282
|
+
- `tests/e2e/gui-webgl2-3d.test.ts` covers 2D-array and 3D texture layer
|
|
283
|
+
sampling, `texSubImage3D` sub-volume updates and rendering to a colour
|
|
284
|
+
attachment layer.
|
|
285
|
+
- `tests/e2e/gui-webgl2-mrt.test.ts` writes two fragment outputs to two
|
|
286
|
+
colour attachments and reads each back.
|
|
287
|
+
- `tests/e2e/gui-webgl2-ubo.test.ts` binds a std140 block, updates its members
|
|
288
|
+
and verifies the drawn colour.
|
|
232
289
|
- `examples/gui/webgl-cube` is a spinning, lit, textured cube; it runs in a
|
|
233
290
|
browser unchanged and is covered by
|
|
234
291
|
`tests/e2e/gui-example-webgl.test.ts`.
|
|
@@ -249,8 +306,10 @@ is bundled any more**. Verified with three.js r160 through SDL_GPU:
|
|
|
249
306
|
`CanvasTexture`, linear fog, ambient/directional/point/spot/hemisphere lights,
|
|
250
307
|
`Sprite`, `Line`, `Points` and `InstancedMesh`.
|
|
251
308
|
|
|
252
|
-
Features outside this engine's subset still cannot be emulated:
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
309
|
+
Features outside this engine's subset still cannot be emulated: transform
|
|
310
|
+
feedback and MSAA.
|
|
311
|
+
Depth textures, float render targets and compressed textures are available, but
|
|
312
|
+
three.js shadow maps still need comparative `sampler2DShadow` sampling, which
|
|
313
|
+
is not translated yet. A scene that needs one of those will not render
|
|
314
|
+
correctly; everything the previous Canvas2D fallback could show now goes
|
|
315
|
+
through the GPU.
|
package/doc/gui.md
CHANGED
|
@@ -25,7 +25,10 @@ engine bounded memory: see [Node lifetime](./gui/dom.md#node-lifetime) and
|
|
|
25
25
|
thread with a vendored minimal FFmpeg, video frames go through the image texture
|
|
26
26
|
path and audio to an SDL stream, with the DOM media API exposing
|
|
27
27
|
`play`/`pause`/`currentTime`/… and media events. Enabling `gui` alone does not
|
|
28
|
-
link FFmpeg.
|
|
28
|
+
link FFmpeg. The browser globals also get a real `AudioContext`: a 48 kHz mixer
|
|
29
|
+
in `runtime/ext_gui/audio_mixer.cpp` plus `decodeAudioData` (WAV in-engine,
|
|
30
|
+
compressed formats through `media`) — see
|
|
31
|
+
[GUI API](./gui/api.md#web-audio).
|
|
29
32
|
**M14** adds `<canvas>` with a self-written 2D software rasteriser (anti-aliased
|
|
30
33
|
fills, paths, text and `drawImage`) uploaded through the image texture path —
|
|
31
34
|
see [Canvas](./gui/canvas.md). **M15** adds CSS `transform` /
|
|
@@ -188,8 +191,9 @@ engine were Rust.
|
|
|
188
191
|
annotating the run.
|
|
189
192
|
- The `package` job builds `gui.a`/`gui.lib` and `media.a`/`media.lib` before
|
|
190
193
|
assembling the release, so both ship inside the existing runtime archive
|
|
191
|
-
(`package-release` copies all of `runtime/`)
|
|
192
|
-
Windows
|
|
194
|
+
(`package-release` copies all of `runtime/`) and inside the optional
|
|
195
|
+
`@xbintsc/<os>-<arch>` npm package. Windows x64 is included; Windows arm64
|
|
196
|
+
still skips them.
|
|
193
197
|
- `vendor/` (SDL3/FreeType/HarfBuzz for the GUI archive, FFmpeg for `media`)
|
|
194
198
|
is cached per OS/arch, keyed by `scripts/build-gui.ts` /
|
|
195
199
|
`scripts/build-media.ts`. Windows x64 gets its own source cache plus the
|
package/doc/npm-package.md
CHANGED
|
@@ -36,8 +36,9 @@ If you are an agent asked to build a project that already depends on `xbintsc`:
|
|
|
36
36
|
4. Run the artifact (`./build/<name>`, `.exe` on Windows) and report its path.
|
|
37
37
|
5. If the build reports unsupported syntax, read the installed subset guide at
|
|
38
38
|
`node_modules/xbintsc/doc/ai/language-support.md`; do not assume
|
|
39
|
-
Node-compatible TypeScript.
|
|
40
|
-
|
|
39
|
+
Node-compatible TypeScript. With the optional platform package installed the
|
|
40
|
+
first build links a prebuilt runtime; without it, the C runtime is compiled
|
|
41
|
+
from source and that build is noticeably slower.
|
|
41
42
|
|
|
42
43
|
Do not run `npm install` inside `node_modules/xbintsc`, and do not substitute
|
|
43
44
|
`tsc`/`esbuild` for xbintsc: the native artifact must come from `npx xbintsc`.
|
|
@@ -54,15 +55,22 @@ The package contains:
|
|
|
54
55
|
It runs the compiler through Node.js. The binary it produces is still
|
|
55
56
|
standalone: it does not embed Node, V8 or a TypeScript compiler.
|
|
56
57
|
|
|
58
|
+
Installing it also installs the optional `@xbintsc/<os>-<arch>` package for the
|
|
59
|
+
host (for example `@xbintsc/linux-x64`). That package contains the prebuilt
|
|
60
|
+
runtime archives under `runtime/lib/<os>-<arch>/`: `core`, `ext_node` and, where
|
|
61
|
+
the release publishes them, `gui` and `media`. The driver links those archives
|
|
62
|
+
in place, so the first build does not compile the C runtime and needs no extra
|
|
63
|
+
download from the release page.
|
|
64
|
+
|
|
57
65
|
The package does **not** contain:
|
|
58
66
|
|
|
59
|
-
- a C compiler — you need clang 16+ on the machine that builds
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
67
|
+
- a C compiler — you need clang 16+ on the machine that builds.
|
|
68
|
+
|
|
69
|
+
If npm skips the optional package (`--omit=optional`, a package manager that
|
|
70
|
+
does not install optional dependencies, or a host the release does not build
|
|
71
|
+
for), the driver falls back to compiling the C runtime from the shipped sources
|
|
72
|
+
and caches the objects; that build works but is slower, and `--ext gui` /
|
|
73
|
+
`--ext media` need the archive to be present.
|
|
66
74
|
|
|
67
75
|
## Requirements
|
|
68
76
|
|
|
@@ -182,7 +190,7 @@ npm run build:native
|
|
|
182
190
|
./build/main # .\build\main.exe on Windows
|
|
183
191
|
```
|
|
184
192
|
|
|
185
|
-
Expected output
|
|
193
|
+
Expected output:
|
|
186
194
|
|
|
187
195
|
```text
|
|
188
196
|
xbintsc: wrote /absolute/path/my-app/build/main
|
|
@@ -195,17 +203,38 @@ pass the file explicitly: `xbintsc build src/main.ts --out build`.
|
|
|
195
203
|
|
|
196
204
|
## The first build and the cache
|
|
197
205
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
206
|
+
With the platform package installed, the first build links the prebuilt
|
|
207
|
+
`runtime/lib/<os>-<arch>/core.a` (`.lib` on Windows) and does not compile C at
|
|
208
|
+
all, so it takes about as long as an incremental build.
|
|
209
|
+
|
|
210
|
+
If the optional package is missing — `npm install --omit=optional`, a package
|
|
211
|
+
manager that does not install optional dependencies, or a host the release does
|
|
212
|
+
not build for — the driver compiles the C runtime from the shipped sources
|
|
213
|
+
instead. The runtime objects are cached by source/header content hash. The
|
|
214
|
+
default cache is `.xbintsc/` **in the directory you run the command from** (not
|
|
215
|
+
necessarily next to the config file); set `xbintsc_CACHE_DIR` to put it
|
|
216
|
+
elsewhere. Expect that fallback build to take noticeably longer than the ones
|
|
217
|
+
after it.
|
|
218
|
+
|
|
219
|
+
To ignore the platform archive on purpose and compile the runtime from the
|
|
220
|
+
sources shipped in the package — for example after patching `runtime/`, or when
|
|
221
|
+
the prebuilt archive does not match the environment — set:
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
xbintsc_PREFER_PREBUILT=0 npx xbintsc build src/main.ts --out build
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
The objects are still cached in `.xbintsc/`; point `xbintsc_CACHE_DIR` at an
|
|
228
|
+
empty directory (or delete `.xbintsc/`) for a full rebuild. `--force` alone
|
|
229
|
+
does not bypass a prebuilt archive. The archive files themselves are produced
|
|
230
|
+
by `npm run runtime` in a source checkout; users never need to regenerate them
|
|
231
|
+
just to compile.
|
|
201
232
|
|
|
202
|
-
|
|
203
|
-
`core.a`, the first build compiles each runtime translation unit. Expect that
|
|
204
|
-
build to take noticeably longer than the ones after it. `--time` shows where the
|
|
205
|
-
time went:
|
|
233
|
+
`--time` shows where the time went:
|
|
206
234
|
|
|
207
235
|
```bash
|
|
208
236
|
npx xbintsc build src/main.ts --out build --time
|
|
237
|
+
# fallback without the platform package:
|
|
209
238
|
# xbintsc: timing (frontend 4ms, codegen 7ms, clang 1089ms, runtime 37770ms, link 1966ms)
|
|
210
239
|
```
|
|
211
240
|
|
|
@@ -220,7 +249,7 @@ Practical consequences:
|
|
|
220
249
|
|
|
221
250
|
- add `.xbintsc/` to `.gitignore`;
|
|
222
251
|
- keep `.xbintsc/` between CI runs (or point `xbintsc_CACHE_DIR` at a persistent
|
|
223
|
-
directory)
|
|
252
|
+
directory) so a fallback build does not recompile the runtime every time;
|
|
224
253
|
- deleting `.xbintsc/` is safe — the next build recreates it;
|
|
225
254
|
- `--force` ignores the build freshness record, but cached runtime objects are
|
|
226
255
|
still reused. Delete `.xbintsc/` if you want to force a full C rebuild.
|
|
@@ -368,17 +397,16 @@ jobs:
|
|
|
368
397
|
| | npm package (`xbintsc`) | Prebuilt release archive |
|
|
369
398
|
| --- | --- | --- |
|
|
370
399
|
| Needs Node.js | Yes, 22+ | No |
|
|
371
|
-
| First build |
|
|
372
|
-
| GUI / media extensions |
|
|
400
|
+
| First build | Links the prebuilt runtime from the optional platform package | Links the prebuilt runtime |
|
|
401
|
+
| GUI / media extensions | Included on Linux/macOS and Windows x64 (the hosts the release builds them for) | Included in Linux/macOS and Windows x64 archives |
|
|
373
402
|
| Installation | `npm install` + lockfile / provenance | Download, verify `.sha256`, unpack |
|
|
374
403
|
| Programmatic API | Yes | No (CLI only) |
|
|
375
404
|
| Cross-compiles | No — host only | No — host only |
|
|
376
|
-
| Best for | Node projects and CI, familiar npm workflow | Machines without Node,
|
|
405
|
+
| Best for | Node projects and CI, familiar npm workflow | Machines without Node, GUI apps, a fully self-contained install |
|
|
377
406
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
development).
|
|
407
|
+
The npm package gets the same prebuilt runtime through its optional platform
|
|
408
|
+
package, so the cold-build penalty only applies when that package is skipped.
|
|
409
|
+
Use a release archive when Node is not available.
|
|
382
410
|
|
|
383
411
|
## Things that differ from a regular Node build
|
|
384
412
|
|
|
@@ -408,10 +436,10 @@ the same file under `node_modules/xbintsc/doc/ai/`.
|
|
|
408
436
|
| `npx xbintsc` uses an unexpected version | Run `npx --no-install xbintsc version` and `npm ls xbintsc`; pin the version in `package.json` and use `npm ci` in CI. |
|
|
409
437
|
| `requires Node.js 22` / engine error | Upgrade Node; the compiler uses modern Node APIs. |
|
|
410
438
|
| `No C compiler found` or `requires clang 16 or newer` | Install clang 16+ and run `npx xbintsc doctor`; set `xbintsc_CLANG` to a specific clang if needed. |
|
|
411
|
-
| The first build takes a long time |
|
|
439
|
+
| The first build takes a long time | The optional `@xbintsc/<os>-<arch>` package was skipped (or this host has no prebuilt package), so the runtime C sources are compiled and cached. Check `npm ls @xbintsc/<os>-<arch>` and reinstall without `--omit=optional`; `--time` confirms. |
|
|
412
440
|
| Permission errors writing `.xbintsc/` | Set `xbintsc_CACHE_DIR` to a writable directory, or run from a writable working directory. |
|
|
413
441
|
| `module 'fs' is provided by the 'node' extension` | Add `--ext node`, or `"extensions": ["node"]` in the config. |
|
|
414
|
-
| `GUI native library not found` / `media native library not found` | The
|
|
442
|
+
| `GUI native library not found` / `media native library not found` | The optional platform package that ships `gui.a`/`gui.lib` or `media.a`/`media.lib` was skipped, or this host has no prebuilt GUI/media archive (Windows arm64). Reinstall without `--omit=optional`, use a Linux/macOS/Windows x64 release archive, or build the archive from a source checkout. |
|
|
415
443
|
| `require("xbintsc")` fails | The package is ESM-only; use `import` (or dynamic `import()`). |
|
|
416
444
|
| Windows link errors about missing MSVC libraries | Run from a Native Tools prompt, install the VS C++ build tools, and check `npx xbintsc doctor`. |
|
|
417
445
|
| `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
|
@@ -81,8 +81,12 @@ xbintsc-<os>-<arch>/
|
|
|
81
81
|
runtime/ C runtime sources + prebuilt runtime/lib/<os>-<arch>/
|
|
82
82
|
```
|
|
83
83
|
|
|
84
|
-
|
|
85
|
-
runtime
|
|
84
|
+
Every archive carries the prebuilt runtime for its host under
|
|
85
|
+
`runtime/lib/<os>-<arch>/`: `core` and `ext_node` on all platforms (`.lib`
|
|
86
|
+
instead of `.a` with the MSVC ABI on Windows), plus `gui`/`media` where the
|
|
87
|
+
release builds them. The npm package receives the same archives from its
|
|
88
|
+
optional `@xbintsc/<os>-<arch>` dependency, so an npm install does not compile
|
|
89
|
+
the C runtime either.
|
|
86
90
|
|
|
87
91
|
Unpack it, put `bin/` on `PATH` (or call `bin/xbintsc` directly), and install the
|
|
88
92
|
toolchain for your platform below. Verify the download against the checksum
|
package/doc/zh-CN/gui/api.md
CHANGED
|
@@ -30,6 +30,12 @@ API 编写的文档可以原样运行。
|
|
|
30
30
|
窗口;这也意味着从资源管理器启动时 stdout/stderr 无处可去,调试时可在
|
|
31
31
|
`xbintsc.config.json` 里设置 `app.console: true` 保留控制台子系统。
|
|
32
32
|
|
|
33
|
+
没有可用 GPU 的宿主无法运行 GUI。当 SDL 无法打开视频驱动,或无法创建
|
|
34
|
+
Metal/Vulkan/D3D12 设备时,引擎会打印原因并以状态码 **77** 退出——这是 autotools
|
|
35
|
+
的“跳过”约定,CI 与脚本因此可以区分“这台机器没有 GUI”和“程序失败”。此后若窗口仍
|
|
36
|
+
无法打开(SDL 窗口或 GPU claim 错误),`createWindow` 会抛出 JavaScript `Error`,
|
|
37
|
+
而不再返回 `undefined` 句柄、让下一行以 `Cannot read properties of undefined` 失败。
|
|
38
|
+
|
|
33
39
|
触发的事件:
|
|
34
40
|
`ready`(首个呈现帧之后)、`load`、`close`、`resize`,以及输入事件
|
|
35
41
|
`mousemove`、`mousedown`、`mouseup`、`click`、`wheel`、`keydown`、`keyup`。
|
|
@@ -53,10 +59,11 @@ requestAnimationFrame(frame);
|
|
|
53
59
|
| `document` | 该窗口的 document 句柄 |
|
|
54
60
|
| `navigator` | `userAgent`(以 `xbintsc` 结尾的桌面 Chrome 字符串)、`platform`、`vendor`、`language(s)`、`hardwareConcurrency`、`maxTouchPoints`、`onLine`、`vibrate()` |
|
|
55
61
|
| `localStorage` | 内存中的 `getItem` / `setItem` / `removeItem` / `clear` / `key` / `length` |
|
|
56
|
-
| `AudioContext`、`webkitAudioContext` | Web Audio
|
|
62
|
+
| `AudioContext`、`webkitAudioContext` | 带真实混音器与解码器的 Web Audio 图(见下) |
|
|
57
63
|
| `Event`、`CustomEvent`、`ProgressEvent` 等 | 事件构造器 |
|
|
58
64
|
| `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`、`
|
|
65
|
+
| `ImageBitmap`、`createImageBitmap(source)` | 由已解码像素支撑的不可变位图(`<img>`、`<canvas>`、`<video>` 帧与 `ImageData` 形状);promise 立即 settle,`texImage2D` 可直接接受该对象 |
|
|
66
|
+
| `ImageData`、`OffscreenCanvas`、`XRWebGL*`、`Request`、`Headers`、`Response`、`ReadableStream`、`DOMParser` | `typeof` 探测返回 `"undefined"`(没有 XR/fetch/流式后端),让页面走自己的“不支持”分支,而不是调用空壳。Three.js 页面在本后端上使用真实渲染器(见[已知问题](./known-issues.md))。 |
|
|
60
67
|
| `requestAnimationFrame` / `cancelAnimationFrame` | 排入窗口的动画帧列表,见[运行时集成](./runtime.md) |
|
|
61
68
|
| `alert` / `confirm` / `prompt`、`matchMedia`、`getComputedStyle`、`escape` | 宿主实现(Annex B `escape` 按 UTF-16 码元编码,与 `decodeURIComponent(escape(bytes))` 一致) |
|
|
62
69
|
|
|
@@ -66,15 +73,49 @@ requestAnimationFrame(frame);
|
|
|
66
73
|
|
|
67
74
|
### Web Audio
|
|
68
75
|
|
|
69
|
-
`new AudioContext()`
|
|
70
|
-
|
|
71
|
-
`
|
|
72
|
-
|
|
73
|
-
|
|
76
|
+
`new AudioContext()` 会构建**真正参与混音的音频图**:`runtime/ext_gui/audio_mixer.cpp`
|
|
77
|
+
以 48 kHz 立体声 float、128 帧为一个渲染量子进行混音,每个节点对多路输入求和;
|
|
78
|
+
首次 `start()`/`resume()` 会尽力打开默认 SDL 播放设备(无头环境下保持静音但仍在渲染)。
|
|
79
|
+
音频在 SDL 音频线程上基于原生状态渲染,页面无须自行驱动,音频线程也不会触碰任何运行时值。
|
|
80
|
+
|
|
81
|
+
已实现的节点:`createGain`、`createOscillator`(sine、square、sawtooth、triangle)、
|
|
82
|
+
`createBufferSource`(buffer、loop、loopStart/loopEnd、playbackRate/detune)、
|
|
83
|
+
`createBiquadFilter`(lowpass、highpass、bandpass、lowshelf、highshelf、peaking、notch、allpass)、
|
|
84
|
+
`createDynamicsCompressor`、`createStereoPanner`、`createConstantSource` 与
|
|
85
|
+
`createDelay(maxDelayTime)`。`connect` 返回目标节点,因此可链式连接
|
|
86
|
+
(`src.connect(gain).connect(ctx.destination)`);`disconnect()` / `disconnect(target)`
|
|
87
|
+
会更新原生图;`start(when, offset, duration)` / `stop(when)` 按图的时钟生效。
|
|
88
|
+
列表之外的节点(`createAnalyser`、`createConvolver`、`createWaveShaper`、
|
|
89
|
+
`createChannelSplitter`、`createPeriodicWave` 等)不提供,其方法就是缺失的。
|
|
90
|
+
|
|
91
|
+
每个 `AudioParam` 都有实时 `value`,以及 `setValueAtTime` / `linearRampToValueAtTime` /
|
|
74
92
|
`exponentialRampToValueAtTime` / `setTargetAtTime` / `cancelScheduledValues` /
|
|
75
|
-
`cancelAndHoldAtTime
|
|
76
|
-
`
|
|
77
|
-
|
|
93
|
+
`cancelAndHoldAtTime`。自动化时间线**逐采样**求值,因此页面空闲时斜坡仍会继续推进;
|
|
94
|
+
`currentTime` 随渲染量子前进。
|
|
95
|
+
|
|
96
|
+
`createBuffer(channels, length, sampleRate)` 返回的 AudioBuffer 的
|
|
97
|
+
`getChannelData(i)` 是真正的 `Float32Array`,可以用代码逐样本填充。
|
|
98
|
+
`decodeAudioData(bytes)` 返回解码后的 AudioBuffer Promise:WAV(PCM 8/16/24/32 位、
|
|
99
|
+
IEEE float 32/64、A-law 与 µ-law)由引擎自身解码;MP3、AAC/M4A、Vorbis、Opus 与 FLAC
|
|
100
|
+
需要可选的 `media` 扩展(`--ext gui,media`),以其中的 FFmpeg 解码器作为回退。
|
|
101
|
+
`bytes` 可以是 ArrayBuffer、类型化数组、Node `Buffer`,或 `fs.readFileSync`
|
|
102
|
+
返回的原始字节字符串(本运行时没有专门的二进制类型,而该字符串的存储正是文件字节)。
|
|
103
|
+
解码结果会重采样到上下文的 48 kHz,因此 `buffer.sampleRate` 与
|
|
104
|
+
`context.sampleRate` 一致;若没有可用的解码器,Promise 会以 `EncodingError` 拒绝。
|
|
105
|
+
|
|
106
|
+
`resume()` / `suspend()` / `close()` 控制设备与 `state` 属性;`sampleRate` 为 48000,
|
|
107
|
+
与媒体解码器一致。
|
|
108
|
+
|
|
109
|
+
测试与诊断可以创建**离线**上下文同步渲染:
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
const ctx = new AudioContext({ __offline: true });
|
|
113
|
+
// … 构建音频图并启动音源 …
|
|
114
|
+
const samples = ctx.__render(480); // 交错立体声 Float32Array
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
这个私有钩子不会打开设备,也不属于 Web Audio API;`tests/e2e/gui-audio.test.ts`
|
|
118
|
+
用它来固定混音数学。
|
|
78
119
|
|
|
79
120
|
输入处理器接收单个负载对象(生命周期处理器不接收任何参数):
|
|
80
121
|
|
package/doc/zh-CN/gui/build.md
CHANGED
|
@@ -52,10 +52,15 @@
|
|
|
52
52
|
`vendor/ffmpeg-build-msvc/dist`,而不是执行 `make install`。
|
|
53
53
|
- CI 在组装发布归档之前构建 `gui.a`/`gui.lib` 与 `media.a`/`media.lib`,因此它们
|
|
54
54
|
会随 `runtime/lib/<slug>/` 一起发布(发布 tarball 会复制整个 `runtime/` 树)。
|
|
55
|
-
|
|
55
|
+
同一批目录还会打进可选的 `@xbintsc/<slug>` npm 包,因此发布覆盖的宿主平台从
|
|
56
|
+
npm 安装后也能使用 `--ext gui`/`--ext media`。归档在 Linux(Xvfb 下,使用
|
|
57
|
+
lavapipe 软件 Vulkan 驱动)与 macOS 上构建并运行
|
|
56
58
|
示例;Windows x64 也会构建两个归档并链接一个 `gui,media` 程序,因此 MSVC
|
|
57
59
|
构建在 CI 中得到验证,只是*运行*示例仍为试验性(托管 runner 没有 GPU/Vulkan
|
|
58
|
-
驱动)。
|
|
60
|
+
驱动)。macOS 的运行同样是试验性的:Intel runner 的虚拟 GPU 缺少
|
|
61
|
+
`MTLGPUFamilyMac2`,引擎会以 **77**(“此机器无法运行 GUI”)退出,任务记录为跳过,
|
|
62
|
+
而不是去编译一套无法呈现的测试。Windows arm64 仍跳过两个归档(FFmpeg 的
|
|
63
|
+
MSVC arm64 构建尚未验证)。
|
|
59
64
|
- Windows CI 通过 `.github/actions/vs-toolchain` →
|
|
60
65
|
`scripts/setup-vs-toolchain.ps1` 使用与本地构建相同的 Visual Studio
|
|
61
66
|
`vcvarsall` 环境和自带的 LLVM(不再单独安装 Chocolatey LLVM)。媒体构建时该
|
package/doc/zh-CN/gui/dom.md
CHANGED
|
@@ -14,7 +14,9 @@ doctype 跳过,实体解码(命名 + 十进制/十六进制),空元素
|
|
|
14
14
|
|
|
15
15
|
**CSS 解析器**(`runtime/ext_gui/css.{h,cpp}`):会剥离注释;`@media` 块递归解析
|
|
16
16
|
(嵌套查询用 `and` 合并,逗号列表会分配到内层查询),其他 at-rule 跳过。规则支持
|
|
17
|
-
|
|
17
|
+
多选择器与声明;选择器列表可以跨任意多行书写(换行就是普通空白,换行后的
|
|
18
|
+
组合器仍按组合器处理),引号内的属性值即使包含逗号、方括号或圆括号也不会
|
|
19
|
+
拆开列表。选择器:类型、`.class`、`#id`、属性
|
|
18
20
|
(`=`、`~=`、`|=`、`^=`、`$=`、`*=`)、四种组合器(后代、子、相邻兄弟与
|
|
19
21
|
通用兄弟)、伪类 `:first-child`、`:last-child`、`:only-child`、`:empty`、
|
|
20
22
|
`:root`、`:not(...)`、`:nth-child(an+b)`、`:disabled`、`:checked`、有状态的
|
package/doc/zh-CN/gui/media.md
CHANGED
|
@@ -91,6 +91,9 @@ Windows 已不再特殊:`media.lib` 是用 clang-cl 为 MSVC ABI 编译的 FFm
|
|
|
91
91
|
`media.a`/`media.lib` 只依赖 FFmpeg。
|
|
92
92
|
- **线程。** 引擎是单线程且非线程感知,因此所有解码都在主线程的
|
|
93
93
|
`xt_gui_media_tick` 内完成——没有解码线程,也没有跨线程 GC 暴露。
|
|
94
|
+
- **`decodeAudioData`。** 同一套 FFmpeg 还会为 `AudioContext.decodeAudioData`
|
|
95
|
+
解码内存中的音频文件(`runtime/ext_media/decode_audio.cpp`,经媒体表分发);
|
|
96
|
+
WAV 由 GUI 引擎自身处理(`audio_decode.cpp`),因此只有压缩格式需要该扩展。
|
|
94
97
|
- **DOM API。** 元素句柄直接暴露媒体接口(见
|
|
95
98
|
`runtime/ext_gui/dom_api_media.cpp` 与 `dom_api_proto.cpp` 中的原型):
|
|
96
99
|
`play()` / `pause()` / `load()`,以及 `paused` / `ended` / `duration` /
|