@flighthq/render-wgpu 0.3.0-next.1445.14ca01c → 0.3.0-next.1454.b17f8a5

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.
@@ -1,6 +1,6 @@
1
1
  import type { Bitmap, WgpuRenderState } from '@flighthq/types/contract';
2
2
  export declare function acquireWgpuFrameCaptureTexture(state: Readonly<WgpuRenderState>): GPUTexture | null;
3
- export declare function createBitmapFromWgpuRenderState(state: Readonly<WgpuRenderState>): Promise<Bitmap>;
3
+ export declare function createBitmapFromWgpuRenderState(state: Readonly<WgpuRenderState>, timeoutMs?: number): Promise<Bitmap>;
4
4
  export declare function enableWgpuFrameCapture(state: Readonly<WgpuRenderState>): void;
5
5
  export declare function encodeWgpuFrameCapture(state: Readonly<WgpuRenderState>, encoder: GPUCommandEncoder): void;
6
6
  //# sourceMappingURL=wgpuSurface.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"wgpuSurface.d.ts","sourceRoot":"","sources":["../src/wgpuSurface.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAcxE,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,QAAQ,CAAC,eAAe,CAAC,GAAG,UAAU,GAAG,IAAI,CAmBlG;AAOD,wBAAsB,+BAA+B,CAAC,KAAK,EAAE,QAAQ,CAAC,eAAe,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CA0CvG;AAMD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,QAAQ,CAAC,eAAe,CAAC,GAAG,IAAI,CAE7E;AAKD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,EAAE,iBAAiB,GAAG,IAAI,CA2BzG"}
