@flighthq/render-wgpu 0.1.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 (79) hide show
  1. package/dist/index.d.ts +17 -0
  2. package/dist/index.d.ts.map +1 -0
  3. package/dist/index.js +16 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/wgpuAdapterCapabilities.d.ts +3 -0
  6. package/dist/wgpuAdapterCapabilities.d.ts.map +1 -0
  7. package/dist/wgpuAdapterCapabilities.js +28 -0
  8. package/dist/wgpuAdapterCapabilities.js.map +1 -0
  9. package/dist/wgpuBackground.d.ts +4 -0
  10. package/dist/wgpuBackground.d.ts.map +1 -0
  11. package/dist/wgpuBackground.js +110 -0
  12. package/dist/wgpuBackground.js.map +1 -0
  13. package/dist/wgpuDraw.d.ts +21 -0
  14. package/dist/wgpuDraw.d.ts.map +1 -0
  15. package/dist/wgpuDraw.js +153 -0
  16. package/dist/wgpuDraw.js.map +1 -0
  17. package/dist/wgpuElement.d.ts +2 -0
  18. package/dist/wgpuElement.d.ts.map +1 -0
  19. package/dist/wgpuElement.js +9 -0
  20. package/dist/wgpuElement.js.map +1 -0
  21. package/dist/wgpuFullscreenPass.d.ts +5 -0
  22. package/dist/wgpuFullscreenPass.d.ts.map +1 -0
  23. package/dist/wgpuFullscreenPass.js +106 -0
  24. package/dist/wgpuFullscreenPass.js.map +1 -0
  25. package/dist/wgpuMaterialRegistry.d.ts +5 -0
  26. package/dist/wgpuMaterialRegistry.d.ts.map +1 -0
  27. package/dist/wgpuMaterialRegistry.js +27 -0
  28. package/dist/wgpuMaterialRegistry.js.map +1 -0
  29. package/dist/wgpuRenderState.d.ts +7 -0
  30. package/dist/wgpuRenderState.d.ts.map +1 -0
  31. package/dist/wgpuRenderState.js +153 -0
  32. package/dist/wgpuRenderState.js.map +1 -0
  33. package/dist/wgpuRenderTarget.d.ts +19 -0
  34. package/dist/wgpuRenderTarget.d.ts.map +1 -0
  35. package/dist/wgpuRenderTarget.js +142 -0
  36. package/dist/wgpuRenderTarget.js.map +1 -0
  37. package/dist/wgpuRenderTargetPool.d.ts +10 -0
  38. package/dist/wgpuRenderTargetPool.d.ts.map +1 -0
  39. package/dist/wgpuRenderTargetPool.js +32 -0
  40. package/dist/wgpuRenderTargetPool.js.map +1 -0
  41. package/dist/wgpuScissor.d.ts +5 -0
  42. package/dist/wgpuScissor.d.ts.map +1 -0
  43. package/dist/wgpuScissor.js +37 -0
  44. package/dist/wgpuScissor.js.map +1 -0
  45. package/dist/wgpuShader.d.ts +43 -0
  46. package/dist/wgpuShader.d.ts.map +1 -0
  47. package/dist/wgpuShader.js +304 -0
  48. package/dist/wgpuShader.js.map +1 -0
  49. package/dist/wgpuShaderBinding.d.ts +5 -0
  50. package/dist/wgpuShaderBinding.d.ts.map +1 -0
  51. package/dist/wgpuShaderBinding.js +28 -0
  52. package/dist/wgpuShaderBinding.js.map +1 -0
  53. package/dist/wgpuShaderRegistry.d.ts +3 -0
  54. package/dist/wgpuShaderRegistry.d.ts.map +1 -0
  55. package/dist/wgpuShaderRegistry.js +8 -0
  56. package/dist/wgpuShaderRegistry.js.map +1 -0
  57. package/dist/wgpuSurface.d.ts +6 -0
  58. package/dist/wgpuSurface.d.ts.map +1 -0
  59. package/dist/wgpuSurface.js +107 -0
  60. package/dist/wgpuSurface.js.map +1 -0
  61. package/dist/wgpuTestHelper.d.ts +4 -0
  62. package/dist/wgpuTestHelper.d.ts.map +1 -0
  63. package/dist/wgpuTestHelper.js +137 -0
  64. package/dist/wgpuTestHelper.js.map +1 -0
  65. package/package.json +42 -0
  66. package/src/wgpuAdapterCapabilities.test.ts +49 -0
  67. package/src/wgpuBackground.test.ts +52 -0
  68. package/src/wgpuDraw.test.ts +174 -0
  69. package/src/wgpuElement.test.ts +21 -0
  70. package/src/wgpuFullscreenPass.test.ts +64 -0
  71. package/src/wgpuMaterialRegistry.test.ts +56 -0
  72. package/src/wgpuRenderState.test.ts +88 -0
  73. package/src/wgpuRenderTarget.test.ts +120 -0
  74. package/src/wgpuRenderTargetPool.test.ts +58 -0
  75. package/src/wgpuScissor.test.ts +97 -0
  76. package/src/wgpuShader.test.ts +140 -0
  77. package/src/wgpuShaderBinding.test.ts +62 -0
  78. package/src/wgpuShaderRegistry.test.ts +30 -0
  79. package/src/wgpuSurface.test.ts +49 -0
