@graview/render 0.0.0-stage → 0.1.0
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/LICENSE +96 -0
- package/README.md +43 -2
- package/dist/gpu.d.ts +6 -0
- package/dist/gpu.d.ts.map +1 -0
- package/dist/gpu.js +23 -0
- package/dist/gpu.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/interaction/pointer-router.d.ts +94 -0
- package/dist/interaction/pointer-router.d.ts.map +1 -0
- package/dist/interaction/pointer-router.js +148 -0
- package/dist/interaction/pointer-router.js.map +1 -0
- package/dist/platform/html-in-canvas.d.ts +100 -0
- package/dist/platform/html-in-canvas.d.ts.map +1 -0
- package/dist/platform/html-in-canvas.js +172 -0
- package/dist/platform/html-in-canvas.js.map +1 -0
- package/dist/platform/matrix.d.ts +53 -0
- package/dist/platform/matrix.d.ts.map +1 -0
- package/dist/platform/matrix.js +61 -0
- package/dist/platform/matrix.js.map +1 -0
- package/dist/scene/compositor.d.ts +112 -0
- package/dist/scene/compositor.d.ts.map +1 -0
- package/dist/scene/compositor.js +340 -0
- package/dist/scene/compositor.js.map +1 -0
- package/dist/scene/compositor.wgsl.d.ts +15 -0
- package/dist/scene/compositor.wgsl.d.ts.map +1 -0
- package/dist/scene/compositor.wgsl.js +106 -0
- package/dist/scene/compositor.wgsl.js.map +1 -0
- package/dist/scene/connectors.d.ts +60 -0
- package/dist/scene/connectors.d.ts.map +1 -0
- package/dist/scene/connectors.js +95 -0
- package/dist/scene/connectors.js.map +1 -0
- package/dist/scene/frame-plan.d.ts +83 -0
- package/dist/scene/frame-plan.d.ts.map +1 -0
- package/dist/scene/frame-plan.js +119 -0
- package/dist/scene/frame-plan.js.map +1 -0
- package/dist/scene/from-layout.d.ts +14 -0
- package/dist/scene/from-layout.d.ts.map +1 -0
- package/dist/scene/from-layout.js +35 -0
- package/dist/scene/from-layout.js.map +1 -0
- package/dist/scene/plane.d.ts +68 -0
- package/dist/scene/plane.d.ts.map +1 -0
- package/dist/scene/plane.js +94 -0
- package/dist/scene/plane.js.map +1 -0
- package/package.json +64 -3
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/// <reference types="@webgpu/types" />
|
|
2
|
+
//
|
|
3
|
+
// The WebGPU globals are part of this file's PUBLIC declarations, so the
|
|
4
|
+
// reference has to live HERE rather than on the package entry: TypeScript
|
|
5
|
+
// drops a type reference from a `.d.ts` that does not itself name one of its
|
|
6
|
+
// types, so a reference on `index.ts` was emitted nowhere and an installed
|
|
7
|
+
// consumer got "cannot find name GPUDevice" from a file they cannot change.
|
|
8
|
+
// Found by typechecking a scratch project against the packed tarballs.
|
|
9
|
+
//
|
|
10
|
+
// It also has to be the ONLY route in: listing `@webgpu/types` under
|
|
11
|
+
// `compilerOptions.types` makes the globals ambient for this build, at which
|
|
12
|
+
// point TypeScript considers the reference satisfied and drops it from the
|
|
13
|
+
// emit. The build sees no difference; a stranger does.
|
|
14
|
+
/**
|
|
15
|
+
* THE platform seam. Every call into the HTML-in-Canvas API passes through
|
|
16
|
+
* this module and nowhere else.
|
|
17
|
+
*
|
|
18
|
+
* The API is mid-origin-trial and its naming is still settling — the WICG
|
|
19
|
+
* README calls the capture entry point `drawElementImageToTexture` in one
|
|
20
|
+
* place and `copyElementImageToTexture` in another — so the whole surface is
|
|
21
|
+
* resolved once, at runtime, behind names of our own. When the spec settles,
|
|
22
|
+
* exactly one file changes.
|
|
23
|
+
*
|
|
24
|
+
* Verified against Chrome Canary 154.0.8032.0 with
|
|
25
|
+
* `--enable-blink-features=CanvasDrawElement`. What that build actually
|
|
26
|
+
* exposes, and the exact call shapes, are recorded in
|
|
27
|
+
* `docs/platform-findings.md`; the shapes below are what it accepts, not what
|
|
28
|
+
* the README suggests.
|
|
29
|
+
*/
|
|
30
|
+
import { IDENTITY, isAffine, perspectiveProbeMatrix, planeTransform, toDOMMatrix, } from "./matrix.js";
|
|
31
|
+
export { IDENTITY, isAffine, perspectiveProbeMatrix, planeTransform, toDOMMatrix };
|
|
32
|
+
const CAPTURE_METHOD_NAMES = [
|
|
33
|
+
"drawElementImageToTexture",
|
|
34
|
+
"copyElementImageToTexture",
|
|
35
|
+
];
|
|
36
|
+
function scope() {
|
|
37
|
+
return typeof globalThis === "undefined" ? undefined : globalThis;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Resolves what this browser can actually do. Called once; everything else in
|
|
41
|
+
* the renderer branches on the result rather than sniffing again.
|
|
42
|
+
*/
|
|
43
|
+
export function detectCapabilities(queue, canvas) {
|
|
44
|
+
const notes = [];
|
|
45
|
+
const g = scope();
|
|
46
|
+
const webgpu = Boolean(g?.navigator && "gpu" in g.navigator);
|
|
47
|
+
if (!webgpu)
|
|
48
|
+
notes.push("navigator.gpu is absent — WebGPU is unavailable.");
|
|
49
|
+
const queueProto = queue ??
|
|
50
|
+
(g?.GPUQueue
|
|
51
|
+
?.prototype ??
|
|
52
|
+
undefined);
|
|
53
|
+
let captureMethod = null;
|
|
54
|
+
if (queueProto) {
|
|
55
|
+
for (const name of CAPTURE_METHOD_NAMES) {
|
|
56
|
+
if (typeof queueProto[name] === "function") {
|
|
57
|
+
captureMethod = name;
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (!captureMethod) {
|
|
63
|
+
notes.push("No element-capture method on GPUQueue. Run Chromium 147+ with " +
|
|
64
|
+
"--enable-blink-features=CanvasDrawElement.");
|
|
65
|
+
}
|
|
66
|
+
const canvasProto = canvas ??
|
|
67
|
+
(g
|
|
68
|
+
?.HTMLCanvasElement?.prototype ??
|
|
69
|
+
undefined);
|
|
70
|
+
const geometrySync = typeof canvasProto?.updateElementGeometry === "function";
|
|
71
|
+
if (!geometrySync) {
|
|
72
|
+
notes.push("canvas.updateElementGeometry is absent — geometry cannot be reported.");
|
|
73
|
+
}
|
|
74
|
+
const paintEvents = typeof canvasProto?.requestPaint === "function";
|
|
75
|
+
if (!paintEvents) {
|
|
76
|
+
notes.push("canvas.requestPaint is absent — there is no capture-safe moment to hook.");
|
|
77
|
+
}
|
|
78
|
+
let layoutSubtree = false;
|
|
79
|
+
if (typeof document !== "undefined") {
|
|
80
|
+
const probe = document.createElement("canvas");
|
|
81
|
+
layoutSubtree = "layoutSubtree" in probe;
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
available: captureMethod !== null,
|
|
85
|
+
captureMethod,
|
|
86
|
+
geometrySync,
|
|
87
|
+
hitTestFollowsGeometry: "unknown",
|
|
88
|
+
layoutSubtree,
|
|
89
|
+
paintEvents,
|
|
90
|
+
webgpu,
|
|
91
|
+
usable: webgpu && captureMethod !== null,
|
|
92
|
+
notes,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
export class PlatformUnavailableError extends Error {
|
|
96
|
+
capabilities;
|
|
97
|
+
constructor(capabilities) {
|
|
98
|
+
super(`HTML-in-Canvas is unavailable:\n ${capabilities.notes.join("\n ")}`);
|
|
99
|
+
this.capabilities = capabilities;
|
|
100
|
+
this.name = "PlatformUnavailableError";
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Captures a DOM element (or a previously taken paint record) into an
|
|
105
|
+
* existing GPU texture.
|
|
106
|
+
*
|
|
107
|
+
* Two preconditions the errors do not make obvious:
|
|
108
|
+
* - the element must be a descendant of a `<canvas layoutsubtree>`, and
|
|
109
|
+
* - that canvas must have a CONFIGURED WebGPU context of its own, or the call
|
|
110
|
+
* fails with "containing canvas does not have a rendering context".
|
|
111
|
+
*
|
|
112
|
+
* The texture is written in place, so the caller keeps ownership and no copy
|
|
113
|
+
* happens on our side.
|
|
114
|
+
*/
|
|
115
|
+
export function captureElement(queue, source, texture) {
|
|
116
|
+
const q = queue;
|
|
117
|
+
for (const name of CAPTURE_METHOD_NAMES) {
|
|
118
|
+
const method = q[name];
|
|
119
|
+
if (typeof method === "function") {
|
|
120
|
+
method.call(q, { source }, { destination: { texture } });
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
throw new PlatformUnavailableError(detectCapabilities(queue));
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Takes a cached paint record for an element. Only valid inside a `paint`
|
|
128
|
+
* event — outside one the browser has no paint record and throws
|
|
129
|
+
* `InvalidStateError`.
|
|
130
|
+
*/
|
|
131
|
+
export function captureElementImage(canvas, element) {
|
|
132
|
+
const target = canvas;
|
|
133
|
+
if (typeof target.captureElementImage !== "function") {
|
|
134
|
+
throw new PlatformUnavailableError(detectCapabilities(undefined, canvas));
|
|
135
|
+
}
|
|
136
|
+
return target.captureElementImage(element);
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Tells the browser where an element was actually drawn.
|
|
140
|
+
*
|
|
141
|
+
* The intent of the spec is that hit-testing, focus order, screen readers and
|
|
142
|
+
* find-in-page then resolve against the drawn pixels. In Chromium 154 the
|
|
143
|
+
* call is accepted and has no observable effect on hit-testing — see
|
|
144
|
+
* `docs/platform-findings.md`. Call it anyway (it costs nothing and will
|
|
145
|
+
* start working), and route pointers through `PointerRouter` meanwhile.
|
|
146
|
+
*/
|
|
147
|
+
export function updateElementGeometry(canvas, source, update) {
|
|
148
|
+
const target = canvas;
|
|
149
|
+
if (typeof target.updateElementGeometry !== "function") {
|
|
150
|
+
throw new PlatformUnavailableError(detectCapabilities(undefined, canvas));
|
|
151
|
+
}
|
|
152
|
+
target.updateElementGeometry(source, update);
|
|
153
|
+
}
|
|
154
|
+
/** Drops a reported geometry, returning the element to its layout position. */
|
|
155
|
+
export function clearElementGeometry(canvas, source) {
|
|
156
|
+
canvas.clearElementGeometry?.(source);
|
|
157
|
+
}
|
|
158
|
+
/** Asks for a `paint` event — the moment at which capture is legal. */
|
|
159
|
+
export function requestPaint(canvas) {
|
|
160
|
+
canvas.requestPaint?.();
|
|
161
|
+
}
|
|
162
|
+
/** Marks a canvas as owning its descendants' layout. */
|
|
163
|
+
export function setLayoutSubtree(canvas, on = true) {
|
|
164
|
+
const target = canvas;
|
|
165
|
+
if ("layoutSubtree" in target)
|
|
166
|
+
target.layoutSubtree = on;
|
|
167
|
+
else if (on)
|
|
168
|
+
target.setAttribute("layoutsubtree", "");
|
|
169
|
+
else
|
|
170
|
+
target.removeAttribute("layoutsubtree");
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=html-in-canvas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html-in-canvas.js","sourceRoot":"","sources":["../../src/platform/html-in-canvas.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,EAAE;AACF,yEAAyE;AACzE,0EAA0E;AAC1E,6EAA6E;AAC7E,2EAA2E;AAC3E,4EAA4E;AAC5E,uEAAuE;AACvE,EAAE;AACF,qEAAqE;AACrE,6EAA6E;AAC7E,2EAA2E;AAC3E,uDAAuD;AAEvD;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EACL,QAAQ,EACR,QAAQ,EACR,sBAAsB,EACtB,cAAc,EACd,WAAW,GAEZ,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,sBAAsB,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC;AAOnF,MAAM,oBAAoB,GAAiC;IACzD,2BAA2B;IAC3B,2BAA2B;CAC5B,CAAC;AAuDF,SAAS,KAAK;IACZ,OAAO,OAAO,UAAU,KAAK,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC;AACpE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAChC,KAAgB,EAChB,MAA0B;IAE1B,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,CAAC,GAAG,KAAK,EAAE,CAAC;IAClB,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,EAAE,SAAS,IAAI,KAAK,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC;IAC7D,IAAI,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,kDAAkD,CAAC,CAAC;IAE5E,MAAM,UAAU,GACb,KAAyC;QAC1C,CAAE,CAAmE,EAAE,QAAQ;YAC7E,EAAE,SAAS;YACX,SAAS,CAAC,CAAC;IACf,IAAI,aAAa,GAA6B,IAAI,CAAC;IACnD,IAAI,UAAU,EAAE,CAAC;QACf,KAAK,MAAM,IAAI,IAAI,oBAAoB,EAAE,CAAC;YACxC,IAAI,OAAO,UAAU,CAAC,IAAI,CAAC,KAAK,UAAU,EAAE,CAAC;gBAC3C,aAAa,GAAG,IAAI,CAAC;gBACrB,MAAM;YACR,CAAC;QACH,CAAC;IACH,CAAC;IACD,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,KAAK,CAAC,IAAI,CACR,gEAAgE;YAC9D,4CAA4C,CAC/C,CAAC;IACJ,CAAC;IAED,MAAM,WAAW,GACd,MAAoC;QACrC,CAAE,CAAsE;YACtE,EAAE,iBAAiB,EAAE,SAAS;YAC9B,SAAS,CAAC,CAAC;IACf,MAAM,YAAY,GAAG,OAAO,WAAW,EAAE,qBAAqB,KAAK,UAAU,CAAC;IAC9E,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,KAAK,CAAC,IAAI,CAAC,uEAAuE,CAAC,CAAC;IACtF,CAAC;IACD,MAAM,WAAW,GAAG,OAAO,WAAW,EAAE,YAAY,KAAK,UAAU,CAAC;IACpE,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,KAAK,CAAC,IAAI,CAAC,0EAA0E,CAAC,CAAC;IACzF,CAAC;IAED,IAAI,aAAa,GAAG,KAAK,CAAC;IAC1B,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE,CAAC;QACpC,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAkB,CAAC;QAChE,aAAa,GAAG,eAAe,IAAI,KAAK,CAAC;IAC3C,CAAC;IAED,OAAO;QACL,SAAS,EAAE,aAAa,KAAK,IAAI;QACjC,aAAa;QACb,YAAY;QACZ,sBAAsB,EAAE,SAAS;QACjC,aAAa;QACb,WAAW;QACX,MAAM;QACN,MAAM,EAAE,MAAM,IAAI,aAAa,KAAK,IAAI;QACxC,KAAK;KACN,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,wBAAyB,SAAQ,KAAK;IAC5B;IAArB,YAAqB,YAAkC;QACrD,KAAK,CAAC,qCAAqC,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAD3D,iBAAY,GAAZ,YAAY,CAAsB;QAErD,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAC;IACzC,CAAC;CACF;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,cAAc,CAC5B,KAAe,EACf,MAAqB,EACrB,OAAmB;IAEnB,MAAM,CAAC,GAAG,KAA4B,CAAC;IACvC,KAAK,MAAM,IAAI,IAAI,oBAAoB,EAAE,CAAC;QACxC,MAAM,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;QACvB,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE,CAAC;YACjC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;YACzD,OAAO;QACT,CAAC;IACH,CAAC;IACD,MAAM,IAAI,wBAAwB,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC;AAChE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CACjC,MAAyB,EACzB,OAAgB;IAEhB,MAAM,MAAM,GAAG,MAAuB,CAAC;IACvC,IAAI,OAAO,MAAM,CAAC,mBAAmB,KAAK,UAAU,EAAE,CAAC;QACrD,MAAM,IAAI,wBAAwB,CAAC,kBAAkB,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO,MAAM,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC7C,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,qBAAqB,CACnC,MAAyB,EACzB,MAAqB,EACrB,MAAsB;IAEtB,MAAM,MAAM,GAAG,MAAuB,CAAC;IACvC,IAAI,OAAO,MAAM,CAAC,qBAAqB,KAAK,UAAU,EAAE,CAAC;QACvD,MAAM,IAAI,wBAAwB,CAAC,kBAAkB,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC;IAC5E,CAAC;IACD,MAAM,CAAC,qBAAqB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAC/C,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,oBAAoB,CAClC,MAAyB,EACzB,MAAqB;IAEpB,MAAwB,CAAC,oBAAoB,EAAE,CAAC,MAAM,CAAC,CAAC;AAC3D,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,YAAY,CAAC,MAAyB;IACnD,MAAwB,CAAC,YAAY,EAAE,EAAE,CAAC;AAC7C,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,gBAAgB,CAAC,MAAyB,EAAE,EAAE,GAAG,IAAI;IACnE,MAAM,MAAM,GAAG,MAAuB,CAAC;IACvC,IAAI,eAAe,IAAI,MAAM;QAAE,MAAM,CAAC,aAAa,GAAG,EAAE,CAAC;SACpD,IAAI,EAAE;QAAE,MAAM,CAAC,YAAY,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;;QACjD,MAAM,CAAC,eAAe,CAAC,eAAe,CAAC,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Affine 4x4 matrices, and the plane transform built from one.
|
|
3
|
+
*
|
|
4
|
+
* Split out of the platform seam because it is PURE: no DOM, no WebGPU, no
|
|
5
|
+
* ambient globals. That matters for more than tidiness — the platform module's
|
|
6
|
+
* declarations name `GPUQueue`, which is an ambient global from
|
|
7
|
+
* `@webgpu/types`, so anything re-exported from there drags that requirement
|
|
8
|
+
* onto every consumer. The geometry every app uses should not.
|
|
9
|
+
*
|
|
10
|
+
* Affine is not a style choice here. The capture pipeline composites textures
|
|
11
|
+
* with a per-plane transform, and a perspective divide would mean resampling
|
|
12
|
+
* each captured view every frame; `isAffine` is the guard that keeps that
|
|
13
|
+
* true, and it is checked in tests on both renderer paths.
|
|
14
|
+
*/
|
|
15
|
+
export type Matrix4 = readonly [
|
|
16
|
+
number,
|
|
17
|
+
number,
|
|
18
|
+
number,
|
|
19
|
+
number,
|
|
20
|
+
number,
|
|
21
|
+
number,
|
|
22
|
+
number,
|
|
23
|
+
number,
|
|
24
|
+
number,
|
|
25
|
+
number,
|
|
26
|
+
number,
|
|
27
|
+
number,
|
|
28
|
+
number,
|
|
29
|
+
number,
|
|
30
|
+
number,
|
|
31
|
+
number
|
|
32
|
+
];
|
|
33
|
+
/** An opaque cached paint record for one element, from `captureElementImage`. */
|
|
34
|
+
/**
|
|
35
|
+
* Whether a matrix is affine — no perspective row.
|
|
36
|
+
*
|
|
37
|
+
* The plane model is designed so that everything it emits passes this test:
|
|
38
|
+
* depth is per-plane uniform scale, blur and shadow, never per-element
|
|
39
|
+
* foreshortening. That keeps the model correct whichever way the platform
|
|
40
|
+
* settles the perspective question.
|
|
41
|
+
*/
|
|
42
|
+
export declare function isAffine(matrix: Matrix4): boolean;
|
|
43
|
+
/** Column-major 4x4 identity. */
|
|
44
|
+
export declare const IDENTITY: Matrix4;
|
|
45
|
+
/**
|
|
46
|
+
* The affine transform a plane contributes: uniform scale about the canvas
|
|
47
|
+
* origin plus a translation. Deliberately nothing else.
|
|
48
|
+
*/
|
|
49
|
+
export declare function planeTransform(scale: number, translateX: number, translateY: number): Matrix4;
|
|
50
|
+
/** A perspective matrix, used only to ask the browser whether it takes one. */
|
|
51
|
+
export declare function perspectiveProbeMatrix(depth?: number): Matrix4;
|
|
52
|
+
export declare function toDOMMatrix(matrix: Matrix4 | DOMMatrix): DOMMatrix;
|
|
53
|
+
//# sourceMappingURL=matrix.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matrix.d.ts","sourceRoot":"","sources":["../../src/platform/matrix.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,MAAM,OAAO,GAAG,SAAS;IAC7B,MAAM;IAAE,MAAM;IAAE,MAAM;IAAE,MAAM;IAC9B,MAAM;IAAE,MAAM;IAAE,MAAM;IAAE,MAAM;IAC9B,MAAM;IAAE,MAAM;IAAE,MAAM;IAAE,MAAM;IAC9B,MAAM;IAAE,MAAM;IAAE,MAAM;IAAE,MAAM;CAC/B,CAAC;AAEF,iFAAiF;AAEjF;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAEjD;AAED,iCAAiC;AACjC,eAAO,MAAM,QAAQ,EAAE,OAKtB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACjB,OAAO,CAOT;AAED,+EAA+E;AAC/E,wBAAgB,sBAAsB,CAAC,KAAK,SAAM,GAAG,OAAO,CAO3D;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,CAKlE"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Affine 4x4 matrices, and the plane transform built from one.
|
|
3
|
+
*
|
|
4
|
+
* Split out of the platform seam because it is PURE: no DOM, no WebGPU, no
|
|
5
|
+
* ambient globals. That matters for more than tidiness — the platform module's
|
|
6
|
+
* declarations name `GPUQueue`, which is an ambient global from
|
|
7
|
+
* `@webgpu/types`, so anything re-exported from there drags that requirement
|
|
8
|
+
* onto every consumer. The geometry every app uses should not.
|
|
9
|
+
*
|
|
10
|
+
* Affine is not a style choice here. The capture pipeline composites textures
|
|
11
|
+
* with a per-plane transform, and a perspective divide would mean resampling
|
|
12
|
+
* each captured view every frame; `isAffine` is the guard that keeps that
|
|
13
|
+
* true, and it is checked in tests on both renderer paths.
|
|
14
|
+
*/
|
|
15
|
+
/** An opaque cached paint record for one element, from `captureElementImage`. */
|
|
16
|
+
/**
|
|
17
|
+
* Whether a matrix is affine — no perspective row.
|
|
18
|
+
*
|
|
19
|
+
* The plane model is designed so that everything it emits passes this test:
|
|
20
|
+
* depth is per-plane uniform scale, blur and shadow, never per-element
|
|
21
|
+
* foreshortening. That keeps the model correct whichever way the platform
|
|
22
|
+
* settles the perspective question.
|
|
23
|
+
*/
|
|
24
|
+
export function isAffine(matrix) {
|
|
25
|
+
return matrix[3] === 0 && matrix[7] === 0 && matrix[11] === 0 && matrix[15] === 1;
|
|
26
|
+
}
|
|
27
|
+
/** Column-major 4x4 identity. */
|
|
28
|
+
export const IDENTITY = [
|
|
29
|
+
1, 0, 0, 0,
|
|
30
|
+
0, 1, 0, 0,
|
|
31
|
+
0, 0, 1, 0,
|
|
32
|
+
0, 0, 0, 1,
|
|
33
|
+
];
|
|
34
|
+
/**
|
|
35
|
+
* The affine transform a plane contributes: uniform scale about the canvas
|
|
36
|
+
* origin plus a translation. Deliberately nothing else.
|
|
37
|
+
*/
|
|
38
|
+
export function planeTransform(scale, translateX, translateY) {
|
|
39
|
+
return [
|
|
40
|
+
scale, 0, 0, 0,
|
|
41
|
+
0, scale, 0, 0,
|
|
42
|
+
0, 0, 1, 0,
|
|
43
|
+
translateX, translateY, 0, 1,
|
|
44
|
+
];
|
|
45
|
+
}
|
|
46
|
+
/** A perspective matrix, used only to ask the browser whether it takes one. */
|
|
47
|
+
export function perspectiveProbeMatrix(depth = 800) {
|
|
48
|
+
return [
|
|
49
|
+
1, 0, 0, 0,
|
|
50
|
+
0, 1, 0, 0,
|
|
51
|
+
0, 0, 1, -1 / depth,
|
|
52
|
+
0, 0, 0, 1,
|
|
53
|
+
];
|
|
54
|
+
}
|
|
55
|
+
export function toDOMMatrix(matrix) {
|
|
56
|
+
if (typeof DOMMatrix === "undefined") {
|
|
57
|
+
throw new Error("DOMMatrix is unavailable outside a browser");
|
|
58
|
+
}
|
|
59
|
+
return matrix instanceof DOMMatrix ? matrix : new DOMMatrix([...matrix]);
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=matrix.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matrix.js","sourceRoot":"","sources":["../../src/platform/matrix.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AASH,iFAAiF;AAEjF;;;;;;;GAOG;AACH,MAAM,UAAU,QAAQ,CAAC,MAAe;IACtC,OAAO,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;AACpF,CAAC;AAED,iCAAiC;AACjC,MAAM,CAAC,MAAM,QAAQ,GAAY;IAC/B,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;IACV,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;IACV,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;IACV,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;CACX,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,cAAc,CAC5B,KAAa,EACb,UAAkB,EAClB,UAAkB;IAElB,OAAO;QACL,KAAK,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;QACd,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;QACd,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;QACV,UAAU,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;KAC7B,CAAC;AACJ,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,sBAAsB,CAAC,KAAK,GAAG,GAAG;IAChD,OAAO;QACL,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;QACV,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;QACV,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK;QACnB,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;KACX,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,MAA2B;IACrD,IAAI,OAAO,SAAS,KAAK,WAAW,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,MAAM,YAAY,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;AAC3E,CAAC"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { type Placement } from "../interaction/pointer-router.js";
|
|
2
|
+
import { type PlatformCapabilities } from "../platform/html-in-canvas.js";
|
|
3
|
+
import type { ConnectorStyle } from "./connectors.js";
|
|
4
|
+
import { type FramePlan, type PlannedConnector, type PlannedView, type ViewDraw } from "./frame-plan.js";
|
|
5
|
+
/** A view in the scene: its DOM subtree, plus everything the plan needs. */
|
|
6
|
+
export interface SceneView extends PlannedView {
|
|
7
|
+
/**
|
|
8
|
+
* The element captured for this view. It MUST be an immediate child of the
|
|
9
|
+
* scene canvas — the platform rejects anything deeper. Its own descendants
|
|
10
|
+
* are captured with it.
|
|
11
|
+
*/
|
|
12
|
+
readonly element: HTMLElement;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* The minimum of a WebGPU device this module uses, said structurally: a
|
|
16
|
+
* device from `navigator.gpu`, from `vgpu`, `vgpu/node` or `vgpu/mock` all
|
|
17
|
+
* fit, and this package depends on none of them.
|
|
18
|
+
*/
|
|
19
|
+
export interface VgpuLike {
|
|
20
|
+
readonly device: {
|
|
21
|
+
readonly gpu: GPUDevice;
|
|
22
|
+
};
|
|
23
|
+
dispose?(): void;
|
|
24
|
+
}
|
|
25
|
+
export interface SurfaceLike {
|
|
26
|
+
readonly context: GPUCanvasContext;
|
|
27
|
+
}
|
|
28
|
+
export interface CompositorDeps {
|
|
29
|
+
readonly gpu: VgpuLike;
|
|
30
|
+
readonly surface: SurfaceLike;
|
|
31
|
+
}
|
|
32
|
+
export interface CompositorOptions {
|
|
33
|
+
/** The ground colour receded planes drift toward. Defaults to a warm off-white. */
|
|
34
|
+
readonly ground?: readonly [number, number, number];
|
|
35
|
+
/** Stand the pointer router down once a browser redirects hit-testing itself. */
|
|
36
|
+
readonly platformHandlesHitTesting?: boolean;
|
|
37
|
+
readonly connectorOverrides?: Readonly<Record<string, Partial<ConnectorStyle>>>;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Captures views into GPU textures and composites them as quads at plane
|
|
41
|
+
* depth, then reports each drawn position back to the browser.
|
|
42
|
+
*
|
|
43
|
+
* The frame is decided by `planFrame` — which fidelity captures, what order
|
|
44
|
+
* things draw in, where each view lands — and this class only submits it.
|
|
45
|
+
* Keeping the decisions out of here is what lets them be tested in CI with
|
|
46
|
+
* no GPU and no DOM.
|
|
47
|
+
*/
|
|
48
|
+
export declare class Compositor {
|
|
49
|
+
readonly canvas: HTMLCanvasElement;
|
|
50
|
+
private readonly deps;
|
|
51
|
+
private readonly options;
|
|
52
|
+
private readonly views;
|
|
53
|
+
private readonly resources;
|
|
54
|
+
private readonly capturedAt;
|
|
55
|
+
private readonly router;
|
|
56
|
+
private pipeline;
|
|
57
|
+
private sampler;
|
|
58
|
+
private frame;
|
|
59
|
+
private detachRouter;
|
|
60
|
+
private connectors;
|
|
61
|
+
private lastPlan;
|
|
62
|
+
private lastPlacements;
|
|
63
|
+
readonly capabilities: PlatformCapabilities;
|
|
64
|
+
constructor(canvas: HTMLCanvasElement, deps: CompositorDeps, options?: CompositorOptions);
|
|
65
|
+
attach(): () => void;
|
|
66
|
+
detach(): void;
|
|
67
|
+
/**
|
|
68
|
+
* Brings the scene in line with a new set of views, keeping the GPU
|
|
69
|
+
* resources of everything that survived.
|
|
70
|
+
*
|
|
71
|
+
* Removing and re-adding every view on each edit destroys and reallocates
|
|
72
|
+
* every texture, which is both wasteful and — at this scene's size — enough
|
|
73
|
+
* to bring the GPU process down. Reconciling touches only what changed.
|
|
74
|
+
*/
|
|
75
|
+
reconcile(views: readonly SceneView[]): void;
|
|
76
|
+
/** Whether this view's cached texture still reflects what it looks like. */
|
|
77
|
+
private capturedAtIsFresh;
|
|
78
|
+
add(view: SceneView): void;
|
|
79
|
+
remove(id: string): void;
|
|
80
|
+
/** Replaces the connector set, e.g. after a layout change. */
|
|
81
|
+
setConnectors(connectors: readonly PlannedConnector[]): void;
|
|
82
|
+
/** Marks a view's texture stale, so the next frame recaptures it. */
|
|
83
|
+
invalidate(id: string): void;
|
|
84
|
+
all(): SceneView[];
|
|
85
|
+
/** Last frame's plan. Measurement harnesses and tests only. */
|
|
86
|
+
plan(): FramePlan | null;
|
|
87
|
+
/** Where each view was drawn last frame, with the element it came from. */
|
|
88
|
+
placements(): readonly Placement[];
|
|
89
|
+
/** Raw device handle. Measurement harnesses only. */
|
|
90
|
+
deviceForProbe(): GPUDevice;
|
|
91
|
+
/** Asks the browser for a `paint` event — the only moment capture is legal. */
|
|
92
|
+
scheduleFrame(): void;
|
|
93
|
+
/**
|
|
94
|
+
* One frame: capture what is stale, draw every view back to front, and tell
|
|
95
|
+
* the browser where each one landed.
|
|
96
|
+
*
|
|
97
|
+
* Call this from a `paint` listener. Outside one the browser has no paint
|
|
98
|
+
* record and capture throws.
|
|
99
|
+
*/
|
|
100
|
+
render(): FramePlan;
|
|
101
|
+
private groundColor;
|
|
102
|
+
private ensurePipeline;
|
|
103
|
+
private ensureResources;
|
|
104
|
+
private ensureBindGroup;
|
|
105
|
+
dispose(): void;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* The uniform layout the compositing shader reads, packed as data so a test
|
|
109
|
+
* can assert on it with no GPU present.
|
|
110
|
+
*/
|
|
111
|
+
export declare function packUniform(draw: ViewDraw, canvasWidth: number, canvasHeight: number, ground: readonly [number, number, number]): Float32Array<ArrayBuffer>;
|
|
112
|
+
//# sourceMappingURL=compositor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compositor.d.ts","sourceRoot":"","sources":["../../src/scene/compositor.ts"],"names":[],"mappings":"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"}
|