xbintsc 0.5.31 → 0.5.32

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 (181) hide show
  1. package/README.md +16 -10
  2. package/dist/src/binder/references.js +14 -1
  3. package/dist/src/binder/references.js.map +1 -1
  4. package/dist/src/cli/help.d.ts +1 -1
  5. package/dist/src/codegen/generator/module.d.ts +1 -0
  6. package/dist/src/codegen/generator/module.js +54 -0
  7. package/dist/src/codegen/generator/module.js.map +1 -1
  8. package/dist/src/codegen/generator/statements/variables.js +6 -4
  9. package/dist/src/codegen/generator/statements/variables.js.map +1 -1
  10. package/dist/src/driver/version.d.ts +1 -1
  11. package/dist/src/driver/version.js +1 -1
  12. package/dist/src/extensions/gui/css.d.ts +26 -0
  13. package/dist/src/extensions/gui/css.js +100 -0
  14. package/dist/src/extensions/gui/css.js.map +1 -0
  15. package/dist/src/extensions/gui/html.js +9 -2
  16. package/dist/src/extensions/gui/html.js.map +1 -1
  17. package/dist/src/extensions/gui/index.js +16 -2
  18. package/dist/src/extensions/gui/index.js.map +1 -1
  19. package/dist/src/extensions/gui/three.d.ts +16 -0
  20. package/dist/src/extensions/gui/three.js +22 -0
  21. package/dist/src/extensions/gui/three.js.map +1 -0
  22. package/dist/src/extensions/media/index.d.ts +6 -5
  23. package/dist/src/extensions/media/index.js +12 -14
  24. package/dist/src/extensions/media/index.js.map +1 -1
  25. package/dist/tests/e2e/compile-builtins.test.js +24 -0
  26. package/dist/tests/e2e/compile-builtins.test.js.map +1 -1
  27. package/dist/tests/e2e/compile-objects-classes.test.js +23 -0
  28. package/dist/tests/e2e/compile-objects-classes.test.js.map +1 -1
  29. package/dist/tests/e2e/gui-browser.test.js +1 -1
  30. package/dist/tests/e2e/gui-browser.test.js.map +1 -1
  31. package/dist/tests/e2e/gui-effects.test.d.ts +6 -0
  32. package/dist/tests/e2e/gui-effects.test.js +262 -0
  33. package/dist/tests/e2e/gui-effects.test.js.map +1 -0
  34. package/dist/tests/e2e/gui-example-webgl.test.d.ts +10 -0
  35. package/dist/tests/e2e/gui-example-webgl.test.js +75 -0
  36. package/dist/tests/e2e/gui-example-webgl.test.js.map +1 -0
  37. package/dist/tests/e2e/gui-example-webgl2.test.d.ts +8 -0
  38. package/dist/tests/e2e/gui-example-webgl2.test.js +72 -0
  39. package/dist/tests/e2e/gui-example-webgl2.test.js.map +1 -0
  40. package/dist/tests/e2e/gui-layout.test.js +48 -0
  41. package/dist/tests/e2e/gui-layout.test.js.map +1 -1
  42. package/dist/tests/e2e/gui-media.test.js +5 -4
  43. package/dist/tests/e2e/gui-media.test.js.map +1 -1
  44. package/dist/tests/e2e/gui-webgl.test.d.ts +11 -0
  45. package/dist/tests/e2e/gui-webgl.test.js +179 -0
  46. package/dist/tests/e2e/gui-webgl.test.js.map +1 -0
  47. package/dist/tests/e2e/gui-webgl2.test.d.ts +10 -0
  48. package/dist/tests/e2e/gui-webgl2.test.js +238 -0
  49. package/dist/tests/e2e/gui-webgl2.test.js.map +1 -0
  50. package/dist/tests/extensions/gui.test.js +41 -0
  51. package/dist/tests/extensions/gui.test.js.map +1 -1
  52. package/dist/tests/extensions/media.test.js +7 -3
  53. package/dist/tests/extensions/media.test.js.map +1 -1
  54. package/doc/ai/extensions.md +29 -9
  55. package/doc/ai/troubleshooting.md +12 -8
  56. package/doc/ai/zh-CN/extensions.md +26 -8
  57. package/doc/ai/zh-CN/troubleshooting.md +10 -6
  58. package/doc/gui/api.md +3 -2
  59. package/doc/gui/build.md +72 -16
  60. package/doc/gui/canvas.md +11 -3
  61. package/doc/gui/dom.md +33 -18
  62. package/doc/gui/known-issues.md +57 -24
  63. package/doc/gui/layout.md +18 -0
  64. package/doc/gui/media.md +17 -13
  65. package/doc/gui/rendering.md +50 -3
  66. package/doc/gui/webgl.md +256 -0
  67. package/doc/gui.md +108 -17
  68. package/doc/npm-package.md +6 -4
  69. package/doc/requirements.md +18 -9
  70. package/doc/zh-CN/gui/api.md +3 -2
  71. package/doc/zh-CN/gui/build.md +64 -15
  72. package/doc/zh-CN/gui/canvas.md +9 -2
  73. package/doc/zh-CN/gui/dom.md +20 -7
  74. package/doc/zh-CN/gui/known-issues.md +45 -19
  75. package/doc/zh-CN/gui/layout.md +14 -0
  76. package/doc/zh-CN/gui/media.md +15 -11
  77. package/doc/zh-CN/gui/rendering.md +41 -4
  78. package/doc/zh-CN/gui/webgl.md +115 -0
  79. package/doc/zh-CN/gui.md +89 -14
  80. package/doc/zh-CN/npm-package.md +9 -6
  81. package/doc/zh-CN/requirements.md +12 -6
  82. package/llms.txt +2 -0
  83. package/package.json +1 -1
  84. package/runtime/ext_gui/browser.cpp +39 -13
  85. package/runtime/ext_gui/canvas.cpp +3 -18
  86. package/runtime/ext_gui/canvas_internal.h +10 -0
  87. package/runtime/ext_gui/canvas_raster.cpp +60 -0
  88. package/runtime/ext_gui/clip_values.cpp +246 -0
  89. package/runtime/ext_gui/css.cpp +94 -0
  90. package/runtime/ext_gui/css.h +22 -1
  91. package/runtime/ext_gui/css_match.cpp +3 -0
  92. package/runtime/ext_gui/css_selector.cpp +9 -0
  93. package/runtime/ext_gui/css_sheet.cpp +89 -45
  94. package/runtime/ext_gui/document.cpp +4 -1
  95. package/runtime/ext_gui/document.h +2 -0
  96. package/runtime/ext_gui/dom.h +16 -0
  97. package/runtime/ext_gui/dom_api.cpp +1 -0
  98. package/runtime/ext_gui/dom_api_canvas.cpp +17 -80
  99. package/runtime/ext_gui/dom_api_canvas_extra.cpp +130 -1
  100. package/runtime/ext_gui/dom_api_canvas_pending.cpp +41 -0
  101. package/runtime/ext_gui/dom_api_internal.h +259 -0
  102. package/runtime/ext_gui/dom_api_webgl.cpp +376 -0
  103. package/runtime/ext_gui/dom_api_webgl2.cpp +434 -0
  104. package/runtime/ext_gui/dom_api_webgl2_draw.cpp +269 -0
  105. package/runtime/ext_gui/dom_api_webgl_buffer.cpp +212 -0
  106. package/runtime/ext_gui/dom_api_webgl_rt.h +30 -0
  107. package/runtime/ext_gui/dom_api_webgl_shader.cpp +443 -0
  108. package/runtime/ext_gui/dom_api_webgl_state.cpp +444 -0
  109. package/runtime/ext_gui/dom_api_webgl_texture.cpp +445 -0
  110. package/runtime/ext_gui/effect_values.cpp +312 -0
  111. package/runtime/ext_gui/gradient_values.cpp +476 -0
  112. package/runtime/ext_gui/grid_values.cpp +230 -0
  113. package/runtime/ext_gui/gui_canvas.cpp +50 -2
  114. package/runtime/ext_gui/gui_engine.h +27 -0
  115. package/runtime/ext_gui/gui_events.cpp +4 -1
  116. package/runtime/ext_gui/gui_media.cpp +1 -1
  117. package/runtime/ext_gui/gui_webgl.cpp +83 -0
  118. package/runtime/ext_gui/layout.cpp +21 -0
  119. package/runtime/ext_gui/layout_flow.cpp +81 -4
  120. package/runtime/ext_gui/layout_flow_internal.h +31 -0
  121. package/runtime/ext_gui/layout_grid.cpp +374 -0
  122. package/runtime/ext_gui/media.h +1 -1
  123. package/runtime/ext_gui/media_api.h +2 -2
  124. package/runtime/ext_gui/media_query.cpp +211 -0
  125. package/runtime/ext_gui/paint.cpp +111 -77
  126. package/runtime/ext_gui/paint.h +33 -3
  127. package/runtime/ext_gui/paint_background.cpp +229 -0
  128. package/runtime/ext_gui/paint_clip.cpp +268 -0
  129. package/runtime/ext_gui/paint_effects.cpp +324 -0
  130. package/runtime/ext_gui/paint_internal.h +85 -0
  131. package/runtime/ext_gui/renderer.cpp +8 -31
  132. package/runtime/ext_gui/renderer_clip.cpp +196 -0
  133. package/runtime/ext_gui/renderer_image.cpp +13 -8
  134. package/runtime/ext_gui/renderer_internal.h +15 -8
  135. package/runtime/ext_gui/renderer_text.cpp +6 -31
  136. package/runtime/ext_gui/style.cpp +343 -20
  137. package/runtime/ext_gui/style.h +144 -3
  138. package/runtime/ext_gui/style_print.cpp +134 -1
  139. package/runtime/ext_gui/style_values.cpp +152 -126
  140. package/runtime/ext_gui/style_values_internal.h +35 -0
  141. package/runtime/ext_gui/webgl.h +466 -0
  142. package/runtime/ext_gui/webgl2_constants.h +274 -0
  143. package/runtime/ext_gui/webgl_buffer.cpp +565 -0
  144. package/runtime/ext_gui/webgl_constants.h +317 -0
  145. package/runtime/ext_gui/webgl_context.cpp +466 -0
  146. package/runtime/ext_gui/webgl_draw.cpp +495 -0
  147. package/runtime/ext_gui/webgl_glsl.h +125 -0
  148. package/runtime/ext_gui/webgl_glsl_compile.cpp +431 -0
  149. package/runtime/ext_gui/webgl_glsl_rewrite.cpp +349 -0
  150. package/runtime/ext_gui/webgl_glsl_scan.cpp +581 -0
  151. package/runtime/ext_gui/webgl_msl.cpp +62 -0
  152. package/runtime/ext_gui/webgl_msl.h +33 -0
  153. package/runtime/ext_gui/webgl_pipeline.cpp +274 -0
  154. package/runtime/ext_gui/webgl_program_internal.h +18 -0
  155. package/runtime/ext_gui/webgl_shader.cpp +582 -0
  156. package/runtime/ext_gui/webgl_texture.cpp +293 -0
  157. package/runtime/ext_gui/webgl_uniform.cpp +167 -0
  158. package/runtime/ext_gui/webgl_webgl2.cpp +224 -0
  159. package/runtime/ext_media/media.cpp +1 -1
  160. package/runtime/ext_media/media_bridge.c +9 -3
  161. package/runtime/rt_internal.h +1 -0
  162. package/runtime/xt_containers/access.inc +8 -0
  163. package/runtime/xt_regex/api.inc +2 -0
  164. package/runtime/xt_regex/matcher.inc +16 -3
  165. package/runtime/xt_regex/parser.inc +8 -2
  166. package/runtime/xt_regex/types.inc +3 -0
  167. package/runtime/xt_stdlib2/regexp-match.inc +60 -21
  168. package/runtime/xt_stdlib2/regexp.inc +1 -0
  169. package/runtime/xt_typed_array.c +1 -1
  170. package/scripts/build-gui.ts +90 -3
  171. package/scripts/build-media.ts +323 -58
  172. package/scripts/setup-vs-toolchain.ps1 +152 -0
  173. package/src/binder/references.ts +13 -1
  174. package/src/codegen/generator/module.ts +50 -0
  175. package/src/codegen/generator/statements/variables.ts +6 -3
  176. package/src/driver/version.ts +1 -1
  177. package/src/extensions/gui/css.ts +113 -0
  178. package/src/extensions/gui/html.ts +9 -2
  179. package/src/extensions/gui/index.ts +16 -2
  180. package/src/extensions/gui/three.ts +25 -0
  181. package/src/extensions/media/index.ts +13 -16
