xbintsc 0.5.38 → 0.5.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/cli/help.d.ts +1 -1
- package/dist/src/codegen/generator/module.js +23 -7
- package/dist/src/codegen/generator/module.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/html.js +9 -2
- package/dist/src/extensions/gui/html.js.map +1 -1
- package/dist/tests/codegen/closures.test.js +7 -0
- package/dist/tests/codegen/closures.test.js.map +1 -1
- package/dist/tests/e2e/compile-objects-classes.test.js +31 -0
- package/dist/tests/e2e/compile-objects-classes.test.js.map +1 -1
- package/dist/tests/e2e/gui-canvas-state.test.d.ts +9 -0
- package/dist/tests/e2e/gui-canvas-state.test.js +297 -0
- package/dist/tests/e2e/gui-canvas-state.test.js.map +1 -0
- package/dist/tests/e2e/gui-draw-perf.test.d.ts +22 -0
- package/dist/tests/e2e/gui-draw-perf.test.js +405 -0
- package/dist/tests/e2e/gui-draw-perf.test.js.map +1 -0
- package/dist/tests/e2e/gui-perf.test.d.ts +23 -0
- package/dist/tests/e2e/gui-perf.test.js +283 -0
- package/dist/tests/e2e/gui-perf.test.js.map +1 -0
- package/dist/tests/e2e/gui-script-import-order.test.js +9 -1
- package/dist/tests/e2e/gui-script-import-order.test.js.map +1 -1
- package/dist/tests/e2e/gui-webgl.test.js +4 -4
- package/dist/tests/e2e/gui-webgl.test.js.map +1 -1
- package/dist/tests/e2e/gui-webgl2-shadow-sampler.test.d.ts +8 -0
- package/dist/tests/e2e/gui-webgl2-shadow-sampler.test.js +336 -0
- package/dist/tests/e2e/gui-webgl2-shadow-sampler.test.js.map +1 -0
- package/dist/tests/extensions/gui.test.js +23 -0
- package/dist/tests/extensions/gui.test.js.map +1 -1
- package/doc/gui/api.md +28 -2
- package/doc/gui/canvas.md +110 -27
- package/doc/gui/known-issues.md +32 -10
- package/doc/gui/rendering.md +77 -0
- package/doc/gui/runtime.md +18 -3
- package/doc/gui/webgl.md +38 -19
- package/doc/gui.md +33 -1
- package/doc/zh-CN/gui/api.md +25 -2
- package/doc/zh-CN/gui/canvas.md +95 -26
- package/doc/zh-CN/gui/known-issues.md +21 -4
- package/doc/zh-CN/gui/rendering.md +59 -0
- package/doc/zh-CN/gui/runtime.md +13 -3
- package/doc/zh-CN/gui/webgl.md +27 -5
- package/doc/zh-CN/gui.md +25 -2
- package/package.json +7 -7
- package/runtime/ext_gui/browser.cpp +3 -1
- package/runtime/ext_gui/canvas.cpp +135 -89
- package/runtime/ext_gui/canvas.h +116 -0
- package/runtime/ext_gui/canvas_clip.cpp +143 -0
- package/runtime/ext_gui/canvas_composite.cpp +241 -0
- package/runtime/ext_gui/canvas_coverage.cpp +241 -0
- package/runtime/ext_gui/canvas_gradient.cpp +41 -4
- package/runtime/ext_gui/canvas_image_data.cpp +4 -0
- package/runtime/ext_gui/canvas_internal.h +34 -9
- package/runtime/ext_gui/canvas_raster.cpp +207 -178
- package/runtime/ext_gui/canvas_shadow.cpp +161 -0
- package/runtime/ext_gui/canvas_stroke.cpp +37 -9
- package/runtime/ext_gui/canvas_style.cpp +59 -0
- package/runtime/ext_gui/canvas_text.cpp +140 -0
- package/runtime/ext_gui/css.h +7 -0
- package/runtime/ext_gui/css_sheet.cpp +22 -0
- package/runtime/ext_gui/document.cpp +25 -1
- package/runtime/ext_gui/document.h +8 -0
- package/runtime/ext_gui/dom_api_canvas.cpp +16 -1
- package/runtime/ext_gui/dom_api_canvas_image.cpp +9 -0
- package/runtime/ext_gui/dom_api_canvas_state.cpp +217 -0
- package/runtime/ext_gui/dom_api_internal.h +36 -37
- package/runtime/ext_gui/dom_api_offscreen.cpp +213 -0
- package/runtime/ext_gui/dom_api_proto.cpp +18 -0
- package/runtime/ext_gui/dom_api_webgl.cpp +19 -9
- package/runtime/ext_gui/dom_api_webgl_internal.h +58 -0
- package/runtime/ext_gui/dom_api_webgl_source.cpp +18 -0
- package/runtime/ext_gui/gradient_values.cpp +12 -1
- package/runtime/ext_gui/gui.cpp +5 -0
- package/runtime/ext_gui/gui_canvas.cpp +4 -0
- package/runtime/ext_gui/gui_engine.h +30 -0
- package/runtime/ext_gui/gui_events.cpp +182 -58
- package/runtime/ext_gui/gui_media.cpp +3 -0
- package/runtime/ext_gui/image.cpp +69 -0
- package/runtime/ext_gui/image_bitmap_browser.cpp +11 -0
- package/runtime/ext_gui/layout.cpp +4 -0
- package/runtime/ext_gui/paint.cpp +19 -0
- package/runtime/ext_gui/paint_background.cpp +18 -1
- package/runtime/ext_gui/perf.cpp +171 -0
- package/runtime/ext_gui/perf.h +127 -0
- package/runtime/ext_gui/renderer.cpp +109 -41
- package/runtime/ext_gui/renderer.h +33 -9
- package/runtime/ext_gui/renderer_image.cpp +135 -65
- package/runtime/ext_gui/renderer_internal.h +15 -3
- package/runtime/ext_gui/renderer_text.cpp +24 -12
- package/runtime/ext_gui/style.cpp +101 -30
- package/runtime/ext_gui/style.h +6 -3
- package/runtime/ext_gui/style_print.cpp +7 -1
- package/runtime/ext_gui/text.cpp +23 -4
- package/runtime/ext_gui/text.h +29 -0
- package/runtime/ext_gui/text_cache.cpp +118 -0
- package/runtime/ext_gui/text_glyph_cache.cpp +100 -0
- package/runtime/ext_gui/webgl.h +48 -146
- package/runtime/ext_gui/webgl_blit.cpp +12 -1
- package/runtime/ext_gui/webgl_blit_depth.cpp +270 -0
- package/runtime/ext_gui/webgl_buffer.cpp +59 -1
- package/runtime/ext_gui/webgl_buffer_objects.cpp +106 -9
- package/runtime/ext_gui/webgl_clear.cpp +3 -0
- package/runtime/ext_gui/webgl_context.cpp +29 -3
- package/runtime/ext_gui/webgl_draw.cpp +75 -270
- package/runtime/ext_gui/webgl_draw_buffers.cpp +1 -0
- package/runtime/ext_gui/webgl_draw_setup.cpp +321 -0
- package/runtime/ext_gui/webgl_draw_state.h +130 -0
- package/runtime/ext_gui/webgl_glsl_scan.cpp +3 -8
- package/runtime/ext_gui/webgl_objects.h +148 -0
- package/runtime/ext_gui/webgl_pipeline.cpp +8 -8
- package/runtime/ext_gui/webgl_program_internal.h +35 -0
- package/runtime/ext_gui/webgl_shader.cpp +22 -30
- package/runtime/ext_gui/webgl_webgl2.cpp +36 -0
- package/runtime/ext_gui/window.cpp +56 -1
- package/src/codegen/generator/module.ts +22 -7
- package/src/driver/version.ts +1 -1
- package/src/extensions/gui/html.ts +9 -2
|
@@ -22,36 +22,8 @@
|
|
|
22
22
|
namespace xtgui {
|
|
23
23
|
namespace {
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
if (type == "vec2") return GL_FLOAT_VEC2;
|
|
28
|
-
if (type == "vec3") return GL_FLOAT_VEC3;
|
|
29
|
-
if (type == "vec4") return GL_FLOAT_VEC4;
|
|
30
|
-
if (type == "int" || type == "uint") return GL_INT;
|
|
31
|
-
if (type == "ivec2" || type == "uvec2") return GL_INT_VEC2;
|
|
32
|
-
if (type == "ivec3" || type == "uvec3") return GL_INT_VEC3;
|
|
33
|
-
if (type == "ivec4" || type == "uvec4") return GL_INT_VEC4;
|
|
34
|
-
if (type == "bool") return GL_BOOL;
|
|
35
|
-
if (type == "bvec2") return GL_BOOL_VEC2;
|
|
36
|
-
if (type == "bvec3") return GL_BOOL_VEC3;
|
|
37
|
-
if (type == "bvec4") return GL_BOOL_VEC4;
|
|
38
|
-
if (type == "mat2") return GL_FLOAT_MAT2;
|
|
39
|
-
if (type == "mat3") return GL_FLOAT_MAT3;
|
|
40
|
-
if (type == "mat4") return GL_FLOAT_MAT4;
|
|
41
|
-
if (type == "sampler2D") return GL_SAMPLER_2D;
|
|
42
|
-
if (type == "samplerCube") return GL_SAMPLER_CUBE;
|
|
43
|
-
if (type == "sampler3D") return GL_SAMPLER_3D;
|
|
44
|
-
if (type == "sampler2DArray") return GL_SAMPLER_2D_ARRAY;
|
|
45
|
-
return 0;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/** How many consecutive attribute/varying locations a type consumes. */
|
|
49
|
-
int location_slots(const std::string &type) {
|
|
50
|
-
if (type == "mat2") return 2;
|
|
51
|
-
if (type == "mat3") return 3;
|
|
52
|
-
if (type == "mat4") return 4;
|
|
53
|
-
return 1;
|
|
54
|
-
}
|
|
25
|
+
using webgl_detail::gl_type_of;
|
|
26
|
+
using webgl_detail::location_slots;
|
|
55
27
|
|
|
56
28
|
/** Merge uniforms declared by both stages, in declaration order. */
|
|
57
29
|
bool merge_uniforms(const GlslShaderInfo &vs, const GlslShaderInfo &fs,
|
|
@@ -232,6 +204,9 @@ void WebGLContext::release_program_pipelines(WebGLProgram *program) {
|
|
|
232
204
|
if (program->fs_shader != nullptr) SDL_ReleaseGPUShader(guidev::g_device, program->fs_shader);
|
|
233
205
|
program->vs_shader = nullptr;
|
|
234
206
|
program->fs_shader = nullptr;
|
|
207
|
+
/* Prepared draws hold pipeline pointers too; a relink reuses the same program
|
|
208
|
+
* id, so they must not be served from the cache after this. */
|
|
209
|
+
clear_draw_cache();
|
|
235
210
|
}
|
|
236
211
|
|
|
237
212
|
void WebGLContext::delete_program(uint32_t id) {
|
|
@@ -425,6 +400,19 @@ bool WebGLContext::link_program(uint32_t id) {
|
|
|
425
400
|
record->vs_sampler_uniforms.clear();
|
|
426
401
|
record->fs_sampler_uniforms.clear();
|
|
427
402
|
|
|
403
|
+
/* Resolve the active attributes once: a draw then iterates this plan instead
|
|
404
|
+
* of re-scanning `attribs` and hashing every attribute name again. */
|
|
405
|
+
record->draw_attribs.clear();
|
|
406
|
+
record->draw_attribs.reserve(record->attribs.size());
|
|
407
|
+
for (const GlslUniformDecl &decl : record->attribs) {
|
|
408
|
+
auto found = record->attrib_locations.find(decl.name);
|
|
409
|
+
if (found == record->attrib_locations.end()) continue;
|
|
410
|
+
WebGLDrawAttribPlan plan;
|
|
411
|
+
plan.location = found->second;
|
|
412
|
+
plan.type = decl.type;
|
|
413
|
+
record->draw_attribs.push_back(plan);
|
|
414
|
+
}
|
|
415
|
+
|
|
428
416
|
for (const GlslBlockMember &member : members) {
|
|
429
417
|
WebGLUniform uniform;
|
|
430
418
|
uniform.name = member.name;
|
|
@@ -442,14 +430,18 @@ bool WebGLContext::link_program(uint32_t id) {
|
|
|
442
430
|
|
|
443
431
|
auto add_sampler = [](WebGLProgram *program, std::vector<int> *stage,
|
|
444
432
|
const GlslUniformDecl &decl) {
|
|
433
|
+
const bool compare = decl.type == "sampler2DShadow" || decl.type == "samplerCubeShadow" ||
|
|
434
|
+
decl.type == "sampler2DArrayShadow";
|
|
445
435
|
int index = -1;
|
|
446
436
|
auto found = program->uniform_index.find(decl.name);
|
|
447
437
|
if (found != program->uniform_index.end()) {
|
|
448
438
|
index = found->second;
|
|
439
|
+
program->uniforms[(size_t)index].compare = compare;
|
|
449
440
|
} else {
|
|
450
441
|
WebGLUniform uniform;
|
|
451
442
|
uniform.name = decl.name;
|
|
452
443
|
uniform.sampler = true;
|
|
444
|
+
uniform.compare = compare;
|
|
453
445
|
uniform.unit = 0;
|
|
454
446
|
uniform.layout.gl_type = gl_type_of(decl.type);
|
|
455
447
|
index = (int)program->uniforms.size();
|
|
@@ -78,6 +78,7 @@ void WebGLContext::save_vertex_array() {
|
|
|
78
78
|
void WebGLContext::load_vertex_array(const WebGLVertexArray *array) {
|
|
79
79
|
for (int i = 0; i < kWebGLMaxAttribs; i++) attribs_[i] = array->attribs[i];
|
|
80
80
|
bound_element_ = array->element_buffer;
|
|
81
|
+
attribs_version_ += 1;
|
|
81
82
|
}
|
|
82
83
|
|
|
83
84
|
void WebGLContext::bind_vertex_array(uint32_t id) {
|
|
@@ -238,6 +239,11 @@ bool WebGLContext::sampler_parameter(uint32_t id, int pname, int value) {
|
|
|
238
239
|
else if (pname == GL_TEXTURE_MAG_FILTER) record->mag_filter = value;
|
|
239
240
|
else if (pname == GL_TEXTURE_WRAP_S) record->wrap_s = value;
|
|
240
241
|
else if (pname == GL_TEXTURE_WRAP_T) record->wrap_t = value;
|
|
242
|
+
else if (pname == GL_TEXTURE_COMPARE_MODE) {
|
|
243
|
+
record->compare_mode = value == GL_COMPARE_REF_TO_TEXTURE;
|
|
244
|
+
} else if (pname == GL_TEXTURE_COMPARE_FUNC) {
|
|
245
|
+
record->compare_func = value;
|
|
246
|
+
}
|
|
241
247
|
if (record->gpu != nullptr && guidev::g_device != nullptr) {
|
|
242
248
|
SDL_ReleaseGPUSampler(guidev::g_device, record->gpu);
|
|
243
249
|
record->gpu = nullptr;
|
|
@@ -252,6 +258,10 @@ int WebGLContext::sampler_parameter_value(uint32_t id, int pname) {
|
|
|
252
258
|
if (pname == GL_TEXTURE_MAG_FILTER) return record->mag_filter;
|
|
253
259
|
if (pname == GL_TEXTURE_WRAP_S) return record->wrap_s;
|
|
254
260
|
if (pname == GL_TEXTURE_WRAP_T) return record->wrap_t;
|
|
261
|
+
if (pname == GL_TEXTURE_COMPARE_MODE) {
|
|
262
|
+
return record->compare_mode ? GL_COMPARE_REF_TO_TEXTURE : GL_NONE;
|
|
263
|
+
}
|
|
264
|
+
if (pname == GL_TEXTURE_COMPARE_FUNC) return record->compare_func;
|
|
255
265
|
return 0;
|
|
256
266
|
}
|
|
257
267
|
|
|
@@ -270,6 +280,32 @@ SDL_GPUSampler *WebGLContext::sampler_gpu(WebGLSampler *record) {
|
|
|
270
280
|
/* A sampler object has no texture, so it cannot know how many levels exist;
|
|
271
281
|
* textures created by this engine always carry a full mip chain. */
|
|
272
282
|
info.max_lod = 1000.0f;
|
|
283
|
+
if (record->compare_mode) {
|
|
284
|
+
info.enable_compare = true;
|
|
285
|
+
switch (record->compare_func) {
|
|
286
|
+
case GL_NEVER:
|
|
287
|
+
info.compare_op = SDL_GPU_COMPAREOP_NEVER;
|
|
288
|
+
break;
|
|
289
|
+
case GL_LESS:
|
|
290
|
+
info.compare_op = SDL_GPU_COMPAREOP_LESS;
|
|
291
|
+
break;
|
|
292
|
+
case GL_EQUAL:
|
|
293
|
+
info.compare_op = SDL_GPU_COMPAREOP_EQUAL;
|
|
294
|
+
break;
|
|
295
|
+
case GL_GREATER:
|
|
296
|
+
info.compare_op = SDL_GPU_COMPAREOP_GREATER;
|
|
297
|
+
break;
|
|
298
|
+
case GL_NOTEQUAL:
|
|
299
|
+
info.compare_op = SDL_GPU_COMPAREOP_NOT_EQUAL;
|
|
300
|
+
break;
|
|
301
|
+
case GL_GEQUAL:
|
|
302
|
+
info.compare_op = SDL_GPU_COMPAREOP_GREATER_OR_EQUAL;
|
|
303
|
+
break;
|
|
304
|
+
default:
|
|
305
|
+
info.compare_op = SDL_GPU_COMPAREOP_LESS_OR_EQUAL;
|
|
306
|
+
break;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
273
309
|
record->gpu = SDL_CreateGPUSampler(guidev::g_device, &info);
|
|
274
310
|
return record->gpu;
|
|
275
311
|
}
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
#include "inline_svg.h"
|
|
17
17
|
#include "paint.h"
|
|
18
|
+
#include "perf.h"
|
|
18
19
|
#include "text.h"
|
|
19
20
|
|
|
20
21
|
static xt_value g_window_proto = XT_UNDEFINED;
|
|
@@ -72,10 +73,15 @@ static xt_value win_load_html(xt_value self, xt_value env, int32_t argc, xt_valu
|
|
|
72
73
|
xt_gui_window_viewport(win, &width, &height);
|
|
73
74
|
win->document->load(html, width, height);
|
|
74
75
|
win->geometry.dirty = 1;
|
|
76
|
+
win->present_dirty = 1;
|
|
75
77
|
/* Run the AOT-compiled `<script>` bodies now that the tree is parsed, so
|
|
76
78
|
* `document.getElementById(...)` resolves, then settle the first layout. */
|
|
77
79
|
xt_gui_run_scripts(win);
|
|
78
80
|
xt_gui_flush_dom(win);
|
|
81
|
+
/* The document was replaced, so the frame loop must reconcile the media
|
|
82
|
+
* and canvas tables with it on the next frame. `loadHTML` already flushed
|
|
83
|
+
* the style/layout, so this is a sync request, not a restyle. */
|
|
84
|
+
win->sync_dirty = 1;
|
|
79
85
|
}
|
|
80
86
|
xt_object_set(self, xt_string_from_cstr("__xt_gui_html"), xt_string_from_cstr(html.c_str()));
|
|
81
87
|
/* Painting the document is milestone M3b+; the parsed tree and computed
|
|
@@ -199,6 +205,7 @@ static xt_value win_set_background(xt_value self, xt_value env, int32_t argc, xt
|
|
|
199
205
|
win->background[1] = color.g;
|
|
200
206
|
win->background[2] = color.b;
|
|
201
207
|
win->background[3] = color.a;
|
|
208
|
+
win->present_dirty = 1;
|
|
202
209
|
}
|
|
203
210
|
}
|
|
204
211
|
xt_object_set(self, xt_string_from_cstr("__xt_gui_background"), text);
|
|
@@ -265,7 +272,10 @@ static xt_value win_advance(xt_value self, xt_value env, int32_t argc, xt_value
|
|
|
265
272
|
XtGuiWindow *win = xt_gui_window_from_this(self);
|
|
266
273
|
if (win == nullptr || win->document == nullptr) return XT_UNDEFINED;
|
|
267
274
|
double ms = argc > 0 ? xt_to_number(xt_arg(argc, argv, 0)) : 0.0;
|
|
268
|
-
if (win->document->advance(ms))
|
|
275
|
+
if (win->document->advance(ms)) {
|
|
276
|
+
win->geometry.dirty = 1;
|
|
277
|
+
win->present_dirty = 1;
|
|
278
|
+
}
|
|
269
279
|
return XT_UNDEFINED;
|
|
270
280
|
}
|
|
271
281
|
|
|
@@ -481,6 +491,51 @@ static xt_value win_stats(xt_value self, xt_value env, int32_t argc, xt_value *a
|
|
|
481
491
|
xt_number(win != nullptr ? (double)win->node_order.size() : 0));
|
|
482
492
|
xt_object_set(object, xt_string_from_cstr("listeners"),
|
|
483
493
|
xt_number(win != nullptr ? (double)win->node_listeners.size() : 0));
|
|
494
|
+
/* -- renderer counters (see `perf.h`) ---------------------------------- */
|
|
495
|
+
/* The `*Ms` values describe the last completed frame; every other counter is
|
|
496
|
+
* cumulative (diff two calls to get the work one frame did). */
|
|
497
|
+
const xtgui::PerfTimings &ms = xtgui::g_perf_last;
|
|
498
|
+
xt_object_set(object, xt_string_from_cstr("frameMs"), xt_number(ms.frame));
|
|
499
|
+
xt_object_set(object, xt_string_from_cstr("restyleMs"), xt_number(ms.restyle));
|
|
500
|
+
xt_object_set(object, xt_string_from_cstr("layoutMs"), xt_number(ms.layout));
|
|
501
|
+
xt_object_set(object, xt_string_from_cstr("paintMs"), xt_number(ms.paint));
|
|
502
|
+
xt_object_set(object, xt_string_from_cstr("uploadMs"), xt_number(ms.upload));
|
|
503
|
+
xt_object_set(object, xt_string_from_cstr("drawMs"), xt_number(ms.draw));
|
|
504
|
+
const xtgui::PerfCounters &counters = xtgui::g_perf_total;
|
|
505
|
+
auto setCounter = [&object](const char *name, uint64_t value) {
|
|
506
|
+
xt_object_set(object, xt_string_from_cstr(name), xt_number((double)value));
|
|
507
|
+
};
|
|
508
|
+
setCounter("frames", counters.frames);
|
|
509
|
+
setCounter("presents", counters.presents);
|
|
510
|
+
setCounter("exposes", counters.exposes);
|
|
511
|
+
setCounter("deferred", counters.deferred);
|
|
512
|
+
setCounter("starvedFrames", counters.starvedFrames);
|
|
513
|
+
setCounter("skippedFrames", counters.skippedFrames);
|
|
514
|
+
setCounter("restyles", counters.restyles);
|
|
515
|
+
setCounter("restyleNodes", counters.restyleNodes);
|
|
516
|
+
setCounter("rulesEvaluated", counters.rulesEvaluated);
|
|
517
|
+
setCounter("mediaEvaluated", counters.mediaEvaluated);
|
|
518
|
+
setCounter("layouts", counters.layouts);
|
|
519
|
+
setCounter("layoutBoxes", counters.layoutBoxes);
|
|
520
|
+
setCounter("textShapeCalls", counters.textShapeCalls);
|
|
521
|
+
setCounter("textShapeHits", counters.textShapeHits);
|
|
522
|
+
setCounter("textCacheBytes", xtgui::xt_text_cache_bytes());
|
|
523
|
+
setCounter("textCacheEntries", xtgui::xt_text_cache_entries());
|
|
524
|
+
setCounter("paints", counters.paints);
|
|
525
|
+
setCounter("paintOps", counters.paintOps);
|
|
526
|
+
setCounter("drawRuns", counters.drawRuns);
|
|
527
|
+
setCounter("drawCalls", counters.drawCalls);
|
|
528
|
+
setCounter("uploadSubmits", counters.uploadSubmits);
|
|
529
|
+
setCounter("vertices", counters.vertices);
|
|
530
|
+
setCounter("syncNodes", counters.syncNodes);
|
|
531
|
+
setCounter("transitionFrames", counters.transitionFrames);
|
|
532
|
+
setCounter("canvasDraws", counters.canvasDraws);
|
|
533
|
+
setCounter("canvasUploads", counters.canvasUploads);
|
|
534
|
+
setCounter("canvasUploadBytes", counters.canvasUploadBytes);
|
|
535
|
+
setCounter("webglDraws", counters.webglDraws);
|
|
536
|
+
setCounter("webglPasses", counters.webglPasses);
|
|
537
|
+
setCounter("webglPipelineMisses", counters.webglPipelineMisses);
|
|
538
|
+
setCounter("webglBufferUploadBytes", counters.webglBufferUploadBytes);
|
|
484
539
|
return object;
|
|
485
540
|
}
|
|
486
541
|
|
|
@@ -160,6 +160,18 @@ export const moduleMethods: ModuleMethods = {
|
|
|
160
160
|
);
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
+
// Captures threaded through the environment. Declared before the
|
|
164
|
+
// parameters because a default parameter may read an enclosing binding
|
|
165
|
+
// (e.g. `constructor(wrapS = ClampToEdgeWrapping)`), and a capture has no
|
|
166
|
+
// other slot to read.
|
|
167
|
+
for (const symbol of fn.captures) {
|
|
168
|
+
if (this.moduleGlobals.has(symbol.id)) continue;
|
|
169
|
+
const index = fn.captureIndex.get(symbol.id)!;
|
|
170
|
+
const value = this.reg();
|
|
171
|
+
this.emit(` ${value} = call i64 @xt_closure_env(i64 %env, i32 ${index})`);
|
|
172
|
+
this.defineCaptureSlot(symbol, value);
|
|
173
|
+
}
|
|
174
|
+
|
|
163
175
|
// Parameters.
|
|
164
176
|
const parameterNodes = (fn.node as { parameters?: Parameter[] }).parameters ?? [];
|
|
165
177
|
for (let index = 0; index < fn.params.length; index++) {
|
|
@@ -185,13 +197,16 @@ export const moduleMethods: ModuleMethods = {
|
|
|
185
197
|
if (parameter.initializer) this.emitDefaultParameter(symbol, value, parameter.initializer);
|
|
186
198
|
}
|
|
187
199
|
|
|
188
|
-
//
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
200
|
+
// Boxed bindings declared in this frame get their box now, before any
|
|
201
|
+
// statement runs. A closure built earlier in the body — a class's methods
|
|
202
|
+
// are installed by the class statement, which may precede the `const` the
|
|
203
|
+
// method reads — captures the box pointer, so the later declaration fills
|
|
204
|
+
// the same box. Without this the closure would capture an undefined slot
|
|
205
|
+
// (Three.js declares `_zero`/`_one` after the class that uses them).
|
|
206
|
+
for (const symbol of fn.locals) {
|
|
207
|
+
if (!symbol.boxed || this.moduleGlobals.has(symbol.id)) continue;
|
|
208
|
+
if (this.current.slots.has(symbol.id)) continue;
|
|
209
|
+
this.declareSlot(symbol, i64(XT_UNDEFINED));
|
|
195
210
|
}
|
|
196
211
|
|
|
197
212
|
// Hoisted function declarations: create their closure values in this
|
package/src/driver/version.ts
CHANGED
|
@@ -163,7 +163,10 @@ function deferredPrelude(alias: string, declaration: ImportDeclaration): string[
|
|
|
163
163
|
|
|
164
164
|
/** Split an external script module into hoisted imports and a body. */
|
|
165
165
|
function compileModuleSource(htmlPath: string, scriptPath: string, scriptIndex: number): CompiledModule {
|
|
166
|
-
|
|
166
|
+
/* Mask the normalized text: the parser indexes the `SourceFile` text, where
|
|
167
|
+
* `\r\n` already became `\n`, so blanking statement spans in the raw file
|
|
168
|
+
* would remove the wrong characters on a CRLF checkout. */
|
|
169
|
+
const source = new SourceFile(scriptPath, readFileSync(scriptPath, "utf8")).text;
|
|
167
170
|
const bag = new DiagnosticBag();
|
|
168
171
|
const parsed = new Parser(new SourceFile(scriptPath, source), bag).parseSourceFile();
|
|
169
172
|
const chars = source.split("");
|
|
@@ -256,6 +259,10 @@ function resolveScriptPath(htmlPath: string, src: string): string {
|
|
|
256
259
|
|
|
257
260
|
/** Rewrite `<script>` bodies into registered AOT functions + an HTML string. */
|
|
258
261
|
export function loadHtmlAsset(path: string, source: string): AssetLoadResult {
|
|
262
|
+
/* The generated module is parsed as a `SourceFile`, which rewrites `\r\n` to
|
|
263
|
+
* `\n`; normalize first so the module text, the offsets recorded for
|
|
264
|
+
* `<script src>` bodies and the exported HTML string all share one layout. */
|
|
265
|
+
const page = new SourceFile(path, source).text;
|
|
259
266
|
/* `file` is set for an external `<script src>`: its body keeps that file as
|
|
260
267
|
* the origin of every node, so a `.js` script stays untyped and diagnostics
|
|
261
268
|
* name the script, not the HTML page. */
|
|
@@ -267,7 +274,7 @@ export function loadHtmlAsset(path: string, source: string): AssetLoadResult {
|
|
|
267
274
|
|
|
268
275
|
/* The engine's cascade only reads `<style>` elements, so a linked stylesheet
|
|
269
276
|
* would be dropped at runtime. Inline it (and its `@import`s) now. */
|
|
270
|
-
const styles = inlineStylesheets(path,
|
|
277
|
+
const styles = inlineStylesheets(path, page);
|
|
271
278
|
const html = styles.html.replace(SCRIPT_RE, (match, attributes: string, inlineBody: string) => {
|
|
272
279
|
if (!isExecutable(attribute(attributes, "type"), attribute(attributes, "lang"))) return match;
|
|
273
280
|
const src = attribute(attributes, "src");
|