@aardworx/wombat.rendering 0.19.18 → 0.19.19
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/window/loop.d.ts.map +1 -1
- package/dist/window/loop.js +32 -3
- package/dist/window/loop.js.map +1 -1
- package/package.json +1 -1
- package/src/window/loop.ts +34 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../../src/window/loop.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAQ,aAAa,EAAe,MAAM,2BAA2B,CAAC;AAElF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../../src/window/loop.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAQ,aAAa,EAAe,MAAM,2BAA2B,CAAC;AAElF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAsBpD,MAAM,WAAW,eAAe;IAC9B,iEAAiE;IACjE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;;;;OAQG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IACnC;;;;;;;;;;;;OAYG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACtC;AAED,MAAM,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;AAE5E,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,QAAQ,CACtB,UAAU,EAAE,gBAAgB,EAC5B,KAAK,EAAE,aAAa,EACpB,IAAI,GAAE,eAAoB,GACzB;IAAE,IAAI,IAAI,IAAI,CAAA;CAAE,CA4FlB"}
|
package/dist/window/loop.js
CHANGED
|
@@ -22,6 +22,23 @@
|
|
|
22
22
|
//
|
|
23
23
|
// Returns a `stop()` to cancel the loop and clear the subscription.
|
|
24
24
|
import { AVal, transact } from "@aardworx/wombat.adaptive";
|
|
25
|
+
// ─── Benchmark toggles ─────────────────────────────────────────────────
|
|
26
|
+
//
|
|
27
|
+
// `globalThis.__wombatUncappedRenderLoop = true` (set BEFORE the loop
|
|
28
|
+
// starts) schedules frames via setTimeout(0) instead of
|
|
29
|
+
// requestAnimationFrame — no vsync clamp; with the standard
|
|
30
|
+
// `onSubmittedWorkDone` pacer the loop then runs at true GPU
|
|
31
|
+
// completion rate. The canvas still presents whatever frame is
|
|
32
|
+
// latest. When uncapped, `globalThis.__wombatFrameCount` increments
|
|
33
|
+
// AFTER each frame's pacer resolves (i.e. GPU work done), so a
|
|
34
|
+
// harness can serialize edit → frame-complete → next edit and read
|
|
35
|
+
// honest end-to-end frame costs.
|
|
36
|
+
const UNCAPPED = globalThis
|
|
37
|
+
.__wombatUncappedRenderLoop === true;
|
|
38
|
+
function bumpFrameCount() {
|
|
39
|
+
const g = globalThis;
|
|
40
|
+
g.__wombatFrameCount = (g.__wombatFrameCount ?? 0) + 1;
|
|
41
|
+
}
|
|
25
42
|
export function runFrame(attachment, frame, opts = {}) {
|
|
26
43
|
let stopped = false;
|
|
27
44
|
let frameNo = 0;
|
|
@@ -50,6 +67,9 @@ export function runFrame(attachment, frame, opts = {}) {
|
|
|
50
67
|
const finalizeFrame = () => {
|
|
51
68
|
if (stopped)
|
|
52
69
|
return;
|
|
70
|
+
// pacer (GPU completion) has resolved by now — this frame is DONE
|
|
71
|
+
if (UNCAPPED)
|
|
72
|
+
bumpFrameCount();
|
|
53
73
|
if (opts.onAfterFrame !== undefined) {
|
|
54
74
|
transact(opts.onAfterFrame);
|
|
55
75
|
}
|
|
@@ -58,6 +78,15 @@ export function runFrame(attachment, frame, opts = {}) {
|
|
|
58
78
|
sub.dispose();
|
|
59
79
|
}
|
|
60
80
|
};
|
|
81
|
+
const schedule = (cb) => UNCAPPED
|
|
82
|
+
? setTimeout(cb, 0)
|
|
83
|
+
: requestAnimationFrame(cb);
|
|
84
|
+
const cancel = (h) => {
|
|
85
|
+
if (UNCAPPED)
|
|
86
|
+
clearTimeout(h);
|
|
87
|
+
else
|
|
88
|
+
cancelAnimationFrame(h);
|
|
89
|
+
};
|
|
61
90
|
const tick = () => {
|
|
62
91
|
if (stopped)
|
|
63
92
|
return;
|
|
@@ -87,16 +116,16 @@ export function runFrame(attachment, frame, opts = {}) {
|
|
|
87
116
|
if (pending || stopped)
|
|
88
117
|
return;
|
|
89
118
|
pending = true;
|
|
90
|
-
rafId =
|
|
119
|
+
rafId = schedule(tick);
|
|
91
120
|
});
|
|
92
121
|
// Initial render. Schedules subsequent frames only when adaptive
|
|
93
122
|
// marks reach `renderAval` (via the marking callback above).
|
|
94
123
|
pending = true;
|
|
95
|
-
rafId =
|
|
124
|
+
rafId = schedule(tick);
|
|
96
125
|
return {
|
|
97
126
|
stop() {
|
|
98
127
|
stopped = true;
|
|
99
|
-
|
|
128
|
+
cancel(rafId);
|
|
100
129
|
sub.dispose();
|
|
101
130
|
},
|
|
102
131
|
};
|
package/dist/window/loop.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loop.js","sourceRoot":"","sources":["../../src/window/loop.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,iEAAiE;AACjE,gEAAgE;AAChE,oEAAoE;AACpE,gEAAgE;AAChE,+CAA+C;AAC/C,EAAE;AACF,0DAA0D;AAC1D,iCAAiC;AACjC,+DAA+D;AAC/D,6DAA6D;AAC7D,4DAA4D;AAC5D,iEAAiE;AACjE,iCAAiC;AACjC,6DAA6D;AAC7D,gEAAgE;AAChE,iEAAiE;AACjE,kEAAkE;AAClE,2CAA2C;AAC3C,gEAAgE;AAChE,wDAAwD;AACxD,EAAE;AACF,oEAAoE;AAGpE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"loop.js","sourceRoot":"","sources":["../../src/window/loop.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aardworx/wombat.rendering",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.19",
|
|
4
4
|
"description": "WebGPU rendering layer for the Wombat TypeScript stack — RenderObject/RenderTask/runtime + window glue, port of Aardvark.Rendering's lower layers on top of WebGPU and wombat.shader.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "krauthaufen",
|
package/src/window/loop.ts
CHANGED
|
@@ -26,6 +26,26 @@ import type { aval, AdaptiveToken, IDisposable } from "@aardworx/wombat.adaptive
|
|
|
26
26
|
import { AVal, transact } from "@aardworx/wombat.adaptive";
|
|
27
27
|
import type { CanvasAttachment } from "./canvas.js";
|
|
28
28
|
|
|
29
|
+
// ─── Benchmark toggles ─────────────────────────────────────────────────
|
|
30
|
+
//
|
|
31
|
+
// `globalThis.__wombatUncappedRenderLoop = true` (set BEFORE the loop
|
|
32
|
+
// starts) schedules frames via setTimeout(0) instead of
|
|
33
|
+
// requestAnimationFrame — no vsync clamp; with the standard
|
|
34
|
+
// `onSubmittedWorkDone` pacer the loop then runs at true GPU
|
|
35
|
+
// completion rate. The canvas still presents whatever frame is
|
|
36
|
+
// latest. When uncapped, `globalThis.__wombatFrameCount` increments
|
|
37
|
+
// AFTER each frame's pacer resolves (i.e. GPU work done), so a
|
|
38
|
+
// harness can serialize edit → frame-complete → next edit and read
|
|
39
|
+
// honest end-to-end frame costs.
|
|
40
|
+
const UNCAPPED: boolean =
|
|
41
|
+
(globalThis as Record<string, unknown> & typeof globalThis)
|
|
42
|
+
.__wombatUncappedRenderLoop === true;
|
|
43
|
+
|
|
44
|
+
function bumpFrameCount(): void {
|
|
45
|
+
const g = globalThis as Record<string, unknown> & typeof globalThis;
|
|
46
|
+
g.__wombatFrameCount = ((g.__wombatFrameCount as number | undefined) ?? 0) + 1;
|
|
47
|
+
}
|
|
48
|
+
|
|
29
49
|
export interface RunFrameOptions {
|
|
30
50
|
/** Stop after N frames. Useful for tests + finite animations. */
|
|
31
51
|
readonly maxFrames?: number;
|
|
@@ -95,6 +115,8 @@ export function runFrame(
|
|
|
95
115
|
|
|
96
116
|
const finalizeFrame = (): void => {
|
|
97
117
|
if (stopped) return;
|
|
118
|
+
// pacer (GPU completion) has resolved by now — this frame is DONE
|
|
119
|
+
if (UNCAPPED) bumpFrameCount();
|
|
98
120
|
if (opts.onAfterFrame !== undefined) {
|
|
99
121
|
transact(opts.onAfterFrame);
|
|
100
122
|
}
|
|
@@ -104,6 +126,15 @@ export function runFrame(
|
|
|
104
126
|
}
|
|
105
127
|
};
|
|
106
128
|
|
|
129
|
+
const schedule = (cb: () => void): number =>
|
|
130
|
+
UNCAPPED
|
|
131
|
+
? (setTimeout(cb, 0) as unknown as number)
|
|
132
|
+
: requestAnimationFrame(cb);
|
|
133
|
+
const cancel = (h: number): void => {
|
|
134
|
+
if (UNCAPPED) clearTimeout(h);
|
|
135
|
+
else cancelAnimationFrame(h);
|
|
136
|
+
};
|
|
137
|
+
|
|
107
138
|
const tick = (): void => {
|
|
108
139
|
if (stopped) return;
|
|
109
140
|
pending = false;
|
|
@@ -133,18 +164,18 @@ export function runFrame(
|
|
|
133
164
|
}).addMarkingCallback(() => {
|
|
134
165
|
if (pending || stopped) return;
|
|
135
166
|
pending = true;
|
|
136
|
-
rafId =
|
|
167
|
+
rafId = schedule(tick);
|
|
137
168
|
});
|
|
138
169
|
|
|
139
170
|
// Initial render. Schedules subsequent frames only when adaptive
|
|
140
171
|
// marks reach `renderAval` (via the marking callback above).
|
|
141
172
|
pending = true;
|
|
142
|
-
rafId =
|
|
173
|
+
rafId = schedule(tick);
|
|
143
174
|
|
|
144
175
|
return {
|
|
145
176
|
stop() {
|
|
146
177
|
stopped = true;
|
|
147
|
-
|
|
178
|
+
cancel(rafId);
|
|
148
179
|
sub.dispose();
|
|
149
180
|
},
|
|
150
181
|
};
|