@codexo/exojs 0.12.0 → 0.13.0

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 (101) hide show
  1. package/CHANGELOG.md +125 -0
  2. package/dist/esm/core/BuildInfo.js +2 -2
  3. package/dist/esm/extensions/Extension.d.ts +39 -7
  4. package/dist/esm/extensions/Extension.d.ts.map +1 -1
  5. package/dist/esm/extensions/ExtensionRegistry.d.ts.map +1 -1
  6. package/dist/esm/extensions/ExtensionRegistry.js.map +1 -1
  7. package/dist/esm/extensions/snapshot.d.ts +12 -2
  8. package/dist/esm/extensions/snapshot.d.ts.map +1 -1
  9. package/dist/esm/extensions/snapshot.js +43 -14
  10. package/dist/esm/extensions/snapshot.js.map +1 -1
  11. package/dist/esm/index.js +8 -0
  12. package/dist/esm/index.js.map +1 -1
  13. package/dist/esm/rendering/Drawable.d.ts +23 -0
  14. package/dist/esm/rendering/Drawable.d.ts.map +1 -1
  15. package/dist/esm/rendering/Drawable.js +34 -0
  16. package/dist/esm/rendering/Drawable.js.map +1 -1
  17. package/dist/esm/rendering/coreRendererBindings.d.ts.map +1 -1
  18. package/dist/esm/rendering/coreRendererBindings.js +22 -0
  19. package/dist/esm/rendering/coreRendererBindings.js.map +1 -1
  20. package/dist/esm/rendering/index.d.ts +13 -0
  21. package/dist/esm/rendering/index.d.ts.map +1 -1
  22. package/dist/esm/rendering/pixelSnap.d.ts +219 -0
  23. package/dist/esm/rendering/pixelSnap.d.ts.map +1 -0
  24. package/dist/esm/rendering/pixelSnap.js +186 -0
  25. package/dist/esm/rendering/pixelSnap.js.map +1 -0
  26. package/dist/esm/rendering/plan/RenderPlanPlayer.d.ts.map +1 -1
  27. package/dist/esm/rendering/plan/RenderPlanPlayer.js +21 -1
  28. package/dist/esm/rendering/plan/RenderPlanPlayer.js.map +1 -1
  29. package/dist/esm/rendering/sprite/NineSliceSprite.d.ts +69 -0
  30. package/dist/esm/rendering/sprite/NineSliceSprite.d.ts.map +1 -0
  31. package/dist/esm/rendering/sprite/NineSliceSprite.js +207 -0
  32. package/dist/esm/rendering/sprite/NineSliceSprite.js.map +1 -0
  33. package/dist/esm/rendering/sprite/RepeatingSprite.d.ts +120 -0
  34. package/dist/esm/rendering/sprite/RepeatingSprite.d.ts.map +1 -0
  35. package/dist/esm/rendering/sprite/RepeatingSprite.js +279 -0
  36. package/dist/esm/rendering/sprite/RepeatingSprite.js.map +1 -0
  37. package/dist/esm/rendering/sprite/Sprite.d.ts +13 -0
  38. package/dist/esm/rendering/sprite/Sprite.d.ts.map +1 -1
  39. package/dist/esm/rendering/sprite/Sprite.js +23 -0
  40. package/dist/esm/rendering/sprite/Sprite.js.map +1 -1
  41. package/dist/esm/rendering/sprite/nineSlice.d.ts +53 -0
  42. package/dist/esm/rendering/sprite/nineSlice.d.ts.map +1 -0
  43. package/dist/esm/rendering/sprite/nineSlice.js +340 -0
  44. package/dist/esm/rendering/sprite/nineSlice.js.map +1 -0
  45. package/dist/esm/rendering/sprite/repeatingSpritePlan.d.ts +57 -0
  46. package/dist/esm/rendering/sprite/repeatingSpritePlan.d.ts.map +1 -0
  47. package/dist/esm/rendering/sprite/repeatingSpritePlan.js +156 -0
  48. package/dist/esm/rendering/sprite/repeatingSpritePlan.js.map +1 -0
  49. package/dist/esm/rendering/texture/TextureRegion.d.ts +100 -0
  50. package/dist/esm/rendering/texture/TextureRegion.d.ts.map +1 -0
  51. package/dist/esm/rendering/texture/TextureRegion.js +144 -0
  52. package/dist/esm/rendering/texture/TextureRegion.js.map +1 -0
  53. package/dist/esm/rendering/texture/repeat.d.ts +96 -0
  54. package/dist/esm/rendering/texture/repeat.d.ts.map +1 -0
  55. package/dist/esm/rendering/texture/repeat.js +158 -0
  56. package/dist/esm/rendering/texture/repeat.js.map +1 -0
  57. package/dist/esm/rendering/webgl2/WebGl2Backend.d.ts +20 -0
  58. package/dist/esm/rendering/webgl2/WebGl2Backend.d.ts.map +1 -1
  59. package/dist/esm/rendering/webgl2/WebGl2Backend.js +31 -2
  60. package/dist/esm/rendering/webgl2/WebGl2Backend.js.map +1 -1
  61. package/dist/esm/rendering/webgl2/WebGl2NineSliceSpriteRenderer.d.ts +32 -0
  62. package/dist/esm/rendering/webgl2/WebGl2NineSliceSpriteRenderer.d.ts.map +1 -0
  63. package/dist/esm/rendering/webgl2/WebGl2NineSliceSpriteRenderer.js +308 -0
  64. package/dist/esm/rendering/webgl2/WebGl2NineSliceSpriteRenderer.js.map +1 -0
  65. package/dist/esm/rendering/webgl2/WebGl2RepeatingSpriteRenderer.d.ts +49 -0
  66. package/dist/esm/rendering/webgl2/WebGl2RepeatingSpriteRenderer.d.ts.map +1 -0
  67. package/dist/esm/rendering/webgl2/WebGl2RepeatingSpriteRenderer.js +535 -0
  68. package/dist/esm/rendering/webgl2/WebGl2RepeatingSpriteRenderer.js.map +1 -0
  69. package/dist/esm/rendering/webgl2/WebGl2SpriteRenderer.d.ts +9 -0
  70. package/dist/esm/rendering/webgl2/WebGl2SpriteRenderer.d.ts.map +1 -1
  71. package/dist/esm/rendering/webgl2/WebGl2SpriteRenderer.js +22 -2
  72. package/dist/esm/rendering/webgl2/WebGl2SpriteRenderer.js.map +1 -1
  73. package/dist/esm/rendering/webgpu/WebGpuBackend.d.ts +21 -1
  74. package/dist/esm/rendering/webgpu/WebGpuBackend.d.ts.map +1 -1
  75. package/dist/esm/rendering/webgpu/WebGpuBackend.js +29 -2
  76. package/dist/esm/rendering/webgpu/WebGpuBackend.js.map +1 -1
  77. package/dist/esm/rendering/webgpu/WebGpuNineSliceSpriteRenderer.d.ts +36 -0
  78. package/dist/esm/rendering/webgpu/WebGpuNineSliceSpriteRenderer.d.ts.map +1 -0
  79. package/dist/esm/rendering/webgpu/WebGpuNineSliceSpriteRenderer.js +358 -0
  80. package/dist/esm/rendering/webgpu/WebGpuNineSliceSpriteRenderer.js.map +1 -0
  81. package/dist/esm/rendering/webgpu/WebGpuRepeatingSpriteRenderer.d.ts +52 -0
  82. package/dist/esm/rendering/webgpu/WebGpuRepeatingSpriteRenderer.d.ts.map +1 -0
  83. package/dist/esm/rendering/webgpu/WebGpuRepeatingSpriteRenderer.js +556 -0
  84. package/dist/esm/rendering/webgpu/WebGpuRepeatingSpriteRenderer.js.map +1 -0
  85. package/dist/esm/rendering/webgpu/WebGpuSpriteRenderer.d.ts +9 -0
  86. package/dist/esm/rendering/webgpu/WebGpuSpriteRenderer.d.ts.map +1 -1
  87. package/dist/esm/rendering/webgpu/WebGpuSpriteRenderer.js +22 -2
  88. package/dist/esm/rendering/webgpu/WebGpuSpriteRenderer.js.map +1 -1
  89. package/dist/esm/rendering/webgpu/WebGpuTransformStorage.d.ts +3 -2
  90. package/dist/esm/rendering/webgpu/WebGpuTransformStorage.d.ts.map +1 -1
  91. package/dist/esm/rendering/webgpu/WebGpuTransformStorage.js +4 -4
  92. package/dist/esm/rendering/webgpu/WebGpuTransformStorage.js.map +1 -1
  93. package/dist/esm/rendering.d.ts +1 -0
  94. package/dist/esm/rendering.d.ts.map +1 -1
  95. package/dist/esm/resources/Loader.d.ts +36 -8
  96. package/dist/esm/resources/Loader.d.ts.map +1 -1
  97. package/dist/esm/resources/Loader.js +30 -11
  98. package/dist/esm/resources/Loader.js.map +1 -1
  99. package/dist/exo.esm.js +3449 -59
  100. package/dist/exo.esm.js.map +1 -1
  101. package/package.json +10 -3