@@ -0,0 +1,466 @@
1
+ /*
2
+ * xbintsc GUI engine — WebGL context lifetime, GPU targets and fixed-function
3
+ * state.
4
+ *
5
+ * Every context records into one SDL_GPU command buffer. A render pass stays
6
+ * open across draws and is ended whenever a copy pass (buffer/texture upload)
7
+ * or a different attachment has to be recorded; the next draw starts a new
8
+ * pass with `LOAD`, so the framebuffer persists like a WebGL drawing buffer.
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) {
50
+ SDL_WaitForGPUIdle(guidev::g_device);
51
+ for (auto &entry : programs_) release_program_pipelines(entry.second.get());
52
+ for (auto &entry : textures_) {
53
+ if (entry.second->gpu != nullptr) SDL_ReleaseGPUTexture(guidev::g_device, entry.second->gpu);
54
+ if (entry.second->sampler != nullptr) {
55
+ SDL_ReleaseGPUSampler(guidev::g_device, entry.second->sampler);
56
+ }
57
+ }
58
+ for (auto &entry : buffers_) {
59
+ if (entry.second->gpu != nullptr) SDL_ReleaseGPUBuffer(guidev::g_device, entry.second->gpu);
60
+ }
61
+ for (auto &entry : samplers_) {
62
+ if (entry.second->gpu != nullptr) {
63
+ SDL_ReleaseGPUSampler(guidev::g_device, entry.second->gpu);
64
+ }
65
+ }
66
+ for (auto &entry : framebuffers_) {
67
+ if (entry.second->depth != nullptr) SDL_ReleaseGPUTexture(guidev::g_device, entry.second->depth);
68
+ }
69
+ for (auto &entry : renderbuffers_) {
70
+ if (entry.second->depth != nullptr) SDL_ReleaseGPUTexture(guidev::g_device, entry.second->depth);
71
+ }
72
+ for (SDL_GPUBuffer *buffer : temp_buffers_) {
73
+ SDL_ReleaseGPUBuffer(guidev::g_device, buffer);
74
+ }
75
+ if (fallback_texture_ != nullptr) SDL_ReleaseGPUTexture(guidev::g_device, fallback_texture_);
76
+ if (fallback_sampler_ != nullptr) SDL_ReleaseGPUSampler(guidev::g_device, fallback_sampler_);
77
+ if (color_ != nullptr) SDL_ReleaseGPUTexture(guidev::g_device, color_);
78
+ if (depth_ != nullptr) SDL_ReleaseGPUTexture(guidev::g_device, depth_);
79
+ }
80
+ g_contexts.erase(id_);
81
+ }
82
+
83
+ /* -- targets ------------------------------------------------------------- */
84
+
85
+ void WebGLContext::ensure_command() {
86
+ if (cmd_ != nullptr || guidev::g_device == nullptr) return;
87
+ cmd_ = SDL_AcquireGPUCommandBuffer(guidev::g_device);
88
+ if (cmd_ == nullptr) {
89
+ lost_ = true;
90
+ set_error(GL_OUT_OF_MEMORY);
91
+ }
92
+ }
93
+
94
+ void WebGLContext::ensure_default_target() {
95
+ if (guidev::g_device == nullptr) return;
96
+ if (color_ != nullptr && depth_ != nullptr) return;
97
+ SDL_GPUTextureCreateInfo info;
98
+ memset(&info, 0, sizeof(info));
99
+ info.type = SDL_GPU_TEXTURETYPE_2D;
100
+ info.format = SDL_GPU_TEXTUREFORMAT_R8G8B8A8_UNORM;
101
+ info.usage = SDL_GPU_TEXTUREUSAGE_SAMPLER | SDL_GPU_TEXTUREUSAGE_COLOR_TARGET;
102
+ info.width = (Uint32)width_;
103
+ info.height = (Uint32)height_;
104
+ info.layer_count_or_depth = 1;
105
+ info.num_levels = 1;
106
+ info.sample_count = SDL_GPU_SAMPLECOUNT_1;
107
+ if (color_ == nullptr) color_ = SDL_CreateGPUTexture(guidev::g_device, &info);
108
+ info.format = SDL_GPU_TEXTUREFORMAT_D32_FLOAT;
109
+ info.usage = SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET;
110
+ if (depth_ == nullptr) depth_ = SDL_CreateGPUTexture(guidev::g_device, &info);
111
+ }
112
+
113
+ void WebGLContext::rebuild_default_target() {
114
+ if (guidev::g_device == nullptr) return;
115
+ end_pass();
116
+ ensure_command();
117
+ if (cmd_ != nullptr) {
118
+ /* Nothing recorded into the old target is worth keeping: a resize discards
119
+ * the drawing buffer, exactly like the DOM `canvas.width = …` rule. */
120
+ SDL_SubmitGPUCommandBuffer(cmd_);
121
+ cmd_ = nullptr;
122
+ }
123
+ SDL_WaitForGPUIdle(guidev::g_device);
124
+ if (color_ != nullptr) SDL_ReleaseGPUTexture(guidev::g_device, color_);
125
+ if (depth_ != nullptr) SDL_ReleaseGPUTexture(guidev::g_device, depth_);
126
+ color_ = nullptr;
127
+ depth_ = nullptr;
128
+ ensure_default_target();
129
+ }
130
+
131
+ SDL_GPUTexture *WebGLContext::color_texture() {
132
+ ensure_default_target();
133
+ return color_;
134
+ }
135
+
136
+ void WebGLContext::resize(int width, int height) {
137
+ if (width < 0) width = 0;
138
+ if (height < 0) height = 0;
139
+ width_ = width > 0 ? width : 1;
140
+ height_ = height > 0 ? height : 1;
141
+ viewport_[0] = 0;
142
+ viewport_[1] = 0;
143
+ viewport_[2] = width_;
144
+ viewport_[3] = height_;
145
+ scissor_box_[0] = 0;
146
+ scissor_box_[1] = 0;
147
+ scissor_box_[2] = width_;
148
+ scissor_box_[3] = height_;
149
+ rebuild_default_target();
150
+ }
151
+
152
+ void WebGLContext::submit() {
153
+ end_pass();
154
+ if (cmd_ != nullptr) {
155
+ SDL_SubmitGPUCommandBuffer(cmd_);
156
+ cmd_ = nullptr;
157
+ }
158
+ }
159
+
160
+ /* -- passes -------------------------------------------------------------- */
161
+
162
+ SDL_GPUTexture *WebGLContext::target_color() {
163
+ if (bound_framebuffer_ == 0) {
164
+ ensure_default_target();
165
+ return color_;
166
+ }
167
+ WebGLFramebuffer *framebuffer = this->framebuffer(bound_framebuffer_);
168
+ if (framebuffer == nullptr || framebuffer->color_texture == 0) return nullptr;
169
+ WebGLTexture *texture = this->texture(framebuffer->color_texture);
170
+ if (texture == nullptr) return nullptr;
171
+ return ensure_texture_gpu(texture, true);
172
+ }
173
+
174
+ SDL_GPUTexture *WebGLContext::target_depth() {
175
+ if (bound_framebuffer_ == 0) {
176
+ ensure_default_target();
177
+ return depth_;
178
+ }
179
+ WebGLFramebuffer *framebuffer = this->framebuffer(bound_framebuffer_);
180
+ if (framebuffer == nullptr) return nullptr;
181
+ if (framebuffer->depth == nullptr && framebuffer->depth_renderbuffer == 0 &&
182
+ framebuffer->width > 0 && framebuffer->height > 0 && guidev::g_device != nullptr) {
183
+ SDL_GPUTextureCreateInfo info;
184
+ memset(&info, 0, sizeof(info));
185
+ info.type = SDL_GPU_TEXTURETYPE_2D;
186
+ info.format = SDL_GPU_TEXTUREFORMAT_D32_FLOAT;
187
+ info.usage = SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET;
188
+ info.width = (Uint32)framebuffer->width;
189
+ info.height = (Uint32)framebuffer->height;
190
+ info.layer_count_or_depth = 1;
191
+ info.num_levels = 1;
192
+ info.sample_count = SDL_GPU_SAMPLECOUNT_1;
193
+ framebuffer->depth = SDL_CreateGPUTexture(guidev::g_device, &info);
194
+ }
195
+ return framebuffer->depth;
196
+ }
197
+
198
+ void WebGLContext::end_pass() {
199
+ if (pass_ != nullptr && cmd_ != nullptr) {
200
+ SDL_EndGPURenderPass(pass_);
201
+ pass_ = nullptr;
202
+ }
203
+ }
204
+
205
+ void WebGLContext::begin_pass(bool clear_color, bool clear_depth) {
206
+ if (guidev::g_device == nullptr) return;
207
+ if (pass_ != nullptr && pass_targets_default_ == (bound_framebuffer_ == 0) &&
208
+ pass_framebuffer_ == bound_framebuffer_ && !clear_color && !clear_depth) {
209
+ return;
210
+ }
211
+ end_pass();
212
+ ensure_command();
213
+ if (cmd_ == nullptr) return;
214
+ SDL_GPUTexture *color = target_color();
215
+ SDL_GPUTexture *depth = target_depth();
216
+ if (color == nullptr) {
217
+ set_error(GL_INVALID_FRAMEBUFFER_OPERATION);
218
+ return;
219
+ }
220
+ SDL_GPUColorTargetInfo color_info;
221
+ memset(&color_info, 0, sizeof(color_info));
222
+ color_info.texture = color;
223
+ color_info.clear_color.r = clear_color_[0];
224
+ color_info.clear_color.g = clear_color_[1];
225
+ color_info.clear_color.b = clear_color_[2];
226
+ color_info.clear_color.a = clear_color_[3];
227
+ color_info.load_op = clear_color ? SDL_GPU_LOADOP_CLEAR : SDL_GPU_LOADOP_LOAD;
228
+ color_info.store_op = SDL_GPU_STOREOP_STORE;
229
+
230
+ SDL_GPUDepthStencilTargetInfo depth_info;
231
+ memset(&depth_info, 0, sizeof(depth_info));
232
+ depth_info.texture = depth;
233
+ depth_info.clear_depth = clear_depth_;
234
+ depth_info.load_op = (clear_depth && depth != nullptr) ? SDL_GPU_LOADOP_CLEAR
235
+ : SDL_GPU_LOADOP_LOAD;
236
+ depth_info.store_op = SDL_GPU_STOREOP_STORE;
237
+ depth_info.stencil_load_op = SDL_GPU_LOADOP_DONT_CARE;
238
+ depth_info.stencil_store_op = SDL_GPU_STOREOP_DONT_CARE;
239
+
240
+ pass_ = SDL_BeginGPURenderPass(cmd_, &color_info, 1, depth != nullptr ? &depth_info : nullptr);
241
+ pass_targets_default_ = bound_framebuffer_ == 0;
242
+ pass_framebuffer_ = bound_framebuffer_;
243
+ }
244
+
245
+ /* -- state --------------------------------------------------------------- */
246
+
247
+ void WebGLContext::enable(int cap) {
248
+ if (cap == GL_BLEND) state_.blend = true;
249
+ if (cap == GL_DEPTH_TEST) state_.depth_test = true;
250
+ if (cap == GL_CULL_FACE) state_.cull = true;
251
+ if (cap == GL_SCISSOR_TEST) scissor_test_ = true;
252
+ if (cap == GL_STENCIL_TEST) stencil_test_ = true;
253
+ }
254
+
255
+ void WebGLContext::disable(int cap) {
256
+ if (cap == GL_BLEND) state_.blend = false;
257
+ if (cap == GL_DEPTH_TEST) state_.depth_test = false;
258
+ if (cap == GL_CULL_FACE) state_.cull = false;
259
+ if (cap == GL_SCISSOR_TEST) scissor_test_ = false;
260
+ if (cap == GL_STENCIL_TEST) stencil_test_ = false;
261
+ }
262
+
263
+ bool WebGLContext::is_enabled(int cap) const {
264
+ if (cap == GL_BLEND) return state_.blend;
265
+ if (cap == GL_DEPTH_TEST) return state_.depth_test;
266
+ if (cap == GL_CULL_FACE) return state_.cull;
267
+ if (cap == GL_SCISSOR_TEST) return scissor_test_;
268
+ if (cap == GL_STENCIL_TEST) return stencil_test_;
269
+ return false;
270
+ }
271
+
272
+ void WebGLContext::clear_color(float r, float g, float b, float a) {
273
+ clear_color_[0] = r;
274
+ clear_color_[1] = g;
275
+ clear_color_[2] = b;
276
+ clear_color_[3] = a;
277
+ }
278
+
279
+ void WebGLContext::color_mask(bool r, bool g, bool b, bool a) {
280
+ state_.color_mask[0] = r;
281
+ state_.color_mask[1] = g;
282
+ state_.color_mask[2] = b;
283
+ state_.color_mask[3] = a;
284
+ }
285
+
286
+ void WebGLContext::blend_func(int src, int dst) {
287
+ state_.blend_src_rgb = src;
288
+ state_.blend_dst_rgb = dst;
289
+ state_.blend_src_alpha = src;
290
+ state_.blend_dst_alpha = dst;
291
+ }
292
+
293
+ void WebGLContext::blend_func_separate(int src_rgb, int dst_rgb, int src_alpha, int dst_alpha) {
294
+ state_.blend_src_rgb = src_rgb;
295
+ state_.blend_dst_rgb = dst_rgb;
296
+ state_.blend_src_alpha = src_alpha;
297
+ state_.blend_dst_alpha = dst_alpha;
298
+ }
299
+
300
+ void WebGLContext::blend_equation(int mode) {
301
+ state_.blend_eq_rgb = mode;
302
+ state_.blend_eq_alpha = mode;
303
+ }
304
+
305
+ void WebGLContext::blend_equation_separate(int rgb, int alpha) {
306
+ state_.blend_eq_rgb = rgb;
307
+ state_.blend_eq_alpha = alpha;
308
+ }
309
+
310
+ void WebGLContext::cull_face(int mode) { state_.cull_face = mode; }
311
+
312
+ void WebGLContext::front_face(int mode) { state_.front_face = mode; }
313
+
314
+ void WebGLContext::viewport(int x, int y, int w, int h) {
315
+ viewport_[0] = x;
316
+ viewport_[1] = y;
317
+ viewport_[2] = w;
318
+ viewport_[3] = h;
319
+ }
320
+
321
+ void WebGLContext::scissor(int x, int y, int w, int h) {
322
+ scissor_box_[0] = x;
323
+ scissor_box_[1] = y;
324
+ scissor_box_[2] = w;
325
+ scissor_box_[3] = h;
326
+ }
327
+
328
+ void WebGLContext::clear(int mask) {
329
+ if (guidev::g_device == nullptr) return;
330
+ const bool color_bit = (mask & GL_COLOR_BUFFER_BIT) != 0;
331
+ const bool depth_bit = (mask & GL_DEPTH_BUFFER_BIT) != 0;
332
+ /* The scissor rectangle is not honoured by a pass-begin clear; WebGL pages
333
+ * that clear a sub-rectangle are rare and documented as a limitation. */
334
+ begin_pass(color_bit, depth_bit);
335
+ }
336
+
337
+ void WebGLContext::finish() {
338
+ submit();
339
+ if (guidev::g_device != nullptr) SDL_WaitForGPUIdle(guidev::g_device);
340
+ }
341
+
342
+ /* -- queries ------------------------------------------------------------- */
343
+
344
+ double WebGLContext::parameter(int pname) {
345
+ switch (pname) {
346
+ case GL_MAX_TEXTURE_SIZE:
347
+ return 8192;
348
+ case GL_MAX_VERTEX_ATTRIBS:
349
+ return kWebGLMaxAttribs;
350
+ case GL_MAX_TEXTURE_IMAGE_UNITS:
351
+ return kWebGLMaxTextureUnits;
352
+ case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
353
+ return kWebGLMaxTextureUnits * 2;
354
+ case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
355
+ return 0;
356
+ case GL_MAX_VERTEX_UNIFORM_VECTORS:
357
+ case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
358
+ case GL_MAX_VARYING_VECTORS:
359
+ return 256;
360
+ case GL_MAX_RENDERBUFFER_SIZE:
361
+ return 8192;
362
+ case GL_MAX_VIEWPORT_DIMS:
363
+ return 8192;
364
+ case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
365
+ return 0;
366
+ case GL_SAMPLES:
367
+ case GL_SAMPLE_BUFFERS:
368
+ return 0;
369
+ case GL_SUBPIXEL_BITS:
370
+ return 4;
371
+ case GL_RED_BITS:
372
+ case GL_GREEN_BITS:
373
+ case GL_BLUE_BITS:
374
+ case GL_ALPHA_BITS:
375
+ case GL_DEPTH_BITS:
376
+ return 8;
377
+ case GL_STENCIL_BITS:
378
+ return 0;
379
+ case GL_UNPACK_ALIGNMENT:
380
+ case GL_PACK_ALIGNMENT:
381
+ return 4;
382
+ case GL_ACTIVE_TEXTURE:
383
+ return active_unit_ + GL_TEXTURE0;
384
+ case GL_CURRENT_PROGRAM:
385
+ return current_program_;
386
+ case GL_DEPTH_CLEAR_VALUE:
387
+ return clear_depth_;
388
+ case GL_STENCIL_CLEAR_VALUE:
389
+ return clear_stencil_;
390
+ /* -- WebGL 2 --------------------------------------------------------- */
391
+ case GL_MAX_3D_TEXTURE_SIZE:
392
+ return 2048;
393
+ case GL_MAX_ARRAY_TEXTURE_LAYERS:
394
+ return 256;
395
+ case GL_MAX_DRAW_BUFFERS:
396
+ case GL_MAX_COLOR_ATTACHMENTS:
397
+ return 1;
398
+ case GL_MAX_SAMPLES:
399
+ return 0;
400
+ case GL_MAX_UNIFORM_BUFFER_BINDINGS:
401
+ case GL_MAX_VERTEX_UNIFORM_BLOCKS:
402
+ case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
403
+ return 0;
404
+ case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
405
+ return 256;
406
+ case GL_MAX_ELEMENT_INDEX:
407
+ return 4294967295.0;
408
+ case GL_MAX_CLIENT_WAIT_TIMEOUT_WEBGL:
409
+ return 0;
410
+ case GL_MAX_VARYING_COMPONENTS:
411
+ case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
412
+ return 60;
413
+ case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
414
+ return 64;
415
+ case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
416
+ case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
417
+ case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
418
+ case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
419
+ return 1024;
420
+ case GL_MAX_UNIFORM_BLOCK_SIZE:
421
+ return 16384;
422
+ case GL_READ_BUFFER:
423
+ case GL_DRAW_BUFFER0:
424
+ return GL_BACK;
425
+ default:
426
+ return 0;
427
+ }
428
+ }
429
+
430
+ std::string WebGLContext::string_parameter(int pname) {
431
+ const char *driver_name = driver();
432
+ switch (pname) {
433
+ case GL_VENDOR:
434
+ return "xbintsc";
435
+ case GL_RENDERER:
436
+ return std::string("xbintsc gui (SDL_GPU ") + (driver_name != nullptr ? driver_name : "?") +
437
+ ")";
438
+ case GL_VERSION:
439
+ return webgl2_ ? "WebGL 2.0 (xbintsc)" : "WebGL 1.0 (xbintsc)";
440
+ case GL_SHADING_LANGUAGE_VERSION:
441
+ return webgl2_ ? "WebGL GLSL ES 3.00 (xbintsc)" : "WebGL GLSL ES 1.0 (xbintsc)";
442
+ default:
443
+ return std::string();
444
+ }
445
+ }
446
+
447
+ const char *WebGLContext::driver() const {
448
+ return xt_gui_driver();
449
+ }
450
+
451
+ uint32_t WebGLContext::bound_buffer(int target) const { return buffer_for_target(target); }
452
+
453
+ uint32_t WebGLContext::bound_texture(int unit) const {
454
+ if (unit < 0 || unit >= kWebGLMaxTextureUnits) return 0;
455
+ return bound_textures_[unit];
456
+ }
457
+
458
+ void WebGLContext::viewport_box(int out[4]) const {
459
+ for (int i = 0; i < 4; i++) out[i] = viewport_[i];
460
+ }
461
+
462
+ void WebGLContext::scissor_box(int out[4]) const {
463
+ for (int i = 0; i < 4; i++) out[i] = scissor_box_[i];
464
+ }
465
+
466
+ } // namespace xtgui