xbintsc 0.5.31 → 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.
Files changed (286) hide show
  1. package/README.md +25 -16
  2. package/README.zh-CN.md +10 -8
  3. package/dist/scripts/check-version.d.ts +27 -0
  4. package/dist/scripts/check-version.js +71 -0
  5. package/dist/scripts/check-version.js.map +1 -0
  6. package/dist/scripts/package-platform.d.ts +58 -0
  7. package/dist/scripts/package-platform.js +142 -0
  8. package/dist/scripts/package-platform.js.map +1 -0
  9. package/dist/scripts/verify-platform-package.d.ts +34 -0
  10. package/dist/scripts/verify-platform-package.js +161 -0
  11. package/dist/scripts/verify-platform-package.js.map +1 -0
  12. package/dist/src/binder/references.js +14 -1
  13. package/dist/src/binder/references.js.map +1 -1
  14. package/dist/src/cli/help.d.ts +1 -1
  15. package/dist/src/cli/main.js +3 -1
  16. package/dist/src/cli/main.js.map +1 -1
  17. package/dist/src/codegen/generator/module.d.ts +1 -0
  18. package/dist/src/codegen/generator/module.js +54 -0
  19. package/dist/src/codegen/generator/module.js.map +1 -1
  20. package/dist/src/codegen/generator/statements/variables.js +6 -4
  21. package/dist/src/codegen/generator/statements/variables.js.map +1 -1
  22. package/dist/src/driver/runtime-lib.d.ts +29 -4
  23. package/dist/src/driver/runtime-lib.js +68 -10
  24. package/dist/src/driver/runtime-lib.js.map +1 -1
  25. package/dist/src/driver/version.d.ts +1 -1
  26. package/dist/src/driver/version.js +1 -1
  27. package/dist/src/extensions/gui/css.d.ts +26 -0
  28. package/dist/src/extensions/gui/css.js +100 -0
  29. package/dist/src/extensions/gui/css.js.map +1 -0
  30. package/dist/src/extensions/gui/html.js +9 -2
  31. package/dist/src/extensions/gui/html.js.map +1 -1
  32. package/dist/src/extensions/gui/index.js +22 -7
  33. package/dist/src/extensions/gui/index.js.map +1 -1
  34. package/dist/src/extensions/gui/three.d.ts +16 -0
  35. package/dist/src/extensions/gui/three.js +22 -0
  36. package/dist/src/extensions/gui/three.js.map +1 -0
  37. package/dist/src/extensions/media/index.d.ts +6 -5
  38. package/dist/src/extensions/media/index.js +15 -16
  39. package/dist/src/extensions/media/index.js.map +1 -1
  40. package/dist/src/parser/context.d.ts +41 -0
  41. package/dist/src/parser/context.js +89 -4
  42. package/dist/src/parser/context.js.map +1 -1
  43. package/dist/src/parser/literals.js +6 -12
  44. package/dist/src/parser/literals.js.map +1 -1
  45. package/dist/tests/driver/platform-package.test.d.ts +1 -0
  46. package/dist/tests/driver/platform-package.test.js +49 -0
  47. package/dist/tests/driver/platform-package.test.js.map +1 -0
  48. package/dist/tests/driver/runtime-lib.test.js +51 -4
  49. package/dist/tests/driver/runtime-lib.test.js.map +1 -1
  50. package/dist/tests/e2e/compile-builtins.test.js +24 -0
  51. package/dist/tests/e2e/compile-builtins.test.js.map +1 -1
  52. package/dist/tests/e2e/compile-objects-classes.test.js +23 -0
  53. package/dist/tests/e2e/compile-objects-classes.test.js.map +1 -1
  54. package/dist/tests/e2e/gui-audio.test.d.ts +14 -0
  55. package/dist/tests/e2e/gui-audio.test.js +287 -0
  56. package/dist/tests/e2e/gui-audio.test.js.map +1 -0
  57. package/dist/tests/e2e/gui-browser.test.js +1 -1
  58. package/dist/tests/e2e/gui-browser.test.js.map +1 -1
  59. package/dist/tests/e2e/gui-effects.test.d.ts +6 -0
  60. package/dist/tests/e2e/gui-effects.test.js +262 -0
  61. package/dist/tests/e2e/gui-effects.test.js.map +1 -0
  62. package/dist/tests/e2e/gui-example-webgl.test.d.ts +10 -0
  63. package/dist/tests/e2e/gui-example-webgl.test.js +75 -0
  64. package/dist/tests/e2e/gui-example-webgl.test.js.map +1 -0
  65. package/dist/tests/e2e/gui-example-webgl2.test.d.ts +8 -0
  66. package/dist/tests/e2e/gui-example-webgl2.test.js +72 -0
  67. package/dist/tests/e2e/gui-example-webgl2.test.js.map +1 -0
  68. package/dist/tests/e2e/gui-helpers.d.ts +7 -0
  69. package/dist/tests/e2e/gui-helpers.js +1 -0
  70. package/dist/tests/e2e/gui-helpers.js.map +1 -1
  71. package/dist/tests/e2e/gui-layout.test.js +48 -0
  72. package/dist/tests/e2e/gui-layout.test.js.map +1 -1
  73. package/dist/tests/e2e/gui-media.test.js +83 -4
  74. package/dist/tests/e2e/gui-media.test.js.map +1 -1
  75. package/dist/tests/e2e/gui-style.test.js +55 -0
  76. package/dist/tests/e2e/gui-style.test.js.map +1 -1
  77. package/dist/tests/e2e/gui-webgl.test.d.ts +11 -0
  78. package/dist/tests/e2e/gui-webgl.test.js +437 -0
  79. package/dist/tests/e2e/gui-webgl.test.js.map +1 -0
  80. package/dist/tests/e2e/gui-webgl2-3d.test.d.ts +4 -0
  81. package/dist/tests/e2e/gui-webgl2-3d.test.js +264 -0
  82. package/dist/tests/e2e/gui-webgl2-3d.test.js.map +1 -0
  83. package/dist/tests/e2e/gui-webgl2-blit.test.d.ts +10 -0
  84. package/dist/tests/e2e/gui-webgl2-blit.test.js +262 -0
  85. package/dist/tests/e2e/gui-webgl2-blit.test.js.map +1 -0
  86. package/dist/tests/e2e/gui-webgl2-formats.test.d.ts +6 -0
  87. package/dist/tests/e2e/gui-webgl2-formats.test.js +395 -0
  88. package/dist/tests/e2e/gui-webgl2-formats.test.js.map +1 -0
  89. package/dist/tests/e2e/gui-webgl2-mrt.test.d.ts +4 -0
  90. package/dist/tests/e2e/gui-webgl2-mrt.test.js +105 -0
  91. package/dist/tests/e2e/gui-webgl2-mrt.test.js.map +1 -0
  92. package/dist/tests/e2e/gui-webgl2-ubo.test.d.ts +8 -0
  93. package/dist/tests/e2e/gui-webgl2-ubo.test.js +112 -0
  94. package/dist/tests/e2e/gui-webgl2-ubo.test.js.map +1 -0
  95. package/dist/tests/e2e/gui-webgl2.test.d.ts +10 -0
  96. package/dist/tests/e2e/gui-webgl2.test.js +282 -0
  97. package/dist/tests/e2e/gui-webgl2.test.js.map +1 -0
  98. package/dist/tests/extensions/gui-index.test.js +1 -0
  99. package/dist/tests/extensions/gui-index.test.js.map +1 -1
  100. package/dist/tests/extensions/gui.test.js +41 -0
  101. package/dist/tests/extensions/gui.test.js.map +1 -1
  102. package/dist/tests/extensions/media.test.js +8 -3
  103. package/dist/tests/extensions/media.test.js.map +1 -1
  104. package/dist/tests/parser/expressions.test.js +30 -0
  105. package/dist/tests/parser/expressions.test.js.map +1 -1
  106. package/dist/tests/platform-tarball.test.d.ts +1 -0
  107. package/dist/tests/platform-tarball.test.js +111 -0
  108. package/dist/tests/platform-tarball.test.js.map +1 -0
  109. package/dist/tests/version.test.js +6 -0
  110. package/dist/tests/version.test.js.map +1 -1
  111. package/doc/ai/contributing.md +11 -0
  112. package/doc/ai/extensions.md +35 -12
  113. package/doc/ai/troubleshooting.md +17 -11
  114. package/doc/ai/zh-CN/contributing.md +9 -0
  115. package/doc/ai/zh-CN/extensions.md +30 -10
  116. package/doc/ai/zh-CN/troubleshooting.md +14 -8
  117. package/doc/gui/api.md +63 -14
  118. package/doc/gui/build.md +79 -16
  119. package/doc/gui/canvas.md +11 -3
  120. package/doc/gui/dom.md +35 -17
  121. package/doc/gui/known-issues.md +57 -24
  122. package/doc/gui/layout.md +18 -0
  123. package/doc/gui/media.md +21 -13
  124. package/doc/gui/rendering.md +50 -3
  125. package/doc/gui/webgl.md +315 -0
  126. package/doc/gui.md +113 -18
  127. package/doc/npm-package.md +59 -29
  128. package/doc/requirements.md +24 -11
  129. package/doc/zh-CN/gui/api.md +53 -11
  130. package/doc/zh-CN/gui/build.md +70 -16
  131. package/doc/zh-CN/gui/canvas.md +9 -2
  132. package/doc/zh-CN/gui/dom.md +22 -7
  133. package/doc/zh-CN/gui/known-issues.md +45 -19
  134. package/doc/zh-CN/gui/layout.md +14 -0
  135. package/doc/zh-CN/gui/media.md +18 -11
  136. package/doc/zh-CN/gui/rendering.md +41 -4
  137. package/doc/zh-CN/gui/webgl.md +121 -0
  138. package/doc/zh-CN/gui.md +91 -15
  139. package/doc/zh-CN/npm-package.md +48 -24
  140. package/doc/zh-CN/requirements.md +16 -7
  141. package/llms.txt +2 -0
  142. package/package.json +17 -1
  143. package/runtime/ext_gui/audio.cpp +365 -153
  144. package/runtime/ext_gui/audio_buffer.cpp +166 -0
  145. package/runtime/ext_gui/audio_buffer.h +37 -0
  146. package/runtime/ext_gui/audio_decode.cpp +219 -0
  147. package/runtime/ext_gui/audio_decode.h +39 -0
  148. package/runtime/ext_gui/audio_device.cpp +87 -0
  149. package/runtime/ext_gui/audio_effects.cpp +163 -0
  150. package/runtime/ext_gui/audio_effects.h +25 -0
  151. package/runtime/ext_gui/audio_internal.h +30 -0
  152. package/runtime/ext_gui/audio_mixer.cpp +494 -0
  153. package/runtime/ext_gui/audio_mixer.h +238 -0
  154. package/runtime/ext_gui/audio_param.cpp +104 -0
  155. package/runtime/ext_gui/audio_param_object.cpp +155 -0
  156. package/runtime/ext_gui/browser.cpp +50 -14
  157. package/runtime/ext_gui/canvas.cpp +3 -18
  158. package/runtime/ext_gui/canvas_internal.h +10 -0
  159. package/runtime/ext_gui/canvas_raster.cpp +60 -0
  160. package/runtime/ext_gui/clip_values.cpp +246 -0
  161. package/runtime/ext_gui/css.cpp +94 -0
  162. package/runtime/ext_gui/css.h +22 -1
  163. package/runtime/ext_gui/css_match.cpp +3 -0
  164. package/runtime/ext_gui/css_selector.cpp +30 -3
  165. package/runtime/ext_gui/css_sheet.cpp +89 -45
  166. package/runtime/ext_gui/document.cpp +4 -1
  167. package/runtime/ext_gui/document.h +2 -0
  168. package/runtime/ext_gui/dom.h +16 -0
  169. package/runtime/ext_gui/dom_api.cpp +1 -0
  170. package/runtime/ext_gui/dom_api_canvas.cpp +17 -80
  171. package/runtime/ext_gui/dom_api_canvas_extra.cpp +130 -1
  172. package/runtime/ext_gui/dom_api_canvas_pending.cpp +41 -0
  173. package/runtime/ext_gui/dom_api_internal.h +275 -0
  174. package/runtime/ext_gui/dom_api_webgl.cpp +383 -0
  175. package/runtime/ext_gui/dom_api_webgl2.cpp +549 -0
  176. package/runtime/ext_gui/dom_api_webgl2_draw.cpp +269 -0
  177. package/runtime/ext_gui/dom_api_webgl_buffer.cpp +216 -0
  178. package/runtime/ext_gui/dom_api_webgl_compressed.cpp +167 -0
  179. package/runtime/ext_gui/dom_api_webgl_framebuffer.cpp +160 -0
  180. package/runtime/ext_gui/dom_api_webgl_rt.h +30 -0
  181. package/runtime/ext_gui/dom_api_webgl_shader.cpp +443 -0
  182. package/runtime/ext_gui/dom_api_webgl_source.cpp +161 -0
  183. package/runtime/ext_gui/dom_api_webgl_state.cpp +590 -0
  184. package/runtime/ext_gui/dom_api_webgl_texture.cpp +485 -0
  185. package/runtime/ext_gui/dom_api_webgl_ubo.cpp +81 -0
  186. package/runtime/ext_gui/effect_values.cpp +312 -0
  187. package/runtime/ext_gui/gradient_values.cpp +476 -0
  188. package/runtime/ext_gui/grid_values.cpp +230 -0
  189. package/runtime/ext_gui/gui.cpp +44 -9
  190. package/runtime/ext_gui/gui_canvas.cpp +50 -2
  191. package/runtime/ext_gui/gui_engine.h +36 -4
  192. package/runtime/ext_gui/gui_events.cpp +4 -1
  193. package/runtime/ext_gui/gui_media.cpp +1 -1
  194. package/runtime/ext_gui/gui_webgl.cpp +83 -0
  195. package/runtime/ext_gui/image_bitmap.cpp +28 -0
  196. package/runtime/ext_gui/image_bitmap.h +26 -0
  197. package/runtime/ext_gui/image_bitmap_browser.cpp +136 -0
  198. package/runtime/ext_gui/layout.cpp +21 -0
  199. package/runtime/ext_gui/layout_flow.cpp +81 -4
  200. package/runtime/ext_gui/layout_flow_internal.h +31 -0
  201. package/runtime/ext_gui/layout_grid.cpp +374 -0
  202. package/runtime/ext_gui/media.cpp +32 -0
  203. package/runtime/ext_gui/media.h +14 -1
  204. package/runtime/ext_gui/media_api.h +25 -2
  205. package/runtime/ext_gui/media_query.cpp +211 -0
  206. package/runtime/ext_gui/paint.cpp +111 -77
  207. package/runtime/ext_gui/paint.h +33 -3
  208. package/runtime/ext_gui/paint_background.cpp +229 -0
  209. package/runtime/ext_gui/paint_clip.cpp +268 -0
  210. package/runtime/ext_gui/paint_effects.cpp +324 -0
  211. package/runtime/ext_gui/paint_internal.h +85 -0
  212. package/runtime/ext_gui/renderer.cpp +8 -31
  213. package/runtime/ext_gui/renderer_clip.cpp +196 -0
  214. package/runtime/ext_gui/renderer_image.cpp +13 -8
  215. package/runtime/ext_gui/renderer_internal.h +15 -8
  216. package/runtime/ext_gui/renderer_text.cpp +6 -31
  217. package/runtime/ext_gui/style.cpp +343 -20
  218. package/runtime/ext_gui/style.h +144 -3
  219. package/runtime/ext_gui/style_print.cpp +134 -1
  220. package/runtime/ext_gui/style_values.cpp +152 -126
  221. package/runtime/ext_gui/style_values_internal.h +35 -0
  222. package/runtime/ext_gui/webgl.h +600 -0
  223. package/runtime/ext_gui/webgl2_constants.h +274 -0
  224. package/runtime/ext_gui/webgl_blit.cpp +95 -0
  225. package/runtime/ext_gui/webgl_buffer.cpp +480 -0
  226. package/runtime/ext_gui/webgl_buffer_objects.cpp +270 -0
  227. package/runtime/ext_gui/webgl_clear.cpp +142 -0
  228. package/runtime/ext_gui/webgl_compressed.cpp +180 -0
  229. package/runtime/ext_gui/webgl_constants.h +317 -0
  230. package/runtime/ext_gui/webgl_context.cpp +551 -0
  231. package/runtime/ext_gui/webgl_draw.cpp +560 -0
  232. package/runtime/ext_gui/webgl_draw_buffers.cpp +75 -0
  233. package/runtime/ext_gui/webgl_glsl.h +165 -0
  234. package/runtime/ext_gui/webgl_glsl_compile.cpp +437 -0
  235. package/runtime/ext_gui/webgl_glsl_rewrite.cpp +367 -0
  236. package/runtime/ext_gui/webgl_glsl_scan.cpp +590 -0
  237. package/runtime/ext_gui/webgl_glsl_scan_block.cpp +126 -0
  238. package/runtime/ext_gui/webgl_glsl_tokens.h +28 -0
  239. package/runtime/ext_gui/webgl_msl.cpp +62 -0
  240. package/runtime/ext_gui/webgl_msl.h +33 -0
  241. package/runtime/ext_gui/webgl_pipeline.cpp +326 -0
  242. package/runtime/ext_gui/webgl_program_blocks.cpp +58 -0
  243. package/runtime/ext_gui/webgl_program_internal.h +24 -0
  244. package/runtime/ext_gui/webgl_shader.cpp +594 -0
  245. package/runtime/ext_gui/webgl_state.cpp +228 -0
  246. package/runtime/ext_gui/webgl_texture.cpp +420 -0
  247. package/runtime/ext_gui/webgl_texture_3d.cpp +215 -0
  248. package/runtime/ext_gui/webgl_uniform.cpp +167 -0
  249. package/runtime/ext_gui/webgl_uniform_block.h +31 -0
  250. package/runtime/ext_gui/webgl_webgl2.cpp +277 -0
  251. package/runtime/ext_media/decode_audio.cpp +308 -0
  252. package/runtime/ext_media/media.cpp +1 -1
  253. package/runtime/ext_media/media_bridge.c +11 -3
  254. package/runtime/rt.h +17 -0
  255. package/runtime/rt_internal.h +1 -0
  256. package/runtime/xt_array_buffer.c +30 -0
  257. package/runtime/xt_containers/access.inc +8 -0
  258. package/runtime/xt_regex/api.inc +2 -0
  259. package/runtime/xt_regex/matcher.inc +16 -3
  260. package/runtime/xt_regex/parser.inc +8 -2
  261. package/runtime/xt_regex/types.inc +3 -0
  262. package/runtime/xt_stdlib2/regexp-match.inc +60 -21
  263. package/runtime/xt_stdlib2/regexp.inc +1 -0
  264. package/runtime/xt_typed_array/elements.inc +13 -0
  265. package/runtime/xt_typed_array.c +1 -1
  266. package/scripts/build-gui.ts +90 -3
  267. package/scripts/build-media.ts +335 -62
  268. package/scripts/build-runtime.ts +21 -16
  269. package/scripts/check-version.ts +39 -9
  270. package/scripts/package-platform.ts +183 -0
  271. package/scripts/set-platform-version.ts +62 -0
  272. package/scripts/setup-vs-toolchain.ps1 +152 -0
  273. package/scripts/verify-platform-package.ts +182 -0
  274. package/src/binder/references.ts +13 -1
  275. package/src/cli/main.ts +5 -1
  276. package/src/codegen/generator/module.ts +50 -0
  277. package/src/codegen/generator/statements/variables.ts +6 -3
  278. package/src/driver/runtime-lib.ts +73 -9
  279. package/src/driver/version.ts +1 -1
  280. package/src/extensions/gui/css.ts +113 -0
  281. package/src/extensions/gui/html.ts +9 -2
  282. package/src/extensions/gui/index.ts +22 -7
  283. package/src/extensions/gui/three.ts +25 -0
  284. package/src/extensions/media/index.ts +16 -18
  285. package/src/parser/context.ts +99 -4
  286. package/src/parser/literals.ts +6 -12
