xbintsc 0.5.37 → 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/codegen/generator/state.js +1 -0
- package/dist/src/codegen/generator/state.js.map +1 -1
- package/dist/src/codegen/generator/tables.js +1 -0
- package/dist/src/codegen/generator/tables.js.map +1 -1
- package/dist/src/driver/bundler/deferred.d.ts +63 -0
- package/dist/src/driver/bundler/deferred.js +279 -0
- package/dist/src/driver/bundler/deferred.js.map +1 -0
- package/dist/src/driver/bundler/merge.js +214 -2
- package/dist/src/driver/bundler/merge.js.map +1 -1
- package/dist/src/driver/runtime-objects.d.ts +1 -1
- package/dist/src/driver/runtime-objects.js +1 -0
- package/dist/src/driver/runtime-objects.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 +98 -15
- package/dist/src/extensions/gui/html.js.map +1 -1
- package/dist/src/extensions/gui/index.js +1 -0
- package/dist/src/extensions/gui/index.js.map +1 -1
- package/dist/src/extensions/gui/three.d.ts +4 -3
- package/dist/src/extensions/gui/three.js +4 -3
- package/dist/src/extensions/gui/three.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.d.ts +10 -0
- package/dist/tests/e2e/gui-script-import-order.test.js +169 -0
- package/dist/tests/e2e/gui-script-import-order.test.js.map +1 -0
- 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/e2e/gui-webgl2-shadow.test.d.ts +10 -0
- package/dist/tests/e2e/gui-webgl2-shadow.test.js +108 -0
- package/dist/tests/e2e/gui-webgl2-shadow.test.js.map +1 -0
- package/dist/tests/e2e/url.test.d.ts +6 -0
- package/dist/tests/e2e/url.test.js +114 -0
- package/dist/tests/e2e/url.test.js.map +1 -0
- package/dist/tests/extensions/gui.test.js +45 -10
- 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 +58 -29
- package/doc/gui-scripts.md +19 -19
- package/doc/gui.md +43 -9
- package/doc/implemented/fetch.md +5 -0
- package/doc/implemented/modules.md +13 -0
- package/doc/implemented/stdlib.md +17 -0
- package/doc/unimplemented/deviations.md +1 -0
- 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 +30 -8
- package/doc/zh-CN/gui-scripts.md +14 -13
- package/doc/zh-CN/gui.md +32 -8
- package/doc/zh-CN/implemented/fetch.md +4 -0
- package/doc/zh-CN/implemented/modules.md +10 -0
- package/doc/zh-CN/implemented/stdlib.md +15 -0
- package/doc/zh-CN/unimplemented/deviations.md +1 -0
- 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 +29 -9
- package/runtime/ext_gui/dom_api_webgl2.cpp +33 -1
- 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 +32 -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/script.cpp +31 -0
- 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.h +3 -0
- package/runtime/ext_gui/webgl_glsl_scan.cpp +3 -8
- package/runtime/ext_gui/webgl_glsl_unroll.cpp +283 -0
- package/runtime/ext_gui/webgl_msl.cpp +4 -0
- 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 +34 -36
- package/runtime/ext_gui/webgl_webgl2.cpp +36 -0
- package/runtime/ext_gui/window.cpp +56 -1
- package/runtime/rt.h +3 -0
- package/runtime/xt_fetch/async.inc +60 -0
- package/runtime/xt_url_object.c +463 -0
- package/src/codegen/generator/module.ts +22 -7
- package/src/codegen/generator/state.ts +1 -0
- package/src/codegen/generator/tables.ts +1 -0
- package/src/driver/bundler/deferred.ts +351 -0
- package/src/driver/bundler/merge.ts +219 -2
- package/src/driver/runtime-objects.ts +1 -0
- package/src/driver/version.ts +1 -1
- package/src/extensions/gui/html.ts +100 -17
- package/src/extensions/gui/index.ts +1 -0
- package/src/extensions/gui/three.ts +4 -3
|
@@ -12,12 +12,13 @@
|
|
|
12
12
|
#include <cstring>
|
|
13
13
|
|
|
14
14
|
#include "gui_internal.h"
|
|
15
|
+
#include "perf.h"
|
|
15
16
|
|
|
16
17
|
namespace xtgui {
|
|
17
18
|
namespace {
|
|
18
19
|
|
|
19
20
|
bool upload_transfer(SDL_GPUDevice *device, SDL_GPUCommandBuffer *cmd, SDL_GPUBuffer *buffer,
|
|
20
|
-
const void *bytes, uint32_t size) {
|
|
21
|
+
const void *bytes, uint32_t size, uint32_t offset) {
|
|
21
22
|
if (size == 0) return true;
|
|
22
23
|
SDL_GPUTransferBufferCreateInfo info;
|
|
23
24
|
memset(&info, 0, sizeof(info));
|
|
@@ -39,6 +40,7 @@ bool upload_transfer(SDL_GPUDevice *device, SDL_GPUCommandBuffer *cmd, SDL_GPUBu
|
|
|
39
40
|
SDL_GPUBufferRegion region;
|
|
40
41
|
memset(®ion, 0, sizeof(region));
|
|
41
42
|
region.buffer = buffer;
|
|
43
|
+
region.offset = offset;
|
|
42
44
|
region.size = size;
|
|
43
45
|
SDL_UploadToGPUBuffer(copy, &source, ®ion, false);
|
|
44
46
|
SDL_EndGPUCopyPass(copy);
|
|
@@ -46,6 +48,33 @@ bool upload_transfer(SDL_GPUDevice *device, SDL_GPUCommandBuffer *cmd, SDL_GPUBu
|
|
|
46
48
|
return true;
|
|
47
49
|
}
|
|
48
50
|
|
|
51
|
+
/** Extend a buffer's dirty range to cover `[offset, offset + size)`. Offsets
|
|
52
|
+
* are rounded to 4 bytes because the SDL_GPU copy path requires an aligned
|
|
53
|
+
* destination offset. */
|
|
54
|
+
void mark_dirty_range(WebGLBuffer *buffer, uint32_t offset, uint32_t size) {
|
|
55
|
+
if (size == 0) return;
|
|
56
|
+
uint32_t lo = offset & ~3u;
|
|
57
|
+
uint32_t hi = (offset + size + 3u) & ~3u;
|
|
58
|
+
if (hi > (uint32_t)buffer->data.size()) hi = (uint32_t)buffer->data.size();
|
|
59
|
+
if (lo > hi) lo = hi;
|
|
60
|
+
if (!buffer->dirty) {
|
|
61
|
+
buffer->dirty_lo = lo;
|
|
62
|
+
buffer->dirty_hi = hi;
|
|
63
|
+
} else {
|
|
64
|
+
buffer->dirty_lo = std::min(buffer->dirty_lo, lo);
|
|
65
|
+
buffer->dirty_hi = std::max(buffer->dirty_hi, hi);
|
|
66
|
+
}
|
|
67
|
+
buffer->dirty = true;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** Round a byte size up to a power of two, so a growing buffer is reallocated
|
|
71
|
+
* O(log n) times instead of once per new frame's vertex count. */
|
|
72
|
+
uint32_t grow_capacity(uint32_t size) {
|
|
73
|
+
uint32_t capacity = 64;
|
|
74
|
+
while (capacity < size && capacity < (1u << 31)) capacity <<= 1;
|
|
75
|
+
return capacity < size ? size : capacity;
|
|
76
|
+
}
|
|
77
|
+
|
|
49
78
|
} // namespace
|
|
50
79
|
|
|
51
80
|
/* -- buffers ------------------------------------------------------------- */
|
|
@@ -66,6 +95,8 @@ void WebGLContext::delete_buffer(uint32_t id) {
|
|
|
66
95
|
for (WebGLAttribState &attrib : attribs_) {
|
|
67
96
|
if (attrib.buffer == id) attrib.buffer = 0;
|
|
68
97
|
}
|
|
98
|
+
gpu_version_ += 1;
|
|
99
|
+
attribs_version_ += 1;
|
|
69
100
|
if (found->second->gpu != nullptr && guidev::g_device != nullptr) {
|
|
70
101
|
submit(); SDL_WaitForGPUIdle(guidev::g_device);
|
|
71
102
|
SDL_ReleaseGPUBuffer(guidev::g_device, found->second->gpu);
|
|
@@ -107,7 +138,7 @@ bool WebGLContext::copy_buffer_sub_data(int read_target, int write_target, uint3
|
|
|
107
138
|
memmove(write_buffer->data.data() + write_offset,
|
|
108
139
|
read_buffer->data.data() + read_offset, size);
|
|
109
140
|
}
|
|
110
|
-
write_buffer
|
|
141
|
+
mark_dirty_range(write_buffer, write_offset, size);
|
|
111
142
|
return ensure_buffer_gpu(write_buffer) != nullptr || size == 0;
|
|
112
143
|
}
|
|
113
144
|
|
|
@@ -125,39 +156,97 @@ bool WebGLContext::get_buffer_sub_data(int target, uint32_t offset, uint8_t *out
|
|
|
125
156
|
SDL_GPUBuffer *WebGLContext::ensure_buffer_gpu(WebGLBuffer *buffer) {
|
|
126
157
|
if (buffer == nullptr || guidev::g_device == nullptr) return nullptr;
|
|
127
158
|
if (buffer->data.empty()) return nullptr;
|
|
159
|
+
const uint32_t size = (uint32_t)buffer->data.size();
|
|
160
|
+
const bool needs_storage = buffer->gpu == nullptr || buffer->capacity < size;
|
|
161
|
+
/* Steady state (data already on the GPU) must not end the open render pass:
|
|
162
|
+
* that was one pass restart per draw for every multi-element scene. */
|
|
163
|
+
if (!needs_storage && !buffer->dirty) return buffer->gpu;
|
|
128
164
|
end_pass();
|
|
129
165
|
ensure_command();
|
|
130
166
|
if (cmd_ == nullptr) return nullptr;
|
|
131
|
-
|
|
132
|
-
if (buffer->gpu == nullptr || buffer->capacity < size) {
|
|
167
|
+
if (needs_storage) {
|
|
133
168
|
if (buffer->gpu != nullptr) {
|
|
134
|
-
submit();
|
|
169
|
+
submit();
|
|
170
|
+
SDL_WaitForGPUIdle(guidev::g_device);
|
|
135
171
|
SDL_ReleaseGPUBuffer(guidev::g_device, buffer->gpu);
|
|
136
172
|
}
|
|
137
173
|
SDL_GPUBufferCreateInfo info;
|
|
138
174
|
memset(&info, 0, sizeof(info));
|
|
139
175
|
info.usage = SDL_GPU_BUFFERUSAGE_VERTEX | SDL_GPU_BUFFERUSAGE_INDEX;
|
|
140
|
-
info.size = size;
|
|
176
|
+
info.size = grow_capacity(size);
|
|
141
177
|
buffer->gpu = SDL_CreateGPUBuffer(guidev::g_device, &info);
|
|
142
|
-
buffer->capacity = size;
|
|
178
|
+
buffer->capacity = info.size;
|
|
143
179
|
if (buffer->gpu == nullptr) {
|
|
144
180
|
set_error(GL_OUT_OF_MEMORY);
|
|
145
181
|
return nullptr;
|
|
146
182
|
}
|
|
183
|
+
/* A fresh buffer holds nothing: everything must be uploaded. */
|
|
184
|
+
buffer->dirty_lo = 0;
|
|
185
|
+
buffer->dirty_hi = size;
|
|
186
|
+
buffer->dirty = true;
|
|
187
|
+
/* Cached draw setups hold the old handle. */
|
|
188
|
+
gpu_version_ += 1;
|
|
147
189
|
}
|
|
148
190
|
if (buffer->dirty) {
|
|
149
191
|
/* Recreating the buffer above submitted the pending command buffer. */
|
|
150
192
|
ensure_command();
|
|
151
193
|
if (cmd_ == nullptr) return nullptr;
|
|
152
|
-
|
|
194
|
+
uint32_t lo = std::min(buffer->dirty_lo, size);
|
|
195
|
+
uint32_t hi = std::min(buffer->dirty_hi, size);
|
|
196
|
+
if (hi > lo &&
|
|
197
|
+
!upload_transfer(guidev::g_device, cmd_, buffer->gpu, buffer->data.data() + lo, hi - lo,
|
|
198
|
+
lo)) {
|
|
153
199
|
set_error(GL_OUT_OF_MEMORY);
|
|
154
200
|
return nullptr;
|
|
155
201
|
}
|
|
202
|
+
g_perf_frame.webglBufferUploadBytes += hi - lo;
|
|
156
203
|
buffer->dirty = false;
|
|
204
|
+
buffer->dirty_lo = 0;
|
|
205
|
+
buffer->dirty_hi = 0;
|
|
157
206
|
}
|
|
158
207
|
return buffer->gpu;
|
|
159
208
|
}
|
|
160
209
|
|
|
210
|
+
bool WebGLContext::upload_buffer_range(SDL_GPUBuffer *gpu, uint32_t offset, const void *bytes,
|
|
211
|
+
uint32_t size) {
|
|
212
|
+
if (gpu == nullptr || size == 0) return true;
|
|
213
|
+
end_pass();
|
|
214
|
+
ensure_command();
|
|
215
|
+
if (cmd_ == nullptr) return false;
|
|
216
|
+
if (!upload_transfer(guidev::g_device, cmd_, gpu, bytes, size, offset)) {
|
|
217
|
+
set_error(GL_OUT_OF_MEMORY);
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
g_perf_frame.webglBufferUploadBytes += size;
|
|
221
|
+
return true;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
SDL_GPUBuffer *WebGLContext::constant_attrib_buffer(int index) {
|
|
225
|
+
if (index < 0 || index >= kWebGLMaxAttribs || guidev::g_device == nullptr) return nullptr;
|
|
226
|
+
WebGLAttribState &attrib = attribs_[index];
|
|
227
|
+
if (attrib.constant_gpu == nullptr) {
|
|
228
|
+
SDL_GPUBufferCreateInfo info;
|
|
229
|
+
memset(&info, 0, sizeof(info));
|
|
230
|
+
info.usage = SDL_GPU_BUFFERUSAGE_VERTEX;
|
|
231
|
+
info.size = sizeof(attrib.current);
|
|
232
|
+
attrib.constant_gpu = SDL_CreateGPUBuffer(guidev::g_device, &info);
|
|
233
|
+
if (attrib.constant_gpu == nullptr) {
|
|
234
|
+
set_error(GL_OUT_OF_MEMORY);
|
|
235
|
+
return nullptr;
|
|
236
|
+
}
|
|
237
|
+
attrib.constant_bytes = (uint32_t)sizeof(attrib.current);
|
|
238
|
+
attrib.constant_dirty = true;
|
|
239
|
+
}
|
|
240
|
+
if (attrib.constant_dirty) {
|
|
241
|
+
if (!upload_buffer_range(attrib.constant_gpu, 0, attrib.current,
|
|
242
|
+
(uint32_t)sizeof(attrib.current))) {
|
|
243
|
+
return nullptr;
|
|
244
|
+
}
|
|
245
|
+
attrib.constant_dirty = false;
|
|
246
|
+
}
|
|
247
|
+
return attrib.constant_gpu;
|
|
248
|
+
}
|
|
249
|
+
|
|
161
250
|
bool WebGLContext::buffer_data(uint32_t id, const uint8_t *bytes, uint32_t size, int usage) {
|
|
162
251
|
WebGLBuffer *record = buffer(id);
|
|
163
252
|
if (record == nullptr) {
|
|
@@ -173,6 +262,8 @@ bool WebGLContext::buffer_data(uint32_t id, const uint8_t *bytes, uint32_t size,
|
|
|
173
262
|
record->data.assign(size, 0);
|
|
174
263
|
if (bytes != nullptr && size > 0) memcpy(record->data.data(), bytes, size);
|
|
175
264
|
record->dirty = true;
|
|
265
|
+
record->dirty_lo = 0;
|
|
266
|
+
record->dirty_hi = size;
|
|
176
267
|
return ensure_buffer_gpu(record) != nullptr || size == 0;
|
|
177
268
|
}
|
|
178
269
|
|
|
@@ -185,7 +276,7 @@ bool WebGLContext::buffer_sub_data(uint32_t id, uint32_t offset, const uint8_t *
|
|
|
185
276
|
return false;
|
|
186
277
|
}
|
|
187
278
|
memcpy(record->data.data() + offset, bytes, size);
|
|
188
|
-
record
|
|
279
|
+
mark_dirty_range(record, offset, size);
|
|
189
280
|
return ensure_buffer_gpu(record) != nullptr;
|
|
190
281
|
}
|
|
191
282
|
|
|
@@ -202,6 +293,7 @@ void WebGLContext::enable_attrib(int index, bool enabled) {
|
|
|
202
293
|
return;
|
|
203
294
|
}
|
|
204
295
|
attribs_[index].enabled = enabled;
|
|
296
|
+
attribs_version_ += 1;
|
|
205
297
|
}
|
|
206
298
|
|
|
207
299
|
bool WebGLContext::attrib_enabled(int index) const {
|
|
@@ -222,6 +314,7 @@ void WebGLContext::attrib_pointer(int index, int size, int type, bool normalized
|
|
|
222
314
|
attrib.integer = false;
|
|
223
315
|
attrib.stride = stride > 0 ? stride : 0;
|
|
224
316
|
attrib.offset = offset;
|
|
317
|
+
attribs_version_ += 1;
|
|
225
318
|
}
|
|
226
319
|
|
|
227
320
|
void WebGLContext::attrib_ipointer(int index, int size, int type, int stride, int offset) {
|
|
@@ -237,6 +330,7 @@ void WebGLContext::attrib_ipointer(int index, int size, int type, int stride, in
|
|
|
237
330
|
attrib.integer = true;
|
|
238
331
|
attrib.stride = stride > 0 ? stride : 0;
|
|
239
332
|
attrib.offset = offset;
|
|
333
|
+
attribs_version_ += 1;
|
|
240
334
|
}
|
|
241
335
|
|
|
242
336
|
void WebGLContext::attrib_divisor(int index, int divisor) {
|
|
@@ -248,12 +342,15 @@ void WebGLContext::attrib_divisor(int index, int divisor) {
|
|
|
248
342
|
* rates WebGL programs use — per vertex (0) and per instance (1) — map onto
|
|
249
343
|
* the backend. A larger divisor is clamped. */
|
|
250
344
|
attribs_[index].divisor = divisor > 0 ? 1 : 0;
|
|
345
|
+
attribs_version_ += 1;
|
|
251
346
|
}
|
|
252
347
|
|
|
253
348
|
void WebGLContext::attrib_value(int index, int components, const float *values) {
|
|
254
349
|
if (index < 0 || index >= kWebGLMaxAttribs) return;
|
|
255
350
|
for (int i = 0; i < 4; i++) attribs_[index].current[i] = i < components ? values[i] : 0.0f;
|
|
256
351
|
if (components < 4) attribs_[index].current[3] = 1.0f;
|
|
352
|
+
attribs_[index].constant_dirty = true;
|
|
353
|
+
attribs_version_ += 1;
|
|
257
354
|
}
|
|
258
355
|
|
|
259
356
|
void WebGLContext::attrib_state(int index, int *size, int *type, int *stride, bool *normalized,
|
|
@@ -114,6 +114,8 @@ void WebGLContext::scissored_clear(int mask) {
|
|
|
114
114
|
attribs_[attrib].type = GL_FLOAT;
|
|
115
115
|
attribs_[attrib].stride = 8;
|
|
116
116
|
attribs_[attrib].offset = 0;
|
|
117
|
+
/* The temporary attribute layout must not be mistaken for the caller's. */
|
|
118
|
+
attribs_version_ += 1;
|
|
117
119
|
int target_width = 0;
|
|
118
120
|
int target_height = 0;
|
|
119
121
|
framebuffer_size(bound_framebuffer_, &target_width, &target_height);
|
|
@@ -136,6 +138,7 @@ void WebGLContext::scissored_clear(int mask) {
|
|
|
136
138
|
current_program_ = saved_program;
|
|
137
139
|
bound_array_ = saved_array;
|
|
138
140
|
memcpy(attribs_, saved_attribs, sizeof(attribs_));
|
|
141
|
+
attribs_version_ += 1;
|
|
139
142
|
for (int i = 0; i < 4; i++) viewport_[i] = saved_viewport[i];
|
|
140
143
|
}
|
|
141
144
|
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
#include <cstring>
|
|
16
16
|
|
|
17
17
|
#include "gui_internal.h"
|
|
18
|
+
#include "perf.h"
|
|
18
19
|
|
|
19
20
|
namespace xtgui {
|
|
20
21
|
namespace {
|
|
@@ -54,13 +55,22 @@ void WebGLContext::release_gpu_resources() {
|
|
|
54
55
|
if (guidev::g_device == nullptr) return;
|
|
55
56
|
SDL_WaitForGPUIdle(guidev::g_device);
|
|
56
57
|
for (auto &entry : programs_) release_program_pipelines(entry.second.get());
|
|
58
|
+
for (auto &entry : internal_pipelines_) {
|
|
59
|
+
if (entry.second != nullptr) SDL_ReleaseGPUGraphicsPipeline(guidev::g_device, entry.second);
|
|
60
|
+
}
|
|
61
|
+
internal_pipelines_.clear();
|
|
62
|
+
clear_draw_cache();
|
|
57
63
|
for (auto &entry : textures_) {
|
|
58
64
|
if (entry.second->gpu != nullptr) SDL_ReleaseGPUTexture(guidev::g_device, entry.second->gpu);
|
|
59
65
|
if (entry.second->sampler != nullptr) {
|
|
60
66
|
SDL_ReleaseGPUSampler(guidev::g_device, entry.second->sampler);
|
|
61
67
|
}
|
|
68
|
+
if (entry.second->compare_sampler != nullptr) {
|
|
69
|
+
SDL_ReleaseGPUSampler(guidev::g_device, entry.second->compare_sampler);
|
|
70
|
+
}
|
|
62
71
|
entry.second->gpu = nullptr;
|
|
63
72
|
entry.second->sampler = nullptr;
|
|
73
|
+
entry.second->compare_sampler = nullptr;
|
|
64
74
|
}
|
|
65
75
|
for (auto &entry : buffers_) {
|
|
66
76
|
if (entry.second->gpu != nullptr) SDL_ReleaseGPUBuffer(guidev::g_device, entry.second->gpu);
|
|
@@ -95,6 +105,10 @@ void WebGLContext::release_gpu_resources() {
|
|
|
95
105
|
SDL_ReleaseGPUSampler(guidev::g_device, fallback_sampler_);
|
|
96
106
|
fallback_sampler_ = nullptr;
|
|
97
107
|
}
|
|
108
|
+
if (blit_sampler_ != nullptr) {
|
|
109
|
+
SDL_ReleaseGPUSampler(guidev::g_device, blit_sampler_);
|
|
110
|
+
blit_sampler_ = nullptr;
|
|
111
|
+
}
|
|
98
112
|
if (color_ != nullptr) {
|
|
99
113
|
SDL_ReleaseGPUTexture(guidev::g_device, color_);
|
|
100
114
|
color_ = nullptr;
|
|
@@ -118,6 +132,8 @@ void WebGLContext::lose_context() {
|
|
|
118
132
|
* after the restore. */
|
|
119
133
|
shaders_.clear();
|
|
120
134
|
programs_.clear();
|
|
135
|
+
clear_draw_cache();
|
|
136
|
+
internal_pipelines_.clear();
|
|
121
137
|
buffers_.clear();
|
|
122
138
|
textures_.clear();
|
|
123
139
|
framebuffers_.clear();
|
|
@@ -198,7 +214,8 @@ void WebGLContext::ensure_default_target() {
|
|
|
198
214
|
info.sample_count = SDL_GPU_SAMPLECOUNT_1;
|
|
199
215
|
if (color_ == nullptr) color_ = SDL_CreateGPUTexture(guidev::g_device, &info);
|
|
200
216
|
info.format = SDL_GPU_TEXTUREFORMAT_D32_FLOAT_S8_UINT;
|
|
201
|
-
|
|
217
|
+
/* SAMPLER too: `blitFramebuffer` may copy the default depth attachment. */
|
|
218
|
+
info.usage = SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET | SDL_GPU_TEXTUREUSAGE_SAMPLER;
|
|
202
219
|
if (depth_ == nullptr) depth_ = SDL_CreateGPUTexture(guidev::g_device, &info);
|
|
203
220
|
}
|
|
204
221
|
|
|
@@ -234,6 +251,7 @@ void WebGLContext::resize(int width, int height) {
|
|
|
234
251
|
if (height < 0) height = 0;
|
|
235
252
|
width_ = width > 0 ? width : 1;
|
|
236
253
|
height_ = height > 0 ? height : 1;
|
|
254
|
+
framebuffer_version_ += 1;
|
|
237
255
|
viewport_[0] = 0;
|
|
238
256
|
viewport_[1] = 0;
|
|
239
257
|
viewport_[2] = width_;
|
|
@@ -290,11 +308,15 @@ void WebGLContext::framebuffer_size(uint32_t id, int *width, int *height) {
|
|
|
290
308
|
}
|
|
291
309
|
|
|
292
310
|
SDL_GPUTexture *WebGLContext::target_depth() {
|
|
293
|
-
|
|
311
|
+
return framebuffer_depth(bound_framebuffer_);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
SDL_GPUTexture *WebGLContext::framebuffer_depth(uint32_t id) {
|
|
315
|
+
if (id == 0) {
|
|
294
316
|
ensure_default_target();
|
|
295
317
|
return depth_;
|
|
296
318
|
}
|
|
297
|
-
WebGLFramebuffer *framebuffer = this->framebuffer(
|
|
319
|
+
WebGLFramebuffer *framebuffer = this->framebuffer(id);
|
|
298
320
|
if (framebuffer == nullptr) return nullptr;
|
|
299
321
|
if (framebuffer->depth_texture != 0) {
|
|
300
322
|
WebGLTexture *texture = this->texture(framebuffer->depth_texture);
|
|
@@ -393,6 +415,10 @@ void WebGLContext::begin_pass(bool clear_color, bool clear_depth, bool clear_ste
|
|
|
393
415
|
|
|
394
416
|
pass_ = SDL_BeginGPURenderPass(cmd_, color_infos, (Uint32)color_count,
|
|
395
417
|
depth != nullptr ? &depth_info : nullptr);
|
|
418
|
+
if (pass_ != nullptr) {
|
|
419
|
+
g_perf_frame.webglPasses += 1;
|
|
420
|
+
pass_serial_ += 1;
|
|
421
|
+
}
|
|
396
422
|
pass_targets_default_ = bound_framebuffer_ == 0;
|
|
397
423
|
pass_framebuffer_ = bound_framebuffer_;
|
|
398
424
|
}
|