@@ -0,0 +1,535 @@
1
+ import { Rectangle } from '../../math/Rectangle.js';
2
+ import { Shader } from '../shader/Shader.js';
3
+ import { computeShaderTiling } from '../sprite/repeatingSpritePlan.js';
4
+ import { Texture } from '../texture/Texture.js';
5
+ import { ScaleModes, RenderingPrimitives, BufferTypes, BufferUsage, WrapModes } from '../types.js';
6
+ import { AbstractWebGl2Renderer } from './AbstractWebGl2Renderer.js';
7
+ import { WebGl2RenderBuffer } from './WebGl2RenderBuffer.js';
8
+ import { createWebGl2ShaderProgram } from './WebGl2ShaderProgram.js';
9
+ import { WebGl2VertexArrayObject } from './WebGl2VertexArrayObject.js';
10
+
11
+ // ---------------------------------------------------------------------------
12
+ // Shader path: one quad per sprite, UVs computed in vertex shader.
13
+ // ---------------------------------------------------------------------------
14
+ const shaderPathVertSource = `#version 300 es
15
+ precision mediump float;
16
+ precision highp int;
17
+
18
+ layout(location = 0) in vec4 a_quadBounds; // x0,y0,x1,y1 (local space)
19
+ layout(location = 1) in vec4 a_uvParams; // tilingX, tilingY, offsetU, offsetV
20
+ layout(location = 2) in vec4 a_color; // RGBA tint (normalised)
21
+ layout(location = 3) in uint a_nodeIndex; // transform row
22
+
23
+ uniform mat3 u_projection;
24
+ uniform sampler2D u_transforms;
25
+
26
+ out vec2 v_texcoord;
27
+ out vec4 v_color;
28
+
29
+ void main(void) {
30
+ int vid = gl_VertexID;
31
+ int cx = vid & 1;
32
+ int cy = (vid >> 1) & 1;
33
+
34
+ float lx = (cx == 0) ? a_quadBounds.x : a_quadBounds.z;
35
+ float ly = (cy == 0) ? a_quadBounds.y : a_quadBounds.w;
36
+
37
+ float destW = a_quadBounds.z - a_quadBounds.x;
38
+ float destH = a_quadBounds.w - a_quadBounds.y;
39
+
40
+ int row = int(a_nodeIndex);
41
+ vec4 m0 = texelFetch(u_transforms, ivec2(0, row), 0);
42
+ vec4 m1 = texelFetch(u_transforms, ivec2(1, row), 0);
43
+
44
+ float wx = m0.x * lx + m0.y * ly + m1.x;
45
+ float wy = m0.z * lx + m0.w * ly + m1.y;
46
+ gl_Position = vec4((u_projection * vec3(wx, wy, 1.0)).xy, 0.0, 1.0);
47
+
48
+ float u = (destW > 0.0)
49
+ ? ((lx - a_quadBounds.x) / destW) * a_uvParams.x + a_uvParams.z
50
+ : a_uvParams.z;
51
+ float v = (destH > 0.0)
52
+ ? ((ly - a_quadBounds.y) / destH) * a_uvParams.y + a_uvParams.w
53
+ : a_uvParams.w;
54
+ v_texcoord = vec2(u, v);
55
+
56
+ v_color = vec4(a_color.rgb * a_color.a, a_color.a);
57
+ }`;
58
+ // ---------------------------------------------------------------------------
59
+ // Geometry path: N quads per sprite, UVs pre-computed in CPU (like NineSlice).
60
+ // ---------------------------------------------------------------------------
61
+ const geoPathVertSource = `#version 300 es
62
+ precision lowp float;
63
+ precision highp int;
64
+
65
+ layout(location = 0) in vec4 a_quadBounds; // x0,y0,x1,y1 (local space)
66
+ layout(location = 1) in vec4 a_uvBounds; // u0,v0,u1,v1 (normalised, flipY pre-applied)
67
+ layout(location = 2) in vec4 a_color; // RGBA tint
68
+ layout(location = 3) in uint a_nodeIndex; // transform row
69
+
70
+ uniform mat3 u_projection;
71
+ uniform sampler2D u_transforms;
72
+
73
+ out vec2 v_texcoord;
74
+ out vec4 v_color;
75
+
76
+ void main(void) {
77
+ int vid = gl_VertexID;
78
+ int cx = vid & 1;
79
+ int cy = (vid >> 1) & 1;
80
+
81
+ float lx = (cx == 0) ? a_quadBounds.x : a_quadBounds.z;
82
+ float ly = (cy == 0) ? a_quadBounds.y : a_quadBounds.w;
83
+
84
+ int row = int(a_nodeIndex);
85
+ vec4 m0 = texelFetch(u_transforms, ivec2(0, row), 0);
86
+ vec4 m1 = texelFetch(u_transforms, ivec2(1, row), 0);
87
+
88
+ float wx = m0.x * lx + m0.y * ly + m1.x;
89
+ float wy = m0.z * lx + m0.w * ly + m1.y;
90
+ gl_Position = vec4((u_projection * vec3(wx, wy, 1.0)).xy, 0.0, 1.0);
91
+
92
+ float u = (cx == 0) ? a_uvBounds.x : a_uvBounds.z;
93
+ float v = (cy == 0) ? a_uvBounds.y : a_uvBounds.w;
94
+ v_texcoord = vec2(u, v);
95
+
96
+ v_color = vec4(a_color.rgb * a_color.a, a_color.a);
97
+ }`;
98
+ const sharedFragSource = `#version 300 es
99
+ precision lowp float;
100
+
101
+ uniform sampler2D u_texture;
102
+
103
+ in vec2 v_texcoord;
104
+ in vec4 v_color;
105
+
106
+ layout(location = 0) out vec4 fragColor;
107
+
108
+ void main(void) {
109
+ fragColor = texture(u_texture, v_texcoord) * v_color;
110
+ }`;
111
+ // ---------------------------------------------------------------------------
112
+ // Layout constants
113
+ // ---------------------------------------------------------------------------
114
+ const shaderStrideBytes = 40; // 10 × float32
115
+ const shaderWordsPerInstance = shaderStrideBytes / Uint32Array.BYTES_PER_ELEMENT;
116
+ const geoStrideBytes = 32; // 8 × uint32 (matches NineSlice layout)
117
+ const geoWordsPerInstance = geoStrideBytes / Uint32Array.BYTES_PER_ELEMENT;
118
+ const transformTextureUnit = 1;
119
+ // ---------------------------------------------------------------------------
120
+ // Sampler cache helper
121
+ // ---------------------------------------------------------------------------
122
+ function repeatModeToWrap(mode) {
123
+ if (mode === 'repeat')
124
+ return WrapModes.Repeat;
125
+ if (mode === 'mirror-repeat')
126
+ return WrapModes.MirroredRepeat;
127
+ return WrapModes.ClampToEdge;
128
+ }
129
+ /** Instanced renderer for {@link RepeatingSprite} using WebGL2. Handles both shader and geometry paths internally. */
130
+ class WebGl2RepeatingSpriteRenderer extends AbstractWebGl2Renderer {
131
+ _shaderPathShader;
132
+ _geoPathShader;
133
+ _batchSize;
134
+ // Shader-path buffers
135
+ _shaderData;
136
+ _shaderF32;
137
+ _shaderU32;
138
+ _shaderBuf = null;
139
+ _shaderVao = null;
140
+ _shaderQuadCount = 0;
141
+ // Geometry-path buffers
142
+ _geoData;
143
+ _geoF32;
144
+ _geoU32;
145
+ _geoBuf = null;
146
+ _geoVao = null;
147
+ _geoQuadCount = 0;
148
+ // Sampler cache keyed by "wrapS:wrapT:scaleMode"
149
+ _samplers = new Map();
150
+ // Shared batch state
151
+ _maxNodeIndex = 0;
152
+ _currentTexture = null;
153
+ _currentBlendMode = null;
154
+ _currentModeX = null;
155
+ _currentModeY = null;
156
+ _currentPath = null;
157
+ _connection = null;
158
+ _transformUnitScratch = new Int32Array([transformTextureUnit]);
159
+ _snapBounds = new Rectangle();
160
+ _currentView = null;
161
+ _currentViewId = -1;
162
+ constructor(batchSize) {
163
+ super();
164
+ this._batchSize = batchSize;
165
+ this._shaderPathShader = new Shader(shaderPathVertSource, sharedFragSource);
166
+ this._geoPathShader = new Shader(geoPathVertSource, sharedFragSource);
167
+ this._shaderData = new ArrayBuffer(batchSize * shaderStrideBytes);
168
+ this._shaderF32 = new Float32Array(this._shaderData);
169
+ this._shaderU32 = new Uint32Array(this._shaderData);
170
+ this._geoData = new ArrayBuffer(batchSize * geoStrideBytes);
171
+ this._geoF32 = new Float32Array(this._geoData);
172
+ this._geoU32 = new Uint32Array(this._geoData);
173
+ }
174
+ render(sprite) {
175
+ const strategy = sprite.resolvedStrategy;
176
+ const texture = sprite.texture;
177
+ const blendMode = sprite.blendMode;
178
+ const modeX = sprite.modeX;
179
+ const modeY = sprite.modeY;
180
+ const hasData = this._shaderQuadCount > 0 || this._geoQuadCount > 0;
181
+ if (hasData) {
182
+ const pathChanged = this._currentPath !== strategy;
183
+ const texChanged = this._currentTexture !== texture;
184
+ const blendChanged = this._currentBlendMode !== blendMode;
185
+ const modeChanged = strategy === 'shader'
186
+ && (this._currentModeX !== modeX || this._currentModeY !== modeY);
187
+ if (pathChanged || texChanged || blendChanged || modeChanged) {
188
+ this.flush();
189
+ }
190
+ }
191
+ const backend = this.getBackend();
192
+ if (this._currentTexture !== texture) {
193
+ this._currentTexture = texture;
194
+ backend.bindTexture(texture, 0);
195
+ }
196
+ if (this._currentBlendMode !== blendMode) {
197
+ this._currentBlendMode = blendMode;
198
+ backend.setBlendMode(blendMode);
199
+ }
200
+ this._currentPath = strategy;
201
+ const command = backend.activeDrawCommand;
202
+ const nodeIndex = command !== null ? command.nodeIndex : backend._pushTransform(sprite);
203
+ if (nodeIndex > this._maxNodeIndex) {
204
+ this._maxNodeIndex = nodeIndex;
205
+ }
206
+ if (strategy === 'shader') {
207
+ this._currentModeX = modeX;
208
+ this._currentModeY = modeY;
209
+ this._writeShaderInstance(sprite, nodeIndex);
210
+ }
211
+ else {
212
+ this._writeGeoQuads(sprite, nodeIndex);
213
+ }
214
+ }
215
+ _writeShaderInstance(sprite, nodeIndex) {
216
+ const texture = sprite.texture;
217
+ const srcW = sprite.region.width;
218
+ const srcH = sprite.region.height;
219
+ let destW = sprite.width;
220
+ let destH = sprite.height;
221
+ const flipY = texture instanceof Texture && texture.flipY;
222
+ // 'geometry' mode: snap the destination quad to the device grid. Repetition
223
+ // stays shader-based; only the outer rectangle (and the tiling derived from
224
+ // it) moves. Position/none leave the destination unchanged.
225
+ if (sprite.pixelSnapMode === 'geometry') {
226
+ const backend = this.getBackend();
227
+ const snap = backend._getSnapPixelSize();
228
+ const rb = sprite.getRenderBounds(backend.view, snap.width, snap.height, this._snapBounds);
229
+ destW = rb.width;
230
+ destH = rb.height;
231
+ }
232
+ const tilingX = computeShaderTiling(srcW, destW, sprite.modeX, sprite.fitX);
233
+ const tilingY = computeShaderTiling(srcH, destH, sprite.modeY, sprite.fitY);
234
+ const offsetU = sprite.offsetX / (srcW > 0 ? srcW : 1);
235
+ const offsetV = sprite.offsetY / (srcH > 0 ? srcH : 1);
236
+ // When flipY, negate tilingY and start from tilingY so V runs top→bottom.
237
+ const uvParamY = flipY ? -tilingY : tilingY;
238
+ const uvParamW = flipY ? tilingY + offsetV : offsetV;
239
+ if (this._shaderQuadCount >= this._batchSize) {
240
+ this.flush();
241
+ }
242
+ const idx = this._shaderQuadCount * shaderWordsPerInstance;
243
+ const f32 = this._shaderF32;
244
+ const u32 = this._shaderU32;
245
+ f32[idx + 0] = 0;
246
+ f32[idx + 1] = 0;
247
+ f32[idx + 2] = destW;
248
+ f32[idx + 3] = destH;
249
+ f32[idx + 4] = tilingX;
250
+ f32[idx + 5] = uvParamY;
251
+ f32[idx + 6] = offsetU;
252
+ f32[idx + 7] = uvParamW;
253
+ u32[idx + 8] = sprite.tint.toRgba();
254
+ u32[idx + 9] = nodeIndex >>> 0;
255
+ this._shaderQuadCount++;
256
+ }
257
+ _writeGeoQuads(sprite, nodeIndex) {
258
+ let quads = sprite.quads;
259
+ // 'geometry' mode: snap shared segment boundaries once (gap-free), like NineSlice.
260
+ if (sprite.pixelSnapMode === 'geometry') {
261
+ const backend = this.getBackend();
262
+ const snap = backend._getSnapPixelSize();
263
+ quads = sprite.getRenderQuads(backend.view, snap.width, snap.height);
264
+ }
265
+ const flipY = (sprite.texture instanceof Texture) && sprite.texture.flipY;
266
+ const tint = sprite.tint.toRgba();
267
+ let offset = 0;
268
+ while (offset < quads.length) {
269
+ const remaining = quads.length - offset;
270
+ const chunk = Math.min(remaining, this._batchSize - this._geoQuadCount);
271
+ if (chunk <= 0) {
272
+ this.flush();
273
+ // Re-establish texture/blend after flush
274
+ const backend = this.getBackend();
275
+ backend.bindTexture(sprite.texture, 0);
276
+ backend.setBlendMode(sprite.blendMode);
277
+ this._currentTexture = sprite.texture;
278
+ this._currentBlendMode = sprite.blendMode;
279
+ this._currentPath = 'geometry';
280
+ if (nodeIndex > this._maxNodeIndex) {
281
+ this._maxNodeIndex = nodeIndex;
282
+ }
283
+ continue;
284
+ }
285
+ const f32 = this._geoF32;
286
+ const u32 = this._geoU32;
287
+ for (let i = 0; i < chunk; i++) {
288
+ const q = quads[offset + i];
289
+ const idx = (this._geoQuadCount + i) * geoWordsPerInstance;
290
+ f32[idx + 0] = q.x0;
291
+ f32[idx + 1] = q.y0;
292
+ f32[idx + 2] = q.x1;
293
+ f32[idx + 3] = q.y1;
294
+ const uMin = (q.u0 * 0xffff) & 0xffff;
295
+ const uMax = (q.u1 * 0xffff) & 0xffff;
296
+ const v0Raw = (q.v0 * 0xffff) & 0xffff;
297
+ const v1Raw = (q.v1 * 0xffff) & 0xffff;
298
+ const vMin = flipY ? v1Raw : v0Raw;
299
+ const vMax = flipY ? v0Raw : v1Raw;
300
+ u32[idx + 4] = uMin | (vMin << 16);
301
+ u32[idx + 5] = uMax | (vMax << 16);
302
+ u32[idx + 6] = tint;
303
+ u32[idx + 7] = nodeIndex >>> 0;
304
+ }
305
+ this._geoQuadCount += chunk;
306
+ offset += chunk;
307
+ }
308
+ }
309
+ flush() {
310
+ const backend = this.getBackendOrNull();
311
+ if (backend === null) {
312
+ this._resetBatchState();
313
+ return;
314
+ }
315
+ const view = backend.view;
316
+ if (this._currentView !== view || this._currentViewId !== view.updateId) {
317
+ this._currentView = view;
318
+ this._currentViewId = view.updateId;
319
+ const proj = view.getTransform().toArray(false);
320
+ this._shaderPathShader.getUniform('u_projection').setValue(proj);
321
+ this._geoPathShader.getUniform('u_projection').setValue(proj);
322
+ }
323
+ if (this._shaderQuadCount > 0) {
324
+ this._flushShaderBatch(backend);
325
+ }
326
+ if (this._geoQuadCount > 0) {
327
+ this._flushGeoBatch(backend);
328
+ }
329
+ this._resetBatchState();
330
+ }
331
+ _flushShaderBatch(backend) {
332
+ const conn = this._connection;
333
+ const buf = this._shaderBuf;
334
+ const vao = this._shaderVao;
335
+ if (!conn || !buf || !vao || this._shaderQuadCount === 0)
336
+ return;
337
+ const gl = conn.gl;
338
+ const texture = this._currentTexture;
339
+ const scaleMode = (texture instanceof Texture) ? texture.scaleMode : ScaleModes.Linear;
340
+ const wrapS = repeatModeToWrap(this._currentModeX ?? 'repeat');
341
+ const wrapT = repeatModeToWrap(this._currentModeY ?? 'repeat');
342
+ // Bind repeat sampler (overrides texture's own wrap params for this unit).
343
+ const samplerHandle = this._getOrCreateSampler(gl, wrapS, wrapT, scaleMode);
344
+ gl.bindSampler(0, samplerHandle);
345
+ backend.bindTransformBufferTexture(transformTextureUnit, this._maxNodeIndex + 1);
346
+ this._shaderPathShader.getUniform('u_texture').setValue(new Int32Array([0]));
347
+ this._shaderPathShader.getUniform('u_transforms').setValue(this._transformUnitScratch);
348
+ this._shaderPathShader.sync();
349
+ backend.bindVertexArrayObject(vao);
350
+ buf.upload(this._shaderF32.subarray(0, this._shaderQuadCount * shaderWordsPerInstance));
351
+ vao.drawInstanced(4, 0, this._shaderQuadCount, RenderingPrimitives.TriangleStrip);
352
+ backend.stats.batches++;
353
+ backend.stats.drawCalls++;
354
+ // Unbind sampler so subsequent draws use the texture's own wrap params.
355
+ gl.bindSampler(0, null);
356
+ this._shaderQuadCount = 0;
357
+ }
358
+ _flushGeoBatch(backend) {
359
+ const conn = this._connection;
360
+ const buf = this._geoBuf;
361
+ const vao = this._geoVao;
362
+ if (!conn || !buf || !vao || this._geoQuadCount === 0)
363
+ return;
364
+ backend.bindTransformBufferTexture(transformTextureUnit, this._maxNodeIndex + 1);
365
+ this._geoPathShader.getUniform('u_texture').setValue(new Int32Array([0]));
366
+ this._geoPathShader.getUniform('u_transforms').setValue(this._transformUnitScratch);
367
+ this._geoPathShader.sync();
368
+ backend.bindVertexArrayObject(vao);
369
+ buf.upload(this._geoF32.subarray(0, this._geoQuadCount * geoWordsPerInstance));
370
+ vao.drawInstanced(4, 0, this._geoQuadCount, RenderingPrimitives.TriangleStrip);
371
+ backend.stats.batches++;
372
+ backend.stats.drawCalls++;
373
+ this._geoQuadCount = 0;
374
+ }
375
+ _resetBatchState() {
376
+ this._shaderQuadCount = 0;
377
+ this._geoQuadCount = 0;
378
+ this._maxNodeIndex = 0;
379
+ this._currentTexture = null;
380
+ this._currentBlendMode = null;
381
+ this._currentModeX = null;
382
+ this._currentModeY = null;
383
+ this._currentPath = null;
384
+ }
385
+ _getOrCreateSampler(gl, wrapS, wrapT, scaleMode) {
386
+ const key = `${wrapS}:${wrapT}:${scaleMode}`;
387
+ const existing = this._samplers.get(key);
388
+ if (existing !== undefined)
389
+ return existing;
390
+ const sampler = gl.createSampler();
391
+ if (sampler === null)
392
+ throw new Error('WebGl2RepeatingSpriteRenderer: could not create sampler.');
393
+ gl.samplerParameteri(sampler, gl.TEXTURE_WRAP_S, wrapS);
394
+ gl.samplerParameteri(sampler, gl.TEXTURE_WRAP_T, wrapT);
395
+ gl.samplerParameteri(sampler, gl.TEXTURE_MAG_FILTER, scaleMode);
396
+ gl.samplerParameteri(sampler, gl.TEXTURE_MIN_FILTER, scaleMode);
397
+ this._samplers.set(key, sampler);
398
+ return sampler;
399
+ }
400
+ onConnect(backend) {
401
+ const gl = backend.context;
402
+ this._shaderPathShader.connect(createWebGl2ShaderProgram(gl));
403
+ this._geoPathShader.connect(createWebGl2ShaderProgram(gl));
404
+ // sync() triggers finalize() which compiles the shaders and populates the
405
+ // attributes/uniforms maps — must happen before any getAttribute() call.
406
+ this._shaderPathShader.sync();
407
+ this._geoPathShader.sync();
408
+ const conn = this._createConnection(gl);
409
+ this._connection = conn;
410
+ // Shader-path VAO (uses float4 uvParams, not packed unorm16)
411
+ this._shaderBuf = new WebGl2RenderBuffer(BufferTypes.ArrayBuffer, this._shaderData, BufferUsage.DynamicDraw)
412
+ .connect(this._createBufRuntime(conn, 'shader'));
413
+ this._shaderVao = new WebGl2VertexArrayObject(RenderingPrimitives.TriangleStrip)
414
+ .addAttribute(this._shaderBuf, this._shaderPathShader.getAttribute('a_quadBounds'), gl.FLOAT, false, shaderStrideBytes, 0, false, 1)
415
+ .addAttribute(this._shaderBuf, this._shaderPathShader.getAttribute('a_uvParams'), gl.FLOAT, false, shaderStrideBytes, 16, false, 1)
416
+ .addAttribute(this._shaderBuf, this._shaderPathShader.getAttribute('a_color'), gl.UNSIGNED_BYTE, true, shaderStrideBytes, 32, false, 1)
417
+ .addAttribute(this._shaderBuf, this._shaderPathShader.getAttribute('a_nodeIndex'), gl.UNSIGNED_INT, false, shaderStrideBytes, 36, true, 1)
418
+ .connect(this._createVaoRuntime(conn, 'shader'));
419
+ // Geometry-path VAO (packed unorm16 UVs, same layout as NineSlice)
420
+ this._geoBuf = new WebGl2RenderBuffer(BufferTypes.ArrayBuffer, this._geoData, BufferUsage.DynamicDraw)
421
+ .connect(this._createBufRuntime(conn, 'geo'));
422
+ this._geoVao = new WebGl2VertexArrayObject(RenderingPrimitives.TriangleStrip)
423
+ .addAttribute(this._geoBuf, this._geoPathShader.getAttribute('a_quadBounds'), gl.FLOAT, false, geoStrideBytes, 0, false, 1)
424
+ .addAttribute(this._geoBuf, this._geoPathShader.getAttribute('a_uvBounds'), gl.UNSIGNED_SHORT, true, geoStrideBytes, 16, false, 1)
425
+ .addAttribute(this._geoBuf, this._geoPathShader.getAttribute('a_color'), gl.UNSIGNED_BYTE, true, geoStrideBytes, 24, false, 1)
426
+ .addAttribute(this._geoBuf, this._geoPathShader.getAttribute('a_nodeIndex'), gl.UNSIGNED_INT, false, geoStrideBytes, 28, true, 1)
427
+ .connect(this._createVaoRuntime(conn, 'geo'));
428
+ }
429
+ onDisconnect() {
430
+ const gl = this._connection?.gl;
431
+ if (gl !== undefined) {
432
+ for (const sampler of this._samplers.values()) {
433
+ gl.deleteSampler(sampler);
434
+ }
435
+ }
436
+ this._samplers.clear();
437
+ this._shaderPathShader.disconnect();
438
+ this._geoPathShader.disconnect();
439
+ this._shaderBuf?.destroy();
440
+ this._shaderBuf = null;
441
+ this._shaderVao?.destroy();
442
+ this._shaderVao = null;
443
+ this._geoBuf?.destroy();
444
+ this._geoBuf = null;
445
+ this._geoVao?.destroy();
446
+ this._geoVao = null;
447
+ this._connection = null;
448
+ this._currentView = null;
449
+ this._currentViewId = -1;
450
+ this._resetBatchState();
451
+ }
452
+ destroy() {
453
+ this.disconnect();
454
+ this._shaderPathShader.destroy();
455
+ this._geoPathShader.destroy();
456
+ }
457
+ // -----------------------------------------------------------------------
458
+ // Private GL helpers
459
+ // -----------------------------------------------------------------------
460
+ _createConnection(gl) {
461
+ const shaderVaoHandle = gl.createVertexArray();
462
+ const geoVaoHandle = gl.createVertexArray();
463
+ if (shaderVaoHandle === null || geoVaoHandle === null) {
464
+ throw new Error('WebGl2RepeatingSpriteRenderer: could not create vertex array object.');
465
+ }
466
+ return { gl, buffers: new Map(), shaderVaoHandle, geoVaoHandle };
467
+ }
468
+ _createBufRuntime(conn, _kind) {
469
+ const handle = conn.gl.createBuffer();
470
+ if (handle === null)
471
+ throw new Error('WebGl2RepeatingSpriteRenderer: could not create render buffer.');
472
+ return {
473
+ bind: (buffer) => { conn.gl.bindBuffer(buffer.type, handle); },
474
+ upload: (buffer, offset) => {
475
+ const gl = conn.gl;
476
+ const data = buffer.data;
477
+ const state = conn.buffers.get(buffer);
478
+ gl.bindBuffer(buffer.type, handle);
479
+ if (state && state.dataByteLength >= data.byteLength) {
480
+ gl.bufferSubData(buffer.type, offset, data);
481
+ state.dataByteLength = data.byteLength;
482
+ }
483
+ else {
484
+ gl.bufferData(buffer.type, data, buffer.usage);
485
+ conn.buffers.set(buffer, { handle, dataByteLength: data.byteLength });
486
+ }
487
+ },
488
+ destroy: (buffer) => {
489
+ conn.gl.deleteBuffer(handle);
490
+ conn.buffers.delete(buffer);
491
+ buffer.disconnect();
492
+ },
493
+ };
494
+ }
495
+ _createVaoRuntime(conn, kind) {
496
+ const vaoHandle = kind === 'shader' ? conn.shaderVaoHandle : conn.geoVaoHandle;
497
+ let appliedVersion = -1;
498
+ return {
499
+ bind: (vao) => {
500
+ const gl = conn.gl;
501
+ gl.bindVertexArray(vaoHandle);
502
+ if (appliedVersion !== vao.version) {
503
+ let lastBuffer = null;
504
+ for (const attr of vao.attributes) {
505
+ if (lastBuffer !== attr.buffer) {
506
+ attr.buffer.bind();
507
+ lastBuffer = attr.buffer;
508
+ }
509
+ if (attr.integer) {
510
+ gl.vertexAttribIPointer(attr.location, attr.size, attr.type, attr.stride, attr.start);
511
+ }
512
+ else {
513
+ gl.vertexAttribPointer(attr.location, attr.size, attr.type, attr.normalized, attr.stride, attr.start);
514
+ }
515
+ gl.enableVertexAttribArray(attr.location);
516
+ gl.vertexAttribDivisor(attr.location, attr.divisor);
517
+ }
518
+ appliedVersion = vao.version;
519
+ }
520
+ },
521
+ unbind: () => { conn.gl.bindVertexArray(null); },
522
+ draw: (_vao, size, start, type) => { conn.gl.drawArrays(type, start, size); },
523
+ drawInstanced: (_vao, count, start, instanceCount, type) => {
524
+ conn.gl.drawArraysInstanced(type, start, count, instanceCount);
525
+ },
526
+ destroy: (vao) => {
527
+ conn.gl.deleteVertexArray(vaoHandle);
528
+ vao.disconnect();
529
+ },
530
+ };
531
+ }
532
+ }
533
+
534
+ export { WebGl2RepeatingSpriteRenderer };
535
+ //# sourceMappingURL=WebGl2RepeatingSpriteRenderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebGl2RepeatingSpriteRenderer.js","sources":["../../../../../src/rendering/webgl2/WebGl2RepeatingSpriteRenderer.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;;;;;AAeA;AACA;AACA;AAEA,MAAM,oBAAoB,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2C3B;AAEF;AACA;AACA;AAEA,MAAM,iBAAiB,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoCxB;AAEF,MAAM,gBAAgB,GAAG,CAAA;;;;;;;;;;;;EAYvB;AAEF;AACA;AACA;AAEA,MAAM,iBAAiB,GAAG,EAAE,CAAC;AAC7B,MAAM,sBAAsB,GAAG,iBAAiB,GAAG,WAAW,CAAC,iBAAiB;AAEhF,MAAM,cAAc,GAAG,EAAE,CAAC;AAC1B,MAAM,mBAAmB,GAAG,cAAc,GAAG,WAAW,CAAC,iBAAiB;AAE1E,MAAM,oBAAoB,GAAG,CAAC;AAE9B;AACA;AACA;AAEA,SAAS,gBAAgB,CAAC,IAAgB,EAAA;IACxC,IAAI,IAAI,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC,MAAM;IAC9C,IAAI,IAAI,KAAK,eAAe;QAAE,OAAO,SAAS,CAAC,cAAc;IAC7D,OAAO,SAAS,CAAC,WAAW;AAC9B;AAaA;AACM,MAAO,6BAA8B,SAAQ,sBAAuC,CAAA;AACvE,IAAA,iBAAiB;AACjB,IAAA,cAAc;AACd,IAAA,UAAU;;AAGV,IAAA,WAAW;AACX,IAAA,UAAU;AACV,IAAA,UAAU;IACnB,UAAU,GAA8B,IAAI;IAC5C,UAAU,GAAmC,IAAI;IACjD,gBAAgB,GAAG,CAAC;;AAGX,IAAA,QAAQ;AACR,IAAA,OAAO;AACP,IAAA,OAAO;IAChB,OAAO,GAA8B,IAAI;IACzC,OAAO,GAAmC,IAAI;IAC9C,aAAa,GAAG,CAAC;;AAGjB,IAAA,SAAS,GAAG,IAAI,GAAG,EAAwB;;IAG3C,aAAa,GAAG,CAAC;IACjB,eAAe,GAAmC,IAAI;IACtD,iBAAiB,GAAsB,IAAI;IAC3C,aAAa,GAAsB,IAAI;IACvC,aAAa,GAAsB,IAAI;IACvC,YAAY,GAAiC,IAAI;IAEjD,WAAW,GAA8B,IAAI;IAEpC,qBAAqB,GAAG,IAAI,UAAU,CAAC,CAAC,oBAAoB,CAAC,CAAC;AAC9D,IAAA,WAAW,GAAG,IAAI,SAAS,EAAE;IACtC,YAAY,GAAY,IAAI;IAC5B,cAAc,GAAG,EAAE;AAE3B,IAAA,WAAA,CAAmB,SAAiB,EAAA;AAClC,QAAA,KAAK,EAAE;AACP,QAAA,IAAI,CAAC,UAAU,GAAG,SAAS;QAC3B,IAAI,CAAC,iBAAiB,GAAG,IAAI,MAAM,CAAC,oBAAoB,EAAE,gBAAgB,CAAC;QAC3E,IAAI,CAAC,cAAc,GAAG,IAAI,MAAM,CAAC,iBAAiB,EAAE,gBAAgB,CAAC;QAErE,IAAI,CAAC,WAAW,GAAG,IAAI,WAAW,CAAC,SAAS,GAAG,iBAAiB,CAAC;QACjE,IAAI,CAAC,UAAU,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC;QACpD,IAAI,CAAC,UAAU,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC;QAEnD,IAAI,CAAC,QAAQ,GAAG,IAAI,WAAW,CAAC,SAAS,GAAG,cAAc,CAAC;QAC3D,IAAI,CAAC,OAAO,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC;QAC9C,IAAI,CAAC,OAAO,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC;IAC/C;AAEO,IAAA,MAAM,CAAC,MAAuB,EAAA;AACnC,QAAA,MAAM,QAAQ,GAAI,MAAM,CAAC,gBAAgB;AACzC,QAAA,MAAM,OAAO,GAAK,MAAM,CAAC,OAAO;AAChC,QAAA,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS;AAClC,QAAA,MAAM,KAAK,GAAO,MAAM,CAAC,KAAK;AAC9B,QAAA,MAAM,KAAK,GAAO,MAAM,CAAC,KAAK;AAE9B,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,GAAG,CAAC,IAAI,IAAI,CAAC,aAAa,GAAG,CAAC;QAEnE,IAAI,OAAO,EAAE;AACX,YAAA,MAAM,WAAW,GAAI,IAAI,CAAC,YAAY,KAAK,QAAQ;AACnD,YAAA,MAAM,UAAU,GAAK,IAAI,CAAC,eAAe,KAAK,OAAO;AACrD,YAAA,MAAM,YAAY,GAAG,IAAI,CAAC,iBAAiB,KAAK,SAAS;AACzD,YAAA,MAAM,WAAW,GAAI,QAAQ,KAAK;AAC7B,oBAAC,IAAI,CAAC,aAAa,KAAK,KAAK,IAAI,IAAI,CAAC,aAAa,KAAK,KAAK,CAAC;YAEnE,IAAI,WAAW,IAAI,UAAU,IAAI,YAAY,IAAI,WAAW,EAAE;gBAC5D,IAAI,CAAC,KAAK,EAAE;YACd;QACF;AAEA,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE;AAEjC,QAAA,IAAI,IAAI,CAAC,eAAe,KAAK,OAAO,EAAE;AACpC,YAAA,IAAI,CAAC,eAAe,GAAG,OAAO;AAC9B,YAAA,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC;QACjC;AAEA,QAAA,IAAI,IAAI,CAAC,iBAAiB,KAAK,SAAS,EAAE;AACxC,YAAA,IAAI,CAAC,iBAAiB,GAAG,SAAS;AAClC,YAAA,OAAO,CAAC,YAAY,CAAC,SAAS,CAAC;QACjC;AAEA,QAAA,IAAI,CAAC,YAAY,GAAG,QAAQ;AAE5B,QAAA,MAAM,OAAO,GAAK,OAAO,CAAC,iBAAiB;QAC3C,MAAM,SAAS,GAAG,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,SAAS,GAAG,OAAO,CAAC,cAAc,CAAC,MAAM,CAAC;AAEvF,QAAA,IAAI,SAAS,GAAG,IAAI,CAAC,aAAa,EAAE;AAClC,YAAA,IAAI,CAAC,aAAa,GAAG,SAAS;QAChC;AAEA,QAAA,IAAI,QAAQ,KAAK,QAAQ,EAAE;AACzB,YAAA,IAAI,CAAC,aAAa,GAAG,KAAK;AAC1B,YAAA,IAAI,CAAC,aAAa,GAAG,KAAK;AAC1B,YAAA,IAAI,CAAC,oBAAoB,CAAC,MAAM,EAAE,SAAS,CAAC;QAC9C;aAAO;AACL,YAAA,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,SAAS,CAAC;QACxC;IACF;IAEQ,oBAAoB,CAAC,MAAuB,EAAE,SAAiB,EAAA;AACrE,QAAA,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO;AAC9B,QAAA,MAAM,IAAI,GAAM,MAAM,CAAC,MAAM,CAAC,KAAK;AACnC,QAAA,MAAM,IAAI,GAAM,MAAM,CAAC,MAAM,CAAC,MAAM;AACpC,QAAA,IAAM,KAAK,GAAK,MAAM,CAAC,KAAK;AAC5B,QAAA,IAAM,KAAK,GAAK,MAAM,CAAC,MAAM;QAC7B,MAAM,KAAK,GAAK,OAAO,YAAY,OAAO,IAAI,OAAO,CAAC,KAAK;;;;AAK3D,QAAA,IAAI,MAAM,CAAC,aAAa,KAAK,UAAU,EAAE;AACvC,YAAA,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE;AACjC,YAAA,MAAM,IAAI,GAAG,OAAO,CAAC,iBAAiB,EAAE;YACxC,MAAM,EAAE,GAAG,MAAM,CAAC,eAAe,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC;AAE1F,YAAA,KAAK,GAAG,EAAE,CAAC,KAAK;AAChB,YAAA,KAAK,GAAG,EAAE,CAAC,MAAM;QACnB;AAEA,QAAA,MAAM,OAAO,GAAG,mBAAmB,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC;AAC3E,QAAA,MAAM,OAAO,GAAG,mBAAmB,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC;AAC3E,QAAA,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC;AACtD,QAAA,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC;;AAGtD,QAAA,MAAM,QAAQ,GAAG,KAAK,GAAG,CAAC,OAAO,GAAG,OAAO;AAC3C,QAAA,MAAM,QAAQ,GAAG,KAAK,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO;QAEpD,IAAI,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAAC,UAAU,EAAE;YAC5C,IAAI,CAAC,KAAK,EAAE;QACd;AAEA,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,gBAAgB,GAAG,sBAAsB;AAC1D,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU;AAC3B,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU;AAE3B,QAAA,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC;AAChB,QAAA,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC;AAChB,QAAA,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,KAAK;AACpB,QAAA,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,KAAK;AACpB,QAAA,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,OAAO;AACtB,QAAA,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,QAAQ;AACvB,QAAA,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,OAAO;AACtB,QAAA,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,QAAQ;AACvB,QAAA,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE;QACnC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,SAAS,KAAK,CAAC;QAE9B,IAAI,CAAC,gBAAgB,EAAE;IACzB;IAEQ,cAAc,CAAC,MAAuB,EAAE,SAAiB,EAAA;AAC/D,QAAA,IAAI,KAAK,GAAmC,MAAM,CAAC,KAAK;;AAGxD,QAAA,IAAI,MAAM,CAAC,aAAa,KAAK,UAAU,EAAE;AACvC,YAAA,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE;AACjC,YAAA,MAAM,IAAI,GAAG,OAAO,CAAC,iBAAiB,EAAE;AAExC,YAAA,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC;QACtE;AAEA,QAAA,MAAM,KAAK,GAAI,CAAC,MAAM,CAAC,OAAO,YAAY,OAAO,KAAK,MAAM,CAAC,OAAO,CAAC,KAAK;QAC1E,MAAM,IAAI,GAAK,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE;QAEnC,IAAI,MAAM,GAAG,CAAC;AAEd,QAAA,OAAO,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE;AAC5B,YAAA,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,MAAM;AACvC,YAAA,MAAM,KAAK,GAAO,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,aAAa,CAAC;AAE3E,YAAA,IAAI,KAAK,IAAI,CAAC,EAAE;gBACd,IAAI,CAAC,KAAK,EAAE;;AAGZ,gBAAA,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE;gBACjC,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;AACtC,gBAAA,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,SAAS,CAAC;AACtC,gBAAA,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC,OAAO;AACrC,gBAAA,IAAI,CAAC,iBAAiB,GAAG,MAAM,CAAC,SAAS;AACzC,gBAAA,IAAI,CAAC,YAAY,GAAG,UAAU;AAE9B,gBAAA,IAAI,SAAS,GAAG,IAAI,CAAC,aAAa,EAAE;AAClC,oBAAA,IAAI,CAAC,aAAa,GAAG,SAAS;gBAChC;gBACA;YACF;AAEA,YAAA,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO;AACxB,YAAA,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO;AAExB,YAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE;gBAC9B,MAAM,CAAC,GAAK,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;gBAC7B,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,aAAa,GAAG,CAAC,IAAI,mBAAmB;gBAE1D,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE;gBACnB,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE;gBACnB,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE;gBACnB,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE;gBAEnB,MAAM,IAAI,GAAI,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,IAAI,MAAM;gBACtC,MAAM,IAAI,GAAI,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,IAAI,MAAM;gBACtC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,IAAI,MAAM;gBACtC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,IAAI,MAAM;gBACtC,MAAM,IAAI,GAAI,KAAK,GAAG,KAAK,GAAG,KAAK;gBACnC,MAAM,IAAI,GAAI,KAAK,GAAG,KAAK,GAAG,KAAK;AAEnC,gBAAA,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;AAClC,gBAAA,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;AAClC,gBAAA,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,IAAI;gBACnB,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,SAAS,KAAK,CAAC;YAChC;AAEA,YAAA,IAAI,CAAC,aAAa,IAAI,KAAK;YAC3B,MAAM,IAAI,KAAK;QACjB;IACF;IAEO,KAAK,GAAA;AACV,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,EAAE;AAEvC,QAAA,IAAI,OAAO,KAAK,IAAI,EAAE;YACpB,IAAI,CAAC,gBAAgB,EAAE;YACvB;QACF;AAEA,QAAA,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI;AAEzB,QAAA,IAAI,IAAI,CAAC,YAAY,KAAK,IAAI,IAAI,IAAI,CAAC,cAAc,KAAM,IAAwC,CAAC,QAAQ,EAAE;AAC5G,YAAA,IAAI,CAAC,YAAY,GAAK,IAAI;AAC1B,YAAA,IAAI,CAAC,cAAc,GAAI,IAAwC,CAAC,QAAQ;YACxE,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;AAC/C,YAAA,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;AAChE,YAAA,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;QAC/D;AAEA,QAAA,IAAI,IAAI,CAAC,gBAAgB,GAAG,CAAC,EAAE;AAC7B,YAAA,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC;QACjC;AAEA,QAAA,IAAI,IAAI,CAAC,aAAa,GAAG,CAAC,EAAE;AAC1B,YAAA,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC;QAC9B;QAEA,IAAI,CAAC,gBAAgB,EAAE;IACzB;AAEQ,IAAA,iBAAiB,CAAC,OAAsB,EAAA;AAC9C,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW;AAC7B,QAAA,MAAM,GAAG,GAAI,IAAI,CAAC,UAAU;AAC5B,QAAA,MAAM,GAAG,GAAI,IAAI,CAAC,UAAU;AAE5B,QAAA,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,gBAAgB,KAAK,CAAC;YAAE;AAE1D,QAAA,MAAM,EAAE,GAAS,IAAI,CAAC,EAAE;AACxB,QAAA,MAAM,OAAO,GAAI,IAAI,CAAC,eAAe;AACrC,QAAA,MAAM,SAAS,GAAG,CAAC,OAAO,YAAY,OAAO,IAAI,OAAO,CAAC,SAAS,GAAG,UAAU,CAAC,MAAM;QACtF,MAAM,KAAK,GAAM,gBAAgB,CAAC,IAAI,CAAC,aAAa,IAAI,QAAQ,CAAC;QACjE,MAAM,KAAK,GAAM,gBAAgB,CAAC,IAAI,CAAC,aAAa,IAAI,QAAQ,CAAC;;AAGjE,QAAA,MAAM,aAAa,GAAG,IAAI,CAAC,mBAAmB,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC;AAC3E,QAAA,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,aAAa,CAAC;QAEhC,OAAO,CAAC,0BAA0B,CAAC,oBAAoB,EAAE,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC;AAChF,QAAA,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5E,QAAA,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,qBAAqB,CAAC;AACtF,QAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE;AAE7B,QAAA,OAAO,CAAC,qBAAqB,CAAC,GAAG,CAAC;AAClC,QAAA,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,gBAAgB,GAAG,sBAAsB,CAAC,CAAC;AACvF,QAAA,GAAG,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,aAAa,CAAC;AAEjF,QAAA,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE;AACvB,QAAA,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE;;AAGzB,QAAA,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,IAAI,CAAC;AAEvB,QAAA,IAAI,CAAC,gBAAgB,GAAG,CAAC;IAC3B;AAEQ,IAAA,cAAc,CAAC,OAAsB,EAAA;AAC3C,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW;AAC7B,QAAA,MAAM,GAAG,GAAI,IAAI,CAAC,OAAO;AACzB,QAAA,MAAM,GAAG,GAAI,IAAI,CAAC,OAAO;AAEzB,QAAA,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,aAAa,KAAK,CAAC;YAAE;QAEvD,OAAO,CAAC,0BAA0B,CAAC,oBAAoB,EAAE,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC;AAChF,QAAA,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACzE,QAAA,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,qBAAqB,CAAC;AACnF,QAAA,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE;AAE1B,QAAA,OAAO,CAAC,qBAAqB,CAAC,GAAG,CAAC;AAClC,QAAA,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,aAAa,GAAG,mBAAmB,CAAC,CAAC;AAC9E,QAAA,GAAG,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,aAAa,EAAE,mBAAmB,CAAC,aAAa,CAAC;AAE9E,QAAA,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE;AACvB,QAAA,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE;AAEzB,QAAA,IAAI,CAAC,aAAa,GAAG,CAAC;IACxB;IAEQ,gBAAgB,GAAA;AACtB,QAAA,IAAI,CAAC,gBAAgB,GAAG,CAAC;AACzB,QAAA,IAAI,CAAC,aAAa,GAAM,CAAC;AACzB,QAAA,IAAI,CAAC,aAAa,GAAM,CAAC;AACzB,QAAA,IAAI,CAAC,eAAe,GAAI,IAAI;AAC5B,QAAA,IAAI,CAAC,iBAAiB,GAAG,IAAI;AAC7B,QAAA,IAAI,CAAC,aAAa,GAAM,IAAI;AAC5B,QAAA,IAAI,CAAC,aAAa,GAAM,IAAI;AAC5B,QAAA,IAAI,CAAC,YAAY,GAAO,IAAI;IAC9B;AAEQ,IAAA,mBAAmB,CACzB,EAA0B,EAC1B,KAAgB,EAChB,KAAgB,EAChB,SAAqB,EAAA;QAErB,MAAM,GAAG,GAAG,CAAA,EAAG,KAAK,IAAI,KAAK,CAAA,CAAA,EAAI,SAAS,CAAA,CAAE;QAC5C,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC;QACxC,IAAI,QAAQ,KAAK,SAAS;AAAE,YAAA,OAAO,QAAQ;AAE3C,QAAA,MAAM,OAAO,GAAG,EAAE,CAAC,aAAa,EAAE;QAClC,IAAI,OAAO,KAAK,IAAI;AAAE,YAAA,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC;QAEjG,EAAE,CAAC,iBAAiB,CAAC,OAAO,EAAE,EAAE,CAAC,cAAc,EAAE,KAAK,CAAC;QACvD,EAAE,CAAC,iBAAiB,CAAC,OAAO,EAAE,EAAE,CAAC,cAAc,EAAE,KAAK,CAAC;QACvD,EAAE,CAAC,iBAAiB,CAAC,OAAO,EAAE,EAAE,CAAC,kBAAkB,EAAE,SAAS,CAAC;QAC/D,EAAE,CAAC,iBAAiB,CAAC,OAAO,EAAE,EAAE,CAAC,kBAAkB,EAAE,SAAS,CAAC;QAE/D,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC;AAChC,QAAA,OAAO,OAAO;IAChB;AAEU,IAAA,SAAS,CAAC,OAAsB,EAAA;AACxC,QAAA,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO;QAE1B,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,yBAAyB,CAAC,EAAE,CAAC,CAAC;QAC7D,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,yBAAyB,CAAC,EAAE,CAAC,CAAC;;;AAI1D,QAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE;AAC7B,QAAA,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE;QAE1B,MAAM,IAAI,GAAG,IAAI,CAAC,iBAAiB,CAAC,EAAE,CAAC;AACvC,QAAA,IAAI,CAAC,WAAW,GAAG,IAAI;;AAGvB,QAAA,IAAI,CAAC,UAAU,GAAG,IAAI,kBAAkB,CAAC,WAAW,CAAC,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,WAAW;aACxG,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAElD,IAAI,CAAC,UAAU,GAAG,IAAI,uBAAuB,CAAC,mBAAmB,CAAC,aAAa;aAC5E,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC;aAClI,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,iBAAiB,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;aACjI,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,aAAa,EAAE,IAAI,EAAE,iBAAiB,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;aACrI,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,aAAa,CAAC,EAAE,EAAE,CAAC,YAAY,EAAE,KAAK,EAAE,iBAAiB,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;aACxI,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;;AAGlD,QAAA,IAAI,CAAC,OAAO,GAAG,IAAI,kBAAkB,CAAC,WAAW,CAAC,WAAW,EAAE,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,WAAW;aAClG,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAE/C,IAAI,CAAC,OAAO,GAAG,IAAI,uBAAuB,CAAC,mBAAmB,CAAC,aAAa;aACzE,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC;aACzH,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC,cAAc,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;aAChI,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,aAAa,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;aAC5H,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,aAAa,CAAC,EAAE,EAAE,CAAC,YAAY,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;aAC/H,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACjD;IAEU,YAAY,GAAA;AACpB,QAAA,MAAM,EAAE,GAAG,IAAI,CAAC,WAAW,EAAE,EAAE;AAE/B,QAAA,IAAI,EAAE,KAAK,SAAS,EAAE;YACpB,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE;AAC7C,gBAAA,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC;YAC3B;QACF;AACA,QAAA,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE;AAEtB,QAAA,IAAI,CAAC,iBAAiB,CAAC,UAAU,EAAE;AACnC,QAAA,IAAI,CAAC,cAAc,CAAC,UAAU,EAAE;AAChC,QAAA,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE;AAC1B,QAAA,IAAI,CAAC,UAAU,GAAG,IAAI;AACtB,QAAA,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE;AAC1B,QAAA,IAAI,CAAC,UAAU,GAAG,IAAI;AACtB,QAAA,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE;AACvB,QAAA,IAAI,CAAC,OAAO,GAAG,IAAI;AACnB,QAAA,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE;AACvB,QAAA,IAAI,CAAC,OAAO,GAAG,IAAI;AACnB,QAAA,IAAI,CAAC,WAAW,GAAG,IAAI;AACvB,QAAA,IAAI,CAAC,YAAY,GAAG,IAAI;AACxB,QAAA,IAAI,CAAC,cAAc,GAAG,EAAE;QACxB,IAAI,CAAC,gBAAgB,EAAE;IACzB;IAEO,OAAO,GAAA;QACZ,IAAI,CAAC,UAAU,EAAE;AACjB,QAAA,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE;AAChC,QAAA,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE;IAC/B;;;;AAMQ,IAAA,iBAAiB,CAAC,EAA0B,EAAA;AAClD,QAAA,MAAM,eAAe,GAAG,EAAE,CAAC,iBAAiB,EAAE;AAC9C,QAAA,MAAM,YAAY,GAAM,EAAE,CAAC,iBAAiB,EAAE;QAE9C,IAAI,eAAe,KAAK,IAAI,IAAI,YAAY,KAAK,IAAI,EAAE;AACrD,YAAA,MAAM,IAAI,KAAK,CAAC,sEAAsE,CAAC;QACzF;AAEA,QAAA,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,GAAG,EAAE,EAAE,eAAe,EAAE,YAAY,EAAE;IAClE;IAEQ,iBAAiB,CAAC,IAAwB,EAAE,KAAa,EAAA;QAC/D,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,YAAY,EAAE;QACrC,IAAI,MAAM,KAAK,IAAI;AAAE,YAAA,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC;QAEtG,OAAO;YACL,IAAI,EAAE,CAAC,MAAM,KAAU,EAAG,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;AACpE,YAAA,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,KAAU;AAC/B,gBAAA,MAAM,EAAE,GAAK,IAAI,CAAC,EAAE;AACpB,gBAAA,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI;gBACxB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC;gBAEtC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC;gBAClC,IAAI,KAAK,IAAI,KAAK,CAAC,cAAc,IAAI,IAAI,CAAC,UAAU,EAAE;oBACpD,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC;AAC3C,oBAAA,KAAK,CAAC,cAAc,GAAG,IAAI,CAAC,UAAU;gBACxC;qBAAO;AACL,oBAAA,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC;AAC9C,oBAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC;gBACvE;YACF,CAAC;AACD,YAAA,OAAO,EAAE,CAAC,MAAM,KAAU;AACxB,gBAAA,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC;AAC5B,gBAAA,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC;gBAC3B,MAAM,CAAC,UAAU,EAAE;YACrB,CAAC;SACF;IACH;IAEQ,iBAAiB,CAAC,IAAwB,EAAE,IAAsB,EAAA;AACxE,QAAA,MAAM,SAAS,GAAG,IAAI,KAAK,QAAQ,GAAG,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,YAAY;AAC9E,QAAA,IAAI,cAAc,GAAG,EAAE;QAEvB,OAAO;AACL,YAAA,IAAI,EAAE,CAAC,GAAG,KAAU;AAClB,gBAAA,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE;AAClB,gBAAA,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC;AAE7B,gBAAA,IAAI,cAAc,KAAK,GAAG,CAAC,OAAO,EAAE;oBAClC,IAAI,UAAU,GAA8B,IAAI;AAEhD,oBAAA,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,UAAU,EAAE;AACjC,wBAAA,IAAI,UAAU,KAAK,IAAI,CAAC,MAAM,EAAE;AAC9B,4BAAA,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE;AAClB,4BAAA,UAAU,GAAG,IAAI,CAAC,MAAM;wBAC1B;AACA,wBAAA,IAAI,IAAI,CAAC,OAAO,EAAE;4BAChB,EAAE,CAAC,oBAAoB,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC;wBACvF;6BAAO;4BACL,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC;wBACvG;AACA,wBAAA,EAAE,CAAC,uBAAuB,CAAC,IAAI,CAAC,QAAQ,CAAC;wBACzC,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC;oBACrD;AACA,oBAAA,cAAc,GAAG,GAAG,CAAC,OAAO;gBAC9B;YACF,CAAC;AACD,YAAA,MAAM,EAAE,MAAW,EAAG,IAAI,CAAC,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACtD,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,KAAU,EAAG,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;AACnF,YAAA,aAAa,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,KAAU;AAC/D,gBAAA,IAAI,CAAC,EAAE,CAAC,mBAAmB,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,CAAC;YAChE,CAAC;AACD,YAAA,OAAO,EAAE,CAAC,GAAG,KAAU;AACrB,gBAAA,IAAI,CAAC,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC;gBACpC,GAAG,CAAC,UAAU,EAAE;YAClB,CAAC;SACF;IACH;AACD;;;;"}
@@ -15,6 +15,8 @@ export declare class WebGl2SpriteRenderer extends AbstractWebGl2Renderer<Sprite>
15
15
  private readonly _transformUnitScratch;