@@ -0,0 +1,551 @@
1
+ /*
2
+ * xbintsc GUI engine — WebGL context lifetime and GPU targets.
3
+ *
4
+ * Every context records into one SDL_GPU command buffer. A render pass stays
5
+ * open across draws and is ended whenever a copy pass (buffer/texture upload)
6
+ * or a different attachment has to be recorded; the next draw starts a new
7
+ * pass with `LOAD`, so the framebuffer persists like a WebGL drawing buffer.
8
+ * Fixed-function state lives in `webgl_state.cpp`.
9
+ */
10
+
11
+ #include "webgl.h"
12
+
13
+ #include <algorithm>
14
+ #include <cmath>
15
+ #include <cstring>
16
+
17
+ #include "gui_internal.h"
18
+
19
+ namespace xtgui {
20
+ namespace {
21
+
22
+ std::unordered_map<uint64_t, WebGLContext *> g_contexts;
23
+
24
+ } // namespace
25
+
26
+ WebGLContext *xt_webgl_by_id(uint64_t id) {
27
+ auto found = g_contexts.find(id);
28
+ return found == g_contexts.end() ? nullptr : found->second;
29
+ }
30
+
31
+ WebGLContext::WebGLContext(uint64_t id, int width, int height, bool webgl2)
32
+ : id_(id), webgl2_(webgl2) {
33
+ width_ = width > 0 ? width : 1;
34
+ height_ = height > 0 ? height : 1;
35
+ viewport_[0] = 0;
36
+ viewport_[1] = 0;
37
+ viewport_[2] = width_;
38
+ viewport_[3] = height_;
39
+ scissor_box_[0] = 0;
40
+ scissor_box_[1] = 0;
41
+ scissor_box_[2] = width_;
42
+ scissor_box_[3] = height_;
43
+ g_contexts[id] = this;
44
+ if (guidev::g_device == nullptr) lost_ = true;
45
+ }
46
+
47
+ WebGLContext::~WebGLContext() {
48
+ submit();
49
+ if (guidev::g_device != nullptr) release_gpu_resources();
50
+ g_contexts.erase(id_);
51
+ }
52
+
53
+ void WebGLContext::release_gpu_resources() {
54
+ if (guidev::g_device == nullptr) return;
55
+ SDL_WaitForGPUIdle(guidev::g_device);
56
+ for (auto &entry : programs_) release_program_pipelines(entry.second.get());
57
+ for (auto &entry : textures_) {
58
+ if (entry.second->gpu != nullptr) SDL_ReleaseGPUTexture(guidev::g_device, entry.second->gpu);
59
+ if (entry.second->sampler != nullptr) {
60
+ SDL_ReleaseGPUSampler(guidev::g_device, entry.second->sampler);
61
+ }
62
+ entry.second->gpu = nullptr;
63
+ entry.second->sampler = nullptr;
64
+ }
65
+ for (auto &entry : buffers_) {
66
+ if (entry.second->gpu != nullptr) SDL_ReleaseGPUBuffer(guidev::g_device, entry.second->gpu);
67
+ entry.second->gpu = nullptr;
68
+ entry.second->capacity = 0;
69
+ }
70
+ for (auto &entry : samplers_) {
71
+ if (entry.second->gpu != nullptr) {
72
+ SDL_ReleaseGPUSampler(guidev::g_device, entry.second->gpu);
73
+ entry.second->gpu = nullptr;
74
+ }
75
+ }
76
+ for (auto &entry : framebuffers_) {
77
+ if (entry.second->depth != nullptr) {
78
+ SDL_ReleaseGPUTexture(guidev::g_device, entry.second->depth);
79
+ entry.second->depth = nullptr;
80
+ }
81
+ }
82
+ for (auto &entry : renderbuffers_) {
83
+ if (entry.second->depth != nullptr) {
84
+ SDL_ReleaseGPUTexture(guidev::g_device, entry.second->depth);
85
+ entry.second->depth = nullptr;
86
+ }
87
+ }
88
+ for (SDL_GPUBuffer *buffer : temp_buffers_) SDL_ReleaseGPUBuffer(guidev::g_device, buffer);
89
+ temp_buffers_.clear();
90
+ if (fallback_texture_ != nullptr) {
91
+ SDL_ReleaseGPUTexture(guidev::g_device, fallback_texture_);
92
+ fallback_texture_ = nullptr;
93
+ }
94
+ if (fallback_sampler_ != nullptr) {
95
+ SDL_ReleaseGPUSampler(guidev::g_device, fallback_sampler_);
96
+ fallback_sampler_ = nullptr;
97
+ }
98
+ if (color_ != nullptr) {
99
+ SDL_ReleaseGPUTexture(guidev::g_device, color_);
100
+ color_ = nullptr;
101
+ }
102
+ if (depth_ != nullptr) {
103
+ SDL_ReleaseGPUTexture(guidev::g_device, depth_);
104
+ depth_ = nullptr;
105
+ }
106
+ if (clear_texture_ != nullptr) {
107
+ SDL_ReleaseGPUTexture(guidev::g_device, clear_texture_);
108
+ clear_texture_ = nullptr;
109
+ }
110
+ }
111
+
112
+ void WebGLContext::lose_context() {
113
+ if (lost_) return;
114
+ submit();
115
+ if (guidev::g_device != nullptr) release_gpu_resources();
116
+ /* The WebGL spec invalidates every object when the context is lost: a page
117
+ * that gets `webglcontextlost` must recreate buffers, textures and programs
118
+ * after the restore. */
119
+ shaders_.clear();
120
+ programs_.clear();
121
+ buffers_.clear();
122
+ textures_.clear();
123
+ framebuffers_.clear();
124
+ renderbuffers_.clear();
125
+ vertex_arrays_.clear();
126
+ samplers_.clear();
127
+ queries_.clear();
128
+ syncs_.clear();
129
+ default_vertex_array_ = WebGLVertexArray();
130
+ for (WebGLAttribState &attrib : attribs_) attrib = WebGLAttribState();
131
+ current_program_ = 0;
132
+ bound_array_ = 0;
133
+ bound_element_ = 0;
134
+ bound_framebuffer_ = 0;
135
+ read_framebuffer_ = 0;
136
+ bound_renderbuffer_ = 0;
137
+ bound_vertex_array_ = 0;
138
+ copy_read_buffer_ = 0;
139
+ copy_write_buffer_ = 0;
140
+ active_unit_ = 0;
141
+ for (uint32_t &texture : bound_textures_) texture = 0;
142
+ for (uint32_t &texture : bound_cube_textures_) texture = 0;
143
+ for (uint32_t &texture : bound_array_textures_) texture = 0;
144
+ for (uint32_t &texture : bound_3d_textures_) texture = 0;
145
+ for (int &target : active_texture_target_) target = GL_TEXTURE_2D;
146
+ for (uint32_t &sampler : bound_samplers_) sampler = 0;
147
+ state_ = WebGLDrawState();
148
+ scissor_test_ = false;
149
+ error_ = 0;
150
+ lost_ = true;
151
+ clear_program_ = 0;
152
+ clear_buffer_ = 0;
153
+ }
154
+
155
+ void WebGLContext::restore_context() {
156
+ if (!lost_) return;
157
+ if (guidev::g_device == nullptr) return;
158
+ lost_ = false;
159
+ error_ = 0;
160
+ ensure_default_target();
161
+ }
162
+
163
+ void WebGLContext::drawing_buffer_storage(int width, int height) {
164
+ if (width <= 0 || height <= 0) {
165
+ set_error(GL_INVALID_VALUE);
166
+ return;
167
+ }
168
+ fixed_storage_ = true;
169
+ if (width == width_ && height == height_) return;
170
+ width_ = width;
171
+ height_ = height;
172
+ rebuild_default_target();
173
+ }
174
+
175
+ /* -- targets ------------------------------------------------------------- */
176
+
177
+ void WebGLContext::ensure_command() {
178
+ if (cmd_ != nullptr || guidev::g_device == nullptr) return;
179
+ cmd_ = SDL_AcquireGPUCommandBuffer(guidev::g_device);
180
+ if (cmd_ == nullptr) {
181
+ lost_ = true;
182
+ set_error(GL_OUT_OF_MEMORY);
183
+ }
184
+ }
185
+
186
+ void WebGLContext::ensure_default_target() {
187
+ if (guidev::g_device == nullptr) return;
188
+ if (color_ != nullptr && depth_ != nullptr) return;
189
+ SDL_GPUTextureCreateInfo info;
190
+ memset(&info, 0, sizeof(info));
191
+ info.type = SDL_GPU_TEXTURETYPE_2D;
192
+ info.format = SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM;
193
+ info.usage = SDL_GPU_TEXTUREUSAGE_SAMPLER | SDL_GPU_TEXTUREUSAGE_COLOR_TARGET;
194
+ info.width = (Uint32)width_;
195
+ info.height = (Uint32)height_;
196
+ info.layer_count_or_depth = 1;
197
+ info.num_levels = 1;
198
+ info.sample_count = SDL_GPU_SAMPLECOUNT_1;
199
+ if (color_ == nullptr) color_ = SDL_CreateGPUTexture(guidev::g_device, &info);
200
+ info.format = SDL_GPU_TEXTUREFORMAT_D32_FLOAT_S8_UINT;
201
+ info.usage = SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET;
202
+ if (depth_ == nullptr) depth_ = SDL_CreateGPUTexture(guidev::g_device, &info);
203
+ }
204
+
205
+ void WebGLContext::rebuild_default_target() {
206
+ if (guidev::g_device == nullptr) return;
207
+ end_pass();
208
+ ensure_command();
209
+ if (cmd_ != nullptr) {
210
+ /* Nothing recorded into the old target is worth keeping: a resize discards
211
+ * the drawing buffer, exactly like the DOM `canvas.width = …` rule. */
212
+ SDL_SubmitGPUCommandBuffer(cmd_);
213
+ cmd_ = nullptr;
214
+ }
215
+ SDL_WaitForGPUIdle(guidev::g_device);
216
+ if (color_ != nullptr) SDL_ReleaseGPUTexture(guidev::g_device, color_);
217
+ if (depth_ != nullptr) SDL_ReleaseGPUTexture(guidev::g_device, depth_);
218
+ color_ = nullptr;
219
+ depth_ = nullptr;
220
+ ensure_default_target();
221
+ }
222
+
223
+ SDL_GPUTexture *WebGLContext::color_texture() {
224
+ if (lost_) return nullptr;
225
+ ensure_default_target();
226
+ return color_;
227
+ }
228
+
229
+ void WebGLContext::resize(int width, int height) {
230
+ /* After `drawingBufferStorage` the drawing buffer has an explicit size and a
231
+ * canvas resize no longer changes it (WebGL 2). */
232
+ if (fixed_storage_) return;
233
+ if (width < 0) width = 0;
234
+ if (height < 0) height = 0;
235
+ width_ = width > 0 ? width : 1;
236
+ height_ = height > 0 ? height : 1;
237
+ viewport_[0] = 0;
238
+ viewport_[1] = 0;
239
+ viewport_[2] = width_;
240
+ viewport_[3] = height_;
241
+ scissor_box_[0] = 0;
242
+ scissor_box_[1] = 0;
243
+ scissor_box_[2] = width_;
244
+ scissor_box_[3] = height_;
245
+ rebuild_default_target();
246
+ }
247
+
248
+ void WebGLContext::submit() {
249
+ end_pass();
250
+ if (cmd_ != nullptr) {
251
+ SDL_SubmitGPUCommandBuffer(cmd_);
252
+ cmd_ = nullptr;
253
+ }
254
+ }
255
+
256
+ /* -- passes -------------------------------------------------------------- */
257
+
258
+ SDL_GPUTexture *WebGLContext::target_color() {
259
+ if (bound_framebuffer_ == 0) {
260
+ ensure_default_target();
261
+ return color_;
262
+ }
263
+ WebGLFramebuffer *framebuffer = this->framebuffer(bound_framebuffer_);
264
+ if (framebuffer == nullptr || framebuffer->color_textures[0] == 0) return nullptr;
265
+ WebGLTexture *texture = this->texture(framebuffer->color_textures[0]);
266
+ if (texture == nullptr) return nullptr;
267
+ return ensure_texture_gpu(texture, true);
268
+ }
269
+
270
+ SDL_GPUTexture *WebGLContext::framebuffer_color(uint32_t id) {
271
+ if (id == 0) {
272
+ ensure_default_target();
273
+ return color_;
274
+ }
275
+ WebGLFramebuffer *framebuffer_ = framebuffer(id);
276
+ if (framebuffer_ == nullptr || framebuffer_->color_textures[0] == 0) return nullptr;
277
+ WebGLTexture *texture_ = texture(framebuffer_->color_textures[0]);
278
+ return texture_ != nullptr ? ensure_texture_gpu(texture_, true) : nullptr;
279
+ }
280
+
281
+ void WebGLContext::framebuffer_size(uint32_t id, int *width, int *height) {
282
+ if (id == 0) {
283
+ *width = width_;
284
+ *height = height_;
285
+ return;
286
+ }
287
+ WebGLFramebuffer *framebuffer_ = framebuffer(id);
288
+ *width = framebuffer_ != nullptr ? framebuffer_->width : 0;
289
+ *height = framebuffer_ != nullptr ? framebuffer_->height : 0;
290
+ }
291
+
292
+ SDL_GPUTexture *WebGLContext::target_depth() {
293
+ if (bound_framebuffer_ == 0) {
294
+ ensure_default_target();
295
+ return depth_;
296
+ }
297
+ WebGLFramebuffer *framebuffer = this->framebuffer(bound_framebuffer_);
298
+ if (framebuffer == nullptr) return nullptr;
299
+ if (framebuffer->depth_texture != 0) {
300
+ WebGLTexture *texture = this->texture(framebuffer->depth_texture);
301
+ if (texture == nullptr) return nullptr;
302
+ texture->as_depth_target = true;
303
+ return ensure_texture_gpu(texture, true);
304
+ }
305
+ if (framebuffer->depth == nullptr && framebuffer->depth_renderbuffer == 0 &&
306
+ framebuffer->width > 0 && framebuffer->height > 0 && guidev::g_device != nullptr) {
307
+ SDL_GPUTextureCreateInfo info;
308
+ memset(&info, 0, sizeof(info));
309
+ info.type = SDL_GPU_TEXTURETYPE_2D;
310
+ info.format = SDL_GPU_TEXTUREFORMAT_D32_FLOAT_S8_UINT;
311
+ info.usage = SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET;
312
+ info.width = (Uint32)framebuffer->width;
313
+ info.height = (Uint32)framebuffer->height;
314
+ info.layer_count_or_depth = 1;
315
+ info.num_levels = 1;
316
+ info.sample_count = SDL_GPU_SAMPLECOUNT_1;
317
+ framebuffer->depth = SDL_CreateGPUTexture(guidev::g_device, &info);
318
+ }
319
+ return framebuffer->depth;
320
+ }
321
+
322
+ int WebGLContext::target_color_format() {
323
+ if (bound_framebuffer_ == 0) return SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM;
324
+ WebGLFramebuffer *framebuffer = this->framebuffer(bound_framebuffer_);
325
+ if (framebuffer == nullptr || framebuffer->color_textures[0] == 0) {
326
+ return SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM;
327
+ }
328
+ WebGLTexture *texture = this->texture(framebuffer->color_textures[0]);
329
+ return texture != nullptr ? (int)texture->format : SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM;
330
+ }
331
+
332
+ int WebGLContext::target_depth_format() {
333
+ if (bound_framebuffer_ == 0) return SDL_GPU_TEXTUREFORMAT_D32_FLOAT_S8_UINT;
334
+ WebGLFramebuffer *framebuffer = this->framebuffer(bound_framebuffer_);
335
+ if (framebuffer == nullptr) return SDL_GPU_TEXTUREFORMAT_D32_FLOAT_S8_UINT;
336
+ if (framebuffer->depth_texture != 0) {
337
+ WebGLTexture *texture = this->texture(framebuffer->depth_texture);
338
+ if (texture != nullptr) return (int)texture->format;
339
+ }
340
+ return SDL_GPU_TEXTUREFORMAT_D32_FLOAT_S8_UINT;
341
+ }
342
+
343
+ void WebGLContext::end_pass() {
344
+ if (pass_ != nullptr && cmd_ != nullptr) {
345
+ SDL_EndGPURenderPass(pass_);
346
+ pass_ = nullptr;
347
+ }
348
+ }
349
+
350
+ void WebGLContext::begin_pass(bool clear_color, bool clear_depth, bool clear_stencil) {
351
+ if (guidev::g_device == nullptr) return;
352
+ if (pass_ != nullptr && pass_targets_default_ == (bound_framebuffer_ == 0) &&
353
+ pass_framebuffer_ == bound_framebuffer_ && !clear_color && !clear_depth &&
354
+ !clear_stencil) {
355
+ return;
356
+ }
357
+ end_pass();
358
+ ensure_command();
359
+ if (cmd_ == nullptr) return;
360
+ SDL_GPUTexture *depth = target_depth();
361
+ SDL_GPUColorTargetInfo color_infos[kWebGLMaxDrawBuffers];
362
+ int color_count = 0;
363
+ for (int slot = 0; slot < kWebGLMaxDrawBuffers; slot++) {
364
+ SDL_GPUTexture *color = draw_color_texture(slot);
365
+ if (color == nullptr) continue;
366
+ SDL_GPUColorTargetInfo &color_info = color_infos[color_count++];
367
+ memset(&color_info, 0, sizeof(color_info));
368
+ color_info.texture = color;
369
+ color_info.layer_or_depth_plane = (Uint32)draw_color_layer(slot);
370
+ color_info.clear_color.r = clear_color_[0];
371
+ color_info.clear_color.g = clear_color_[1];
372
+ color_info.clear_color.b = clear_color_[2];
373
+ color_info.clear_color.a = clear_color_[3];
374
+ color_info.load_op = clear_color ? SDL_GPU_LOADOP_CLEAR : SDL_GPU_LOADOP_LOAD;
375
+ color_info.store_op = SDL_GPU_STOREOP_STORE;
376
+ }
377
+ if (color_count == 0) {
378
+ set_error(GL_INVALID_FRAMEBUFFER_OPERATION);
379
+ return;
380
+ }
381
+
382
+ SDL_GPUDepthStencilTargetInfo depth_info;
383
+ memset(&depth_info, 0, sizeof(depth_info));
384
+ depth_info.texture = depth;
385
+ depth_info.clear_depth = clear_depth_;
386
+ depth_info.load_op = (clear_depth && depth != nullptr) ? SDL_GPU_LOADOP_CLEAR
387
+ : SDL_GPU_LOADOP_LOAD;
388
+ depth_info.store_op = SDL_GPU_STOREOP_STORE;
389
+ depth_info.clear_stencil = (Uint8)(clear_stencil_ & 0xFF);
390
+ depth_info.stencil_load_op = (clear_stencil && depth != nullptr) ? SDL_GPU_LOADOP_CLEAR
391
+ : SDL_GPU_LOADOP_LOAD;
392
+ depth_info.stencil_store_op = SDL_GPU_STOREOP_STORE;
393
+
394
+ pass_ = SDL_BeginGPURenderPass(cmd_, color_infos, (Uint32)color_count,
395
+ depth != nullptr ? &depth_info : nullptr);
396
+ pass_targets_default_ = bound_framebuffer_ == 0;
397
+ pass_framebuffer_ = bound_framebuffer_;
398
+ }
399
+
400
+ /* -- queries ------------------------------------------------------------- */
401
+
402
+ double WebGLContext::parameter(int pname) {
403
+ switch (pname) {
404
+ case GL_MAX_TEXTURE_SIZE:
405
+ return 8192;
406
+ case GL_MAX_VERTEX_ATTRIBS:
407
+ return kWebGLMaxAttribs;
408
+ case GL_MAX_TEXTURE_IMAGE_UNITS:
409
+ return kWebGLMaxTextureUnits;
410
+ case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
411
+ return kWebGLMaxTextureUnits * 2;
412
+ case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
413
+ /* The vertex stage binds its own sampler set (`SDL_BindGPUVertexSamplers`)
414
+ * and the translator emits vertex samplers in descriptor set 0. */
415
+ return kWebGLMaxTextureUnits;
416
+ case GL_MAX_VERTEX_UNIFORM_VECTORS:
417
+ case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
418
+ case GL_MAX_VARYING_VECTORS:
419
+ return 256;
420
+ case GL_MAX_RENDERBUFFER_SIZE:
421
+ return 8192;
422
+ case GL_MAX_VIEWPORT_DIMS:
423
+ return 8192;
424
+ case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
425
+ return 8192;
426
+ case GL_SAMPLES:
427
+ case GL_SAMPLE_BUFFERS:
428
+ return 0;
429
+ case GL_SUBPIXEL_BITS:
430
+ return 4;
431
+ case GL_RED_BITS:
432
+ case GL_GREEN_BITS:
433
+ case GL_BLUE_BITS:
434
+ case GL_ALPHA_BITS:
435
+ case GL_DEPTH_BITS:
436
+ return 8;
437
+ case GL_STENCIL_BITS:
438
+ return 8;
439
+ case GL_UNPACK_ALIGNMENT:
440
+ case GL_PACK_ALIGNMENT:
441
+ return 4;
442
+ case GL_ACTIVE_TEXTURE:
443
+ return active_unit_ + GL_TEXTURE0;
444
+ case GL_CURRENT_PROGRAM:
445
+ return current_program_;
446
+ case GL_DEPTH_CLEAR_VALUE:
447
+ return clear_depth_;
448
+ case GL_STENCIL_CLEAR_VALUE:
449
+ return clear_stencil_;
450
+ /* -- WebGL 2 --------------------------------------------------------- */
451
+ case GL_MAX_3D_TEXTURE_SIZE:
452
+ return 2048;
453
+ case GL_MAX_ARRAY_TEXTURE_LAYERS:
454
+ return 256;
455
+ case GL_MAX_DRAW_BUFFERS:
456
+ case GL_MAX_COLOR_ATTACHMENTS:
457
+ return kWebGLMaxDrawBuffers;
458
+ case GL_READ_BUFFER:
459
+ return read_buffer_;
460
+ case GL_DRAW_BUFFER0:
461
+ return draw_buffer_value(0);
462
+ case GL_DRAW_BUFFER1:
463
+ return draw_buffer_value(1);
464
+ case GL_DRAW_BUFFER2:
465
+ return draw_buffer_value(2);
466
+ case GL_DRAW_BUFFER3:
467
+ return draw_buffer_value(3);
468
+ case GL_MAX_SAMPLES:
469
+ return 0;
470
+ case GL_MAX_UNIFORM_BUFFER_BINDINGS:
471
+ case GL_MAX_VERTEX_UNIFORM_BLOCKS:
472
+ case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
473
+ return 16;
474
+ case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
475
+ return 256;
476
+ case GL_MAX_ELEMENT_INDEX:
477
+ return 4294967295.0;
478
+ case GL_MAX_CLIENT_WAIT_TIMEOUT_WEBGL:
479
+ return 0;
480
+ case GL_MAX_VARYING_COMPONENTS:
481
+ case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
482
+ return 60;
483
+ case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
484
+ return 64;
485
+ case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
486
+ case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
487
+ case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
488
+ case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
489
+ return 1024;
490
+
491
+ default:
492
+ return 0;
493
+ }
494
+ }
495
+
496
+ std::string WebGLContext::string_parameter(int pname) {
497
+ const char *driver_name = driver();
498
+ switch (pname) {
499
+ case GL_VENDOR:
500
+ return "xbintsc";
501
+ case GL_RENDERER:
502
+ return std::string("xbintsc gui (SDL_GPU ") + (driver_name != nullptr ? driver_name : "?") +
503
+ ")";
504
+ case GL_VERSION:
505
+ return webgl2_ ? "WebGL 2.0 (xbintsc)" : "WebGL 1.0 (xbintsc)";
506
+ case GL_SHADING_LANGUAGE_VERSION:
507
+ return webgl2_ ? "WebGL GLSL ES 3.00 (xbintsc)" : "WebGL GLSL ES 1.0 (xbintsc)";
508
+ default:
509
+ return std::string();
510
+ }
511
+ }
512
+
513
+ const char *WebGLContext::driver() const {
514
+ return xt_gui_driver();
515
+ }
516
+
517
+ uint32_t WebGLContext::bound_buffer(int target) const { return buffer_for_target(target); }
518
+
519
+ uint32_t WebGLContext::bound_texture(int unit) const {
520
+ if (unit < 0 || unit >= kWebGLMaxTextureUnits) return 0;
521
+ const int target = active_texture_target_[unit];
522
+ if (target == GL_TEXTURE_CUBE_MAP) return bound_cube_textures_[unit];
523
+ if (target == GL_TEXTURE_2D_ARRAY) return bound_array_textures_[unit];
524
+ if (target == GL_TEXTURE_3D) return bound_3d_textures_[unit];
525
+ return bound_textures_[unit];
526
+ }
527
+
528
+ uint32_t WebGLContext::bound_cube_texture(int unit) const {
529
+ if (unit < 0 || unit >= kWebGLMaxTextureUnits) return 0;
530
+ return bound_cube_textures_[unit];
531
+ }
532
+
533
+ uint32_t WebGLContext::bound_array_texture(int unit) const {
534
+ if (unit < 0 || unit >= kWebGLMaxTextureUnits) return 0;
535
+ return bound_array_textures_[unit];
536
+ }
537
+
538
+ uint32_t WebGLContext::bound_3d_texture(int unit) const {
539
+ if (unit < 0 || unit >= kWebGLMaxTextureUnits) return 0;
540
+ return bound_3d_textures_[unit];
541
+ }
542
+
543
+ void WebGLContext::viewport_box(int out[4]) const {
544
+ for (int i = 0; i < 4; i++) out[i] = viewport_[i];
545
+ }
546
+
547
+ void WebGLContext::scissor_box(int out[4]) const {
548
+ for (int i = 0; i < 4; i++) out[i] = scissor_box_[i];
549
+ }
550
+
551
+ } // namespace xtgui