@@ -0,0 +1,17 @@
1
+ export * from './wgpuAdapterCapabilities';
2
+ export * from './wgpuBackground';
3
+ export * from './wgpuDraw';
4
+ export * from './wgpuElement';
5
+ export * from './wgpuFullscreenPass';
6
+ export * from './wgpuMaterialRegistry';
7
+ export * from './wgpuRenderState';
8
+ export * from './wgpuRenderTarget';
9
+ export * from './wgpuRenderTargetPool';
10
+ export * from './wgpuScissor';
11
+ export * from './wgpuShader';
12
+ export * from './wgpuShaderBinding';
13
+ export * from './wgpuShaderRegistry';
14
+ export * from './wgpuSurface';
15
+ export { createWgpuRenderStateForTest, installWgpuMock } from './wgpuTestHelper';
16
+ export type { WgpuRenderTarget, WgpuRenderTargetPool } from '@flighthq/types';
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,4BAA4B,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACjF,YAAY,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,16 @@
1
+ export * from './wgpuAdapterCapabilities';
2
+ export * from './wgpuBackground';
3
+ export * from './wgpuDraw';
4
+ export * from './wgpuElement';
5
+ export * from './wgpuFullscreenPass';
6
+ export * from './wgpuMaterialRegistry';
7
+ export * from './wgpuRenderState';
8
+ export * from './wgpuRenderTarget';
9
+ export * from './wgpuRenderTargetPool';
10
+ export * from './wgpuScissor';
11
+ export * from './wgpuShader';
12
+ export * from './wgpuShaderBinding';
13
+ export * from './wgpuShaderRegistry';
14
+ export * from './wgpuSurface';
15
+ export { createWgpuRenderStateForTest, installWgpuMock } from './wgpuTestHelper';
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC;AACvC,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC;AACpC,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,4BAA4B,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { WgpuAdapterCapabilities } from '@flighthq/types';
2
+ export declare function getWgpuAdapterCapabilities(adapter: GPUAdapter): WgpuAdapterCapabilities;
3
+ //# sourceMappingURL=wgpuAdapterCapabilities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wgpuAdapterCapabilities.d.ts","sourceRoot":"","sources":["../src/wgpuAdapterCapabilities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAS/D,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,UAAU,GAAG,uBAAuB,CAwBvF"}
@@ -0,0 +1,28 @@
1
+ // Queries a GPUAdapter for the capabilities that createWgpuRenderState uses to gate format and
2
+ // feature paths. Call this after requestAdapter but before createWgpuRenderState and pass the
3
+ // result as options.adapterCapabilities so the state is configured correctly from the start.
4
+ //
5
+ // The adapter is read-only here — no device is created. This is intentional: capabilities are
6
+ // queried at configuration time, before the device is allocated, so the device can be requested
7
+ // with the right requiredFeatures list.
8
+ export function getWgpuAdapterCapabilities(adapter) {
9
+ const features = adapter.features;
10
+ const limits = adapter.limits;
11
+ // float32-filterable: allows rgba16float render targets with linear filtering (HDR).
12
+ const supportsFloat32Filterable = features.has('float32-filterable');
13
+ // timestamp-query: enables GPU time measurement (enableWgpuTimestampQueries).
14
+ const supportsTimestampQuery = features.has('timestamp-query');
15
+ // maxTextureDimension2D: the limit is defined by the spec; fall back to 8192 if absent.
16
+ const maxTextureDimension2D = limits.maxTextureDimension2D ?? 8192;
17
+ // WebGPU does not expose supported MSAA sample counts per format directly via the adapter.
18
+ // All conformant WebGPU implementations support sampleCount 4 for standard formats; 8+ is
19
+ // implementation-defined. Report 4 as the safe maximum for antialias paths.
20
+ const maxSampleCount = 4;
21
+ return {
22
+ maxSampleCount,
23
+ maxTextureDimension2D,
24
+ supportsFloat32Filterable,
25
+ supportsTimestampQuery,
26
+ };
27
+ }
28
+ //# sourceMappingURL=wgpuAdapterCapabilities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wgpuAdapterCapabilities.js","sourceRoot":"","sources":["../src/wgpuAdapterCapabilities.ts"],"names":[],"mappings":"AAEA,+FAA+F;AAC/F,8FAA8F;AAC9F,6FAA6F;AAC7F,EAAE;AACF,8FAA8F;AAC9F,gGAAgG;AAChG,wCAAwC;AACxC,MAAM,UAAU,0BAA0B,CAAC,OAAmB;IAC5D,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAClC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAE9B,qFAAqF;IACrF,MAAM,yBAAyB,GAAG,QAAQ,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IAErE,8EAA8E;IAC9E,MAAM,sBAAsB,GAAG,QAAQ,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAE/D,wFAAwF;IACxF,MAAM,qBAAqB,GAAG,MAAM,CAAC,qBAAqB,IAAI,IAAI,CAAC;IAEnE,2FAA2F;IAC3F,0FAA0F;IAC1F,4EAA4E;IAC5E,MAAM,cAAc,GAAG,CAAC,CAAC;IAEzB,OAAO;QACL,cAAc;QACd,qBAAqB;QACrB,yBAAyB;QACzB,sBAAsB;KACvB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { WgpuRenderState } from '@flighthq/types';
2
+ export declare function renderWgpuBackground(state: WgpuRenderState): void;
3
+ export declare function submitWgpuRenderPass(state: WgpuRenderState): void;
4
+ //# sourceMappingURL=wgpuBackground.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wgpuBackground.d.ts","sourceRoot":"","sources":["../src/wgpuBackground.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AA6BvD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAmEjE;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAiCjE"}
@@ -0,0 +1,110 @@
1
+ import { getWgpuRenderStateRuntime } from './wgpuRenderState';
2
+ import { acquireWgpuFrameCaptureTexture, encodeWgpuFrameCapture } from './wgpuSurface';
3
+ function ensureWgpuDepthStencil(state, width, height) {
4
+ const runtime = getWgpuRenderStateRuntime(state);
5
+ if (runtime.depthStencilTexture !== null &&
6
+ runtime.depthStencilWidth === width &&
7
+ runtime.depthStencilHeight === height) {
8
+ return;
9
+ }
10
+ runtime.depthStencilTexture?.destroy();
11
+ const texture = state.device.createTexture({
12
+ size: [Math.max(1, width), Math.max(1, height), 1],
13
+ format: 'depth24plus-stencil8',
14
+ usage: GPUTextureUsage.RENDER_ATTACHMENT,
15
+ });
16
+ runtime.depthStencilTexture = texture;
17
+ runtime.depthStencilView = texture.createView();
18
+ runtime.depthStencilWidth = width;
19
+ runtime.depthStencilHeight = height;
20
+ }
21
+ export function renderWgpuBackground(state) {
22
+ const runtime = getWgpuRenderStateRuntime(state);
23
+ // End any previous open pass (safety guard)
24
+ if (runtime.renderPass !== null) {
25
+ runtime.renderPass.end();
26
+ runtime.renderPass = null;
27
+ }
28
+ runtime.uniformOffset = 0;
29
+ // Reclaim the sprite-batch buffer pool from the start of the frame; last frame's submit has been
30
+ // queued, so its slots are safe to overwrite.
31
+ runtime.spriteBatchBufferCursor = 0;
32
+ runtime.currentBlendMode = null;
33
+ runtime.currentMaskDepth = 0;
34
+ runtime.maskWriteMode = false;
35
+ runtime.currentScissorRect = null;
36
+ runtime.scissorStack = [];
37
+ const device = state.device;
38
+ const canvas = state.canvas;
39
+ const context = state.context;
40
+ const width = canvas.width;
41
+ const height = canvas.height;
42
+ ensureWgpuDepthStencil(state, width, height);
43
+ // With frame capture on, render into an offscreen COPY_SRC texture instead of the swapchain: software/
44
+ // headless adapters never present the swapchain and its texture reads back as zeros, so the readable
45
+ // copy must be the render target itself.
46
+ const canvasTexture = acquireWgpuFrameCaptureTexture(state) ?? context.getCurrentTexture();
47
+ const canvasView = canvasTexture.createView();
48
+ runtime.canvasTextureView = canvasView;
49
+ runtime.canvasViewCleared = true;
50
+ // The canvas (and the capture texture, when capture is on) is the canvas format; scene pipelines key on this.
51
+ runtime.currentColorFormat = state.format;
52
+ runtime.renderTargetViewport = null;
53
+ const rgba = state.backgroundColorRgba;
54
+ const clearValue = rgba.length >= 4 && rgba[3] > 0 ? { r: rgba[0], g: rgba[1], b: rgba[2], a: rgba[3] } : { r: 0, g: 0, b: 0, a: 0 };
55
+ const commandEncoder = device.createCommandEncoder();
56
+ runtime.commandEncoder = commandEncoder;
57
+ const renderPass = commandEncoder.beginRenderPass({
58
+ colorAttachments: [
59
+ {
60
+ view: canvasView,
61
+ clearValue,
62
+ loadOp: 'clear',
63
+ storeOp: 'store',
64
+ },
65
+ ],
66
+ depthStencilAttachment: {
67
+ view: runtime.depthStencilView,
68
+ depthClearValue: 1.0,
69
+ depthLoadOp: 'clear',
70
+ depthStoreOp: 'discard',
71
+ stencilClearValue: 0,
72
+ stencilLoadOp: 'clear',
73
+ stencilStoreOp: 'discard',
74
+ },
75
+ });
76
+ renderPass.setViewport(0, 0, width, height, 0, 1);
77
+ runtime.renderPass = renderPass;
78
+ }
79
+ export function submitWgpuRenderPass(state) {
80
+ const runtime = getWgpuRenderStateRuntime(state);
81
+ const { renderPass, commandEncoder, uniformBuffer, uniformData, uniformOffset } = runtime;
82
+ const device = state.device;
83
+ if (renderPass !== null) {
84
+ renderPass.end();
85
+ runtime.renderPass = null;
86
+ }
87
+ if (commandEncoder !== null) {
88
+ // Upload used portion of the uniform ring buffer before submission.
89
+ // writeBuffer is a queue operation that completes before the subsequent submit.
90
+ if (uniformOffset > 0) {
91
+ device.queue.writeBuffer(uniformBuffer, 0, uniformData.buffer, 0, uniformOffset);
92
+ }
93
+ // Copy the offscreen capture texture into the readback buffer within this frame's encoder; on the
94
+ // adapters capture exists for, GPU work queued in a later task does not land.
95
+ encodeWgpuFrameCapture(state, commandEncoder);
96
+ device.queue.submit([commandEncoder.finish()]);
97
+ runtime.commandEncoder = null;
98
+ // Now that the frame is submitted, free the buffers retired mid-frame (clip pops, grown particle
99
+ // instance buffers) — they were kept alive because the submitted command buffer referenced them.
100
+ const retired = runtime.retiredBuffers;
101
+ if (retired !== undefined && retired.length > 0) {
102
+ for (let i = 0; i < retired.length; i++)
103
+ retired[i].destroy();
104
+ retired.length = 0;
105
+ }
106
+ }
107
+ runtime.canvasTextureView = null;
108
+ runtime.canvasViewCleared = false;
109
+ }
110
+ //# sourceMappingURL=wgpuBackground.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wgpuBackground.js","sourceRoot":"","sources":["../src/wgpuBackground.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { ColorTransform, RenderProxy, RenderProxy2D, WgpuRenderState, WgpuTextureEntry } from '@flighthq/types';
2
+ import { BlendMode } from '@flighthq/types';
3
+ export declare function applyWgpuBlendMode(state: WgpuRenderState, blendMode: BlendMode | null): void;
4
+ export declare function bindWgpuTexture(state: WgpuRenderState, imageSource: CanvasImageSource): WgpuTextureEntry;
5
+ export declare function buildWgpuRenderTargetBindGroup(state: WgpuRenderState, view: GPUTextureView): GPUBindGroup;
6
+ export declare function createWgpuTextureEntry(state: WgpuRenderState, width: number, height: number, canvas: HTMLCanvasElement): WgpuTextureEntry;
7
+ export declare function drawWgpuQuad(state: WgpuRenderState, renderProxy: RenderProxy2D, textureEntry: WgpuTextureEntry, x0: number, y0: number, x1: number, y1: number, u0: number, v0: number, u1: number, v1: number): void;
8
+ export declare function drawWgpuQuadWithTransform(state: WgpuRenderState, renderProxy: RenderProxy, transform: {
9
+ a: number;
10
+ b: number;
11
+ c: number;
12
+ d: number;
13
+ tx: number;
14
+ ty: number;
15
+ }, textureEntry: WgpuTextureEntry, x0: number, y0: number, x1: number, y1: number, u0: number, v0: number, u1: number, v1: number): void;
16
+ export declare function enableWgpuBlendModeSupport(state: WgpuRenderState): void;
17
+ export declare function getWgpuRenderProxyColorTransform(renderProxy: Readonly<RenderProxy>): ColorTransform | null;
18
+ export declare function submitWgpuQuadDraw(state: WgpuRenderState, uniformOffset: number, textureBindGroup: GPUBindGroup): void;
19
+ export declare function updateWgpuTextureEntry(state: WgpuRenderState, entry: WgpuTextureEntry, canvas: HTMLCanvasElement): void;
20
+ export declare function warmWgpuPipelines(state: WgpuRenderState): void;
21
+ //# sourceMappingURL=wgpuDraw.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wgpuDraw.d.ts","sourceRoot":"","sources":["../src/wgpuDraw.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,WAAW,EACX,aAAa,EAEb,eAAe,EACf,gBAAgB,EACjB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,SAAS,EAAiE,MAAM,iBAAiB,CAAC;AAK3G,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,SAAS,GAAG,IAAI,GAAG,IAAI,CAE5F;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,iBAAiB,GAAG,gBAAgB,CA4DxG;AAED,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,cAAc,GAAG,YAAY,CAUzG;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,eAAe,EACtB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,iBAAiB,GACxB,gBAAgB,CA+BlB;AAED,wBAAgB,YAAY,CAC1B,KAAK,EAAE,eAAe,EACtB,WAAW,EAAE,aAAa,EAC1B,YAAY,EAAE,gBAAgB,EAC9B,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,GACT,IAAI,CAmBN;AAED,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,eAAe,EACtB,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,EACjF,YAAY,EAAE,gBAAgB,EAC9B,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,GACT,IAAI,CAkBN;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAEvE;AAKD,wBAAgB,gCAAgC,CAAC,WAAW,EAAE,QAAQ,CAAC,WAAW,CAAC,GAAG,cAAc,GAAG,IAAI,CAU1G;AAED,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,eAAe,EACtB,aAAa,EAAE,MAAM,EACrB,gBAAgB,EAAE,YAAY,GAC7B,IAAI,CAUN;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,eAAe,EACtB,KAAK,EAAE,gBAAgB,EACvB,MAAM,EAAE,iBAAiB,GACxB,IAAI,CAUN;AAGD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAG9D"}
@@ -0,0 +1,153 @@
1
+ import { BlendMode, ColorTransformMaterialKind, UniformColorTransformMaterialKind } from '@flighthq/types';
2
+ import { getWgpuRenderStateRuntime } from './wgpuRenderState';
3
+ import { getActiveWgpuPipeline, getWgpuPipeline, writeWgpuQuadUniforms } from './wgpuShader';
4
+ export function applyWgpuBlendMode(state, blendMode) {
5
+ getWgpuRenderStateRuntime(state).currentBlendMode = blendMode;
6
+ }
7
+ export function bindWgpuTexture(state, imageSource) {
8
+ const runtime = getWgpuRenderStateRuntime(state);
9
+ const cached = runtime.textureCache.get(imageSource);
10
+ if (cached !== undefined)
11
+ return cached;
12
+ const { device } = state;
13
+ const { textureBindGroupLayout } = runtime;
14
+ // Determine pixel dimensions from the image source type
15
+ let width = 1;
16
+ let height = 1;
17
+ if (imageSource instanceof HTMLCanvasElement) {
18
+ width = imageSource.width || 1;
19
+ height = imageSource.height || 1;
20
+ }
21
+ else if (imageSource instanceof HTMLImageElement) {
22
+ width = imageSource.naturalWidth || 1;
23
+ height = imageSource.naturalHeight || 1;
24
+ }
25
+ else if (imageSource instanceof HTMLVideoElement) {
26
+ width = imageSource.videoWidth || 1;
27
+ height = imageSource.videoHeight || 1;
28
+ }
29
+ else if (imageSource instanceof ImageBitmap) {
30
+ width = imageSource.width || 1;
31
+ height = imageSource.height || 1;
32
+ }
33
+ else if (typeof OffscreenCanvas !== 'undefined' && imageSource instanceof OffscreenCanvas) {
34
+ width = imageSource.width || 1;
35
+ height = imageSource.height || 1;
36
+ }
37
+ const texture = device.createTexture({
38
+ size: [width, height, 1],
39
+ format: 'rgba8unorm',
40
+ usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT,
41
+ });
42
+ // Store every uploaded texture premultiplied, matching the premultiplied (ONE, ONE_MINUS_SRC_ALPHA)
43
+ // blend and the shaders, which expect premultiplied input (e.g. the particle shader tints
44
+ // tex.rgb assuming it is already alpha-multiplied). Canvas/OffscreenCanvas are premultiplied
45
+ // internally, so premultipliedAlpha: true is the lossless pass-through; Image/ImageBitmap carry
46
+ // straight alpha and get premultiplied on copy. (A straight-alpha texture under premultiplied
47
+ // blend blows RGB out — it turned the semi-transparent shape panel opaque white.)
48
+ device.queue.copyExternalImageToTexture({ source: imageSource, flipY: false }, { texture, premultipliedAlpha: true }, [width, height]);
49
+ const view = texture.createView();
50
+ const sampler = state.allowSmoothing ? runtime.linearSampler : runtime.nearestSampler;
51
+ const bindGroup = device.createBindGroup({
52
+ layout: textureBindGroupLayout,
53
+ entries: [
54
+ { binding: 0, resource: view },
55
+ { binding: 1, resource: sampler },
56
+ ],
57
+ });
58
+ const entry = { texture, view, bindGroup };
59
+ runtime.textureCache.set(imageSource, entry);
60
+ return entry;
61
+ }
62
+ export function buildWgpuRenderTargetBindGroup(state, view) {
63
+ const runtime = getWgpuRenderStateRuntime(state);
64
+ const sampler = state.allowSmoothing ? runtime.linearSampler : runtime.nearestSampler;
65
+ return state.device.createBindGroup({
66
+ layout: runtime.textureBindGroupLayout,
67
+ entries: [
68
+ { binding: 0, resource: view },
69
+ { binding: 1, resource: sampler },
70
+ ],
71
+ });
72
+ }
73
+ export function createWgpuTextureEntry(state, width, height, canvas) {
74
+ const runtime = getWgpuRenderStateRuntime(state);
75
+ const { device } = state;
76
+ const { textureBindGroupLayout } = runtime;
77
+ const w = Math.max(1, width);
78
+ const h = Math.max(1, height);
79
+ const texture = device.createTexture({
80
+ size: [w, h, 1],
81
+ format: 'rgba8unorm',
82
+ usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT,
83
+ });
84
+ device.queue.copyExternalImageToTexture({ source: canvas, flipY: false }, { texture, premultipliedAlpha: true }, [w, h]);
85
+ const view = texture.createView();
86
+ const sampler = state.allowSmoothing ? runtime.linearSampler : runtime.nearestSampler;
87
+ const bindGroup = device.createBindGroup({
88
+ layout: textureBindGroupLayout,
89
+ entries: [
90
+ { binding: 0, resource: view },
91
+ { binding: 1, resource: sampler },
92
+ ],
93
+ });
94
+ return { texture, view, bindGroup };
95
+ }
96
+ export function drawWgpuQuad(state, renderProxy, textureEntry, x0, y0, x1, y1, u0, v0, u1, v1) {
97
+ const runtime = getWgpuRenderStateRuntime(state);
98
+ const pass = runtime.renderPass;
99
+ if (pass === null)
100
+ return;
101
+ const uniformOffset = writeWgpuQuadUniforms(state, renderProxy, getWgpuRenderProxyColorTransform(renderProxy), x0, y0, x1, y1, u0, v0, u1, v1);
102
+ submitWgpuQuadDraw(state, uniformOffset, textureEntry.bindGroup);
103
+ }
104
+ export function drawWgpuQuadWithTransform(state, renderProxy, transform, textureEntry, x0, y0, x1, y1, u0, v0, u1, v1) {
105
+ const runtime = getWgpuRenderStateRuntime(state);
106
+ if (runtime.renderPass === null)
107
+ return;
108
+ const uniformOffset = writeWgpuQuadUniforms(state, { alpha: renderProxy.alpha, transform2D: transform }, getWgpuRenderProxyColorTransform(renderProxy), x0, y0, x1, y1, u0, v0, u1, v1);
109
+ submitWgpuQuadDraw(state, uniformOffset, textureEntry.bindGroup);
110
+ }
111
+ export function enableWgpuBlendModeSupport(state) {
112
+ state.applyBlendMode = applyWgpuBlendMode;
113
+ }
114
+ // Effective color transform for a render node from its material — the value on a
115
+ // UniformColorTransformMaterial or the per-node materialData for a ColorTransformMaterial. Used by
116
+ // the immediate (display-object) draw path; the batch path packs it per-instance instead.
117
+ export function getWgpuRenderProxyColorTransform(renderProxy) {
118
+ const material = renderProxy.material;
119
+ if (material === null)
120
+ return null;
121
+ if (material.kind === UniformColorTransformMaterialKind) {
122
+ return material.colorTransform;
123
+ }
124
+ if (material.kind === ColorTransformMaterialKind) {
125
+ return renderProxy.materialData;
126
+ }
127
+ return null;
128
+ }
129
+ export function submitWgpuQuadDraw(state, uniformOffset, textureBindGroup) {
130
+ const runtime = getWgpuRenderStateRuntime(state);
131
+ const pass = runtime.renderPass;
132
+ if (pass === null)
133
+ return;
134
+ const pipeline = getActiveWgpuPipeline(state);
135
+ pass.setPipeline(pipeline);
136
+ pass.setBindGroup(0, runtime.uniformBindGroup, [uniformOffset]);
137
+ pass.setBindGroup(1, textureBindGroup);
138
+ if (runtime.currentMaskDepth > 0)
139
+ pass.setStencilReference(runtime.currentMaskDepth);
140
+ pass.draw(6);
141
+ }
142
+ export function updateWgpuTextureEntry(state, entry, canvas) {
143
+ const { device } = state;
144
+ const w = Math.max(1, canvas.width);
145
+ const h = Math.max(1, canvas.height);
146
+ device.queue.copyExternalImageToTexture({ source: canvas, flipY: false }, { texture: entry.texture, premultipliedAlpha: true }, [w, h]);
147
+ }
148
+ // Pre-warm the normal + blend pipelines so the first frame doesn't stall.
149
+ export function warmWgpuPipelines(state) {
150
+ getWgpuPipeline(state, BlendMode.Normal, 'normal');
151
+ getWgpuPipeline(state, BlendMode.Add, 'normal');
152
+ }
153
+ //# sourceMappingURL=wgpuDraw.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wgpuDraw.js","sourceRoot":"","sources":["../src/wgpuDraw.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function createWgpuCanvasElement(width: number, height: number, pixelRatio?: number): HTMLCanvasElement;
2
+ //# sourceMappingURL=wgpuElement.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wgpuElement.d.ts","sourceRoot":"","sources":["../src/wgpuElement.ts"],"names":[],"mappings":"AAAA,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAE,MAAU,GAAG,iBAAiB,CAOhH"}
@@ -0,0 +1,9 @@
1
+ export function createWgpuCanvasElement(width, height, pixelRatio = 1) {
2
+ const canvas = document.createElement('canvas');
3
+ canvas.style.width = `${width}px`;
4
+ canvas.style.height = `${height}px`;
5
+ canvas.width = width * pixelRatio;
6
+ canvas.height = height * pixelRatio;
7
+ return canvas;
8
+ }
9
+ //# sourceMappingURL=wgpuElement.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wgpuElement.js","sourceRoot":"","sources":["../src/wgpuElement.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,uBAAuB,CAAC,KAAa,EAAE,MAAc,EAAE,aAAqB,CAAC;IAC3F,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IAChD,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,KAAK,IAAI,CAAC;IAClC,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC;IACpC,MAAM,CAAC,KAAK,GAAG,KAAK,GAAG,UAAU,CAAC;IAClC,MAAM,CAAC,MAAM,GAAG,MAAM,GAAG,UAAU,CAAC;IACpC,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { WgpuFullscreenPipeline, WgpuRenderState, WgpuRenderTarget } from '@flighthq/types';
2
+ export declare function createWgpuFullscreenPipeline(state: WgpuRenderState, fragmentWgsl: string, textureInputCount?: number, format?: GPUTextureFormat): WgpuFullscreenPipeline;
3
+ export declare function destroyWgpuFullscreenPipeline(_state: WgpuRenderState, _pipeline: WgpuFullscreenPipeline): void;
4
+ export declare function drawWgpuFullscreenPass(state: WgpuRenderState, wgpuPipeline: Readonly<WgpuFullscreenPipeline>, inputs: ReadonlyArray<Readonly<WgpuRenderTarget>>, dest: Readonly<WgpuRenderTarget> | null, setUniforms: ((state: WgpuRenderState, uniformBindGroupLayout: GPUBindGroupLayout) => GPUBindGroup) | null): void;
5
+ //# sourceMappingURL=wgpuFullscreenPass.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wgpuFullscreenPass.d.ts","sourceRoot":"","sources":["../src/wgpuFullscreenPass.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AASjG,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,eAAe,EACtB,YAAY,EAAE,MAAM,EACpB,iBAAiB,SAAI,EACrB,MAAM,GAAE,gBAA+B,GACtC,sBAAsB,CAsCxB;AAKD,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,eAAe,EAAE,SAAS,EAAE,sBAAsB,GAAG,IAAI,CAG9G;AASD,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,eAAe,EACtB,YAAY,EAAE,QAAQ,CAAC,sBAAsB,CAAC,EAC9C,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,EACjD,IAAI,EAAE,QAAQ,CAAC,gBAAgB,CAAC,GAAG,IAAI,EACvC,WAAW,EAAE,CAAC,CAAC,KAAK,EAAE,eAAe,EAAE,sBAAsB,EAAE,kBAAkB,KAAK,YAAY,CAAC,GAAG,IAAI,GACzG,IAAI,CAyBN"}
@@ -0,0 +1,106 @@
1
+ import { getWgpuRenderStateRuntime } from './wgpuRenderState';
2
+ // Creates a fullscreen-pass pipeline for the given fragment WGSL source and target format.
3
+ // The pipeline expects:
4
+ // @group(0) @binding(0) — optional uniform buffer (if the shader declares it)
5
+ // @group(1) @binding(i) — texture_2d<f32> input i, and a paired sampler at @binding(2i+1)
6
+ // `textureInputCount` controls how many input-texture bind group layouts are built.
7
+ export function createWgpuFullscreenPipeline(state, fragmentWgsl, textureInputCount = 1, format = state.format) {
8
+ const { device } = state;
9
+ const uniformBindGroupLayout = device.createBindGroupLayout({
10
+ entries: [
11
+ {
12
+ binding: 0,
13
+ visibility: GPUShaderStage.FRAGMENT,
14
+ buffer: { type: 'uniform' },
15
+ },
16
+ ],
17
+ });
18
+ const textureBindGroupLayouts = [];
19
+ for (let i = 0; i < textureInputCount; i++) {
20
+ textureBindGroupLayouts.push(device.createBindGroupLayout({
21
+ entries: [
22
+ { binding: 0, visibility: GPUShaderStage.FRAGMENT, texture: { sampleType: 'float' } },
23
+ { binding: 1, visibility: GPUShaderStage.FRAGMENT, sampler: { type: 'filtering' } },
24
+ ],
25
+ }));
26
+ }
27
+ const pipelineLayout = device.createPipelineLayout({
28
+ bindGroupLayouts: [uniformBindGroupLayout, ...textureBindGroupLayouts],
29
+ });
30
+ const vsModule = device.createShaderModule({ code: FULLSCREEN_VERTEX_WGSL });
31
+ const fsModule = device.createShaderModule({ code: fragmentWgsl });
32
+ const pipeline = device.createRenderPipeline({
33
+ layout: pipelineLayout,
34
+ vertex: { module: vsModule, entryPoint: 'vs_main' },
35
+ fragment: {
36
+ module: fsModule,
37
+ entryPoint: 'fs_main',
38
+ targets: [{ format }],
39
+ },
40
+ primitive: { topology: 'triangle-list' },
41
+ });
42
+ return { pipeline, pipelineLayout, uniformBindGroupLayout, textureBindGroupLayouts };
43
+ }
44
+ // Destroys a fullscreen pipeline's GPU resources. The pipeline and layouts are GC-managed in
45
+ // WebGPU and have no explicit destroy(); this function is a no-op but kept for API symmetry with
46
+ // createWgpuFullscreenPipeline and to signal that the caller should drop its reference.
47
+ export function destroyWgpuFullscreenPipeline(_state, _pipeline) {
48
+ // WebGPU pipelines and layouts have no destroy() — they are GC-managed. Drop the reference
49
+ // on the caller's side to allow collection.
50
+ }
51
+ // Draws a fullscreen pass into the current render target (or a provided explicit target).
52
+ // Binds `inputs[i]` as texture @group(1+i) @binding(0), calls `setUniforms` for per-pass
53
+ // uploads (pass null if the shader declares no uniforms), then draws 3 vertices.
54
+ //
55
+ // Requires an open render pass (renderWgpuBackground or beginWgpuRenderTarget must have been
56
+ // called first). When `dest` is null the current open pass is used as-is; when `dest` is
57
+ // provided, its bind group is set via the caller's render pass.
58
+ export function drawWgpuFullscreenPass(state, wgpuPipeline, inputs, dest, setUniforms) {
59
+ const runtime = getWgpuRenderStateRuntime(state);
60
+ const pass = dest !== null ? runtime.renderPass : runtime.renderPass;
61
+ if (pass === null)
62
+ return;
63
+ pass.setPipeline(wgpuPipeline.pipeline);
64
+ if (setUniforms !== null) {
65
+ const uniformBindGroup = setUniforms(state, wgpuPipeline.uniformBindGroupLayout);
66
+ pass.setBindGroup(0, uniformBindGroup);
67
+ }
68
+ const runtime2 = getWgpuRenderStateRuntime(state);
69
+ for (let i = 0; i < inputs.length; i++) {
70
+ const input = inputs[i];
71
+ const layout = wgpuPipeline.textureBindGroupLayouts[i];
72
+ if (layout === undefined)
73
+ continue;
74
+ const sampler = state.allowSmoothing ? runtime2.linearSampler : runtime2.nearestSampler;
75
+ const bindGroup = state.device.createBindGroup({
76
+ layout,
77
+ entries: [
78
+ { binding: 0, resource: input.view },
79
+ { binding: 1, resource: sampler },
80
+ ],
81
+ });
82
+ pass.setBindGroup(1 + i, bindGroup);
83
+ }
84
+ pass.draw(3);
85
+ }
86
+ // The substrate-level WebGPU fullscreen-pass primitive. Filter and effect leaf packages draw
87
+ // through this; it is not filter-specific.
88
+ //
89
+ // The vertex shader generates a full-screen triangle from the vertex index alone (no vertex
90
+ // buffer needed): three vertices cover the clip space (-1..1 in both axes) with a single
91
+ // extra-large triangle. This avoids the clip-space seam that a quad with a diagonal would
92
+ // introduce and is the canonical WebGPU full-screen approach.
93
+ //
94
+ // Fragment shaders read input textures at @group(1) @binding(i) (one binding per input).
95
+ // An optional uniform buffer lives at @group(0) @binding(0) (set by the caller via setUniforms).
96
+ // Fragment shaders that take no uniforms may omit group 0 entirely.
97
+ const FULLSCREEN_VERTEX_WGSL = /* wgsl */ `
98
+ @vertex
99
+ fn vs_main(@builtin(vertex_index) vi : u32) -> @builtin(position) vec4f {
100
+ // Full-screen triangle: three vertices covering the clip rect.
101
+ let x = f32((vi & 1u) << 2u) - 1.0;
102
+ let y = f32((vi & 2u) << 1u) - 1.0;
103
+ return vec4f(x, y, 0.0, 1.0);
104
+ }
105
+ `;
106
+ //# sourceMappingURL=wgpuFullscreenPass.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wgpuFullscreenPass.js","sourceRoot":"","sources":["../src/wgpuFullscreenPass.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { Kind, Material, WgpuMaterialRenderer, WgpuRenderState } from '@flighthq/types';
2
+ export declare function getWgpuMaterialRenderer(state: WgpuRenderState, kind: Kind): WgpuMaterialRenderer | null;
3
+ export declare function registerWgpuMaterialRenderer(state: WgpuRenderState, kind: Kind, renderer: WgpuMaterialRenderer): void;
4
+ export declare function resolveWgpuMaterialRenderer(state: WgpuRenderState, material: Material | null): WgpuMaterialRenderer | null;
5
+ //# sourceMappingURL=wgpuMaterialRegistry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wgpuMaterialRegistry.d.ts","sourceRoot":"","sources":["../src/wgpuMaterialRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAK7F,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,IAAI,GAAG,oBAAoB,GAAG,IAAI,CAGvG;AAED,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,oBAAoB,GAAG,IAAI,CAGrH;AAMD,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,eAAe,EACtB,QAAQ,EAAE,QAAQ,GAAG,IAAI,GACxB,oBAAoB,GAAG,IAAI,CAS7B"}
@@ -0,0 +1,27 @@
1
+ import { DefaultMaterialKind } from '@flighthq/types';
2
+ import { getWgpuRenderStateRuntime } from './wgpuRenderState';
3
+ export function getWgpuMaterialRenderer(state, kind) {
4
+ const runtime = getWgpuRenderStateRuntime(state);
5
+ return runtime.materialRendererMap?.get(kind) ?? null;
6
+ }
7
+ export function registerWgpuMaterialRenderer(state, kind, renderer) {
8
+ const runtime = getWgpuRenderStateRuntime(state);
9
+ (runtime.materialRendererMap ??= new Map()).set(kind, renderer);
10
+ }
11
+ // Resolves a node's material to its registered renderer: by the material's kind, else the renderer
12
+ // registered for DefaultMaterialKind, else null. The render path knows nothing about which materials
13
+ // exist — every material (including the default) enters only through user registration, and an
14
+ // unresolved material is a no-op (the node does not render), never a built-in fallback.
15
+ export function resolveWgpuMaterialRenderer(state, material) {
16
+ const runtime = getWgpuRenderStateRuntime(state);
17
+ const map = runtime.materialRendererMap;
18
+ if (map === undefined)
19
+ return null;
20
+ if (material !== null) {
21
+ const renderer = map.get(material.kind);
22
+ if (renderer !== undefined)
23
+ return renderer;
24
+ }
25
+ return map.get(DefaultMaterialKind) ?? null;
26
+ }
27
+ //# sourceMappingURL=wgpuMaterialRegistry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wgpuMaterialRegistry.js","sourceRoot":"","sources":["../src/wgpuMaterialRegistry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAEtD,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAE9D,MAAM,UAAU,uBAAuB,CAAC,KAAsB,EAAE,IAAU;IACxE,MAAM,OAAO,GAAG,yBAAyB,CAAC,KAAK,CAAC,CAAC;IACjD,OAAO,OAAO,CAAC,mBAAmB,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,4BAA4B,CAAC,KAAsB,EAAE,IAAU,EAAE,QAA8B;IAC7G,MAAM,OAAO,GAAG,yBAAyB,CAAC,KAAK,CAAC,CAAC;IACjD,CAAC,OAAO,CAAC,mBAAmB,KAAK,IAAI,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAClE,CAAC;AAED,mGAAmG;AACnG,qGAAqG;AACrG,+FAA+F;AAC/F,wFAAwF;AACxF,MAAM,UAAU,2BAA2B,CACzC,KAAsB,EACtB,QAAyB;IAEzB,MAAM,OAAO,GAAG,yBAAyB,CAAC,KAAK,CAAC,CAAC;IACjD,MAAM,GAAG,GAAG,OAAO,CAAC,mBAAmB,CAAC;IACxC,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACnC,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO,QAAQ,CAAC;IAC9C,CAAC;IACD,OAAO,GAAG,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,IAAI,CAAC;AAC9C,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { WgpuRenderOptions, WgpuRenderState, WgpuRenderStateRuntime } from '@flighthq/types';
2
+ export declare function createWgpuRenderState(canvas: HTMLCanvasElement, options?: Partial<WgpuRenderOptions>): Promise<WgpuRenderState>;
3
+ export declare function createWgpuRenderStateRuntime(): WgpuRenderStateRuntime;
4
+ export declare function destroyWgpuRenderState(state: WgpuRenderState): void;
5
+ export declare function getWgpuRenderStateRuntime(state: WgpuRenderState): WgpuRenderStateRuntime;
6
+ export declare function isWgpuSupported(): boolean;
7
+ //# sourceMappingURL=wgpuRenderState.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wgpuRenderState.d.ts","sourceRoot":"","sources":["../src/wgpuRenderState.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AASlG,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,iBAAiB,EACzB,OAAO,GAAE,OAAO,CAAC,iBAAiB,CAAM,GACvC,OAAO,CAAC,eAAe,CAAC,CAsI1B;AAMD,wBAAgB,4BAA4B,IAAI,sBAAsB,CAErE;AAWD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CASnE;AAID,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,eAAe,GAAG,sBAAsB,CAExF;AAED,wBAAgB,eAAe,IAAI,OAAO,CAEzC"}