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,600 @@
1
+ /*
2
+ * xbintsc GUI engine — WebGL 1.0 context on SDL_GPU.
3
+ *
4
+ * A `WebGLContext` owns one offscreen RGBA8 colour texture (plus a depth
5
+ * texture) and records GPU work into its own SDL_GPU command buffer. The
6
+ * texture the page composites is that colour target, so a draw reaches the
7
+ * screen without a CPU round-trip: geometry, lighting, texture sampling and
8
+ * blending all execute on the GPU.
9
+ *
10
+ * WebGL's origin is bottom-left while SDL_GPU render targets use a top-left
11
+ * origin (its Vulkan backend flips the viewport), so the framebuffer is stored
12
+ * top-down; `viewport`/`scissor` are converted and `readPixels` flips rows back
13
+ * to the GL convention.
14
+ *
15
+ * Shaders are translated to SPIR-V by `webgl_glsl.cpp` (glslang). Pipeline
16
+ * objects depend on the vertex layout and fixed-function state, so they are
17
+ * created lazily per (program, layout, state) combination and cached.
18
+ *
19
+ * Handles are integer ids, not pointers: a `deleteBuffer`/`deleteTexture` call
20
+ * must make an old JavaScript handle a no-op rather than a dangling pointer.
21
+ */
22
+ #ifndef XT_GUI_WEBGL_H
23
+ #define XT_GUI_WEBGL_H
24
+
25
+ #include <SDL3/SDL.h>
26
+
27
+ #include <cstdint>
28
+ #include <memory>
29
+ #include <string>
30
+ #include <unordered_map>
31
+ #include <vector>
32
+
33
+ #include "webgl_constants.h"
34
+ #include "webgl2_constants.h"
35
+ #include "webgl_glsl.h"
36
+ #include "webgl_uniform_block.h"
37
+
38
+ namespace xtgui {
39
+
40
+ constexpr int kWebGLMaxAttribs = 16;
41
+ constexpr int kWebGLMaxTextureUnits = 16;
42
+ constexpr int kWebGLMaxDrawBuffers = 4;
43
+
44
+ struct WebGLShader {
45
+ uint32_t id = 0;
46
+ int type = 0; // GL_VERTEX_SHADER / GL_FRAGMENT_SHADER
47
+ std::string source;
48
+ std::string log;
49
+ bool compiled = false;
50
+ bool delete_requested = false;
51
+ int attachments = 0;
52
+ };
53
+
54
+ /** One active uniform of a linked program, with its std140 home. */
55
+ struct WebGLUniform {
56
+ std::string name;
57
+ GlslBlockMember layout;
58
+ bool sampler = false;
59
+ int unit = -1;
60
+ };
61
+
62
+ struct WebGLProgram {
63
+ uint32_t id = 0;
64
+ uint32_t vs = 0;
65
+ uint32_t fs = 0;
66
+ bool linked = false;
67
+ std::string log;
68
+ std::vector<WebGLUniform> uniforms;
69
+ std::vector<WebGLUniformBlock> blocks;
70
+ std::vector<GlslUniformDecl> attribs;
71
+ std::unordered_map<std::string, int> attrib_locations; // name -> location
72
+ std::unordered_map<std::string, int> attrib_bindings; // bindAttribLocation overrides
73
+ std::unordered_map<std::string, int> uniform_index; // name -> uniforms[] index
74
+ std::vector<int> vs_sampler_uniforms; // local binding -> uniforms[] index
75
+ std::vector<int> fs_sampler_uniforms;
76
+ std::vector<uint8_t> block; // std140 uniform data
77
+ int block_size = 0;
78
+ bool block_dirty = true;
79
+ bool vs_has_block = false;
80
+ bool fs_has_block = false;
81
+ SDL_GPUShader *vs_shader = nullptr;
82
+ SDL_GPUShader *fs_shader = nullptr;
83
+ std::vector<SDL_GPUGraphicsPipeline *> pipelines;
84
+ std::unordered_map<std::string, SDL_GPUGraphicsPipeline *> pipeline_cache;
85
+ };
86
+
87
+ struct WebGLBuffer {
88
+ uint32_t id = 0;
89
+ std::vector<uint8_t> data;
90
+ SDL_GPUBuffer *gpu = nullptr;
91
+ uint32_t capacity = 0;
92
+ bool dirty = true;
93
+ /** `bufferData` usage hint, reported by `getBufferParameter`. */
94
+ int usage = GL_STATIC_DRAW;
95
+ };
96
+
97
+ struct WebGLTexture {
98
+ uint32_t id = 0;
99
+ int width = 0;
100
+ int height = 0;
101
+ int levels = 1;
102
+ /** The binding target this texture was created for. */
103
+ int target = GL_TEXTURE_2D;
104
+ /** Layers for a cube/2D-array texture, depth for a 3D texture. */
105
+ int layers = 1;
106
+ SDL_GPUTexture *gpu = nullptr;
107
+ SDL_GPUTextureFormat format = SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM;
108
+ /** Depth(-stencil) formats can only be depth attachments. */
109
+ bool depth = false;
110
+ /** Block-compressed textures are sample-only, with one mip level. */
111
+ bool compressed = false;
112
+ /** Usage flags the current `gpu` texture was created with. */
113
+ uint32_t usage = 0;
114
+ bool as_target = false; // bound as a colour attachment
115
+ bool as_depth_target = false; // bound as a depth attachment
116
+ bool has_mipmaps = false;
117
+ int min_filter = 0;
118
+ int mag_filter = 0;
119
+ int wrap_s = 0;
120
+ int wrap_t = 0;
121
+ SDL_GPUSampler *sampler = nullptr;
122
+ bool dirty = false;
123
+ bool defined = false;
124
+ };
125
+
126
+ struct WebGLRenderbuffer {
127
+ uint32_t id = 0;
128
+ int width = 0;
129
+ int height = 0;
130
+ bool stencil = false;
131
+ SDL_GPUTexture *depth = nullptr;
132
+ };
133
+
134
+ struct WebGLFramebuffer {
135
+ uint32_t id = 0;
136
+ uint32_t color_textures[kWebGLMaxDrawBuffers] = {};
137
+ /** Layer rendered to for an array/cube colour attachment. */
138
+ int color_layers[kWebGLMaxDrawBuffers] = {};
139
+ /** `COLOR_ATTACHMENTi` or `NONE` per draw-buffer slot. */
140
+ int draw_buffers[kWebGLMaxDrawBuffers] = {GL_COLOR_ATTACHMENT0, GL_NONE, GL_NONE, GL_NONE};
141
+ uint32_t depth_texture = 0;
142
+ uint32_t depth_renderbuffer = 0;
143
+ int width = 0;
144
+ int height = 0;
145
+ SDL_GPUTexture *depth = nullptr; // owned when no renderbuffer/texture supplies one
146
+ };
147
+
148
+ /** Per-attribute array state. */
149
+ struct WebGLAttribState {
150
+ bool enabled = false;
151
+ bool integer = false; // `vertexAttribIPointer` rather than `vertexAttribPointer`
152
+ uint32_t buffer = 0;
153
+ int size = 4;
154
+ int type = GL_FLOAT;
155
+ bool normalized = false;
156
+ int stride = 0;
157
+ int offset = 0;
158
+ int divisor = 0; // 0 = per vertex, 1 = per instance
159
+ float current[4] = {0.0f, 0.0f, 0.0f, 1.0f};
160
+ };
161
+
162
+ /** A WebGL 2 vertex-array object; binding one restores this state. */
163
+ struct WebGLVertexArray {
164
+ uint32_t id = 0;
165
+ WebGLAttribState attribs[kWebGLMaxAttribs];
166
+ uint32_t element_buffer = 0;
167
+ };
168
+
169
+ /** A WebGL 2 sampler object, bound to a texture unit with `bindSampler`. */
170
+ struct WebGLSampler {
171
+ uint32_t id = 0;
172
+ int min_filter = 0;
173
+ int mag_filter = 0;
174
+ int wrap_s = 0;
175
+ int wrap_t = 0;
176
+ SDL_GPUSampler *gpu = nullptr;
177
+ };
178
+
179
+ struct WebGLQuery {
180
+ uint32_t id = 0;
181
+ };
182
+
183
+ struct WebGLSync {
184
+ uint32_t id = 0;
185
+ };
186
+
187
+ /** One face's stencil test and update state. */
188
+ struct WebGLStencilFace {
189
+ int func = GL_ALWAYS;
190
+ int ref = 0;
191
+ uint32_t value_mask = 0xFFFFFFFFu; // compare mask
192
+ uint32_t write_mask = 0xFFFFFFFFu;
193
+ int fail = GL_KEEP;
194
+ int zfail = GL_KEEP;
195
+ int zpass = GL_KEEP;
196
+ };
197
+
198
+ /** The fixed-function state a pipeline depends on. */
199
+ struct WebGLDrawState {
200
+ bool blend = false;
201
+ int blend_src_rgb = GL_ONE;
202
+ int blend_dst_rgb = GL_ZERO;
203
+ int blend_src_alpha = GL_ONE;
204
+ int blend_dst_alpha = GL_ZERO;
205
+ int blend_eq_rgb = GL_FUNC_ADD;
206
+ int blend_eq_alpha = GL_FUNC_ADD;
207
+ bool depth_test = false;
208
+ bool depth_write = true;
209
+ int depth_func = GL_LESS;
210
+ bool stencil = false;
211
+ WebGLStencilFace stencil_front;
212
+ WebGLStencilFace stencil_back;
213
+ bool cull = false;
214
+ int cull_face = GL_BACK;
215
+ int front_face = GL_CCW;
216
+ bool color_mask[4] = {true, true, true, true};
217
+ /** Attachment formats of the bound target; pipelines are format-specific. */
218
+ int color_formats[kWebGLMaxDrawBuffers] = {
219
+ SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM, SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM,
220
+ SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM, SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM};
221
+ int color_target_count = 1;
222
+ int depth_format = SDL_GPU_TEXTUREFORMAT_D32_FLOAT_S8_UINT;
223
+ };
224
+
225
+ class WebGLContext {
226
+ public:
227
+ WebGLContext(uint64_t id, int width, int height, bool webgl2);
228
+ ~WebGLContext();
229
+
230
+ uint64_t id() const { return id_; }
231
+ bool is_webgl2() const { return webgl2_; }
232
+ int width() const { return width_; }
233
+ int height() const { return height_; }
234
+ /** Resize the drawing buffer; GL semantics discard its contents. */
235
+ void resize(int width, int height);
236
+
237
+ /** End the pass and submit (once per frame, before sampling). */
238
+ void submit();
239
+ SDL_GPUTexture *color_texture();
240
+ bool lost() const { return lost_; }
241
+ /** Lose/restore the GPU device, dropping every WebGL object. */
242
+ void lose_context();
243
+ void restore_context();
244
+ /** `drawingBufferStorage`: fix the size across canvas resizes. */
245
+ void drawing_buffer_storage(int width, int height);
246
+
247
+ /* -- object lookups ---------------------------------------------------- */
248
+ WebGLShader *shader(uint32_t id);
249
+ WebGLProgram *program(uint32_t id);
250
+ WebGLBuffer *buffer(uint32_t id);
251
+ WebGLTexture *texture(uint32_t id);
252
+ WebGLFramebuffer *framebuffer(uint32_t id);
253
+ WebGLRenderbuffer *renderbuffer(uint32_t id);
254
+ WebGLVertexArray *vertex_array(uint32_t id);
255
+ WebGLSampler *sampler(uint32_t id);
256
+ WebGLQuery *query(uint32_t id);
257
+ WebGLSync *sync(uint32_t id);
258
+
259
+ /* -- state ------------------------------------------------------------- */
260
+ void enable(int cap);
261
+ void disable(int cap);
262
+ bool is_enabled(int cap) const;
263
+ void clear_color(float r, float g, float b, float a);
264
+ void clear_depth(float depth) { clear_depth_ = depth; }
265
+ void clear_stencil(int value) { clear_stencil_ = value; }
266
+ void color_mask(bool r, bool g, bool b, bool a);
267
+ void depth_mask(bool write) { state_.depth_write = write; }
268
+ void depth_func(int func) { state_.depth_func = func; }
269
+ void stencil_func(int func, int ref, uint32_t mask);
270
+ void stencil_func_separate(int face, int func, int ref, uint32_t mask);
271
+ void stencil_op(int fail, int zfail, int zpass);
272
+ void stencil_op_separate(int face, int fail, int zfail, int zpass);
273
+ void stencil_mask(uint32_t mask);
274
+ void stencil_mask_separate(int face, uint32_t mask);
275
+ const WebGLStencilFace &stencil_face(int face) const;
276
+ int stencil_reference() const; // the value the GPU test sees
277
+ void blend_func(int src, int dst);
278
+ void blend_func_separate(int src_rgb, int dst_rgb, int src_alpha, int dst_alpha);
279
+ void blend_equation(int mode);
280
+ void blend_equation_separate(int rgb, int alpha);
281
+ void blend_color(float r, float g, float b, float a);
282
+ void blend_color_value(float out[4]) const;
283
+ void cull_face(int mode);
284
+ void front_face(int mode);
285
+ void viewport(int x, int y, int w, int h);
286
+ void scissor(int x, int y, int w, int h);
287
+ void clear(int mask);
288
+ void finish();
289
+
290
+ /* -- shaders and programs --------------------------------------------- */
291
+ uint32_t create_shader(int type);
292
+ void delete_shader(uint32_t id);
293
+ void shader_source(uint32_t id, const std::string &source);
294
+ bool compile_shader(uint32_t id);
295
+ std::string shader_info_log(uint32_t id);
296
+ bool shader_compiled(uint32_t id);
297
+ std::string shader_source_text(uint32_t id);
298
+
299
+ uint32_t create_program();
300
+ void delete_program(uint32_t id);
301
+ bool attach_shader(uint32_t program, uint32_t shader);
302
+ bool detach_shader(uint32_t program, uint32_t shader);
303
+ bool link_program(uint32_t id);
304
+ void use_program(uint32_t id);
305
+ bool program_linked(uint32_t id);
306
+ std::string program_info_log(uint32_t id);
307
+ std::vector<uint32_t> attached_shaders(uint32_t id);
308
+ int active_uniform_count(uint32_t id);
309
+ int active_attrib_count(uint32_t id);
310
+ const WebGLUniform *active_uniform(uint32_t id, int index);
311
+ const GlslUniformDecl *active_attrib(uint32_t id, int index);
312
+
313
+ int uniform_location(uint32_t program, const std::string &name);
314
+ int attrib_location(uint32_t program, const std::string &name);
315
+ void bind_attrib_location(uint32_t program, int index, const std::string &name);
316
+
317
+ /* Uniform uploads; `location` indexes the program's uniform table. */
318
+ void uniform_floats(uint32_t program, int location, int components, const double *values,
319
+ int count);
320
+ void uniform_ints(uint32_t program, int location, int components, const int *values, int count);
321
+ void uniform_matrix(uint32_t program, int location, int dimensions, const double *values);
322
+ bool uniform_values(uint32_t program, int location, std::vector<double> *out);
323
+
324
+ /* -- buffers and vertex attributes ------------------------------------ */
325
+ uint32_t create_buffer();
326
+ void delete_buffer(uint32_t id);
327
+ void bind_buffer(int target, uint32_t id);
328
+ bool buffer_data(uint32_t id, const uint8_t *bytes, uint32_t size, int usage);
329
+ bool buffer_sub_data(uint32_t id, uint32_t offset, const uint8_t *bytes, uint32_t size);
330
+ uint32_t buffer_size(uint32_t id);
331
+ void enable_attrib(int index, bool enabled);
332
+ bool attrib_enabled(int index) const;
333
+ void attrib_pointer(int index, int size, int type, bool normalized, int stride, int offset);
334
+ void attrib_value(int index, int components, const float *values);
335
+ void attrib_state(int index, int *size, int *type, int *stride, bool *normalized,
336
+ float current[4]) const;
337
+ uint32_t attrib_buffer(int index) const { return attribs_[index].buffer; }
338
+ void attrib_ipointer(int index, int size, int type, int stride, int offset);
339
+ void attrib_divisor(int index, int divisor);
340
+
341
+ /* -- WebGL 2 vertex arrays, instancing and buffer copies --------------- */
342
+ uint32_t create_vertex_array();
343
+ void delete_vertex_array(uint32_t id);
344
+ void bind_vertex_array(uint32_t id);
345
+ bool is_vertex_array(uint32_t id) const;
346
+ uint32_t bound_vertex_array() const { return bound_vertex_array_; }
347
+ void draw_arrays_instanced(int mode, int first, int count, int instances);
348
+ void draw_elements_instanced(int mode, int count, int type, int offset, int instances);
349
+ void draw_range_elements(int mode, int start, int end, int count, int type, int offset);
350
+ bool copy_buffer_sub_data(int read_target, int write_target, uint32_t read_offset,
351
+ uint32_t write_offset, uint32_t size);
352
+ bool get_buffer_sub_data(int target, uint32_t offset, uint8_t *out, uint32_t size);
353
+
354
+ /* -- WebGL 2 sampler objects ------------------------------------------- */
355
+ uint32_t create_sampler();
356
+ void delete_sampler(uint32_t id);
357
+ void bind_sampler(int unit, uint32_t id);
358
+ bool sampler_parameter(uint32_t id, int pname, int value);
359
+ int sampler_parameter_value(uint32_t id, int pname);
360
+
361
+ /* -- WebGL 2 queries, syncs and uniform-block stubs -------------------- */
362
+ uint32_t create_query();
363
+ void delete_query(uint32_t id);
364
+ bool is_query(uint32_t id) const;
365
+ uint32_t create_sync();
366
+ void delete_sync(uint32_t id);
367
+ bool is_sync(uint32_t id) const;
368
+ uint32_t uniform_block_index(uint32_t program, const std::string &name) const;
369
+ WebGLUniformBlock *uniform_block(uint32_t program, uint32_t index);
370
+ int uniform_block_parameter(uint32_t program, uint32_t index, int pname) const;
371
+ std::string uniform_block_name(uint32_t program, uint32_t index) const;
372
+ void uniform_block_binding(uint32_t program, uint32_t index, int binding);
373
+ void bind_buffer_base(int target, int index, uint32_t buffer, uint32_t offset, uint32_t size);
374
+ uint32_t uniform_buffer_binding(int index) const;
375
+
376
+ /* -- textures ---------------------------------------------------------- */
377
+ uint32_t create_texture();
378
+ void delete_texture(uint32_t id);
379
+ void bind_texture(int target, uint32_t id);
380
+ void active_texture(int unit);
381
+ bool tex_parameter(uint32_t texture, int pname, int value);
382
+ int tex_parameter_value(uint32_t id, int pname);
383
+ bool tex_image_rgba(uint32_t id, int width, int height, const uint8_t *rgba);
384
+ bool tex_sub_image_rgba(uint32_t id, int x, int y, int width, int height, const uint8_t *rgba);
385
+ /** Level-0 upload; `pixels` is tightly packed RGBA or expanded already. */
386
+ bool tex_image_format(uint32_t id, int width, int height, SDL_GPUTextureFormat format,
387
+ const uint8_t *pixels, int layer = -1);
388
+ bool tex_sub_image_format(uint32_t id, int x, int y, int width, int height,
389
+ const uint8_t *pixels, int layer = 0);
390
+ bool generate_mipmap(uint32_t id);
391
+ /** `texStorage2D`; the backend allocates the full mip chain. */
392
+ bool tex_storage_2d(uint32_t id, int levels, int width, int height);
393
+ bool tex_storage_format(uint32_t id, int levels, int width, int height,
394
+ SDL_GPUTextureFormat format);
395
+ /** Allocate (and optionally upload) a 3D or 2D-array texture. */
396
+ bool tex_storage_3d(uint32_t id, int levels, int width, int height, int depth,
397
+ SDL_GPUTextureFormat format, int target);
398
+ bool tex_image_3d(uint32_t id, int width, int height, int depth,
399
+ SDL_GPUTextureFormat format, const uint8_t *pixels, int target);
400
+ bool tex_sub_image_3d(uint32_t id, int x, int y, int z, int width, int height, int depth,
401
+ const uint8_t *pixels);
402
+ /** Upload a block-compressed region. */
403
+ bool tex_image_compressed(uint32_t id, int width, int height, SDL_GPUTextureFormat format,
404
+ int x, int y, int region_width, int region_height,
405
+ const uint8_t *data, uint32_t size);
406
+ /** Whether the device can sample `internalformat` (compressed formats). */
407
+ bool supports_texture_format(int internalformat);
408
+ int texture_width(uint32_t id);
409
+ int texture_height(uint32_t id);
410
+ /** The SDL_GPU format of a texture (RGBA8 before `texImage2D`). */
411
+ int texture_format(uint32_t id);
412
+
413
+ /* -- framebuffers ------------------------------------------------------ */
414
+ uint32_t create_framebuffer();
415
+ void delete_framebuffer(uint32_t id);
416
+ void bind_framebuffer(int target, uint32_t id);
417
+ uint32_t bound_read_framebuffer_id() const { return read_framebuffer_; }
418
+ bool blit_framebuffer(const int source[4], const int destination[4], int mask, int filter);
419
+ bool framebuffer_texture(uint32_t framebuffer, uint32_t texture,
420
+ int attachment = GL_COLOR_ATTACHMENT0);
421
+ bool framebuffer_texture_layer(uint32_t framebuffer, uint32_t texture, int attachment,
422
+ int layer);
423
+ bool framebuffer_status(uint32_t id);
424
+ /** WebGL 2 `drawBuffers` / `readBuffer`. */
425
+ void draw_buffers(int count, const int *buffers);
426
+ void read_buffer(int mode) { read_buffer_ = mode; }
427
+ int read_buffer_value() const { return read_buffer_; }
428
+ int draw_buffer_value(int index);
429
+ uint32_t create_renderbuffer();
430
+ void delete_renderbuffer(uint32_t id);
431
+ void bind_renderbuffer(uint32_t id) { bound_renderbuffer_ = id; }
432
+ bool renderbuffer_storage(uint32_t id, int width, int height, bool stencil);
433
+ bool framebuffer_renderbuffer(uint32_t framebuffer, uint32_t renderbuffer);
434
+
435
+ /* -- drawing ----------------------------------------------------------- */
436
+ void draw_arrays(int mode, int first, int count);
437
+ void draw_elements(int mode, int count, int type, int offset);
438
+ bool read_pixels(int x, int y, int width, int height, uint8_t *out);
439
+ /** WebGL 2 `clearBufferfv` / `clearBufferiv` / `clearBufferuiv`. */
440
+ void clear_buffer_float(int buffer, int drawbuffer, const float *values, int count);
441
+ void clear_buffer_int(int buffer, int drawbuffer, const int *values, int count);
442
+ void clear_buffer_uint(int buffer, int drawbuffer, const unsigned int *values, int count);
443
+ void clear_buffer_fi(int buffer, int drawbuffer, float depth, int stencil);
444
+
445
+ /* -- queries ----------------------------------------------------------- */
446
+ double parameter(int pname);
447
+ std::string string_parameter(int pname);
448
+ uint32_t bound_buffer(int target) const;
449
+ uint32_t bound_texture(int unit) const;
450
+ uint32_t bound_cube_texture(int unit) const;
451
+ uint32_t bound_array_texture(int unit) const;
452
+ uint32_t bound_3d_texture(int unit) const;
453
+ uint32_t current_program_id() const { return current_program_; }
454
+ uint32_t bound_framebuffer_id() const { return bound_framebuffer_; }
455
+ uint32_t bound_renderbuffer_id() const { return bound_renderbuffer_; }
456
+ void viewport_box(int out[4]) const;
457
+ void scissor_box(int out[4]) const;
458
+ int error() {
459
+ int value = error_;
460
+ error_ = 0;
461
+ return value;
462
+ }
463
+ void set_error(int value) {
464
+ if (error_ == 0) error_ = value;
465
+ }
466
+ const char *driver() const;
467
+
468
+ private:
469
+ /* -- GPU plumbing ------------------------------------------------------ */
470
+ void ensure_command();
471
+ void end_pass();
472
+ void flush_uploads();
473
+ void begin_pass(bool clear_color, bool clear_depth, bool clear_stencil);
474
+ /** Scissored depth/stencil clear via a masked fullscreen triangle. */
475
+ void scissored_clear(int mask);
476
+ /** The 1×1 texture a scissored colour clear blits from. */
477
+ SDL_GPUTexture *clear_color_texture();
478
+ SDL_GPUTexture *framebuffer_color(uint32_t id);
479
+ void framebuffer_size(uint32_t id, int *width, int *height);
480
+ /** Release every GPU handle this context owns, keeping the CPU-side object
481
+ * table. Used by the destructor and by `lose_context`. */
482
+ void release_gpu_resources();
483
+ SDL_GPUTexture *target_color();
484
+ SDL_GPUTexture *target_depth();
485
+ int target_color_format();
486
+ int target_depth_format();
487
+ /** The texture rendered to for draw-buffer slot `slot`, or null. */
488
+ SDL_GPUTexture *draw_color_texture(int slot);
489
+ int draw_color_format(int slot);
490
+ int draw_color_layer(int slot);
491
+ SDL_GPUTexture *ensure_texture_gpu(WebGLTexture *texture, bool as_target);
492
+ SDL_GPUSampler *sampler_for(WebGLTexture *texture);
493
+ SDL_GPUBuffer *ensure_buffer_gpu(WebGLBuffer *buffer);
494
+ void ensure_default_target();
495
+ void rebuild_default_target();
496
+ bool ensure_fallback();
497
+ SDL_GPUBuffer *upload_temp_buffer(const void *data, uint32_t size,
498
+ SDL_GPUBufferUsageFlags usage);
499
+ void draw(int mode, int first, int count, int index_type, int offset, int instances);
500
+ void save_vertex_array();
501
+ void load_vertex_array(const WebGLVertexArray *array);
502
+ SDL_GPUSampler *sampler_gpu(WebGLSampler *sampler);
503
+ uint32_t buffer_for_target(int target) const;
504
+ void release_program_pipelines(WebGLProgram *program);
505
+ SDL_GPUGraphicsPipeline *create_pipeline(WebGLProgram *program, int mode, int index_type,
506
+ int attribute_count, int buffer_count,
507
+ const SDL_GPUVertexAttribute *attrs,
508
+ const SDL_GPUVertexBufferDescription *buffers,
509
+ const std::string &key);
510
+
511
+ uint64_t id_ = 0;
512
+ int width_ = 0;
513
+ int height_ = 0;
514
+ bool lost_ = false;
515
+ bool webgl2_ = false;
516
+
517
+ SDL_GPUCommandBuffer *cmd_ = nullptr;
518
+ SDL_GPURenderPass *pass_ = nullptr;
519
+ bool pass_targets_default_ = true;
520
+ uint32_t pass_framebuffer_ = 0;
521
+
522
+ SDL_GPUTexture *color_ = nullptr;
523
+ SDL_GPUTexture *depth_ = nullptr;
524
+ SDL_GPUTexture *fallback_texture_ = nullptr;
525
+ SDL_GPUSampler *fallback_sampler_ = nullptr;
526
+ /** 1×1 RGBA8 source for a scissored colour clear. */
527
+ SDL_GPUTexture *clear_texture_ = nullptr;
528
+ /** Internal program/buffer for a scissored depth/stencil clear. */
529
+ uint32_t clear_program_ = 0;
530
+ uint32_t clear_buffer_ = 0;
531
+
532
+ float clear_color_[4] = {0.0f, 0.0f, 0.0f, 0.0f};
533
+ float clear_depth_ = 1.0f;
534
+ int clear_stencil_ = 0;
535
+ float blend_color_[4] = {0.0f, 0.0f, 0.0f, 0.0f};
536
+ /** Set by `drawingBufferStorage`; canvas resizes then leave the size. */
537
+ bool fixed_storage_ = false;
538
+ WebGLDrawState state_;
539
+ int viewport_[4] = {0, 0, 0, 0};
540
+ int scissor_box_[4] = {0, 0, 0, 0};
541
+ bool scissor_test_ = false;
542
+
543
+ std::unordered_map<uint32_t, std::unique_ptr<WebGLShader>> shaders_;
544
+ std::unordered_map<uint32_t, std::unique_ptr<WebGLProgram>> programs_;
545
+ std::unordered_map<uint32_t, std::unique_ptr<WebGLBuffer>> buffers_;
546
+ std::unordered_map<uint32_t, std::unique_ptr<WebGLTexture>> textures_;
547
+ std::unordered_map<uint32_t, std::unique_ptr<WebGLFramebuffer>> framebuffers_;
548
+ std::unordered_map<uint32_t, std::unique_ptr<WebGLRenderbuffer>> renderbuffers_;
549
+ std::unordered_map<uint32_t, std::unique_ptr<WebGLVertexArray>> vertex_arrays_;
550
+ std::unordered_map<uint32_t, std::unique_ptr<WebGLSampler>> samplers_;
551
+ std::unordered_map<uint32_t, std::unique_ptr<WebGLQuery>> queries_;
552
+ std::unordered_map<uint32_t, std::unique_ptr<WebGLSync>> syncs_;
553
+ /** GPU buffers for transient draws (constant attributes, expanded indices). */
554
+ std::vector<SDL_GPUBuffer *> temp_buffers_;
555
+
556
+ uint32_t current_program_ = 0;
557
+ uint32_t bound_array_ = 0;
558
+ uint32_t bound_element_ = 0;
559
+ uint32_t bound_uniform_ = 0;
560
+ uint32_t bound_transform_feedback_ = 0;
561
+ uint32_t bound_framebuffer_ = 0;
562
+ uint32_t read_framebuffer_ = 0;
563
+ int read_buffer_ = GL_BACK;
564
+ int default_draw_buffers_[kWebGLMaxDrawBuffers] = {GL_BACK, GL_NONE, GL_NONE, GL_NONE};
565
+ uint32_t bound_renderbuffer_ = 0;
566
+ WebGLUniformBinding uniform_bindings_[16];
567
+ uint32_t bound_textures_[kWebGLMaxTextureUnits] = {};
568
+ uint32_t bound_cube_textures_[kWebGLMaxTextureUnits] = {};
569
+ uint32_t bound_array_textures_[kWebGLMaxTextureUnits] = {};
570
+ uint32_t bound_3d_textures_[kWebGLMaxTextureUnits] = {};
571
+ /** The target of the most recent `bindTexture` on each unit, so the existing
572
+ * per-unit entry points operate on the object the page just bound. */
573
+ int active_texture_target_[kWebGLMaxTextureUnits] = {};
574
+ uint32_t bound_samplers_[kWebGLMaxTextureUnits] = {};
575
+ uint32_t bound_vertex_array_ = 0;
576
+ WebGLVertexArray default_vertex_array_;
577
+ uint32_t copy_read_buffer_ = 0;
578
+ uint32_t copy_write_buffer_ = 0;
579
+ int active_unit_ = 0;
580
+ WebGLAttribState attribs_[kWebGLMaxAttribs];
581
+
582
+ uint32_t next_object_id_ = 1;
583
+ int error_ = 0;
584
+ };
585
+
586
+ /** Resolve a process-wide WebGL context id (used by the renderer when it paints
587
+ * a `<canvas>`). */
588
+ WebGLContext *xt_webgl_by_id(uint64_t id);
589
+
590
+ /** Map a WebGL internal format to the SDL_GPU texture format the engine uses
591
+ * (RGBA8 for formats without a special backend representation). */
592
+ SDL_GPUTextureFormat webgl_storage_format(int internalformat);
593
+
594
+ /** Map a WebGL compressed-texture internal format to its SDL_GPU format, or
595
+ * `SDL_GPU_TEXTUREFORMAT_INVALID` for anything else. */
596
+ SDL_GPUTextureFormat webgl_compressed_format(int internalformat);
597
+
598
+ } // namespace xtgui
599
+
600
+ #endif /* XT_GUI_WEBGL_H */