@flighthq/render-wgpu 0.5.1-next.1069.554a2ac → 0.5.1-next.1201.9b49dee
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/README.md +2 -2
- package/dist/contract.d.ts +9 -6
- package/dist/contract.d.ts.map +1 -1
- package/dist/contract.js +9 -6
- package/dist/contract.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/wgpuDraw.js +1 -1
- package/dist/wgpuDraw.js.map +1 -1
- package/dist/wgpuFrame.d.ts +23 -0
- package/dist/wgpuFrame.d.ts.map +1 -0
- package/dist/{wgpuBackground.js → wgpuFrame.js} +67 -121
- package/dist/wgpuFrame.js.map +1 -0
- package/dist/wgpuFullscreenPass.d.ts +2 -2
- package/dist/wgpuFullscreenPass.d.ts.map +1 -1
- package/dist/wgpuFullscreenPass.js +1 -2
- package/dist/wgpuFullscreenPass.js.map +1 -1
- package/dist/wgpuHost.d.ts +6 -6
- package/dist/wgpuHost.d.ts.map +1 -1
- package/dist/wgpuHost.js +17 -3
- package/dist/wgpuHost.js.map +1 -1
- package/dist/wgpuRenderPass.d.ts +9 -0
- package/dist/wgpuRenderPass.d.ts.map +1 -0
- package/dist/wgpuRenderPass.js +222 -0
- package/dist/wgpuRenderPass.js.map +1 -0
- package/dist/wgpuRenderState.d.ts +3 -4
- package/dist/wgpuRenderState.d.ts.map +1 -1
- package/dist/wgpuRenderState.js +17 -88
- package/dist/wgpuRenderState.js.map +1 -1
- package/dist/wgpuRenderTarget.d.ts +12 -29
- package/dist/wgpuRenderTarget.d.ts.map +1 -1
- package/dist/wgpuRenderTarget.js +19 -252
- package/dist/wgpuRenderTarget.js.map +1 -1
- package/dist/wgpuRenderTargetPool.d.ts +5 -5
- package/dist/wgpuRenderTargetPool.d.ts.map +1 -1
- package/dist/wgpuRenderTargetPool.js +7 -7
- package/dist/wgpuRenderTargetPool.js.map +1 -1
- package/dist/wgpuRenderTexture.d.ts +5 -4
- package/dist/wgpuRenderTexture.d.ts.map +1 -1
- package/dist/wgpuRenderTexture.js +14 -16
- package/dist/wgpuRenderTexture.js.map +1 -1
- package/dist/wgpuRenderTexturePool.js +1 -3
- package/dist/wgpuRenderTexturePool.js.map +1 -1
- package/dist/wgpuScissor.d.ts +1 -1
- package/dist/wgpuScissor.d.ts.map +1 -1
- package/dist/wgpuScissor.js +7 -4
- package/dist/wgpuScissor.js.map +1 -1
- package/dist/wgpuScreenAntialias.d.ts +3 -0
- package/dist/wgpuScreenAntialias.d.ts.map +1 -0
- package/dist/wgpuScreenAntialias.js +119 -0
- package/dist/wgpuScreenAntialias.js.map +1 -0
- package/dist/wgpuScreenCapture.d.ts +5 -0
- package/dist/wgpuScreenCapture.d.ts.map +1 -0
- package/dist/{wgpuSurface.js → wgpuScreenCapture.js} +55 -73
- package/dist/wgpuScreenCapture.js.map +1 -0
- package/dist/wgpuScreenRenderTarget.d.ts +9 -0
- package/dist/wgpuScreenRenderTarget.d.ts.map +1 -0
- package/dist/wgpuScreenRenderTarget.js +123 -0
- package/dist/wgpuScreenRenderTarget.js.map +1 -0
- package/dist/wgpuShader.js +2 -2
- package/dist/wgpuShader.js.map +1 -1
- package/dist/wgpuTestHelper.d.ts +8 -2
- package/dist/wgpuTestHelper.d.ts.map +1 -1
- package/dist/wgpuTestHelper.js +38 -3
- package/dist/wgpuTestHelper.js.map +1 -1
- package/dist/wgpuTextureRenderTarget.d.ts +18 -0
- package/dist/wgpuTextureRenderTarget.d.ts.map +1 -0
- package/dist/wgpuTextureRenderTarget.js +122 -0
- package/dist/wgpuTextureRenderTarget.js.map +1 -0
- package/package.json +11 -11
- package/src/wgpuDraw.test.ts +8 -8
- package/src/{wgpuBackground.test.ts → wgpuFrame.test.ts} +34 -20
- package/src/wgpuFullscreenPass.test.ts +7 -7
- package/src/wgpuHost.test.ts +28 -82
- package/src/wgpuRenderPass.test.ts +258 -0
- package/src/wgpuRenderState.test.ts +34 -313
- package/src/wgpuRenderTarget.test.ts +44 -219
- package/src/wgpuRenderTargetPool.test.ts +21 -21
- package/src/wgpuRenderTexture.test.ts +17 -15
- package/src/wgpuScissor.test.ts +43 -13
- package/src/wgpuScreenAntialias.test.ts +60 -0
- package/src/wgpuScreenCapture.test.ts +156 -0
- package/src/wgpuScreenRenderTarget.test.ts +152 -0
- package/src/wgpuShader.test.ts +5 -6
- package/src/wgpuTextureRenderTarget.test.ts +129 -0
- package/src/wgpuTextureResolver.test.ts +5 -5
- package/dist/wgpuAntialias.d.ts +0 -14
- package/dist/wgpuAntialias.d.ts.map +0 -1
- package/dist/wgpuAntialias.js +0 -155
- package/dist/wgpuAntialias.js.map +0 -1
- package/dist/wgpuBackground.d.ts +0 -20
- package/dist/wgpuBackground.d.ts.map +0 -1
- package/dist/wgpuBackground.js.map +0 -1
- package/dist/wgpuElement.d.ts +0 -7
- package/dist/wgpuElement.d.ts.map +0 -1
- package/dist/wgpuElement.js +0 -20
- package/dist/wgpuElement.js.map +0 -1
- package/dist/wgpuSurface.d.ts +0 -6
- package/dist/wgpuSurface.d.ts.map +0 -1
- package/dist/wgpuSurface.js.map +0 -1
- package/src/wgpuAntialias.test.ts +0 -239
- package/src/wgpuElement.test.ts +0 -145
- package/src/wgpuSurface.test.ts +0 -141
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { resolveRenderTargetDescriptor } from '@flighthq/render/contract';
|
|
2
|
+
import { beginWgpuRenderPass, endWgpuRenderPass } from './wgpuRenderPass';
|
|
2
3
|
import { getWgpuRenderStateRuntime } from './wgpuRenderState';
|
|
3
|
-
import {
|
|
4
|
+
import { createWgpuTextureRenderTarget, destroyWgpuTextureRenderTarget, resizeWgpuTextureRenderTarget, } from './wgpuTextureRenderTarget';
|
|
4
5
|
// Returns a populated render texture's state-owned allocation without copying pixels through the
|
|
5
6
|
// CPU. An unrendered or currently-written Texture returns null.
|
|
6
7
|
export function bindWgpuRenderTexture(state, renderTexture) {
|
|
@@ -15,7 +16,7 @@ export function destroyWgpuRenderTexture(state, renderTexture) {
|
|
|
15
16
|
const entry = runtime.context.wgpuRenderTextureCache?.get(renderTexture);
|
|
16
17
|
if (entry === undefined)
|
|
17
18
|
return;
|
|
18
|
-
|
|
19
|
+
destroyWgpuTextureRenderTarget(entry.target);
|
|
19
20
|
runtime.context.wgpuRenderTextureCache.delete(renderTexture);
|
|
20
21
|
}
|
|
21
22
|
export function explainWgpuRenderTexture(state, renderTexture) {
|
|
@@ -47,17 +48,18 @@ export function isWgpuRenderTextureReady(state, renderTexture) {
|
|
|
47
48
|
return ready;
|
|
48
49
|
}
|
|
49
50
|
/**
|
|
50
|
-
* Clears and populates a render texture's hidden WebGPU target. The
|
|
51
|
-
*
|
|
51
|
+
* Clears and populates a render texture's hidden WebGPU target. The callback receives the pass bound to
|
|
52
|
+
* that target — the same handle every other draw entry point takes — and the enclosing pass is restored
|
|
53
|
+
* even when the callback throws. `clear` is what the target starts from.
|
|
52
54
|
*/
|
|
53
|
-
export function renderIntoWgpuRenderTexture(state, renderTexture, callback) {
|
|
55
|
+
export function renderIntoWgpuRenderTexture(state, renderTexture, callback, clear) {
|
|
54
56
|
writeWgpuRenderTextureTarget(state, renderTexture, (target) => {
|
|
55
|
-
beginWgpuRenderPass(state, target);
|
|
57
|
+
const pass = beginWgpuRenderPass(state, target, clear);
|
|
56
58
|
try {
|
|
57
|
-
callback(
|
|
59
|
+
callback(pass);
|
|
58
60
|
}
|
|
59
61
|
finally {
|
|
60
|
-
endWgpuRenderPass(
|
|
62
|
+
endWgpuRenderPass(pass);
|
|
61
63
|
}
|
|
62
64
|
});
|
|
63
65
|
}
|
|
@@ -93,24 +95,20 @@ function ensureWgpuRenderTextureEntry(state, renderTexture) {
|
|
|
93
95
|
const entries = (runtime.context.wgpuRenderTextureCache ??= new WeakMap());
|
|
94
96
|
let entry = entries.get(renderTexture);
|
|
95
97
|
if (entry === undefined) {
|
|
96
|
-
const target =
|
|
97
|
-
target.clearColors = [...requested.clearColors];
|
|
98
|
-
target.clearDepth = requested.clearDepth;
|
|
98
|
+
const target = createWgpuTextureRenderTarget(state, requested.width, requested.height, format, colorSpace, requested.sampleCount);
|
|
99
99
|
entry = { status: 'unrendered', target };
|
|
100
100
|
entries.set(renderTexture, entry);
|
|
101
101
|
}
|
|
102
102
|
else {
|
|
103
103
|
if (entry.target.format !== format) {
|
|
104
|
-
|
|
105
|
-
entry.target =
|
|
104
|
+
destroyWgpuTextureRenderTarget(entry.target);
|
|
105
|
+
entry.target = createWgpuTextureRenderTarget(state, requested.width, requested.height, format, colorSpace, requested.sampleCount);
|
|
106
106
|
entry.status = 'unrendered';
|
|
107
107
|
}
|
|
108
108
|
else {
|
|
109
|
-
|
|
109
|
+
resizeWgpuTextureRenderTarget(state, entry.target, requested.width, requested.height, requested.sampleCount);
|
|
110
110
|
entry.target.colorSpace = colorSpace;
|
|
111
111
|
}
|
|
112
|
-
entry.target.clearColors = [...requested.clearColors];
|
|
113
|
-
entry.target.clearDepth = requested.clearDepth;
|
|
114
112
|
}
|
|
115
113
|
return entry;
|
|
116
114
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wgpuRenderTexture.js","sourceRoot":"","sources":["../src/wgpuRenderTexture.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"wgpuRenderTexture.js","sourceRoot":"","sources":["../src/wgpuRenderTexture.ts"],"names":[],"mappings":"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"}
|
|
@@ -28,7 +28,7 @@ export function destroyWgpuRenderTexturePool(state, pool) {
|
|
|
28
28
|
destroyWgpuRenderTexture(state, renderTexture);
|
|
29
29
|
pool.free.length = 0;
|
|
30
30
|
pool.leased.clear();
|
|
31
|
-
destroyWgpuRenderTargetPool(
|
|
31
|
+
destroyWgpuRenderTargetPool(pool.effectTargets);
|
|
32
32
|
pool.destroyed = true;
|
|
33
33
|
}
|
|
34
34
|
export function initializeWgpuRenderTexturePool(out) {
|
|
@@ -70,8 +70,6 @@ function applyRenderTargetDescriptor(target, descriptor) {
|
|
|
70
70
|
target.sampleCount = descriptor.sampleCount;
|
|
71
71
|
target.depth = descriptor.depth;
|
|
72
72
|
target.colorSpace = descriptor.colorSpace ?? 'srgb';
|
|
73
|
-
target.clearColors = descriptor.clearColors === undefined ? undefined : [...descriptor.clearColors];
|
|
74
|
-
target.clearDepth = descriptor.clearDepth;
|
|
75
73
|
target.version = (target.version + 1) >>> 0;
|
|
76
74
|
}
|
|
77
75
|
function assertUsablePool(state, pool) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wgpuRenderTexturePool.js","sourceRoot":"","sources":["../src/wgpuRenderTexturePool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzE,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAU1F,OAAO,EAAE,0BAA0B,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AACjG,OAAO,EAAE,wBAAwB,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAE5F,MAAM,UAAU,wBAAwB,CACtC,KAAsB,EACtB,IAA2B,EAC3B,UAA4C;IAE5C,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC9B,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,mBAAmB,CAAC,UAAU,CAAC,CAAC;IACzE,2BAA2B,CAAC,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC9D,uBAAuB,CAAC,aAAa,CAAC,CAAC;IACvC,aAAa,CAAC,UAAU,GAAG,UAAU,CAAC,UAAU,IAAI,MAAM,CAAC;IAC3D,2BAA2B,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;IAClD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAC/B,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,2BAA2B;IACzC,MAAM,GAAG,GAAG,cAAc,EAAyB,CAAC;IACpD,+BAA+B,CAAC,GAAG,CAAC,CAAC;IACrC,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC;AAC3B,CAAC;AAED,iGAAiG;AACjG,0EAA0E;AAC1E,MAAM,UAAU,4BAA4B,CAAC,KAAsB,EAAE,IAA2B;IAC9F,IAAI,IAAI,CAAC,SAAS;QAAE,OAAO;IAC3B,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC9B,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IACzD,KAAK,MAAM,aAAa,IAAI,QAAQ;QAAE,wBAAwB,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;IACrF,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;IACrB,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IACpB,2BAA2B,CAAC,
|
|
1
|
+
{"version":3,"file":"wgpuRenderTexturePool.js","sourceRoot":"","sources":["../src/wgpuRenderTexturePool.ts"],"names":[],"mappings":"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"}
|
package/dist/wgpuScissor.d.ts
CHANGED
|
@@ -2,5 +2,5 @@ import type { WgpuRenderState, WgpuScissorRect } from '@flighthq/types/contract'
|
|
|
2
2
|
export declare function applyWgpuScissorRect(state: WgpuRenderState, pass: GPURenderPassEncoder): void;
|
|
3
3
|
export declare function popWgpuScissorRect(state: WgpuRenderState): void;
|
|
4
4
|
export declare function pushWgpuScissorRect(state: WgpuRenderState, rect: Readonly<WgpuScissorRect>): void;
|
|
5
|
-
export declare function setWgpuRenderPassScissorRect(state:
|
|
5
|
+
export declare function setWgpuRenderPassScissorRect(state: WgpuRenderState, pass: GPURenderPassEncoder, x: number, y: number, width: number, height: number): void;
|
|
6
6
|
//# sourceMappingURL=wgpuScissor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wgpuScissor.d.ts","sourceRoot":"","sources":["../src/wgpuScissor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAQjF,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,oBAAoB,GAAG,IAAI,CAW7F;AAKD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAI/D;AAMD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,QAAQ,CAAC,eAAe,CAAC,GAAG,IAAI,CAMjG;
|
|
1
|
+
{"version":3,"file":"wgpuScissor.d.ts","sourceRoot":"","sources":["../src/wgpuScissor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAQjF,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,oBAAoB,GAAG,IAAI,CAW7F;AAKD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAI/D;AAMD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,QAAQ,CAAC,eAAe,CAAC,GAAG,IAAI,CAMjG;AAMD,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,eAAe,EACtB,IAAI,EAAE,oBAAoB,EAC1B,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,IAAI,CAIN"}
|
package/dist/wgpuScissor.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { getWgpuSurfaceRenderScale } from './wgpuAntialias';
|
|
2
1
|
import { getWgpuRenderStateRuntime } from './wgpuRenderState';
|
|
2
|
+
import { getWgpuRenderTargetSupersampleScale } from './wgpuRenderTarget';
|
|
3
3
|
// Applies the current scissor rectangle to the active render pass. No-op when there is no active
|
|
4
4
|
// scissor or no open render pass. Call after each draw call or once per pass when the active
|
|
5
5
|
// scissor changes.
|
|
@@ -35,10 +35,13 @@ export function pushWgpuScissorRect(state, rect) {
|
|
|
35
35
|
}
|
|
36
36
|
runtime.currentScissorRect = { x: rect.x, y: rect.y, width: rect.width, height: rect.height };
|
|
37
37
|
}
|
|
38
|
-
// Converts a logical
|
|
39
|
-
//
|
|
38
|
+
// Converts a logical scissor rect to the target's physical extent. Logical is the space every 2D
|
|
39
|
+
// coordinate is in — the pass viewport, the projection, and these rects — so a supersampled target
|
|
40
|
+
// (a screen with antialias, or an effect target at sampleCount 4) scales them by the same factor its
|
|
41
|
+
// storage was grown by, and a target with no supersample scales by 1.
|
|
40
42
|
export function setWgpuRenderPassScissorRect(state, pass, x, y, width, height) {
|
|
41
|
-
const
|
|
43
|
+
const target = getWgpuRenderStateRuntime(state).currentRenderTarget;
|
|
44
|
+
const scale = target === null ? 1 : getWgpuRenderTargetSupersampleScale(target);
|
|
42
45
|
pass.setScissorRect(x * scale, y * scale, width * scale, height * scale);
|
|
43
46
|
}
|
|
44
47
|
//# sourceMappingURL=wgpuScissor.js.map
|
package/dist/wgpuScissor.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wgpuScissor.js","sourceRoot":"","sources":["../src/wgpuScissor.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,yBAAyB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"wgpuScissor.js","sourceRoot":"","sources":["../src/wgpuScissor.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAAE,mCAAmC,EAAE,MAAM,oBAAoB,CAAC;AAEzE,iGAAiG;AACjG,6FAA6F;AAC7F,mBAAmB;AACnB,MAAM,UAAU,oBAAoB,CAAC,KAAsB,EAAE,IAA0B;IACrF,MAAM,OAAO,GAAG,yBAAyB,CAAC,KAAK,CAAC,CAAC;IACjD,MAAM,IAAI,GAAG,OAAO,CAAC,kBAAkB,CAAC;IACxC,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO;IAC1B,kGAAkG;IAClG,yEAAyE;IACzE,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1C,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1C,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAC7C,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAC9C,4BAA4B,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AACxD,CAAC;AAED,6FAA6F;AAC7F,iGAAiG;AACjG,wDAAwD;AACxD,MAAM,UAAU,kBAAkB,CAAC,KAAsB;IACvD,MAAM,OAAO,GAAG,yBAAyB,CAAC,KAAK,CAAC,CAAC;IACjD,MAAM,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC;IACxC,OAAO,CAAC,kBAAkB,GAAG,IAAI,IAAI,IAAI,CAAC;AAC5C,CAAC;AAED,2FAA2F;AAC3F,kGAAkG;AAClG,gGAAgG;AAChG,qEAAqE;AACrE,MAAM,UAAU,mBAAmB,CAAC,KAAsB,EAAE,IAA+B;IACzF,MAAM,OAAO,GAAG,yBAAyB,CAAC,KAAK,CAAC,CAAC;IACjD,IAAI,OAAO,CAAC,kBAAkB,KAAK,IAAI,EAAE,CAAC;QACxC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,CAAC,kBAAkB,GAAG,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;AAChG,CAAC;AAED,iGAAiG;AACjG,mGAAmG;AACnG,qGAAqG;AACrG,sEAAsE;AACtE,MAAM,UAAU,4BAA4B,CAC1C,KAAsB,EACtB,IAA0B,EAC1B,CAAS,EACT,CAAS,EACT,KAAa,EACb,MAAc;IAEd,MAAM,MAAM,GAAG,yBAAyB,CAAC,KAAK,CAAC,CAAC,mBAAmB,CAAC;IACpE,MAAM,KAAK,GAAG,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,mCAAmC,CAAC,MAAM,CAAC,CAAC;IAChF,IAAI,CAAC,cAAc,CAAC,CAAC,GAAG,KAAK,EAAE,CAAC,GAAG,KAAK,EAAE,KAAK,GAAG,KAAK,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC;AAC3E,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wgpuScreenAntialias.d.ts","sourceRoot":"","sources":["../src/wgpuScreenAntialias.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmB,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAaxF,wBAAgB,qCAAqC,CAAC,MAAM,EAAE,sBAAsB,GAAG,IAAI,CAO1F"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { getWgpuRenderStateDeviceResources, getWgpuRenderStateRuntime } from './wgpuRenderState';
|
|
2
|
+
import { syncWgpuScreenRenderTargetExtent } from './wgpuScreenRenderTarget';
|
|
3
|
+
// Turns on 2x-per-axis supersampling for a screen target: the frame draws into a 2x texture and one
|
|
4
|
+
// fullscreen linear-sampling pass resolves it into the swap chain immediately before submit. Each
|
|
5
|
+
// destination pixel center averages the corresponding 2x2 source texels, so this is a real resolve and
|
|
6
|
+
// not a post-hoc image filter, and every scene pipeline stays single-sampled — the seam is the surface,
|
|
7
|
+
// not the pipeline.
|
|
8
|
+
//
|
|
9
|
+
// Separately importable on purpose: a frame loop that never calls this pulls in neither the resolve
|
|
10
|
+
// pipeline nor its shader, which is most of what a screen target would otherwise cost.
|
|
11
|
+
export function enableWgpuScreenRenderTargetAntialias(target) {
|
|
12
|
+
target.antialias = true;
|
|
13
|
+
target.acquireAntialiasView = acquireWgpuScreenRenderTargetAntialiasView;
|
|
14
|
+
target.encodeAntialiasResolve = encodeWgpuScreenRenderTargetResolve;
|
|
15
|
+
// The extent is physical storage, and the factor it is measured in just changed: re-sync now rather
|
|
16
|
+
// than leaving width/height a frame behind the flag that scales them.
|
|
17
|
+
syncWgpuScreenRenderTargetExtent(target);
|
|
18
|
+
}
|
|
19
|
+
function acquireWgpuScreenRenderTargetAntialiasView(state, target) {
|
|
20
|
+
const width = target.width;
|
|
21
|
+
const height = target.height;
|
|
22
|
+
const maxDimension = target.device.limits.maxTextureDimension2D;
|
|
23
|
+
if (width > maxDimension || height > maxDimension) {
|
|
24
|
+
throw new Error(`enableWgpuScreenRenderTargetAntialias requires a ${width}x${height} supersample surface, exceeding maxTextureDimension2D ${maxDimension}.`);
|
|
25
|
+
}
|
|
26
|
+
const existing = target.antialiasTexture;
|
|
27
|
+
if (existing !== null && existing.width === width && existing.height === height)
|
|
28
|
+
return target.antialiasView;
|
|
29
|
+
existing?.destroy();
|
|
30
|
+
const texture = target.device.createTexture({
|
|
31
|
+
size: [width, height, 1],
|
|
32
|
+
format: target.format,
|
|
33
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING,
|
|
34
|
+
});
|
|
35
|
+
target.antialiasTexture = texture;
|
|
36
|
+
target.antialiasView = texture.createView();
|
|
37
|
+
target.antialiasResolveBindGroup = target.device.createBindGroup({
|
|
38
|
+
layout: ensureWgpuScreenAntialiasPipeline(state, target),
|
|
39
|
+
entries: [
|
|
40
|
+
{ binding: 0, resource: target.antialiasView },
|
|
41
|
+
{ binding: 1, resource: getWgpuRenderStateDeviceResources(state).linearSampler },
|
|
42
|
+
],
|
|
43
|
+
});
|
|
44
|
+
return target.antialiasView;
|
|
45
|
+
}
|
|
46
|
+
function encodeWgpuScreenRenderTargetResolve(state, target, encoder) {
|
|
47
|
+
const presentationView = target.presentationView;
|
|
48
|
+
const bindGroup = target.antialiasResolveBindGroup;
|
|
49
|
+
const pipeline = getWgpuRenderStateRuntime(state).surfaceAntialiasResolvePipeline;
|
|
50
|
+
if (presentationView === null || pipeline === null || bindGroup === null)
|
|
51
|
+
return;
|
|
52
|
+
const pass = encoder.beginRenderPass({
|
|
53
|
+
colorAttachments: [
|
|
54
|
+
{
|
|
55
|
+
view: presentationView,
|
|
56
|
+
loadOp: 'clear',
|
|
57
|
+
storeOp: 'store',
|
|
58
|
+
clearValue: { r: 0, g: 0, b: 0, a: 0 },
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
});
|
|
62
|
+
pass.setPipeline(pipeline);
|
|
63
|
+
pass.setBindGroup(0, bindGroup);
|
|
64
|
+
pass.draw(3);
|
|
65
|
+
pass.end();
|
|
66
|
+
}
|
|
67
|
+
// The resolve pipeline is device-tier: every screen target on one device compiles it once and shares it.
|
|
68
|
+
// Returns the bind-group layout the caller's per-target bind group is built against.
|
|
69
|
+
function ensureWgpuScreenAntialiasPipeline(state, target) {
|
|
70
|
+
const runtime = getWgpuRenderStateRuntime(state);
|
|
71
|
+
const existing = runtime.surfaceAntialiasResolveBindGroupLayout;
|
|
72
|
+
if (existing !== null && runtime.surfaceAntialiasResolvePipeline !== null)
|
|
73
|
+
return existing;
|
|
74
|
+
const bindGroupLayout = target.device.createBindGroupLayout({
|
|
75
|
+
entries: [
|
|
76
|
+
{ binding: 0, visibility: GPUShaderStage.FRAGMENT, texture: { sampleType: 'float' } },
|
|
77
|
+
{ binding: 1, visibility: GPUShaderStage.FRAGMENT, sampler: { type: 'filtering' } },
|
|
78
|
+
],
|
|
79
|
+
});
|
|
80
|
+
const layout = target.device.createPipelineLayout({ bindGroupLayouts: [bindGroupLayout] });
|
|
81
|
+
const module = target.device.createShaderModule({ code: SCREEN_ANTIALIAS_WGSL });
|
|
82
|
+
runtime.surfaceAntialiasResolveBindGroupLayout = bindGroupLayout;
|
|
83
|
+
runtime.surfaceAntialiasResolvePipeline = target.device.createRenderPipeline({
|
|
84
|
+
layout,
|
|
85
|
+
vertex: { module, entryPoint: 'vs_main' },
|
|
86
|
+
fragment: { module, entryPoint: 'fs_main', targets: [{ format: target.format }] },
|
|
87
|
+
primitive: { topology: 'triangle-list' },
|
|
88
|
+
});
|
|
89
|
+
return bindGroupLayout;
|
|
90
|
+
}
|
|
91
|
+
const SCREEN_ANTIALIAS_WGSL = /* wgsl */ `
|
|
92
|
+
struct VertexOutput {
|
|
93
|
+
@builtin(position) position: vec4f,
|
|
94
|
+
@location(0) uv: vec2f,
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
@vertex
|
|
98
|
+
fn vs_main(@builtin(vertex_index) index: u32) -> VertexOutput {
|
|
99
|
+
let positions = array<vec2f, 3>(
|
|
100
|
+
vec2f(-1.0, -1.0),
|
|
101
|
+
vec2f(3.0, -1.0),
|
|
102
|
+
vec2f(-1.0, 3.0),
|
|
103
|
+
);
|
|
104
|
+
let position = positions[index];
|
|
105
|
+
var output: VertexOutput;
|
|
106
|
+
output.position = vec4f(position, 0.0, 1.0);
|
|
107
|
+
output.uv = position * vec2f(0.5, -0.5) + vec2f(0.5);
|
|
108
|
+
return output;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
@group(0) @binding(0) var source_texture: texture_2d<f32>;
|
|
112
|
+
@group(0) @binding(1) var source_sampler: sampler;
|
|
113
|
+
|
|
114
|
+
@fragment
|
|
115
|
+
fn fs_main(input: VertexOutput) -> @location(0) vec4f {
|
|
116
|
+
return textureSample(source_texture, source_sampler, input.uv);
|
|
117
|
+
}
|
|
118
|
+
`;
|
|
119
|
+
//# sourceMappingURL=wgpuScreenAntialias.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wgpuScreenAntialias.js","sourceRoot":"","sources":["../src/wgpuScreenAntialias.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Bitmap, WgpuScreenRenderTarget } from '@flighthq/types/contract';
|
|
2
|
+
export declare function createBitmapFromWgpuScreenRenderTarget(target: Readonly<WgpuScreenRenderTarget>, timeoutMs?: number): Promise<Bitmap>;
|
|
3
|
+
export declare function enableWgpuScreenRenderTargetCapture(target: WgpuScreenRenderTarget): void;
|
|
4
|
+
export declare function encodeWgpuScreenRenderTargetCapture(target: WgpuScreenRenderTarget, encoder: GPUCommandEncoder): void;
|
|
5
|
+
//# sourceMappingURL=wgpuScreenCapture.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wgpuScreenCapture.d.ts","sourceRoot":"","sources":["../src/wgpuScreenCapture.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAa/E,wBAAsB,sCAAsC,CAC1D,MAAM,EAAE,QAAQ,CAAC,sBAAsB,CAAC,EACxC,SAAS,SAAyB,GACjC,OAAO,CAAC,MAAM,CAAC,CAyCjB;AAMD,wBAAgB,mCAAmC,CAAC,MAAM,EAAE,sBAAsB,GAAG,IAAI,CAIxF;AAwBD,wBAAgB,mCAAmC,CAAC,MAAM,EAAE,sBAAsB,EAAE,OAAO,EAAE,iBAAiB,GAAG,IAAI,CAgCpH"}
|
|
@@ -1,56 +1,22 @@
|
|
|
1
1
|
import { createBitmap } from '@flighthq/bitmap/contract';
|
|
2
|
-
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
// the frame is
|
|
6
|
-
//
|
|
7
|
-
// adapters, so submitWgpuRenderPass copies the capture texture into the retained capture buffer in the
|
|
8
|
-
// same frame (encodeWgpuFrameCapture), and createBitmapFromWgpuRenderState only maps that buffer.
|
|
2
|
+
// Opt-in capture of a screen target's frame to a CPU Bitmap. Two environment facts drive the design:
|
|
3
|
+
// (1) headless/software adapters never present the swap chain, and its texture reads back as zeros, so
|
|
4
|
+
// the frame is redirected into an offscreen COPY_SRC texture the screen target owns; (2) GPU work queued
|
|
5
|
+
// in a later task than the frame is dropped on these adapters, so the frame's own submit copies that
|
|
6
|
+
// texture into the retained capture buffer, and the readback below only maps the buffer.
|
|
9
7
|
//
|
|
10
8
|
// One buffer serves both sides, so they take turns: the writer skips its copy while the reader holds a
|
|
11
9
|
// map (or has one in flight), and resumes on the next frame. Without that turn-taking a continuously
|
|
12
10
|
// animating scene re-enqueues a copy every frame into the buffer a readback is waiting on — which the
|
|
13
11
|
// queue may not touch while it is mapped, and which pushes the pending map behind ever more GPU work.
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const runtime = getWgpuRenderStateRuntime(state);
|
|
19
|
-
if (!runtime.frameCaptureEnabled)
|
|
20
|
-
return null;
|
|
21
|
-
const width = Math.max(1, state.surface.width);
|
|
22
|
-
const height = Math.max(1, state.surface.height);
|
|
23
|
-
const existing = runtime.frameCaptureTexture;
|
|
24
|
-
if (existing !== null && existing !== undefined && existing.width === width && existing.height === height) {
|
|
25
|
-
return existing;
|
|
26
|
-
}
|
|
27
|
-
existing?.destroy();
|
|
28
|
-
const texture = state.device.createTexture({
|
|
29
|
-
size: [width, height, 1],
|
|
30
|
-
format: state.format,
|
|
31
|
-
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC,
|
|
32
|
-
});
|
|
33
|
-
runtime.frameCaptureTexture = texture;
|
|
34
|
-
return texture;
|
|
35
|
-
}
|
|
36
|
-
// Reads the most recently captured frame into a CPU Bitmap. Requires enableWgpuFrameCapture(state)
|
|
37
|
-
// before rendering and at least one submitWgpuRenderPass since (which fills the capture buffer);
|
|
38
|
-
// throws otherwise (calling it without enabling capture is API misuse). Only maps the retained buffer —
|
|
39
|
-
// no GPU work is queued here, since later-task GPU work is unreliable on the adapters this exists for.
|
|
40
|
-
// Allocates the returned Bitmap; the capture buffer is retained and reused across frames.
|
|
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) {
|
|
46
|
-
const runtime = getWgpuRenderStateRuntime(state);
|
|
47
|
-
const buffer = runtime.frameCaptureBuffer;
|
|
48
|
-
if (buffer === null || buffer === undefined) {
|
|
49
|
-
throw new Error('createBitmapFromWgpuRenderState requires enableWgpuFrameCapture(state) before rendering, then a submitWgpuRenderPass.');
|
|
12
|
+
export async function createBitmapFromWgpuScreenRenderTarget(target, timeoutMs = DEFAULT_MAP_TIMEOUT_MS) {
|
|
13
|
+
const buffer = target.captureBuffer;
|
|
14
|
+
if (buffer === null) {
|
|
15
|
+
throw new Error('createBitmapFromWgpuScreenRenderTarget requires enableWgpuScreenRenderTargetCapture(target) before rendering, then a submitted frame.');
|
|
50
16
|
}
|
|
51
|
-
const width =
|
|
52
|
-
const height =
|
|
53
|
-
const bytesPerRow =
|
|
17
|
+
const width = target.captureWidth;
|
|
18
|
+
const height = target.captureHeight;
|
|
19
|
+
const bytesPerRow = target.captureBytesPerRow;
|
|
54
20
|
await mapWgpuCaptureBuffer(buffer, timeoutMs);
|
|
55
21
|
const mapped = new Uint8Array(buffer.getMappedRange());
|
|
56
22
|
const bitmap = createBitmap(width, height);
|
|
@@ -62,7 +28,7 @@ export async function createBitmapFromWgpuRenderState(state, timeoutMs = DEFAULT
|
|
|
62
28
|
// by an 8-bit alpha amplifies quantization and clamps, blowing out exactly the semi-transparent pixels
|
|
63
29
|
// a colour comparison cares about. If straight-alpha output is ever needed, convert at the consumer in
|
|
64
30
|
// higher precision, or compare in premultiplied space on both sides.
|
|
65
|
-
const swizzleBGRA =
|
|
31
|
+
const swizzleBGRA = target.format === 'bgra8unorm' || target.format === 'bgra8unorm-srgb';
|
|
66
32
|
for (let y = 0; y < height; y++) {
|
|
67
33
|
const srcRow = y * bytesPerRow;
|
|
68
34
|
const dstRow = y * width * 4;
|
|
@@ -79,20 +45,39 @@ export async function createBitmapFromWgpuRenderState(state, timeoutMs = DEFAULT
|
|
|
79
45
|
buffer.unmap();
|
|
80
46
|
return bitmap;
|
|
81
47
|
}
|
|
82
|
-
// Enables opt-in
|
|
83
|
-
// The frame is then drawn into an offscreen texture instead of the
|
|
84
|
-
//
|
|
85
|
-
//
|
|
86
|
-
export function
|
|
87
|
-
|
|
48
|
+
// Enables opt-in capture on a screen target so createBitmapFromWgpuScreenRenderTarget can read it back.
|
|
49
|
+
// The frame is then drawn into an offscreen texture instead of the swap chain (the only reliably readable
|
|
50
|
+
// path on headless/software adapters); the canvas is not presented while capture is on. Leave it off for
|
|
51
|
+
// normal on-screen rendering. The capture texture and buffer are allocated lazily.
|
|
52
|
+
export function enableWgpuScreenRenderTargetCapture(target) {
|
|
53
|
+
target.captureEnabled = true;
|
|
54
|
+
target.acquireCaptureTexture = acquireWgpuScreenRenderTargetCaptureTexture;
|
|
55
|
+
target.encodeCapture = encodeWgpuScreenRenderTargetCapture;
|
|
56
|
+
}
|
|
57
|
+
// The offscreen texture a captured frame renders into, sized to the surface's logical extent (a
|
|
58
|
+
// supersampled frame resolves down into it). Installed as the target's capture slot by the enable above.
|
|
59
|
+
function acquireWgpuScreenRenderTargetCaptureTexture(target) {
|
|
60
|
+
const scale = target.antialias ? 2 : 1;
|
|
61
|
+
const width = Math.max(1, Math.floor(target.width / scale));
|
|
62
|
+
const height = Math.max(1, Math.floor(target.height / scale));
|
|
63
|
+
const existing = target.captureTexture;
|
|
64
|
+
if (existing !== null && existing.width === width && existing.height === height)
|
|
65
|
+
return existing;
|
|
66
|
+
existing?.destroy();
|
|
67
|
+
const texture = target.device.createTexture({
|
|
68
|
+
size: [width, height, 1],
|
|
69
|
+
format: target.format,
|
|
70
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC,
|
|
71
|
+
});
|
|
72
|
+
target.captureTexture = texture;
|
|
73
|
+
return texture;
|
|
88
74
|
}
|
|
89
|
-
// Encodes the capture-texture → capture-buffer copy into the frame's command encoder, sizing
|
|
90
|
-
// the retained buffer to the
|
|
91
|
-
//
|
|
92
|
-
export function
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
if (!runtime.frameCaptureEnabled || texture === null || texture === undefined)
|
|
75
|
+
// Encodes the capture-texture → capture-buffer copy into the frame's command encoder, sizing and
|
|
76
|
+
// reallocating the retained buffer to the surface on demand. No-op unless capture is enabled. Internal:
|
|
77
|
+
// called by submitWgpuFrame so the copy is queued in the render frame, not a later (dropped) task.
|
|
78
|
+
export function encodeWgpuScreenRenderTargetCapture(target, encoder) {
|
|
79
|
+
const texture = target.captureTexture;
|
|
80
|
+
if (!target.captureEnabled || texture === null)
|
|
96
81
|
return;
|
|
97
82
|
// The reader owns the buffer while it holds a map. One retained buffer serves both sides, and the
|
|
98
83
|
// queue may not touch a buffer that is mapped or has a map in flight — so a frame encoded during a
|
|
@@ -103,27 +88,24 @@ export function encodeWgpuFrameCapture(state, encoder) {
|
|
|
103
88
|
// Deliberately written as "is it busy" rather than "is it not unmapped": an implementation without
|
|
104
89
|
// `mapState` reports undefined, and the inverted test would then skip every copy for the whole run
|
|
105
90
|
// and capture nothing. Unknown state falls through to the copy, which is the pre-existing behaviour.
|
|
106
|
-
const mapState =
|
|
91
|
+
const mapState = target.captureBuffer?.mapState;
|
|
107
92
|
if (mapState === 'pending' || mapState === 'mapped')
|
|
108
93
|
return;
|
|
109
94
|
const width = texture.width;
|
|
110
95
|
const height = texture.height;
|
|
111
96
|
// Wgpu requires copyTextureToBuffer rows to be 256-byte aligned; the buffer is padded per row.
|
|
112
97
|
const bytesPerRow = Math.ceil((width * 4) / 256) * 256;
|
|
113
|
-
if (
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
runtime.frameCaptureHeight !== height) {
|
|
117
|
-
runtime.frameCaptureBuffer?.destroy();
|
|
118
|
-
runtime.frameCaptureBuffer = state.device.createBuffer({
|
|
98
|
+
if (target.captureBuffer === null || target.captureWidth !== width || target.captureHeight !== height) {
|
|
99
|
+
target.captureBuffer?.destroy();
|
|
100
|
+
target.captureBuffer = target.device.createBuffer({
|
|
119
101
|
size: bytesPerRow * height,
|
|
120
102
|
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ,
|
|
121
103
|
});
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
104
|
+
target.captureBytesPerRow = bytesPerRow;
|
|
105
|
+
target.captureWidth = width;
|
|
106
|
+
target.captureHeight = height;
|
|
125
107
|
}
|
|
126
|
-
encoder.copyTextureToBuffer({ texture }, { buffer:
|
|
108
|
+
encoder.copyTextureToBuffer({ texture }, { buffer: target.captureBuffer, bytesPerRow }, [width, height, 1]);
|
|
127
109
|
}
|
|
128
110
|
// Maps the retained capture buffer, giving up by name after `timeoutMs` (0 waits indefinitely).
|
|
129
111
|
// `mapAsync` carries no timeout and no reject path of its own: on the contended software adapters this
|
|
@@ -139,7 +121,7 @@ async function mapWgpuCaptureBuffer(buffer, timeoutMs) {
|
|
|
139
121
|
let timer;
|
|
140
122
|
const expiry = new Promise((_resolve, reject) => {
|
|
141
123
|
timer = setTimeout(() => {
|
|
142
|
-
reject(new Error(`
|
|
124
|
+
reject(new Error(`createBitmapFromWgpuScreenRenderTarget: capture buffer did not map within ${timeoutMs}ms`));
|
|
143
125
|
}, timeoutMs);
|
|
144
126
|
});
|
|
145
127
|
try {
|
|
@@ -152,4 +134,4 @@ async function mapWgpuCaptureBuffer(buffer, timeoutMs) {
|
|
|
152
134
|
// Generous by design: this bounds a driver that has stopped answering, not a slow one. Callers working
|
|
153
135
|
// inside a tighter budget (the capture harness) pass their own.
|
|
154
136
|
const DEFAULT_MAP_TIMEOUT_MS = 10_000;
|
|
155
|
-
//# sourceMappingURL=
|
|
137
|
+
//# sourceMappingURL=wgpuScreenCapture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wgpuScreenCapture.js","sourceRoot":"","sources":["../src/wgpuScreenCapture.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { EntityConstruction, WgpuRenderState, WgpuRenderTarget, WgpuScreenRenderTarget, WgpuScreenRenderTargetOptions, WgpuScreenSurface } from '@flighthq/types/contract';
|
|
2
|
+
export declare function bindWgpuScreenRenderTarget(state: WgpuRenderState, target: WgpuScreenRenderTarget): GPUTextureView;
|
|
3
|
+
export declare function createWgpuScreenRenderTarget(device: GPUDevice, surface: WgpuScreenSurface, options?: Readonly<WgpuScreenRenderTargetOptions>): WgpuScreenRenderTarget;
|
|
4
|
+
export declare function destroyWgpuScreenRenderTarget(target: WgpuScreenRenderTarget): void;
|
|
5
|
+
export declare function endWgpuScreenRenderTargetFrame(target: WgpuScreenRenderTarget): void;
|
|
6
|
+
export declare function initializeWgpuScreenRenderTarget(out: EntityConstruction<WgpuScreenRenderTarget>, device: GPUDevice, surface: WgpuScreenSurface, options?: Readonly<WgpuScreenRenderTargetOptions>): void;
|
|
7
|
+
export declare function isWgpuScreenRenderTarget(target: Readonly<WgpuRenderTarget>): target is WgpuScreenRenderTarget;
|
|
8
|
+
export declare function syncWgpuScreenRenderTargetExtent(target: WgpuScreenRenderTarget): void;
|
|
9
|
+
//# sourceMappingURL=wgpuScreenRenderTarget.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wgpuScreenRenderTarget.d.ts","sourceRoot":"","sources":["../src/wgpuScreenRenderTarget.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,sBAAsB,EACtB,6BAA6B,EAC7B,iBAAiB,EAClB,MAAM,0BAA0B,CAAC;AAQlC,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,eAAe,EAAE,MAAM,EAAE,sBAAsB,GAAG,cAAc,CAYjH;AAID,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,iBAAiB,EAC1B,OAAO,GAAE,QAAQ,CAAC,6BAA6B,CAAM,GACpD,sBAAsB,CAIxB;AAKD,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,sBAAsB,GAAG,IAAI,CAYlF;AAID,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,sBAAsB,GAAG,IAAI,CAEnF;AAED,wBAAgB,gCAAgC,CAC9C,GAAG,EAAE,kBAAkB,CAAC,sBAAsB,CAAC,EAC/C,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE,iBAAiB,EAC1B,OAAO,GAAE,QAAQ,CAAC,6BAA6B,CAAM,GACpD,IAAI,CA0CN;AAKD,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,QAAQ,CAAC,gBAAgB,CAAC,GAAG,MAAM,IAAI,sBAAsB,CAE7G;AAED,wBAAgB,gCAAgC,CAAC,MAAM,EAAE,sBAAsB,GAAG,IAAI,CAIrF"}
|