@flighthq/effects-wgpu 0.3.0 → 0.3.1-next.1041.35b950c
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/enableWgpuRenderEffectGuards.d.ts +5 -0
- package/dist/enableWgpuRenderEffectGuards.d.ts.map +1 -0
- package/dist/enableWgpuRenderEffectGuards.js +63 -0
- package/dist/enableWgpuRenderEffectGuards.js.map +1 -0
- package/dist/wgpuBevelEffect.d.ts.map +1 -1
- package/dist/wgpuBevelEffect.js +13 -7
- package/dist/wgpuBevelEffect.js.map +1 -1
- package/dist/wgpuConvolutionEffect.d.ts.map +1 -1
- package/dist/wgpuConvolutionEffect.js +8 -4
- package/dist/wgpuConvolutionEffect.js.map +1 -1
- package/dist/wgpuDropShadowEffect.d.ts.map +1 -1
- package/dist/wgpuDropShadowEffect.js +3 -1
- package/dist/wgpuDropShadowEffect.js.map +1 -1
- package/dist/wgpuEffectTintShader.d.ts.map +1 -1
- package/dist/wgpuEffectTintShader.js +13 -13
- package/dist/wgpuEffectTintShader.js.map +1 -1
- package/dist/wgpuGradientBevelEffect.d.ts.map +1 -1
- package/dist/wgpuGradientBevelEffect.js +3 -8
- package/dist/wgpuGradientBevelEffect.js.map +1 -1
- package/dist/wgpuGradientGlowEffect.js +1 -1
- package/dist/wgpuGradientGlowEffect.js.map +1 -1
- package/dist/wgpuInnerGlowEffect.d.ts.map +1 -1
- package/dist/wgpuInnerGlowEffect.js +8 -8
- package/dist/wgpuInnerGlowEffect.js.map +1 -1
- package/dist/wgpuInnerShadowEffect.d.ts.map +1 -1
- package/dist/wgpuInnerShadowEffect.js +8 -8
- package/dist/wgpuInnerShadowEffect.js.map +1 -1
- package/dist/wgpuOuterGlowEffect.js +1 -1
- package/dist/wgpuOuterGlowEffect.js.map +1 -1
- package/dist/wgpuRenderEffectPipeline.d.ts +2 -1
- package/dist/wgpuRenderEffectPipeline.d.ts.map +1 -1
- package/dist/wgpuRenderEffectPipeline.js +16 -1
- package/dist/wgpuRenderEffectPipeline.js.map +1 -1
- package/dist/wgpuRenderEffectRegistry.d.ts.map +1 -1
- package/dist/wgpuRenderEffectRegistry.js +6 -3
- package/dist/wgpuRenderEffectRegistry.js.map +1 -1
- package/dist/wgpuRenderTextureEffect.d.ts +4 -1
- package/dist/wgpuRenderTextureEffect.d.ts.map +1 -1
- package/dist/wgpuRenderTextureEffect.js +60 -3
- package/dist/wgpuRenderTextureEffect.js.map +1 -1
- package/dist/wgpuScreenSpaceFogEffect.js +1 -1
- package/dist/wgpuScreenSpaceFogEffect.js.map +1 -1
- package/package.json +13 -6
- package/src/enableWgpuRenderEffectGuards.test.ts +169 -0
- package/src/wgpuInnerGlowEffect.test.ts +1 -1
- package/src/wgpuInnerShadowEffect.test.ts +1 -1
- package/src/wgpuRenderEffectPipeline.test.ts +31 -0
- package/src/wgpuRenderEffectRegistry.test.ts +21 -1
- package/src/wgpuRenderTextureEffect.test.ts +57 -2
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import type { Adjustment, RenderEffect, RenderEffectPipelineOptions, RenderTargetColorSpace, WgpuRenderEffectPipeline, WgpuRenderState } from '@flighthq/types/contract';
|
|
1
|
+
import type { Adjustment, RenderEffect, RenderEffectPipelineOptions, RenderTargetColorSpace, WgpuRenderEffectPipeline, WgpuRenderEffectPipelineSkipGuard, WgpuRenderState } from '@flighthq/types/contract';
|
|
2
2
|
export declare function beginWgpuRenderEffectPipeline(state: WgpuRenderState, pipeline: WgpuRenderEffectPipeline, colorSpace?: RenderTargetColorSpace): void;
|
|
3
3
|
export declare function createWgpuRenderEffectPipeline(_state: WgpuRenderState, options?: Readonly<RenderEffectPipelineOptions>): WgpuRenderEffectPipeline;
|
|
4
4
|
export declare function destroyWgpuRenderEffectPipeline(state: WgpuRenderState, pipeline: WgpuRenderEffectPipeline): void;
|
|
5
5
|
export declare function endWgpuRenderEffectPipeline(state: WgpuRenderState, pipeline: WgpuRenderEffectPipeline, operations: ReadonlyArray<RenderEffect | Adjustment>): void;
|
|
6
|
+
export declare function setWgpuRenderEffectPipelineSkipGuard(state: WgpuRenderState, guard: WgpuRenderEffectPipelineSkipGuard | null): void;
|
|
6
7
|
export declare function setWgpuRenderEffectVelocityTexture(pipeline: WgpuRenderEffectPipeline, texture: GPUTexture | null): void;
|
|
7
8
|
//# sourceMappingURL=wgpuRenderEffectPipeline.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wgpuRenderEffectPipeline.d.ts","sourceRoot":"","sources":["../src/wgpuRenderEffectPipeline.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EACV,UAAU,EACV,YAAY,EACZ,2BAA2B,EAC3B,sBAAsB,EACtB,wBAAwB,EACxB,eAAe,EAEhB,MAAM,0BAA0B,CAAC;AAmBlC,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,eAAe,EACtB,QAAQ,EAAE,wBAAwB,EAClC,UAAU,GAAE,sBAA+B,GAC1C,IAAI,CAqBN;AAED,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,eAAe,EACvB,OAAO,GAAE,QAAQ,CAAC,2BAA2B,CAAM,GAClD,wBAAwB,CAS1B;AAED,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,wBAAwB,GAAG,IAAI,CAYhH;AAED,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,eAAe,EACtB,QAAQ,EAAE,wBAAwB,EAClC,UAAU,EAAE,aAAa,CAAC,YAAY,GAAG,UAAU,CAAC,GACnD,IAAI,
|
|
1
|
+
{"version":3,"file":"wgpuRenderEffectPipeline.d.ts","sourceRoot":"","sources":["../src/wgpuRenderEffectPipeline.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EACV,UAAU,EACV,YAAY,EACZ,2BAA2B,EAC3B,sBAAsB,EACtB,wBAAwB,EACxB,iCAAiC,EACjC,eAAe,EAEhB,MAAM,0BAA0B,CAAC;AAmBlC,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,eAAe,EACtB,QAAQ,EAAE,wBAAwB,EAClC,UAAU,GAAE,sBAA+B,GAC1C,IAAI,CAqBN;AAED,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,eAAe,EACvB,OAAO,GAAE,QAAQ,CAAC,2BAA2B,CAAM,GAClD,wBAAwB,CAS1B;AAED,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,wBAAwB,GAAG,IAAI,CAYhH;AAED,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,eAAe,EACtB,QAAQ,EAAE,wBAAwB,EAClC,UAAU,EAAE,aAAa,CAAC,YAAY,GAAG,UAAU,CAAC,GACnD,IAAI,CA2EN;AAOD,wBAAgB,oCAAoC,CAClD,KAAK,EAAE,eAAe,EACtB,KAAK,EAAE,iCAAiC,GAAG,IAAI,GAC9C,IAAI,CAGN;AAED,wBAAgB,kCAAkC,CAChD,QAAQ,EAAE,wBAAwB,EAClC,OAAO,EAAE,UAAU,GAAG,IAAI,GACzB,IAAI,CAEN"}
|
|
@@ -108,8 +108,10 @@ export function endWgpuRenderEffectPipeline(state, pipeline, operations) {
|
|
|
108
108
|
continue;
|
|
109
109
|
}
|
|
110
110
|
const runner = getWgpuRenderEffectRunner(state, operation.kind);
|
|
111
|
-
if (runner === null)
|
|
111
|
+
if (runner === null) {
|
|
112
|
+
reportWgpuRenderEffectPipelineSkip(state, operation.kind);
|
|
112
113
|
continue;
|
|
114
|
+
}
|
|
113
115
|
flushAdjustments();
|
|
114
116
|
ensureScratch();
|
|
115
117
|
const dest = source === scratchA ? scratchB : scratchA;
|
|
@@ -135,6 +137,15 @@ export function endWgpuRenderEffectPipeline(state, pipeline, operations) {
|
|
|
135
137
|
}
|
|
136
138
|
// Sets the velocity G-buffer the pipeline feeds to velocity-driven effects this frame, or null to
|
|
137
139
|
// clear it. The Wgpu mirror of setGlRenderEffectVelocityTexture.
|
|
140
|
+
// The diagnostics seam. Core stays message-free; enableWgpuRenderEffectGuards installs the reporter that
|
|
141
|
+
// turns a dropped effect into a caller-facing warning. Mirrors setWgpuRenderEffectApplicationGuard, which
|
|
142
|
+
// covers the render-texture path — this one covers the pipeline path, where the drop is a bare `continue`.
|
|
143
|
+
export function setWgpuRenderEffectPipelineSkipGuard(state, guard) {
|
|
144
|
+
if (guard === null)
|
|
145
|
+
_skipGuards.delete(state);
|
|
146
|
+
else
|
|
147
|
+
_skipGuards.set(state, guard);
|
|
148
|
+
}
|
|
138
149
|
export function setWgpuRenderEffectVelocityTexture(pipeline, texture) {
|
|
139
150
|
pipeline.velocityTexture = texture;
|
|
140
151
|
}
|
|
@@ -184,4 +195,8 @@ fn fs_main(@location(0) uv : vec2f) -> @location(0) vec4f {
|
|
|
184
195
|
let linear = textureSampleLevel(tex, smp, uv, 0.0);
|
|
185
196
|
return vec4f(linearToSrgb(linear.rgb), linear.a);
|
|
186
197
|
}`;
|
|
198
|
+
function reportWgpuRenderEffectPipelineSkip(state, kind) {
|
|
199
|
+
_skipGuards.get(state)?.(state, kind);
|
|
200
|
+
}
|
|
201
|
+
const _skipGuards = new WeakMap();
|
|
187
202
|
//# sourceMappingURL=wgpuRenderEffectPipeline.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wgpuRenderEffectPipeline.js","sourceRoot":"","sources":["../src/wgpuRenderEffectPipeline.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,wBAAwB,EACxB,oBAAoB,GACrB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,uBAAuB,EACvB,mBAAmB,EACnB,sBAAsB,EACtB,0BAA0B,EAC1B,uBAAuB,EACvB,2BAA2B,EAC3B,iBAAiB,EACjB,yBAAyB,EACzB,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"wgpuRenderEffectPipeline.js","sourceRoot":"","sources":["../src/wgpuRenderEffectPipeline.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wgpuRenderEffectRegistry.d.ts","sourceRoot":"","sources":["../src/wgpuRenderEffectRegistry.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"wgpuRenderEffectRegistry.d.ts","sourceRoot":"","sources":["../src/wgpuRenderEffectRegistry.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAWxF,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,GAAG,sBAAsB,GAAG,IAAI,CAG7G;AAMD,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAIvF;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,sBAAsB,GAAG,IAAI,CAGnH"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { withRegistryTableEntry } from '@flighthq/registry/contract';
|
|
1
2
|
import { getWgpuRenderStateRuntime } from '@flighthq/render-wgpu/contract';
|
|
3
|
+
import { RegistryEntryState } from '@flighthq/types/contract';
|
|
2
4
|
// Per-state registry mapping an effect `kind` string to its Wgpu runner — the material-renderer
|
|
3
5
|
// pattern one tier up. Registration is opt-in (import a runner only to register it) and dispatch is a
|
|
4
6
|
// Map lookup, so there is no monolithic switch and unused effect recipes tree-shake away. Register an
|
|
@@ -7,17 +9,18 @@ import { getWgpuRenderStateRuntime } from '@flighthq/render-wgpu/contract';
|
|
|
7
9
|
// A built-in registerWgpu<Kind>Effect wrapper is pure ergonomics: it calls this function with the
|
|
8
10
|
// literal kind and public default runner, and installs no padding, shader-source, or backdrop companions.
|
|
9
11
|
export function getWgpuRenderEffectRunner(state, kind) {
|
|
10
|
-
|
|
12
|
+
const entry = getWgpuRenderStateRuntime(state).registries.renderEffects.entries.get(kind);
|
|
13
|
+
return entry?.state === RegistryEntryState.Bound ? entry.value : null;
|
|
11
14
|
}
|
|
12
15
|
// Returns true if a runner is registered for the given kind in this state. Symmetric with
|
|
13
16
|
// hasGlRenderEffectRunner. Use to validate an effect chain before dispatching — the pipeline
|
|
14
17
|
// silently skips unregistered kinds; check up front to apply your own policy (warn, filter)
|
|
15
18
|
// rather than relying on silent no-ops.
|
|
16
19
|
export function hasWgpuRenderEffectRunner(state, kind) {
|
|
17
|
-
return getWgpuRenderStateRuntime(state).
|
|
20
|
+
return (getWgpuRenderStateRuntime(state).registries.renderEffects.entries.get(kind)?.state === RegistryEntryState.Bound);
|
|
18
21
|
}
|
|
19
22
|
export function registerWgpuRenderEffect(state, kind, runner) {
|
|
20
23
|
const runtime = getWgpuRenderStateRuntime(state);
|
|
21
|
-
|
|
24
|
+
runtime.registries.renderEffects = withRegistryTableEntry(runtime.registries.renderEffects, kind, runner);
|
|
22
25
|
}
|
|
23
26
|
//# sourceMappingURL=wgpuRenderEffectRegistry.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wgpuRenderEffectRegistry.js","sourceRoot":"","sources":["../src/wgpuRenderEffectRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"wgpuRenderEffectRegistry.js","sourceRoot":"","sources":["../src/wgpuRenderEffectRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAE3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE9D,gGAAgG;AAChG,sGAAsG;AACtG,sGAAsG;AACtG,8FAA8F;AAC9F,yGAAyG;AACzG,kGAAkG;AAClG,0GAA0G;AAE1G,MAAM,UAAU,yBAAyB,CAAC,KAAsB,EAAE,IAAY;IAC5E,MAAM,KAAK,GAAG,yBAAyB,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC1F,OAAO,KAAK,EAAE,KAAK,KAAK,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACxE,CAAC;AAED,0FAA0F;AAC1F,6FAA6F;AAC7F,4FAA4F;AAC5F,wCAAwC;AACxC,MAAM,UAAU,yBAAyB,CAAC,KAAsB,EAAE,IAAY;IAC5E,OAAO,CACL,yBAAyB,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,KAAK,KAAK,kBAAkB,CAAC,KAAK,CAChH,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,KAAsB,EAAE,IAAY,EAAE,MAA8B;IAC3G,MAAM,OAAO,GAAG,yBAAyB,CAAC,KAAK,CAAC,CAAC;IACjD,OAAO,CAAC,UAAU,CAAC,aAAa,GAAG,sBAAsB,CAAC,OAAO,CAAC,UAAU,CAAC,aAAa,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AAC5G,CAAC"}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
-
import type { RenderEffect, RenderTexture, WgpuRenderState, WgpuRenderTexturePool } from '@flighthq/types/contract';
|
|
1
|
+
import type { RenderEffect, RenderTexture, WgpuRenderEffectApplicationExplanation, WgpuRenderEffectApplicationGuard, WgpuRenderState, WgpuRenderTexturePool } from '@flighthq/types/contract';
|
|
2
2
|
export declare function applyWgpuRenderEffectsToRenderTexture(state: WgpuRenderState, pool: WgpuRenderTexturePool, source: Readonly<RenderTexture>, dest: RenderTexture, scratch: RenderTexture, effects: ReadonlyArray<Readonly<RenderEffect>>): boolean;
|
|
3
|
+
/** Explains why an application did not do what the caller asked, as plain data. */
|
|
4
|
+
export declare function explainWgpuRenderEffectApplication(state: WgpuRenderState, source: Readonly<RenderTexture>, dest: Readonly<RenderTexture>, effects: ReadonlyArray<Readonly<RenderEffect>>): WgpuRenderEffectApplicationExplanation;
|
|
5
|
+
export declare function setWgpuRenderEffectApplicationGuard(state: WgpuRenderState, guard: WgpuRenderEffectApplicationGuard | null): void;
|
|
3
6
|
//# sourceMappingURL=wgpuRenderTextureEffect.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wgpuRenderTextureEffect.d.ts","sourceRoot":"","sources":["../src/wgpuRenderTextureEffect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"wgpuRenderTextureEffect.d.ts","sourceRoot":"","sources":["../src/wgpuRenderTextureEffect.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,sCAAsC,EACtC,gCAAgC,EAEhC,eAAe,EACf,qBAAqB,EACtB,MAAM,0BAA0B,CAAC;AAOlC,wBAAgB,qCAAqC,CACnD,KAAK,EAAE,eAAe,EACtB,IAAI,EAAE,qBAAqB,EAC3B,MAAM,EAAE,QAAQ,CAAC,aAAa,CAAC,EAC/B,IAAI,EAAE,aAAa,EACnB,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,aAAa,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,GAC7C,OAAO,CAoDT;AAED,mFAAmF;AACnF,wBAAgB,kCAAkC,CAChD,KAAK,EAAE,eAAe,EACtB,MAAM,EAAE,QAAQ,CAAC,aAAa,CAAC,EAC/B,IAAI,EAAE,QAAQ,CAAC,aAAa,CAAC,EAC7B,OAAO,EAAE,aAAa,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,GAC7C,sCAAsC,CAgBxC;AAID,wBAAgB,mCAAmC,CACjD,KAAK,EAAE,eAAe,EACtB,KAAK,EAAE,gCAAgC,GAAG,IAAI,GAC7C,IAAI,CAGN"}
|
|
@@ -8,12 +8,26 @@ export function applyWgpuRenderEffectsToRenderTexture(state, pool, source, dest,
|
|
|
8
8
|
throw new Error('applyWgpuRenderEffectsToRenderTexture: source, destination, and scratch must be distinct');
|
|
9
9
|
}
|
|
10
10
|
const sourceTarget = getWgpuRenderTextureTarget(state, source);
|
|
11
|
-
|
|
12
|
-
return false;
|
|
11
|
+
const unregisteredKinds = [];
|
|
13
12
|
const operations = effects.flatMap((effect) => {
|
|
14
13
|
const runner = getWgpuRenderEffectRunner(state, effect.kind);
|
|
15
|
-
|
|
14
|
+
if (runner === null) {
|
|
15
|
+
unregisteredKinds.push(effect.kind);
|
|
16
|
+
return [];
|
|
17
|
+
}
|
|
18
|
+
return [{ effect, runner }];
|
|
19
|
+
});
|
|
20
|
+
// Reported BEFORE either early return, because both of them are the silent cases: a false return that
|
|
21
|
+
// never wrote `dest` leaves whatever a consumer last sampled in place, which reads as a stale frame
|
|
22
|
+
// rather than as a failed call.
|
|
23
|
+
reportWgpuRenderEffectApplication(state, {
|
|
24
|
+
registeredCount: operations.length,
|
|
25
|
+
requestedCount: effects.length,
|
|
26
|
+
status: getWgpuRenderEffectApplicationStatus(effects.length, operations.length, sourceTarget !== null, getWgpuRenderTextureTarget(state, dest) !== null),
|
|
27
|
+
unregisteredKinds,
|
|
16
28
|
});
|
|
29
|
+
if (sourceTarget === null)
|
|
30
|
+
return false;
|
|
17
31
|
if (operations.length === 0)
|
|
18
32
|
return false;
|
|
19
33
|
let current = sourceTarget;
|
|
@@ -35,4 +49,47 @@ export function applyWgpuRenderEffectsToRenderTexture(state, pool, source, dest,
|
|
|
35
49
|
}
|
|
36
50
|
return true;
|
|
37
51
|
}
|
|
52
|
+
/** Explains why an application did not do what the caller asked, as plain data. */
|
|
53
|
+
export function explainWgpuRenderEffectApplication(state, source, dest, effects) {
|
|
54
|
+
const unregisteredKinds = effects
|
|
55
|
+
.filter((effect) => getWgpuRenderEffectRunner(state, effect.kind) === null)
|
|
56
|
+
.map((effect) => effect.kind);
|
|
57
|
+
const registeredCount = effects.length - unregisteredKinds.length;
|
|
58
|
+
return {
|
|
59
|
+
registeredCount,
|
|
60
|
+
requestedCount: effects.length,
|
|
61
|
+
status: getWgpuRenderEffectApplicationStatus(effects.length, registeredCount, getWgpuRenderTextureTarget(state, source) !== null, getWgpuRenderTextureTarget(state, dest) !== null),
|
|
62
|
+
unregisteredKinds,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
// The diagnostics seam. Core stays message-free; enableWgpuRenderEffectGuards installs the reporter that
|
|
66
|
+
// turns these observations into caller-facing warnings.
|
|
67
|
+
export function setWgpuRenderEffectApplicationGuard(state, guard) {
|
|
68
|
+
if (guard === null)
|
|
69
|
+
_guards.delete(state);
|
|
70
|
+
else
|
|
71
|
+
_guards.set(state, guard);
|
|
72
|
+
}
|
|
73
|
+
function getWgpuRenderEffectApplicationStatus(requestedCount, registeredCount, sourceAvailable, destinationAvailable) {
|
|
74
|
+
// An empty chain is a no-op the caller asked for, NOT a miss — reporting it would train readers to
|
|
75
|
+
// ignore the crumb. A ready destination is the highest-cost failed-call outcome, because consumers
|
|
76
|
+
// keep sampling plausible pixels from an older application instead of an empty texture.
|
|
77
|
+
if (requestedCount === 0)
|
|
78
|
+
return 'no-effects';
|
|
79
|
+
if (destinationAvailable && (!sourceAvailable || registeredCount === 0))
|
|
80
|
+
return 'stale-destination';
|
|
81
|
+
if (!sourceAvailable)
|
|
82
|
+
return 'source-unavailable';
|
|
83
|
+
if (registeredCount === 0)
|
|
84
|
+
return 'unregistered-effects';
|
|
85
|
+
if (registeredCount < requestedCount)
|
|
86
|
+
return 'partial-registration';
|
|
87
|
+
return 'complete';
|
|
88
|
+
}
|
|
89
|
+
function reportWgpuRenderEffectApplication(state, explanation) {
|
|
90
|
+
if (explanation.status === 'complete' || explanation.status === 'no-effects')
|
|
91
|
+
return;
|
|
92
|
+
_guards.get(state)?.(state, explanation);
|
|
93
|
+
}
|
|
94
|
+
const _guards = new WeakMap();
|
|
38
95
|
//# sourceMappingURL=wgpuRenderTextureEffect.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wgpuRenderTextureEffect.js","sourceRoot":"","sources":["../src/wgpuRenderTextureEffect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"wgpuRenderTextureEffect.js","sourceRoot":"","sources":["../src/wgpuRenderTextureEffect.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@ import { registerWgpuRenderEffect } from './wgpuRenderEffectRegistry';
|
|
|
4
4
|
// Screen-space fog: blends the scene toward an unpacked fog color by a depth proxy. The real recipe
|
|
5
5
|
// reads a sampleable DEPTH texture per fragment — fog = 1 - exp(-density * remap(depth, near, far)) — but
|
|
6
6
|
// Wgpu has no depth G-buffer yet, so this color-only fallback uses the screen-Y gradient as the proxy
|
|
7
|
-
// (
|
|
7
|
+
// (top of frame reads as "far"). near/far are reserved for the depth-driven recipe; density scales
|
|
8
8
|
// the proxy. color is a packed RGBA int unpacked to 0..1 floats on the JS side.
|
|
9
9
|
export function applyScreenSpaceFogEffectToWgpu(state, source, dest, effect) {
|
|
10
10
|
const packed = effect.color ?? 0xc8d2dcff;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wgpuScreenSpaceFogEffect.js","sourceRoot":"","sources":["../src/wgpuScreenSpaceFogEffect.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAEtE,oGAAoG;AACpG,0GAA0G;AAC1G,sGAAsG;AACtG,
|
|
1
|
+
{"version":3,"file":"wgpuScreenSpaceFogEffect.js","sourceRoot":"","sources":["../src/wgpuScreenSpaceFogEffect.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAEtE,oGAAoG;AACpG,0GAA0G;AAC1G,sGAAsG;AACtG,mGAAmG;AACnG,gFAAgF;AAChF,MAAM,UAAU,+BAA+B,CAC7C,KAAsB,EACtB,MAAkC,EAClC,IAAgC,EAChC,MAAsC;IAEtC,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,IAAI,UAAU,CAAC;IAC1C,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC;IACzC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC;IACzC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC;IACxC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,CAAC,CAAC;IACpC,MAAM,QAAQ,GAAG,qBAAqB,CACpC,KAAK,EACL,4BAA4B,EAC5B,8BAA8B,EAC9B,SAAS,CACV,CAAC;IACF,kBAAkB,CAAC,KAAK,EAAE,MAA0B,EAAE,IAAwB,EAAE,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE;QAChG,GAAG,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;QACjB,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACX,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACX,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACb,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,MAAM,qCAAqC,GAA2B,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;IAC3F,+BAA+B,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,MAA8B,CAAC,CAAC;AACnG,CAAC,CAAC;AAEF,MAAM,UAAU,gCAAgC,CAAC,KAAsB;IACrE,wBAAwB,CAAC,KAAK,EAAE,sBAAsB,EAAE,qCAAqC,CAAC,CAAC;AACjG,CAAC;AAED,sGAAsG;AACtG,mEAAmE;AACnE,MAAM,8BAA8B,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;;;;;EAmBhD,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flighthq/effects-wgpu",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1-next.1041.35b950c",
|
|
4
4
|
"author": "Joshua Granick and other contributors",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -38,13 +38,20 @@
|
|
|
38
38
|
"clean:dist": "tsx ../../scripts/clean-package-dist.ts"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@flighthq/adjustments": "0.3.
|
|
42
|
-
"@flighthq/
|
|
43
|
-
"@flighthq/
|
|
44
|
-
"@flighthq/
|
|
45
|
-
"@flighthq/
|
|
41
|
+
"@flighthq/adjustments": "0.3.1-next.1041.35b950c",
|
|
42
|
+
"@flighthq/color": "0.3.1-next.1041.35b950c",
|
|
43
|
+
"@flighthq/effects": "0.3.1-next.1041.35b950c",
|
|
44
|
+
"@flighthq/geometry": "0.3.1-next.1041.35b950c",
|
|
45
|
+
"@flighthq/log": "0.3.1-next.1041.35b950c",
|
|
46
|
+
"@flighthq/render-wgpu": "0.3.1-next.1041.35b950c",
|
|
47
|
+
"@flighthq/registry": "0.3.1-next.1041.35b950c",
|
|
48
|
+
"@flighthq/types": "0.3.1-next.1041.35b950c"
|
|
49
|
+
},
|
|
50
|
+
"peerDependencies": {
|
|
51
|
+
"@webgpu/types": "^0.1.70"
|
|
46
52
|
},
|
|
47
53
|
"devDependencies": {
|
|
54
|
+
"@webgpu/types": "*",
|
|
48
55
|
"typescript": "^5.3.0"
|
|
49
56
|
},
|
|
50
57
|
"description": "WebGPU shader recipes for render effects (substrate-agnostic post-process pipeline)",
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { addLogSink, createMemoryLogSink, getMemoryLogSinkEntries, removeLogSink } from '@flighthq/log/contract';
|
|
2
|
+
import {
|
|
3
|
+
acquireWgpuRenderTexture,
|
|
4
|
+
beginWgpuFrame,
|
|
5
|
+
createWgpuRenderStateForTest,
|
|
6
|
+
createWgpuRenderTexturePool,
|
|
7
|
+
installWgpuMock,
|
|
8
|
+
writeWgpuRenderTextureTarget,
|
|
9
|
+
} from '@flighthq/render-wgpu/contract';
|
|
10
|
+
import type { LogEntry, RenderEffect, WgpuRenderEffectRunner, WgpuRenderState } from '@flighthq/types/contract';
|
|
11
|
+
|
|
12
|
+
import {
|
|
13
|
+
areWgpuRenderEffectGuardsEnabled,
|
|
14
|
+
disableWgpuRenderEffectGuards,
|
|
15
|
+
enableWgpuRenderEffectGuards,
|
|
16
|
+
} from './enableWgpuRenderEffectGuards';
|
|
17
|
+
import {
|
|
18
|
+
beginWgpuRenderEffectPipeline,
|
|
19
|
+
createWgpuRenderEffectPipeline,
|
|
20
|
+
endWgpuRenderEffectPipeline,
|
|
21
|
+
} from './wgpuRenderEffectPipeline';
|
|
22
|
+
import { registerWgpuRenderEffect } from './wgpuRenderEffectRegistry';
|
|
23
|
+
import { applyWgpuRenderEffectsToRenderTexture } from './wgpuRenderTextureEffect';
|
|
24
|
+
|
|
25
|
+
beforeAll(() => installWgpuMock());
|
|
26
|
+
|
|
27
|
+
describe('areWgpuRenderEffectGuardsEnabled', () => {
|
|
28
|
+
it('reports whether diagnostics were installed for the state', async () => {
|
|
29
|
+
const state = await createWgpuRenderStateForTest();
|
|
30
|
+
expect(areWgpuRenderEffectGuardsEnabled(state)).toBe(false);
|
|
31
|
+
|
|
32
|
+
enableWgpuRenderEffectGuards(state);
|
|
33
|
+
expect(areWgpuRenderEffectGuardsEnabled(state)).toBe(true);
|
|
34
|
+
|
|
35
|
+
disableWgpuRenderEffectGuards(state);
|
|
36
|
+
expect(areWgpuRenderEffectGuardsEnabled(state)).toBe(false);
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
describe('disableWgpuRenderEffectGuards', () => {
|
|
41
|
+
it('stops reporting, leaving the silent sentinel silent again', async () => {
|
|
42
|
+
const state = await createWgpuRenderStateForTest();
|
|
43
|
+
enableWgpuRenderEffectGuards(state);
|
|
44
|
+
disableWgpuRenderEffectGuards(state);
|
|
45
|
+
|
|
46
|
+
const entries = captureLog(() => {
|
|
47
|
+
expect(applyChain(state, ['test.wgpu-disabled-kind'])).toBe(false);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
expect(entries.length).toBe(0);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
describe('enableWgpuRenderEffectGuards', () => {
|
|
55
|
+
// logOnce suppresses a key for the whole PROCESS, so a fired key can never fire again in a later test.
|
|
56
|
+
// Both the fire and the silence assertions live in this one test, in order, and every test in this file
|
|
57
|
+
// uses distinct effect kinds so no two share a key.
|
|
58
|
+
it('WARNS that an unregistered chain returned false without writing dest, then stays quiet', async () => {
|
|
59
|
+
const state = await createWgpuRenderStateForTest();
|
|
60
|
+
enableWgpuRenderEffectGuards(state);
|
|
61
|
+
|
|
62
|
+
const entries = captureLog(() => {
|
|
63
|
+
expect(applyChain(state, ['test.wgpu-unregistered-a'])).toBe(false);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
expect(entries).toHaveLength(1);
|
|
67
|
+
expect(messageOf(entries[0])).toContain('NEVER WRITTEN');
|
|
68
|
+
expect(messageOf(entries[0])).toContain('registerWgpuRenderEffect');
|
|
69
|
+
|
|
70
|
+
const again = captureLog(() => {
|
|
71
|
+
expect(applyChain(state, ['test.wgpu-unregistered-a'])).toBe(false);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
expect(again).toHaveLength(0);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('WARNS that a partially registered chain silently DROPPED the effects it could not run', async () => {
|
|
78
|
+
const state = await createWgpuRenderStateForTest();
|
|
79
|
+
enableWgpuRenderEffectGuards(state);
|
|
80
|
+
registerWgpuRenderEffect(state, 'test.wgpu-registered-b', noopRunner);
|
|
81
|
+
|
|
82
|
+
const entries = captureLog(() => {
|
|
83
|
+
expect(applyChain(state, ['test.wgpu-registered-b', 'test.wgpu-unregistered-b'])).toBe(true);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
expect(entries).toHaveLength(1);
|
|
87
|
+
expect(messageOf(entries[0])).toContain('SKIPPED');
|
|
88
|
+
expect(messageOf(entries[0])).toContain('test.wgpu-unregistered-b');
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('WARNS that a pipeline pass DROPPED an effect kind with no runner, once per kind', async () => {
|
|
92
|
+
const state = await createWgpuRenderStateForTest();
|
|
93
|
+
enableWgpuRenderEffectGuards(state);
|
|
94
|
+
const pipeline = createWgpuRenderEffectPipeline(state);
|
|
95
|
+
const chain = [{ kind: 'test.wgpu-pipeline-dropped-kind' }] as unknown as Readonly<RenderEffect>[];
|
|
96
|
+
|
|
97
|
+
const entries = captureLog(() => {
|
|
98
|
+
beginWgpuFrame(state);
|
|
99
|
+
beginWgpuRenderEffectPipeline(state, pipeline);
|
|
100
|
+
endWgpuRenderEffectPipeline(state, pipeline, chain);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
expect(entries).toHaveLength(1);
|
|
104
|
+
expect(messageOf(entries[0])).toContain('test.wgpu-pipeline-dropped-kind');
|
|
105
|
+
expect(messageOf(entries[0])).toContain('SKIPPED');
|
|
106
|
+
|
|
107
|
+
// Once per KIND, not once per frame: a chain missing the same effect every frame is one observation,
|
|
108
|
+
// and a warning that repeated per frame would be its own defect.
|
|
109
|
+
const again = captureLog(() => {
|
|
110
|
+
beginWgpuFrame(state);
|
|
111
|
+
beginWgpuRenderEffectPipeline(state, pipeline);
|
|
112
|
+
endWgpuRenderEffectPipeline(state, pipeline, chain);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
expect(again).toHaveLength(0);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it('stays SILENT for an empty chain, which is a no-op the caller asked for rather than a miss', async () => {
|
|
119
|
+
const state = await createWgpuRenderStateForTest();
|
|
120
|
+
enableWgpuRenderEffectGuards(state);
|
|
121
|
+
|
|
122
|
+
const entries = captureLog(() => {
|
|
123
|
+
expect(applyChain(state, [])).toBe(false);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
expect(entries).toHaveLength(0);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it('stays SILENT when every requested effect has a runner', async () => {
|
|
130
|
+
const state = await createWgpuRenderStateForTest();
|
|
131
|
+
enableWgpuRenderEffectGuards(state);
|
|
132
|
+
registerWgpuRenderEffect(state, 'test.wgpu-registered-c', noopRunner);
|
|
133
|
+
|
|
134
|
+
const entries = captureLog(() => {
|
|
135
|
+
expect(applyChain(state, ['test.wgpu-registered-c'])).toBe(true);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
expect(entries).toHaveLength(0);
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
function applyChain(state: WgpuRenderState, kinds: readonly string[]): boolean {
|
|
143
|
+
const pool = createWgpuRenderTexturePool();
|
|
144
|
+
const source = acquireWgpuRenderTexture(state, pool, { width: 8, height: 8 });
|
|
145
|
+
const dest = acquireWgpuRenderTexture(state, pool, { width: 8, height: 8 });
|
|
146
|
+
const scratch = acquireWgpuRenderTexture(state, pool, { width: 8, height: 8 });
|
|
147
|
+
// Realize the source so `source-unavailable` is not what is being measured here.
|
|
148
|
+
writeWgpuRenderTextureTarget(state, source, () => {});
|
|
149
|
+
const effects = kinds.map((kind) => ({ kind }) as unknown as Readonly<RenderEffect>);
|
|
150
|
+
return applyWgpuRenderEffectsToRenderTexture(state, pool, source, dest, scratch, effects);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function captureLog(run: () => void): readonly LogEntry[] {
|
|
154
|
+
const sink = createMemoryLogSink(8);
|
|
155
|
+
addLogSink(sink.sink);
|
|
156
|
+
try {
|
|
157
|
+
run();
|
|
158
|
+
} finally {
|
|
159
|
+
removeLogSink(sink.sink);
|
|
160
|
+
}
|
|
161
|
+
return getMemoryLogSinkEntries(sink);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function messageOf(entry: Readonly<LogEntry>): string {
|
|
165
|
+
const data = entry.data;
|
|
166
|
+
return typeof data === 'string' ? data : String(data.message);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const noopRunner: WgpuRenderEffectRunner = () => {};
|
|
@@ -1,11 +1,17 @@
|
|
|
1
|
+
import { beginWgpuFrame, createWgpuRenderStateForTest, installWgpuMock } from '@flighthq/render-wgpu/contract';
|
|
2
|
+
import type { RenderEffect } from '@flighthq/types/contract';
|
|
3
|
+
|
|
1
4
|
import {
|
|
2
5
|
beginWgpuRenderEffectPipeline,
|
|
3
6
|
createWgpuRenderEffectPipeline,
|
|
4
7
|
destroyWgpuRenderEffectPipeline,
|
|
5
8
|
endWgpuRenderEffectPipeline,
|
|
9
|
+
setWgpuRenderEffectPipelineSkipGuard,
|
|
6
10
|
setWgpuRenderEffectVelocityTexture,
|
|
7
11
|
} from './wgpuRenderEffectPipeline';
|
|
8
12
|
|
|
13
|
+
beforeAll(() => installWgpuMock());
|
|
14
|
+
|
|
9
15
|
describe('beginWgpuRenderEffectPipeline', () => {
|
|
10
16
|
it('is a function', () => {
|
|
11
17
|
expect(typeof beginWgpuRenderEffectPipeline).toBe('function');
|
|
@@ -30,6 +36,31 @@ describe('endWgpuRenderEffectPipeline', () => {
|
|
|
30
36
|
});
|
|
31
37
|
});
|
|
32
38
|
|
|
39
|
+
describe('setWgpuRenderEffectPipelineSkipGuard', () => {
|
|
40
|
+
it('reports every effect kind the pass drops, and goes silent again when cleared', async () => {
|
|
41
|
+
const state = await createWgpuRenderStateForTest();
|
|
42
|
+
const pipeline = createWgpuRenderEffectPipeline(state);
|
|
43
|
+
const dropped: string[] = [];
|
|
44
|
+
const chain = [{ kind: 'test.wgpu-pipeline-skip-seam' } as RenderEffect];
|
|
45
|
+
|
|
46
|
+
setWgpuRenderEffectPipelineSkipGuard(state, (_state, kind) => dropped.push(kind));
|
|
47
|
+
beginWgpuFrame(state);
|
|
48
|
+
beginWgpuRenderEffectPipeline(state, pipeline);
|
|
49
|
+
endWgpuRenderEffectPipeline(state, pipeline, chain);
|
|
50
|
+
|
|
51
|
+
expect(dropped).toEqual(['test.wgpu-pipeline-skip-seam']);
|
|
52
|
+
|
|
53
|
+
// Clearing must restore the original silence exactly: the seam is the ONLY path by which a dropped
|
|
54
|
+
// effect is observable, so a stale guard would be the difference between a diagnostic and a leak.
|
|
55
|
+
setWgpuRenderEffectPipelineSkipGuard(state, null);
|
|
56
|
+
beginWgpuFrame(state);
|
|
57
|
+
beginWgpuRenderEffectPipeline(state, pipeline);
|
|
58
|
+
endWgpuRenderEffectPipeline(state, pipeline, chain);
|
|
59
|
+
|
|
60
|
+
expect(dropped).toEqual(['test.wgpu-pipeline-skip-seam']);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
33
64
|
describe('setWgpuRenderEffectVelocityTexture', () => {
|
|
34
65
|
it('sets the velocity texture on the pipeline', () => {
|
|
35
66
|
const pipeline = {
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
createWgpuRenderStateForTest,
|
|
3
|
+
getWgpuRenderStateRuntime,
|
|
4
|
+
installWgpuMock,
|
|
5
|
+
} from '@flighthq/render-wgpu/contract';
|
|
2
6
|
|
|
3
7
|
import {
|
|
4
8
|
getWgpuRenderEffectRunner,
|
|
@@ -34,7 +38,23 @@ describe('registerWgpuRenderEffect', () => {
|
|
|
34
38
|
it('registers a runner retrievable by its kind', async () => {
|
|
35
39
|
const state = await createWgpuRenderStateForTest();
|
|
36
40
|
const runner = vi.fn();
|
|
41
|
+
const before = getWgpuRenderStateRuntime(state).registries.renderEffects;
|
|
37
42
|
registerWgpuRenderEffect(state, 'VignetteEffect', runner);
|
|
38
43
|
expect(getWgpuRenderEffectRunner(state, 'VignetteEffect')).toBe(runner);
|
|
44
|
+
expect(getWgpuRenderStateRuntime(state).registries.renderEffects).not.toBe(before);
|
|
45
|
+
expect(before.entries.size).toBe(0);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('is last-write-wins without mutating the earlier snapshot', async () => {
|
|
49
|
+
const state = await createWgpuRenderStateForTest();
|
|
50
|
+
const runnerA = vi.fn();
|
|
51
|
+
const runnerB = vi.fn();
|
|
52
|
+
registerWgpuRenderEffect(state, 'TestEffect', runnerA);
|
|
53
|
+
const before = getWgpuRenderStateRuntime(state).registries.renderEffects;
|
|
54
|
+
|
|
55
|
+
registerWgpuRenderEffect(state, 'TestEffect', runnerB);
|
|
56
|
+
|
|
57
|
+
expect(getWgpuRenderEffectRunner(state, 'TestEffect')).toBe(runnerB);
|
|
58
|
+
expect(before.entries.get('TestEffect')).toEqual({ state: 'bound', value: runnerA });
|
|
39
59
|
});
|
|
40
60
|
});
|