@luma.gl/core 9.2.5 → 9.3.0-alpha.10
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/adapter/canvas-context.d.ts +6 -162
- package/dist/adapter/canvas-context.d.ts.map +1 -1
- package/dist/adapter/canvas-context.js +5 -419
- package/dist/adapter/canvas-context.js.map +1 -1
- package/dist/adapter/canvas-observer.d.ts +32 -0
- package/dist/adapter/canvas-observer.d.ts.map +1 -0
- package/dist/adapter/canvas-observer.js +90 -0
- package/dist/adapter/canvas-observer.js.map +1 -0
- package/dist/adapter/canvas-surface.d.ts +150 -0
- package/dist/adapter/canvas-surface.d.ts.map +1 -0
- package/dist/adapter/canvas-surface.js +392 -0
- package/dist/adapter/canvas-surface.js.map +1 -0
- package/dist/adapter/device.d.ts +81 -16
- package/dist/adapter/device.d.ts.map +1 -1
- package/dist/adapter/device.js +196 -10
- package/dist/adapter/device.js.map +1 -1
- package/dist/adapter/luma.js +1 -1
- package/dist/adapter/luma.js.map +1 -1
- package/dist/adapter/presentation-context.d.ts +11 -0
- package/dist/adapter/presentation-context.d.ts.map +1 -0
- package/dist/adapter/presentation-context.js +12 -0
- package/dist/adapter/presentation-context.js.map +1 -0
- package/dist/adapter/resources/buffer.d.ts +5 -5
- package/dist/adapter/resources/buffer.d.ts.map +1 -1
- package/dist/adapter/resources/buffer.js +18 -7
- package/dist/adapter/resources/buffer.js.map +1 -1
- package/dist/adapter/resources/command-buffer.d.ts +3 -1
- package/dist/adapter/resources/command-buffer.d.ts.map +1 -1
- package/dist/adapter/resources/command-buffer.js +3 -1
- package/dist/adapter/resources/command-buffer.js.map +1 -1
- package/dist/adapter/resources/command-encoder.d.ts +30 -7
- package/dist/adapter/resources/command-encoder.d.ts.map +1 -1
- package/dist/adapter/resources/command-encoder.js +68 -2
- package/dist/adapter/resources/command-encoder.js.map +1 -1
- package/dist/adapter/resources/compute-pipeline.d.ts +2 -2
- package/dist/adapter/resources/compute-pipeline.d.ts.map +1 -1
- package/dist/adapter/resources/fence.d.ts +16 -0
- package/dist/adapter/resources/fence.d.ts.map +1 -0
- package/dist/adapter/resources/fence.js +17 -0
- package/dist/adapter/resources/fence.js.map +1 -0
- package/dist/adapter/resources/framebuffer.d.ts +1 -1
- package/dist/adapter/resources/framebuffer.d.ts.map +1 -1
- package/dist/adapter/resources/framebuffer.js +15 -12
- package/dist/adapter/resources/framebuffer.js.map +1 -1
- package/dist/adapter/resources/query-set.d.ts +17 -1
- package/dist/adapter/resources/query-set.d.ts.map +1 -1
- package/dist/adapter/resources/query-set.js.map +1 -1
- package/dist/adapter/resources/render-pipeline.d.ts +28 -10
- package/dist/adapter/resources/render-pipeline.d.ts.map +1 -1
- package/dist/adapter/resources/render-pipeline.js +21 -2
- package/dist/adapter/resources/render-pipeline.js.map +1 -1
- package/dist/adapter/resources/resource.d.ts +13 -0
- package/dist/adapter/resources/resource.d.ts.map +1 -1
- package/dist/adapter/resources/resource.js +243 -14
- package/dist/adapter/resources/resource.js.map +1 -1
- package/dist/adapter/resources/shader.js +27 -25
- package/dist/adapter/resources/shader.js.map +1 -1
- package/dist/adapter/resources/shared-render-pipeline.d.ts +22 -0
- package/dist/adapter/resources/shared-render-pipeline.d.ts.map +1 -0
- package/dist/adapter/resources/shared-render-pipeline.js +25 -0
- package/dist/adapter/resources/shared-render-pipeline.js.map +1 -0
- package/dist/adapter/resources/texture-view.d.ts +1 -1
- package/dist/adapter/resources/texture-view.d.ts.map +1 -1
- package/dist/adapter/resources/texture.d.ts +168 -28
- package/dist/adapter/resources/texture.d.ts.map +1 -1
- package/dist/adapter/resources/texture.js +284 -25
- package/dist/adapter/resources/texture.js.map +1 -1
- package/dist/adapter/types/attachments.d.ts +1 -1
- package/dist/adapter/types/attachments.d.ts.map +1 -1
- package/dist/adapter/types/buffer-layout.d.ts +1 -1
- package/dist/adapter/types/buffer-layout.d.ts.map +1 -1
- package/dist/adapter/types/parameters.d.ts +3 -1
- package/dist/adapter/types/parameters.d.ts.map +1 -1
- package/dist/adapter/types/parameters.js +1 -0
- package/dist/adapter/types/parameters.js.map +1 -1
- package/dist/adapter/types/shader-layout.d.ts +10 -6
- package/dist/adapter/types/shader-layout.d.ts.map +1 -1
- package/dist/adapter/types/uniforms.d.ts +6 -0
- package/dist/adapter/types/uniforms.d.ts.map +1 -1
- package/dist/adapter-utils/bind-groups.d.ts +9 -0
- package/dist/adapter-utils/bind-groups.d.ts.map +1 -0
- package/dist/adapter-utils/bind-groups.js +41 -0
- package/dist/adapter-utils/bind-groups.js.map +1 -0
- package/dist/adapter-utils/format-compiler-log.d.ts.map +1 -1
- package/dist/adapter-utils/format-compiler-log.js +23 -15
- package/dist/adapter-utils/format-compiler-log.js.map +1 -1
- package/dist/adapter-utils/get-attribute-from-layouts.d.ts +2 -2
- package/dist/adapter-utils/get-attribute-from-layouts.d.ts.map +1 -1
- package/dist/adapter-utils/get-attribute-from-layouts.js +6 -6
- package/dist/adapter-utils/get-attribute-from-layouts.js.map +1 -1
- package/dist/dist.dev.js +2692 -645
- package/dist/dist.min.js +10 -9
- package/dist/factories/bind-group-factory.d.ts +20 -0
- package/dist/factories/bind-group-factory.d.ts.map +1 -0
- package/dist/factories/bind-group-factory.js +79 -0
- package/dist/factories/bind-group-factory.js.map +1 -0
- package/dist/factories/core-module-state.d.ts +7 -0
- package/dist/factories/core-module-state.d.ts.map +1 -0
- package/dist/{shadertypes/data-types/shader-types.js → factories/core-module-state.js} +1 -1
- package/dist/factories/core-module-state.js.map +1 -0
- package/dist/factories/pipeline-factory.d.ts +54 -0
- package/dist/factories/pipeline-factory.d.ts.map +1 -0
- package/dist/factories/pipeline-factory.js +270 -0
- package/dist/factories/pipeline-factory.js.map +1 -0
- package/dist/factories/shader-factory.d.ts +20 -0
- package/dist/factories/shader-factory.d.ts.map +1 -0
- package/dist/factories/shader-factory.js +84 -0
- package/dist/factories/shader-factory.js.map +1 -0
- package/dist/index.cjs +2427 -554
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +30 -14
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -7
- package/dist/index.js.map +1 -1
- package/dist/portable/shader-block-writer.d.ts +51 -0
- package/dist/portable/shader-block-writer.d.ts.map +1 -0
- package/dist/portable/shader-block-writer.js +185 -0
- package/dist/portable/shader-block-writer.js.map +1 -0
- package/dist/portable/uniform-block.d.ts +1 -1
- package/dist/portable/uniform-block.d.ts.map +1 -1
- package/dist/portable/uniform-store.d.ts +55 -24
- package/dist/portable/uniform-store.d.ts.map +1 -1
- package/dist/portable/uniform-store.js +73 -25
- package/dist/portable/uniform-store.js.map +1 -1
- package/dist/shadertypes/data-types/data-type-decoder.d.ts +20 -0
- package/dist/shadertypes/data-types/data-type-decoder.d.ts.map +1 -0
- package/dist/shadertypes/data-types/data-type-decoder.js +79 -0
- package/dist/shadertypes/data-types/data-type-decoder.js.map +1 -0
- package/dist/shadertypes/data-types/data-types.d.ts +31 -12
- package/dist/shadertypes/data-types/data-types.d.ts.map +1 -1
- package/dist/shadertypes/data-types/decode-data-types.d.ts.map +1 -1
- package/dist/shadertypes/data-types/decode-data-types.js +2 -1
- package/dist/shadertypes/data-types/decode-data-types.js.map +1 -1
- package/dist/{image-utils → shadertypes/image-types}/image-types.d.ts +0 -6
- package/dist/shadertypes/image-types/image-types.d.ts.map +1 -0
- package/dist/shadertypes/image-types/image-types.js.map +1 -0
- package/dist/shadertypes/shader-types/shader-block-layout.d.ts +72 -0
- package/dist/shadertypes/shader-types/shader-block-layout.d.ts.map +1 -0
- package/dist/shadertypes/shader-types/shader-block-layout.js +209 -0
- package/dist/shadertypes/shader-types/shader-block-layout.js.map +1 -0
- package/dist/shadertypes/shader-types/shader-type-decoder.d.ts +41 -0
- package/dist/shadertypes/shader-types/shader-type-decoder.d.ts.map +1 -0
- package/dist/shadertypes/{data-types/decode-shader-types.js → shader-types/shader-type-decoder.js} +43 -4
- package/dist/shadertypes/shader-types/shader-type-decoder.js.map +1 -0
- package/dist/shadertypes/shader-types/shader-types.d.ts +101 -0
- package/dist/shadertypes/shader-types/shader-types.d.ts.map +1 -0
- package/dist/shadertypes/shader-types/shader-types.js +30 -0
- package/dist/shadertypes/shader-types/shader-types.js.map +1 -0
- package/dist/shadertypes/texture-types/pixel-utils.d.ts.map +1 -0
- package/dist/shadertypes/{textures → texture-types}/pixel-utils.js +4 -4
- package/dist/shadertypes/texture-types/pixel-utils.js.map +1 -0
- package/dist/shadertypes/texture-types/texture-format-decoder.d.ts +36 -0
- package/dist/shadertypes/texture-types/texture-format-decoder.d.ts.map +1 -0
- package/dist/shadertypes/{textures → texture-types}/texture-format-decoder.js +109 -37
- package/dist/shadertypes/texture-types/texture-format-decoder.js.map +1 -0
- package/dist/shadertypes/texture-types/texture-format-generics.d.ts +34 -0
- package/dist/shadertypes/texture-types/texture-format-generics.d.ts.map +1 -0
- package/dist/shadertypes/texture-types/texture-format-generics.js.map +1 -0
- package/dist/shadertypes/texture-types/texture-format-table.d.ts.map +1 -0
- package/dist/shadertypes/{textures → texture-types}/texture-format-table.js +10 -9
- package/dist/shadertypes/texture-types/texture-format-table.js.map +1 -0
- package/dist/shadertypes/{textures → texture-types}/texture-formats.d.ts +51 -17
- package/dist/shadertypes/texture-types/texture-formats.d.ts.map +1 -0
- package/dist/shadertypes/{textures → texture-types}/texture-formats.js +1 -0
- package/dist/shadertypes/texture-types/texture-formats.js.map +1 -0
- package/dist/shadertypes/texture-types/texture-layout.d.ts +5 -0
- package/dist/shadertypes/texture-types/texture-layout.d.ts.map +1 -0
- package/dist/shadertypes/texture-types/texture-layout.js +41 -0
- package/dist/shadertypes/texture-types/texture-layout.js.map +1 -0
- package/dist/shadertypes/vertex-types/vertex-format-decoder.d.ts +24 -0
- package/dist/shadertypes/vertex-types/vertex-format-decoder.d.ts.map +1 -0
- package/dist/shadertypes/vertex-types/vertex-format-decoder.js +106 -0
- package/dist/shadertypes/vertex-types/vertex-format-decoder.js.map +1 -0
- package/dist/shadertypes/vertex-types/vertex-formats.d.ts +50 -0
- package/dist/shadertypes/vertex-types/vertex-formats.d.ts.map +1 -0
- package/dist/shadertypes/vertex-types/vertex-formats.js.map +1 -0
- package/dist/utils/array-equal.d.ts +1 -1
- package/dist/utils/array-equal.d.ts.map +1 -1
- package/dist/utils/array-equal.js +15 -9
- package/dist/utils/array-equal.js.map +1 -1
- package/dist/utils/assert.d.ts +5 -0
- package/dist/utils/assert.d.ts.map +1 -0
- package/dist/utils/assert.js +17 -0
- package/dist/utils/assert.js.map +1 -0
- package/dist/utils/stats-manager.d.ts.map +1 -1
- package/dist/utils/stats-manager.js +61 -1
- package/dist/utils/stats-manager.js.map +1 -1
- package/package.json +6 -6
- package/src/adapter/canvas-context.ts +7 -556
- package/src/adapter/canvas-observer.ts +130 -0
- package/src/adapter/canvas-surface.ts +521 -0
- package/src/adapter/device.ts +312 -24
- package/src/adapter/presentation-context.ts +16 -0
- package/src/adapter/resources/buffer.ts +19 -9
- package/src/adapter/resources/command-buffer.ts +4 -2
- package/src/adapter/resources/command-encoder.ts +101 -10
- package/src/adapter/resources/compute-pipeline.ts +2 -2
- package/src/adapter/resources/fence.ts +32 -0
- package/src/adapter/resources/framebuffer.ts +16 -13
- package/src/adapter/resources/query-set.ts +17 -1
- package/src/adapter/resources/render-pipeline.ts +52 -16
- package/src/adapter/resources/resource.ts +289 -14
- package/src/adapter/resources/shader.ts +28 -28
- package/src/adapter/resources/shared-render-pipeline.ts +40 -0
- package/src/adapter/resources/texture-view.ts +1 -1
- package/src/adapter/resources/texture.ts +427 -49
- package/src/adapter/types/attachments.ts +1 -1
- package/src/adapter/types/buffer-layout.ts +1 -1
- package/src/adapter/types/parameters.ts +4 -1
- package/src/adapter/types/shader-layout.ts +15 -9
- package/src/adapter/types/uniforms.ts +12 -0
- package/src/adapter-utils/bind-groups.ts +71 -0
- package/src/adapter-utils/format-compiler-log.ts +23 -15
- package/src/adapter-utils/get-attribute-from-layouts.ts +8 -11
- package/src/factories/bind-group-factory.ts +139 -0
- package/src/factories/core-module-state.ts +11 -0
- package/src/factories/pipeline-factory.ts +328 -0
- package/src/factories/shader-factory.ts +103 -0
- package/src/index.ts +70 -26
- package/src/portable/shader-block-writer.ts +254 -0
- package/src/portable/uniform-block.ts +1 -1
- package/src/portable/uniform-store.ts +98 -40
- package/src/shadertypes/data-types/data-type-decoder.ts +105 -0
- package/src/shadertypes/data-types/data-types.ts +100 -48
- package/src/shadertypes/data-types/decode-data-types.ts +2 -1
- package/src/{image-utils → shadertypes/image-types}/image-types.ts +0 -7
- package/src/shadertypes/shader-types/shader-block-layout.ts +340 -0
- package/src/shadertypes/{data-types/decode-shader-types.ts → shader-types/shader-type-decoder.ts} +88 -14
- package/src/shadertypes/shader-types/shader-types.ts +207 -0
- package/src/shadertypes/{textures → texture-types}/pixel-utils.ts +4 -4
- package/src/shadertypes/{textures → texture-types}/texture-format-decoder.ts +166 -45
- package/src/shadertypes/{textures → texture-types}/texture-format-generics.ts +42 -48
- package/src/shadertypes/{textures → texture-types}/texture-format-table.ts +10 -9
- package/src/shadertypes/{textures → texture-types}/texture-formats.ts +73 -17
- package/src/shadertypes/texture-types/texture-layout.ts +60 -0
- package/src/shadertypes/vertex-types/vertex-format-decoder.ts +131 -0
- package/src/shadertypes/vertex-types/vertex-formats.ts +183 -0
- package/src/utils/array-equal.ts +21 -9
- package/src/utils/assert.ts +18 -0
- package/src/utils/stats-manager.ts +76 -2
- package/dist/image-utils/image-types.d.ts.map +0 -1
- package/dist/image-utils/image-types.js.map +0 -1
- package/dist/portable/uniform-buffer-layout.d.ts +0 -28
- package/dist/portable/uniform-buffer-layout.d.ts.map +0 -1
- package/dist/portable/uniform-buffer-layout.js +0 -96
- package/dist/portable/uniform-buffer-layout.js.map +0 -1
- package/dist/shadertypes/data-types/decode-shader-types.d.ts +0 -17
- package/dist/shadertypes/data-types/decode-shader-types.d.ts.map +0 -1
- package/dist/shadertypes/data-types/decode-shader-types.js.map +0 -1
- package/dist/shadertypes/data-types/shader-types.d.ts +0 -45
- package/dist/shadertypes/data-types/shader-types.d.ts.map +0 -1
- package/dist/shadertypes/data-types/shader-types.js.map +0 -1
- package/dist/shadertypes/textures/pixel-utils.d.ts.map +0 -1
- package/dist/shadertypes/textures/pixel-utils.js.map +0 -1
- package/dist/shadertypes/textures/texture-format-decoder.d.ts +0 -18
- package/dist/shadertypes/textures/texture-format-decoder.d.ts.map +0 -1
- package/dist/shadertypes/textures/texture-format-decoder.js.map +0 -1
- package/dist/shadertypes/textures/texture-format-generics.d.ts +0 -33
- package/dist/shadertypes/textures/texture-format-generics.d.ts.map +0 -1
- package/dist/shadertypes/textures/texture-format-generics.js.map +0 -1
- package/dist/shadertypes/textures/texture-format-table.d.ts.map +0 -1
- package/dist/shadertypes/textures/texture-format-table.js.map +0 -1
- package/dist/shadertypes/textures/texture-formats.d.ts.map +0 -1
- package/dist/shadertypes/textures/texture-formats.js.map +0 -1
- package/dist/shadertypes/vertex-arrays/decode-vertex-format.d.ts +0 -18
- package/dist/shadertypes/vertex-arrays/decode-vertex-format.d.ts.map +0 -1
- package/dist/shadertypes/vertex-arrays/decode-vertex-format.js +0 -100
- package/dist/shadertypes/vertex-arrays/decode-vertex-format.js.map +0 -1
- package/dist/shadertypes/vertex-arrays/vertex-formats.d.ts +0 -27
- package/dist/shadertypes/vertex-arrays/vertex-formats.d.ts.map +0 -1
- package/dist/shadertypes/vertex-arrays/vertex-formats.js.map +0 -1
- package/src/portable/uniform-buffer-layout.ts +0 -118
- package/src/shadertypes/data-types/shader-types.ts +0 -87
- package/src/shadertypes/vertex-arrays/decode-vertex-format.ts +0 -124
- package/src/shadertypes/vertex-arrays/vertex-formats.ts +0 -91
- /package/dist/{image-utils → shadertypes/image-types}/image-types.js +0 -0
- /package/dist/shadertypes/{textures → texture-types}/pixel-utils.d.ts +0 -0
- /package/dist/shadertypes/{textures → texture-types}/texture-format-generics.js +0 -0
- /package/dist/shadertypes/{textures → texture-types}/texture-format-table.d.ts +0 -0
- /package/dist/shadertypes/{vertex-arrays → vertex-types}/vertex-formats.js +0 -0
|
@@ -0,0 +1,521 @@
|
|
|
1
|
+
// luma.gl
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
import {isBrowser} from '@probe.gl/env';
|
|
6
|
+
import type {Device} from './device';
|
|
7
|
+
import type {CanvasContext} from './canvas-context';
|
|
8
|
+
import {CanvasObserver} from './canvas-observer';
|
|
9
|
+
import type {PresentationContext} from './presentation-context';
|
|
10
|
+
import type {Framebuffer} from './resources/framebuffer';
|
|
11
|
+
import type {TextureFormatDepthStencil} from '../shadertypes/texture-types/texture-formats';
|
|
12
|
+
import {uid} from '../utils/uid';
|
|
13
|
+
import {withResolvers} from '../utils/promise-utils';
|
|
14
|
+
import {assertDefined} from '../utils/assert';
|
|
15
|
+
|
|
16
|
+
/** Properties for a CanvasContext */
|
|
17
|
+
export type CanvasContextProps = {
|
|
18
|
+
/** Identifier, for debugging */
|
|
19
|
+
id?: string;
|
|
20
|
+
/** If a canvas not supplied, one will be created and added to the DOM. If a string, a canvas with that id will be looked up in the DOM */
|
|
21
|
+
canvas?: HTMLCanvasElement | OffscreenCanvas | string | null;
|
|
22
|
+
/** If new canvas is created, it will be created in the specified container, otherwise is appended as a child of document.body */
|
|
23
|
+
container?: HTMLElement | string | null;
|
|
24
|
+
/** Width in pixels of the canvas - used when creating a new canvas */
|
|
25
|
+
width?: number;
|
|
26
|
+
/** Height in pixels of the canvas - used when creating a new canvas */
|
|
27
|
+
height?: number;
|
|
28
|
+
/** Visibility (only used if new canvas is created). */
|
|
29
|
+
visible?: boolean;
|
|
30
|
+
/** Whether to size the drawing buffer to the pixel size during auto resize. If a number is provided it is used as a static pixel ratio */
|
|
31
|
+
useDevicePixels?: boolean | number;
|
|
32
|
+
/** Whether to track window resizes. */
|
|
33
|
+
autoResize?: boolean;
|
|
34
|
+
/** @see https://developer.mozilla.org/en-US/docs/Web/API/GPUCanvasContext/configure#alphamode */
|
|
35
|
+
alphaMode?: 'opaque' | 'premultiplied';
|
|
36
|
+
/** @see https://developer.mozilla.org/en-US/docs/Web/API/GPUCanvasContext/configure#colorspace */
|
|
37
|
+
colorSpace?: 'srgb'; // GPUPredefinedColorSpace
|
|
38
|
+
/** Whether to track position changes. Calls this.device.onPositionChange */
|
|
39
|
+
trackPosition?: boolean;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export type MutableCanvasContextProps = {
|
|
43
|
+
/** Whether to size the drawing buffer to the pixel size during auto resize. If a number is provided it is used as a static pixel ratio */
|
|
44
|
+
useDevicePixels?: boolean | number;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Shared tracked-canvas lifecycle used by both renderable and presentation contexts.
|
|
49
|
+
* - Creates a new canvas or looks up a canvas from the DOM
|
|
50
|
+
* - Provides check for DOM loaded
|
|
51
|
+
* @todo commit() @see https://github.com/w3ctag/design-reviews/issues/288
|
|
52
|
+
* @todo transferControlToOffscreen: @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/transferControlToOffscreen
|
|
53
|
+
*/
|
|
54
|
+
export abstract class CanvasSurface {
|
|
55
|
+
static isHTMLCanvas(canvas: unknown): canvas is HTMLCanvasElement {
|
|
56
|
+
return typeof HTMLCanvasElement !== 'undefined' && canvas instanceof HTMLCanvasElement;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
static isOffscreenCanvas(canvas: unknown): canvas is OffscreenCanvas {
|
|
60
|
+
return typeof OffscreenCanvas !== 'undefined' && canvas instanceof OffscreenCanvas;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
static defaultProps: Required<CanvasContextProps> = {
|
|
64
|
+
id: undefined!,
|
|
65
|
+
canvas: null,
|
|
66
|
+
width: 800,
|
|
67
|
+
height: 600,
|
|
68
|
+
useDevicePixels: true,
|
|
69
|
+
autoResize: true,
|
|
70
|
+
container: null,
|
|
71
|
+
visible: true,
|
|
72
|
+
alphaMode: 'opaque',
|
|
73
|
+
colorSpace: 'srgb',
|
|
74
|
+
trackPosition: false
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
abstract readonly device: Device;
|
|
78
|
+
abstract readonly handle: unknown;
|
|
79
|
+
readonly id: string;
|
|
80
|
+
|
|
81
|
+
readonly props: Required<CanvasContextProps>;
|
|
82
|
+
readonly canvas: HTMLCanvasElement | OffscreenCanvas;
|
|
83
|
+
/** Handle to HTML canvas */
|
|
84
|
+
readonly htmlCanvas?: HTMLCanvasElement;
|
|
85
|
+
/** Handle to wrapped OffScreenCanvas */
|
|
86
|
+
readonly offscreenCanvas?: OffscreenCanvas;
|
|
87
|
+
readonly type: 'html-canvas' | 'offscreen-canvas' | 'node';
|
|
88
|
+
|
|
89
|
+
/** Promise that resolved once the resize observer has updated the pixel size */
|
|
90
|
+
initialized: Promise<void>;
|
|
91
|
+
isInitialized: boolean = false;
|
|
92
|
+
|
|
93
|
+
/** Visibility is automatically updated (via an IntersectionObserver) */
|
|
94
|
+
isVisible: boolean = true;
|
|
95
|
+
|
|
96
|
+
/** Width of canvas in CSS units (tracked by a ResizeObserver) */
|
|
97
|
+
cssWidth: number;
|
|
98
|
+
/** Height of canvas in CSS units (tracked by a ResizeObserver) */
|
|
99
|
+
cssHeight: number;
|
|
100
|
+
|
|
101
|
+
/** Device pixel ratio. Automatically updated via media queries */
|
|
102
|
+
devicePixelRatio: number;
|
|
103
|
+
/** Exact width of canvas in physical pixels (tracked by a ResizeObserver) */
|
|
104
|
+
devicePixelWidth: number;
|
|
105
|
+
/** Exact height of canvas in physical pixels (tracked by a ResizeObserver) */
|
|
106
|
+
devicePixelHeight: number;
|
|
107
|
+
|
|
108
|
+
/** Width of drawing buffer: automatically tracks this.pixelWidth if props.autoResize is true */
|
|
109
|
+
drawingBufferWidth: number;
|
|
110
|
+
/** Height of drawing buffer: automatically tracks this.pixelHeight if props.autoResize is true */
|
|
111
|
+
drawingBufferHeight: number;
|
|
112
|
+
|
|
113
|
+
/** Resolves when the canvas is initialized, i.e. when the ResizeObserver has updated the pixel size */
|
|
114
|
+
protected _initializedResolvers = withResolvers<void>();
|
|
115
|
+
protected _canvasObserver: CanvasObserver;
|
|
116
|
+
/** Position of the canvas in the document, updated by a timer */
|
|
117
|
+
protected _position: [number, number] = [0, 0];
|
|
118
|
+
/** Whether this canvas context has been destroyed */
|
|
119
|
+
protected destroyed = false;
|
|
120
|
+
/** Whether the drawing buffer size needs to be resized (deferred resizing to avoid flicker) */
|
|
121
|
+
protected _needsDrawingBufferResize: boolean = true;
|
|
122
|
+
|
|
123
|
+
abstract get [Symbol.toStringTag](): string;
|
|
124
|
+
|
|
125
|
+
toString(): string {
|
|
126
|
+
return `${this[Symbol.toStringTag]}(${this.id})`;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
constructor(props?: CanvasContextProps) {
|
|
130
|
+
this.props = {...CanvasSurface.defaultProps, ...props};
|
|
131
|
+
props = this.props;
|
|
132
|
+
|
|
133
|
+
this.initialized = this._initializedResolvers.promise;
|
|
134
|
+
|
|
135
|
+
if (!isBrowser()) {
|
|
136
|
+
this.canvas = {width: props.width || 1, height: props.height || 1} as OffscreenCanvas;
|
|
137
|
+
} else if (!props.canvas) {
|
|
138
|
+
this.canvas = createCanvasElement(props);
|
|
139
|
+
} else if (typeof props.canvas === 'string') {
|
|
140
|
+
this.canvas = getCanvasFromDOM(props.canvas);
|
|
141
|
+
} else {
|
|
142
|
+
this.canvas = props.canvas;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (CanvasSurface.isHTMLCanvas(this.canvas)) {
|
|
146
|
+
this.id = props.id || this.canvas.id;
|
|
147
|
+
this.type = 'html-canvas';
|
|
148
|
+
this.htmlCanvas = this.canvas;
|
|
149
|
+
} else if (CanvasSurface.isOffscreenCanvas(this.canvas)) {
|
|
150
|
+
this.id = props.id || 'offscreen-canvas';
|
|
151
|
+
this.type = 'offscreen-canvas';
|
|
152
|
+
this.offscreenCanvas = this.canvas;
|
|
153
|
+
} else {
|
|
154
|
+
this.id = props.id || 'node-canvas-context';
|
|
155
|
+
this.type = 'node';
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
this.cssWidth = this.htmlCanvas?.clientWidth || this.canvas.width;
|
|
159
|
+
this.cssHeight = this.htmlCanvas?.clientHeight || this.canvas.height;
|
|
160
|
+
this.devicePixelWidth = this.canvas.width;
|
|
161
|
+
this.devicePixelHeight = this.canvas.height;
|
|
162
|
+
this.drawingBufferWidth = this.canvas.width;
|
|
163
|
+
this.drawingBufferHeight = this.canvas.height;
|
|
164
|
+
this.devicePixelRatio = globalThis.devicePixelRatio || 1;
|
|
165
|
+
this._position = [0, 0];
|
|
166
|
+
this._canvasObserver = new CanvasObserver({
|
|
167
|
+
canvas: this.htmlCanvas,
|
|
168
|
+
trackPosition: this.props.trackPosition,
|
|
169
|
+
onResize: entries => this._handleResize(entries),
|
|
170
|
+
onIntersection: entries => this._handleIntersection(entries),
|
|
171
|
+
onDevicePixelRatioChange: () => this._observeDevicePixelRatio(),
|
|
172
|
+
onPositionChange: () => this.updatePosition()
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
destroy() {
|
|
177
|
+
if (!this.destroyed) {
|
|
178
|
+
this.destroyed = true;
|
|
179
|
+
this._stopObservers();
|
|
180
|
+
// @ts-expect-error Clear the device to make sure we don't access it after destruction.
|
|
181
|
+
this.device = null;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
setProps(props: MutableCanvasContextProps): this {
|
|
186
|
+
if ('useDevicePixels' in props) {
|
|
187
|
+
this.props.useDevicePixels = props.useDevicePixels || false;
|
|
188
|
+
this._updateDrawingBufferSize();
|
|
189
|
+
}
|
|
190
|
+
return this;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/** Returns a framebuffer with properly resized current 'swap chain' textures */
|
|
194
|
+
getCurrentFramebuffer(options?: {
|
|
195
|
+
depthStencilFormat?: TextureFormatDepthStencil | false;
|
|
196
|
+
}): Framebuffer {
|
|
197
|
+
this._resizeDrawingBufferIfNeeded();
|
|
198
|
+
return this._getCurrentFramebuffer(options);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
getCSSSize(): [number, number] {
|
|
202
|
+
return [this.cssWidth, this.cssHeight];
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
getPosition() {
|
|
206
|
+
return this._position;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
getDevicePixelSize(): [number, number] {
|
|
210
|
+
return [this.devicePixelWidth, this.devicePixelHeight];
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
getDrawingBufferSize(): [number, number] {
|
|
214
|
+
return [this.drawingBufferWidth, this.drawingBufferHeight];
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
getMaxDrawingBufferSize(): [number, number] {
|
|
218
|
+
const maxTextureDimension = this.device.limits.maxTextureDimension2D;
|
|
219
|
+
return [maxTextureDimension, maxTextureDimension];
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
setDrawingBufferSize(width: number, height: number) {
|
|
223
|
+
width = Math.floor(width);
|
|
224
|
+
height = Math.floor(height);
|
|
225
|
+
if (this.drawingBufferWidth === width && this.drawingBufferHeight === height) {
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
this.drawingBufferWidth = width;
|
|
229
|
+
this.drawingBufferHeight = height;
|
|
230
|
+
this._needsDrawingBufferResize = true;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
getDevicePixelRatio(): number {
|
|
234
|
+
const devicePixelRatio = typeof window !== 'undefined' && window.devicePixelRatio;
|
|
235
|
+
return devicePixelRatio || 1;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
cssToDevicePixels(
|
|
239
|
+
cssPixel: [number, number],
|
|
240
|
+
yInvert: boolean = true
|
|
241
|
+
): {
|
|
242
|
+
x: number;
|
|
243
|
+
y: number;
|
|
244
|
+
width: number;
|
|
245
|
+
height: number;
|
|
246
|
+
} {
|
|
247
|
+
const ratio = this.cssToDeviceRatio();
|
|
248
|
+
const [width, height] = this.getDrawingBufferSize();
|
|
249
|
+
return scalePixels(cssPixel, ratio, width, height, yInvert);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/** @deprecated - use .getDevicePixelSize() */
|
|
253
|
+
getPixelSize() {
|
|
254
|
+
return this.getDevicePixelSize();
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/** @deprecated Use the current drawing buffer size for projection setup. */
|
|
258
|
+
getAspect(): number {
|
|
259
|
+
const [width, height] = this.getDrawingBufferSize();
|
|
260
|
+
return width > 0 && height > 0 ? width / height : 1;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/** @deprecated Returns multiplier need to convert CSS size to Device size */
|
|
264
|
+
cssToDeviceRatio(): number {
|
|
265
|
+
try {
|
|
266
|
+
const [drawingBufferWidth] = this.getDrawingBufferSize();
|
|
267
|
+
const [cssWidth] = this.getCSSSize();
|
|
268
|
+
return cssWidth ? drawingBufferWidth / cssWidth : 1;
|
|
269
|
+
} catch {
|
|
270
|
+
return 1;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/** @deprecated Use canvasContext.setDrawingBufferSize() */
|
|
275
|
+
resize(size: {width: number; height: number}): void {
|
|
276
|
+
this.setDrawingBufferSize(size.width, size.height);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
protected abstract _configureDevice(): void;
|
|
280
|
+
|
|
281
|
+
protected abstract _getCurrentFramebuffer(options?: {
|
|
282
|
+
depthStencilFormat?: TextureFormatDepthStencil | false;
|
|
283
|
+
}): Framebuffer;
|
|
284
|
+
|
|
285
|
+
protected _setAutoCreatedCanvasId(id: string) {
|
|
286
|
+
if (this.htmlCanvas?.id === 'lumagl-auto-created-canvas') {
|
|
287
|
+
this.htmlCanvas.id = id;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Starts DOM observation after the derived context and its device are fully initialized.
|
|
293
|
+
*
|
|
294
|
+
* `CanvasSurface` construction runs before subclasses can assign `this.device`, and the
|
|
295
|
+
* default WebGL canvas context is created before `WebGLDevice` has initialized `limits`,
|
|
296
|
+
* `features`, and the rest of its runtime state. Deferring observer startup avoids early
|
|
297
|
+
* `ResizeObserver` and DPR callbacks running against a partially initialized device.
|
|
298
|
+
*/
|
|
299
|
+
_startObservers(): void {
|
|
300
|
+
if (this.destroyed) {
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
this._canvasObserver.start();
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Stops all DOM observation and timers associated with a canvas surface.
|
|
308
|
+
*
|
|
309
|
+
* This pairs with `_startObservers()` so teardown uses the same lifecycle whether a context is
|
|
310
|
+
* explicitly destroyed, abandoned during device reuse, or temporarily has not started observing
|
|
311
|
+
* yet. Centralizing shutdown here keeps resize/DPR/position watchers from surviving past the
|
|
312
|
+
* lifetime of the owning device.
|
|
313
|
+
*/
|
|
314
|
+
_stopObservers(): void {
|
|
315
|
+
this._canvasObserver.stop();
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
protected _handleIntersection(entries: IntersectionObserverEntry[]) {
|
|
319
|
+
if (this.destroyed) {
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
const entry = entries.find(entry_ => entry_.target === this.canvas);
|
|
324
|
+
if (!entry) {
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
const isVisible = entry.isIntersecting;
|
|
328
|
+
if (this.isVisible !== isVisible) {
|
|
329
|
+
this.isVisible = isVisible;
|
|
330
|
+
this.device.props.onVisibilityChange(this as CanvasContext | PresentationContext);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
protected _handleResize(entries: ResizeObserverEntry[]) {
|
|
335
|
+
if (this.destroyed) {
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
const entry = entries.find(entry_ => entry_.target === this.canvas);
|
|
340
|
+
if (!entry) {
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
const contentBoxSize = assertDefined(entry.contentBoxSize?.[0]);
|
|
345
|
+
this.cssWidth = contentBoxSize.inlineSize;
|
|
346
|
+
this.cssHeight = contentBoxSize.blockSize;
|
|
347
|
+
|
|
348
|
+
const oldPixelSize = this.getDevicePixelSize();
|
|
349
|
+
|
|
350
|
+
const devicePixelWidth =
|
|
351
|
+
entry.devicePixelContentBoxSize?.[0]?.inlineSize ||
|
|
352
|
+
contentBoxSize.inlineSize * devicePixelRatio;
|
|
353
|
+
|
|
354
|
+
const devicePixelHeight =
|
|
355
|
+
entry.devicePixelContentBoxSize?.[0]?.blockSize ||
|
|
356
|
+
contentBoxSize.blockSize * devicePixelRatio;
|
|
357
|
+
|
|
358
|
+
const [maxDevicePixelWidth, maxDevicePixelHeight] = this.getMaxDrawingBufferSize();
|
|
359
|
+
this.devicePixelWidth = Math.max(1, Math.min(devicePixelWidth, maxDevicePixelWidth));
|
|
360
|
+
this.devicePixelHeight = Math.max(1, Math.min(devicePixelHeight, maxDevicePixelHeight));
|
|
361
|
+
|
|
362
|
+
this._updateDrawingBufferSize();
|
|
363
|
+
|
|
364
|
+
this.device.props.onResize(this as CanvasContext | PresentationContext, {oldPixelSize});
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
protected _updateDrawingBufferSize() {
|
|
368
|
+
if (this.props.autoResize) {
|
|
369
|
+
if (typeof this.props.useDevicePixels === 'number') {
|
|
370
|
+
const devicePixelRatio = this.props.useDevicePixels;
|
|
371
|
+
this.setDrawingBufferSize(
|
|
372
|
+
this.cssWidth * devicePixelRatio,
|
|
373
|
+
this.cssHeight * devicePixelRatio
|
|
374
|
+
);
|
|
375
|
+
} else if (this.props.useDevicePixels) {
|
|
376
|
+
this.setDrawingBufferSize(this.devicePixelWidth, this.devicePixelHeight);
|
|
377
|
+
} else {
|
|
378
|
+
this.setDrawingBufferSize(this.cssWidth, this.cssHeight);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
this._initializedResolvers.resolve();
|
|
383
|
+
this.isInitialized = true;
|
|
384
|
+
|
|
385
|
+
this.updatePosition();
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
_resizeDrawingBufferIfNeeded() {
|
|
389
|
+
if (this._needsDrawingBufferResize) {
|
|
390
|
+
this._needsDrawingBufferResize = false;
|
|
391
|
+
const sizeChanged =
|
|
392
|
+
this.drawingBufferWidth !== this.canvas.width ||
|
|
393
|
+
this.drawingBufferHeight !== this.canvas.height;
|
|
394
|
+
if (sizeChanged) {
|
|
395
|
+
this.canvas.width = this.drawingBufferWidth;
|
|
396
|
+
this.canvas.height = this.drawingBufferHeight;
|
|
397
|
+
this._configureDevice();
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
_observeDevicePixelRatio() {
|
|
403
|
+
if (this.destroyed || !this._canvasObserver.started) {
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
const oldRatio = this.devicePixelRatio;
|
|
407
|
+
this.devicePixelRatio = window.devicePixelRatio;
|
|
408
|
+
|
|
409
|
+
this.updatePosition();
|
|
410
|
+
|
|
411
|
+
this.device.props.onDevicePixelRatioChange?.(this as CanvasContext | PresentationContext, {
|
|
412
|
+
oldRatio
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
updatePosition() {
|
|
417
|
+
if (this.destroyed) {
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
const newRect = this.htmlCanvas?.getBoundingClientRect();
|
|
421
|
+
if (newRect) {
|
|
422
|
+
const position: [number, number] = [newRect.left, newRect.top];
|
|
423
|
+
this._position ??= position;
|
|
424
|
+
const positionChanged =
|
|
425
|
+
position[0] !== this._position[0] || position[1] !== this._position[1];
|
|
426
|
+
if (positionChanged) {
|
|
427
|
+
const oldPosition = this._position;
|
|
428
|
+
this._position = position;
|
|
429
|
+
this.device.props.onPositionChange?.(this as CanvasContext | PresentationContext, {
|
|
430
|
+
oldPosition
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
function getContainer(container: HTMLElement | string | null): HTMLElement {
|
|
438
|
+
if (typeof container === 'string') {
|
|
439
|
+
const element = document.getElementById(container);
|
|
440
|
+
if (!element) {
|
|
441
|
+
throw new Error(`${container} is not an HTML element`);
|
|
442
|
+
}
|
|
443
|
+
return element;
|
|
444
|
+
}
|
|
445
|
+
if (container) {
|
|
446
|
+
return container;
|
|
447
|
+
}
|
|
448
|
+
return document.body;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
function getCanvasFromDOM(canvasId: string): HTMLCanvasElement {
|
|
452
|
+
const canvas = document.getElementById(canvasId);
|
|
453
|
+
if (!CanvasSurface.isHTMLCanvas(canvas)) {
|
|
454
|
+
throw new Error('Object is not a canvas element');
|
|
455
|
+
}
|
|
456
|
+
return canvas;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
function createCanvasElement(props: CanvasContextProps) {
|
|
460
|
+
const {width, height} = props;
|
|
461
|
+
const newCanvas = document.createElement('canvas');
|
|
462
|
+
newCanvas.id = uid('lumagl-auto-created-canvas');
|
|
463
|
+
newCanvas.width = width || 1;
|
|
464
|
+
newCanvas.height = height || 1;
|
|
465
|
+
newCanvas.style.width = Number.isFinite(width) ? `${width}px` : '100%';
|
|
466
|
+
newCanvas.style.height = Number.isFinite(height) ? `${height}px` : '100%';
|
|
467
|
+
if (!props?.visible) {
|
|
468
|
+
newCanvas.style.visibility = 'hidden';
|
|
469
|
+
}
|
|
470
|
+
const container = getContainer(props?.container || null);
|
|
471
|
+
container.insertBefore(newCanvas, container.firstChild);
|
|
472
|
+
|
|
473
|
+
return newCanvas;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
function scalePixels(
|
|
477
|
+
pixel: [number, number],
|
|
478
|
+
ratio: number,
|
|
479
|
+
width: number,
|
|
480
|
+
height: number,
|
|
481
|
+
yInvert: boolean
|
|
482
|
+
): {
|
|
483
|
+
x: number;
|
|
484
|
+
y: number;
|
|
485
|
+
width: number;
|
|
486
|
+
height: number;
|
|
487
|
+
} {
|
|
488
|
+
const point = pixel;
|
|
489
|
+
|
|
490
|
+
const x = scaleX(point[0], ratio, width);
|
|
491
|
+
let y = scaleY(point[1], ratio, height, yInvert);
|
|
492
|
+
|
|
493
|
+
let temporary = scaleX(point[0] + 1, ratio, width);
|
|
494
|
+
const xHigh = temporary === width - 1 ? temporary : temporary - 1;
|
|
495
|
+
|
|
496
|
+
temporary = scaleY(point[1] + 1, ratio, height, yInvert);
|
|
497
|
+
let yHigh;
|
|
498
|
+
if (yInvert) {
|
|
499
|
+
temporary = temporary === 0 ? temporary : temporary + 1;
|
|
500
|
+
yHigh = y;
|
|
501
|
+
y = temporary;
|
|
502
|
+
} else {
|
|
503
|
+
yHigh = temporary === height - 1 ? temporary : temporary - 1;
|
|
504
|
+
}
|
|
505
|
+
return {
|
|
506
|
+
x,
|
|
507
|
+
y,
|
|
508
|
+
width: Math.max(xHigh - x + 1, 1),
|
|
509
|
+
height: Math.max(yHigh - y + 1, 1)
|
|
510
|
+
};
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
function scaleX(x: number, ratio: number, width: number): number {
|
|
514
|
+
return Math.min(Math.round(x * ratio), width - 1);
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
function scaleY(y: number, ratio: number, height: number, yInvert: boolean): number {
|
|
518
|
+
return yInvert
|
|
519
|
+
? Math.max(0, height - 1 - Math.round(y * ratio))
|
|
520
|
+
: Math.min(Math.round(y * ratio), height - 1);
|
|
521
|
+
}
|