1
+ {"version":3,"file":"wgpuSurface.d.ts","sourceRoot":"","sources":["../src/wgpuSurface.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAmBxE,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,QAAQ,CAAC,eAAe,CAAC,GAAG,UAAU,GAAG,IAAI,CAmBlG;AAWD,wBAAsB,+BAA+B,CACnD,KAAK,EAAE,QAAQ,CAAC,eAAe,CAAC,EAChC,SAAS,SAAyB,GACjC,OAAO,CAAC,MAAM,CAAC,CA0CjB;AAMD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,QAAQ,CAAC,eAAe,CAAC,GAAG,IAAI,CAE7E;AAKD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,EAAE,iBAAiB,GAAG,IAAI,CAsCzG"}
@@ -6,6 +6,11 @@ import { getWgpuRenderStateRuntime } from './wgpuRenderState';
6
6
  // renderWgpuBackground); (2) GPU work queued in a later task than the frame is dropped on these
7
7
  // adapters, so submitWgpuRenderPass copies the capture texture into the retained capture buffer in the
8
8
  // same frame (encodeWgpuFrameCapture), and createBitmapFromWgpuRenderState only maps that buffer.
9
+ //
10
+ // One buffer serves both sides, so they take turns: the writer skips its copy while the reader holds a
11
+ // map (or has one in flight), and resumes on the next frame. Without that turn-taking a continuously
12
+ // animating scene re-enqueues a copy every frame into the buffer a readback is waiting on — which the
13
+ // queue may not touch while it is mapped, and which pushes the pending map behind ever more GPU work.
9
14
  // Returns the offscreen texture the frame should render into when capture is enabled, creating/resizing
10
15
  // it to the canvas on demand, or null when capture is off (the caller then renders to the swapchain).
11
16
  // Internal: called by renderWgpuBackground to redirect the frame so its pixels stay readable.
@@ -33,7 +38,11 @@ export function acquireWgpuFrameCaptureTexture(state) {
33
38
  // throws otherwise (calling it without enabling capture is API misuse). Only maps the retained buffer —
34
39
  // no GPU work is queued here, since later-task GPU work is unreliable on the adapters this exists for.
35
40
  // Allocates the returned Bitmap; the capture buffer is retained and reused across frames.
36
- export async function createBitmapFromWgpuRenderState(state) {
41
+ //
42
+ // `timeoutMs` bounds the buffer map (pass 0 to wait indefinitely, the pre-bound behaviour). The default
43
+ // is deliberately generous: a readback that takes seconds is a loaded machine, while one that never
44
+ // settles is the failure this bounds, and only the caller knows which budget it is working inside.
45
+ export async function createBitmapFromWgpuRenderState(state, timeoutMs = DEFAULT_MAP_TIMEOUT_MS) {
37
46
  const runtime = getWgpuRenderStateRuntime(state);
38
47
  const buffer = runtime.frameCaptureBuffer;
39
48
  if (buffer === null || buffer === undefined) {
@@ -42,7 +51,7 @@ export async function createBitmapFromWgpuRenderState(state) {
42
51
  const width = runtime.frameCaptureWidth;
43
52
  const height = runtime.frameCaptureHeight;
44
53
  const bytesPerRow = runtime.frameCaptureBytesPerRow;
45
- await buffer.mapAsync(GPUMapMode.READ);
54
+ await mapWgpuCaptureBuffer(buffer, timeoutMs);
46
55
  const mapped = new Uint8Array(buffer.getMappedRange());
47
56
  const bitmap = createBitmap(width, height);
48
57
  const out = bitmap.data;
@@ -85,6 +94,18 @@ export function encodeWgpuFrameCapture(state, encoder) {
85
94
  const texture = runtime.frameCaptureTexture;
86
95
  if (!runtime.frameCaptureEnabled || texture === null || texture === undefined)
87
96
  return;
97
+ // The reader owns the buffer while it holds a map. One retained buffer serves both sides, and the
98
+ // queue may not touch a buffer that is mapped or has a map in flight — so a frame encoded during a
99
+ // readback both invalidates the copy and stacks more GPU work in front of the map it is waiting on.
100
+ // Skipping the frame is the handshake: the reader is already taking a snapshot, and the next frame
101
+ // resumes copying once it lets go.
102
+ //
103
+ // Deliberately written as "is it busy" rather than "is it not unmapped": an implementation without
104
+ // `mapState` reports undefined, and the inverted test would then skip every copy for the whole run
105
+ // and capture nothing. Unknown state falls through to the copy, which is the pre-existing behaviour.
106
+ const mapState = runtime.frameCaptureBuffer?.mapState;
107
+ if (mapState === 'pending' || mapState === 'mapped')
108
+ return;
88
109
  const width = texture.width;
89
110
  const height = texture.height;
90
111
  // Wgpu requires copyTextureToBuffer rows to be 256-byte aligned; the buffer is padded per row.
@@ -104,4 +125,31 @@ export function encodeWgpuFrameCapture(state, encoder) {
104
125
  }
105
126
  encoder.copyTextureToBuffer({ texture }, { buffer: runtime.frameCaptureBuffer, bytesPerRow }, [width, height, 1]);
106
127
  }
128
+ // Maps the retained capture buffer, giving up by name after `timeoutMs` (0 waits indefinitely).
129
+ // `mapAsync` carries no timeout and no reject path of its own: on the contended software adapters this
130
+ // capture path exists for, the promise can simply never settle, and an unbounded await is indistinguishable
131
+ // from a caller that stopped running. A late resolution after the deadline leaves the buffer mapped, which
132
+ // is why the timeout is a hard end for this capture and not something to retry against the same buffer.
133
+ async function mapWgpuCaptureBuffer(buffer, timeoutMs) {
134
+ const mapping = buffer.mapAsync(GPUMapMode.READ);
135
+ if (timeoutMs <= 0)
136
+ return mapping;
137
+ // The race abandons `mapping` on timeout; adopt its eventual rejection here so it is never unhandled.
138
+ mapping.catch(() => { });
139
+ let timer;
140
+ const expiry = new Promise((_resolve, reject) => {
141
+ timer = setTimeout(() => {
142
+ reject(new Error(`createBitmapFromWgpuRenderState: frame capture buffer did not map within ${timeoutMs}ms`));
143
+ }, timeoutMs);
144
+ });
145
+ try {
146
+ await Promise.race([mapping, expiry]);
147
+ }
148
+ finally {
149
+ clearTimeout(timer);
150
+ }
151
+ }
152
+ // Generous by design: this bounds a driver that has stopped answering, not a slow one. Callers working
153
+ // inside a tighter budget (the capture harness) pass their own.
154
+ const DEFAULT_MAP_TIMEOUT_MS = 10_000;
107
155
  //# sourceMappingURL=wgpuSurface.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"wgpuSurface.js","sourceRoot":"","sources":["../src/wgpuSurface.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"wgpuSurface.js","sourceRoot":"","sources":["../src/wgpuSurface.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,9 @@
1
- import type { TextureSourceKind, TextureLike, WgpuRenderState, WgpuTextureEntry, WgpuTextureResolver } from '@flighthq/types/contract';
1
+ import type { TextureColorSpace, TextureSourceKind, TextureLike, WgpuRenderState, WgpuTextureEntry, WgpuTextureResolver } from '@flighthq/types/contract';
2
2
  export declare function registerStandardWgpuTextureResolvers(state: WgpuRenderState): void;
3
3
  export declare function registerWgpuBitmapTextureResolver(state: WgpuRenderState): void;
4
4
  export declare function registerWgpuCompressedImageTextureResolver(state: WgpuRenderState): void;
5
5
  export declare function registerWgpuImageTextureResolver(state: WgpuRenderState): void;
6
6
  export declare function registerWgpuRenderTextureResolver(state: WgpuRenderState): void;
7
7
  export declare function registerWgpuTextureResolver(state: WgpuRenderState, sourceKind: TextureSourceKind, resolver: WgpuTextureResolver | null): void;
8
- export declare function resolveWgpuTexture(state: WgpuRenderState, texture: Readonly<TextureLike>, premultiply?: boolean): WgpuTextureEntry | null;
8
+ export declare function resolveWgpuTexture(state: WgpuRenderState, texture: Readonly<TextureLike>, premultiply?: boolean, colorSpace?: TextureColorSpace): WgpuTextureEntry | null;
9
9
  //# sourceMappingURL=wgpuTextureResolver.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"wgpuTextureResolver.d.ts","sourceRoot":"","sources":["../src/wgpuTextureResolver.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAKV,iBAAiB,EACjB,WAAW,EACX,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACpB,MAAM,0BAA0B,CAAC;AAYlC,wBAAgB,oCAAoC,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAIjF;AAED,wBAAgB,iCAAiC,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAE9E;AAED,wBAAgB,0CAA0C,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAEvF;AAED,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAE7E;AAED,wBAAgB,iCAAiC,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAE9E;AAID,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,eAAe,EACtB,UAAU,EAAE,iBAAiB,EAC7B,QAAQ,EAAE,mBAAmB,GAAG,IAAI,GACnC,IAAI,CAKN;AAKD,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,eAAe,EACtB,OAAO,EAAE,QAAQ,CAAC,WAAW,CAAC,EAC9B,WAAW,UAAQ,GAClB,gBAAgB,GAAG,IAAI,CAUzB"}
1
+ {"version":3,"file":"wgpuTextureResolver.d.ts","sourceRoot":"","sources":["../src/wgpuTextureResolver.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAKV,iBAAiB,EACjB,iBAAiB,EACjB,WAAW,EACX,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACpB,MAAM,0BAA0B,CAAC;AAYlC,wBAAgB,oCAAoC,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAIjF;AAED,wBAAgB,iCAAiC,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAE9E;AAED,wBAAgB,0CAA0C,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAEvF;AAED,wBAAgB,gCAAgC,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAE7E;AAED,wBAAgB,iCAAiC,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAE9E;AAID,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,eAAe,EACtB,UAAU,EAAE,iBAAiB,EAC7B,QAAQ,EAAE,mBAAmB,GAAG,IAAI,GACnC,IAAI,CAKN;AAKD,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,eAAe,EACtB,OAAO,EAAE,QAAQ,CAAC,WAAW,CAAC,EAC9B,WAAW,UAAQ,EACnB,UAAU,GAAE,iBAAsC,GACjD,gBAAgB,GAAG,IAAI,CAUzB"}
@@ -33,7 +33,7 @@ export function registerWgpuTextureResolver(state, sourceKind, resolver) {
33
33
  // Resolves through one keyed lookup using the source's declared kind. Resolution may realize, upload,
34
34
  // and cache the GPU entry, but unlike the GL twin it does not bind command-pass state; the draw caller
35
35
  // binds the returned entry's group explicitly.
36
- export function resolveWgpuTexture(state, texture, premultiply = false) {
36
+ export function resolveWgpuTexture(state, texture, premultiply = false, colorSpace = texture.colorSpace) {
37
37
  const sourceKind = getTextureSourceKind(texture);
38
38
  if (sourceKind === null)
39
39
  return null;
@@ -43,23 +43,23 @@ export function resolveWgpuTexture(state, texture, premultiply = false) {
43
43
  runtime.registryMiss?.(3, sourceKind);
44
44
  return null;
45
45
  }
46
- return resolver(state, texture, premultiply);
46
+ return resolver(state, texture, premultiply, colorSpace);
47
47
  }
48
- function resolveWgpuBitmapTexture(state, texture, premultiply) {
48
+ function resolveWgpuBitmapTexture(state, texture, premultiply, colorSpace) {
49
49
  const bitmap = getTextureSource(texture);
50
50
  return bitmap === null
51
51
  ? null
52
- : bindWgpuBitmapTexture(state, bitmap, texture.sampler.mipmaps, premultiply, texture.colorSpace);
52
+ : bindWgpuBitmapTexture(state, bitmap, texture.sampler.mipmaps, premultiply, colorSpace);
53
53
  }
54
- function resolveWgpuCompressedImageTexture(state, texture) {
54
+ function resolveWgpuCompressedImageTexture(state, texture, _premultiply, colorSpace) {
55
55
  const image = getTextureSource(texture);
56
- return image === null ? null : bindWgpuCompressedImageTexture(state, image, texture.colorSpace);
56
+ return image === null ? null : bindWgpuCompressedImageTexture(state, image, colorSpace);
57
57
  }
58
- function resolveWgpuImageTexture(state, texture, premultiply) {
58
+ function resolveWgpuImageTexture(state, texture, premultiply, colorSpace) {
59
59
  const image = getTextureSource(texture);
60
60
  return image === null
61
61
  ? null
62
- : bindWgpuImageResourceTexture(state, image, texture.sampler.mipmaps, premultiply, texture.colorSpace);
62
+ : bindWgpuImageResourceTexture(state, image, texture.sampler.mipmaps, premultiply, colorSpace);
63
63
  }
64
64
  function resolveWgpuRenderTexture(state, texture) {
65
65
  return bindWgpuRenderTexture(state, texture);
@@ -1 +1 @@
1
- {"version":3,"file":"wgpuTextureResolver.js","sourceRoot":"","sources":["../src/wgpuTextureResolver.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"wgpuTextureResolver.js","sourceRoot":"","sources":["../src/wgpuTextureResolver.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flighthq/render-wgpu",
3
- "version": "0.3.0-next.1445.14ca01c",
3
+ "version": "0.3.0-next.1454.b17f8a5",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/flighthq/flight.git",
@@ -36,16 +36,16 @@
36
36
  "clean:dist": "tsx ../../scripts/clean-package-dist.ts"
37
37
  },
38
38
  "dependencies": {
39
- "@flighthq/color": "0.3.0-next.1445.14ca01c",
40
- "@flighthq/entity": "0.3.0-next.1445.14ca01c",
41
- "@flighthq/scene2d": "0.3.0-next.1445.14ca01c",
42
- "@flighthq/geometry": "0.3.0-next.1445.14ca01c",
43
- "@flighthq/log": "0.3.0-next.1445.14ca01c",
44
- "@flighthq/render": "0.3.0-next.1445.14ca01c",
45
- "@flighthq/signals": "0.3.0-next.1445.14ca01c",
46
- "@flighthq/bitmap": "0.3.0-next.1445.14ca01c",
47
- "@flighthq/texture": "0.3.0-next.1445.14ca01c",
48
- "@flighthq/types": "0.3.0-next.1445.14ca01c"
39
+ "@flighthq/color": "0.3.0-next.1454.b17f8a5",
40
+ "@flighthq/entity": "0.3.0-next.1454.b17f8a5",
41
+ "@flighthq/scene2d": "0.3.0-next.1454.b17f8a5",
42
+ "@flighthq/geometry": "0.3.0-next.1454.b17f8a5",
43
+ "@flighthq/log": "0.3.0-next.1454.b17f8a5",
44
+ "@flighthq/render": "0.3.0-next.1454.b17f8a5",
45
+ "@flighthq/signals": "0.3.0-next.1454.b17f8a5",
46
+ "@flighthq/bitmap": "0.3.0-next.1454.b17f8a5",
47
+ "@flighthq/texture": "0.3.0-next.1454.b17f8a5",
48
+ "@flighthq/types": "0.3.0-next.1454.b17f8a5"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@webgpu/types": "*",
@@ -1,3 +1,4 @@
1
+ import type { WgpuRenderState } from '@flighthq/types/contract';
1
2
  import { beforeAll, describe, expect, it } from 'vitest';
2
3
 
3
4
  import { getWgpuRenderStateRuntime } from './wgpuRenderState';
@@ -27,8 +28,57 @@ describe('createBitmapFromWgpuRenderState', () => {
27
28
  const state = await createWgpuRenderStateForTest();
28
29
  await expect(createBitmapFromWgpuRenderState(state)).rejects.toThrow(/enableWgpuFrameCapture/);
29
30
  });
31
+
32
+ it('reads the mapped buffer within the bound', async () => {
33
+ const state = await createWgpuRenderStateForTest();
34
+ installCaptureBuffer(state, () => Promise.resolve());
35
+
36
+ const bitmap = await createBitmapFromWgpuRenderState(state, 1_000);
37
+
38
+ expect(bitmap.width).toBe(1);
39
+ expect(bitmap.height).toBe(1);
40
+ });
41
+
42
+ it('fails by name when the buffer never maps, instead of awaiting forever', async () => {
43
+ // The driver failure this bounds: mapAsync neither resolves nor rejects. Before the bound, the
44
+ // caller sat here until something outside it gave up and reported a stall with no location.
45
+ const state = await createWgpuRenderStateForTest();
46
+ installCaptureBuffer(state, () => new Promise<void>(() => {}));
47
+
48
+ await expect(createBitmapFromWgpuRenderState(state, 25)).rejects.toThrow(/did not map within 25ms/);
49
+ });
50
+
51
+ it('leaves the wait unbounded when the caller passes 0', async () => {
52
+ const state = await createWgpuRenderStateForTest();
53
+ let settle = (): void => {};
54
+ installCaptureBuffer(state, () => new Promise<void>((resolve) => (settle = resolve)));
55
+
56
+ let done = false;
57
+ const pending = createBitmapFromWgpuRenderState(state, 0).then(() => (done = true));
58
+ await new Promise((resolve) => setTimeout(resolve, 40));
59
+ expect(done).toBe(false);
60
+
61
+ settle();
62
+ await pending;
63
+ expect(done).toBe(true);
64
+ });
30
65
  });
31
66
 
67
+ // Installs a 1×1 retained capture buffer whose map step the caller controls, so the map bound can be
68
+ // exercised without a GPU. The mock device's buffers carry no map surface of their own.
69
+ function installCaptureBuffer(state: WgpuRenderState, mapAsync: () => Promise<void>): void {
70
+ const runtime = getWgpuRenderStateRuntime(state);
71
+ runtime.frameCaptureBuffer = {
72
+ mapAsync,
73
+ getMappedRange: () => new ArrayBuffer(256),
74
+ unmap: () => {},
75
+ destroy: () => {},
76
+ } as unknown as GPUBuffer;
77
+ runtime.frameCaptureWidth = 1;
78
+ runtime.frameCaptureHeight = 1;
79
+ runtime.frameCaptureBytesPerRow = 256;
80
+ }
81
+
32
82
  describe('enableWgpuFrameCapture', () => {
33
83
  it('sets the capture flag on the render state runtime', async () => {
34
84
  const state = await createWgpuRenderStateForTest();
@@ -46,4 +96,46 @@ describe('encodeWgpuFrameCapture', () => {
46
96
  encodeWgpuFrameCapture(state, encoder);
47
97
  expect(copied).toBe(false);
48
98
  });
99
+
100
+ it('skips the copy while a readback holds the buffer, and resumes once it lets go', async () => {
101
+ // The writer/reader handshake over the single retained buffer: an animating scene must not keep
102
+ // enqueueing copies into a buffer a readback has mapped or is waiting to map.
103
+ const state = await createWgpuRenderStateForTest();
104
+ enableWgpuFrameCapture(state);
105
+ acquireWgpuFrameCaptureTexture(state);
106
+ const runtime = getWgpuRenderStateRuntime(state);
107
+ let mapState: GPUBufferMapState = 'unmapped';
108
+ installCaptureBuffer(state, () => Promise.resolve());
109
+ Object.defineProperty(runtime.frameCaptureBuffer, 'mapState', { get: () => mapState });
110
+
111
+ let copies = 0;
112
+ const encoder = { copyTextureToBuffer: () => copies++ } as unknown as GPUCommandEncoder;
113
+
114
+ mapState = 'pending';
115
+ encodeWgpuFrameCapture(state, encoder);
116
+ mapState = 'mapped';
117
+ encodeWgpuFrameCapture(state, encoder);
118
+ expect(copies).toBe(0);
119
+
120
+ mapState = 'unmapped';
121
+ encodeWgpuFrameCapture(state, encoder);
122
+ expect(copies).toBe(1);
123
+ });
124
+
125
+ it('still copies when the implementation reports no map state at all', async () => {
126
+ // Fails safe in the direction that keeps capturing: an undefined mapState must not read as "busy"
127
+ // and silence every copy for the rest of the run.
128
+ const state = await createWgpuRenderStateForTest();
129
+ enableWgpuFrameCapture(state);
130
+ acquireWgpuFrameCaptureTexture(state);
131
+ installCaptureBuffer(state, () => Promise.resolve());
132
+ Object.defineProperty(getWgpuRenderStateRuntime(state).frameCaptureBuffer, 'mapState', {
133
+ get: () => undefined,
134
+ });
135
+
136
+ let copies = 0;
137
+ encodeWgpuFrameCapture(state, { copyTextureToBuffer: () => copies++ } as unknown as GPUCommandEncoder);
138
+
139
+ expect(copies).toBe(1);
140
+ });
49
141
  });
@@ -122,7 +122,7 @@ describe('registerWgpuImageTextureResolver', () => {
122
122
  expect(resolveWgpuTexture(state, texture)).toBe(first);
123
123
  });
124
124
 
125
- it('realizes linear and sRGB interpretations as distinct GPU textures', async () => {
125
+ it('realizes an override independently and defaults to the texture color space', async () => {
126
126
  const state = await createWgpuRenderStateForTest();
127
127
  const createTexture = vi.spyOn(state.device, 'createTexture');
128
128
  const texture = textureWithImage(imageResource());
@@ -130,10 +130,10 @@ describe('registerWgpuImageTextureResolver', () => {
130
130
 
131
131
  const srgb = resolveWgpuTexture(state, texture);
132
132
  expect(createTexture).toHaveBeenLastCalledWith(expect.objectContaining({ format: 'rgba8unorm-srgb' }));
133
- texture.colorSpace = 'linear';
134
- const linear = resolveWgpuTexture(state, texture);
133
+ const linear = resolveWgpuTexture(state, texture, false, 'linear');
135
134
  expect(linear).not.toBe(srgb);
136
135
  expect(createTexture).toHaveBeenLastCalledWith(expect.objectContaining({ format: 'rgba8unorm' }));
136
+ expect(resolveWgpuTexture(state, texture)).toBe(srgb);
137
137
  });
138
138
 
139
139
  it('resolves a host video through the image source kind', async () => {