xbintsc 0.5.32 → 0.5.37
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 +18 -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-browser.test.js +65 -0
- package/dist/tests/e2e/gui-browser.test.js.map +1 -1
- package/dist/tests/e2e/gui-canvas-args.test.d.ts +6 -0
- package/dist/tests/e2e/gui-canvas-args.test.js +217 -0
- package/dist/tests/e2e/gui-canvas-args.test.js.map +1 -0
- package/dist/tests/e2e/gui-canvas.test.js.map +1 -1
- package/dist/tests/e2e/gui-dom.test.js +215 -0
- package/dist/tests/e2e/gui-dom.test.js.map +1 -1
- package/dist/tests/e2e/gui-events.test.js +112 -0
- package/dist/tests/e2e/gui-events.test.js.map +1 -1
- 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 +99 -22
- package/doc/gui/build.md +11 -4
- package/doc/gui/canvas.md +49 -18
- package/doc/gui/dom.md +57 -7
- 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 +84 -14
- package/doc/zh-CN/gui/build.md +7 -2
- package/doc/zh-CN/gui/canvas.md +44 -19
- package/doc/zh-CN/gui/dom.md +48 -4
- 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 +45 -50
- package/runtime/ext_gui/browser_abort.cpp +249 -0
- package/runtime/ext_gui/browser_dialogs.cpp +76 -0
- package/runtime/ext_gui/browser_media.cpp +176 -0
- package/runtime/ext_gui/browser_navigation.cpp +130 -0
- package/runtime/ext_gui/canvas.cpp +88 -30
- package/runtime/ext_gui/canvas.h +74 -9
- package/runtime/ext_gui/canvas_image_data.cpp +143 -0
- package/runtime/ext_gui/canvas_internal.h +8 -5
- package/runtime/ext_gui/canvas_pattern.cpp +90 -0
- package/runtime/ext_gui/canvas_raster.cpp +31 -9
- package/runtime/ext_gui/canvas_style.cpp +4 -2
- package/runtime/ext_gui/css_selector.cpp +21 -3
- package/runtime/ext_gui/dom.h +4 -0
- package/runtime/ext_gui/dom_api.cpp +1 -0
- package/runtime/ext_gui/dom_api_canvas.cpp +120 -114
- package/runtime/ext_gui/dom_api_canvas_extra.cpp +57 -2
- package/runtime/ext_gui/dom_api_canvas_image.cpp +239 -0
- package/runtime/ext_gui/dom_api_canvas_paths.cpp +179 -0
- package/runtime/ext_gui/dom_api_computed_style.cpp +124 -0
- package/runtime/ext_gui/dom_api_dataset.cpp +154 -0
- package/runtime/ext_gui/dom_api_document.cpp +58 -5
- package/runtime/ext_gui/dom_api_events.cpp +93 -17
- package/runtime/ext_gui/dom_api_internal.h +71 -2
- package/runtime/ext_gui/dom_api_mutation.cpp +159 -0
- package/runtime/ext_gui/dom_api_node.cpp +40 -19
- package/runtime/ext_gui/dom_api_node_read.cpp +37 -1
- package/runtime/ext_gui/dom_api_path2d.cpp +358 -0
- package/runtime/ext_gui/dom_api_proto.cpp +35 -0
- package/runtime/ext_gui/dom_api_style.cpp +223 -13
- 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 +103 -14
- package/runtime/ext_gui/gui_engine.h +56 -4
- package/runtime/ext_gui/gui_events.cpp +80 -9
- 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/listener_options.h +43 -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/paint.cpp +28 -0
- package/runtime/ext_gui/paint.h +4 -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_gui/window.cpp +14 -65
- package/runtime/ext_gui/window_events.cpp +125 -0
- package/runtime/ext_media/decode_audio.cpp +308 -0
- package/runtime/ext_media/media_bridge.c +2 -0
- package/runtime/rt.h +43 -0
- package/runtime/rt_internal.h +4 -0
- package/runtime/xt_array_buffer.c +30 -0
- package/runtime/xt_builtins.c +0 -21
- package/runtime/xt_containers/access.inc +94 -2
- package/runtime/xt_containers/objects.inc +29 -31
- 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 +18 -5
- package/src/extensions/media/index.ts +4 -3
- package/src/parser/context.ts +99 -4
- package/src/parser/literals.ts +6 -12
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* xbintsc GUI engine — WebGL fixed-function state.
|
|
3
|
+
*
|
|
4
|
+
* SDL_GPU bakes blend/depth/stencil/rasterisation into a pipeline, so these
|
|
5
|
+
* setters only record the values; `webgl_draw.cpp` hashes them into the
|
|
6
|
+
* pipeline cache key and `webgl_pipeline.cpp` builds the matching state.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
#include "webgl.h"
|
|
10
|
+
|
|
11
|
+
#include <algorithm>
|
|
12
|
+
#include <cstring>
|
|
13
|
+
|
|
14
|
+
#include "gui_internal.h"
|
|
15
|
+
|
|
16
|
+
namespace xtgui {
|
|
17
|
+
|
|
18
|
+
/* -- state --------------------------------------------------------------- */
|
|
19
|
+
|
|
20
|
+
void WebGLContext::enable(int cap) {
|
|
21
|
+
if (cap == GL_BLEND) state_.blend = true;
|
|
22
|
+
if (cap == GL_DEPTH_TEST) state_.depth_test = true;
|
|
23
|
+
if (cap == GL_CULL_FACE) state_.cull = true;
|
|
24
|
+
if (cap == GL_SCISSOR_TEST) scissor_test_ = true;
|
|
25
|
+
if (cap == GL_STENCIL_TEST) state_.stencil = true;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
void WebGLContext::disable(int cap) {
|
|
29
|
+
if (cap == GL_BLEND) state_.blend = false;
|
|
30
|
+
if (cap == GL_DEPTH_TEST) state_.depth_test = false;
|
|
31
|
+
if (cap == GL_CULL_FACE) state_.cull = false;
|
|
32
|
+
if (cap == GL_SCISSOR_TEST) scissor_test_ = false;
|
|
33
|
+
if (cap == GL_STENCIL_TEST) state_.stencil = false;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
bool WebGLContext::is_enabled(int cap) const {
|
|
37
|
+
if (cap == GL_BLEND) return state_.blend;
|
|
38
|
+
if (cap == GL_DEPTH_TEST) return state_.depth_test;
|
|
39
|
+
if (cap == GL_CULL_FACE) return state_.cull;
|
|
40
|
+
if (cap == GL_SCISSOR_TEST) return scissor_test_;
|
|
41
|
+
if (cap == GL_STENCIL_TEST) return state_.stencil;
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
void WebGLContext::clear_color(float r, float g, float b, float a) {
|
|
46
|
+
clear_color_[0] = r;
|
|
47
|
+
clear_color_[1] = g;
|
|
48
|
+
clear_color_[2] = b;
|
|
49
|
+
clear_color_[3] = a;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
void WebGLContext::color_mask(bool r, bool g, bool b, bool a) {
|
|
53
|
+
state_.color_mask[0] = r;
|
|
54
|
+
state_.color_mask[1] = g;
|
|
55
|
+
state_.color_mask[2] = b;
|
|
56
|
+
state_.color_mask[3] = a;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
void WebGLContext::blend_func(int src, int dst) {
|
|
60
|
+
state_.blend_src_rgb = src;
|
|
61
|
+
state_.blend_dst_rgb = dst;
|
|
62
|
+
state_.blend_src_alpha = src;
|
|
63
|
+
state_.blend_dst_alpha = dst;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
void WebGLContext::blend_func_separate(int src_rgb, int dst_rgb, int src_alpha, int dst_alpha) {
|
|
67
|
+
state_.blend_src_rgb = src_rgb;
|
|
68
|
+
state_.blend_dst_rgb = dst_rgb;
|
|
69
|
+
state_.blend_src_alpha = src_alpha;
|
|
70
|
+
state_.blend_dst_alpha = dst_alpha;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
void WebGLContext::blend_equation(int mode) {
|
|
74
|
+
state_.blend_eq_rgb = mode;
|
|
75
|
+
state_.blend_eq_alpha = mode;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
void WebGLContext::blend_equation_separate(int rgb, int alpha) {
|
|
79
|
+
state_.blend_eq_rgb = rgb;
|
|
80
|
+
state_.blend_eq_alpha = alpha;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
void WebGLContext::blend_color(float r, float g, float b, float a) {
|
|
84
|
+
blend_color_[0] = r;
|
|
85
|
+
blend_color_[1] = g;
|
|
86
|
+
blend_color_[2] = b;
|
|
87
|
+
blend_color_[3] = a;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
void WebGLContext::blend_color_value(float out[4]) const {
|
|
91
|
+
for (int i = 0; i < 4; i++) out[i] = blend_color_[i];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
void WebGLContext::cull_face(int mode) { state_.cull_face = mode; }
|
|
95
|
+
|
|
96
|
+
void WebGLContext::front_face(int mode) { state_.front_face = mode; }
|
|
97
|
+
|
|
98
|
+
void WebGLContext::stencil_func(int func, int ref, uint32_t mask) {
|
|
99
|
+
stencil_func_separate(GL_FRONT_AND_BACK, func, ref, mask);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
void WebGLContext::stencil_func_separate(int face, int func, int ref, uint32_t mask) {
|
|
103
|
+
if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
|
|
104
|
+
state_.stencil_front.func = func;
|
|
105
|
+
state_.stencil_front.ref = ref;
|
|
106
|
+
state_.stencil_front.value_mask = mask;
|
|
107
|
+
}
|
|
108
|
+
if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
|
|
109
|
+
state_.stencil_back.func = func;
|
|
110
|
+
state_.stencil_back.ref = ref;
|
|
111
|
+
state_.stencil_back.value_mask = mask;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
void WebGLContext::stencil_op(int fail, int zfail, int zpass) {
|
|
116
|
+
stencil_op_separate(GL_FRONT_AND_BACK, fail, zfail, zpass);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
void WebGLContext::stencil_op_separate(int face, int fail, int zfail, int zpass) {
|
|
120
|
+
if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
|
|
121
|
+
state_.stencil_front.fail = fail;
|
|
122
|
+
state_.stencil_front.zfail = zfail;
|
|
123
|
+
state_.stencil_front.zpass = zpass;
|
|
124
|
+
}
|
|
125
|
+
if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
|
|
126
|
+
state_.stencil_back.fail = fail;
|
|
127
|
+
state_.stencil_back.zfail = zfail;
|
|
128
|
+
state_.stencil_back.zpass = zpass;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
void WebGLContext::stencil_mask(uint32_t mask) {
|
|
133
|
+
stencil_mask_separate(GL_FRONT_AND_BACK, mask);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
void WebGLContext::stencil_mask_separate(int face, uint32_t mask) {
|
|
137
|
+
if (face == GL_FRONT || face == GL_FRONT_AND_BACK) state_.stencil_front.write_mask = mask;
|
|
138
|
+
if (face == GL_BACK || face == GL_FRONT_AND_BACK) state_.stencil_back.write_mask = mask;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const WebGLStencilFace &WebGLContext::stencil_face(int face) const {
|
|
142
|
+
return face == GL_FRONT ? state_.stencil_front : state_.stencil_back;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
int WebGLContext::stencil_reference() const {
|
|
146
|
+
/* SDL_GPU has one stencil reference for a draw; the front value is the
|
|
147
|
+
* WebGL default for both faces. */
|
|
148
|
+
return state_.stencil_front.ref;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
void WebGLContext::viewport(int x, int y, int w, int h) {
|
|
152
|
+
viewport_[0] = x;
|
|
153
|
+
viewport_[1] = y;
|
|
154
|
+
viewport_[2] = w;
|
|
155
|
+
viewport_[3] = h;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
void WebGLContext::scissor(int x, int y, int w, int h) {
|
|
159
|
+
scissor_box_[0] = x;
|
|
160
|
+
scissor_box_[1] = y;
|
|
161
|
+
scissor_box_[2] = w;
|
|
162
|
+
scissor_box_[3] = h;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
void WebGLContext::clear(int mask) {
|
|
166
|
+
if (guidev::g_device == nullptr) return;
|
|
167
|
+
const bool color_bit = (mask & GL_COLOR_BUFFER_BIT) != 0;
|
|
168
|
+
const bool depth_bit = (mask & GL_DEPTH_BUFFER_BIT) != 0;
|
|
169
|
+
const bool stencil_bit = (mask & GL_STENCIL_BUFFER_BIT) != 0;
|
|
170
|
+
const bool scissored = scissor_test_ && scissor_box_[2] > 0 && scissor_box_[3] > 0;
|
|
171
|
+
if (!scissored) {
|
|
172
|
+
begin_pass(color_bit, depth_bit, stencil_bit);
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
if (color_bit) {
|
|
176
|
+
SDL_GPUTexture *source = clear_color_texture();
|
|
177
|
+
SDL_GPUTexture *destination = target_color();
|
|
178
|
+
int target_width = 0;
|
|
179
|
+
int target_height = 0;
|
|
180
|
+
framebuffer_size(bound_framebuffer_, &target_width, &target_height);
|
|
181
|
+
if (source != nullptr && destination != nullptr && target_width > 0 && target_height > 0) {
|
|
182
|
+
end_pass();
|
|
183
|
+
ensure_command();
|
|
184
|
+
if (cmd_ != nullptr) {
|
|
185
|
+
int x = std::max(0, scissor_box_[0]);
|
|
186
|
+
int y = std::max(0, scissor_box_[1]);
|
|
187
|
+
int w = scissor_box_[2];
|
|
188
|
+
int h = scissor_box_[3];
|
|
189
|
+
if (x + w > target_width) w = target_width - x;
|
|
190
|
+
if (y + h > target_height) h = target_height - y;
|
|
191
|
+
if (w > 0 && h > 0) {
|
|
192
|
+
SDL_GPUBlitRegion source_region;
|
|
193
|
+
memset(&source_region, 0, sizeof(source_region));
|
|
194
|
+
source_region.texture = source;
|
|
195
|
+
source_region.w = 1;
|
|
196
|
+
source_region.h = 1;
|
|
197
|
+
SDL_GPUBlitRegion destination_region;
|
|
198
|
+
memset(&destination_region, 0, sizeof(destination_region));
|
|
199
|
+
destination_region.texture = destination;
|
|
200
|
+
destination_region.x = (Uint32)x;
|
|
201
|
+
destination_region.y = (Uint32)(target_height - (y + h));
|
|
202
|
+
destination_region.w = (Uint32)w;
|
|
203
|
+
destination_region.h = (Uint32)h;
|
|
204
|
+
SDL_GPUBlitInfo info;
|
|
205
|
+
memset(&info, 0, sizeof(info));
|
|
206
|
+
info.source = source_region;
|
|
207
|
+
info.destination = destination_region;
|
|
208
|
+
/* The pixels outside the scissor rectangle must survive the clear, so
|
|
209
|
+
* the blit has to load the destination. DONT_CARE maps to Metal's
|
|
210
|
+
* MTLLoadActionDontCare, which discards the whole attachment before
|
|
211
|
+
* the blit writes its region and leaves the rest undefined (Vulkan
|
|
212
|
+
* happened to preserve it, which hid this in CI on Linux). */
|
|
213
|
+
info.load_op = SDL_GPU_LOADOP_LOAD;
|
|
214
|
+
info.filter = SDL_GPU_FILTER_NEAREST;
|
|
215
|
+
SDL_BlitGPUTexture(cmd_, &info);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
if (depth_bit || stencil_bit) scissored_clear(mask);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
void WebGLContext::finish() {
|
|
224
|
+
submit();
|
|
225
|
+
if (guidev::g_device != nullptr) SDL_WaitForGPUIdle(guidev::g_device);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
} // namespace xtgui
|
|
@@ -12,16 +12,31 @@
|
|
|
12
12
|
namespace xtgui {
|
|
13
13
|
namespace {
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
bool depth_texture_format(SDL_GPUTextureFormat format) {
|
|
16
|
+
return format == SDL_GPU_TEXTUREFORMAT_D16_UNORM ||
|
|
17
|
+
format == SDL_GPU_TEXTUREFORMAT_D24_UNORM ||
|
|
18
|
+
format == SDL_GPU_TEXTUREFORMAT_D32_FLOAT ||
|
|
19
|
+
format == SDL_GPU_TEXTUREFORMAT_D24_UNORM_S8_UINT ||
|
|
20
|
+
format == SDL_GPU_TEXTUREFORMAT_D32_FLOAT_S8_UINT;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
int texel_bytes(SDL_GPUTextureFormat format) {
|
|
24
|
+
if (format == SDL_GPU_TEXTUREFORMAT_R16G16B16A16_FLOAT) return 8;
|
|
25
|
+
if (format == SDL_GPU_TEXTUREFORMAT_R32G32B32A32_FLOAT) return 16;
|
|
26
|
+
return 4;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Upload a rectangle of tightly packed texels into level 0 of `gpu`. `pixels`
|
|
30
|
+
* may be null, which uploads zeros. */
|
|
17
31
|
bool upload_region(SDL_GPUDevice *device, SDL_GPUCommandBuffer *cmd, SDL_GPUTexture *gpu, int x,
|
|
18
|
-
int y, int width, int height, const uint8_t *
|
|
19
|
-
|
|
32
|
+
int y, int width, int height, const uint8_t *pixels, int bytes_per_texel,
|
|
33
|
+
int layer = 0) {
|
|
34
|
+
const uint32_t bytes = (uint32_t)(width * height * bytes_per_texel);
|
|
20
35
|
if (bytes == 0) return true;
|
|
21
36
|
std::vector<uint8_t> zeros;
|
|
22
|
-
if (
|
|
37
|
+
if (pixels == nullptr) {
|
|
23
38
|
zeros.assign(bytes, 0);
|
|
24
|
-
|
|
39
|
+
pixels = zeros.data();
|
|
25
40
|
}
|
|
26
41
|
SDL_GPUTransferBufferCreateInfo info;
|
|
27
42
|
memset(&info, 0, sizeof(info));
|
|
@@ -34,7 +49,7 @@ bool upload_region(SDL_GPUDevice *device, SDL_GPUCommandBuffer *cmd, SDL_GPUText
|
|
|
34
49
|
SDL_ReleaseGPUTransferBuffer(device, transfer);
|
|
35
50
|
return false;
|
|
36
51
|
}
|
|
37
|
-
memcpy(mapped,
|
|
52
|
+
memcpy(mapped, pixels, bytes);
|
|
38
53
|
SDL_UnmapGPUTransferBuffer(device, transfer);
|
|
39
54
|
SDL_GPUTextureTransferInfo source;
|
|
40
55
|
memset(&source, 0, sizeof(source));
|
|
@@ -46,6 +61,7 @@ bool upload_region(SDL_GPUDevice *device, SDL_GPUCommandBuffer *cmd, SDL_GPUText
|
|
|
46
61
|
region.texture = gpu;
|
|
47
62
|
region.x = (Uint32)x;
|
|
48
63
|
region.y = (Uint32)y;
|
|
64
|
+
region.layer = (Uint32)layer;
|
|
49
65
|
region.w = (Uint32)width;
|
|
50
66
|
region.h = (Uint32)height;
|
|
51
67
|
region.d = 1;
|
|
@@ -58,7 +74,44 @@ bool upload_region(SDL_GPUDevice *device, SDL_GPUCommandBuffer *cmd, SDL_GPUText
|
|
|
58
74
|
|
|
59
75
|
} // namespace
|
|
60
76
|
|
|
61
|
-
|
|
77
|
+
SDL_GPUTexture *WebGLContext::clear_color_texture() {
|
|
78
|
+
if (guidev::g_device == nullptr) return nullptr;
|
|
79
|
+
if (clear_texture_ == nullptr) {
|
|
80
|
+
end_pass();
|
|
81
|
+
ensure_command();
|
|
82
|
+
SDL_GPUTextureCreateInfo info;
|
|
83
|
+
memset(&info, 0, sizeof(info));
|
|
84
|
+
info.type = SDL_GPU_TEXTURETYPE_2D;
|
|
85
|
+
info.format = SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM;
|
|
86
|
+
info.usage = SDL_GPU_TEXTUREUSAGE_SAMPLER | SDL_GPU_TEXTUREUSAGE_COLOR_TARGET;
|
|
87
|
+
info.width = 1;
|
|
88
|
+
info.height = 1;
|
|
89
|
+
info.layer_count_or_depth = 1;
|
|
90
|
+
info.num_levels = 1;
|
|
91
|
+
info.sample_count = SDL_GPU_SAMPLECOUNT_1;
|
|
92
|
+
clear_texture_ = SDL_CreateGPUTexture(guidev::g_device, &info);
|
|
93
|
+
if (clear_texture_ == nullptr) {
|
|
94
|
+
set_error(GL_OUT_OF_MEMORY);
|
|
95
|
+
return nullptr;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
end_pass();
|
|
99
|
+
ensure_command();
|
|
100
|
+
if (cmd_ == nullptr) return clear_texture_;
|
|
101
|
+
uint8_t rgba[4];
|
|
102
|
+
for (int i = 0; i < 4; i++) {
|
|
103
|
+
float value = clear_color_[i];
|
|
104
|
+
if (value < 0.0f) value = 0.0f;
|
|
105
|
+
if (value > 1.0f) value = 1.0f;
|
|
106
|
+
rgba[i] = (uint8_t)(value * 255.0f + 0.5f);
|
|
107
|
+
}
|
|
108
|
+
upload_region(guidev::g_device, cmd_, clear_texture_, 0, 0, 1, 1, rgba, 4);
|
|
109
|
+
return clear_texture_;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
bool WebGLContext::tex_image_format(uint32_t id, int width, int height,
|
|
113
|
+
SDL_GPUTextureFormat format, const uint8_t *pixels,
|
|
114
|
+
int layer) {
|
|
62
115
|
WebGLTexture *record = texture(id);
|
|
63
116
|
if (record == nullptr || width <= 0 || height <= 0) {
|
|
64
117
|
set_error(GL_INVALID_VALUE);
|
|
@@ -67,27 +120,43 @@ bool WebGLContext::tex_image_rgba(uint32_t id, int width, int height, const uint
|
|
|
67
120
|
end_pass();
|
|
68
121
|
ensure_command();
|
|
69
122
|
if (cmd_ == nullptr) return false;
|
|
70
|
-
if (record->width != width || record->height != height) {
|
|
123
|
+
if (record->width != width || record->height != height || record->format != format) {
|
|
71
124
|
if (record->gpu != nullptr) {
|
|
72
125
|
SDL_WaitForGPUIdle(guidev::g_device);
|
|
73
126
|
SDL_ReleaseGPUTexture(guidev::g_device, record->gpu);
|
|
74
127
|
record->gpu = nullptr;
|
|
128
|
+
record->usage = 0;
|
|
75
129
|
}
|
|
76
130
|
record->width = width;
|
|
77
131
|
record->height = height;
|
|
132
|
+
record->format = format;
|
|
133
|
+
record->layers = 1;
|
|
134
|
+
record->target = layer >= 0 ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
|
|
135
|
+
record->compressed = false;
|
|
78
136
|
record->has_mipmaps = false;
|
|
79
137
|
if (record->sampler != nullptr) {
|
|
80
138
|
SDL_ReleaseGPUSampler(guidev::g_device, record->sampler);
|
|
81
139
|
record->sampler = nullptr;
|
|
82
140
|
}
|
|
83
141
|
}
|
|
84
|
-
if (ensure_texture_gpu(record, record->as_target) == nullptr)
|
|
142
|
+
if (ensure_texture_gpu(record, record->as_target || record->as_depth_target) == nullptr) {
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
85
145
|
record->defined = true;
|
|
86
|
-
|
|
146
|
+
if (layer >= 0) {
|
|
147
|
+
record->target = GL_TEXTURE_CUBE_MAP;
|
|
148
|
+
record->layers = 6;
|
|
149
|
+
}
|
|
150
|
+
return upload_region(guidev::g_device, cmd_, record->gpu, 0, 0, width, height, pixels,
|
|
151
|
+
texel_bytes(format), layer >= 0 ? layer : 0);
|
|
87
152
|
}
|
|
88
153
|
|
|
89
|
-
bool WebGLContext::
|
|
90
|
-
|
|
154
|
+
bool WebGLContext::tex_image_rgba(uint32_t id, int width, int height, const uint8_t *rgba) {
|
|
155
|
+
return tex_image_format(id, width, height, SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM, rgba);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
bool WebGLContext::tex_sub_image_format(uint32_t id, int x, int y, int width, int height,
|
|
159
|
+
const uint8_t *pixels, int layer) {
|
|
91
160
|
WebGLTexture *record = texture(id);
|
|
92
161
|
if (record == nullptr || !record->defined || record->gpu == nullptr) {
|
|
93
162
|
set_error(GL_INVALID_OPERATION);
|
|
@@ -101,7 +170,13 @@ bool WebGLContext::tex_sub_image_rgba(uint32_t id, int x, int y, int width, int
|
|
|
101
170
|
end_pass();
|
|
102
171
|
ensure_command();
|
|
103
172
|
if (cmd_ == nullptr) return false;
|
|
104
|
-
return upload_region(guidev::g_device, cmd_, record->gpu, x, y, width, height,
|
|
173
|
+
return upload_region(guidev::g_device, cmd_, record->gpu, x, y, width, height, pixels,
|
|
174
|
+
texel_bytes(record->format), layer);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
bool WebGLContext::tex_sub_image_rgba(uint32_t id, int x, int y, int width, int height,
|
|
178
|
+
const uint8_t *rgba) {
|
|
179
|
+
return tex_sub_image_format(id, x, y, width, height, rgba);
|
|
105
180
|
}
|
|
106
181
|
|
|
107
182
|
bool WebGLContext::generate_mipmap(uint32_t id) {
|
|
@@ -110,6 +185,11 @@ bool WebGLContext::generate_mipmap(uint32_t id) {
|
|
|
110
185
|
set_error(GL_INVALID_OPERATION);
|
|
111
186
|
return false;
|
|
112
187
|
}
|
|
188
|
+
if (record->depth) {
|
|
189
|
+
/* Depth textures have no mip chain in this backend. */
|
|
190
|
+
set_error(GL_INVALID_OPERATION);
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
113
193
|
end_pass();
|
|
114
194
|
ensure_command();
|
|
115
195
|
if (cmd_ == nullptr || record->levels <= 1) return false;
|
|
@@ -124,7 +204,25 @@ bool WebGLContext::generate_mipmap(uint32_t id) {
|
|
|
124
204
|
|
|
125
205
|
bool WebGLContext::read_pixels(int x, int y, int width, int height, uint8_t *out) {
|
|
126
206
|
if (out == nullptr || width <= 0 || height <= 0) return false;
|
|
207
|
+
if (target_color_format() != (int)SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM) {
|
|
208
|
+
/* The only readback this surface offers is RGBA8; a float/half colour
|
|
209
|
+
* target is read by rendering it into an RGBA8 target instead. */
|
|
210
|
+
set_error(GL_INVALID_OPERATION);
|
|
211
|
+
return false;
|
|
212
|
+
}
|
|
127
213
|
SDL_GPUTexture *target = target_color();
|
|
214
|
+
if (bound_framebuffer_ != 0) {
|
|
215
|
+
WebGLFramebuffer *framebuffer = this->framebuffer(bound_framebuffer_);
|
|
216
|
+
if (framebuffer != nullptr) {
|
|
217
|
+
int index = read_buffer_ - GL_COLOR_ATTACHMENT0;
|
|
218
|
+
if (index < 0 || index >= kWebGLMaxDrawBuffers ||
|
|
219
|
+
framebuffer->color_textures[index] == 0) {
|
|
220
|
+
index = 0;
|
|
221
|
+
}
|
|
222
|
+
WebGLTexture *read_texture = texture(framebuffer->color_textures[index]);
|
|
223
|
+
target = read_texture != nullptr ? ensure_texture_gpu(read_texture, true) : nullptr;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
128
226
|
int target_width = bound_framebuffer_ == 0 ? width_ : 0;
|
|
129
227
|
int target_height = bound_framebuffer_ == 0 ? height_ : 0;
|
|
130
228
|
if (bound_framebuffer_ != 0) {
|
|
@@ -196,7 +294,8 @@ bool WebGLContext::read_pixels(int x, int y, int width, int height, uint8_t *out
|
|
|
196
294
|
return true;
|
|
197
295
|
}
|
|
198
296
|
|
|
199
|
-
bool WebGLContext::
|
|
297
|
+
bool WebGLContext::tex_storage_format(uint32_t id, int levels, int width, int height,
|
|
298
|
+
SDL_GPUTextureFormat format) {
|
|
200
299
|
(void)levels; // the backend always allocates the full mip chain
|
|
201
300
|
WebGLTexture *record = texture(id);
|
|
202
301
|
if (record == nullptr || width <= 0 || height <= 0) {
|
|
@@ -210,20 +309,29 @@ bool WebGLContext::tex_storage_2d(uint32_t id, int levels, int width, int height
|
|
|
210
309
|
SDL_WaitForGPUIdle(guidev::g_device);
|
|
211
310
|
SDL_ReleaseGPUTexture(guidev::g_device, record->gpu);
|
|
212
311
|
record->gpu = nullptr;
|
|
312
|
+
record->usage = 0;
|
|
213
313
|
}
|
|
214
314
|
record->width = width;
|
|
215
315
|
record->height = height;
|
|
316
|
+
record->format = format;
|
|
317
|
+
record->layers = 1;
|
|
318
|
+
record->target = GL_TEXTURE_2D;
|
|
319
|
+
record->compressed = false;
|
|
216
320
|
record->has_mipmaps = false;
|
|
217
321
|
if (record->sampler != nullptr && guidev::g_device != nullptr) {
|
|
218
322
|
SDL_ReleaseGPUSampler(guidev::g_device, record->sampler);
|
|
219
323
|
record->sampler = nullptr;
|
|
220
324
|
}
|
|
221
325
|
record->defined = true;
|
|
222
|
-
return ensure_texture_gpu(record, record->as_target) != nullptr;
|
|
326
|
+
return ensure_texture_gpu(record, record->as_target || record->as_depth_target) != nullptr;
|
|
223
327
|
}
|
|
224
328
|
|
|
225
|
-
|
|
329
|
+
bool WebGLContext::tex_storage_2d(uint32_t id, int levels, int width, int height) {
|
|
330
|
+
return tex_storage_format(id, levels, width, height,
|
|
331
|
+
SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM);
|
|
332
|
+
}
|
|
226
333
|
|
|
334
|
+
/* -- WebGL 2 clearBuffer* ------------------------------------------------ */
|
|
227
335
|
void WebGLContext::clear_buffer_float(int buffer, int drawbuffer, const float *values,
|
|
228
336
|
int count) {
|
|
229
337
|
if (buffer == GL_COLOR) {
|
|
@@ -290,4 +398,23 @@ void WebGLContext::clear_buffer_fi(int buffer, int drawbuffer, float depth, int
|
|
|
290
398
|
}
|
|
291
399
|
}
|
|
292
400
|
|
|
401
|
+
SDL_GPUTextureFormat webgl_storage_format(int internalformat) {
|
|
402
|
+
if (internalformat == GL_DEPTH_COMPONENT16 || internalformat == GL_DEPTH_COMPONENT24 ||
|
|
403
|
+
internalformat == GL_DEPTH_COMPONENT32F) {
|
|
404
|
+
return SDL_GPU_TEXTUREFORMAT_D32_FLOAT;
|
|
405
|
+
}
|
|
406
|
+
if (internalformat == GL_DEPTH_STENCIL || internalformat == GL_DEPTH24_STENCIL8) {
|
|
407
|
+
return SDL_GPU_TEXTUREFORMAT_D32_FLOAT_S8_UINT;
|
|
408
|
+
}
|
|
409
|
+
if (internalformat == GL_RGBA32F || internalformat == GL_RGB32F ||
|
|
410
|
+
internalformat == GL_RG32F || internalformat == GL_R32F) {
|
|
411
|
+
return SDL_GPU_TEXTUREFORMAT_R32G32B32A32_FLOAT;
|
|
412
|
+
}
|
|
413
|
+
if (internalformat == GL_RGBA16F || internalformat == GL_RGB16F ||
|
|
414
|
+
internalformat == GL_RG16F || internalformat == GL_R16F) {
|
|
415
|
+
return SDL_GPU_TEXTUREFORMAT_R16G16B16A16_FLOAT;
|
|
416
|
+
}
|
|
417
|
+
return SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM;
|
|
418
|
+
}
|
|
419
|
+
|
|
293
420
|
} // namespace xtgui
|