@aardworx/wombat.rendering 0.19.18 → 0.19.20

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 +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;AAEpD,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,CAiFlB"}
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;AAyBpD,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,CA6FlB"}
@@ -22,12 +22,34 @@
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
+ // Read at runFrame() start (NOT module load) — consumers set the flag
37
+ // from app code that runs after this module is imported.
38
+ function isUncapped() {
39
+ return globalThis
40
+ .__wombatUncappedRenderLoop === true;
41
+ }
42
+ function bumpFrameCount() {
43
+ const g = globalThis;
44
+ g.__wombatFrameCount = (g.__wombatFrameCount ?? 0) + 1;
45
+ }
25
46
  export function runFrame(attachment, frame, opts = {}) {
26
47
  let stopped = false;
27
48
  let frameNo = 0;
28
49
  let lastTime = performance.now();
29
50
  let rafId = 0;
30
51
  let pending = false;
52
+ const UNCAPPED = isUncapped();
31
53
  // Wrap the frame callback in an AVal so the adaptive system tracks
32
54
  // its dependency set. Each `force()` re-reads the inputs and runs
33
55
  // the frame; subsequent input marks fire the marking callback.
@@ -50,6 +72,9 @@ export function runFrame(attachment, frame, opts = {}) {
50
72
  const finalizeFrame = () => {
51
73
  if (stopped)
52
74
  return;
75
+ // pacer (GPU completion) has resolved by now — this frame is DONE
76
+ if (UNCAPPED)
77
+ bumpFrameCount();
53
78
  if (opts.onAfterFrame !== undefined) {
54
79
  transact(opts.onAfterFrame);
55
80
  }
@@ -58,6 +83,15 @@ export function runFrame(attachment, frame, opts = {}) {
58
83
  sub.dispose();
59
84
  }
60
85
  };
86
+ const schedule = (cb) => UNCAPPED
87
+ ? setTimeout(cb, 0)
88
+ : requestAnimationFrame(cb);
89
+ const cancel = (h) => {
90
+ if (UNCAPPED)
91
+ clearTimeout(h);
92
+ else
93
+ cancelAnimationFrame(h);
94
+ };
61
95
  const tick = () => {
62
96
  if (stopped)
63
97
  return;
@@ -87,16 +121,16 @@ export function runFrame(attachment, frame, opts = {}) {
87
121
  if (pending || stopped)
88
122
  return;
89
123
  pending = true;
90
- rafId = requestAnimationFrame(tick);
124
+ rafId = schedule(tick);
91
125
  });
92
126
  // Initial render. Schedules subsequent frames only when adaptive
93
127
  // marks reach `renderAval` (via the marking callback above).
94
128
  pending = true;
95
- rafId = requestAnimationFrame(tick);
129
+ rafId = schedule(tick);
96
130
  return {
97
131
  stop() {
98
132
  stopped = true;
99
- cancelAnimationFrame(rafId);
133
+ cancel(rafId);
100
134
  sub.dispose();
101
135
  },
102
136
  };
@@ -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;AAwC3D,MAAM,UAAU,QAAQ,CACtB,UAA4B,EAC5B,KAAoB,EACpB,OAAwB,EAAE;IAE1B,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IACjC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,OAAO,GAAG,KAAK,CAAC;IAEpB,mEAAmE;IACnE,kEAAkE;IAClE,+DAA+D;IAC/D,MAAM,UAAU,GAAiB,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;QACrD,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAG,GAAG,GAAG,QAAQ,CAAC;QAC7B,QAAQ,GAAG,GAAG,CAAC;QACf,UAAU,CAAC,SAAS,EAAE,CAAC;QACvB,IAAI,CAAC;YACH,KAAK,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QACrE,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,GAAG,IAAI,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,mCAAmC,EAAE,CAAC,CAAC,CAAC;YACtD,MAAM,CAAC,CAAC;QACV,CAAC;QACD,OAAO,EAAE,CAAC;QACV,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC,CAAC;IAEH,MAAM,aAAa,GAAG,GAAS,EAAE;QAC/B,IAAI,OAAO;YAAE,OAAO;QACpB,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;YACpC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC9B,CAAC;QACD,IAAI,IAAI,CAAC,SAAS,KAAK,SAAS,IAAI,OAAO,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAC9D,OAAO,GAAG,IAAI,CAAC;YACf,GAAG,CAAC,OAAO,EAAE,CAAC;QAChB,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,IAAI,GAAG,GAAS,EAAE;QACtB,IAAI,OAAO;YAAE,OAAO;QACpB,OAAO,GAAG,KAAK,CAAC;QAChB,6DAA6D;QAC7D,+DAA+D;QAC/D,+DAA+D;QAC/D,sBAAsB;QACtB,UAAU,CAAC,KAAK,EAAC,iBAAiB,CAAC,CAAC;QACpC,2DAA2D;QAC3D,mDAAmD;QACnD,yDAAyD;QACzD,+CAA+C;QAC/C,8DAA8D;QAC9D,SAAS;QACT,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC7B,IAAI,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,EAAE,EAAE;gBACrC,OAAO,GAAG,IAAI,CAAC;gBACf,OAAO,CAAC,KAAK,CAAC,0BAA0B,EAAE,CAAC,CAAC,CAAC;YAC/C,CAAC,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,aAAa,EAAE,CAAC;QAClB,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,GAAG,GAAiB,UAExB,CAAC,kBAAkB,CAAC,GAAG,EAAE;QACzB,IAAI,OAAO,IAAI,OAAO;YAAE,OAAO;QAC/B,OAAO,GAAG,IAAI,CAAC;QACf,KAAK,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,iEAAiE;IACjE,6DAA6D;IAC7D,OAAO,GAAG,IAAI,CAAC;IACf,KAAK,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAC;IAEpC,OAAO;QACL,IAAI;YACF,OAAO,GAAG,IAAI,CAAC;YACf,oBAAoB,CAAC,KAAK,CAAC,CAAC;YAC5B,GAAG,CAAC,OAAO,EAAE,CAAC;QAChB,CAAC;KACF,CAAC;AACJ,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.18",
3
+ "version": "0.19.20",
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",
@@ -26,6 +26,29 @@ 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
+ // Read at runFrame() start (NOT module load) — consumers set the flag
41
+ // from app code that runs after this module is imported.
42
+ function isUncapped(): boolean {
43
+ return (globalThis as Record<string, unknown> & typeof globalThis)
44
+ .__wombatUncappedRenderLoop === true;
45
+ }
46
+
47
+ function bumpFrameCount(): void {
48
+ const g = globalThis as Record<string, unknown> & typeof globalThis;
49
+ g.__wombatFrameCount = ((g.__wombatFrameCount as number | undefined) ?? 0) + 1;
50
+ }
51
+
29
52
  export interface RunFrameOptions {
30
53
  /** Stop after N frames. Useful for tests + finite animations. */
31
54
  readonly maxFrames?: number;
@@ -73,6 +96,7 @@ export function runFrame(
73
96
  let lastTime = performance.now();
74
97
  let rafId = 0;
75
98
  let pending = false;
99
+ const UNCAPPED = isUncapped();
76
100
 
77
101
  // Wrap the frame callback in an AVal so the adaptive system tracks
78
102
  // its dependency set. Each `force()` re-reads the inputs and runs
@@ -95,6 +119,8 @@ export function runFrame(
95
119
 
96
120
  const finalizeFrame = (): void => {
97
121
  if (stopped) return;
122
+ // pacer (GPU completion) has resolved by now — this frame is DONE
123
+ if (UNCAPPED) bumpFrameCount();
98
124
  if (opts.onAfterFrame !== undefined) {
99
125
  transact(opts.onAfterFrame);
100
126
  }
@@ -104,6 +130,15 @@ export function runFrame(
104
130
  }
105
131
  };
106
132
 
133
+ const schedule = (cb: () => void): number =>
134
+ UNCAPPED
135
+ ? (setTimeout(cb, 0) as unknown as number)
136
+ : requestAnimationFrame(cb);
137
+ const cancel = (h: number): void => {
138
+ if (UNCAPPED) clearTimeout(h);
139
+ else cancelAnimationFrame(h);
140
+ };
141
+
107
142
  const tick = (): void => {
108
143
  if (stopped) return;
109
144
  pending = false;
@@ -133,18 +168,18 @@ export function runFrame(
133
168
  }).addMarkingCallback(() => {
134
169
  if (pending || stopped) return;
135
170
  pending = true;
136
- rafId = requestAnimationFrame(tick);
171
+ rafId = schedule(tick);
137
172
  });
138
173
 
139
174
  // Initial render. Schedules subsequent frames only when adaptive
140
175
  // marks reach `renderAval` (via the marking callback above).
141
176
  pending = true;
142
- rafId = requestAnimationFrame(tick);
177
+ rafId = schedule(tick);
143
178
 
144
179
  return {
145
180
  stop() {
146
181
  stopped = true;
147
- cancelAnimationFrame(rafId);
182
+ cancel(rafId);
148
183
  sub.dispose();
149
184
  },
150
185
  };