16
16
  private _currentMaterial;
17
17
  private _currentBaseTexture;
18
+ private readonly _snapBounds;
19
+ private _activeBounds;
18
20
  private _instanceCount;
19
21
  private _maxNodeIndex;
20
22
  private _currentBlendMode;
@@ -25,6 +27,13 @@ export declare class WebGl2SpriteRenderer extends AbstractWebGl2Renderer<Sprite>
25
27
  private _connection;
26
28
  constructor(batchSize: number);
27
29
  render(sprite: Sprite): this;
30
+ /**
31
+ * Local bounds to upload for `sprite` this draw: device-pixel-snapped in
32
+ * `'geometry'` pixel-snap mode (axis-aligned only), otherwise the sprite's
33
+ * logical local bounds. Reuses a scratch rectangle and never mutates logical
34
+ * state. Consumed synchronously by {@link _packInstance}.
35
+ */
36
+ private _resolveBounds;
28
37
  flush(): void;
29
38
  protected onConnect(backend: WebGl2Backend): void;
30
39
  protected onDisconnect(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"WebGl2SpriteRenderer.d.ts","sourceRoot":"","sources":["../../../../src/rendering/webgl2/WebGl2SpriteRenderer.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAOvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAGlE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAwDrD,qBAAa,oBAAqB,SAAQ,sBAAsB,CAAC,MAAM,CAAC;IACtE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAc;IAC5C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAe;IAChD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAc;IAE9C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAiF;IACjH,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA8C;IAC5E,OAAO,CAAC,UAAU,CAAK;IAIvB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqC;IAGpE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAyF;IAExH,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAsD;IAC5F,OAAO,CAAC,gBAAgB,CAA+B;IACvD,OAAO,CAAC,mBAAmB,CAAwC;IAEnE,OAAO,CAAC,cAAc,CAAK;IAG3B,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,iBAAiB,CAA2B;IACpD,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,cAAc,CAAM;IAE5B,OAAO,CAAC,eAAe,CAAmC;IAC1D,OAAO,CAAC,IAAI,CAAwC;IACpD,OAAO,CAAC,WAAW,CAAyC;gBAEzC,SAAS,EAAE,MAAM;IAU7B,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IA0B5B,KAAK,IAAI,IAAI;IA+DpB,SAAS,CAAC,SAAS,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IA2BjD,SAAS,CAAC,YAAY,IAAI,IAAI;IAsBvB,OAAO,IAAI,IAAI;IAKtB,2EAA2E;IAC3E,OAAO,CAAC,cAAc;IAgCtB,sEAAsE;IACtE,OAAO,CAAC,aAAa;IA0BrB,OAAO,CAAC,aAAa;IA8CrB,OAAO,CAAC,wBAAwB;IAmChC,OAAO,CAAC,mBAAmB;IA8C3B,OAAO,CAAC,oBAAoB;IAY5B,OAAO,CAAC,WAAW;IAWnB,OAAO,CAAC,iBAAiB;IAczB,OAAO,CAAC,oBAAoB;IAkC5B,OAAO,CAAC,iBAAiB;CA8C1B"}
1
+ {"version":3,"file":"WebGl2SpriteRenderer.d.ts","sourceRoot":"","sources":["../../../../src/rendering/webgl2/WebGl2SpriteRenderer.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAOvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAGlE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAwDrD,qBAAa,oBAAqB,SAAQ,sBAAsB,CAAC,MAAM,CAAC;IACtE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAc;IAC5C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAe;IAChD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAc;IAE9C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAiF;IACjH,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA8C;IAC5E,OAAO,CAAC,UAAU,CAAK;IAIvB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqC;IAGpE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAyF;IAExH,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAsD;IAC5F,OAAO,CAAC,gBAAgB,CAA+B;IACvD,OAAO,CAAC,mBAAmB,CAAwC;IAGnE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA8B;IAC1D,OAAO,CAAC,aAAa,CAA0B;IAE/C,OAAO,CAAC,cAAc,CAAK;IAG3B,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,iBAAiB,CAA2B;IACpD,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,cAAc,CAAM;IAE5B,OAAO,CAAC,eAAe,CAAmC;IAC1D,OAAO,CAAC,IAAI,CAAwC;IACpD,OAAO,CAAC,WAAW,CAAyC;gBAEzC,SAAS,EAAE,MAAM;IAU7B,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IA4BnC;;;;;OAKG;IACH,OAAO,CAAC,cAAc;IAUf,KAAK,IAAI,IAAI;IA+DpB,SAAS,CAAC,SAAS,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IA2BjD,SAAS,CAAC,YAAY,IAAI,IAAI;IAsBvB,OAAO,IAAI,IAAI;IAKtB,2EAA2E;IAC3E,OAAO,CAAC,cAAc;IAgCtB,sEAAsE;IACtE,OAAO,CAAC,aAAa;IA0BrB,OAAO,CAAC,aAAa;IA+CrB,OAAO,CAAC,wBAAwB;IAmChC,OAAO,CAAC,mBAAmB;IA8C3B,OAAO,CAAC,oBAAoB;IAY5B,OAAO,CAAC,WAAW;IAWnB,OAAO,CAAC,iBAAiB;IAczB,OAAO,CAAC,oBAAoB;IAkC5B,OAAO,CAAC,iBAAiB;CA8C1B"}
@@ -1,3 +1,4 @@
1
+ import { Rectangle } from '../../math/Rectangle.js';
1
2
  import { Shader } from '../shader/Shader.js';
2
3
  import { spriteVertexGlsl } from '../sprite/spriteMaterialSources.js';
3
4
  import { RenderTexture } from '../texture/RenderTexture.js';
@@ -72,6 +73,10 @@ class WebGl2SpriteRenderer extends AbstractWebGl2Renderer {
72
73
  _transformUnitScratch = new Int32Array([transformTextureUnit]);
73
74
  _currentMaterial = null;
74
75
  _currentBaseTexture = null;
76
+ // Reusable scratch for device-snapped local bounds ('geometry' mode), and the
77
+ // bounds resolved for the sprite currently being packed (snapped or logical).
78
+ _snapBounds = new Rectangle();
79
+ _activeBounds = null;
75
80
  _instanceCount = 0;
76
81
  // Highest transform-buffer row referenced by the pending batch; drives the
77
82
  // minimum row count uploaded for the transform texture at flush time.
@@ -103,6 +108,7 @@ class WebGl2SpriteRenderer extends AbstractWebGl2Renderer {
103
108
  // sprite's transform into the buffer and use the freshly-allocated slot.
104
109
  const command = backend.activeDrawCommand;
105
110
  const nodeIndex = command !== null ? command.nodeIndex : backend._pushTransform(sprite);
111
+ this._activeBounds = this._resolveBounds(sprite, backend);
106
112
  if (material === null) {
107
113
  this._renderDefault(sprite, texture, backend, nodeIndex);
108
114
  }
@@ -111,6 +117,19 @@ class WebGl2SpriteRenderer extends AbstractWebGl2Renderer {
111
117
  }
112
118
  return this;
113
119
  }
120
+ /**
121
+ * Local bounds to upload for `sprite` this draw: device-pixel-snapped in
122
+ * `'geometry'` pixel-snap mode (axis-aligned only), otherwise the sprite's
123
+ * logical local bounds. Reuses a scratch rectangle and never mutates logical
124
+ * state. Consumed synchronously by {@link _packInstance}.
125
+ */
126
+ _resolveBounds(sprite, backend) {
127
+ if (sprite.pixelSnapMode !== 'geometry') {
128
+ return sprite.getLocalBounds();
129
+ }
130
+ const snap = backend._getSnapPixelSize();
131
+ return sprite.getRenderBounds(backend.view, snap.width, snap.height, this._snapBounds);
132
+ }
114
133
  flush() {
115
134
  const backend = this.getBackendOrNull();
116
135
  const instanceBuffer = this._instanceBuffer;
@@ -257,8 +276,9 @@ class WebGl2SpriteRenderer extends AbstractWebGl2Renderer {
257
276
  const offset = this._instanceCount * wordsPerInstance;
258
277
  const f32 = this._instanceFloat32;
259
278
  const u32 = this._instanceUint32;
260
- // localBounds: left, top, right, bottom (offset 0..3)
261
- const bounds = sprite.getLocalBounds();
279
+ // localBounds: left, top, right, bottom (offset 0..3) — device-snapped in
280
+ // 'geometry' pixel-snap mode, otherwise the logical local bounds.
281
+ const bounds = this._activeBounds ?? sprite.getLocalBounds();
262
282
  f32[offset + 0] = bounds.left;
263
283
  f32[offset + 1] = bounds.top;
264
284
  f32[offset + 2] = bounds.right;