@babylonjs/lite 1.5.0 → 1.6.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.
- package/dist/index.js +440 -446
- package/dist/index.js.map +1 -1
- package/index.d.ts +90 -46
- package/lib/camera/geospatial-camera-controls.js +22 -0
- package/lib/camera/geospatial-camera-controls.js.map +1 -1
- package/lib/camera/geospatial-camera-fly.js +2 -1
- package/lib/camera/geospatial-camera-fly.js.map +1 -1
- package/lib/effect/effect-renderer.js +1 -1
- package/lib/effect/effect-renderer.js.map +1 -1
- package/lib/engine/engine.js +1 -1
- package/lib/index.js +4 -1
- package/lib/index.js.map +1 -1
- package/lib/post-process/taa.js +193 -0
- package/lib/post-process/taa.js.map +1 -0
- package/lib/sprite/billboard-custom-shader.js +32 -32
- package/lib/sprite/billboard-custom-shader.js.map +1 -1
- package/lib/sprite/billboard-pipeline.js +54 -56
- package/lib/sprite/billboard-pipeline.js.map +1 -1
- package/lib/sprite/custom-shader-core.js +1 -1
- package/lib/sprite/custom-shader-core.js.map +1 -1
- package/lib/sprite/shared/sprite-atlas.js +2 -2
- package/lib/sprite/shared/sprite-atlas.js.map +1 -1
- package/lib/sprite/sprite-2d-coverage-gamma.js +58 -0
- package/lib/sprite/sprite-2d-coverage-gamma.js.map +1 -0
- package/lib/sprite/sprite-2d-uvscroll.js +39 -0
- package/lib/sprite/sprite-2d-uvscroll.js.map +1 -0
- package/lib/sprite/sprite-2d.js +6 -40
- package/lib/sprite/sprite-2d.js.map +1 -1
- package/lib/sprite/sprite-coverage-gamma-hook.js +10 -0
- package/lib/sprite/sprite-coverage-gamma-hook.js.map +1 -0
- package/lib/sprite/sprite-custom-shader.js +2 -2
- package/lib/sprite/sprite-custom-shader.js.map +1 -1
- package/lib/sprite/sprite-pipeline.js +56 -71
- package/lib/sprite/sprite-pipeline.js.map +1 -1
- package/lib/sprite/sprite-renderable.js +5 -5
- package/lib/sprite/sprite-renderable.js.map +1 -1
- package/lib/sprite/sprite-renderer.js +4 -4
- package/lib/sprite/sprite-renderer.js.map +1 -1
- package/lib/sprite/sprite-scene.js +1 -1
- package/lib/sprite/sprite-scene.js.map +1 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sprite-renderer.js","sources":["../../../src/sprite/sprite-renderer.ts"],"sourcesContent":["/**\n * `SpriteRenderer` — owns the shared index buffer and per-layer GPU state\n * required to draw `Sprite2DLayer`s. Implements\n * `RenderingContext` directly, so it plugs into `engine._renderingContexts`\n * the same way a `SceneContext` does.\n *\n * Scope:\n * - Pure-2D / HUD path only — all layers must use `depth: \"none\"`.\n * - One sprite-pipeline cache per renderer instance, keyed by format,\n * blend mode, and sample count. The direct HUD path always uses\n * `sampleCount=1` and `hasDepth=false`.\n * - The renderer opens a sprite-only swapchain pass using the engine's\n * current command encoder and swapchain view. Off-screen / HUD-to-texture\n * rendering is deferred until there is a concrete caller.\n */\nimport { F32 } from \"../engine/typed-arrays.js\";\nimport { BU } from \"../engine/gpu-flags.js\";\nimport { registerRenderingContext, unregisterRenderingContext, getRenderTargetSize } from \"../engine/engine.js\";\nimport type { RenderingContext } from \"../engine/engine.js\";\nimport type { SurfaceContext } from \"../engine/surface.js\";\nimport { createEmptyUniformBuffer, createMappedBuffer } from \"../resource/gpu-buffers.js\";\nimport type { SpriteLayerFx } from \"./custom-shader-core.js\";\nimport { _getSpriteFxHook } from \"./sprite-fx-hook.js\";\nimport type { Sprite2DLayer } from \"./sprite-2d.js\";\nimport type { Texture2D } from \"../texture/texture-2d.js\";\nimport {\n LAYER_UBO_BYTES,\n SHARED_SPRITE_INDEX_DATA,\n buildSpriteLayerUbo,\n createSpriteInstanceBuffer,\n createSpriteLayerBindGroup,\n createSpritePipelineCache,\n ensureSpriteInstanceBuffer,\n getOrCreateSpritePipeline,\n getSpritePipelineCacheSize,\n resetSpritePipelineCache,\n uploadSpriteInstances,\n writeSpriteLayerUboIfDirty,\n} from \"./sprite-pipeline.js\";\nimport type { SpritePipelineCache } from \"./sprite-pipeline.js\";\n\n/** Tag used by the engine and by tests to identify a sprite renderer. */\nconst KIND = \"sprite-renderer\" as const;\n\n/** Options accepted by `createSpriteRenderer`. */\nexport interface SpriteRendererOptions {\n /** Layers to draw, in registration order. The renderer also re-sorts internally each frame. */\n layers: readonly Sprite2DLayer[];\n /** Default true. Set false for HUD overlays so the sprite pass preserves existing scene color. */\n clear?: boolean;\n /** Default `{ r: 0, g: 0, b: 0, a: 1 }`. */\n clearValue?: GPUColorDict;\n}\n\n/**\n * A `SpriteRenderer` — pure data, plugs into `engine._renderingContexts`.\n * Inherits `clearColor`, `_drawCallsPre`, `_update`, `_record` from `RenderingContext`;\n * adds only its discriminator tag and the renderer-owned layer list.\n *\n * **Lifecycle.** A `SpriteRenderer` is independent of any `SceneContext` — it is\n * registered directly on the engine, opens its own sampleCount=1 swapchain pass, and\n * must be disposed by the caller. Two patterns:\n *\n * 1. **Standalone** (no scene, or one or more renderers alongside a scene):\n * `registerSpriteRenderer` after `createSpriteRenderer`, `disposeSpriteRenderer`\n * on shutdown. Caller owns the lifetime end-to-end.\n * 2. **HUD-on-3D** (renderer overlaid on a scene): same `register` step,\n * then tie disposal to the scene with\n * `onSceneDispose(scene, () => disposeSpriteRenderer(hud))` —\n * `disposeScene` then cleans it up automatically. Register the renderer\n * *after* `registerScene` so it draws on top.\n *\n * Scene 52 demonstrates pattern (2). For depth-hosted sprites that should\n * sort against 3D meshes, use `addDepthHostedSpriteLayer(scene, layer)` with\n * a depth-enabled `Sprite2DLayer` instead — that route is fully owned by the scene.\n */\nexport interface SpriteRenderer extends RenderingContext {\n /** @internal */\n readonly _kind: typeof KIND;\n /** Renderer-owned layer membership. Use `addSpriteRendererLayer` / `removeSpriteRendererLayer` to mutate. */\n readonly layers: readonly Sprite2DLayer[];\n /** @internal Mutable alias of {@link layers} — same array, used by internal helpers. */\n _layers: Sprite2DLayer[];\n /** @internal Surface this renderer draws into. */\n _surface: SurfaceContext;\n /** @internal */\n _indexBuffer: GPUBuffer;\n /** @internal */\n _pipelineCache: SpritePipelineCache;\n /** @internal */\n _layerGpu: Map<Sprite2DLayer, LayerGpu>;\n /** @internal Hooks run at the start of `_update`, before layer uploads. */\n _beforeUpdate: ((deltaMs: number) => void)[];\n /** @internal Cleanup callbacks run by `disposeSpriteRenderer`; optional integrations register here. */\n _disposeCallbacks: (() => void)[];\n /** @internal */\n _visibleBundles: GPURenderBundle[];\n /** @internal Captured each `_update`, read in `_record`. */\n _targetWidth: number;\n /** @internal */\n _targetHeight: number;\n /** @internal */\n _disposed: boolean;\n /** @internal Whether this pass clears the swapchain before drawing. False for HUD overlays. */\n _clear: boolean;\n /** @internal Offscreen color-attachment view to render into; null = the swapchain.\n * Set via {@link setSpriteRendererTarget} (which takes a {@link Texture2D} target)\n * for render-to-texture / post-process. */\n _targetView: GPUTextureView | null;\n}\n\n/** @internal Per-layer GPU resources owned by the renderer. */\ninterface LayerGpu {\n layer: Sprite2DLayer;\n instanceBuffer: GPUBuffer;\n instanceBufferCapacity: number;\n uniformBuffer: GPUBuffer;\n /** Built once per layer; the bind group binds the uniform buffer + atlas texture/sampler,\n * none of which change after construction (atlas is `readonly` on the layer; uniform\n * buffer is allocated once in `ensureLayerGpu`). Cleared if we ever recreate either. */\n bindGroup: GPUBindGroup | null;\n uploadedVersion: number;\n /** Opaque fx attachment (`SpriteFx` UBO, scratch, elapsed time); non-null only for `customShader` layers. */\n fx: SpriteLayerFx | null;\n /** Cached pipeline object. Refreshed when target-defining GPU state resolves to a different pipeline. */\n pipeline: GPURenderPipeline | null;\n /** Snapshot of the last UBO bytes written to `uniformBuffer`. We rebuild the UBO into\n * `_scratchUbo` each frame, then `writeBuffer` only if the contents actually changed.\n * For static scenes (steady-state) this skips one `queue.writeBuffer` per layer per frame. */\n lastUbo: Float32Array;\n /** False until the first UBO upload. Forces an unconditional first write so `lastUbo` is real. */\n uboUploaded: boolean;\n /** Pre-recorded GPU command bundle: `setIndexBuffer` + `setPipeline` + `setBindGroup` +\n * `setVertexBuffer` + `drawIndexed`. Collected into a reused bundle array for\n * near-zero per-frame CPU command-recording cost (the big WebGPU win for static scenes —\n * see `scene-core.ts._record` for the same pattern). Invalidated when `layer.count` changes\n * (the `drawIndexed` instance count is baked into the bundle) or when the instance buffer is\n * reallocated by `ensureLayerGpu` (the bundle holds a GPUBuffer reference). The UBO contents\n * may freely change frame-to-frame — the bundle binds the buffer *object*, not its bytes. */\n renderBundle: GPURenderBundle | null;\n /** `layer.count` value the cached `renderBundle` was recorded against. */\n bundleCount: number;\n}\n\n/**\n * Lazy GPU-resource provisioner for one layer. On first sight: allocates the per-instance\n * vertex buffer + the 48 B layer UBO and stashes a `LayerGpu` record in `_layerGpu`. On\n * subsequent calls where the layer's CPU `_capacity` outgrew the GPU buffer (after\n * `growCapacity` doubled the array): destroys + reallocates the instance buffer at the\n * new size and forces a full re-upload via `uploadedVersion = -1`. The bind group is\n * left intact — it doesn't reference the instance buffer (vertex buffers are bound\n * separately at draw time), only the uniform buffer + atlas, neither of which moves.\n */\nfunction ensureLayerGpu(rr: SpriteRenderer, layer: Sprite2DLayer): LayerGpu {\n let lg = rr._layerGpu.get(layer);\n if (!lg) {\n const cap = layer._capacity;\n const instanceBuffer = createSpriteInstanceBuffer(rr._surface.engine._device, layer, \"sprite-layer-instances\");\n const uniformBuffer = createEmptyUniformBuffer(rr._surface.engine, LAYER_UBO_BYTES, \"sprite-layer-ubo\");\n const fx = _getSpriteFxHook()?.createLayerFx(rr._surface.engine, \"sprite-layer-fx-ubo\", layer) ?? null;\n lg = {\n layer,\n instanceBuffer,\n instanceBufferCapacity: cap,\n uniformBuffer,\n bindGroup: null,\n uploadedVersion: -1,\n fx,\n pipeline: null,\n lastUbo: new F32(LAYER_UBO_BYTES / 4),\n uboUploaded: false,\n renderBundle: null,\n bundleCount: -1,\n };\n rr._layerGpu.set(layer, lg);\n }\n const grown = ensureSpriteInstanceBuffer(rr._surface.engine._device, layer, lg.instanceBuffer, lg.instanceBufferCapacity, \"sprite-layer-instances\");\n if (grown.reallocated) {\n lg.instanceBuffer = grown.buffer;\n lg.instanceBufferCapacity = grown.capacity;\n lg.uploadedVersion = -1;\n // Bundle baked a reference to the *old* GPUBuffer; the new buffer needs a re-record.\n lg.renderBundle = null;\n }\n return lg;\n}\n\n/** Sync one layer's GPU state to its CPU state — instance vertex data + per-layer UBO.\n * Both helpers are version-/dirty-gated and skip work in the steady state. */\nfunction uploadLayer(rr: SpriteRenderer, lg: LayerGpu, deltaMs: number): void {\n const layer = lg.layer;\n lg.uploadedVersion = uploadSpriteInstances(rr._surface.engine._device, layer, lg.instanceBuffer, lg.uploadedVersion);\n buildSpriteLayerUbo(layer, rr._targetWidth, rr._targetHeight, _scratchUbo);\n lg.uboUploaded = writeSpriteLayerUboIfDirty(rr._surface.engine._device, lg.uniformBuffer, _scratchUbo, lg.lastUbo, lg.uboUploaded);\n if (lg.fx) {\n _getSpriteFxHook()!.updateFx(lg.fx, layer, deltaMs);\n }\n}\n\nfunction disposeLayerGpu(lg: LayerGpu): void {\n lg.instanceBuffer.destroy();\n lg.uniformBuffer.destroy();\n if (lg.fx) {\n _getSpriteFxHook()!.disposeFx(lg.fx);\n }\n}\n\nconst _scratchUbo = new F32(LAYER_UBO_BYTES / 4);\n\n/**\n * Build (and cache) the bind group that attaches `lg.uniformBuffer` + atlas texture +\n * sampler to the pipeline's sprite `@group(0)` schema. All three resources are immutable for\n * the layer's lifetime, so this runs at most once per layer; subsequent calls return\n * the cached group. The instance buffer is **not** in the bind group — it's a vertex\n * buffer, bound separately at draw time — which is why instance-buffer growth in\n * `ensureLayerGpu` doesn't invalidate this cache.\n */\nfunction ensureBindGroup(rr: SpriteRenderer, lg: LayerGpu, pipeline: GPURenderPipeline): GPUBindGroup {\n if (lg.bindGroup) {\n return lg.bindGroup;\n }\n lg.bindGroup = createSpriteLayerBindGroup(rr._surface.engine, pipeline, 0, lg.layer, lg.uniformBuffer, lg.fx);\n return lg.bindGroup;\n}\n\n/** Sort key for layers within a renderer: ascending `order` (back-to-front draw order). */\nfunction compareLayers(a: Sprite2DLayer, b: Sprite2DLayer): number {\n if (a.order !== b.order) {\n return a.order - b.order;\n }\n return 0;\n}\n\n/** Create a `SpriteRenderer` for `surface`, pre-warming pipelines for the layers' blend\n * modes. Pass the engine directly for the common single-canvas case (since\n * `EngineContext extends SurfaceContext`); pass an auxiliary surface created via\n * `createSurface` for multi-canvas. */\nexport function createSpriteRenderer(surface: SurfaceContext, opts: SpriteRendererOptions): SpriteRenderer {\n const engine = surface.engine;\n assertSpriteRendererLayers(opts.layers);\n const indexBuffer = createMappedBuffer(engine, SHARED_SPRITE_INDEX_DATA, BU.INDEX);\n const canvas = surface.canvas;\n\n const layers = opts.layers.slice();\n const rr: SpriteRenderer = {\n _kind: KIND,\n _surface: surface,\n _indexBuffer: indexBuffer,\n _pipelineCache: createSpritePipelineCache(),\n _layerGpu: new Map(),\n _visibleBundles: [],\n _targetWidth: canvas.width,\n _targetHeight: canvas.height,\n _disposed: false,\n _clear: opts.clear ?? true,\n _targetView: null,\n _beforeUpdate: [],\n _disposeCallbacks: [],\n layers,\n _layers: layers,\n clearColor: opts.clearValue ?? { r: 0, g: 0, b: 0, a: 1 },\n _drawCallsPre: 0,\n _update(): void {\n spriteRendererUpdate(rr);\n },\n _record(): number {\n return spriteRendererRecord(rr);\n },\n };\n\n // Pre-warm pipelines currently in use, so the first frame doesn't pay compile cost.\n for (const layer of rr.layers) {\n getOrCreateSpritePipeline(engine, rr._pipelineCache, surface.format, 1, layer.blendMode, false, false, undefined, undefined, layer);\n }\n\n return rr;\n}\n\nfunction assertSpriteRendererLayers(layers: readonly Sprite2DLayer[]): void {\n for (const layer of layers) {\n assertSpriteRendererLayer(layer);\n }\n}\n\nfunction assertSpriteRendererLayer(layer: Sprite2DLayer): void {\n if (layer.depth !== \"none\") {\n throw new Error('SpriteRenderer only supports Sprite2DLayer with depth: \"none\". Use addDepthHostedSpriteLayer(scene, layer) for depth-hosted sprites.');\n }\n}\n\n/**\n * Per-frame **update** pass (called by the engine before this renderer records its pass).\n * Refreshes target dims (canvas may have resized), sorts `rr.layers` in place by\n * `order` (TimSort is O(n) on already-sorted input — effectively free in steady state),\n * then walks every visible non-empty layer and runs `ensureLayerGpu` + `uploadLayer`.\n * No GPU draw work here — only buffer uploads via `writeBuffer`.\n */\nfunction spriteRendererUpdate(rr: SpriteRenderer): void {\n if (rr._disposed) {\n return;\n }\n const deltaMs = rr._surface.engine._currentDelta ?? 0;\n for (const hook of rr._beforeUpdate) {\n hook(deltaMs);\n }\n assertSpriteRendererLayers(rr.layers);\n const targetSize = getRenderTargetSize(rr._surface);\n rr._targetWidth = targetSize.width;\n rr._targetHeight = targetSize.height;\n\n // Sort layers in place by `order` once per frame. TimSort is O(n) on already-sorted input,\n // so this is effectively free in the steady state. Documented side-effect on `rr.layers`\n // (registration order is not the ground truth — `layer.order` is). Skipped for the common\n // single-layer case to avoid even the comparator-call overhead.\n if (rr.layers.length > 1) {\n rr._layers.sort(compareLayers);\n }\n\n for (const layer of rr.layers) {\n if (!layer.visible || layer.count === 0) {\n continue;\n }\n const lg = ensureLayerGpu(rr, layer);\n uploadLayer(rr, lg, deltaMs);\n }\n}\n\n/**\n * Per-frame **record** pass (called by the engine after `_update`).\n * For each visible non-empty layer: builds (or reuses) a `GPURenderBundle` that bakes\n * `setIndexBuffer` + `setPipeline` + `setBindGroup` + `setVertexBuffer` + `drawIndexed`,\n * then queues it for a single `pass.executeBundles(...)` replay. The bundle is the per-frame\n * fast path — it skips Chromium's per-call WebGPU validation and IPC, which dominates\n * CPU cost for static scenes at multi-kHz framerates. Bundle is rebuilt only when\n * `layer.count` changes or the instance buffer was reallocated.\n * Returns one draw call per visible non-empty layer (1000 sprites in a layer = 1 draw\n * call thanks to instancing).\n */\nfunction spriteRendererRecord(rr: SpriteRenderer): number {\n if (rr._disposed) {\n return 0;\n }\n assertSpriteRendererLayers(rr.layers);\n const eng = rr._surface.engine;\n const encoder = eng._currentEncoder;\n const swapView = rr._targetView ?? eng.scRT._colorView!;\n\n // Open a sampleCount=1 render pass on the target view (the swapchain by default, or an\n // offscreen render texture when one is set via setSpriteRendererTarget). This keeps HUD\n // sprites from resolving a fresh MSAA target over the already-rendered scene.\n const pass = encoder.beginRenderPass({\n colorAttachments: [\n {\n view: swapView,\n clearValue: rr.clearColor,\n loadOp: rr._clear ? \"clear\" : \"load\",\n storeOp: \"store\",\n },\n ],\n });\n let drawCalls = 0;\n const visibleBundles = rr._visibleBundles;\n visibleBundles.length = 0;\n\n for (const layer of rr.layers) {\n if (!layer.visible || layer.count === 0) {\n continue;\n }\n const lg = rr._layerGpu.get(layer);\n if (!lg) {\n continue;\n }\n const sampleCount = 1;\n const pipeline = getOrCreateSpritePipeline(\n rr._surface.engine,\n rr._pipelineCache,\n rr._surface.format,\n sampleCount,\n layer.blendMode,\n false,\n false,\n undefined,\n undefined,\n layer\n );\n if (lg.pipeline !== pipeline) {\n lg.pipeline = pipeline;\n lg.bindGroup = null;\n lg.renderBundle = null;\n }\n const bg = ensureBindGroup(rr, lg, pipeline);\n // (Re)record the bundle when count changes (drawIndexed instance count is baked in)\n // or when ensureLayerGpu reallocated the instance buffer (renderBundle was nulled).\n if (lg.renderBundle == null || lg.bundleCount !== layer.count) {\n const be = rr._surface.engine._device.createRenderBundleEncoder({\n colorFormats: [rr._surface.format],\n sampleCount,\n });\n be.setIndexBuffer(rr._indexBuffer, \"uint16\");\n be.setPipeline(pipeline);\n be.setBindGroup(0, bg);\n be.setVertexBuffer(0, lg.instanceBuffer);\n be.drawIndexed(6, layer.count, 0, 0, 0);\n lg.renderBundle = be.finish();\n lg.bundleCount = layer.count;\n }\n visibleBundles.push(lg.renderBundle!);\n drawCalls++;\n }\n\n if (visibleBundles.length > 0) {\n pass.executeBundles(visibleBundles);\n }\n pass.end();\n return drawCalls;\n}\n\n/** Add a pure-2D layer to the renderer. No-op if the layer is already present. */\nexport function addSpriteRendererLayer(sr: SpriteRenderer, layer: Sprite2DLayer): void {\n if (sr._disposed) {\n throw new Error(\"SpriteRenderer has been disposed.\");\n }\n assertSpriteRendererLayer(layer);\n if (sr.layers.includes(layer)) {\n return;\n }\n sr._layers.push(layer);\n getOrCreateSpritePipeline(sr._surface.engine, sr._pipelineCache, sr._surface.format, 1, layer.blendMode, false);\n}\n\n/** Remove a layer from the renderer and destroy any GPU resources cached for it. */\nexport function removeSpriteRendererLayer(sr: SpriteRenderer, layer: Sprite2DLayer): boolean {\n const index = sr.layers.indexOf(layer);\n if (index < 0) {\n return false;\n }\n sr._layers.splice(index, 1);\n const lg = sr._layerGpu.get(layer);\n if (lg) {\n disposeLayerGpu(lg);\n sr._layerGpu.delete(layer);\n }\n return true;\n}\n\n/** Push the renderer onto its engine's `_renderingContexts`. Idempotent — a second call is a no-op. */\nexport function registerSpriteRenderer(sr: SpriteRenderer): void {\n registerRenderingContext(sr._surface, sr);\n}\n\n/**\n * Redirect a sprite renderer's output to an offscreen render {@link Texture2D} `target` (for\n * render-to-texture / post-processing), or pass `null` to render to the swapchain (the\n * default). Pair with {@link createRenderTexture2D} at its default format and the renderer's\n * target size. The target's texture must be the engine's swapchain format: sprite pipelines\n * are baked with `engine.format`, so a target of any OTHER format fails WebGPU validation at\n * render-pass begin. A second renderer can then sample that texture (e.g. a fullscreen\n * custom-shader layer) and present it. Renderers registered later run later, so register the\n * offscreen scene pass before the presenting pass.\n */\nexport function setSpriteRendererTarget(sr: SpriteRenderer, target: Texture2D | null): void {\n sr._targetView = target ? target.view : null;\n}\n\n/** Splice the renderer out of its engine's `_renderingContexts`. No-op if not present. */\nexport function unregisterSpriteRenderer(sr: SpriteRenderer): void {\n unregisterRenderingContext(sr._surface, sr);\n}\n\n/**\n * Destroy all GPU resources owned by the renderer, unregister it from the engine, and clear `layers`.\n * Idempotent. To tie disposal to a scene, call\n * `onSceneDispose(scene, () => disposeSpriteRenderer(sr))` after `registerSpriteRenderer` —\n * see the `SpriteRenderer` doc-comment.\n */\nexport function disposeSpriteRenderer(sr: SpriteRenderer): void {\n if (sr._disposed) {\n return;\n }\n unregisterSpriteRenderer(sr);\n sr._disposed = true;\n const disposeCallbacks = sr._disposeCallbacks.slice();\n sr._disposeCallbacks.length = 0;\n for (const dispose of disposeCallbacks) {\n dispose();\n }\n for (const lg of sr._layerGpu.values()) {\n disposeLayerGpu(lg);\n }\n sr._layerGpu.clear();\n sr._visibleBundles.length = 0;\n sr._beforeUpdate.length = 0;\n sr._indexBuffer.destroy();\n resetSpritePipelineCache(sr._pipelineCache);\n sr._layers.length = 0;\n}\n\n/** @internal Test-only accessor for pipeline-cache size. */\nexport function _spriteRendererPipelineCacheSize(sr: SpriteRenderer): number {\n return getSpritePipelineCacheSize(sr._pipelineCache, sr._surface.engine._device);\n}\n"],"names":[],"mappings":";;;;;;;AA0CA,MAAM,IAAA,GAAO,iBAAA;AA+Gb,SAAS,cAAA,CAAe,IAAoB,KAAA,EAAgC;AACxE,EAAA,IAAI,EAAA,GAAK,EAAA,CAAG,SAAA,CAAU,GAAA,CAAI,KAAK,CAAA;AAC/B,EAAA,IAAI,CAAC,EAAA,EAAI;AACL,IAAA,MAAM,MAAM,KAAA,CAAM,SAAA;AAClB,IAAA,MAAM,iBAAiB,0BAAA,CAA2B,EAAA,CAAG,SAAS,MAAA,CAAO,OAAA,EAAS,OAAO,wBAAwB,CAAA;AAC7G,IAAA,MAAM,gBAAgB,wBAAA,CAAyB,EAAA,CAAG,QAAA,CAAS,MAAA,EAAQ,iBAAiB,kBAAkB,CAAA;AACtG,IAAA,MAAM,EAAA,GAAK,kBAAiB,EAAG,aAAA,CAAc,GAAG,QAAA,CAAS,MAAA,EAAQ,qBAAA,EAAuB,KAAK,CAAA,IAAK,IAAA;AAClG,IAAA,EAAA,GAAK;AAAA,MACD,KAAA;AAAA,MACA,cAAA;AAAA,MACA,sBAAA,EAAwB,GAAA;AAAA,MACxB,aAAA;AAAA,MACA,SAAA,EAAW,IAAA;AAAA,MACX,eAAA,EAAiB,EAAA;AAAA,MACjB,EAAA;AAAA,MACA,QAAA,EAAU,IAAA;AAAA,MACV,OAAA,EAAS,IAAI,GAAA,CAAI,eAAA,GAAkB,CAAC,CAAA;AAAA,MACpC,WAAA,EAAa,KAAA;AAAA,MACb,YAAA,EAAc,IAAA;AAAA,MACd,WAAA,EAAa;AAAA,KACjB;AACA,IAAA,EAAA,CAAG,SAAA,CAAU,GAAA,CAAI,KAAA,EAAO,EAAE,CAAA;AAAA,EAC9B;AACA,EAAA,MAAM,KAAA,GAAQ,0BAAA,CAA2B,EAAA,CAAG,QAAA,CAAS,MAAA,CAAO,OAAA,EAAS,KAAA,EAAO,EAAA,CAAG,cAAA,EAAgB,EAAA,CAAG,sBAAA,EAAwB,wBAAwB,CAAA;AAClJ,EAAA,IAAI,MAAM,WAAA,EAAa;AACnB,IAAA,EAAA,CAAG,iBAAiB,KAAA,CAAM,MAAA;AAC1B,IAAA,EAAA,CAAG,yBAAyB,KAAA,CAAM,QAAA;AAClC,IAAA,EAAA,CAAG,eAAA,GAAkB,EAAA;AAErB,IAAA,EAAA,CAAG,YAAA,GAAe,IAAA;AAAA,EACtB;AACA,EAAA,OAAO,EAAA;AACX;AAIA,SAAS,WAAA,CAAY,EAAA,EAAoB,EAAA,EAAc,OAAA,EAAuB;AAC1E,EAAA,MAAM,QAAQ,EAAA,CAAG,KAAA;AACjB,EAAA,EAAA,CAAG,eAAA,GAAkB,qBAAA,CAAsB,EAAA,CAAG,QAAA,CAAS,MAAA,CAAO,SAAS,KAAA,EAAO,EAAA,CAAG,cAAA,EAAgB,EAAA,CAAG,eAAe,CAAA;AACnH,EAAA,mBAAA,CAAoB,KAAA,EAAO,EAAA,CAAG,YAAA,EAAc,EAAA,CAAG,eAAe,WAAW,CAAA;AACzE,EAAA,EAAA,CAAG,WAAA,GAAc,0BAAA,CAA2B,EAAA,CAAG,QAAA,CAAS,MAAA,CAAO,OAAA,EAAS,EAAA,CAAG,aAAA,EAAe,WAAA,EAAa,EAAA,CAAG,OAAA,EAAS,EAAA,CAAG,WAAW,CAAA;AACjI,EAAA,IAAI,GAAG,EAAA,EAAI;AACP,IAAA,gBAAA,EAAiB,CAAG,QAAA,CAAS,EAAA,CAAG,EAAA,EAAI,OAAO,OAAO,CAAA;AAAA,EACtD;AACJ;AAEA,SAAS,gBAAgB,EAAA,EAAoB;AACzC,EAAA,EAAA,CAAG,eAAe,OAAA,EAAQ;AAC1B,EAAA,EAAA,CAAG,cAAc,OAAA,EAAQ;AACzB,EAAA,IAAI,GAAG,EAAA,EAAI;AACP,IAAA,gBAAA,EAAiB,CAAG,SAAA,CAAU,EAAA,CAAG,EAAE,CAAA;AAAA,EACvC;AACJ;AAEA,MAAM,WAAA,GAAc,IAAI,GAAA,CAAI,eAAA,GAAkB,CAAC,CAAA;AAU/C,SAAS,eAAA,CAAgB,EAAA,EAAoB,EAAA,EAAc,QAAA,EAA2C;AAClG,EAAA,IAAI,GAAG,SAAA,EAAW;AACd,IAAA,OAAO,EAAA,CAAG,SAAA;AAAA,EACd;AACA,EAAA,EAAA,CAAG,SAAA,GAAY,0BAAA,CAA2B,EAAA,CAAG,QAAA,CAAS,MAAA,EAAQ,QAAA,EAAU,CAAA,EAAG,EAAA,CAAG,KAAA,EAAO,EAAA,CAAG,aAAA,EAAe,EAAA,CAAG,EAAE,CAAA;AAC5G,EAAA,OAAO,EAAA,CAAG,SAAA;AACd;AAGA,SAAS,aAAA,CAAc,GAAkB,CAAA,EAA0B;AAC/D,EAAA,IAAI,CAAA,CAAE,KAAA,KAAU,CAAA,CAAE,KAAA,EAAO;AACrB,IAAA,OAAO,CAAA,CAAE,QAAQ,CAAA,CAAE,KAAA;AAAA,EACvB;AACA,EAAA,OAAO,CAAA;AACX;AAMO,SAAS,oBAAA,CAAqB,SAAyB,IAAA,EAA6C;AACvG,EAAA,MAAM,SAAS,OAAA,CAAQ,MAAA;AACvB,EAAA,0BAAA,CAA2B,KAAK,MAAM,CAAA;AACtC,EAAA,MAAM,WAAA,GAAc,kBAAA,CAAmB,MAAA,EAAQ,wBAAA,EAA0B,GAAG,KAAK,CAAA;AACjF,EAAA,MAAM,SAAS,OAAA,CAAQ,MAAA;AAEvB,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,KAAA,EAAM;AACjC,EAAA,MAAM,EAAA,GAAqB;AAAA,IACvB,KAAA,EAAO,IAAA;AAAA,IACP,QAAA,EAAU,OAAA;AAAA,IACV,YAAA,EAAc,WAAA;AAAA,IACd,gBAAgB,yBAAA,EAA0B;AAAA,IAC1C,SAAA,sBAAe,GAAA,EAAI;AAAA,IACnB,iBAAiB,EAAC;AAAA,IAClB,cAAc,MAAA,CAAO,KAAA;AAAA,IACrB,eAAe,MAAA,CAAO,MAAA;AAAA,IACtB,SAAA,EAAW,KAAA;AAAA,IACX,MAAA,EAAQ,KAAK,KAAA,IAAS,IAAA;AAAA,IACtB,WAAA,EAAa,IAAA;AAAA,IACb,eAAe,EAAC;AAAA,IAChB,mBAAmB,EAAC;AAAA,IACpB,MAAA;AAAA,IACA,OAAA,EAAS,MAAA;AAAA,IACT,UAAA,EAAY,IAAA,CAAK,UAAA,IAAc,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAE;AAAA,IACxD,aAAA,EAAe,CAAA;AAAA,IACf,OAAA,GAAgB;AACZ,MAAA,oBAAA,CAAqB,EAAE,CAAA;AAAA,IAC3B,CAAA;AAAA,IACA,OAAA,GAAkB;AACd,MAAA,OAAO,qBAAqB,EAAE,CAAA;AAAA,IAClC;AAAA,GACJ;AAGA,EAAA,KAAA,MAAW,KAAA,IAAS,GAAG,MAAA,EAAQ;AAC3B,IAAA,yBAAA,CAA0B,MAAA,EAAQ,EAAA,CAAG,cAAA,EAAgB,OAAA,CAAQ,MAAA,EAAQ,CAAA,EAAG,KAAA,CAAM,SAAA,EAAW,KAAA,EAAO,KAAA,EAAO,MAAA,EAAW,MAAA,EAAW,KAAK,CAAA;AAAA,EACtI;AAEA,EAAA,OAAO,EAAA;AACX;AAEA,SAAS,2BAA2B,MAAA,EAAwC;AACxE,EAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AACxB,IAAA,yBAAA,CAA0B,KAAK,CAAA;AAAA,EACnC;AACJ;AAEA,SAAS,0BAA0B,KAAA,EAA4B;AAC3D,EAAA,IAAI,KAAA,CAAM,UAAU,MAAA,EAAQ;AACxB,IAAA,MAAM,IAAI,MAAM,sIAAsI,CAAA;AAAA,EAC1J;AACJ;AASA,SAAS,qBAAqB,EAAA,EAA0B;AACpD,EAAA,IAAI,GAAG,SAAA,EAAW;AACd,IAAA;AAAA,EACJ;AACA,EAAA,MAAM,OAAA,GAAU,EAAA,CAAG,QAAA,CAAS,MAAA,CAAO,aAAA,IAAiB,CAAA;AACpD,EAAA,KAAA,MAAW,IAAA,IAAQ,GAAG,aAAA,EAAe;AACjC,IAAA,IAAA,CAAK,OAAO,CAAA;AAAA,EAChB;AACA,EAAA,0BAAA,CAA2B,GAAG,MAAM,CAAA;AACpC,EAAA,MAAM,UAAA,GAAa,mBAAA,CAAoB,EAAA,CAAG,QAAQ,CAAA;AAClD,EAAA,EAAA,CAAG,eAAe,UAAA,CAAW,KAAA;AAC7B,EAAA,EAAA,CAAG,gBAAgB,UAAA,CAAW,MAAA;AAM9B,EAAA,IAAI,EAAA,CAAG,MAAA,CAAO,MAAA,GAAS,CAAA,EAAG;AACtB,IAAA,EAAA,CAAG,OAAA,CAAQ,KAAK,aAAa,CAAA;AAAA,EACjC;AAEA,EAAA,KAAA,MAAW,KAAA,IAAS,GAAG,MAAA,EAAQ;AAC3B,IAAA,IAAI,CAAC,KAAA,CAAM,OAAA,IAAW,KAAA,CAAM,UAAU,CAAA,EAAG;AACrC,MAAA;AAAA,IACJ;AACA,IAAA,MAAM,EAAA,GAAK,cAAA,CAAe,EAAA,EAAI,KAAK,CAAA;AACnC,IAAA,WAAA,CAAY,EAAA,EAAI,IAAI,OAAO,CAAA;AAAA,EAC/B;AACJ;AAaA,SAAS,qBAAqB,EAAA,EAA4B;AACtD,EAAA,IAAI,GAAG,SAAA,EAAW;AACd,IAAA,OAAO,CAAA;AAAA,EACX;AACA,EAAA,0BAAA,CAA2B,GAAG,MAAM,CAAA;AACpC,EAAA,MAAM,GAAA,GAAM,GAAG,QAAA,CAAS,MAAA;AACxB,EAAA,MAAM,UAAU,GAAA,CAAI,eAAA;AACpB,EAAA,MAAM,QAAA,GAAW,EAAA,CAAG,WAAA,IAAe,GAAA,CAAI,IAAA,CAAK,UAAA;AAK5C,EAAA,MAAM,IAAA,GAAO,QAAQ,eAAA,CAAgB;AAAA,IACjC,gBAAA,EAAkB;AAAA,MACd;AAAA,QACI,IAAA,EAAM,QAAA;AAAA,QACN,YAAY,EAAA,CAAG,UAAA;AAAA,QACf,MAAA,EAAQ,EAAA,CAAG,MAAA,GAAS,OAAA,GAAU,MAAA;AAAA,QAC9B,OAAA,EAAS;AAAA;AACb;AACJ,GACH,CAAA;AACD,EAAA,IAAI,SAAA,GAAY,CAAA;AAChB,EAAA,MAAM,iBAAiB,EAAA,CAAG,eAAA;AAC1B,EAAA,cAAA,CAAe,MAAA,GAAS,CAAA;AAExB,EAAA,KAAA,MAAW,KAAA,IAAS,GAAG,MAAA,EAAQ;AAC3B,IAAA,IAAI,CAAC,KAAA,CAAM,OAAA,IAAW,KAAA,CAAM,UAAU,CAAA,EAAG;AACrC,MAAA;AAAA,IACJ;AACA,IAAA,MAAM,EAAA,GAAK,EAAA,CAAG,SAAA,CAAU,GAAA,CAAI,KAAK,CAAA;AACjC,IAAA,IAAI,CAAC,EAAA,EAAI;AACL,MAAA;AAAA,IACJ;AACA,IAAA,MAAM,WAAA,GAAc,CAAA;AACpB,IAAA,MAAM,QAAA,GAAW,yBAAA;AAAA,MACb,GAAG,QAAA,CAAS,MAAA;AAAA,MACZ,EAAA,CAAG,cAAA;AAAA,MACH,GAAG,QAAA,CAAS,MAAA;AAAA,MACZ,WAAA;AAAA,MACA,KAAA,CAAM,SAAA;AAAA,MACN,KAAA;AAAA,MACA,KAAA;AAAA,MACA,MAAA;AAAA,MACA,MAAA;AAAA,MACA;AAAA,KACJ;AACA,IAAA,IAAI,EAAA,CAAG,aAAa,QAAA,EAAU;AAC1B,MAAA,EAAA,CAAG,QAAA,GAAW,QAAA;AACd,MAAA,EAAA,CAAG,SAAA,GAAY,IAAA;AACf,MAAA,EAAA,CAAG,YAAA,GAAe,IAAA;AAAA,IACtB;AACA,IAAA,MAAM,EAAA,GAAK,eAAA,CAAgB,EAAA,EAAI,EAAA,EAAI,QAAQ,CAAA;AAG3C,IAAA,IAAI,GAAG,YAAA,IAAgB,IAAA,IAAQ,EAAA,CAAG,WAAA,KAAgB,MAAM,KAAA,EAAO;AAC3D,MAAA,MAAM,EAAA,GAAK,EAAA,CAAG,QAAA,CAAS,MAAA,CAAO,QAAQ,yBAAA,CAA0B;AAAA,QAC5D,YAAA,EAAc,CAAC,EAAA,CAAG,QAAA,CAAS,MAAM,CAAA;AAAA,QACjC;AAAA,OACH,CAAA;AACD,MAAA,EAAA,CAAG,cAAA,CAAe,EAAA,CAAG,YAAA,EAAc,QAAQ,CAAA;AAC3C,MAAA,EAAA,CAAG,YAAY,QAAQ,CAAA;AACvB,MAAA,EAAA,CAAG,YAAA,CAAa,GAAG,EAAE,CAAA;AACrB,MAAA,EAAA,CAAG,eAAA,CAAgB,CAAA,EAAG,EAAA,CAAG,cAAc,CAAA;AACvC,MAAA,EAAA,CAAG,YAAY,CAAA,EAAG,KAAA,CAAM,KAAA,EAAO,CAAA,EAAG,GAAG,CAAC,CAAA;AACtC,MAAA,EAAA,CAAG,YAAA,GAAe,GAAG,MAAA,EAAO;AAC5B,MAAA,EAAA,CAAG,cAAc,KAAA,CAAM,KAAA;AAAA,IAC3B;AACA,IAAA,cAAA,CAAe,IAAA,CAAK,GAAG,YAAa,CAAA;AACpC,IAAA,SAAA,EAAA;AAAA,EACJ;AAEA,EAAA,IAAI,cAAA,CAAe,SAAS,CAAA,EAAG;AAC3B,IAAA,IAAA,CAAK,eAAe,cAAc,CAAA;AAAA,EACtC;AACA,EAAA,IAAA,CAAK,GAAA,EAAI;AACT,EAAA,OAAO,SAAA;AACX;AAGO,SAAS,sBAAA,CAAuB,IAAoB,KAAA,EAA4B;AACnF,EAAA,IAAI,GAAG,SAAA,EAAW;AACd,IAAA,MAAM,IAAI,MAAM,mCAAmC,CAAA;AAAA,EACvD;AACA,EAAA,yBAAA,CAA0B,KAAK,CAAA;AAC/B,EAAA,IAAI,EAAA,CAAG,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,EAAG;AAC3B,IAAA;AAAA,EACJ;AACA,EAAA,EAAA,CAAG,OAAA,CAAQ,KAAK,KAAK,CAAA;AACrB,EAAA,yBAAA,CAA0B,EAAA,CAAG,QAAA,CAAS,MAAA,EAAQ,EAAA,CAAG,cAAA,EAAgB,EAAA,CAAG,QAAA,CAAS,MAAA,EAAQ,CAAA,EAAG,KAAA,CAAM,SAAA,EAAW,KAAK,CAAA;AAClH;AAGO,SAAS,yBAAA,CAA0B,IAAoB,KAAA,EAA+B;AACzF,EAAA,MAAM,KAAA,GAAQ,EAAA,CAAG,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA;AACrC,EAAA,IAAI,QAAQ,CAAA,EAAG;AACX,IAAA,OAAO,KAAA;AAAA,EACX;AACA,EAAA,EAAA,CAAG,OAAA,CAAQ,MAAA,CAAO,KAAA,EAAO,CAAC,CAAA;AAC1B,EAAA,MAAM,EAAA,GAAK,EAAA,CAAG,SAAA,CAAU,GAAA,CAAI,KAAK,CAAA;AACjC,EAAA,IAAI,EAAA,EAAI;AACJ,IAAA,eAAA,CAAgB,EAAE,CAAA;AAClB,IAAA,EAAA,CAAG,SAAA,CAAU,OAAO,KAAK,CAAA;AAAA,EAC7B;AACA,EAAA,OAAO,IAAA;AACX;AAGO,SAAS,uBAAuB,EAAA,EAA0B;AAC7D,EAAA,wBAAA,CAAyB,EAAA,CAAG,UAAU,EAAE,CAAA;AAC5C;AAYO,SAAS,uBAAA,CAAwB,IAAoB,MAAA,EAAgC;AACxF,EAAA,EAAA,CAAG,WAAA,GAAc,MAAA,GAAS,MAAA,CAAO,IAAA,GAAO,IAAA;AAC5C;AAGO,SAAS,yBAAyB,EAAA,EAA0B;AAC/D,EAAA,0BAAA,CAA2B,EAAA,CAAG,UAAU,EAAE,CAAA;AAC9C;AAQO,SAAS,sBAAsB,EAAA,EAA0B;AAC5D,EAAA,IAAI,GAAG,SAAA,EAAW;AACd,IAAA;AAAA,EACJ;AACA,EAAA,wBAAA,CAAyB,EAAE,CAAA;AAC3B,EAAA,EAAA,CAAG,SAAA,GAAY,IAAA;AACf,EAAA,MAAM,gBAAA,GAAmB,EAAA,CAAG,iBAAA,CAAkB,KAAA,EAAM;AACpD,EAAA,EAAA,CAAG,kBAAkB,MAAA,GAAS,CAAA;AAC9B,EAAA,KAAA,MAAW,WAAW,gBAAA,EAAkB;AACpC,IAAA,OAAA,EAAQ;AAAA,EACZ;AACA,EAAA,KAAA,MAAW,EAAA,IAAM,EAAA,CAAG,SAAA,CAAU,MAAA,EAAO,EAAG;AACpC,IAAA,eAAA,CAAgB,EAAE,CAAA;AAAA,EACtB;AACA,EAAA,EAAA,CAAG,UAAU,KAAA,EAAM;AACnB,EAAA,EAAA,CAAG,gBAAgB,MAAA,GAAS,CAAA;AAC5B,EAAA,EAAA,CAAG,cAAc,MAAA,GAAS,CAAA;AAC1B,EAAA,EAAA,CAAG,aAAa,OAAA,EAAQ;AACxB,EAAA,wBAAA,CAAyB,GAAG,cAAc,CAAA;AAC1C,EAAA,EAAA,CAAG,QAAQ,MAAA,GAAS,CAAA;AACxB;AAGO,SAAS,iCAAiC,EAAA,EAA4B;AACzE,EAAA,OAAO,2BAA2B,EAAA,CAAG,cAAA,EAAgB,EAAA,CAAG,QAAA,CAAS,OAAO,OAAO,CAAA;AACnF;;;;"}
|
|
1
|
+
{"version":3,"file":"sprite-renderer.js","sources":["../../../src/sprite/sprite-renderer.ts"],"sourcesContent":["/**\n * `SpriteRenderer` — owns the shared index buffer and per-layer GPU state\n * required to draw `Sprite2DLayer`s. Implements\n * `RenderingContext` directly, so it plugs into `engine._renderingContexts`\n * the same way a `SceneContext` does.\n *\n * Scope:\n * - Pure-2D / HUD path only — all layers must use `depth: \"none\"`.\n * - One sprite-pipeline cache per renderer instance, keyed by format,\n * blend mode, and sample count. The direct HUD path always uses\n * `sampleCount=1` and `hasDepth=false`.\n * - The renderer opens a sprite-only swapchain pass using the engine's\n * current command encoder and swapchain view. Off-screen / HUD-to-texture\n * rendering is deferred until there is a concrete caller.\n */\nimport { F32 } from \"../engine/typed-arrays.js\";\nimport { BU } from \"../engine/gpu-flags.js\";\nimport { registerRenderingContext, unregisterRenderingContext, getRenderTargetSize } from \"../engine/engine.js\";\nimport type { RenderingContext } from \"../engine/engine.js\";\nimport type { SurfaceContext } from \"../engine/surface.js\";\nimport { createEmptyUniformBuffer, createMappedBuffer } from \"../resource/gpu-buffers.js\";\nimport type { SpriteLayerFx } from \"./custom-shader-core.js\";\nimport { _getSpriteFxHook } from \"./sprite-fx-hook.js\";\nimport type { Sprite2DLayer } from \"./sprite-2d.js\";\nimport type { Texture2D } from \"../texture/texture-2d.js\";\nimport {\n LAYER_UBO_BYTES,\n SHARED_SPRITE_INDEX_DATA,\n buildSpriteLayerUbo,\n createSpriteInstanceBuffer,\n createSpriteLayerBindGroup,\n createSpritePipelineCache,\n ensureSpriteInstanceBuffer,\n getOrCreateSpritePipeline,\n getSpritePipelineCacheSize,\n resetSpritePipelineCache,\n uploadSpriteInstances,\n writeSpriteLayerUboIfDirty,\n} from \"./sprite-pipeline.js\";\nimport type { SpritePipelineCache } from \"./sprite-pipeline.js\";\n\n/** Tag used by the engine and by tests to identify a sprite renderer. */\nconst KIND = \"sprite-renderer\" as const;\n\n/** Options accepted by `createSpriteRenderer`. */\nexport interface SpriteRendererOptions {\n /** Layers to draw, in registration order. The renderer also re-sorts internally each frame. */\n layers: readonly Sprite2DLayer[];\n /** Default true. Set false for HUD overlays so the sprite pass preserves existing scene color. */\n clear?: boolean;\n /** Default `{ r: 0, g: 0, b: 0, a: 1 }`. */\n clearValue?: GPUColorDict;\n}\n\n/**\n * A `SpriteRenderer` — pure data, plugs into `engine._renderingContexts`.\n * Inherits `clearColor`, `_drawCallsPre`, `_update`, `_record` from `RenderingContext`;\n * adds only its discriminator tag and the renderer-owned layer list.\n *\n * **Lifecycle.** A `SpriteRenderer` is independent of any `SceneContext` — it is\n * registered directly on the engine, opens its own sampleCount=1 swapchain pass, and\n * must be disposed by the caller. Two patterns:\n *\n * 1. **Standalone** (no scene, or one or more renderers alongside a scene):\n * `registerSpriteRenderer` after `createSpriteRenderer`, `disposeSpriteRenderer`\n * on shutdown. Caller owns the lifetime end-to-end.\n * 2. **HUD-on-3D** (renderer overlaid on a scene): same `register` step,\n * then tie disposal to the scene with\n * `onSceneDispose(scene, () => disposeSpriteRenderer(hud))` —\n * `disposeScene` then cleans it up automatically. Register the renderer\n * *after* `registerScene` so it draws on top.\n *\n * Scene 52 demonstrates pattern (2). For depth-hosted sprites that should\n * sort against 3D meshes, use `addDepthHostedSpriteLayer(scene, layer)` with\n * a depth-enabled `Sprite2DLayer` instead — that route is fully owned by the scene.\n */\nexport interface SpriteRenderer extends RenderingContext {\n /** @internal */\n readonly _kind: typeof KIND;\n /** Renderer-owned layer membership. Use `addSpriteRendererLayer` / `removeSpriteRendererLayer` to mutate. */\n readonly layers: readonly Sprite2DLayer[];\n /** @internal Mutable alias of {@link layers} — same array, used by internal helpers. */\n _layers: Sprite2DLayer[];\n /** @internal Surface this renderer draws into. */\n _surface: SurfaceContext;\n /** @internal */\n _indexBuffer: GPUBuffer;\n /** @internal */\n _pipelineCache: SpritePipelineCache;\n /** @internal */\n _layerGpu: Map<Sprite2DLayer, LayerGpu>;\n /** @internal Hooks run at the start of `_update`, before layer uploads. */\n _beforeUpdate: ((deltaMs: number) => void)[];\n /** @internal Cleanup callbacks run by `disposeSpriteRenderer`; optional integrations register here. */\n _disposeCallbacks: (() => void)[];\n /** @internal */\n _visibleBundles: GPURenderBundle[];\n /** @internal Captured each `_update`, read in `_record`. */\n _targetWidth: number;\n /** @internal */\n _targetHeight: number;\n /** @internal */\n _disposed: boolean;\n /** @internal Whether this pass clears the swapchain before drawing. False for HUD overlays. */\n _clear: boolean;\n /** @internal Offscreen color-attachment view to render into; null = the swapchain.\n * Set via {@link setSpriteRendererTarget} (which takes a {@link Texture2D} target)\n * for render-to-texture / post-process. */\n _targetView: GPUTextureView | null;\n}\n\n/** @internal Per-layer GPU resources owned by the renderer. */\ninterface LayerGpu {\n layer: Sprite2DLayer;\n instanceBuffer: GPUBuffer;\n instanceBufferCapacity: number;\n uniformBuffer: GPUBuffer;\n /** Built once per layer; the bind group binds the uniform buffer + atlas texture/sampler,\n * none of which change after construction (atlas is `readonly` on the layer; uniform\n * buffer is allocated once in `ensureLayerGpu`). Cleared if we ever recreate either. */\n bindGroup: GPUBindGroup | null;\n uploadedVersion: number;\n /** Opaque fx attachment (`SpriteFx` UBO, scratch, elapsed time); non-null only for `customShader` layers. */\n fx: SpriteLayerFx | null;\n /** Cached pipeline object. Refreshed when target-defining GPU state resolves to a different pipeline. */\n pipeline: GPURenderPipeline | null;\n /** Snapshot of the last UBO bytes written to `uniformBuffer`. We rebuild the UBO into\n * `_scratchUbo` each frame, then `writeBuffer` only if the contents actually changed.\n * For static scenes (steady-state) this skips one `queue.writeBuffer` per layer per frame. */\n lastUbo: Float32Array;\n /** False until the first UBO upload. Forces an unconditional first write so `lastUbo` is real. */\n uboUploaded: boolean;\n /** Pre-recorded GPU command bundle: `setIndexBuffer` + `setPipeline` + `setBindGroup` +\n * `setVertexBuffer` + `drawIndexed`. Collected into a reused bundle array for\n * near-zero per-frame CPU command-recording cost (the big WebGPU win for static scenes —\n * see `scene-core.ts._record` for the same pattern). Invalidated when `layer.count` changes\n * (the `drawIndexed` instance count is baked into the bundle) or when the instance buffer is\n * reallocated by `ensureLayerGpu` (the bundle holds a GPUBuffer reference). The UBO contents\n * may freely change frame-to-frame — the bundle binds the buffer *object*, not its bytes. */\n renderBundle: GPURenderBundle | null;\n /** `layer.count` value the cached `renderBundle` was recorded against. */\n bundleCount: number;\n}\n\n/**\n * Lazy GPU-resource provisioner for one layer. On first sight: allocates the per-instance\n * vertex buffer + the 48 B layer UBO and stashes a `LayerGpu` record in `_layerGpu`. On\n * subsequent calls where the layer's CPU `_capacity` outgrew the GPU buffer (after\n * `growCapacity` doubled the array): destroys + reallocates the instance buffer at the\n * new size and forces a full re-upload via `uploadedVersion = -1`. The bind group is\n * left intact — it doesn't reference the instance buffer (vertex buffers are bound\n * separately at draw time), only the uniform buffer + atlas, neither of which moves.\n */\nfunction ensureLayerGpu(rr: SpriteRenderer, layer: Sprite2DLayer): LayerGpu {\n let lg = rr._layerGpu.get(layer);\n if (!lg) {\n const cap = layer._capacity;\n const instanceBuffer = createSpriteInstanceBuffer(rr._surface.engine._device, layer);\n const uniformBuffer = createEmptyUniformBuffer(rr._surface.engine, LAYER_UBO_BYTES);\n const fx = _getSpriteFxHook()?.createLayerFx(rr._surface.engine, \"sprite-layer-fx-ubo\", layer) ?? null;\n lg = {\n layer,\n instanceBuffer,\n instanceBufferCapacity: cap,\n uniformBuffer,\n bindGroup: null,\n uploadedVersion: -1,\n fx,\n pipeline: null,\n lastUbo: new F32(LAYER_UBO_BYTES / 4),\n uboUploaded: false,\n renderBundle: null,\n bundleCount: -1,\n };\n rr._layerGpu.set(layer, lg);\n }\n const grown = ensureSpriteInstanceBuffer(rr._surface.engine._device, layer, lg.instanceBuffer, lg.instanceBufferCapacity);\n if (grown.reallocated) {\n lg.instanceBuffer = grown.buffer;\n lg.instanceBufferCapacity = grown.capacity;\n lg.uploadedVersion = -1;\n // Bundle baked a reference to the *old* GPUBuffer; the new buffer needs a re-record.\n lg.renderBundle = null;\n }\n return lg;\n}\n\n/** Sync one layer's GPU state to its CPU state — instance vertex data + per-layer UBO.\n * Both helpers are version-/dirty-gated and skip work in the steady state. */\nfunction uploadLayer(rr: SpriteRenderer, lg: LayerGpu, deltaMs: number): void {\n const layer = lg.layer;\n lg.uploadedVersion = uploadSpriteInstances(rr._surface.engine._device, layer, lg.instanceBuffer, lg.uploadedVersion);\n buildSpriteLayerUbo(layer, rr._targetWidth, rr._targetHeight, _scratchUbo);\n lg.uboUploaded = writeSpriteLayerUboIfDirty(rr._surface.engine._device, lg.uniformBuffer, _scratchUbo, lg.lastUbo, lg.uboUploaded);\n if (lg.fx) {\n _getSpriteFxHook()!.updateFx(lg.fx, layer, deltaMs);\n }\n}\n\nfunction disposeLayerGpu(lg: LayerGpu): void {\n lg.instanceBuffer.destroy();\n lg.uniformBuffer.destroy();\n if (lg.fx) {\n _getSpriteFxHook()!.disposeFx(lg.fx);\n }\n}\n\nconst _scratchUbo = new F32(LAYER_UBO_BYTES / 4);\n\n/**\n * Build (and cache) the bind group that attaches `lg.uniformBuffer` + atlas texture +\n * sampler to the pipeline's sprite `@group(0)` schema. All three resources are immutable for\n * the layer's lifetime, so this runs at most once per layer; subsequent calls return\n * the cached group. The instance buffer is **not** in the bind group — it's a vertex\n * buffer, bound separately at draw time — which is why instance-buffer growth in\n * `ensureLayerGpu` doesn't invalidate this cache.\n */\nfunction ensureBindGroup(rr: SpriteRenderer, lg: LayerGpu, pipeline: GPURenderPipeline): GPUBindGroup {\n if (lg.bindGroup) {\n return lg.bindGroup;\n }\n lg.bindGroup = createSpriteLayerBindGroup(rr._surface.engine, pipeline, 0, lg.layer, lg.uniformBuffer, lg.fx);\n return lg.bindGroup;\n}\n\n/** Sort key for layers within a renderer: ascending `order` (back-to-front draw order). */\nfunction compareLayers(a: Sprite2DLayer, b: Sprite2DLayer): number {\n if (a.order !== b.order) {\n return a.order - b.order;\n }\n return 0;\n}\n\n/** Create a `SpriteRenderer` for `surface`, pre-warming pipelines for the layers' blend\n * modes. Pass the engine directly for the common single-canvas case (since\n * `EngineContext extends SurfaceContext`); pass an auxiliary surface created via\n * `createSurface` for multi-canvas. */\nexport function createSpriteRenderer(surface: SurfaceContext, opts: SpriteRendererOptions): SpriteRenderer {\n const engine = surface.engine;\n assertSpriteRendererLayers(opts.layers);\n const indexBuffer = createMappedBuffer(engine, SHARED_SPRITE_INDEX_DATA, BU.INDEX);\n const canvas = surface.canvas;\n\n const layers = opts.layers.slice();\n const rr: SpriteRenderer = {\n _kind: KIND,\n _surface: surface,\n _indexBuffer: indexBuffer,\n _pipelineCache: createSpritePipelineCache(),\n _layerGpu: new Map(),\n _visibleBundles: [],\n _targetWidth: canvas.width,\n _targetHeight: canvas.height,\n _disposed: false,\n _clear: opts.clear ?? true,\n _targetView: null,\n _beforeUpdate: [],\n _disposeCallbacks: [],\n layers,\n _layers: layers,\n clearColor: opts.clearValue ?? { r: 0, g: 0, b: 0, a: 1 },\n _drawCallsPre: 0,\n _update(): void {\n spriteRendererUpdate(rr);\n },\n _record(): number {\n return spriteRendererRecord(rr);\n },\n };\n\n // Pre-warm pipelines currently in use, so the first frame doesn't pay compile cost.\n for (const layer of rr.layers) {\n getOrCreateSpritePipeline(engine, rr._pipelineCache, surface.format, 1, layer.blendMode, false, false, undefined, undefined, layer);\n }\n\n return rr;\n}\n\nfunction assertSpriteRendererLayers(layers: readonly Sprite2DLayer[]): void {\n for (const layer of layers) {\n assertSpriteRendererLayer(layer);\n }\n}\n\nfunction assertSpriteRendererLayer(layer: Sprite2DLayer): void {\n if (layer.depth !== \"none\") {\n throw new Error('SpriteRenderer requires depth: \"none\".');\n }\n}\n\n/**\n * Per-frame **update** pass (called by the engine before this renderer records its pass).\n * Refreshes target dims (canvas may have resized), sorts `rr.layers` in place by\n * `order` (TimSort is O(n) on already-sorted input — effectively free in steady state),\n * then walks every visible non-empty layer and runs `ensureLayerGpu` + `uploadLayer`.\n * No GPU draw work here — only buffer uploads via `writeBuffer`.\n */\nfunction spriteRendererUpdate(rr: SpriteRenderer): void {\n if (rr._disposed) {\n return;\n }\n const deltaMs = rr._surface.engine._currentDelta ?? 0;\n for (const hook of rr._beforeUpdate) {\n hook(deltaMs);\n }\n assertSpriteRendererLayers(rr.layers);\n const targetSize = getRenderTargetSize(rr._surface);\n rr._targetWidth = targetSize.width;\n rr._targetHeight = targetSize.height;\n\n // Sort layers in place by `order` once per frame. TimSort is O(n) on already-sorted input,\n // so this is effectively free in the steady state. Documented side-effect on `rr.layers`\n // (registration order is not the ground truth — `layer.order` is). Skipped for the common\n // single-layer case to avoid even the comparator-call overhead.\n if (rr.layers.length > 1) {\n rr._layers.sort(compareLayers);\n }\n\n for (const layer of rr.layers) {\n if (!layer.visible || layer.count === 0) {\n continue;\n }\n const lg = ensureLayerGpu(rr, layer);\n uploadLayer(rr, lg, deltaMs);\n }\n}\n\n/**\n * Per-frame **record** pass (called by the engine after `_update`).\n * For each visible non-empty layer: builds (or reuses) a `GPURenderBundle` that bakes\n * `setIndexBuffer` + `setPipeline` + `setBindGroup` + `setVertexBuffer` + `drawIndexed`,\n * then queues it for a single `pass.executeBundles(...)` replay. The bundle is the per-frame\n * fast path — it skips Chromium's per-call WebGPU validation and IPC, which dominates\n * CPU cost for static scenes at multi-kHz framerates. Bundle is rebuilt only when\n * `layer.count` changes or the instance buffer was reallocated.\n * Returns one draw call per visible non-empty layer (1000 sprites in a layer = 1 draw\n * call thanks to instancing).\n */\nfunction spriteRendererRecord(rr: SpriteRenderer): number {\n if (rr._disposed) {\n return 0;\n }\n assertSpriteRendererLayers(rr.layers);\n const eng = rr._surface.engine;\n const encoder = eng._currentEncoder;\n const swapView = rr._targetView ?? eng.scRT._colorView!;\n\n // Open a sampleCount=1 render pass on the target view (the swapchain by default, or an\n // offscreen render texture when one is set via setSpriteRendererTarget). This keeps HUD\n // sprites from resolving a fresh MSAA target over the already-rendered scene.\n const pass = encoder.beginRenderPass({\n colorAttachments: [\n {\n view: swapView,\n clearValue: rr.clearColor,\n loadOp: rr._clear ? \"clear\" : \"load\",\n storeOp: \"store\",\n },\n ],\n });\n let drawCalls = 0;\n const visibleBundles = rr._visibleBundles;\n visibleBundles.length = 0;\n\n for (const layer of rr.layers) {\n if (!layer.visible || layer.count === 0) {\n continue;\n }\n const lg = rr._layerGpu.get(layer);\n if (!lg) {\n continue;\n }\n const sampleCount = 1;\n const pipeline = getOrCreateSpritePipeline(\n rr._surface.engine,\n rr._pipelineCache,\n rr._surface.format,\n sampleCount,\n layer.blendMode,\n false,\n false,\n undefined,\n undefined,\n layer\n );\n if (lg.pipeline !== pipeline) {\n lg.pipeline = pipeline;\n lg.bindGroup = null;\n lg.renderBundle = null;\n }\n const bg = ensureBindGroup(rr, lg, pipeline);\n // (Re)record the bundle when count changes (drawIndexed instance count is baked in)\n // or when ensureLayerGpu reallocated the instance buffer (renderBundle was nulled).\n if (lg.renderBundle == null || lg.bundleCount !== layer.count) {\n const be = rr._surface.engine._device.createRenderBundleEncoder({\n colorFormats: [rr._surface.format],\n sampleCount,\n });\n be.setIndexBuffer(rr._indexBuffer, \"uint16\");\n be.setPipeline(pipeline);\n be.setBindGroup(0, bg);\n be.setVertexBuffer(0, lg.instanceBuffer);\n be.drawIndexed(6, layer.count, 0, 0, 0);\n lg.renderBundle = be.finish();\n lg.bundleCount = layer.count;\n }\n visibleBundles.push(lg.renderBundle!);\n drawCalls++;\n }\n\n if (visibleBundles.length > 0) {\n pass.executeBundles(visibleBundles);\n }\n pass.end();\n return drawCalls;\n}\n\n/** Add a pure-2D layer to the renderer. No-op if the layer is already present. */\nexport function addSpriteRendererLayer(sr: SpriteRenderer, layer: Sprite2DLayer): void {\n if (sr._disposed) {\n throw new Error(\"SpriteRenderer has been disposed.\");\n }\n assertSpriteRendererLayer(layer);\n if (sr.layers.includes(layer)) {\n return;\n }\n sr._layers.push(layer);\n getOrCreateSpritePipeline(sr._surface.engine, sr._pipelineCache, sr._surface.format, 1, layer.blendMode, false);\n}\n\n/** Remove a layer from the renderer and destroy any GPU resources cached for it. */\nexport function removeSpriteRendererLayer(sr: SpriteRenderer, layer: Sprite2DLayer): boolean {\n const index = sr.layers.indexOf(layer);\n if (index < 0) {\n return false;\n }\n sr._layers.splice(index, 1);\n const lg = sr._layerGpu.get(layer);\n if (lg) {\n disposeLayerGpu(lg);\n sr._layerGpu.delete(layer);\n }\n return true;\n}\n\n/** Push the renderer onto its engine's `_renderingContexts`. Idempotent — a second call is a no-op. */\nexport function registerSpriteRenderer(sr: SpriteRenderer): void {\n registerRenderingContext(sr._surface, sr);\n}\n\n/**\n * Redirect a sprite renderer's output to an offscreen render {@link Texture2D} `target` (for\n * render-to-texture / post-processing), or pass `null` to render to the swapchain (the\n * default). Pair with {@link createRenderTexture2D} at its default format and the renderer's\n * target size. The target's texture must be the engine's swapchain format: sprite pipelines\n * are baked with `engine.format`, so a target of any OTHER format fails WebGPU validation at\n * render-pass begin. A second renderer can then sample that texture (e.g. a fullscreen\n * custom-shader layer) and present it. Renderers registered later run later, so register the\n * offscreen scene pass before the presenting pass.\n */\nexport function setSpriteRendererTarget(sr: SpriteRenderer, target: Texture2D | null): void {\n sr._targetView = target ? target.view : null;\n}\n\n/** Splice the renderer out of its engine's `_renderingContexts`. No-op if not present. */\nexport function unregisterSpriteRenderer(sr: SpriteRenderer): void {\n unregisterRenderingContext(sr._surface, sr);\n}\n\n/**\n * Destroy all GPU resources owned by the renderer, unregister it from the engine, and clear `layers`.\n * Idempotent. To tie disposal to a scene, call\n * `onSceneDispose(scene, () => disposeSpriteRenderer(sr))` after `registerSpriteRenderer` —\n * see the `SpriteRenderer` doc-comment.\n */\nexport function disposeSpriteRenderer(sr: SpriteRenderer): void {\n if (sr._disposed) {\n return;\n }\n unregisterSpriteRenderer(sr);\n sr._disposed = true;\n const disposeCallbacks = sr._disposeCallbacks.slice();\n sr._disposeCallbacks.length = 0;\n for (const dispose of disposeCallbacks) {\n dispose();\n }\n for (const lg of sr._layerGpu.values()) {\n disposeLayerGpu(lg);\n }\n sr._layerGpu.clear();\n sr._visibleBundles.length = 0;\n sr._beforeUpdate.length = 0;\n sr._indexBuffer.destroy();\n resetSpritePipelineCache(sr._pipelineCache);\n sr._layers.length = 0;\n}\n\n/** @internal Test-only accessor for pipeline-cache size. */\nexport function _spriteRendererPipelineCacheSize(sr: SpriteRenderer): number {\n return getSpritePipelineCacheSize(sr._pipelineCache, sr._surface.engine._device);\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -3,7 +3,7 @@ import { buildSpriteRenderable } from './sprite-renderable.js';
|
|
|
3
3
|
|
|
4
4
|
function addDepthHostedSpriteLayer(scene, layer) {
|
|
5
5
|
if (layer.depth === "none") {
|
|
6
|
-
throw new Error('
|
|
6
|
+
throw new Error('Depth-hosted sprites require depth != "none".');
|
|
7
7
|
}
|
|
8
8
|
addDeferredSceneRenderables(scene, (engine) => {
|
|
9
9
|
const built = buildSpriteRenderable(engine, layer);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sprite-scene.js","sources":["../../../src/sprite/sprite-scene.ts"],"sourcesContent":["import type { SceneContext } from \"../scene/scene-core.js\";\nimport { addDeferredSceneRenderables } from \"../scene/scene-core.js\";\nimport type { Sprite2DLayer } from \"./sprite-2d.js\";\nimport { buildSpriteRenderable } from \"./sprite-renderable.js\";\n\n/**\n * Add a depth-hosted Sprite2D layer to a SceneContext via the scene's optional\n * renderable extension hook. Pure HUD layers (`depth: \"none\"`) are rendered by\n * `createSpriteRenderer + registerSpriteRenderer` instead.\n */\nexport function addDepthHostedSpriteLayer(scene: SceneContext, layer: Sprite2DLayer): void {\n if (layer.depth === \"none\") {\n throw new Error('
|
|
1
|
+
{"version":3,"file":"sprite-scene.js","sources":["../../../src/sprite/sprite-scene.ts"],"sourcesContent":["import type { SceneContext } from \"../scene/scene-core.js\";\nimport { addDeferredSceneRenderables } from \"../scene/scene-core.js\";\nimport type { Sprite2DLayer } from \"./sprite-2d.js\";\nimport { buildSpriteRenderable } from \"./sprite-renderable.js\";\n\n/**\n * Add a depth-hosted Sprite2D layer to a SceneContext via the scene's optional\n * renderable extension hook. Pure HUD layers (`depth: \"none\"`) are rendered by\n * `createSpriteRenderer + registerSpriteRenderer` instead.\n */\nexport function addDepthHostedSpriteLayer(scene: SceneContext, layer: Sprite2DLayer): void {\n if (layer.depth === \"none\") {\n throw new Error('Depth-hosted sprites require depth != \"none\".');\n }\n addDeferredSceneRenderables(scene, (engine) => {\n const built = buildSpriteRenderable(engine, layer);\n return { renderables: [built.renderable], dispose: built.dispose };\n });\n}\n"],"names":[],"mappings":";;;AAUO,SAAS,yBAAA,CAA0B,OAAqB,KAAA,EAA4B;AACvF,EAAA,IAAI,KAAA,CAAM,UAAU,MAAA,EAAQ;AACxB,IAAA,MAAM,IAAI,MAAM,+CAA+C,CAAA;AAAA,EACnE;AACA,EAAA,2BAAA,CAA4B,KAAA,EAAO,CAAC,MAAA,KAAW;AAC3C,IAAA,MAAM,KAAA,GAAQ,qBAAA,CAAsB,MAAA,EAAQ,KAAK,CAAA;AACjD,IAAA,OAAO,EAAE,aAAa,CAAC,KAAA,CAAM,UAAU,CAAA,EAAG,OAAA,EAAS,MAAM,OAAA,EAAQ;AAAA,EACrE,CAAC,CAAA;AACL;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@babylonjs/lite",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "A lightweight, tree-shakable, WebGPU-first rendering library derived from Babylon.js.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://doc.babylonjs.com/lite/",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"unpkg": "./dist/index.js",
|
|
23
23
|
"sideEffects": false,
|
|
24
24
|
"babylonLiteRelease": {
|
|
25
|
-
"azureBuildId": "
|
|
26
|
-
"sourceVersion": "
|
|
25
|
+
"azureBuildId": "55411",
|
|
26
|
+
"sourceVersion": "e533d48d9eff9391768488b35503868cf4d76d5e"
|
|
27
27
|
}
|
|
28
28
|
}
|