@luma.gl/core 9.2.6 → 9.3.0-alpha.11
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 +193 -11
- package/dist/adapter/device.js.map +1 -1
- package/dist/adapter/luma.d.ts.map +1 -1
- package/dist/adapter/luma.js +2 -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 +1 -1
- package/dist/adapter/resources/buffer.d.ts.map +1 -1
- package/dist/adapter/resources/buffer.js +14 -6
- 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 +2734 -644
- 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 +88 -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 +2447 -534
- 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 +4 -3
- 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 +110 -38
- 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 +12 -11
- 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 +144 -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 +311 -25
- package/src/adapter/luma.ts +1 -0
- package/src/adapter/presentation-context.ts +16 -0
- package/src/adapter/resources/buffer.ts +13 -5
- 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 +157 -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 +4 -3
- 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 +167 -46
- package/src/shadertypes/{textures → texture-types}/texture-format-generics.ts +42 -48
- package/src/shadertypes/{textures → texture-types}/texture-format-table.ts +12 -11
- 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 +175 -0
- package/src/shadertypes/vertex-types/vertex-formats.ts +196 -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
package/dist/index.cjs
CHANGED
|
@@ -36,45 +36,75 @@ __export(dist_exports, {
|
|
|
36
36
|
DeviceFeatures: () => DeviceFeatures,
|
|
37
37
|
DeviceLimits: () => DeviceLimits,
|
|
38
38
|
ExternalTexture: () => ExternalTexture,
|
|
39
|
+
Fence: () => Fence,
|
|
39
40
|
Framebuffer: () => Framebuffer,
|
|
41
|
+
PipelineFactory: () => PipelineFactory,
|
|
40
42
|
PipelineLayout: () => PipelineLayout,
|
|
43
|
+
PresentationContext: () => PresentationContext,
|
|
41
44
|
QuerySet: () => QuerySet,
|
|
42
45
|
RenderPass: () => RenderPass,
|
|
43
46
|
RenderPipeline: () => RenderPipeline,
|
|
44
47
|
Resource: () => Resource,
|
|
45
48
|
Sampler: () => Sampler,
|
|
46
49
|
Shader: () => Shader,
|
|
50
|
+
ShaderBlockWriter: () => ShaderBlockWriter,
|
|
51
|
+
ShaderFactory: () => ShaderFactory,
|
|
52
|
+
SharedRenderPipeline: () => SharedRenderPipeline,
|
|
47
53
|
Texture: () => Texture,
|
|
48
|
-
TextureFormatDecoder: () => TextureFormatDecoder,
|
|
49
54
|
TextureView: () => TextureView,
|
|
50
55
|
TransformFeedback: () => TransformFeedback,
|
|
51
56
|
UniformBlock: () => UniformBlock,
|
|
52
|
-
UniformBufferLayout: () => UniformBufferLayout,
|
|
53
57
|
UniformStore: () => UniformStore,
|
|
54
58
|
VertexArray: () => VertexArray,
|
|
59
|
+
_getDefaultBindGroupFactory: () => _getDefaultBindGroupFactory,
|
|
55
60
|
_getTextureFormatDefinition: () => getTextureFormatDefinition,
|
|
56
61
|
_getTextureFormatTable: () => getTextureFormatTable,
|
|
62
|
+
assert: () => assert,
|
|
63
|
+
assertDefined: () => assertDefined,
|
|
64
|
+
dataTypeDecoder: () => dataTypeDecoder,
|
|
65
|
+
flattenBindingsByGroup: () => flattenBindingsByGroup,
|
|
57
66
|
getAttributeInfosFromLayouts: () => getAttributeInfosFromLayouts,
|
|
58
67
|
getAttributeShaderTypeInfo: () => getAttributeShaderTypeInfo,
|
|
59
|
-
|
|
60
|
-
getDataTypeInfo: () => getDataTypeInfo,
|
|
61
|
-
getNormalizedDataType: () => getNormalizedDataType,
|
|
68
|
+
getExternalImageSize: () => getExternalImageSize,
|
|
62
69
|
getScratchArray: () => getScratchArray,
|
|
70
|
+
getShaderLayoutBinding: () => getShaderLayoutBinding,
|
|
71
|
+
getTextureImageView: () => getTextureImageView,
|
|
63
72
|
getTypedArrayConstructor: () => getTypedArrayConstructor,
|
|
64
73
|
getVariableShaderTypeInfo: () => getVariableShaderTypeInfo,
|
|
65
|
-
|
|
66
|
-
getVertexFormatInfo: () => getVertexFormatInfo,
|
|
74
|
+
isExternalImage: () => isExternalImage,
|
|
67
75
|
log: () => log,
|
|
68
76
|
luma: () => luma,
|
|
69
|
-
|
|
77
|
+
makeShaderBlockLayout: () => makeShaderBlockLayout,
|
|
78
|
+
normalizeBindingsByGroup: () => normalizeBindingsByGroup,
|
|
70
79
|
readPixel: () => readPixel,
|
|
80
|
+
setTextureImageData: () => setTextureImageData,
|
|
81
|
+
shaderTypeDecoder: () => shaderTypeDecoder,
|
|
71
82
|
textureFormatDecoder: () => textureFormatDecoder,
|
|
83
|
+
vertexFormatDecoder: () => vertexFormatDecoder,
|
|
72
84
|
writePixel: () => writePixel
|
|
73
85
|
});
|
|
74
86
|
module.exports = __toCommonJS(dist_exports);
|
|
75
87
|
|
|
76
88
|
// dist/utils/stats-manager.js
|
|
77
89
|
var import_stats = require("@probe.gl/stats");
|
|
90
|
+
var GPU_TIME_AND_MEMORY_STATS = "GPU Time and Memory";
|
|
91
|
+
var GPU_TIME_AND_MEMORY_STAT_ORDER = [
|
|
92
|
+
"Adapter",
|
|
93
|
+
"GPU",
|
|
94
|
+
"GPU Type",
|
|
95
|
+
"GPU Backend",
|
|
96
|
+
"Frame Rate",
|
|
97
|
+
"CPU Time",
|
|
98
|
+
"GPU Time",
|
|
99
|
+
"GPU Memory",
|
|
100
|
+
"Buffer Memory",
|
|
101
|
+
"Texture Memory",
|
|
102
|
+
"Referenced Buffer Memory",
|
|
103
|
+
"Referenced Texture Memory",
|
|
104
|
+
"Swap Chain Texture"
|
|
105
|
+
];
|
|
106
|
+
var ORDERED_STATS_CACHE = /* @__PURE__ */ new WeakMap();
|
|
107
|
+
var ORDERED_STAT_NAME_SET_CACHE = /* @__PURE__ */ new WeakMap();
|
|
78
108
|
var StatsManager = class {
|
|
79
109
|
stats = /* @__PURE__ */ new Map();
|
|
80
110
|
getStats(name2) {
|
|
@@ -84,10 +114,50 @@ var StatsManager = class {
|
|
|
84
114
|
if (!this.stats.has(name2)) {
|
|
85
115
|
this.stats.set(name2, new import_stats.Stats({ id: name2 }));
|
|
86
116
|
}
|
|
87
|
-
|
|
117
|
+
const stats = this.stats.get(name2);
|
|
118
|
+
if (name2 === GPU_TIME_AND_MEMORY_STATS) {
|
|
119
|
+
initializeStats(stats, GPU_TIME_AND_MEMORY_STAT_ORDER);
|
|
120
|
+
}
|
|
121
|
+
return stats;
|
|
88
122
|
}
|
|
89
123
|
};
|
|
90
124
|
var lumaStats = new StatsManager();
|
|
125
|
+
function initializeStats(stats, orderedStatNames) {
|
|
126
|
+
const statsMap = stats.stats;
|
|
127
|
+
let addedOrderedStat = false;
|
|
128
|
+
for (const statName of orderedStatNames) {
|
|
129
|
+
if (!statsMap[statName]) {
|
|
130
|
+
stats.get(statName);
|
|
131
|
+
addedOrderedStat = true;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
const statCount = Object.keys(statsMap).length;
|
|
135
|
+
const cachedStats = ORDERED_STATS_CACHE.get(stats);
|
|
136
|
+
if (!addedOrderedStat && (cachedStats == null ? void 0 : cachedStats.orderedStatNames) === orderedStatNames && cachedStats.statCount === statCount) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
const reorderedStats = {};
|
|
140
|
+
let orderedStatNamesSet = ORDERED_STAT_NAME_SET_CACHE.get(orderedStatNames);
|
|
141
|
+
if (!orderedStatNamesSet) {
|
|
142
|
+
orderedStatNamesSet = new Set(orderedStatNames);
|
|
143
|
+
ORDERED_STAT_NAME_SET_CACHE.set(orderedStatNames, orderedStatNamesSet);
|
|
144
|
+
}
|
|
145
|
+
for (const statName of orderedStatNames) {
|
|
146
|
+
if (statsMap[statName]) {
|
|
147
|
+
reorderedStats[statName] = statsMap[statName];
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
for (const [statName, stat] of Object.entries(statsMap)) {
|
|
151
|
+
if (!orderedStatNamesSet.has(statName)) {
|
|
152
|
+
reorderedStats[statName] = stat;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
for (const statName of Object.keys(statsMap)) {
|
|
156
|
+
delete statsMap[statName];
|
|
157
|
+
}
|
|
158
|
+
Object.assign(statsMap, reorderedStats);
|
|
159
|
+
ORDERED_STATS_CACHE.set(stats, { orderedStatNames, statCount });
|
|
160
|
+
}
|
|
91
161
|
|
|
92
162
|
// dist/utils/log.js
|
|
93
163
|
var import_log = require("@probe.gl/log");
|
|
@@ -102,19 +172,75 @@ function uid(id = "id") {
|
|
|
102
172
|
}
|
|
103
173
|
|
|
104
174
|
// dist/adapter/resources/resource.js
|
|
175
|
+
var CPU_HOTSPOT_PROFILER_MODULE = "cpu-hotspot-profiler";
|
|
176
|
+
var RESOURCE_COUNTS_STATS = "GPU Resource Counts";
|
|
177
|
+
var LEGACY_RESOURCE_COUNTS_STATS = "Resource Counts";
|
|
178
|
+
var GPU_TIME_AND_MEMORY_STATS2 = "GPU Time and Memory";
|
|
179
|
+
var BASE_RESOURCE_COUNT_ORDER = [
|
|
180
|
+
"Resources",
|
|
181
|
+
"Buffers",
|
|
182
|
+
"Textures",
|
|
183
|
+
"Samplers",
|
|
184
|
+
"TextureViews",
|
|
185
|
+
"Framebuffers",
|
|
186
|
+
"QuerySets",
|
|
187
|
+
"Shaders",
|
|
188
|
+
"RenderPipelines",
|
|
189
|
+
"ComputePipelines",
|
|
190
|
+
"PipelineLayouts",
|
|
191
|
+
"VertexArrays",
|
|
192
|
+
"RenderPasss",
|
|
193
|
+
"ComputePasss",
|
|
194
|
+
"CommandEncoders",
|
|
195
|
+
"CommandBuffers"
|
|
196
|
+
];
|
|
197
|
+
var WEBGL_RESOURCE_COUNT_ORDER = [
|
|
198
|
+
"Resources",
|
|
199
|
+
"Buffers",
|
|
200
|
+
"Textures",
|
|
201
|
+
"Samplers",
|
|
202
|
+
"TextureViews",
|
|
203
|
+
"Framebuffers",
|
|
204
|
+
"QuerySets",
|
|
205
|
+
"Shaders",
|
|
206
|
+
"RenderPipelines",
|
|
207
|
+
"SharedRenderPipelines",
|
|
208
|
+
"ComputePipelines",
|
|
209
|
+
"PipelineLayouts",
|
|
210
|
+
"VertexArrays",
|
|
211
|
+
"RenderPasss",
|
|
212
|
+
"ComputePasss",
|
|
213
|
+
"CommandEncoders",
|
|
214
|
+
"CommandBuffers"
|
|
215
|
+
];
|
|
216
|
+
var BASE_RESOURCE_COUNT_STAT_ORDER = BASE_RESOURCE_COUNT_ORDER.flatMap((resourceType) => [
|
|
217
|
+
`${resourceType} Created`,
|
|
218
|
+
`${resourceType} Active`
|
|
219
|
+
]);
|
|
220
|
+
var WEBGL_RESOURCE_COUNT_STAT_ORDER = WEBGL_RESOURCE_COUNT_ORDER.flatMap((resourceType) => [
|
|
221
|
+
`${resourceType} Created`,
|
|
222
|
+
`${resourceType} Active`
|
|
223
|
+
]);
|
|
224
|
+
var ORDERED_STATS_CACHE2 = /* @__PURE__ */ new WeakMap();
|
|
225
|
+
var ORDERED_STAT_NAME_SET_CACHE2 = /* @__PURE__ */ new WeakMap();
|
|
105
226
|
var Resource = class {
|
|
106
227
|
toString() {
|
|
107
228
|
return `${this[Symbol.toStringTag] || this.constructor.name}:"${this.id}"`;
|
|
108
229
|
}
|
|
109
230
|
/** props.id, for debugging. */
|
|
110
231
|
id;
|
|
232
|
+
/** The props that this resource was created with */
|
|
111
233
|
props;
|
|
234
|
+
/** User data object, reserved for the application */
|
|
112
235
|
userData = {};
|
|
236
|
+
/** The device that this resource is associated with - TODO can we remove this dup? */
|
|
113
237
|
_device;
|
|
114
238
|
/** Whether this resource has been destroyed */
|
|
115
239
|
destroyed = false;
|
|
116
240
|
/** For resources that allocate GPU memory */
|
|
117
241
|
allocatedBytes = 0;
|
|
242
|
+
/** Stats bucket currently holding the tracked allocation */
|
|
243
|
+
allocatedBytesName = null;
|
|
118
244
|
/** Attached resources will be destroyed when this resource is destroyed. Tracks auto-created "sub" resources. */
|
|
119
245
|
_attachedResources = /* @__PURE__ */ new Set();
|
|
120
246
|
/**
|
|
@@ -136,6 +262,9 @@ var Resource = class {
|
|
|
136
262
|
* destroy can be called on any resource to release it before it is garbage collected.
|
|
137
263
|
*/
|
|
138
264
|
destroy() {
|
|
265
|
+
if (this.destroyed) {
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
139
268
|
this.destroyResource();
|
|
140
269
|
}
|
|
141
270
|
/** @deprecated Use destroy() */
|
|
@@ -174,7 +303,7 @@ var Resource = class {
|
|
|
174
303
|
}
|
|
175
304
|
/** Destroy all owned resources. Make sure the resources are no longer needed before calling. */
|
|
176
305
|
destroyAttachedResources() {
|
|
177
|
-
for (const resource of
|
|
306
|
+
for (const resource of this._attachedResources) {
|
|
178
307
|
resource.destroy();
|
|
179
308
|
}
|
|
180
309
|
this._attachedResources = /* @__PURE__ */ new Set();
|
|
@@ -182,37 +311,107 @@ var Resource = class {
|
|
|
182
311
|
// PROTECTED METHODS
|
|
183
312
|
/** Perform all destroy steps. Can be called by derived resources when overriding destroy() */
|
|
184
313
|
destroyResource() {
|
|
314
|
+
if (this.destroyed) {
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
185
317
|
this.destroyAttachedResources();
|
|
186
318
|
this.removeStats();
|
|
187
319
|
this.destroyed = true;
|
|
188
320
|
}
|
|
189
321
|
/** Called by .destroy() to track object destruction. Subclass must call if overriding destroy() */
|
|
190
322
|
removeStats() {
|
|
191
|
-
const
|
|
192
|
-
const
|
|
193
|
-
|
|
323
|
+
const profiler = getCpuHotspotProfiler(this._device);
|
|
324
|
+
const startTime = profiler ? getTimestamp() : 0;
|
|
325
|
+
const statsObjects = [
|
|
326
|
+
this._device.statsManager.getStats(RESOURCE_COUNTS_STATS),
|
|
327
|
+
this._device.statsManager.getStats(LEGACY_RESOURCE_COUNTS_STATS)
|
|
328
|
+
];
|
|
329
|
+
const orderedStatNames = getResourceCountStatOrder(this._device);
|
|
330
|
+
for (const stats of statsObjects) {
|
|
331
|
+
initializeStats2(stats, orderedStatNames);
|
|
332
|
+
}
|
|
333
|
+
const name2 = this.getStatsName();
|
|
334
|
+
for (const stats of statsObjects) {
|
|
335
|
+
stats.get("Resources Active").decrementCount();
|
|
336
|
+
stats.get(`${name2}s Active`).decrementCount();
|
|
337
|
+
}
|
|
338
|
+
if (profiler) {
|
|
339
|
+
profiler.statsBookkeepingCalls = (profiler.statsBookkeepingCalls || 0) + 1;
|
|
340
|
+
profiler.statsBookkeepingTimeMs = (profiler.statsBookkeepingTimeMs || 0) + (getTimestamp() - startTime);
|
|
341
|
+
}
|
|
194
342
|
}
|
|
195
343
|
/** Called by subclass to track memory allocations */
|
|
196
|
-
trackAllocatedMemory(bytes, name2 = this
|
|
197
|
-
const
|
|
344
|
+
trackAllocatedMemory(bytes, name2 = this.getStatsName()) {
|
|
345
|
+
const profiler = getCpuHotspotProfiler(this._device);
|
|
346
|
+
const startTime = profiler ? getTimestamp() : 0;
|
|
347
|
+
const stats = this._device.statsManager.getStats(GPU_TIME_AND_MEMORY_STATS2);
|
|
348
|
+
if (this.allocatedBytes > 0 && this.allocatedBytesName) {
|
|
349
|
+
stats.get("GPU Memory").subtractCount(this.allocatedBytes);
|
|
350
|
+
stats.get(`${this.allocatedBytesName} Memory`).subtractCount(this.allocatedBytes);
|
|
351
|
+
}
|
|
198
352
|
stats.get("GPU Memory").addCount(bytes);
|
|
199
353
|
stats.get(`${name2} Memory`).addCount(bytes);
|
|
354
|
+
if (profiler) {
|
|
355
|
+
profiler.statsBookkeepingCalls = (profiler.statsBookkeepingCalls || 0) + 1;
|
|
356
|
+
profiler.statsBookkeepingTimeMs = (profiler.statsBookkeepingTimeMs || 0) + (getTimestamp() - startTime);
|
|
357
|
+
}
|
|
200
358
|
this.allocatedBytes = bytes;
|
|
359
|
+
this.allocatedBytesName = name2;
|
|
360
|
+
}
|
|
361
|
+
/** Called by subclass to track handle-backed memory allocations separately from owned allocations */
|
|
362
|
+
trackReferencedMemory(bytes, name2 = this.getStatsName()) {
|
|
363
|
+
this.trackAllocatedMemory(bytes, `Referenced ${name2}`);
|
|
201
364
|
}
|
|
202
365
|
/** Called by subclass to track memory deallocations */
|
|
203
|
-
trackDeallocatedMemory(name2 = this
|
|
204
|
-
|
|
366
|
+
trackDeallocatedMemory(name2 = this.getStatsName()) {
|
|
367
|
+
if (this.allocatedBytes === 0) {
|
|
368
|
+
this.allocatedBytesName = null;
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
const profiler = getCpuHotspotProfiler(this._device);
|
|
372
|
+
const startTime = profiler ? getTimestamp() : 0;
|
|
373
|
+
const stats = this._device.statsManager.getStats(GPU_TIME_AND_MEMORY_STATS2);
|
|
205
374
|
stats.get("GPU Memory").subtractCount(this.allocatedBytes);
|
|
206
|
-
stats.get(`${name2} Memory`).subtractCount(this.allocatedBytes);
|
|
375
|
+
stats.get(`${this.allocatedBytesName || name2} Memory`).subtractCount(this.allocatedBytes);
|
|
376
|
+
if (profiler) {
|
|
377
|
+
profiler.statsBookkeepingCalls = (profiler.statsBookkeepingCalls || 0) + 1;
|
|
378
|
+
profiler.statsBookkeepingTimeMs = (profiler.statsBookkeepingTimeMs || 0) + (getTimestamp() - startTime);
|
|
379
|
+
}
|
|
207
380
|
this.allocatedBytes = 0;
|
|
381
|
+
this.allocatedBytesName = null;
|
|
382
|
+
}
|
|
383
|
+
/** Called by subclass to deallocate handle-backed memory tracked via trackReferencedMemory() */
|
|
384
|
+
trackDeallocatedReferencedMemory(name2 = this.getStatsName()) {
|
|
385
|
+
this.trackDeallocatedMemory(`Referenced ${name2}`);
|
|
208
386
|
}
|
|
209
387
|
/** Called by resource constructor to track object creation */
|
|
210
388
|
addStats() {
|
|
211
|
-
const
|
|
212
|
-
const
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
389
|
+
const name2 = this.getStatsName();
|
|
390
|
+
const profiler = getCpuHotspotProfiler(this._device);
|
|
391
|
+
const startTime = profiler ? getTimestamp() : 0;
|
|
392
|
+
const statsObjects = [
|
|
393
|
+
this._device.statsManager.getStats(RESOURCE_COUNTS_STATS),
|
|
394
|
+
this._device.statsManager.getStats(LEGACY_RESOURCE_COUNTS_STATS)
|
|
395
|
+
];
|
|
396
|
+
const orderedStatNames = getResourceCountStatOrder(this._device);
|
|
397
|
+
for (const stats of statsObjects) {
|
|
398
|
+
initializeStats2(stats, orderedStatNames);
|
|
399
|
+
}
|
|
400
|
+
for (const stats of statsObjects) {
|
|
401
|
+
stats.get("Resources Created").incrementCount();
|
|
402
|
+
stats.get("Resources Active").incrementCount();
|
|
403
|
+
stats.get(`${name2}s Created`).incrementCount();
|
|
404
|
+
stats.get(`${name2}s Active`).incrementCount();
|
|
405
|
+
}
|
|
406
|
+
if (profiler) {
|
|
407
|
+
profiler.statsBookkeepingCalls = (profiler.statsBookkeepingCalls || 0) + 1;
|
|
408
|
+
profiler.statsBookkeepingTimeMs = (profiler.statsBookkeepingTimeMs || 0) + (getTimestamp() - startTime);
|
|
409
|
+
}
|
|
410
|
+
recordTransientCanvasResourceCreate(this._device, name2);
|
|
411
|
+
}
|
|
412
|
+
/** Canonical resource name used for stats buckets. */
|
|
413
|
+
getStatsName() {
|
|
414
|
+
return getCanonicalResourceName(this);
|
|
216
415
|
}
|
|
217
416
|
};
|
|
218
417
|
/** Default properties for resource */
|
|
@@ -230,6 +429,97 @@ function selectivelyMerge(props, defaultProps) {
|
|
|
230
429
|
}
|
|
231
430
|
return mergedProps;
|
|
232
431
|
}
|
|
432
|
+
function initializeStats2(stats, orderedStatNames) {
|
|
433
|
+
const statsMap = stats.stats;
|
|
434
|
+
let addedOrderedStat = false;
|
|
435
|
+
for (const statName of orderedStatNames) {
|
|
436
|
+
if (!statsMap[statName]) {
|
|
437
|
+
stats.get(statName);
|
|
438
|
+
addedOrderedStat = true;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
const statCount = Object.keys(statsMap).length;
|
|
442
|
+
const cachedStats = ORDERED_STATS_CACHE2.get(stats);
|
|
443
|
+
if (!addedOrderedStat && (cachedStats == null ? void 0 : cachedStats.orderedStatNames) === orderedStatNames && cachedStats.statCount === statCount) {
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
const reorderedStats = {};
|
|
447
|
+
let orderedStatNamesSet = ORDERED_STAT_NAME_SET_CACHE2.get(orderedStatNames);
|
|
448
|
+
if (!orderedStatNamesSet) {
|
|
449
|
+
orderedStatNamesSet = new Set(orderedStatNames);
|
|
450
|
+
ORDERED_STAT_NAME_SET_CACHE2.set(orderedStatNames, orderedStatNamesSet);
|
|
451
|
+
}
|
|
452
|
+
for (const statName of orderedStatNames) {
|
|
453
|
+
if (statsMap[statName]) {
|
|
454
|
+
reorderedStats[statName] = statsMap[statName];
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
for (const [statName, stat] of Object.entries(statsMap)) {
|
|
458
|
+
if (!orderedStatNamesSet.has(statName)) {
|
|
459
|
+
reorderedStats[statName] = stat;
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
for (const statName of Object.keys(statsMap)) {
|
|
463
|
+
delete statsMap[statName];
|
|
464
|
+
}
|
|
465
|
+
Object.assign(statsMap, reorderedStats);
|
|
466
|
+
ORDERED_STATS_CACHE2.set(stats, { orderedStatNames, statCount });
|
|
467
|
+
}
|
|
468
|
+
function getResourceCountStatOrder(device) {
|
|
469
|
+
return device.type === "webgl" ? WEBGL_RESOURCE_COUNT_STAT_ORDER : BASE_RESOURCE_COUNT_STAT_ORDER;
|
|
470
|
+
}
|
|
471
|
+
function getCpuHotspotProfiler(device) {
|
|
472
|
+
const profiler = device.userData[CPU_HOTSPOT_PROFILER_MODULE];
|
|
473
|
+
return (profiler == null ? void 0 : profiler.enabled) ? profiler : null;
|
|
474
|
+
}
|
|
475
|
+
function getTimestamp() {
|
|
476
|
+
var _a, _b;
|
|
477
|
+
return ((_b = (_a = globalThis.performance) == null ? void 0 : _a.now) == null ? void 0 : _b.call(_a)) ?? Date.now();
|
|
478
|
+
}
|
|
479
|
+
function recordTransientCanvasResourceCreate(device, name2) {
|
|
480
|
+
const profiler = getCpuHotspotProfiler(device);
|
|
481
|
+
if (!profiler || !profiler.activeDefaultFramebufferAcquireDepth) {
|
|
482
|
+
return;
|
|
483
|
+
}
|
|
484
|
+
profiler.transientCanvasResourceCreates = (profiler.transientCanvasResourceCreates || 0) + 1;
|
|
485
|
+
switch (name2) {
|
|
486
|
+
case "Texture":
|
|
487
|
+
profiler.transientCanvasTextureCreates = (profiler.transientCanvasTextureCreates || 0) + 1;
|
|
488
|
+
break;
|
|
489
|
+
case "TextureView":
|
|
490
|
+
profiler.transientCanvasTextureViewCreates = (profiler.transientCanvasTextureViewCreates || 0) + 1;
|
|
491
|
+
break;
|
|
492
|
+
case "Sampler":
|
|
493
|
+
profiler.transientCanvasSamplerCreates = (profiler.transientCanvasSamplerCreates || 0) + 1;
|
|
494
|
+
break;
|
|
495
|
+
case "Framebuffer":
|
|
496
|
+
profiler.transientCanvasFramebufferCreates = (profiler.transientCanvasFramebufferCreates || 0) + 1;
|
|
497
|
+
break;
|
|
498
|
+
default:
|
|
499
|
+
break;
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
function getCanonicalResourceName(resource) {
|
|
503
|
+
let prototype = Object.getPrototypeOf(resource);
|
|
504
|
+
while (prototype) {
|
|
505
|
+
const parentPrototype = Object.getPrototypeOf(prototype);
|
|
506
|
+
if (!parentPrototype || parentPrototype === Resource.prototype) {
|
|
507
|
+
return getPrototypeToStringTag(prototype) || resource[Symbol.toStringTag] || resource.constructor.name;
|
|
508
|
+
}
|
|
509
|
+
prototype = parentPrototype;
|
|
510
|
+
}
|
|
511
|
+
return resource[Symbol.toStringTag] || resource.constructor.name;
|
|
512
|
+
}
|
|
513
|
+
function getPrototypeToStringTag(prototype) {
|
|
514
|
+
const descriptor = Object.getOwnPropertyDescriptor(prototype, Symbol.toStringTag);
|
|
515
|
+
if (typeof (descriptor == null ? void 0 : descriptor.get) === "function") {
|
|
516
|
+
return descriptor.get.call(prototype);
|
|
517
|
+
}
|
|
518
|
+
if (typeof (descriptor == null ? void 0 : descriptor.value) === "string") {
|
|
519
|
+
return descriptor.value;
|
|
520
|
+
}
|
|
521
|
+
return null;
|
|
522
|
+
}
|
|
233
523
|
|
|
234
524
|
// dist/adapter/resources/buffer.js
|
|
235
525
|
var _Buffer = class extends Resource {
|
|
@@ -269,15 +559,23 @@ var _Buffer = class extends Resource {
|
|
|
269
559
|
/** A partial CPU-side copy of the data in this buffer, for debugging purposes */
|
|
270
560
|
debugData = new ArrayBuffer(0);
|
|
271
561
|
/** This doesn't handle partial non-zero offset updates correctly */
|
|
272
|
-
_setDebugData(data,
|
|
273
|
-
|
|
562
|
+
_setDebugData(data, _byteOffset, byteLength) {
|
|
563
|
+
let arrayBufferView = null;
|
|
564
|
+
let arrayBuffer2;
|
|
565
|
+
if (ArrayBuffer.isView(data)) {
|
|
566
|
+
arrayBufferView = data;
|
|
567
|
+
arrayBuffer2 = data.buffer;
|
|
568
|
+
} else {
|
|
569
|
+
arrayBuffer2 = data;
|
|
570
|
+
}
|
|
274
571
|
const debugDataLength = Math.min(data ? data.byteLength : byteLength, _Buffer.DEBUG_DATA_MAX_LENGTH);
|
|
275
572
|
if (arrayBuffer2 === null) {
|
|
276
573
|
this.debugData = new ArrayBuffer(debugDataLength);
|
|
277
|
-
} else if (byteOffset === 0 && byteLength === arrayBuffer2.byteLength) {
|
|
278
|
-
this.debugData = arrayBuffer2.slice(0, debugDataLength);
|
|
279
574
|
} else {
|
|
280
|
-
|
|
575
|
+
const sourceByteOffset = Math.min((arrayBufferView == null ? void 0 : arrayBufferView.byteOffset) || 0, arrayBuffer2.byteLength);
|
|
576
|
+
const availableByteLength = Math.max(0, arrayBuffer2.byteLength - sourceByteOffset);
|
|
577
|
+
const copyByteLength = Math.min(debugDataLength, availableByteLength);
|
|
578
|
+
this.debugData = new Uint8Array(arrayBuffer2, sourceByteOffset, copyByteLength).slice().buffer;
|
|
281
579
|
}
|
|
282
580
|
}
|
|
283
581
|
};
|
|
@@ -311,61 +609,73 @@ __publicField(Buffer2, "defaultProps", {
|
|
|
311
609
|
onMapped: void 0
|
|
312
610
|
});
|
|
313
611
|
|
|
314
|
-
// dist/shadertypes/data-types/
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
signedType,
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
case "sint8":
|
|
335
|
-
return "snorm8";
|
|
336
|
-
case "uint16":
|
|
337
|
-
return "unorm16";
|
|
338
|
-
case "sint16":
|
|
339
|
-
return "snorm16";
|
|
340
|
-
default:
|
|
341
|
-
return dataType;
|
|
612
|
+
// dist/shadertypes/data-types/data-type-decoder.js
|
|
613
|
+
var DataTypeDecoder = class {
|
|
614
|
+
/**
|
|
615
|
+
* Gets info about a data type constant (signed or normalized)
|
|
616
|
+
* @returns underlying primitive / signed types, byte length, normalization, integer, signed flags
|
|
617
|
+
*/
|
|
618
|
+
getDataTypeInfo(type) {
|
|
619
|
+
const [signedType, primitiveType, byteLength] = NORMALIZED_TYPE_MAP[type];
|
|
620
|
+
const normalized = type.includes("norm");
|
|
621
|
+
const integer = !normalized && !type.startsWith("float");
|
|
622
|
+
const signed = type.startsWith("s");
|
|
623
|
+
return {
|
|
624
|
+
signedType,
|
|
625
|
+
primitiveType,
|
|
626
|
+
byteLength,
|
|
627
|
+
normalized,
|
|
628
|
+
integer,
|
|
629
|
+
signed
|
|
630
|
+
// TODO - add webglOnly flag
|
|
631
|
+
};
|
|
342
632
|
}
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
633
|
+
/** Build a vertex format from a signed data type and a component */
|
|
634
|
+
getNormalizedDataType(signedDataType) {
|
|
635
|
+
const dataType = signedDataType;
|
|
636
|
+
switch (dataType) {
|
|
637
|
+
case "uint8":
|
|
638
|
+
return "unorm8";
|
|
639
|
+
case "sint8":
|
|
640
|
+
return "snorm8";
|
|
641
|
+
case "uint16":
|
|
642
|
+
return "unorm16";
|
|
643
|
+
case "sint16":
|
|
644
|
+
return "snorm16";
|
|
645
|
+
default:
|
|
646
|
+
return dataType;
|
|
647
|
+
}
|
|
352
648
|
}
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
649
|
+
/** Align offset to 1, 2 or 4 elements (4, 8 or 16 bytes) */
|
|
650
|
+
alignTo(size, count) {
|
|
651
|
+
switch (count) {
|
|
652
|
+
case 1:
|
|
653
|
+
return size;
|
|
654
|
+
case 2:
|
|
655
|
+
return size + size % 2;
|
|
656
|
+
default:
|
|
657
|
+
return size + (4 - size % 4) % 4;
|
|
658
|
+
}
|
|
358
659
|
}
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
660
|
+
/** Returns the VariableShaderType that corresponds to a typed array */
|
|
661
|
+
getDataType(arrayOrType) {
|
|
662
|
+
const Constructor = ArrayBuffer.isView(arrayOrType) ? arrayOrType.constructor : arrayOrType;
|
|
663
|
+
if (Constructor === Uint8ClampedArray) {
|
|
664
|
+
return "uint8";
|
|
665
|
+
}
|
|
666
|
+
const info = Object.values(NORMALIZED_TYPE_MAP).find((entry) => Constructor === entry[4]);
|
|
667
|
+
if (!info) {
|
|
668
|
+
throw new Error(Constructor.name);
|
|
669
|
+
}
|
|
670
|
+
return info[0];
|
|
362
671
|
}
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
}
|
|
672
|
+
/** Returns the TypedArray that corresponds to a shader data type */
|
|
673
|
+
getTypedArrayConstructor(type) {
|
|
674
|
+
const [, , , , Constructor] = NORMALIZED_TYPE_MAP[type];
|
|
675
|
+
return Constructor;
|
|
676
|
+
}
|
|
677
|
+
};
|
|
678
|
+
var dataTypeDecoder = new DataTypeDecoder();
|
|
369
679
|
var NORMALIZED_TYPE_MAP = {
|
|
370
680
|
uint8: ["uint8", "u32", 1, false, Uint8Array],
|
|
371
681
|
sint8: ["sint8", "i32", 1, false, Int8Array],
|
|
@@ -381,87 +691,138 @@ var NORMALIZED_TYPE_MAP = {
|
|
|
381
691
|
sint32: ["sint32", "i32", 4, false, Int32Array]
|
|
382
692
|
};
|
|
383
693
|
|
|
384
|
-
// dist/shadertypes/vertex-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
type
|
|
397
|
-
components
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
694
|
+
// dist/shadertypes/vertex-types/vertex-format-decoder.js
|
|
695
|
+
var VertexFormatDecoder = class {
|
|
696
|
+
/**
|
|
697
|
+
* Decodes a vertex format, returning type, components, byte length and flags (integer, signed, normalized)
|
|
698
|
+
*/
|
|
699
|
+
getVertexFormatInfo(format) {
|
|
700
|
+
let webglOnly;
|
|
701
|
+
if (format.endsWith("-webgl")) {
|
|
702
|
+
format.replace("-webgl", "");
|
|
703
|
+
webglOnly = true;
|
|
704
|
+
}
|
|
705
|
+
const [type_, count] = format.split("x");
|
|
706
|
+
const type = type_;
|
|
707
|
+
const components = count ? parseInt(count) : 1;
|
|
708
|
+
const decodedType = dataTypeDecoder.getDataTypeInfo(type);
|
|
709
|
+
const result = {
|
|
710
|
+
type,
|
|
711
|
+
components,
|
|
712
|
+
byteLength: decodedType.byteLength * components,
|
|
713
|
+
integer: decodedType.integer,
|
|
714
|
+
signed: decodedType.signed,
|
|
715
|
+
normalized: decodedType.normalized
|
|
716
|
+
};
|
|
717
|
+
if (webglOnly) {
|
|
718
|
+
result.webglOnly = true;
|
|
719
|
+
}
|
|
720
|
+
return result;
|
|
721
|
+
}
|
|
722
|
+
/** Build a vertex format from a signed data type and a component */
|
|
723
|
+
makeVertexFormat(signedDataType, components, normalized) {
|
|
724
|
+
const dataType = normalized ? dataTypeDecoder.getNormalizedDataType(signedDataType) : signedDataType;
|
|
725
|
+
switch (dataType) {
|
|
726
|
+
case "unorm8":
|
|
727
|
+
if (components === 1) {
|
|
728
|
+
return "unorm8";
|
|
729
|
+
}
|
|
730
|
+
if (components === 3) {
|
|
731
|
+
return "unorm8x3-webgl";
|
|
732
|
+
}
|
|
733
|
+
return `${dataType}x${components}`;
|
|
734
|
+
case "snorm8":
|
|
735
|
+
if (components === 1) {
|
|
736
|
+
return "snorm8";
|
|
737
|
+
}
|
|
738
|
+
if (components === 3) {
|
|
739
|
+
return "snorm8x3-webgl";
|
|
740
|
+
}
|
|
741
|
+
return `${dataType}x${components}`;
|
|
742
|
+
case "uint8":
|
|
743
|
+
case "sint8":
|
|
744
|
+
if (components === 1 || components === 3) {
|
|
745
|
+
throw new Error(`size: ${components}`);
|
|
746
|
+
}
|
|
747
|
+
return `${dataType}x${components}`;
|
|
748
|
+
case "uint16":
|
|
749
|
+
if (components === 1) {
|
|
750
|
+
return "uint16";
|
|
751
|
+
}
|
|
752
|
+
if (components === 3) {
|
|
753
|
+
return "uint16x3-webgl";
|
|
754
|
+
}
|
|
755
|
+
return `${dataType}x${components}`;
|
|
756
|
+
case "sint16":
|
|
757
|
+
if (components === 1) {
|
|
758
|
+
return "sint16";
|
|
759
|
+
}
|
|
760
|
+
if (components === 3) {
|
|
761
|
+
return "sint16x3-webgl";
|
|
762
|
+
}
|
|
763
|
+
return `${dataType}x${components}`;
|
|
764
|
+
case "unorm16":
|
|
765
|
+
if (components === 1) {
|
|
766
|
+
return "unorm16";
|
|
767
|
+
}
|
|
768
|
+
if (components === 3) {
|
|
769
|
+
return "unorm16x3-webgl";
|
|
770
|
+
}
|
|
771
|
+
return `${dataType}x${components}`;
|
|
772
|
+
case "snorm16":
|
|
773
|
+
if (components === 1) {
|
|
774
|
+
return "snorm16";
|
|
775
|
+
}
|
|
776
|
+
if (components === 3) {
|
|
777
|
+
return "snorm16x3-webgl";
|
|
778
|
+
}
|
|
779
|
+
return `${dataType}x${components}`;
|
|
780
|
+
case "float16":
|
|
781
|
+
if (components === 1 || components === 3) {
|
|
782
|
+
throw new Error(`size: ${components}`);
|
|
783
|
+
}
|
|
784
|
+
return `${dataType}x${components}`;
|
|
785
|
+
default:
|
|
786
|
+
return components === 1 ? dataType : `${dataType}x${components}`;
|
|
787
|
+
}
|
|
438
788
|
}
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
vertexType = "float32";
|
|
448
|
-
break;
|
|
449
|
-
case "i32":
|
|
450
|
-
vertexType = "sint32";
|
|
451
|
-
break;
|
|
452
|
-
case "u32":
|
|
453
|
-
vertexType = "uint32";
|
|
454
|
-
break;
|
|
455
|
-
case "f16":
|
|
456
|
-
return opts.components <= 2 ? "float16x2" : "float16x4";
|
|
789
|
+
/** Get the vertex format for an attribute with TypedArray and size */
|
|
790
|
+
getVertexFormatFromAttribute(typedArray, size, normalized) {
|
|
791
|
+
if (!size || size > 4) {
|
|
792
|
+
throw new Error(`size ${size}`);
|
|
793
|
+
}
|
|
794
|
+
const components = size;
|
|
795
|
+
const signedDataType = dataTypeDecoder.getDataType(typedArray);
|
|
796
|
+
return this.makeVertexFormat(signedDataType, components, normalized);
|
|
457
797
|
}
|
|
458
|
-
|
|
459
|
-
|
|
798
|
+
/**
|
|
799
|
+
* Return a "default" vertex format for a certain shader data type
|
|
800
|
+
* The simplest vertex format that matches the shader attribute's data type
|
|
801
|
+
*/
|
|
802
|
+
getCompatibleVertexFormat(opts) {
|
|
803
|
+
let vertexType;
|
|
804
|
+
switch (opts.primitiveType) {
|
|
805
|
+
case "f32":
|
|
806
|
+
vertexType = "float32";
|
|
807
|
+
break;
|
|
808
|
+
case "i32":
|
|
809
|
+
vertexType = "sint32";
|
|
810
|
+
break;
|
|
811
|
+
case "u32":
|
|
812
|
+
vertexType = "uint32";
|
|
813
|
+
break;
|
|
814
|
+
case "f16":
|
|
815
|
+
return opts.components <= 2 ? "float16x2" : "float16x4";
|
|
816
|
+
}
|
|
817
|
+
if (opts.components === 1) {
|
|
818
|
+
return vertexType;
|
|
819
|
+
}
|
|
820
|
+
return `${vertexType}x${opts.components}`;
|
|
460
821
|
}
|
|
461
|
-
|
|
462
|
-
|
|
822
|
+
};
|
|
823
|
+
var vertexFormatDecoder = new VertexFormatDecoder();
|
|
463
824
|
|
|
464
|
-
// dist/shadertypes/
|
|
825
|
+
// dist/shadertypes/texture-types/texture-format-table.js
|
|
465
826
|
var texture_compression_bc = "texture-compression-bc";
|
|
466
827
|
var texture_compression_astc = "texture-compression-astc";
|
|
467
828
|
var texture_compression_etc2 = "texture-compression-etc2";
|
|
@@ -472,6 +833,7 @@ var float32_renderable = "float32-renderable-webgl";
|
|
|
472
833
|
var float16_renderable = "float16-renderable-webgl";
|
|
473
834
|
var rgb9e5ufloat_renderable = "rgb9e5ufloat-renderable-webgl";
|
|
474
835
|
var snorm8_renderable = "snorm8-renderable-webgl";
|
|
836
|
+
var norm16_webgl = "norm16-webgl";
|
|
475
837
|
var norm16_renderable = "norm16-renderable-webgl";
|
|
476
838
|
var snorm16_renderable = "snorm16-renderable-webgl";
|
|
477
839
|
var float32_filterable = "float32-filterable";
|
|
@@ -505,16 +867,16 @@ var TEXTURE_FORMAT_COLOR_DEPTH_TABLE = {
|
|
|
505
867
|
"rgba8sint": {},
|
|
506
868
|
"bgra8unorm": {},
|
|
507
869
|
"bgra8unorm-srgb": {},
|
|
508
|
-
"r16unorm": { f: norm16_renderable },
|
|
509
|
-
"rg16unorm": { render: norm16_renderable },
|
|
510
|
-
"rgb16unorm-webgl": { f:
|
|
870
|
+
"r16unorm": { f: norm16_webgl, render: norm16_renderable },
|
|
871
|
+
"rg16unorm": { f: norm16_webgl, render: norm16_renderable },
|
|
872
|
+
"rgb16unorm-webgl": { f: norm16_webgl, render: false },
|
|
511
873
|
// rgb not renderable
|
|
512
|
-
"rgba16unorm": { render: norm16_renderable },
|
|
513
|
-
"r16snorm": { f: snorm16_renderable },
|
|
514
|
-
"rg16snorm": { render: snorm16_renderable },
|
|
515
|
-
"rgb16snorm-webgl": { f:
|
|
874
|
+
"rgba16unorm": { f: norm16_webgl, render: norm16_renderable },
|
|
875
|
+
"r16snorm": { f: norm16_webgl, render: snorm16_renderable },
|
|
876
|
+
"rg16snorm": { f: norm16_webgl, render: snorm16_renderable },
|
|
877
|
+
"rgb16snorm-webgl": { f: norm16_webgl, render: false },
|
|
516
878
|
// rgb not renderable
|
|
517
|
-
"rgba16snorm": { render: snorm16_renderable },
|
|
879
|
+
"rgba16snorm": { f: norm16_webgl, render: snorm16_renderable },
|
|
518
880
|
"r16uint": {},
|
|
519
881
|
"rg16uint": {},
|
|
520
882
|
"rgba16uint": {},
|
|
@@ -617,7 +979,7 @@ var TEXTURE_FORMAT_COMPRESSED_TABLE = {
|
|
|
617
979
|
// WEBGL_compressed_texture_pvrtc
|
|
618
980
|
"pvrtc-rgb4unorm-webgl": { f: texture_compression_pvrtc_webgl },
|
|
619
981
|
"pvrtc-rgba4unorm-webgl": { f: texture_compression_pvrtc_webgl },
|
|
620
|
-
"pvrtc-
|
|
982
|
+
"pvrtc-rgb2unorm-webgl": { f: texture_compression_pvrtc_webgl },
|
|
621
983
|
"pvrtc-rgba2unorm-webgl": { f: texture_compression_pvrtc_webgl },
|
|
622
984
|
// WEBGL_compressed_texture_etc1
|
|
623
985
|
"etc1-rbg-unorm-webgl": { f: texture_compression_etc1_webgl },
|
|
@@ -631,7 +993,10 @@ var TEXTURE_FORMAT_TABLE = {
|
|
|
631
993
|
...TEXTURE_FORMAT_COMPRESSED_TABLE
|
|
632
994
|
};
|
|
633
995
|
|
|
634
|
-
// dist/shadertypes/
|
|
996
|
+
// dist/shadertypes/texture-types/texture-format-decoder.js
|
|
997
|
+
var RGB_FORMAT_REGEX = /^(r|rg|rgb|rgba|bgra)([0-9]*)([a-z]*)(-srgb)?(-webgl)?$/;
|
|
998
|
+
var COLOR_FORMAT_PREFIXES = ["rgb", "rgba", "bgra"];
|
|
999
|
+
var DEPTH_FORMAT_PREFIXES = ["depth", "stencil"];
|
|
635
1000
|
var COMPRESSED_TEXTURE_FORMAT_PREFIXES = [
|
|
636
1001
|
"bc1",
|
|
637
1002
|
"bc2",
|
|
@@ -647,49 +1012,71 @@ var COMPRESSED_TEXTURE_FORMAT_PREFIXES = [
|
|
|
647
1012
|
"astc",
|
|
648
1013
|
"pvrtc"
|
|
649
1014
|
];
|
|
650
|
-
var RGB_FORMAT_REGEX = /^(r|rg|rgb|rgba|bgra)([0-9]*)([a-z]*)(-srgb)?(-webgl)?$/;
|
|
651
1015
|
var TextureFormatDecoder = class {
|
|
652
|
-
/** Returns information about a texture format, e.g. attatchment type, components, byte length and flags (integer, signed, normalized) */
|
|
653
|
-
getInfo(format) {
|
|
654
|
-
return getTextureFormatInfo(format);
|
|
655
|
-
}
|
|
656
1016
|
/** Checks if a texture format is color */
|
|
657
1017
|
isColor(format) {
|
|
658
|
-
return
|
|
1018
|
+
return COLOR_FORMAT_PREFIXES.some((prefix) => format.startsWith(prefix));
|
|
659
1019
|
}
|
|
660
1020
|
/** Checks if a texture format is depth or stencil */
|
|
661
1021
|
isDepthStencil(format) {
|
|
662
|
-
return
|
|
1022
|
+
return DEPTH_FORMAT_PREFIXES.some((prefix) => format.startsWith(prefix));
|
|
663
1023
|
}
|
|
664
1024
|
/** Checks if a texture format is compressed */
|
|
665
1025
|
isCompressed(format) {
|
|
666
1026
|
return COMPRESSED_TEXTURE_FORMAT_PREFIXES.some((prefix) => format.startsWith(prefix));
|
|
667
1027
|
}
|
|
668
|
-
/**
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
1028
|
+
/** Returns information about a texture format, e.g. attachment type, components, byte length and flags (integer, signed, normalized) */
|
|
1029
|
+
getInfo(format) {
|
|
1030
|
+
return getTextureFormatInfo(format);
|
|
1031
|
+
}
|
|
1032
|
+
/** "static" capabilities of a texture format. @note Needs to be adjusted against current device */
|
|
672
1033
|
getCapabilities(format) {
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
filter: info.filter ?? true,
|
|
679
|
-
blend: info.blend ?? true,
|
|
680
|
-
store: info.store ?? true
|
|
681
|
-
};
|
|
682
|
-
const formatInfo = getTextureFormatInfo(format);
|
|
683
|
-
const isDepthStencil = format.startsWith("depth") || format.startsWith("stencil");
|
|
684
|
-
const isSigned = formatInfo == null ? void 0 : formatInfo.signed;
|
|
685
|
-
const isInteger = formatInfo == null ? void 0 : formatInfo.integer;
|
|
686
|
-
const isWebGLSpecific = formatInfo == null ? void 0 : formatInfo.webgl;
|
|
687
|
-
formatCapabilities.render &&= !isSigned;
|
|
688
|
-
formatCapabilities.filter &&= !isDepthStencil && !isSigned && !isInteger && !isWebGLSpecific;
|
|
689
|
-
return formatCapabilities;
|
|
1034
|
+
return getTextureFormatCapabilities(format);
|
|
1035
|
+
}
|
|
1036
|
+
/** Computes the memory layout for a texture, in particular including row byte alignment */
|
|
1037
|
+
computeMemoryLayout(opts) {
|
|
1038
|
+
return computeTextureMemoryLayout(opts);
|
|
690
1039
|
}
|
|
691
1040
|
};
|
|
692
1041
|
var textureFormatDecoder = new TextureFormatDecoder();
|
|
1042
|
+
function computeTextureMemoryLayout({ format, width, height, depth, byteAlignment }) {
|
|
1043
|
+
const formatInfo = textureFormatDecoder.getInfo(format);
|
|
1044
|
+
const { bytesPerPixel, bytesPerBlock = bytesPerPixel, blockWidth = 1, blockHeight = 1, compressed = false } = formatInfo;
|
|
1045
|
+
const blockColumns = compressed ? Math.ceil(width / blockWidth) : width;
|
|
1046
|
+
const blockRows = compressed ? Math.ceil(height / blockHeight) : height;
|
|
1047
|
+
const unpaddedBytesPerRow = blockColumns * bytesPerBlock;
|
|
1048
|
+
const bytesPerRow = Math.ceil(unpaddedBytesPerRow / byteAlignment) * byteAlignment;
|
|
1049
|
+
const rowsPerImage = blockRows;
|
|
1050
|
+
const byteLength = bytesPerRow * rowsPerImage * depth;
|
|
1051
|
+
return {
|
|
1052
|
+
bytesPerPixel,
|
|
1053
|
+
bytesPerRow,
|
|
1054
|
+
rowsPerImage,
|
|
1055
|
+
depthOrArrayLayers: depth,
|
|
1056
|
+
bytesPerImage: bytesPerRow * rowsPerImage,
|
|
1057
|
+
byteLength
|
|
1058
|
+
};
|
|
1059
|
+
}
|
|
1060
|
+
function getTextureFormatCapabilities(format) {
|
|
1061
|
+
const info = getTextureFormatDefinition(format);
|
|
1062
|
+
const formatCapabilities = {
|
|
1063
|
+
format,
|
|
1064
|
+
create: info.f ?? true,
|
|
1065
|
+
render: info.render ?? true,
|
|
1066
|
+
filter: info.filter ?? true,
|
|
1067
|
+
blend: info.blend ?? true,
|
|
1068
|
+
store: info.store ?? true
|
|
1069
|
+
};
|
|
1070
|
+
const formatInfo = getTextureFormatInfo(format);
|
|
1071
|
+
const isDepthStencil = format.startsWith("depth") || format.startsWith("stencil");
|
|
1072
|
+
const isSigned = formatInfo == null ? void 0 : formatInfo.signed;
|
|
1073
|
+
const isInteger = formatInfo == null ? void 0 : formatInfo.integer;
|
|
1074
|
+
const isWebGLSpecific = formatInfo == null ? void 0 : formatInfo.webgl;
|
|
1075
|
+
const isCompressed = Boolean(formatInfo == null ? void 0 : formatInfo.compressed);
|
|
1076
|
+
formatCapabilities.render &&= !isDepthStencil && !isCompressed;
|
|
1077
|
+
formatCapabilities.filter &&= !isDepthStencil && !isSigned && !isInteger && !isWebGLSpecific;
|
|
1078
|
+
return formatCapabilities;
|
|
1079
|
+
}
|
|
693
1080
|
function getTextureFormatInfo(format) {
|
|
694
1081
|
let formatInfo = getTextureFormatInfoUsingTable(format);
|
|
695
1082
|
if (textureFormatDecoder.isCompressed(format)) {
|
|
@@ -698,19 +1085,20 @@ function getTextureFormatInfo(format) {
|
|
|
698
1085
|
formatInfo.bytesPerPixel = 1;
|
|
699
1086
|
formatInfo.srgb = false;
|
|
700
1087
|
formatInfo.compressed = true;
|
|
1088
|
+
formatInfo.bytesPerBlock = getCompressedTextureBlockByteLength(format);
|
|
701
1089
|
const blockSize = getCompressedTextureBlockSize(format);
|
|
702
1090
|
if (blockSize) {
|
|
703
1091
|
formatInfo.blockWidth = blockSize.blockWidth;
|
|
704
1092
|
formatInfo.blockHeight = blockSize.blockHeight;
|
|
705
1093
|
}
|
|
706
1094
|
}
|
|
707
|
-
const matches = RGB_FORMAT_REGEX.exec(format);
|
|
1095
|
+
const matches = !formatInfo.packed ? RGB_FORMAT_REGEX.exec(format) : null;
|
|
708
1096
|
if (matches) {
|
|
709
1097
|
const [, channels, length, type, srgb, suffix] = matches;
|
|
710
1098
|
const dataType = `${type}${length}`;
|
|
711
|
-
const decodedType = getDataTypeInfo(dataType);
|
|
1099
|
+
const decodedType = dataTypeDecoder.getDataTypeInfo(dataType);
|
|
712
1100
|
const bits = decodedType.byteLength * 8;
|
|
713
|
-
const components = channels.length;
|
|
1101
|
+
const components = (channels == null ? void 0 : channels.length) ?? 1;
|
|
714
1102
|
const bitsPerChannel = [
|
|
715
1103
|
bits,
|
|
716
1104
|
components >= 2 ? bits : 0,
|
|
@@ -727,7 +1115,7 @@ function getTextureFormatInfo(format) {
|
|
|
727
1115
|
signed: decodedType.signed,
|
|
728
1116
|
normalized: decodedType.normalized,
|
|
729
1117
|
bitsPerChannel,
|
|
730
|
-
bytesPerPixel: decodedType.byteLength *
|
|
1118
|
+
bytesPerPixel: decodedType.byteLength * components,
|
|
731
1119
|
packed: formatInfo.packed,
|
|
732
1120
|
srgb: formatInfo.srgb
|
|
733
1121
|
};
|
|
@@ -784,10 +1172,31 @@ function getCompressedTextureBlockSize(format) {
|
|
|
784
1172
|
const [, blockWidth, blockHeight] = matches;
|
|
785
1173
|
return { blockWidth: Number(blockWidth), blockHeight: Number(blockHeight) };
|
|
786
1174
|
}
|
|
1175
|
+
if (format.startsWith("bc") || format.startsWith("etc1") || format.startsWith("etc2") || format.startsWith("eac") || format.startsWith("atc")) {
|
|
1176
|
+
return { blockWidth: 4, blockHeight: 4 };
|
|
1177
|
+
}
|
|
1178
|
+
if (format.startsWith("pvrtc-rgb4") || format.startsWith("pvrtc-rgba4")) {
|
|
1179
|
+
return { blockWidth: 4, blockHeight: 4 };
|
|
1180
|
+
}
|
|
1181
|
+
if (format.startsWith("pvrtc-rgb2") || format.startsWith("pvrtc-rgba2")) {
|
|
1182
|
+
return { blockWidth: 8, blockHeight: 4 };
|
|
1183
|
+
}
|
|
787
1184
|
return null;
|
|
788
1185
|
}
|
|
1186
|
+
function getCompressedTextureBlockByteLength(format) {
|
|
1187
|
+
if (format.startsWith("bc1") || format.startsWith("bc4") || format.startsWith("etc1") || format.startsWith("etc2-rgb8") || format.startsWith("etc2-rgb8a1") || format.startsWith("eac-r11") || format === "atc-rgb-unorm-webgl") {
|
|
1188
|
+
return 8;
|
|
1189
|
+
}
|
|
1190
|
+
if (format.startsWith("bc2") || format.startsWith("bc3") || format.startsWith("bc5") || format.startsWith("bc6h") || format.startsWith("bc7") || format.startsWith("etc2-rgba8") || format.startsWith("eac-rg11") || format.startsWith("astc") || format === "atc-rgba-unorm-webgl" || format === "atc-rgbai-unorm-webgl") {
|
|
1191
|
+
return 16;
|
|
1192
|
+
}
|
|
1193
|
+
if (format.startsWith("pvrtc")) {
|
|
1194
|
+
return 8;
|
|
1195
|
+
}
|
|
1196
|
+
return 16;
|
|
1197
|
+
}
|
|
789
1198
|
|
|
790
|
-
// dist/image-
|
|
1199
|
+
// dist/shadertypes/image-types/image-types.js
|
|
791
1200
|
function isExternalImage(data) {
|
|
792
1201
|
return typeof ImageData !== "undefined" && data instanceof ImageData || typeof ImageBitmap !== "undefined" && data instanceof ImageBitmap || typeof HTMLImageElement !== "undefined" && data instanceof HTMLImageElement || typeof HTMLVideoElement !== "undefined" && data instanceof HTMLVideoElement || typeof VideoFrame !== "undefined" && data instanceof VideoFrame || typeof HTMLCanvasElement !== "undefined" && data instanceof HTMLCanvasElement || typeof OffscreenCanvas !== "undefined" && data instanceof OffscreenCanvas;
|
|
793
1202
|
}
|
|
@@ -810,6 +1219,53 @@ function getExternalImageSize(data) {
|
|
|
810
1219
|
// dist/adapter/device.js
|
|
811
1220
|
var DeviceLimits = class {
|
|
812
1221
|
};
|
|
1222
|
+
function formatErrorLogArguments(context, args) {
|
|
1223
|
+
const formattedContext = formatErrorLogValue(context);
|
|
1224
|
+
const formattedArgs = args.map(formatErrorLogValue).filter((arg) => arg !== void 0);
|
|
1225
|
+
return [formattedContext, ...formattedArgs].filter((arg) => arg !== void 0);
|
|
1226
|
+
}
|
|
1227
|
+
function formatErrorLogValue(value) {
|
|
1228
|
+
var _a;
|
|
1229
|
+
if (value === void 0) {
|
|
1230
|
+
return void 0;
|
|
1231
|
+
}
|
|
1232
|
+
if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
1233
|
+
return value;
|
|
1234
|
+
}
|
|
1235
|
+
if (value instanceof Error) {
|
|
1236
|
+
return value.message;
|
|
1237
|
+
}
|
|
1238
|
+
if (Array.isArray(value)) {
|
|
1239
|
+
return value.map(formatErrorLogValue);
|
|
1240
|
+
}
|
|
1241
|
+
if (typeof value === "object") {
|
|
1242
|
+
if (hasCustomToString(value)) {
|
|
1243
|
+
const stringValue = String(value);
|
|
1244
|
+
if (stringValue !== "[object Object]") {
|
|
1245
|
+
return stringValue;
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
if (looksLikeGPUCompilationMessage(value)) {
|
|
1249
|
+
return formatGPUCompilationMessage(value);
|
|
1250
|
+
}
|
|
1251
|
+
return ((_a = value.constructor) == null ? void 0 : _a.name) || "Object";
|
|
1252
|
+
}
|
|
1253
|
+
return String(value);
|
|
1254
|
+
}
|
|
1255
|
+
function hasCustomToString(value) {
|
|
1256
|
+
return "toString" in value && typeof value.toString === "function" && value.toString !== Object.prototype.toString;
|
|
1257
|
+
}
|
|
1258
|
+
function looksLikeGPUCompilationMessage(value) {
|
|
1259
|
+
return "message" in value && "type" in value;
|
|
1260
|
+
}
|
|
1261
|
+
function formatGPUCompilationMessage(value) {
|
|
1262
|
+
const type = typeof value.type === "string" ? value.type : "message";
|
|
1263
|
+
const message = typeof value.message === "string" ? value.message : "";
|
|
1264
|
+
const lineNum = typeof value.lineNum === "number" ? value.lineNum : null;
|
|
1265
|
+
const linePos = typeof value.linePos === "number" ? value.linePos : null;
|
|
1266
|
+
const location = lineNum !== null && linePos !== null ? ` @ ${lineNum}:${linePos}` : lineNum !== null ? ` @ ${lineNum}` : "";
|
|
1267
|
+
return `${type}${location}: ${message}`.trim();
|
|
1268
|
+
}
|
|
813
1269
|
var DeviceFeatures = class {
|
|
814
1270
|
features;
|
|
815
1271
|
disabledFeatures;
|
|
@@ -840,19 +1296,24 @@ var _Device = class {
|
|
|
840
1296
|
userData = {};
|
|
841
1297
|
/** stats */
|
|
842
1298
|
statsManager = lumaStats;
|
|
1299
|
+
/** Internal per-device factory storage */
|
|
1300
|
+
_factories = {};
|
|
843
1301
|
/** An abstract timestamp used for change tracking */
|
|
844
1302
|
timestamp = 0;
|
|
845
1303
|
/** True if this device has been reused during device creation (app has multiple references) */
|
|
846
1304
|
_reused = false;
|
|
847
1305
|
/** Used by other luma.gl modules to store data on the device */
|
|
848
|
-
|
|
1306
|
+
_moduleData = {};
|
|
849
1307
|
_textureCaps = {};
|
|
1308
|
+
/** Internal timestamp query set used when GPU timing collection is enabled for this device. */
|
|
1309
|
+
_debugGPUTimeQuery = null;
|
|
850
1310
|
constructor(props) {
|
|
851
1311
|
this.props = { ..._Device.defaultProps, ...props };
|
|
852
1312
|
this.id = this.props.id || uid(this[Symbol.toStringTag].toLowerCase());
|
|
853
1313
|
}
|
|
1314
|
+
// TODO - just expose the shadertypes decoders?
|
|
854
1315
|
getVertexFormatInfo(format) {
|
|
855
|
-
return getVertexFormatInfo(format);
|
|
1316
|
+
return vertexFormatDecoder.getVertexFormatInfo(format);
|
|
856
1317
|
}
|
|
857
1318
|
isVertexFormatSupported(format) {
|
|
858
1319
|
return true;
|
|
@@ -900,6 +1361,16 @@ var _Device = class {
|
|
|
900
1361
|
isTextureFormatCompressed(format) {
|
|
901
1362
|
return textureFormatDecoder.isCompressed(format);
|
|
902
1363
|
}
|
|
1364
|
+
/** Returns the compressed texture formats that can be created and sampled on this device */
|
|
1365
|
+
getSupportedCompressedTextureFormats() {
|
|
1366
|
+
const supportedFormats = [];
|
|
1367
|
+
for (const format of Object.keys(getTextureFormatTable())) {
|
|
1368
|
+
if (this.isTextureFormatCompressed(format) && this.isTextureFormatSupported(format)) {
|
|
1369
|
+
supportedFormats.push(format);
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
return supportedFormats;
|
|
1373
|
+
}
|
|
903
1374
|
// DEBUG METHODS
|
|
904
1375
|
pushDebugGroup(groupLabel) {
|
|
905
1376
|
this.commandEncoder.pushDebugGroup(groupLabel);
|
|
@@ -944,7 +1415,8 @@ var _Device = class {
|
|
|
944
1415
|
reportError(error, context, ...args) {
|
|
945
1416
|
const isHandled = this.props.onError(error, context);
|
|
946
1417
|
if (!isHandled) {
|
|
947
|
-
|
|
1418
|
+
const logArguments = formatErrorLogArguments(context, args);
|
|
1419
|
+
return log.error(this.type === "webgl" ? "%cWebGL" : "%cWebGPU", "color: white; background: red; padding: 2px 6px; border-radius: 3px;", error.message, ...logArguments);
|
|
948
1420
|
}
|
|
949
1421
|
return () => {
|
|
950
1422
|
};
|
|
@@ -966,6 +1438,10 @@ or create a device with the 'debug: true' prop.`;
|
|
|
966
1438
|
}
|
|
967
1439
|
return this.canvasContext;
|
|
968
1440
|
}
|
|
1441
|
+
/** Create a fence sync object */
|
|
1442
|
+
createFence() {
|
|
1443
|
+
throw new Error("createFence() not implemented");
|
|
1444
|
+
}
|
|
969
1445
|
/** Create a RenderPass using the default CommandEncoder */
|
|
970
1446
|
beginRenderPass(props) {
|
|
971
1447
|
return this.commandEncoder.beginRenderPass(props);
|
|
@@ -974,6 +1450,78 @@ or create a device with the 'debug: true' prop.`;
|
|
|
974
1450
|
beginComputePass(props) {
|
|
975
1451
|
return this.commandEncoder.beginComputePass(props);
|
|
976
1452
|
}
|
|
1453
|
+
/**
|
|
1454
|
+
* Generate mipmaps for a WebGPU texture.
|
|
1455
|
+
* WebGPU textures must be created up front with the required mip count, usage flags, and a format that supports the chosen generation path.
|
|
1456
|
+
* WebGL uses `Texture.generateMipmapsWebGL()` directly because the backend manages mip generation on the texture object itself.
|
|
1457
|
+
*/
|
|
1458
|
+
generateMipmapsWebGPU(_texture) {
|
|
1459
|
+
throw new Error("not implemented");
|
|
1460
|
+
}
|
|
1461
|
+
/** Internal helper for creating a shareable WebGL render-pipeline implementation. */
|
|
1462
|
+
_createSharedRenderPipelineWebGL(_props) {
|
|
1463
|
+
throw new Error("_createSharedRenderPipelineWebGL() not implemented");
|
|
1464
|
+
}
|
|
1465
|
+
/** Internal WebGPU-only helper for retrieving the native bind-group layout for a pipeline group. */
|
|
1466
|
+
_createBindGroupLayoutWebGPU(_pipeline, _group) {
|
|
1467
|
+
throw new Error("_createBindGroupLayoutWebGPU() not implemented");
|
|
1468
|
+
}
|
|
1469
|
+
/** Internal WebGPU-only helper for creating a native bind group. */
|
|
1470
|
+
_createBindGroupWebGPU(_bindGroupLayout, _shaderLayout, _bindings, _group, _label) {
|
|
1471
|
+
throw new Error("_createBindGroupWebGPU() not implemented");
|
|
1472
|
+
}
|
|
1473
|
+
/**
|
|
1474
|
+
* Internal helper that returns `true` when timestamp-query GPU timing should be
|
|
1475
|
+
* collected for this device.
|
|
1476
|
+
*/
|
|
1477
|
+
_supportsDebugGPUTime() {
|
|
1478
|
+
return this.features.has("timestamp-query") && Boolean(this.props.debug || this.props.debugGPUTime);
|
|
1479
|
+
}
|
|
1480
|
+
/**
|
|
1481
|
+
* Internal helper that enables device-managed GPU timing collection on the
|
|
1482
|
+
* default command encoder. Reuses the existing query set if timing is already enabled.
|
|
1483
|
+
*
|
|
1484
|
+
* @param queryCount - Number of timestamp slots reserved for profiled passes.
|
|
1485
|
+
* @returns The device-managed timestamp QuerySet, or `null` when timing is not supported or could not be enabled.
|
|
1486
|
+
*/
|
|
1487
|
+
_enableDebugGPUTime(queryCount = 256) {
|
|
1488
|
+
if (!this._supportsDebugGPUTime()) {
|
|
1489
|
+
return null;
|
|
1490
|
+
}
|
|
1491
|
+
if (this._debugGPUTimeQuery) {
|
|
1492
|
+
return this._debugGPUTimeQuery;
|
|
1493
|
+
}
|
|
1494
|
+
try {
|
|
1495
|
+
this._debugGPUTimeQuery = this.createQuerySet({ type: "timestamp", count: queryCount });
|
|
1496
|
+
this.commandEncoder = this.createCommandEncoder({
|
|
1497
|
+
id: this.commandEncoder.props.id,
|
|
1498
|
+
timeProfilingQuerySet: this._debugGPUTimeQuery
|
|
1499
|
+
});
|
|
1500
|
+
} catch {
|
|
1501
|
+
this._debugGPUTimeQuery = null;
|
|
1502
|
+
}
|
|
1503
|
+
return this._debugGPUTimeQuery;
|
|
1504
|
+
}
|
|
1505
|
+
/**
|
|
1506
|
+
* Internal helper that disables device-managed GPU timing collection and restores
|
|
1507
|
+
* the default command encoder to an unprofiled state.
|
|
1508
|
+
*/
|
|
1509
|
+
_disableDebugGPUTime() {
|
|
1510
|
+
if (!this._debugGPUTimeQuery) {
|
|
1511
|
+
return;
|
|
1512
|
+
}
|
|
1513
|
+
if (this.commandEncoder.getTimeProfilingQuerySet() === this._debugGPUTimeQuery) {
|
|
1514
|
+
this.commandEncoder = this.createCommandEncoder({
|
|
1515
|
+
id: this.commandEncoder.props.id
|
|
1516
|
+
});
|
|
1517
|
+
}
|
|
1518
|
+
this._debugGPUTimeQuery.destroy();
|
|
1519
|
+
this._debugGPUTimeQuery = null;
|
|
1520
|
+
}
|
|
1521
|
+
/** Internal helper that returns `true` when device-managed GPU timing is currently active. */
|
|
1522
|
+
_isDebugGPUTimeEnabled() {
|
|
1523
|
+
return this._debugGPUTimeQuery !== null;
|
|
1524
|
+
}
|
|
977
1525
|
// DEPRECATED METHODS
|
|
978
1526
|
/** @deprecated Use getDefaultCanvasContext() */
|
|
979
1527
|
getCanvasContext() {
|
|
@@ -1009,6 +1557,12 @@ or create a device with the 'debug: true' prop.`;
|
|
|
1009
1557
|
resetWebGL() {
|
|
1010
1558
|
throw new Error("not implemented");
|
|
1011
1559
|
}
|
|
1560
|
+
// INTERNAL LUMA.GL METHODS
|
|
1561
|
+
getModuleData(moduleName) {
|
|
1562
|
+
this._moduleData[moduleName] ||= {};
|
|
1563
|
+
return this._moduleData[moduleName];
|
|
1564
|
+
}
|
|
1565
|
+
// INTERNAL HELPERS
|
|
1012
1566
|
// IMPLEMENTATION
|
|
1013
1567
|
/** Helper to get the canvas context props */
|
|
1014
1568
|
static _getCanvasContextProps(props) {
|
|
@@ -1075,7 +1629,8 @@ __publicField(Device, "defaultProps", {
|
|
|
1075
1629
|
onVisibilityChange: (context) => log.log(1, `${context} Visibility changed ${context.isVisible}`)(),
|
|
1076
1630
|
onDevicePixelRatioChange: (context, info) => log.log(1, `${context} DPR changed ${info.oldRatio} => ${context.devicePixelRatio}`)(),
|
|
1077
1631
|
// Debug flags
|
|
1078
|
-
debug:
|
|
1632
|
+
debug: getDefaultDebugValue(),
|
|
1633
|
+
debugGPUTime: false,
|
|
1079
1634
|
debugShaders: log.get("debug-shaders") || void 0,
|
|
1080
1635
|
debugFramebuffers: Boolean(log.get("debug-framebuffers")),
|
|
1081
1636
|
debugFactories: Boolean(log.get("debug-factories")),
|
|
@@ -1086,9 +1641,11 @@ __publicField(Device, "defaultProps", {
|
|
|
1086
1641
|
// Experimental
|
|
1087
1642
|
_reuseDevices: false,
|
|
1088
1643
|
_requestMaxLimits: true,
|
|
1089
|
-
_cacheShaders:
|
|
1090
|
-
|
|
1091
|
-
|
|
1644
|
+
_cacheShaders: true,
|
|
1645
|
+
_destroyShaders: false,
|
|
1646
|
+
_cachePipelines: true,
|
|
1647
|
+
_sharePipelines: true,
|
|
1648
|
+
_destroyPipelines: false,
|
|
1092
1649
|
// TODO - Change these after confirming things work as expected
|
|
1093
1650
|
_initializeFeatures: true,
|
|
1094
1651
|
_disabledFeatures: {
|
|
@@ -1097,6 +1654,25 @@ __publicField(Device, "defaultProps", {
|
|
|
1097
1654
|
// INTERNAL
|
|
1098
1655
|
_handle: void 0
|
|
1099
1656
|
});
|
|
1657
|
+
function _getDefaultDebugValue(logDebugValue, nodeEnv) {
|
|
1658
|
+
if (logDebugValue !== void 0 && logDebugValue !== null) {
|
|
1659
|
+
return Boolean(logDebugValue);
|
|
1660
|
+
}
|
|
1661
|
+
if (nodeEnv !== void 0) {
|
|
1662
|
+
return nodeEnv !== "production";
|
|
1663
|
+
}
|
|
1664
|
+
return false;
|
|
1665
|
+
}
|
|
1666
|
+
function getDefaultDebugValue() {
|
|
1667
|
+
return _getDefaultDebugValue(log.get("debug"), getNodeEnv());
|
|
1668
|
+
}
|
|
1669
|
+
function getNodeEnv() {
|
|
1670
|
+
const processObject = globalThis.process;
|
|
1671
|
+
if (!(processObject == null ? void 0 : processObject.env)) {
|
|
1672
|
+
return void 0;
|
|
1673
|
+
}
|
|
1674
|
+
return processObject.env["NODE_ENV"];
|
|
1675
|
+
}
|
|
1100
1676
|
|
|
1101
1677
|
// dist/adapter/luma.js
|
|
1102
1678
|
var STARTUP_MESSAGE = "set luma.log.level=1 (or higher) to trace rendering";
|
|
@@ -1116,7 +1692,7 @@ var _Luma = class {
|
|
|
1116
1692
|
VERSION = (
|
|
1117
1693
|
// Version detection using build plugin
|
|
1118
1694
|
// @ts-expect-error no-undef
|
|
1119
|
-
true ? "9.
|
|
1695
|
+
true ? "9.3.0-alpha.11" : "running from source"
|
|
1120
1696
|
);
|
|
1121
1697
|
spector;
|
|
1122
1698
|
preregisteredAdapters = /* @__PURE__ */ new Map();
|
|
@@ -1281,32 +1857,128 @@ function getPageLoadPromise() {
|
|
|
1281
1857
|
return pageLoadPromise;
|
|
1282
1858
|
}
|
|
1283
1859
|
|
|
1284
|
-
// dist/adapter/canvas-
|
|
1860
|
+
// dist/adapter/canvas-surface.js
|
|
1285
1861
|
var import_env2 = require("@probe.gl/env");
|
|
1286
1862
|
|
|
1287
|
-
// dist/
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
var _CanvasContext = class {
|
|
1300
|
-
static isHTMLCanvas(canvas) {
|
|
1301
|
-
return typeof HTMLCanvasElement !== "undefined" && canvas instanceof HTMLCanvasElement;
|
|
1863
|
+
// dist/adapter/canvas-observer.js
|
|
1864
|
+
var CanvasObserver = class {
|
|
1865
|
+
props;
|
|
1866
|
+
_resizeObserver;
|
|
1867
|
+
_intersectionObserver;
|
|
1868
|
+
_observeDevicePixelRatioTimeout = null;
|
|
1869
|
+
_observeDevicePixelRatioMediaQuery = null;
|
|
1870
|
+
_handleDevicePixelRatioChange = () => this._refreshDevicePixelRatio();
|
|
1871
|
+
_trackPositionInterval = null;
|
|
1872
|
+
_started = false;
|
|
1873
|
+
get started() {
|
|
1874
|
+
return this._started;
|
|
1302
1875
|
}
|
|
1303
|
-
|
|
1304
|
-
|
|
1876
|
+
constructor(props) {
|
|
1877
|
+
this.props = props;
|
|
1305
1878
|
}
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1879
|
+
start() {
|
|
1880
|
+
if (this._started || !this.props.canvas) {
|
|
1881
|
+
return;
|
|
1882
|
+
}
|
|
1883
|
+
this._started = true;
|
|
1884
|
+
this._intersectionObserver ||= new IntersectionObserver((entries) => this.props.onIntersection(entries));
|
|
1885
|
+
this._resizeObserver ||= new ResizeObserver((entries) => this.props.onResize(entries));
|
|
1886
|
+
this._intersectionObserver.observe(this.props.canvas);
|
|
1887
|
+
try {
|
|
1888
|
+
this._resizeObserver.observe(this.props.canvas, { box: "device-pixel-content-box" });
|
|
1889
|
+
} catch {
|
|
1890
|
+
this._resizeObserver.observe(this.props.canvas, { box: "content-box" });
|
|
1891
|
+
}
|
|
1892
|
+
this._observeDevicePixelRatioTimeout = setTimeout(() => this._refreshDevicePixelRatio(), 0);
|
|
1893
|
+
if (this.props.trackPosition) {
|
|
1894
|
+
this._trackPosition();
|
|
1895
|
+
}
|
|
1896
|
+
}
|
|
1897
|
+
stop() {
|
|
1898
|
+
var _a, _b;
|
|
1899
|
+
if (!this._started) {
|
|
1900
|
+
return;
|
|
1901
|
+
}
|
|
1902
|
+
this._started = false;
|
|
1903
|
+
if (this._observeDevicePixelRatioTimeout) {
|
|
1904
|
+
clearTimeout(this._observeDevicePixelRatioTimeout);
|
|
1905
|
+
this._observeDevicePixelRatioTimeout = null;
|
|
1906
|
+
}
|
|
1907
|
+
if (this._observeDevicePixelRatioMediaQuery) {
|
|
1908
|
+
this._observeDevicePixelRatioMediaQuery.removeEventListener("change", this._handleDevicePixelRatioChange);
|
|
1909
|
+
this._observeDevicePixelRatioMediaQuery = null;
|
|
1910
|
+
}
|
|
1911
|
+
if (this._trackPositionInterval) {
|
|
1912
|
+
clearInterval(this._trackPositionInterval);
|
|
1913
|
+
this._trackPositionInterval = null;
|
|
1914
|
+
}
|
|
1915
|
+
(_a = this._resizeObserver) == null ? void 0 : _a.disconnect();
|
|
1916
|
+
(_b = this._intersectionObserver) == null ? void 0 : _b.disconnect();
|
|
1917
|
+
}
|
|
1918
|
+
_refreshDevicePixelRatio() {
|
|
1919
|
+
var _a;
|
|
1920
|
+
if (!this._started) {
|
|
1921
|
+
return;
|
|
1922
|
+
}
|
|
1923
|
+
this.props.onDevicePixelRatioChange();
|
|
1924
|
+
(_a = this._observeDevicePixelRatioMediaQuery) == null ? void 0 : _a.removeEventListener("change", this._handleDevicePixelRatioChange);
|
|
1925
|
+
this._observeDevicePixelRatioMediaQuery = matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`);
|
|
1926
|
+
this._observeDevicePixelRatioMediaQuery.addEventListener("change", this._handleDevicePixelRatioChange, { once: true });
|
|
1927
|
+
}
|
|
1928
|
+
_trackPosition(intervalMs = 100) {
|
|
1929
|
+
if (this._trackPositionInterval) {
|
|
1930
|
+
return;
|
|
1931
|
+
}
|
|
1932
|
+
this._trackPositionInterval = setInterval(() => {
|
|
1933
|
+
if (!this._started) {
|
|
1934
|
+
if (this._trackPositionInterval) {
|
|
1935
|
+
clearInterval(this._trackPositionInterval);
|
|
1936
|
+
this._trackPositionInterval = null;
|
|
1937
|
+
}
|
|
1938
|
+
} else {
|
|
1939
|
+
this.props.onPositionChange();
|
|
1940
|
+
}
|
|
1941
|
+
}, intervalMs);
|
|
1942
|
+
}
|
|
1943
|
+
};
|
|
1944
|
+
|
|
1945
|
+
// dist/utils/promise-utils.js
|
|
1946
|
+
function withResolvers() {
|
|
1947
|
+
let resolve;
|
|
1948
|
+
let reject;
|
|
1949
|
+
const promise = new Promise((_resolve, _reject) => {
|
|
1950
|
+
resolve = _resolve;
|
|
1951
|
+
reject = _reject;
|
|
1952
|
+
});
|
|
1953
|
+
return { promise, resolve, reject };
|
|
1954
|
+
}
|
|
1955
|
+
|
|
1956
|
+
// dist/utils/assert.js
|
|
1957
|
+
function assert(condition, message) {
|
|
1958
|
+
var _a;
|
|
1959
|
+
if (!condition) {
|
|
1960
|
+
const error = new Error(message ?? "luma.gl assertion failed.");
|
|
1961
|
+
(_a = Error.captureStackTrace) == null ? void 0 : _a.call(Error, error, assert);
|
|
1962
|
+
throw error;
|
|
1963
|
+
}
|
|
1964
|
+
}
|
|
1965
|
+
function assertDefined(value, message) {
|
|
1966
|
+
assert(value, message);
|
|
1967
|
+
return value;
|
|
1968
|
+
}
|
|
1969
|
+
|
|
1970
|
+
// dist/adapter/canvas-surface.js
|
|
1971
|
+
var _CanvasSurface = class {
|
|
1972
|
+
static isHTMLCanvas(canvas) {
|
|
1973
|
+
return typeof HTMLCanvasElement !== "undefined" && canvas instanceof HTMLCanvasElement;
|
|
1974
|
+
}
|
|
1975
|
+
static isOffscreenCanvas(canvas) {
|
|
1976
|
+
return typeof OffscreenCanvas !== "undefined" && canvas instanceof OffscreenCanvas;
|
|
1977
|
+
}
|
|
1978
|
+
id;
|
|
1979
|
+
props;
|
|
1980
|
+
canvas;
|
|
1981
|
+
/** Handle to HTML canvas */
|
|
1310
1982
|
htmlCanvas;
|
|
1311
1983
|
/** Handle to wrapped OffScreenCanvas */
|
|
1312
1984
|
offscreenCanvas;
|
|
@@ -1330,17 +2002,21 @@ var _CanvasContext = class {
|
|
|
1330
2002
|
drawingBufferWidth;
|
|
1331
2003
|
/** Height of drawing buffer: automatically tracks this.pixelHeight if props.autoResize is true */
|
|
1332
2004
|
drawingBufferHeight;
|
|
2005
|
+
/** Resolves when the canvas is initialized, i.e. when the ResizeObserver has updated the pixel size */
|
|
1333
2006
|
_initializedResolvers = withResolvers();
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
_position;
|
|
2007
|
+
_canvasObserver;
|
|
2008
|
+
/** Position of the canvas in the document, updated by a timer */
|
|
2009
|
+
_position = [0, 0];
|
|
2010
|
+
/** Whether this canvas context has been destroyed */
|
|
1337
2011
|
destroyed = false;
|
|
2012
|
+
/** Whether the drawing buffer size needs to be resized (deferred resizing to avoid flicker) */
|
|
2013
|
+
_needsDrawingBufferResize = true;
|
|
1338
2014
|
toString() {
|
|
1339
2015
|
return `${this[Symbol.toStringTag]}(${this.id})`;
|
|
1340
2016
|
}
|
|
1341
2017
|
constructor(props) {
|
|
1342
2018
|
var _a, _b;
|
|
1343
|
-
this.props = { ...
|
|
2019
|
+
this.props = { ..._CanvasSurface.defaultProps, ...props };
|
|
1344
2020
|
props = this.props;
|
|
1345
2021
|
this.initialized = this._initializedResolvers.promise;
|
|
1346
2022
|
if (!(0, import_env2.isBrowser)()) {
|
|
@@ -1352,11 +2028,11 @@ var _CanvasContext = class {
|
|
|
1352
2028
|
} else {
|
|
1353
2029
|
this.canvas = props.canvas;
|
|
1354
2030
|
}
|
|
1355
|
-
if (
|
|
2031
|
+
if (_CanvasSurface.isHTMLCanvas(this.canvas)) {
|
|
1356
2032
|
this.id = props.id || this.canvas.id;
|
|
1357
2033
|
this.type = "html-canvas";
|
|
1358
2034
|
this.htmlCanvas = this.canvas;
|
|
1359
|
-
} else if (
|
|
2035
|
+
} else if (_CanvasSurface.isOffscreenCanvas(this.canvas)) {
|
|
1360
2036
|
this.id = props.id || "offscreen-canvas";
|
|
1361
2037
|
this.type = "offscreen-canvas";
|
|
1362
2038
|
this.offscreenCanvas = this.canvas;
|
|
@@ -1372,23 +2048,21 @@ var _CanvasContext = class {
|
|
|
1372
2048
|
this.drawingBufferHeight = this.canvas.height;
|
|
1373
2049
|
this.devicePixelRatio = globalThis.devicePixelRatio || 1;
|
|
1374
2050
|
this._position = [0, 0];
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
this.
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
}
|
|
1384
|
-
setTimeout(() => this._observeDevicePixelRatio(), 0);
|
|
1385
|
-
if (this.props.trackPosition) {
|
|
1386
|
-
this._trackPosition();
|
|
1387
|
-
}
|
|
1388
|
-
}
|
|
2051
|
+
this._canvasObserver = new CanvasObserver({
|
|
2052
|
+
canvas: this.htmlCanvas,
|
|
2053
|
+
trackPosition: this.props.trackPosition,
|
|
2054
|
+
onResize: (entries) => this._handleResize(entries),
|
|
2055
|
+
onIntersection: (entries) => this._handleIntersection(entries),
|
|
2056
|
+
onDevicePixelRatioChange: () => this._observeDevicePixelRatio(),
|
|
2057
|
+
onPositionChange: () => this.updatePosition()
|
|
2058
|
+
});
|
|
1389
2059
|
}
|
|
1390
2060
|
destroy() {
|
|
1391
|
-
this.destroyed
|
|
2061
|
+
if (!this.destroyed) {
|
|
2062
|
+
this.destroyed = true;
|
|
2063
|
+
this._stopObservers();
|
|
2064
|
+
this.device = null;
|
|
2065
|
+
}
|
|
1392
2066
|
}
|
|
1393
2067
|
setProps(props) {
|
|
1394
2068
|
if ("useDevicePixels" in props) {
|
|
@@ -1397,55 +2071,41 @@ var _CanvasContext = class {
|
|
|
1397
2071
|
}
|
|
1398
2072
|
return this;
|
|
1399
2073
|
}
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
*/
|
|
2074
|
+
/** Returns a framebuffer with properly resized current 'swap chain' textures */
|
|
2075
|
+
getCurrentFramebuffer(options) {
|
|
2076
|
+
this._resizeDrawingBufferIfNeeded();
|
|
2077
|
+
return this._getCurrentFramebuffer(options);
|
|
2078
|
+
}
|
|
1406
2079
|
getCSSSize() {
|
|
1407
2080
|
return [this.cssWidth, this.cssHeight];
|
|
1408
2081
|
}
|
|
1409
2082
|
getPosition() {
|
|
1410
2083
|
return this._position;
|
|
1411
2084
|
}
|
|
1412
|
-
/**
|
|
1413
|
-
* Returns the size covered by the canvas in actual device pixels.
|
|
1414
|
-
* @note This can be different from the 'CSS' size of a canvas due to DPR scaling, and rounding to integer pixels
|
|
1415
|
-
* @note This is independent of the canvas' internal drawing buffer size (.width, .height).
|
|
1416
|
-
*/
|
|
1417
2085
|
getDevicePixelSize() {
|
|
1418
2086
|
return [this.devicePixelWidth, this.devicePixelHeight];
|
|
1419
2087
|
}
|
|
1420
|
-
/** Get the drawing buffer size (number of pixels GPU is rendering into, can be different from CSS size) */
|
|
1421
2088
|
getDrawingBufferSize() {
|
|
1422
2089
|
return [this.drawingBufferWidth, this.drawingBufferHeight];
|
|
1423
2090
|
}
|
|
1424
|
-
/** Returns the biggest allowed framebuffer size. @todo Allow the application to limit this? */
|
|
1425
2091
|
getMaxDrawingBufferSize() {
|
|
1426
2092
|
const maxTextureDimension = this.device.limits.maxTextureDimension2D;
|
|
1427
2093
|
return [maxTextureDimension, maxTextureDimension];
|
|
1428
2094
|
}
|
|
1429
|
-
/** Update the canvas drawing buffer size. Called automatically if props.autoResize is true. */
|
|
1430
2095
|
setDrawingBufferSize(width, height) {
|
|
1431
|
-
|
|
1432
|
-
|
|
2096
|
+
width = Math.floor(width);
|
|
2097
|
+
height = Math.floor(height);
|
|
2098
|
+
if (this.drawingBufferWidth === width && this.drawingBufferHeight === height) {
|
|
2099
|
+
return;
|
|
2100
|
+
}
|
|
1433
2101
|
this.drawingBufferWidth = width;
|
|
1434
2102
|
this.drawingBufferHeight = height;
|
|
2103
|
+
this._needsDrawingBufferResize = true;
|
|
1435
2104
|
}
|
|
1436
|
-
/**
|
|
1437
|
-
* Returns the current DPR (number of physical pixels per CSS pixel), if props.useDevicePixels is true
|
|
1438
|
-
* @note This can be a fractional (non-integer) number, e.g. when the user zooms in the browser.
|
|
1439
|
-
* @note This function handles the non-HTML canvas cases
|
|
1440
|
-
*/
|
|
1441
2105
|
getDevicePixelRatio() {
|
|
1442
|
-
const
|
|
1443
|
-
return
|
|
2106
|
+
const devicePixelRatio2 = typeof window !== "undefined" && window.devicePixelRatio;
|
|
2107
|
+
return devicePixelRatio2 || 1;
|
|
1444
2108
|
}
|
|
1445
|
-
// DEPRECATED METHODS
|
|
1446
|
-
/**
|
|
1447
|
-
* Maps CSS pixel position to device pixel position
|
|
1448
|
-
*/
|
|
1449
2109
|
cssToDevicePixels(cssPixel, yInvert = true) {
|
|
1450
2110
|
const ratio = this.cssToDeviceRatio();
|
|
1451
2111
|
const [width, height] = this.getDrawingBufferSize();
|
|
@@ -1455,10 +2115,10 @@ var _CanvasContext = class {
|
|
|
1455
2115
|
getPixelSize() {
|
|
1456
2116
|
return this.getDevicePixelSize();
|
|
1457
2117
|
}
|
|
1458
|
-
/** @deprecated
|
|
2118
|
+
/** @deprecated Use the current drawing buffer size for projection setup. */
|
|
1459
2119
|
getAspect() {
|
|
1460
|
-
const [width, height] = this.
|
|
1461
|
-
return width / height;
|
|
2120
|
+
const [width, height] = this.getDrawingBufferSize();
|
|
2121
|
+
return width > 0 && height > 0 ? width / height : 1;
|
|
1462
2122
|
}
|
|
1463
2123
|
/** @deprecated Returns multiplier need to convert CSS size to Device size */
|
|
1464
2124
|
cssToDeviceRatio() {
|
|
@@ -1474,19 +2134,41 @@ var _CanvasContext = class {
|
|
|
1474
2134
|
resize(size) {
|
|
1475
2135
|
this.setDrawingBufferSize(size.width, size.height);
|
|
1476
2136
|
}
|
|
1477
|
-
// IMPLEMENTATION
|
|
1478
|
-
/**
|
|
1479
|
-
* Allows subclass constructor to override the canvas id for auto created canvases.
|
|
1480
|
-
* This can really help when debugging DOM in apps that create multiple devices
|
|
1481
|
-
*/
|
|
1482
2137
|
_setAutoCreatedCanvasId(id) {
|
|
1483
2138
|
var _a;
|
|
1484
2139
|
if (((_a = this.htmlCanvas) == null ? void 0 : _a.id) === "lumagl-auto-created-canvas") {
|
|
1485
2140
|
this.htmlCanvas.id = id;
|
|
1486
2141
|
}
|
|
1487
2142
|
}
|
|
1488
|
-
/**
|
|
2143
|
+
/**
|
|
2144
|
+
* Starts DOM observation after the derived context and its device are fully initialized.
|
|
2145
|
+
*
|
|
2146
|
+
* `CanvasSurface` construction runs before subclasses can assign `this.device`, and the
|
|
2147
|
+
* default WebGL canvas context is created before `WebGLDevice` has initialized `limits`,
|
|
2148
|
+
* `features`, and the rest of its runtime state. Deferring observer startup avoids early
|
|
2149
|
+
* `ResizeObserver` and DPR callbacks running against a partially initialized device.
|
|
2150
|
+
*/
|
|
2151
|
+
_startObservers() {
|
|
2152
|
+
if (this.destroyed) {
|
|
2153
|
+
return;
|
|
2154
|
+
}
|
|
2155
|
+
this._canvasObserver.start();
|
|
2156
|
+
}
|
|
2157
|
+
/**
|
|
2158
|
+
* Stops all DOM observation and timers associated with a canvas surface.
|
|
2159
|
+
*
|
|
2160
|
+
* This pairs with `_startObservers()` so teardown uses the same lifecycle whether a context is
|
|
2161
|
+
* explicitly destroyed, abandoned during device reuse, or temporarily has not started observing
|
|
2162
|
+
* yet. Centralizing shutdown here keeps resize/DPR/position watchers from surviving past the
|
|
2163
|
+
* lifetime of the owning device.
|
|
2164
|
+
*/
|
|
2165
|
+
_stopObservers() {
|
|
2166
|
+
this._canvasObserver.stop();
|
|
2167
|
+
}
|
|
1489
2168
|
_handleIntersection(entries) {
|
|
2169
|
+
if (this.destroyed) {
|
|
2170
|
+
return;
|
|
2171
|
+
}
|
|
1490
2172
|
const entry = entries.find((entry_) => entry_.target === this.canvas);
|
|
1491
2173
|
if (!entry) {
|
|
1492
2174
|
return;
|
|
@@ -1497,22 +2179,21 @@ var _CanvasContext = class {
|
|
|
1497
2179
|
this.device.props.onVisibilityChange(this);
|
|
1498
2180
|
}
|
|
1499
2181
|
}
|
|
1500
|
-
/**
|
|
1501
|
-
* Reacts to an observed resize by using the most accurate pixel size information the browser can provide
|
|
1502
|
-
* @see https://web.dev/articles/device-pixel-content-box
|
|
1503
|
-
* @see https://webgpufundamentals.org/webgpu/lessons/webgpu-resizing-the-canvas.html
|
|
1504
|
-
*/
|
|
1505
2182
|
_handleResize(entries) {
|
|
1506
|
-
var _a, _b;
|
|
2183
|
+
var _a, _b, _c, _d, _e;
|
|
2184
|
+
if (this.destroyed) {
|
|
2185
|
+
return;
|
|
2186
|
+
}
|
|
1507
2187
|
const entry = entries.find((entry_) => entry_.target === this.canvas);
|
|
1508
2188
|
if (!entry) {
|
|
1509
2189
|
return;
|
|
1510
2190
|
}
|
|
1511
|
-
|
|
1512
|
-
this.
|
|
2191
|
+
const contentBoxSize = assertDefined((_a = entry.contentBoxSize) == null ? void 0 : _a[0]);
|
|
2192
|
+
this.cssWidth = contentBoxSize.inlineSize;
|
|
2193
|
+
this.cssHeight = contentBoxSize.blockSize;
|
|
1513
2194
|
const oldPixelSize = this.getDevicePixelSize();
|
|
1514
|
-
const devicePixelWidth = ((
|
|
1515
|
-
const devicePixelHeight = ((
|
|
2195
|
+
const devicePixelWidth = ((_c = (_b = entry.devicePixelContentBoxSize) == null ? void 0 : _b[0]) == null ? void 0 : _c.inlineSize) || contentBoxSize.inlineSize * devicePixelRatio;
|
|
2196
|
+
const devicePixelHeight = ((_e = (_d = entry.devicePixelContentBoxSize) == null ? void 0 : _d[0]) == null ? void 0 : _e.blockSize) || contentBoxSize.blockSize * devicePixelRatio;
|
|
1516
2197
|
const [maxDevicePixelWidth, maxDevicePixelHeight] = this.getMaxDrawingBufferSize();
|
|
1517
2198
|
this.devicePixelWidth = Math.max(1, Math.min(devicePixelWidth, maxDevicePixelWidth));
|
|
1518
2199
|
this.devicePixelHeight = Math.max(1, Math.min(devicePixelHeight, maxDevicePixelHeight));
|
|
@@ -1522,44 +2203,46 @@ var _CanvasContext = class {
|
|
|
1522
2203
|
_updateDrawingBufferSize() {
|
|
1523
2204
|
if (this.props.autoResize) {
|
|
1524
2205
|
if (typeof this.props.useDevicePixels === "number") {
|
|
1525
|
-
const
|
|
1526
|
-
this.setDrawingBufferSize(this.cssWidth *
|
|
2206
|
+
const devicePixelRatio2 = this.props.useDevicePixels;
|
|
2207
|
+
this.setDrawingBufferSize(this.cssWidth * devicePixelRatio2, this.cssHeight * devicePixelRatio2);
|
|
1527
2208
|
} else if (this.props.useDevicePixels) {
|
|
1528
2209
|
this.setDrawingBufferSize(this.devicePixelWidth, this.devicePixelHeight);
|
|
1529
2210
|
} else {
|
|
1530
2211
|
this.setDrawingBufferSize(this.cssWidth, this.cssHeight);
|
|
1531
2212
|
}
|
|
1532
|
-
this._updateDevice();
|
|
1533
2213
|
}
|
|
1534
2214
|
this._initializedResolvers.resolve();
|
|
1535
2215
|
this.isInitialized = true;
|
|
1536
2216
|
this.updatePosition();
|
|
1537
2217
|
}
|
|
1538
|
-
|
|
2218
|
+
_resizeDrawingBufferIfNeeded() {
|
|
2219
|
+
if (this._needsDrawingBufferResize) {
|
|
2220
|
+
this._needsDrawingBufferResize = false;
|
|
2221
|
+
const sizeChanged = this.drawingBufferWidth !== this.canvas.width || this.drawingBufferHeight !== this.canvas.height;
|
|
2222
|
+
if (sizeChanged) {
|
|
2223
|
+
this.canvas.width = this.drawingBufferWidth;
|
|
2224
|
+
this.canvas.height = this.drawingBufferHeight;
|
|
2225
|
+
this._configureDevice();
|
|
2226
|
+
}
|
|
2227
|
+
}
|
|
2228
|
+
}
|
|
1539
2229
|
_observeDevicePixelRatio() {
|
|
2230
|
+
var _a, _b;
|
|
2231
|
+
if (this.destroyed || !this._canvasObserver.started) {
|
|
2232
|
+
return;
|
|
2233
|
+
}
|
|
1540
2234
|
const oldRatio = this.devicePixelRatio;
|
|
1541
2235
|
this.devicePixelRatio = window.devicePixelRatio;
|
|
1542
2236
|
this.updatePosition();
|
|
1543
|
-
this.device.props.onDevicePixelRatioChange(this, {
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
/** Start tracking positions with a timer */
|
|
1547
|
-
_trackPosition(intervalMs = 100) {
|
|
1548
|
-
const intervalId = setInterval(() => {
|
|
1549
|
-
if (this.destroyed) {
|
|
1550
|
-
clearInterval(intervalId);
|
|
1551
|
-
} else {
|
|
1552
|
-
this.updatePosition();
|
|
1553
|
-
}
|
|
1554
|
-
}, intervalMs);
|
|
2237
|
+
(_b = (_a = this.device.props).onDevicePixelRatioChange) == null ? void 0 : _b.call(_a, this, {
|
|
2238
|
+
oldRatio
|
|
2239
|
+
});
|
|
1555
2240
|
}
|
|
1556
|
-
/**
|
|
1557
|
-
* Calculated the absolute position of the canvas
|
|
1558
|
-
* @note - getBoundingClientRect() is normally cheap but can be expensive
|
|
1559
|
-
* if called before browser has finished a reflow. Should not be the case here.
|
|
1560
|
-
*/
|
|
1561
2241
|
updatePosition() {
|
|
1562
2242
|
var _a, _b, _c;
|
|
2243
|
+
if (this.destroyed) {
|
|
2244
|
+
return;
|
|
2245
|
+
}
|
|
1563
2246
|
const newRect = (_a = this.htmlCanvas) == null ? void 0 : _a.getBoundingClientRect();
|
|
1564
2247
|
if (newRect) {
|
|
1565
2248
|
const position = [newRect.left, newRect.top];
|
|
@@ -1568,13 +2251,15 @@ var _CanvasContext = class {
|
|
|
1568
2251
|
if (positionChanged) {
|
|
1569
2252
|
const oldPosition = this._position;
|
|
1570
2253
|
this._position = position;
|
|
1571
|
-
(_c = (_b = this.device.props).onPositionChange) == null ? void 0 : _c.call(_b, this, {
|
|
2254
|
+
(_c = (_b = this.device.props).onPositionChange) == null ? void 0 : _c.call(_b, this, {
|
|
2255
|
+
oldPosition
|
|
2256
|
+
});
|
|
1572
2257
|
}
|
|
1573
2258
|
}
|
|
1574
2259
|
}
|
|
1575
2260
|
};
|
|
1576
|
-
var
|
|
1577
|
-
__publicField(
|
|
2261
|
+
var CanvasSurface = _CanvasSurface;
|
|
2262
|
+
__publicField(CanvasSurface, "defaultProps", {
|
|
1578
2263
|
id: void 0,
|
|
1579
2264
|
canvas: null,
|
|
1580
2265
|
width: 800,
|
|
@@ -1602,7 +2287,7 @@ function getContainer(container) {
|
|
|
1602
2287
|
}
|
|
1603
2288
|
function getCanvasFromDOM(canvasId) {
|
|
1604
2289
|
const canvas = document.getElementById(canvasId);
|
|
1605
|
-
if (!
|
|
2290
|
+
if (!CanvasSurface.isHTMLCanvas(canvas)) {
|
|
1606
2291
|
throw new Error("Object is not a canvas element");
|
|
1607
2292
|
}
|
|
1608
2293
|
return canvas;
|
|
@@ -1626,33 +2311,40 @@ function scalePixels(pixel, ratio, width, height, yInvert) {
|
|
|
1626
2311
|
const point = pixel;
|
|
1627
2312
|
const x = scaleX(point[0], ratio, width);
|
|
1628
2313
|
let y = scaleY(point[1], ratio, height, yInvert);
|
|
1629
|
-
let
|
|
1630
|
-
const xHigh =
|
|
1631
|
-
|
|
2314
|
+
let temporary = scaleX(point[0] + 1, ratio, width);
|
|
2315
|
+
const xHigh = temporary === width - 1 ? temporary : temporary - 1;
|
|
2316
|
+
temporary = scaleY(point[1] + 1, ratio, height, yInvert);
|
|
1632
2317
|
let yHigh;
|
|
1633
2318
|
if (yInvert) {
|
|
1634
|
-
|
|
2319
|
+
temporary = temporary === 0 ? temporary : temporary + 1;
|
|
1635
2320
|
yHigh = y;
|
|
1636
|
-
y =
|
|
2321
|
+
y = temporary;
|
|
1637
2322
|
} else {
|
|
1638
|
-
yHigh =
|
|
2323
|
+
yHigh = temporary === height - 1 ? temporary : temporary - 1;
|
|
1639
2324
|
}
|
|
1640
2325
|
return {
|
|
1641
2326
|
x,
|
|
1642
2327
|
y,
|
|
1643
|
-
// when ratio < 1, current css pixel and next css pixel may point to same device pixel, set width/height to 1 in those cases.
|
|
1644
2328
|
width: Math.max(xHigh - x + 1, 1),
|
|
1645
2329
|
height: Math.max(yHigh - y + 1, 1)
|
|
1646
2330
|
};
|
|
1647
2331
|
}
|
|
1648
2332
|
function scaleX(x, ratio, width) {
|
|
1649
|
-
|
|
1650
|
-
return r;
|
|
2333
|
+
return Math.min(Math.round(x * ratio), width - 1);
|
|
1651
2334
|
}
|
|
1652
2335
|
function scaleY(y, ratio, height, yInvert) {
|
|
1653
2336
|
return yInvert ? Math.max(0, height - 1 - Math.round(y * ratio)) : Math.min(Math.round(y * ratio), height - 1);
|
|
1654
2337
|
}
|
|
1655
2338
|
|
|
2339
|
+
// dist/adapter/canvas-context.js
|
|
2340
|
+
var CanvasContext = class extends CanvasSurface {
|
|
2341
|
+
};
|
|
2342
|
+
__publicField(CanvasContext, "defaultProps", CanvasSurface.defaultProps);
|
|
2343
|
+
|
|
2344
|
+
// dist/adapter/presentation-context.js
|
|
2345
|
+
var PresentationContext = class extends CanvasSurface {
|
|
2346
|
+
};
|
|
2347
|
+
|
|
1656
2348
|
// dist/adapter/resources/sampler.js
|
|
1657
2349
|
var _Sampler = class extends Resource {
|
|
1658
2350
|
get [Symbol.toStringTag]() {
|
|
@@ -1707,7 +2399,15 @@ var _Texture = class extends Resource {
|
|
|
1707
2399
|
depth;
|
|
1708
2400
|
/** mip levels in this texture */
|
|
1709
2401
|
mipLevels;
|
|
1710
|
-
/**
|
|
2402
|
+
/** sample count */
|
|
2403
|
+
samples;
|
|
2404
|
+
/** Rows are multiples of this length, padded with extra bytes if needed */
|
|
2405
|
+
byteAlignment;
|
|
2406
|
+
/** The ready promise is always resolved. It is provided for type compatibility with DynamicTexture. */
|
|
2407
|
+
ready = Promise.resolve(this);
|
|
2408
|
+
/** isReady is always true. It is provided for type compatibility with DynamicTexture. */
|
|
2409
|
+
isReady = true;
|
|
2410
|
+
/** "Time" of last update. Monotonically increasing timestamp. TODO move to DynamicTexture? */
|
|
1711
2411
|
updateTimestamp;
|
|
1712
2412
|
get [Symbol.toStringTag]() {
|
|
1713
2413
|
return "Texture";
|
|
@@ -1716,7 +2416,7 @@ var _Texture = class extends Resource {
|
|
|
1716
2416
|
return `Texture(${this.id},${this.format},${this.width}x${this.height})`;
|
|
1717
2417
|
}
|
|
1718
2418
|
/** Do not use directly. Create with device.createTexture() */
|
|
1719
|
-
constructor(device, props) {
|
|
2419
|
+
constructor(device, props, backendProps) {
|
|
1720
2420
|
props = _Texture.normalizeProps(device, props);
|
|
1721
2421
|
super(device, props, _Texture.defaultProps);
|
|
1722
2422
|
this.dimension = this.props.dimension;
|
|
@@ -1726,6 +2426,10 @@ var _Texture = class extends Resource {
|
|
|
1726
2426
|
this.height = this.props.height;
|
|
1727
2427
|
this.depth = this.props.depth;
|
|
1728
2428
|
this.mipLevels = this.props.mipLevels;
|
|
2429
|
+
this.samples = this.props.samples || 1;
|
|
2430
|
+
if (this.dimension === "cube") {
|
|
2431
|
+
this.depth = 6;
|
|
2432
|
+
}
|
|
1729
2433
|
if (this.props.width === void 0 || this.props.height === void 0) {
|
|
1730
2434
|
if (device.isExternalImage(props.data)) {
|
|
1731
2435
|
const size = device.getExternalImageSize(props.data);
|
|
@@ -1735,16 +2439,13 @@ var _Texture = class extends Resource {
|
|
|
1735
2439
|
this.width = 1;
|
|
1736
2440
|
this.height = 1;
|
|
1737
2441
|
if (this.props.width === void 0 || this.props.height === void 0) {
|
|
1738
|
-
log.warn(`${this} created with undefined width or height. This is deprecated. Use
|
|
2442
|
+
log.warn(`${this} created with undefined width or height. This is deprecated. Use DynamicTexture instead.`)();
|
|
1739
2443
|
}
|
|
1740
2444
|
}
|
|
1741
2445
|
}
|
|
2446
|
+
this.byteAlignment = (backendProps == null ? void 0 : backendProps.byteAlignment) || 1;
|
|
1742
2447
|
this.updateTimestamp = device.incrementTimestamp();
|
|
1743
2448
|
}
|
|
1744
|
-
/** Set sampler props associated with this texture */
|
|
1745
|
-
setSampler(sampler) {
|
|
1746
|
-
this.sampler = sampler instanceof Sampler ? sampler : this.device.createSampler(sampler);
|
|
1747
|
-
}
|
|
1748
2449
|
/**
|
|
1749
2450
|
* Create a new texture with the same parameters and optionally a different size
|
|
1750
2451
|
* @note Textures are immutable and cannot be resized after creation, but we can create a similar texture with the same parameters but a new size.
|
|
@@ -1753,6 +2454,105 @@ var _Texture = class extends Resource {
|
|
|
1753
2454
|
clone(size) {
|
|
1754
2455
|
return this.device.createTexture({ ...this.props, ...size });
|
|
1755
2456
|
}
|
|
2457
|
+
/** Set sampler props associated with this texture */
|
|
2458
|
+
setSampler(sampler) {
|
|
2459
|
+
this.sampler = sampler instanceof Sampler ? sampler : this.device.createSampler(sampler);
|
|
2460
|
+
}
|
|
2461
|
+
/**
|
|
2462
|
+
* Copy raw image data (bytes) into the texture.
|
|
2463
|
+
*
|
|
2464
|
+
* @note Deprecated compatibility wrapper over {@link writeData}.
|
|
2465
|
+
* @note Uses the same layout defaults and alignment rules as {@link writeData}.
|
|
2466
|
+
* @note Tightly packed CPU uploads can omit `bytesPerRow` and `rowsPerImage`.
|
|
2467
|
+
* @note If the CPU source rows are padded, pass explicit `bytesPerRow` and `rowsPerImage`.
|
|
2468
|
+
* @deprecated Use writeData()
|
|
2469
|
+
*/
|
|
2470
|
+
copyImageData(options) {
|
|
2471
|
+
const { data, depth, ...writeOptions } = options;
|
|
2472
|
+
this.writeData(data, {
|
|
2473
|
+
...writeOptions,
|
|
2474
|
+
depthOrArrayLayers: writeOptions.depthOrArrayLayers ?? depth
|
|
2475
|
+
});
|
|
2476
|
+
}
|
|
2477
|
+
/**
|
|
2478
|
+
* Calculates the memory layout of the texture, required when reading and writing data.
|
|
2479
|
+
* @return the backend-aligned linear layout, in particular bytesPerRow which includes any required padding for buffer copy/read paths
|
|
2480
|
+
*/
|
|
2481
|
+
computeMemoryLayout(options_ = {}) {
|
|
2482
|
+
const options = this._normalizeTextureReadOptions(options_);
|
|
2483
|
+
const { width = this.width, height = this.height, depthOrArrayLayers = this.depth } = options;
|
|
2484
|
+
const { format, byteAlignment } = this;
|
|
2485
|
+
return textureFormatDecoder.computeMemoryLayout({
|
|
2486
|
+
format,
|
|
2487
|
+
width,
|
|
2488
|
+
height,
|
|
2489
|
+
depth: depthOrArrayLayers,
|
|
2490
|
+
byteAlignment
|
|
2491
|
+
});
|
|
2492
|
+
}
|
|
2493
|
+
/**
|
|
2494
|
+
* Read the contents of a texture into a GPU Buffer.
|
|
2495
|
+
* @returns A Buffer containing the texture data.
|
|
2496
|
+
*
|
|
2497
|
+
* @note The memory layout of the texture data is determined by the texture format and dimensions.
|
|
2498
|
+
* @note The application can call Texture.computeMemoryLayout() to compute the backend-aligned layout.
|
|
2499
|
+
* @note The application can call Buffer.readAsync() to read the returned buffer on the CPU.
|
|
2500
|
+
* @note The destination buffer must be supplied by the caller and must be large enough for the requested region.
|
|
2501
|
+
* @note On WebGPU this corresponds to a texture-to-buffer copy and uses buffer-copy alignment rules.
|
|
2502
|
+
* @note On WebGL, luma.gl emulates the same logical readback behavior.
|
|
2503
|
+
*/
|
|
2504
|
+
readBuffer(options, buffer) {
|
|
2505
|
+
throw new Error("readBuffer not implemented");
|
|
2506
|
+
}
|
|
2507
|
+
/**
|
|
2508
|
+
* Reads data from a texture into an ArrayBuffer.
|
|
2509
|
+
* @returns An ArrayBuffer containing the texture data.
|
|
2510
|
+
*
|
|
2511
|
+
* @note The memory layout of the texture data is determined by the texture format and dimensions.
|
|
2512
|
+
* @note The application can call Texture.computeMemoryLayout() to compute the layout.
|
|
2513
|
+
* @deprecated Use Texture.readBuffer() with an explicit destination buffer, or DynamicTexture.readAsync() for convenience readback.
|
|
2514
|
+
*/
|
|
2515
|
+
readDataAsync(options) {
|
|
2516
|
+
throw new Error("readBuffer not implemented");
|
|
2517
|
+
}
|
|
2518
|
+
/**
|
|
2519
|
+
* Writes a GPU Buffer into a texture.
|
|
2520
|
+
*
|
|
2521
|
+
* @param buffer - Source GPU buffer.
|
|
2522
|
+
* @param options - Destination subresource, extent, and source layout options.
|
|
2523
|
+
* @note The memory layout of the texture data is determined by the texture format and dimensions.
|
|
2524
|
+
* @note The application can call Texture.computeMemoryLayout() to compute the backend-aligned layout.
|
|
2525
|
+
* @note On WebGPU this corresponds to a buffer-to-texture copy and uses buffer-copy alignment rules.
|
|
2526
|
+
* @note On WebGL, luma.gl emulates the same destination and layout semantics.
|
|
2527
|
+
*/
|
|
2528
|
+
writeBuffer(buffer, options) {
|
|
2529
|
+
throw new Error("readBuffer not implemented");
|
|
2530
|
+
}
|
|
2531
|
+
/**
|
|
2532
|
+
* Writes an array buffer into a texture.
|
|
2533
|
+
*
|
|
2534
|
+
* @param data - Source texel data.
|
|
2535
|
+
* @param options - Destination subresource, extent, and source layout options.
|
|
2536
|
+
* @note If `bytesPerRow` and `rowsPerImage` are omitted, luma.gl computes a tightly packed CPU-memory layout for the requested region.
|
|
2537
|
+
* @note On WebGPU this corresponds to `GPUQueue.writeTexture()` and does not implicitly pad rows to 256 bytes.
|
|
2538
|
+
* @note On WebGL, padded CPU data is supported via the same `bytesPerRow` and `rowsPerImage` options.
|
|
2539
|
+
*/
|
|
2540
|
+
writeData(data, options) {
|
|
2541
|
+
throw new Error("readBuffer not implemented");
|
|
2542
|
+
}
|
|
2543
|
+
// IMPLEMENTATION SPECIFIC
|
|
2544
|
+
/**
|
|
2545
|
+
* WebGL can read data synchronously.
|
|
2546
|
+
* @note While it is convenient, the performance penalty is very significant
|
|
2547
|
+
*/
|
|
2548
|
+
readDataSyncWebGL(options) {
|
|
2549
|
+
throw new Error("readDataSyncWebGL not available");
|
|
2550
|
+
}
|
|
2551
|
+
/** Generate mipmaps (WebGL only) */
|
|
2552
|
+
generateMipmapsWebGL() {
|
|
2553
|
+
throw new Error("generateMipmapsWebGL not available");
|
|
2554
|
+
}
|
|
2555
|
+
// HELPERS
|
|
1756
2556
|
/** Ensure we have integer coordinates */
|
|
1757
2557
|
static normalizeProps(device, props) {
|
|
1758
2558
|
const newProps = { ...props };
|
|
@@ -1765,7 +2565,6 @@ var _Texture = class extends Resource {
|
|
|
1765
2565
|
}
|
|
1766
2566
|
return newProps;
|
|
1767
2567
|
}
|
|
1768
|
-
// HELPERS
|
|
1769
2568
|
/** Initialize texture with supplied props */
|
|
1770
2569
|
// eslint-disable-next-line max-statements
|
|
1771
2570
|
_initializeData(data) {
|
|
@@ -1799,23 +2598,148 @@ var _Texture = class extends Resource {
|
|
|
1799
2598
|
}
|
|
1800
2599
|
}
|
|
1801
2600
|
_normalizeCopyImageDataOptions(options_) {
|
|
1802
|
-
const {
|
|
1803
|
-
const options = {
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
}
|
|
1808
|
-
options.bytesPerRow = options_.bytesPerRow || width * (info.bytesPerPixel || 4);
|
|
1809
|
-
options.rowsPerImage = options_.rowsPerImage || height;
|
|
1810
|
-
return options;
|
|
2601
|
+
const { data, depth, ...writeOptions } = options_;
|
|
2602
|
+
const options = this._normalizeTextureWriteOptions({
|
|
2603
|
+
...writeOptions,
|
|
2604
|
+
depthOrArrayLayers: writeOptions.depthOrArrayLayers ?? depth
|
|
2605
|
+
});
|
|
2606
|
+
return { data, depth: options.depthOrArrayLayers, ...options };
|
|
1811
2607
|
}
|
|
1812
2608
|
_normalizeCopyExternalImageOptions(options_) {
|
|
2609
|
+
const optionsWithoutUndefined = _Texture._omitUndefined(options_);
|
|
2610
|
+
const mipLevel = optionsWithoutUndefined.mipLevel ?? 0;
|
|
2611
|
+
const mipLevelSize = this._getMipLevelSize(mipLevel);
|
|
1813
2612
|
const size = this.device.getExternalImageSize(options_.image);
|
|
1814
|
-
const options = {
|
|
1815
|
-
|
|
1816
|
-
|
|
2613
|
+
const options = {
|
|
2614
|
+
..._Texture.defaultCopyExternalImageOptions,
|
|
2615
|
+
...mipLevelSize,
|
|
2616
|
+
...size,
|
|
2617
|
+
...optionsWithoutUndefined
|
|
2618
|
+
};
|
|
2619
|
+
options.width = Math.min(options.width, mipLevelSize.width - options.x);
|
|
2620
|
+
options.height = Math.min(options.height, mipLevelSize.height - options.y);
|
|
2621
|
+
options.depth = Math.min(options.depth, mipLevelSize.depthOrArrayLayers - options.z);
|
|
2622
|
+
return options;
|
|
2623
|
+
}
|
|
2624
|
+
_normalizeTextureReadOptions(options_) {
|
|
2625
|
+
const optionsWithoutUndefined = _Texture._omitUndefined(options_);
|
|
2626
|
+
const mipLevel = optionsWithoutUndefined.mipLevel ?? 0;
|
|
2627
|
+
const mipLevelSize = this._getMipLevelSize(mipLevel);
|
|
2628
|
+
const options = {
|
|
2629
|
+
..._Texture.defaultTextureReadOptions,
|
|
2630
|
+
...mipLevelSize,
|
|
2631
|
+
...optionsWithoutUndefined
|
|
2632
|
+
};
|
|
2633
|
+
options.width = Math.min(options.width, mipLevelSize.width - options.x);
|
|
2634
|
+
options.height = Math.min(options.height, mipLevelSize.height - options.y);
|
|
2635
|
+
options.depthOrArrayLayers = Math.min(options.depthOrArrayLayers, mipLevelSize.depthOrArrayLayers - options.z);
|
|
2636
|
+
return options;
|
|
2637
|
+
}
|
|
2638
|
+
/**
|
|
2639
|
+
* Normalizes a texture read request and validates the color-only readback contract used by the
|
|
2640
|
+
* current texture read APIs. Supported dimensions are `2d`, `cube`, `cube-array`,
|
|
2641
|
+
* `2d-array`, and `3d`.
|
|
2642
|
+
*
|
|
2643
|
+
* @throws if the texture format, aspect, or dimension is not supported by the first-pass
|
|
2644
|
+
* color-read implementation.
|
|
2645
|
+
*/
|
|
2646
|
+
_getSupportedColorReadOptions(options_) {
|
|
2647
|
+
const options = this._normalizeTextureReadOptions(options_);
|
|
2648
|
+
const formatInfo = textureFormatDecoder.getInfo(this.format);
|
|
2649
|
+
this._validateColorReadAspect(options);
|
|
2650
|
+
this._validateColorReadFormat(formatInfo);
|
|
2651
|
+
switch (this.dimension) {
|
|
2652
|
+
case "2d":
|
|
2653
|
+
case "cube":
|
|
2654
|
+
case "cube-array":
|
|
2655
|
+
case "2d-array":
|
|
2656
|
+
case "3d":
|
|
2657
|
+
return options;
|
|
2658
|
+
default:
|
|
2659
|
+
throw new Error(`${this} color readback does not support ${this.dimension} textures`);
|
|
2660
|
+
}
|
|
2661
|
+
}
|
|
2662
|
+
/** Validates that a read request targets the full color aspect of the texture. */
|
|
2663
|
+
_validateColorReadAspect(options) {
|
|
2664
|
+
if (options.aspect !== "all") {
|
|
2665
|
+
throw new Error(`${this} color readback only supports aspect 'all'`);
|
|
2666
|
+
}
|
|
2667
|
+
}
|
|
2668
|
+
/** Validates that a read request targets an uncompressed color-renderable texture format. */
|
|
2669
|
+
_validateColorReadFormat(formatInfo) {
|
|
2670
|
+
if (formatInfo.compressed) {
|
|
2671
|
+
throw new Error(`${this} color readback does not support compressed formats (${this.format})`);
|
|
2672
|
+
}
|
|
2673
|
+
switch (formatInfo.attachment) {
|
|
2674
|
+
case "color":
|
|
2675
|
+
return;
|
|
2676
|
+
case "depth":
|
|
2677
|
+
throw new Error(`${this} color readback does not support depth formats (${this.format})`);
|
|
2678
|
+
case "stencil":
|
|
2679
|
+
throw new Error(`${this} color readback does not support stencil formats (${this.format})`);
|
|
2680
|
+
case "depth-stencil":
|
|
2681
|
+
throw new Error(`${this} color readback does not support depth-stencil formats (${this.format})`);
|
|
2682
|
+
default:
|
|
2683
|
+
throw new Error(`${this} color readback does not support format ${this.format}`);
|
|
2684
|
+
}
|
|
2685
|
+
}
|
|
2686
|
+
_normalizeTextureWriteOptions(options_) {
|
|
2687
|
+
const optionsWithoutUndefined = _Texture._omitUndefined(options_);
|
|
2688
|
+
const mipLevel = optionsWithoutUndefined.mipLevel ?? 0;
|
|
2689
|
+
const mipLevelSize = this._getMipLevelSize(mipLevel);
|
|
2690
|
+
const options = {
|
|
2691
|
+
..._Texture.defaultTextureWriteOptions,
|
|
2692
|
+
...mipLevelSize,
|
|
2693
|
+
...optionsWithoutUndefined
|
|
2694
|
+
};
|
|
2695
|
+
options.width = Math.min(options.width, mipLevelSize.width - options.x);
|
|
2696
|
+
options.height = Math.min(options.height, mipLevelSize.height - options.y);
|
|
2697
|
+
options.depthOrArrayLayers = Math.min(options.depthOrArrayLayers, mipLevelSize.depthOrArrayLayers - options.z);
|
|
2698
|
+
const layout = textureFormatDecoder.computeMemoryLayout({
|
|
2699
|
+
format: this.format,
|
|
2700
|
+
width: options.width,
|
|
2701
|
+
height: options.height,
|
|
2702
|
+
depth: options.depthOrArrayLayers,
|
|
2703
|
+
byteAlignment: this.byteAlignment
|
|
2704
|
+
});
|
|
2705
|
+
const minimumBytesPerRow = layout.bytesPerPixel * options.width;
|
|
2706
|
+
options.bytesPerRow = optionsWithoutUndefined.bytesPerRow ?? layout.bytesPerRow;
|
|
2707
|
+
options.rowsPerImage = optionsWithoutUndefined.rowsPerImage ?? options.height;
|
|
2708
|
+
if (options.bytesPerRow < minimumBytesPerRow) {
|
|
2709
|
+
throw new Error(`bytesPerRow (${options.bytesPerRow}) must be at least ${minimumBytesPerRow} for ${this.format}`);
|
|
2710
|
+
}
|
|
2711
|
+
if (options.rowsPerImage < options.height) {
|
|
2712
|
+
throw new Error(`rowsPerImage (${options.rowsPerImage}) must be at least ${options.height} for ${this.format}`);
|
|
2713
|
+
}
|
|
2714
|
+
const bytesPerPixel = this.device.getTextureFormatInfo(this.format).bytesPerPixel;
|
|
2715
|
+
if (bytesPerPixel && options.bytesPerRow % bytesPerPixel !== 0) {
|
|
2716
|
+
throw new Error(`bytesPerRow (${options.bytesPerRow}) must be a multiple of bytesPerPixel (${bytesPerPixel}) for ${this.format}`);
|
|
2717
|
+
}
|
|
1817
2718
|
return options;
|
|
1818
2719
|
}
|
|
2720
|
+
_getMipLevelSize(mipLevel) {
|
|
2721
|
+
const width = Math.max(1, this.width >> mipLevel);
|
|
2722
|
+
const height = this.baseDimension === "1d" ? 1 : Math.max(1, this.height >> mipLevel);
|
|
2723
|
+
const depthOrArrayLayers = this.dimension === "3d" ? Math.max(1, this.depth >> mipLevel) : this.depth;
|
|
2724
|
+
return { width, height, depthOrArrayLayers };
|
|
2725
|
+
}
|
|
2726
|
+
getAllocatedByteLength() {
|
|
2727
|
+
let allocatedByteLength = 0;
|
|
2728
|
+
for (let mipLevel = 0; mipLevel < this.mipLevels; mipLevel++) {
|
|
2729
|
+
const { width, height, depthOrArrayLayers } = this._getMipLevelSize(mipLevel);
|
|
2730
|
+
allocatedByteLength += textureFormatDecoder.computeMemoryLayout({
|
|
2731
|
+
format: this.format,
|
|
2732
|
+
width,
|
|
2733
|
+
height,
|
|
2734
|
+
depth: depthOrArrayLayers,
|
|
2735
|
+
byteAlignment: 1
|
|
2736
|
+
}).byteLength;
|
|
2737
|
+
}
|
|
2738
|
+
return allocatedByteLength * this.samples;
|
|
2739
|
+
}
|
|
2740
|
+
static _omitUndefined(options) {
|
|
2741
|
+
return Object.fromEntries(Object.entries(options).filter(([, value]) => value !== void 0));
|
|
2742
|
+
}
|
|
1819
2743
|
};
|
|
1820
2744
|
var Texture = _Texture;
|
|
1821
2745
|
/** The texture can be bound for use as a sampled texture in a shader */
|
|
@@ -1832,13 +2756,12 @@ __publicField(Texture, "COPY_DST", 2);
|
|
|
1832
2756
|
__publicField(Texture, "TEXTURE", 4);
|
|
1833
2757
|
/** @deprecated Use Texture.RENDER */
|
|
1834
2758
|
__publicField(Texture, "RENDER_ATTACHMENT", 16);
|
|
1835
|
-
/** Default options */
|
|
1836
2759
|
__publicField(Texture, "defaultProps", {
|
|
1837
2760
|
...Resource.defaultProps,
|
|
1838
2761
|
data: null,
|
|
1839
2762
|
dimension: "2d",
|
|
1840
2763
|
format: "rgba8unorm",
|
|
1841
|
-
usage: _Texture.
|
|
2764
|
+
usage: _Texture.SAMPLE | _Texture.RENDER | _Texture.COPY_DST,
|
|
1842
2765
|
width: void 0,
|
|
1843
2766
|
height: void 0,
|
|
1844
2767
|
depth: 1,
|
|
@@ -1852,6 +2775,10 @@ __publicField(Texture, "defaultCopyDataOptions", {
|
|
|
1852
2775
|
byteOffset: 0,
|
|
1853
2776
|
bytesPerRow: void 0,
|
|
1854
2777
|
rowsPerImage: void 0,
|
|
2778
|
+
width: void 0,
|
|
2779
|
+
height: void 0,
|
|
2780
|
+
depthOrArrayLayers: void 0,
|
|
2781
|
+
depth: 1,
|
|
1855
2782
|
mipLevel: 0,
|
|
1856
2783
|
x: 0,
|
|
1857
2784
|
y: 0,
|
|
@@ -1875,6 +2802,29 @@ __publicField(Texture, "defaultCopyExternalImageOptions", {
|
|
|
1875
2802
|
premultipliedAlpha: false,
|
|
1876
2803
|
flipY: false
|
|
1877
2804
|
});
|
|
2805
|
+
__publicField(Texture, "defaultTextureReadOptions", {
|
|
2806
|
+
x: 0,
|
|
2807
|
+
y: 0,
|
|
2808
|
+
z: 0,
|
|
2809
|
+
width: void 0,
|
|
2810
|
+
height: void 0,
|
|
2811
|
+
depthOrArrayLayers: 1,
|
|
2812
|
+
mipLevel: 0,
|
|
2813
|
+
aspect: "all"
|
|
2814
|
+
});
|
|
2815
|
+
__publicField(Texture, "defaultTextureWriteOptions", {
|
|
2816
|
+
byteOffset: 0,
|
|
2817
|
+
bytesPerRow: void 0,
|
|
2818
|
+
rowsPerImage: void 0,
|
|
2819
|
+
x: 0,
|
|
2820
|
+
y: 0,
|
|
2821
|
+
z: 0,
|
|
2822
|
+
width: void 0,
|
|
2823
|
+
height: void 0,
|
|
2824
|
+
depthOrArrayLayers: 1,
|
|
2825
|
+
mipLevel: 0,
|
|
2826
|
+
aspect: "all"
|
|
2827
|
+
});
|
|
1878
2828
|
|
|
1879
2829
|
// dist/adapter/resources/texture-view.js
|
|
1880
2830
|
var _TextureView = class extends Resource {
|
|
@@ -1921,24 +2871,32 @@ function formatCompilerLog(shaderLog, source, options) {
|
|
|
1921
2871
|
const log2 = shaderLog.slice().sort((a, b) => a.lineNum - b.lineNum);
|
|
1922
2872
|
switch ((options == null ? void 0 : options.showSourceCode) || "no") {
|
|
1923
2873
|
case "all":
|
|
1924
|
-
let
|
|
2874
|
+
let currentMessageIndex = 0;
|
|
1925
2875
|
for (let lineNum = 1; lineNum <= lines.length; lineNum++) {
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
formattedLog +=
|
|
2876
|
+
const line = lines[lineNum - 1];
|
|
2877
|
+
const currentMessage = log2[currentMessageIndex];
|
|
2878
|
+
if (line && currentMessage) {
|
|
2879
|
+
formattedLog += getNumberedLine(line, lineNum, options);
|
|
2880
|
+
}
|
|
2881
|
+
while (log2.length > currentMessageIndex && currentMessage.lineNum === lineNum) {
|
|
2882
|
+
const message = log2[currentMessageIndex++];
|
|
2883
|
+
if (message) {
|
|
2884
|
+
formattedLog += formatCompilerMessage(message, lines, message.lineNum, {
|
|
2885
|
+
...options,
|
|
2886
|
+
inlineSource: false
|
|
2887
|
+
});
|
|
2888
|
+
}
|
|
2889
|
+
}
|
|
2890
|
+
}
|
|
2891
|
+
while (log2.length > currentMessageIndex) {
|
|
2892
|
+
const message = log2[currentMessageIndex++];
|
|
2893
|
+
if (message) {
|
|
2894
|
+
formattedLog += formatCompilerMessage(message, [], 0, {
|
|
1930
2895
|
...options,
|
|
1931
2896
|
inlineSource: false
|
|
1932
2897
|
});
|
|
1933
2898
|
}
|
|
1934
2899
|
}
|
|
1935
|
-
while (log2.length > currentMessage) {
|
|
1936
|
-
const message = log2[currentMessage++];
|
|
1937
|
-
formattedLog += formatCompilerMessage(message, [], 0, {
|
|
1938
|
-
...options,
|
|
1939
|
-
inlineSource: false
|
|
1940
|
-
});
|
|
1941
|
-
}
|
|
1942
2900
|
return formattedLog;
|
|
1943
2901
|
case "issues":
|
|
1944
2902
|
case "no":
|
|
@@ -1960,8 +2918,8 @@ ${numberedLines}${positionIndicator}${message.type.toUpperCase()}: ${message.mes
|
|
|
1960
2918
|
|
|
1961
2919
|
`;
|
|
1962
2920
|
}
|
|
1963
|
-
const color = message.type === "error" ? "red" : "
|
|
1964
|
-
return (options == null ? void 0 : options.html) ? `<div class='luma-compiler-log
|
|
2921
|
+
const color = message.type === "error" ? "red" : "orange";
|
|
2922
|
+
return (options == null ? void 0 : options.html) ? `<div class='luma-compiler-log-${message.type}' style="color:${color};"><b> ${message.type.toUpperCase()}: ${message.message}</b></div>` : `${message.type.toUpperCase()}: ${message.message}`;
|
|
1965
2923
|
}
|
|
1966
2924
|
function getNumberedLines(lines, lineNum, options) {
|
|
1967
2925
|
let numberedLines = "";
|
|
@@ -2042,35 +3000,39 @@ var _Shader = class extends Resource {
|
|
|
2042
3000
|
* TODO - this HTML formatting code should not be in Device, should be pluggable
|
|
2043
3001
|
*/
|
|
2044
3002
|
_displayShaderLog(messages, shaderId) {
|
|
2045
|
-
var _a;
|
|
2046
3003
|
if (typeof document === "undefined" || !(document == null ? void 0 : document.createElement)) {
|
|
2047
3004
|
return;
|
|
2048
3005
|
}
|
|
2049
3006
|
const shaderName = shaderId;
|
|
2050
3007
|
const shaderTitle = `${this.stage} shader "${shaderName}"`;
|
|
2051
|
-
|
|
3008
|
+
const htmlLog = formatCompilerLog(messages, this.source, { showSourceCode: "all", html: true });
|
|
2052
3009
|
const translatedSource = this.getTranslatedSource();
|
|
3010
|
+
const container = document.createElement("div");
|
|
3011
|
+
container.innerHTML = `<h1>Compilation error in ${shaderTitle}</h1>
|
|
3012
|
+
<div style="display:flex;position:fixed;top:10px;right:20px;gap:2px;">
|
|
3013
|
+
<button id="copy">Copy source</button><br/>
|
|
3014
|
+
<button id="close">Close</button>
|
|
3015
|
+
</div>
|
|
3016
|
+
<code><pre>${htmlLog}</pre></code>`;
|
|
2053
3017
|
if (translatedSource) {
|
|
2054
|
-
|
|
2055
|
-
}
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
button.
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
(
|
|
2071
|
-
|
|
2072
|
-
const dataURI = `data:text/plain,${encodeURIComponent(this.source)}`;
|
|
2073
|
-
navigator.clipboard.writeText(dataURI);
|
|
3018
|
+
container.innerHTML += `<br /><h1>Translated Source</h1><br /><br /><code><pre>${translatedSource}</pre></code>`;
|
|
3019
|
+
}
|
|
3020
|
+
container.style.top = "0";
|
|
3021
|
+
container.style.left = "0";
|
|
3022
|
+
container.style.background = "white";
|
|
3023
|
+
container.style.position = "fixed";
|
|
3024
|
+
container.style.zIndex = "9999";
|
|
3025
|
+
container.style.maxWidth = "100vw";
|
|
3026
|
+
container.style.maxHeight = "100vh";
|
|
3027
|
+
container.style.overflowY = "auto";
|
|
3028
|
+
document.body.appendChild(container);
|
|
3029
|
+
const error = container.querySelector(".luma-compiler-log-error");
|
|
3030
|
+
error == null ? void 0 : error.scrollIntoView();
|
|
3031
|
+
container.querySelector("button#close").onclick = () => {
|
|
3032
|
+
container.remove();
|
|
3033
|
+
};
|
|
3034
|
+
container.querySelector("button#copy").onclick = () => {
|
|
3035
|
+
navigator.clipboard.writeText(this.source);
|
|
2074
3036
|
};
|
|
2075
3037
|
}
|
|
2076
3038
|
};
|
|
@@ -2090,7 +3052,7 @@ function getShaderIdFromProps(props) {
|
|
|
2090
3052
|
function getShaderName(shader, defaultName = "unnamed") {
|
|
2091
3053
|
const SHADER_NAME_REGEXP = /#define[\s*]SHADER_NAME[\s*]([A-Za-z0-9_-]+)[\s*]/;
|
|
2092
3054
|
const match = SHADER_NAME_REGEXP.exec(shader);
|
|
2093
|
-
return match ? match[1]
|
|
3055
|
+
return (match == null ? void 0 : match[1]) ?? defaultName;
|
|
2094
3056
|
}
|
|
2095
3057
|
|
|
2096
3058
|
// dist/adapter/resources/framebuffer.js
|
|
@@ -2114,7 +3076,12 @@ var _Framebuffer = class extends Resource {
|
|
|
2114
3076
|
clone(size) {
|
|
2115
3077
|
const colorAttachments = this.colorAttachments.map((colorAttachment) => colorAttachment.texture.clone(size));
|
|
2116
3078
|
const depthStencilAttachment = this.depthStencilAttachment && this.depthStencilAttachment.texture.clone(size);
|
|
2117
|
-
return this.device.createFramebuffer({
|
|
3079
|
+
return this.device.createFramebuffer({
|
|
3080
|
+
...this.props,
|
|
3081
|
+
...size,
|
|
3082
|
+
colorAttachments,
|
|
3083
|
+
depthStencilAttachment
|
|
3084
|
+
});
|
|
2118
3085
|
}
|
|
2119
3086
|
resize(size) {
|
|
2120
3087
|
let updateSize = !size;
|
|
@@ -2189,17 +3156,15 @@ var _Framebuffer = class extends Resource {
|
|
|
2189
3156
|
* and destroys existing textures if owned
|
|
2190
3157
|
*/
|
|
2191
3158
|
resizeAttachments(width, height) {
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
}
|
|
2202
|
-
}
|
|
3159
|
+
this.colorAttachments.forEach((colorAttachment, i) => {
|
|
3160
|
+
const resizedTexture = colorAttachment.texture.clone({
|
|
3161
|
+
width,
|
|
3162
|
+
height
|
|
3163
|
+
});
|
|
3164
|
+
this.destroyAttachedResource(colorAttachment);
|
|
3165
|
+
this.colorAttachments[i] = resizedTexture.view;
|
|
3166
|
+
this.attachResource(resizedTexture.view);
|
|
3167
|
+
});
|
|
2203
3168
|
if (this.depthStencilAttachment) {
|
|
2204
3169
|
const resizedTexture = this.depthStencilAttachment.texture.clone({
|
|
2205
3170
|
width,
|
|
@@ -2236,10 +3201,23 @@ var _RenderPipeline = class extends Resource {
|
|
|
2236
3201
|
linkStatus = "pending";
|
|
2237
3202
|
/** The hash of the pipeline */
|
|
2238
3203
|
hash = "";
|
|
3204
|
+
/** Optional shared backend implementation */
|
|
3205
|
+
sharedRenderPipeline = null;
|
|
3206
|
+
/** Whether shader or pipeline compilation/linking is still in progress */
|
|
3207
|
+
get isPending() {
|
|
3208
|
+
var _a;
|
|
3209
|
+
return this.linkStatus === "pending" || this.vs.compilationStatus === "pending" || ((_a = this.fs) == null ? void 0 : _a.compilationStatus) === "pending";
|
|
3210
|
+
}
|
|
3211
|
+
/** Whether shader or pipeline compilation/linking has failed */
|
|
3212
|
+
get isErrored() {
|
|
3213
|
+
var _a;
|
|
3214
|
+
return this.linkStatus === "error" || this.vs.compilationStatus === "error" || ((_a = this.fs) == null ? void 0 : _a.compilationStatus) === "error";
|
|
3215
|
+
}
|
|
2239
3216
|
constructor(device, props) {
|
|
2240
3217
|
super(device, props, _RenderPipeline.defaultProps);
|
|
2241
3218
|
this.shaderLayout = this.props.shaderLayout;
|
|
2242
3219
|
this.bufferLayout = this.props.bufferLayout || [];
|
|
3220
|
+
this.sharedRenderPipeline = this.props._sharedRenderPipeline || null;
|
|
2243
3221
|
}
|
|
2244
3222
|
};
|
|
2245
3223
|
var RenderPipeline = _RenderPipeline;
|
|
@@ -2257,27 +3235,499 @@ __publicField(RenderPipeline, "defaultProps", {
|
|
|
2257
3235
|
colorAttachmentFormats: void 0,
|
|
2258
3236
|
depthStencilAttachmentFormat: void 0,
|
|
2259
3237
|
parameters: {},
|
|
2260
|
-
|
|
2261
|
-
|
|
3238
|
+
varyings: void 0,
|
|
3239
|
+
bufferMode: void 0,
|
|
3240
|
+
disableWarnings: false,
|
|
3241
|
+
_sharedRenderPipeline: void 0,
|
|
3242
|
+
bindings: void 0,
|
|
3243
|
+
bindGroups: void 0
|
|
2262
3244
|
});
|
|
2263
3245
|
|
|
2264
|
-
// dist/adapter/resources/render-
|
|
2265
|
-
var
|
|
3246
|
+
// dist/adapter/resources/shared-render-pipeline.js
|
|
3247
|
+
var SharedRenderPipeline = class extends Resource {
|
|
2266
3248
|
get [Symbol.toStringTag]() {
|
|
2267
|
-
return "
|
|
3249
|
+
return "SharedRenderPipeline";
|
|
2268
3250
|
}
|
|
2269
3251
|
constructor(device, props) {
|
|
2270
|
-
|
|
2271
|
-
|
|
3252
|
+
super(device, props, {
|
|
3253
|
+
...Resource.defaultProps,
|
|
3254
|
+
handle: void 0,
|
|
3255
|
+
vs: void 0,
|
|
3256
|
+
fs: void 0,
|
|
3257
|
+
varyings: void 0,
|
|
3258
|
+
bufferMode: void 0
|
|
3259
|
+
});
|
|
2272
3260
|
}
|
|
2273
|
-
|
|
2274
|
-
|
|
3261
|
+
};
|
|
3262
|
+
|
|
3263
|
+
// dist/adapter/resources/compute-pipeline.js
|
|
3264
|
+
var _ComputePipeline = class extends Resource {
|
|
3265
|
+
get [Symbol.toStringTag]() {
|
|
3266
|
+
return "ComputePipeline";
|
|
3267
|
+
}
|
|
3268
|
+
hash = "";
|
|
3269
|
+
/** The merged shader layout */
|
|
3270
|
+
shaderLayout;
|
|
3271
|
+
constructor(device, props) {
|
|
3272
|
+
super(device, props, _ComputePipeline.defaultProps);
|
|
3273
|
+
this.shaderLayout = props.shaderLayout;
|
|
2275
3274
|
}
|
|
2276
3275
|
};
|
|
2277
|
-
var
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
3276
|
+
var ComputePipeline = _ComputePipeline;
|
|
3277
|
+
__publicField(ComputePipeline, "defaultProps", {
|
|
3278
|
+
...Resource.defaultProps,
|
|
3279
|
+
shader: void 0,
|
|
3280
|
+
entryPoint: void 0,
|
|
3281
|
+
constants: {},
|
|
3282
|
+
shaderLayout: void 0
|
|
3283
|
+
});
|
|
3284
|
+
|
|
3285
|
+
// dist/factories/pipeline-factory.js
|
|
3286
|
+
var _PipelineFactory = class {
|
|
3287
|
+
/** Get the singleton default pipeline factory for the specified device */
|
|
3288
|
+
static getDefaultPipelineFactory(device) {
|
|
3289
|
+
const moduleData = device.getModuleData("@luma.gl/core");
|
|
3290
|
+
moduleData.defaultPipelineFactory ||= new _PipelineFactory(device);
|
|
3291
|
+
return moduleData.defaultPipelineFactory;
|
|
3292
|
+
}
|
|
3293
|
+
device;
|
|
3294
|
+
_hashCounter = 0;
|
|
3295
|
+
_hashes = {};
|
|
3296
|
+
_renderPipelineCache = {};
|
|
3297
|
+
_computePipelineCache = {};
|
|
3298
|
+
_sharedRenderPipelineCache = {};
|
|
3299
|
+
get [Symbol.toStringTag]() {
|
|
3300
|
+
return "PipelineFactory";
|
|
3301
|
+
}
|
|
3302
|
+
toString() {
|
|
3303
|
+
return `PipelineFactory(${this.device.id})`;
|
|
3304
|
+
}
|
|
3305
|
+
constructor(device) {
|
|
3306
|
+
this.device = device;
|
|
3307
|
+
}
|
|
3308
|
+
/**
|
|
3309
|
+
* WebGL has two cache layers with different priorities:
|
|
3310
|
+
* - `_sharedRenderPipelineCache` owns `WEBGLSharedRenderPipeline` / `WebGLProgram` reuse.
|
|
3311
|
+
* - `_renderPipelineCache` owns `RenderPipeline` wrapper reuse.
|
|
3312
|
+
*
|
|
3313
|
+
* Shared WebGL program reuse is the hard requirement. Wrapper reuse is beneficial,
|
|
3314
|
+
* but wrapper cache misses are acceptable if that keeps the cache logic simple and
|
|
3315
|
+
* prevents incorrect cache hits.
|
|
3316
|
+
*
|
|
3317
|
+
* In particular, wrapper hash logic must never force program creation or linked-program
|
|
3318
|
+
* introspection just to decide whether a shared WebGL program can be reused.
|
|
3319
|
+
*/
|
|
3320
|
+
/** Return a RenderPipeline matching supplied props. Reuses an equivalent pipeline if already created. */
|
|
3321
|
+
createRenderPipeline(props) {
|
|
3322
|
+
var _a;
|
|
3323
|
+
if (!this.device.props._cachePipelines) {
|
|
3324
|
+
return this.device.createRenderPipeline(props);
|
|
3325
|
+
}
|
|
3326
|
+
const allProps = { ...RenderPipeline.defaultProps, ...props };
|
|
3327
|
+
const cache = this._renderPipelineCache;
|
|
3328
|
+
const hash = this._hashRenderPipeline(allProps);
|
|
3329
|
+
let pipeline = (_a = cache[hash]) == null ? void 0 : _a.resource;
|
|
3330
|
+
if (!pipeline) {
|
|
3331
|
+
const sharedRenderPipeline = this.device.type === "webgl" && this.device.props._sharePipelines ? this.createSharedRenderPipeline(allProps) : void 0;
|
|
3332
|
+
pipeline = this.device.createRenderPipeline({
|
|
3333
|
+
...allProps,
|
|
3334
|
+
id: allProps.id ? `${allProps.id}-cached` : uid("unnamed-cached"),
|
|
3335
|
+
_sharedRenderPipeline: sharedRenderPipeline
|
|
3336
|
+
});
|
|
3337
|
+
pipeline.hash = hash;
|
|
3338
|
+
cache[hash] = { resource: pipeline, useCount: 1 };
|
|
3339
|
+
if (this.device.props.debugFactories) {
|
|
3340
|
+
log.log(3, `${this}: ${pipeline} created, count=${cache[hash].useCount}`)();
|
|
3341
|
+
}
|
|
3342
|
+
} else {
|
|
3343
|
+
cache[hash].useCount++;
|
|
3344
|
+
if (this.device.props.debugFactories) {
|
|
3345
|
+
log.log(3, `${this}: ${cache[hash].resource} reused, count=${cache[hash].useCount}, (id=${props.id})`)();
|
|
3346
|
+
}
|
|
3347
|
+
}
|
|
3348
|
+
return pipeline;
|
|
3349
|
+
}
|
|
3350
|
+
/** Return a ComputePipeline matching supplied props. Reuses an equivalent pipeline if already created. */
|
|
3351
|
+
createComputePipeline(props) {
|
|
3352
|
+
var _a;
|
|
3353
|
+
if (!this.device.props._cachePipelines) {
|
|
3354
|
+
return this.device.createComputePipeline(props);
|
|
3355
|
+
}
|
|
3356
|
+
const allProps = { ...ComputePipeline.defaultProps, ...props };
|
|
3357
|
+
const cache = this._computePipelineCache;
|
|
3358
|
+
const hash = this._hashComputePipeline(allProps);
|
|
3359
|
+
let pipeline = (_a = cache[hash]) == null ? void 0 : _a.resource;
|
|
3360
|
+
if (!pipeline) {
|
|
3361
|
+
pipeline = this.device.createComputePipeline({
|
|
3362
|
+
...allProps,
|
|
3363
|
+
id: allProps.id ? `${allProps.id}-cached` : void 0
|
|
3364
|
+
});
|
|
3365
|
+
pipeline.hash = hash;
|
|
3366
|
+
cache[hash] = { resource: pipeline, useCount: 1 };
|
|
3367
|
+
if (this.device.props.debugFactories) {
|
|
3368
|
+
log.log(3, `${this}: ${pipeline} created, count=${cache[hash].useCount}`)();
|
|
3369
|
+
}
|
|
3370
|
+
} else {
|
|
3371
|
+
cache[hash].useCount++;
|
|
3372
|
+
if (this.device.props.debugFactories) {
|
|
3373
|
+
log.log(3, `${this}: ${cache[hash].resource} reused, count=${cache[hash].useCount}, (id=${props.id})`)();
|
|
3374
|
+
}
|
|
3375
|
+
}
|
|
3376
|
+
return pipeline;
|
|
3377
|
+
}
|
|
3378
|
+
release(pipeline) {
|
|
3379
|
+
if (!this.device.props._cachePipelines) {
|
|
3380
|
+
pipeline.destroy();
|
|
3381
|
+
return;
|
|
3382
|
+
}
|
|
3383
|
+
const cache = this._getCache(pipeline);
|
|
3384
|
+
const hash = pipeline.hash;
|
|
3385
|
+
cache[hash].useCount--;
|
|
3386
|
+
if (cache[hash].useCount === 0) {
|
|
3387
|
+
this._destroyPipeline(pipeline);
|
|
3388
|
+
if (this.device.props.debugFactories) {
|
|
3389
|
+
log.log(3, `${this}: ${pipeline} released and destroyed`)();
|
|
3390
|
+
}
|
|
3391
|
+
} else if (cache[hash].useCount < 0) {
|
|
3392
|
+
log.error(`${this}: ${pipeline} released, useCount < 0, resetting`)();
|
|
3393
|
+
cache[hash].useCount = 0;
|
|
3394
|
+
} else if (this.device.props.debugFactories) {
|
|
3395
|
+
log.log(3, `${this}: ${pipeline} released, count=${cache[hash].useCount}`)();
|
|
3396
|
+
}
|
|
3397
|
+
}
|
|
3398
|
+
createSharedRenderPipeline(props) {
|
|
3399
|
+
const sharedPipelineHash = this._hashSharedRenderPipeline(props);
|
|
3400
|
+
let sharedCacheItem = this._sharedRenderPipelineCache[sharedPipelineHash];
|
|
3401
|
+
if (!sharedCacheItem) {
|
|
3402
|
+
const sharedRenderPipeline = this.device._createSharedRenderPipelineWebGL(props);
|
|
3403
|
+
sharedCacheItem = { resource: sharedRenderPipeline, useCount: 0 };
|
|
3404
|
+
this._sharedRenderPipelineCache[sharedPipelineHash] = sharedCacheItem;
|
|
3405
|
+
}
|
|
3406
|
+
sharedCacheItem.useCount++;
|
|
3407
|
+
return sharedCacheItem.resource;
|
|
3408
|
+
}
|
|
3409
|
+
releaseSharedRenderPipeline(pipeline) {
|
|
3410
|
+
if (!pipeline.sharedRenderPipeline) {
|
|
3411
|
+
return;
|
|
3412
|
+
}
|
|
3413
|
+
const sharedPipelineHash = this._hashSharedRenderPipeline(pipeline.sharedRenderPipeline.props);
|
|
3414
|
+
const sharedCacheItem = this._sharedRenderPipelineCache[sharedPipelineHash];
|
|
3415
|
+
if (!sharedCacheItem) {
|
|
3416
|
+
return;
|
|
3417
|
+
}
|
|
3418
|
+
sharedCacheItem.useCount--;
|
|
3419
|
+
if (sharedCacheItem.useCount === 0) {
|
|
3420
|
+
sharedCacheItem.resource.destroy();
|
|
3421
|
+
delete this._sharedRenderPipelineCache[sharedPipelineHash];
|
|
3422
|
+
}
|
|
3423
|
+
}
|
|
3424
|
+
// PRIVATE
|
|
3425
|
+
/** Destroy a cached pipeline, removing it from the cache if configured to do so. */
|
|
3426
|
+
_destroyPipeline(pipeline) {
|
|
3427
|
+
const cache = this._getCache(pipeline);
|
|
3428
|
+
if (!this.device.props._destroyPipelines) {
|
|
3429
|
+
return false;
|
|
3430
|
+
}
|
|
3431
|
+
delete cache[pipeline.hash];
|
|
3432
|
+
pipeline.destroy();
|
|
3433
|
+
if (pipeline instanceof RenderPipeline) {
|
|
3434
|
+
this.releaseSharedRenderPipeline(pipeline);
|
|
3435
|
+
}
|
|
3436
|
+
return true;
|
|
3437
|
+
}
|
|
3438
|
+
/** Get the appropriate cache for the type of pipeline */
|
|
3439
|
+
_getCache(pipeline) {
|
|
3440
|
+
let cache;
|
|
3441
|
+
if (pipeline instanceof ComputePipeline) {
|
|
3442
|
+
cache = this._computePipelineCache;
|
|
3443
|
+
}
|
|
3444
|
+
if (pipeline instanceof RenderPipeline) {
|
|
3445
|
+
cache = this._renderPipelineCache;
|
|
3446
|
+
}
|
|
3447
|
+
if (!cache) {
|
|
3448
|
+
throw new Error(`${this}`);
|
|
3449
|
+
}
|
|
3450
|
+
if (!cache[pipeline.hash]) {
|
|
3451
|
+
throw new Error(`${this}: ${pipeline} matched incorrect entry`);
|
|
3452
|
+
}
|
|
3453
|
+
return cache;
|
|
3454
|
+
}
|
|
3455
|
+
/** Calculate a hash based on all the inputs for a compute pipeline */
|
|
3456
|
+
_hashComputePipeline(props) {
|
|
3457
|
+
const { type } = this.device;
|
|
3458
|
+
const shaderHash = this._getHash(props.shader.source);
|
|
3459
|
+
const shaderLayoutHash = this._getHash(JSON.stringify(props.shaderLayout));
|
|
3460
|
+
return `${type}/C/${shaderHash}SL${shaderLayoutHash}`;
|
|
3461
|
+
}
|
|
3462
|
+
/** Calculate a hash based on all the inputs for a render pipeline */
|
|
3463
|
+
_hashRenderPipeline(props) {
|
|
3464
|
+
const vsHash = props.vs ? this._getHash(props.vs.source) : 0;
|
|
3465
|
+
const fsHash = props.fs ? this._getHash(props.fs.source) : 0;
|
|
3466
|
+
const varyingHash = this._getWebGLVaryingHash(props);
|
|
3467
|
+
const shaderLayoutHash = this._getHash(JSON.stringify(props.shaderLayout));
|
|
3468
|
+
const bufferLayoutHash = this._getHash(JSON.stringify(props.bufferLayout));
|
|
3469
|
+
const { type } = this.device;
|
|
3470
|
+
switch (type) {
|
|
3471
|
+
case "webgl":
|
|
3472
|
+
const webglParameterHash = this._getHash(JSON.stringify(props.parameters));
|
|
3473
|
+
return `${type}/R/${vsHash}/${fsHash}V${varyingHash}T${props.topology}P${webglParameterHash}SL${shaderLayoutHash}BL${bufferLayoutHash}`;
|
|
3474
|
+
case "webgpu":
|
|
3475
|
+
default:
|
|
3476
|
+
const entryPointHash = this._getHash(JSON.stringify({
|
|
3477
|
+
vertexEntryPoint: props.vertexEntryPoint,
|
|
3478
|
+
fragmentEntryPoint: props.fragmentEntryPoint
|
|
3479
|
+
}));
|
|
3480
|
+
const parameterHash = this._getHash(JSON.stringify(props.parameters));
|
|
3481
|
+
const attachmentHash = this._getWebGPUAttachmentHash(props);
|
|
3482
|
+
return `${type}/R/${vsHash}/${fsHash}V${varyingHash}T${props.topology}EP${entryPointHash}P${parameterHash}SL${shaderLayoutHash}BL${bufferLayoutHash}A${attachmentHash}`;
|
|
3483
|
+
}
|
|
3484
|
+
}
|
|
3485
|
+
// This is the only gate for shared `WebGLProgram` reuse.
|
|
3486
|
+
// Only include inputs that affect program linking or transform-feedback linkage.
|
|
3487
|
+
// Wrapper-only concerns such as topology, parameters, attachment formats and layout
|
|
3488
|
+
// overrides must not be added here.
|
|
3489
|
+
_hashSharedRenderPipeline(props) {
|
|
3490
|
+
const vsHash = props.vs ? this._getHash(props.vs.source) : 0;
|
|
3491
|
+
const fsHash = props.fs ? this._getHash(props.fs.source) : 0;
|
|
3492
|
+
const varyingHash = this._getWebGLVaryingHash(props);
|
|
3493
|
+
return `webgl/S/${vsHash}/${fsHash}V${varyingHash}`;
|
|
3494
|
+
}
|
|
3495
|
+
_getHash(key) {
|
|
3496
|
+
if (this._hashes[key] === void 0) {
|
|
3497
|
+
this._hashes[key] = this._hashCounter++;
|
|
3498
|
+
}
|
|
3499
|
+
return this._hashes[key];
|
|
3500
|
+
}
|
|
3501
|
+
_getWebGLVaryingHash(props) {
|
|
3502
|
+
const { varyings = [], bufferMode = null } = props;
|
|
3503
|
+
return this._getHash(JSON.stringify({ varyings, bufferMode }));
|
|
3504
|
+
}
|
|
3505
|
+
_getWebGPUAttachmentHash(props) {
|
|
3506
|
+
var _a;
|
|
3507
|
+
const colorAttachmentFormats = props.colorAttachmentFormats ?? [
|
|
3508
|
+
this.device.preferredColorFormat
|
|
3509
|
+
];
|
|
3510
|
+
const depthStencilAttachmentFormat = ((_a = props.parameters) == null ? void 0 : _a.depthWriteEnabled) ? props.depthStencilAttachmentFormat || this.device.preferredDepthFormat : null;
|
|
3511
|
+
return this._getHash(JSON.stringify({
|
|
3512
|
+
colorAttachmentFormats,
|
|
3513
|
+
depthStencilAttachmentFormat
|
|
3514
|
+
}));
|
|
3515
|
+
}
|
|
3516
|
+
};
|
|
3517
|
+
var PipelineFactory = _PipelineFactory;
|
|
3518
|
+
__publicField(PipelineFactory, "defaultProps", { ...RenderPipeline.defaultProps });
|
|
3519
|
+
|
|
3520
|
+
// dist/factories/shader-factory.js
|
|
3521
|
+
var _ShaderFactory = class {
|
|
3522
|
+
/** Returns the default ShaderFactory for the given {@link Device}, creating one if necessary. */
|
|
3523
|
+
static getDefaultShaderFactory(device) {
|
|
3524
|
+
const moduleData = device.getModuleData("@luma.gl/core");
|
|
3525
|
+
moduleData.defaultShaderFactory ||= new _ShaderFactory(device);
|
|
3526
|
+
return moduleData.defaultShaderFactory;
|
|
3527
|
+
}
|
|
3528
|
+
device;
|
|
3529
|
+
_cache = {};
|
|
3530
|
+
get [Symbol.toStringTag]() {
|
|
3531
|
+
return "ShaderFactory";
|
|
3532
|
+
}
|
|
3533
|
+
toString() {
|
|
3534
|
+
return `${this[Symbol.toStringTag]}(${this.device.id})`;
|
|
3535
|
+
}
|
|
3536
|
+
/** @internal */
|
|
3537
|
+
constructor(device) {
|
|
3538
|
+
this.device = device;
|
|
3539
|
+
}
|
|
3540
|
+
/** Requests a {@link Shader} from the cache, creating a new Shader only if necessary. */
|
|
3541
|
+
createShader(props) {
|
|
3542
|
+
if (!this.device.props._cacheShaders) {
|
|
3543
|
+
return this.device.createShader(props);
|
|
3544
|
+
}
|
|
3545
|
+
const key = this._hashShader(props);
|
|
3546
|
+
let cacheEntry = this._cache[key];
|
|
3547
|
+
if (!cacheEntry) {
|
|
3548
|
+
const resource = this.device.createShader({
|
|
3549
|
+
...props,
|
|
3550
|
+
id: props.id ? `${props.id}-cached` : void 0
|
|
3551
|
+
});
|
|
3552
|
+
this._cache[key] = cacheEntry = { resource, useCount: 1 };
|
|
3553
|
+
if (this.device.props.debugFactories) {
|
|
3554
|
+
log.log(3, `${this}: Created new shader ${resource.id}`)();
|
|
3555
|
+
}
|
|
3556
|
+
} else {
|
|
3557
|
+
cacheEntry.useCount++;
|
|
3558
|
+
if (this.device.props.debugFactories) {
|
|
3559
|
+
log.log(3, `${this}: Reusing shader ${cacheEntry.resource.id} count=${cacheEntry.useCount}`)();
|
|
3560
|
+
}
|
|
3561
|
+
}
|
|
3562
|
+
return cacheEntry.resource;
|
|
3563
|
+
}
|
|
3564
|
+
/** Releases a previously-requested {@link Shader}, destroying it if no users remain. */
|
|
3565
|
+
release(shader) {
|
|
3566
|
+
if (!this.device.props._cacheShaders) {
|
|
3567
|
+
shader.destroy();
|
|
3568
|
+
return;
|
|
3569
|
+
}
|
|
3570
|
+
const key = this._hashShader(shader);
|
|
3571
|
+
const cacheEntry = this._cache[key];
|
|
3572
|
+
if (cacheEntry) {
|
|
3573
|
+
cacheEntry.useCount--;
|
|
3574
|
+
if (cacheEntry.useCount === 0) {
|
|
3575
|
+
if (this.device.props._destroyShaders) {
|
|
3576
|
+
delete this._cache[key];
|
|
3577
|
+
cacheEntry.resource.destroy();
|
|
3578
|
+
if (this.device.props.debugFactories) {
|
|
3579
|
+
log.log(3, `${this}: Releasing shader ${shader.id}, destroyed`)();
|
|
3580
|
+
}
|
|
3581
|
+
}
|
|
3582
|
+
} else if (cacheEntry.useCount < 0) {
|
|
3583
|
+
throw new Error(`ShaderFactory: Shader ${shader.id} released too many times`);
|
|
3584
|
+
} else if (this.device.props.debugFactories) {
|
|
3585
|
+
log.log(3, `${this}: Releasing shader ${shader.id} count=${cacheEntry.useCount}`)();
|
|
3586
|
+
}
|
|
3587
|
+
}
|
|
3588
|
+
}
|
|
3589
|
+
// PRIVATE
|
|
3590
|
+
_hashShader(value) {
|
|
3591
|
+
return `${value.stage}:${value.source}`;
|
|
3592
|
+
}
|
|
3593
|
+
};
|
|
3594
|
+
var ShaderFactory = _ShaderFactory;
|
|
3595
|
+
__publicField(ShaderFactory, "defaultProps", { ...Shader.defaultProps });
|
|
3596
|
+
|
|
3597
|
+
// dist/adapter-utils/bind-groups.js
|
|
3598
|
+
function getShaderLayoutBinding(shaderLayout, bindingName, options) {
|
|
3599
|
+
const bindingLayout = shaderLayout.bindings.find((binding) => binding.name === bindingName || `${binding.name.toLocaleLowerCase()}uniforms` === bindingName.toLocaleLowerCase());
|
|
3600
|
+
if (!bindingLayout && !(options == null ? void 0 : options.ignoreWarnings)) {
|
|
3601
|
+
log.warn(`Binding ${bindingName} not set: Not found in shader layout.`)();
|
|
3602
|
+
}
|
|
3603
|
+
return bindingLayout || null;
|
|
3604
|
+
}
|
|
3605
|
+
function normalizeBindingsByGroup(shaderLayout, bindingsOrBindGroups) {
|
|
3606
|
+
if (!bindingsOrBindGroups) {
|
|
3607
|
+
return {};
|
|
3608
|
+
}
|
|
3609
|
+
if (areBindingsGrouped(bindingsOrBindGroups)) {
|
|
3610
|
+
const bindGroups2 = bindingsOrBindGroups;
|
|
3611
|
+
return Object.fromEntries(Object.entries(bindGroups2).map(([group, bindings]) => [Number(group), { ...bindings }]));
|
|
3612
|
+
}
|
|
3613
|
+
const bindGroups = {};
|
|
3614
|
+
for (const [bindingName, binding] of Object.entries(bindingsOrBindGroups)) {
|
|
3615
|
+
const bindingLayout = getShaderLayoutBinding(shaderLayout, bindingName);
|
|
3616
|
+
const group = (bindingLayout == null ? void 0 : bindingLayout.group) ?? 0;
|
|
3617
|
+
bindGroups[group] ||= {};
|
|
3618
|
+
bindGroups[group][bindingName] = binding;
|
|
3619
|
+
}
|
|
3620
|
+
return bindGroups;
|
|
3621
|
+
}
|
|
3622
|
+
function flattenBindingsByGroup(bindGroups) {
|
|
3623
|
+
const bindings = {};
|
|
3624
|
+
for (const groupBindings of Object.values(bindGroups)) {
|
|
3625
|
+
Object.assign(bindings, groupBindings);
|
|
3626
|
+
}
|
|
3627
|
+
return bindings;
|
|
3628
|
+
}
|
|
3629
|
+
function areBindingsGrouped(bindingsOrBindGroups) {
|
|
3630
|
+
const keys = Object.keys(bindingsOrBindGroups);
|
|
3631
|
+
return keys.length > 0 && keys.every((key) => /^\d+$/.test(key));
|
|
3632
|
+
}
|
|
3633
|
+
|
|
3634
|
+
// dist/factories/bind-group-factory.js
|
|
3635
|
+
var BindGroupFactory = class {
|
|
3636
|
+
device;
|
|
3637
|
+
_layoutCacheByPipeline = /* @__PURE__ */ new WeakMap();
|
|
3638
|
+
_bindGroupCacheByLayout = /* @__PURE__ */ new WeakMap();
|
|
3639
|
+
constructor(device) {
|
|
3640
|
+
this.device = device;
|
|
3641
|
+
}
|
|
3642
|
+
getBindGroups(pipeline, bindings, bindGroupCacheKeys) {
|
|
3643
|
+
if (this.device.type !== "webgpu" || pipeline.shaderLayout.bindings.length === 0) {
|
|
3644
|
+
return {};
|
|
3645
|
+
}
|
|
3646
|
+
const bindingsByGroup = normalizeBindingsByGroup(pipeline.shaderLayout, bindings);
|
|
3647
|
+
const resolvedBindGroups = {};
|
|
3648
|
+
for (const group of getBindGroupIndicesUpToMax(pipeline.shaderLayout.bindings)) {
|
|
3649
|
+
const groupBindings = bindingsByGroup[group];
|
|
3650
|
+
const bindGroupLayout = this._getBindGroupLayout(pipeline, group);
|
|
3651
|
+
const bindGroupLabel = getBindGroupLabel(pipeline, pipeline.shaderLayout, group);
|
|
3652
|
+
if (!groupBindings || Object.keys(groupBindings).length === 0) {
|
|
3653
|
+
if (!hasBindingsInGroup(pipeline.shaderLayout.bindings, group)) {
|
|
3654
|
+
resolvedBindGroups[group] = this._getEmptyBindGroup(bindGroupLayout, pipeline.shaderLayout, group, bindGroupLabel);
|
|
3655
|
+
}
|
|
3656
|
+
continue;
|
|
3657
|
+
}
|
|
3658
|
+
const bindGroupCacheKey = bindGroupCacheKeys == null ? void 0 : bindGroupCacheKeys[group];
|
|
3659
|
+
if (bindGroupCacheKey) {
|
|
3660
|
+
const layoutCache = this._getLayoutBindGroupCache(bindGroupLayout);
|
|
3661
|
+
if (layoutCache.bindGroupsBySource.has(bindGroupCacheKey)) {
|
|
3662
|
+
resolvedBindGroups[group] = layoutCache.bindGroupsBySource.get(bindGroupCacheKey) || null;
|
|
3663
|
+
continue;
|
|
3664
|
+
}
|
|
3665
|
+
const bindGroup = this.device._createBindGroupWebGPU(bindGroupLayout, pipeline.shaderLayout, groupBindings, group, bindGroupLabel);
|
|
3666
|
+
layoutCache.bindGroupsBySource.set(bindGroupCacheKey, bindGroup);
|
|
3667
|
+
resolvedBindGroups[group] = bindGroup;
|
|
3668
|
+
} else {
|
|
3669
|
+
resolvedBindGroups[group] = this.device._createBindGroupWebGPU(bindGroupLayout, pipeline.shaderLayout, groupBindings, group, bindGroupLabel);
|
|
3670
|
+
}
|
|
3671
|
+
}
|
|
3672
|
+
return resolvedBindGroups;
|
|
3673
|
+
}
|
|
3674
|
+
_getBindGroupLayout(pipeline, group) {
|
|
3675
|
+
let layoutCache = this._layoutCacheByPipeline.get(pipeline);
|
|
3676
|
+
if (!layoutCache) {
|
|
3677
|
+
layoutCache = {};
|
|
3678
|
+
this._layoutCacheByPipeline.set(pipeline, layoutCache);
|
|
3679
|
+
}
|
|
3680
|
+
layoutCache[group] ||= this.device._createBindGroupLayoutWebGPU(pipeline, group);
|
|
3681
|
+
return layoutCache[group];
|
|
3682
|
+
}
|
|
3683
|
+
_getEmptyBindGroup(bindGroupLayout, shaderLayout, group, label) {
|
|
3684
|
+
const layoutCache = this._getLayoutBindGroupCache(bindGroupLayout);
|
|
3685
|
+
layoutCache.emptyBindGroup ||= this.device._createBindGroupWebGPU(bindGroupLayout, shaderLayout, {}, group, label) || null;
|
|
3686
|
+
return layoutCache.emptyBindGroup;
|
|
3687
|
+
}
|
|
3688
|
+
_getLayoutBindGroupCache(bindGroupLayout) {
|
|
3689
|
+
let layoutCache = this._bindGroupCacheByLayout.get(bindGroupLayout);
|
|
3690
|
+
if (!layoutCache) {
|
|
3691
|
+
layoutCache = { bindGroupsBySource: /* @__PURE__ */ new WeakMap() };
|
|
3692
|
+
this._bindGroupCacheByLayout.set(bindGroupLayout, layoutCache);
|
|
3693
|
+
}
|
|
3694
|
+
return layoutCache;
|
|
3695
|
+
}
|
|
3696
|
+
};
|
|
3697
|
+
function _getDefaultBindGroupFactory(device) {
|
|
3698
|
+
device._factories.bindGroupFactory ||= new BindGroupFactory(device);
|
|
3699
|
+
return device._factories.bindGroupFactory;
|
|
3700
|
+
}
|
|
3701
|
+
function getBindGroupIndicesUpToMax(bindings) {
|
|
3702
|
+
const maxGroup = bindings.reduce((highestGroup, binding) => Math.max(highestGroup, binding.group), -1);
|
|
3703
|
+
return Array.from({ length: maxGroup + 1 }, (_, group) => group);
|
|
3704
|
+
}
|
|
3705
|
+
function hasBindingsInGroup(bindings, group) {
|
|
3706
|
+
return bindings.some((binding) => binding.group === group);
|
|
3707
|
+
}
|
|
3708
|
+
function getBindGroupLabel(pipeline, shaderLayout, group) {
|
|
3709
|
+
const bindingNames = shaderLayout.bindings.filter((binding) => binding.group === group).sort((left, right) => left.location - right.location).map((binding) => binding.name);
|
|
3710
|
+
const bindingSuffix = bindingNames.length > 0 ? bindingNames.join(",") : "empty";
|
|
3711
|
+
return `${pipeline.id}/group${group}[${bindingSuffix}]`;
|
|
3712
|
+
}
|
|
3713
|
+
|
|
3714
|
+
// dist/adapter/resources/render-pass.js
|
|
3715
|
+
var _RenderPass = class extends Resource {
|
|
3716
|
+
get [Symbol.toStringTag]() {
|
|
3717
|
+
return "RenderPass";
|
|
3718
|
+
}
|
|
3719
|
+
constructor(device, props) {
|
|
3720
|
+
props = _RenderPass.normalizeProps(device, props);
|
|
3721
|
+
super(device, props, _RenderPass.defaultProps);
|
|
3722
|
+
}
|
|
3723
|
+
static normalizeProps(device, props) {
|
|
3724
|
+
return props;
|
|
3725
|
+
}
|
|
3726
|
+
};
|
|
3727
|
+
var RenderPass = _RenderPass;
|
|
3728
|
+
/** TODO - should be [0, 0, 0, 0], update once deck.gl tests run clean */
|
|
3729
|
+
__publicField(RenderPass, "defaultClearColor", [0, 0, 0, 1]);
|
|
3730
|
+
/** Depth 1.0 represents the far plance */
|
|
2281
3731
|
__publicField(RenderPass, "defaultClearDepth", 1);
|
|
2282
3732
|
/** Clears all stencil bits */
|
|
2283
3733
|
__publicField(RenderPass, "defaultClearStencil", 0);
|
|
@@ -2299,28 +3749,6 @@ __publicField(RenderPass, "defaultProps", {
|
|
|
2299
3749
|
endTimestampIndex: void 0
|
|
2300
3750
|
});
|
|
2301
3751
|
|
|
2302
|
-
// dist/adapter/resources/compute-pipeline.js
|
|
2303
|
-
var _ComputePipeline = class extends Resource {
|
|
2304
|
-
get [Symbol.toStringTag]() {
|
|
2305
|
-
return "ComputePipeline";
|
|
2306
|
-
}
|
|
2307
|
-
hash = "";
|
|
2308
|
-
/** The merged shader layout */
|
|
2309
|
-
shaderLayout;
|
|
2310
|
-
constructor(device, props) {
|
|
2311
|
-
super(device, props, _ComputePipeline.defaultProps);
|
|
2312
|
-
this.shaderLayout = props.shaderLayout;
|
|
2313
|
-
}
|
|
2314
|
-
};
|
|
2315
|
-
var ComputePipeline = _ComputePipeline;
|
|
2316
|
-
__publicField(ComputePipeline, "defaultProps", {
|
|
2317
|
-
...Resource.defaultProps,
|
|
2318
|
-
shader: void 0,
|
|
2319
|
-
entryPoint: void 0,
|
|
2320
|
-
constants: {},
|
|
2321
|
-
shaderLayout: void 0
|
|
2322
|
-
});
|
|
2323
|
-
|
|
2324
3752
|
// dist/adapter/resources/compute-pass.js
|
|
2325
3753
|
var _ComputePass = class extends Resource {
|
|
2326
3754
|
constructor(device, props) {
|
|
@@ -2343,8 +3771,69 @@ var _CommandEncoder = class extends Resource {
|
|
|
2343
3771
|
get [Symbol.toStringTag]() {
|
|
2344
3772
|
return "CommandEncoder";
|
|
2345
3773
|
}
|
|
3774
|
+
_timeProfilingQuerySet = null;
|
|
3775
|
+
_timeProfilingSlotCount = 0;
|
|
3776
|
+
_gpuTimeMs;
|
|
2346
3777
|
constructor(device, props) {
|
|
2347
3778
|
super(device, props, _CommandEncoder.defaultProps);
|
|
3779
|
+
this._timeProfilingQuerySet = props.timeProfilingQuerySet ?? null;
|
|
3780
|
+
this._timeProfilingSlotCount = 0;
|
|
3781
|
+
this._gpuTimeMs = void 0;
|
|
3782
|
+
}
|
|
3783
|
+
/**
|
|
3784
|
+
* Reads all resolved timestamp pairs on the current profiler query set and caches the sum
|
|
3785
|
+
* as milliseconds on this encoder.
|
|
3786
|
+
*/
|
|
3787
|
+
async resolveTimeProfilingQuerySet() {
|
|
3788
|
+
this._gpuTimeMs = void 0;
|
|
3789
|
+
if (!this._timeProfilingQuerySet) {
|
|
3790
|
+
return;
|
|
3791
|
+
}
|
|
3792
|
+
const pairCount = Math.floor(this._timeProfilingSlotCount / 2);
|
|
3793
|
+
if (pairCount <= 0) {
|
|
3794
|
+
return;
|
|
3795
|
+
}
|
|
3796
|
+
const queryCount = pairCount * 2;
|
|
3797
|
+
const results = await this._timeProfilingQuerySet.readResults({
|
|
3798
|
+
firstQuery: 0,
|
|
3799
|
+
queryCount
|
|
3800
|
+
});
|
|
3801
|
+
let totalDurationNanoseconds = 0n;
|
|
3802
|
+
for (let queryIndex = 0; queryIndex < queryCount; queryIndex += 2) {
|
|
3803
|
+
totalDurationNanoseconds += results[queryIndex + 1] - results[queryIndex];
|
|
3804
|
+
}
|
|
3805
|
+
this._gpuTimeMs = Number(totalDurationNanoseconds) / 1e6;
|
|
3806
|
+
}
|
|
3807
|
+
/** Returns the number of query slots consumed by automatic pass profiling on this encoder. */
|
|
3808
|
+
getTimeProfilingSlotCount() {
|
|
3809
|
+
return this._timeProfilingSlotCount;
|
|
3810
|
+
}
|
|
3811
|
+
getTimeProfilingQuerySet() {
|
|
3812
|
+
return this._timeProfilingQuerySet;
|
|
3813
|
+
}
|
|
3814
|
+
/** Internal helper for auto-assigning timestamp slots to render/compute passes on this encoder. */
|
|
3815
|
+
_applyTimeProfilingToPassProps(props) {
|
|
3816
|
+
const passProps = props || {};
|
|
3817
|
+
if (!this._supportsTimestampQueries() || !this._timeProfilingQuerySet) {
|
|
3818
|
+
return passProps;
|
|
3819
|
+
}
|
|
3820
|
+
if (passProps.timestampQuerySet !== void 0 || passProps.beginTimestampIndex !== void 0 || passProps.endTimestampIndex !== void 0) {
|
|
3821
|
+
return passProps;
|
|
3822
|
+
}
|
|
3823
|
+
const beginTimestampIndex = this._timeProfilingSlotCount;
|
|
3824
|
+
if (beginTimestampIndex + 1 >= this._timeProfilingQuerySet.props.count) {
|
|
3825
|
+
return passProps;
|
|
3826
|
+
}
|
|
3827
|
+
this._timeProfilingSlotCount += 2;
|
|
3828
|
+
return {
|
|
3829
|
+
...passProps,
|
|
3830
|
+
timestampQuerySet: this._timeProfilingQuerySet,
|
|
3831
|
+
beginTimestampIndex,
|
|
3832
|
+
endTimestampIndex: beginTimestampIndex + 1
|
|
3833
|
+
};
|
|
3834
|
+
}
|
|
3835
|
+
_supportsTimestampQueries() {
|
|
3836
|
+
return this.device.features.has("timestamp-query");
|
|
2348
3837
|
}
|
|
2349
3838
|
};
|
|
2350
3839
|
var CommandEncoder = _CommandEncoder;
|
|
@@ -2353,7 +3842,8 @@ var CommandEncoder = _CommandEncoder;
|
|
|
2353
3842
|
// beginComputePass(optional GPUComputePassDescriptor descriptor = {}): GPUComputePassEncoder;
|
|
2354
3843
|
__publicField(CommandEncoder, "defaultProps", {
|
|
2355
3844
|
...Resource.defaultProps,
|
|
2356
|
-
measureExecutionTime: void 0
|
|
3845
|
+
measureExecutionTime: void 0,
|
|
3846
|
+
timeProfilingQuerySet: void 0
|
|
2357
3847
|
});
|
|
2358
3848
|
|
|
2359
3849
|
// dist/adapter/resources/command-buffer.js
|
|
@@ -2370,13 +3860,22 @@ __publicField(CommandBuffer, "defaultProps", {
|
|
|
2370
3860
|
...Resource.defaultProps
|
|
2371
3861
|
});
|
|
2372
3862
|
|
|
2373
|
-
// dist/shadertypes/
|
|
3863
|
+
// dist/shadertypes/shader-types/shader-type-decoder.js
|
|
2374
3864
|
function getVariableShaderTypeInfo(format) {
|
|
2375
|
-
const
|
|
3865
|
+
const resolvedFormat = resolveVariableShaderTypeAlias(format);
|
|
3866
|
+
const decoded = UNIFORM_FORMATS[resolvedFormat];
|
|
3867
|
+
if (!decoded) {
|
|
3868
|
+
throw new Error(`Unsupported variable shader type: ${format}`);
|
|
3869
|
+
}
|
|
2376
3870
|
return decoded;
|
|
2377
3871
|
}
|
|
2378
3872
|
function getAttributeShaderTypeInfo(attributeType) {
|
|
2379
|
-
const
|
|
3873
|
+
const resolvedAttributeType = resolveAttributeShaderTypeAlias(attributeType);
|
|
3874
|
+
const decoded = TYPE_INFO[resolvedAttributeType];
|
|
3875
|
+
if (!decoded) {
|
|
3876
|
+
throw new Error(`Unsupported attribute shader type: ${attributeType}`);
|
|
3877
|
+
}
|
|
3878
|
+
const [primitiveType, components] = decoded;
|
|
2380
3879
|
const integer = primitiveType === "i32" || primitiveType === "u32";
|
|
2381
3880
|
const signed = primitiveType !== "u32";
|
|
2382
3881
|
const byteLength = PRIMITIVE_TYPE_SIZES[primitiveType] * components;
|
|
@@ -2388,6 +3887,33 @@ function getAttributeShaderTypeInfo(attributeType) {
|
|
|
2388
3887
|
signed
|
|
2389
3888
|
};
|
|
2390
3889
|
}
|
|
3890
|
+
var ShaderTypeDecoder = class {
|
|
3891
|
+
getVariableShaderTypeInfo(format) {
|
|
3892
|
+
return getVariableShaderTypeInfo(format);
|
|
3893
|
+
}
|
|
3894
|
+
getAttributeShaderTypeInfo(attributeType) {
|
|
3895
|
+
return getAttributeShaderTypeInfo(attributeType);
|
|
3896
|
+
}
|
|
3897
|
+
makeShaderAttributeType(primitiveType, components) {
|
|
3898
|
+
return makeShaderAttributeType(primitiveType, components);
|
|
3899
|
+
}
|
|
3900
|
+
resolveAttributeShaderTypeAlias(alias) {
|
|
3901
|
+
return resolveAttributeShaderTypeAlias(alias);
|
|
3902
|
+
}
|
|
3903
|
+
resolveVariableShaderTypeAlias(alias) {
|
|
3904
|
+
return resolveVariableShaderTypeAlias(alias);
|
|
3905
|
+
}
|
|
3906
|
+
};
|
|
3907
|
+
function makeShaderAttributeType(primitiveType, components) {
|
|
3908
|
+
return components === 1 ? primitiveType : `vec${components}<${primitiveType}>`;
|
|
3909
|
+
}
|
|
3910
|
+
function resolveAttributeShaderTypeAlias(alias) {
|
|
3911
|
+
return WGSL_ATTRIBUTE_TYPE_ALIAS_MAP[alias] || alias;
|
|
3912
|
+
}
|
|
3913
|
+
function resolveVariableShaderTypeAlias(alias) {
|
|
3914
|
+
return WGSL_VARIABLE_TYPE_ALIAS_MAP[alias] || alias;
|
|
3915
|
+
}
|
|
3916
|
+
var shaderTypeDecoder = new ShaderTypeDecoder();
|
|
2391
3917
|
var PRIMITIVE_TYPE_SIZES = {
|
|
2392
3918
|
f32: 4,
|
|
2393
3919
|
f16: 2,
|
|
@@ -2484,7 +4010,18 @@ var WGSL_ATTRIBUTE_TYPE_ALIAS_MAP = {
|
|
|
2484
4010
|
vec4h: "vec4<f16>"
|
|
2485
4011
|
};
|
|
2486
4012
|
var WGSL_VARIABLE_TYPE_ALIAS_MAP = {
|
|
2487
|
-
|
|
4013
|
+
vec2i: "vec2<i32>",
|
|
4014
|
+
vec3i: "vec3<i32>",
|
|
4015
|
+
vec4i: "vec4<i32>",
|
|
4016
|
+
vec2u: "vec2<u32>",
|
|
4017
|
+
vec3u: "vec3<u32>",
|
|
4018
|
+
vec4u: "vec4<u32>",
|
|
4019
|
+
vec2f: "vec2<f32>",
|
|
4020
|
+
vec3f: "vec3<f32>",
|
|
4021
|
+
vec4f: "vec4<f32>",
|
|
4022
|
+
vec2h: "vec2<f16>",
|
|
4023
|
+
vec3h: "vec3<f16>",
|
|
4024
|
+
vec4h: "vec4<f16>",
|
|
2488
4025
|
mat2x2f: "mat2x2<f32>",
|
|
2489
4026
|
mat2x3f: "mat2x3<f32>",
|
|
2490
4027
|
mat2x4f: "mat2x4<f32>",
|
|
@@ -2548,10 +4085,10 @@ function getAttributeInfoFromLayouts(shaderLayout, bufferLayout, name2) {
|
|
|
2548
4085
|
if (!shaderDeclaration) {
|
|
2549
4086
|
return null;
|
|
2550
4087
|
}
|
|
2551
|
-
const attributeTypeInfo = getAttributeShaderTypeInfo(shaderDeclaration.type);
|
|
2552
|
-
const defaultVertexFormat = getCompatibleVertexFormat(attributeTypeInfo);
|
|
4088
|
+
const attributeTypeInfo = shaderTypeDecoder.getAttributeShaderTypeInfo(shaderDeclaration.type);
|
|
4089
|
+
const defaultVertexFormat = vertexFormatDecoder.getCompatibleVertexFormat(attributeTypeInfo);
|
|
2553
4090
|
const vertexFormat = (bufferMapping == null ? void 0 : bufferMapping.vertexFormat) || defaultVertexFormat;
|
|
2554
|
-
const vertexFormatInfo = getVertexFormatInfo(vertexFormat);
|
|
4091
|
+
const vertexFormatInfo = vertexFormatDecoder.getVertexFormatInfo(vertexFormat);
|
|
2555
4092
|
return {
|
|
2556
4093
|
attributeName: (bufferMapping == null ? void 0 : bufferMapping.attributeName) || shaderDeclaration.name,
|
|
2557
4094
|
bufferName: (bufferMapping == null ? void 0 : bufferMapping.bufferName) || shaderDeclaration.name,
|
|
@@ -2620,7 +4157,7 @@ function getAttributeFromAttributesList(bufferLayouts, name2) {
|
|
|
2620
4157
|
let byteStride = bufferLayout.byteStride;
|
|
2621
4158
|
if (typeof bufferLayout.byteStride !== "number") {
|
|
2622
4159
|
for (const attributeMapping2 of bufferLayout.attributes || []) {
|
|
2623
|
-
const info = getVertexFormatInfo(attributeMapping2.format);
|
|
4160
|
+
const info = vertexFormatDecoder.getVertexFormatInfo(attributeMapping2.format);
|
|
2624
4161
|
byteStride += info.byteLength;
|
|
2625
4162
|
}
|
|
2626
4163
|
}
|
|
@@ -2704,6 +4241,20 @@ __publicField(QuerySet, "defaultProps", {
|
|
|
2704
4241
|
count: void 0
|
|
2705
4242
|
});
|
|
2706
4243
|
|
|
4244
|
+
// dist/adapter/resources/fence.js
|
|
4245
|
+
var _Fence = class extends Resource {
|
|
4246
|
+
get [Symbol.toStringTag]() {
|
|
4247
|
+
return "Fence";
|
|
4248
|
+
}
|
|
4249
|
+
constructor(device, props = {}) {
|
|
4250
|
+
super(device, props, _Fence.defaultProps);
|
|
4251
|
+
}
|
|
4252
|
+
};
|
|
4253
|
+
var Fence = _Fence;
|
|
4254
|
+
__publicField(Fence, "defaultProps", {
|
|
4255
|
+
...Resource.defaultProps
|
|
4256
|
+
});
|
|
4257
|
+
|
|
2707
4258
|
// dist/adapter/resources/pipeline-layout.js
|
|
2708
4259
|
var _PipelineLayout = class extends Resource {
|
|
2709
4260
|
get [Symbol.toStringTag]() {
|
|
@@ -2722,6 +4273,190 @@ __publicField(PipelineLayout, "defaultProps", {
|
|
|
2722
4273
|
}
|
|
2723
4274
|
});
|
|
2724
4275
|
|
|
4276
|
+
// dist/shadertypes/data-types/decode-data-types.js
|
|
4277
|
+
function alignTo(size, count) {
|
|
4278
|
+
switch (count) {
|
|
4279
|
+
case 1:
|
|
4280
|
+
return size;
|
|
4281
|
+
case 2:
|
|
4282
|
+
return size + size % 2;
|
|
4283
|
+
default:
|
|
4284
|
+
return size + (4 - size % 4) % 4;
|
|
4285
|
+
}
|
|
4286
|
+
}
|
|
4287
|
+
function getTypedArrayConstructor(type) {
|
|
4288
|
+
const [, , , , Constructor] = NORMALIZED_TYPE_MAP2[type];
|
|
4289
|
+
return Constructor;
|
|
4290
|
+
}
|
|
4291
|
+
var NORMALIZED_TYPE_MAP2 = {
|
|
4292
|
+
uint8: ["uint8", "u32", 1, false, Uint8Array],
|
|
4293
|
+
sint8: ["sint8", "i32", 1, false, Int8Array],
|
|
4294
|
+
unorm8: ["uint8", "f32", 1, true, Uint8Array],
|
|
4295
|
+
snorm8: ["sint8", "f32", 1, true, Int8Array],
|
|
4296
|
+
uint16: ["uint16", "u32", 2, false, Uint16Array],
|
|
4297
|
+
sint16: ["sint16", "i32", 2, false, Int16Array],
|
|
4298
|
+
unorm16: ["uint16", "u32", 2, true, Uint16Array],
|
|
4299
|
+
snorm16: ["sint16", "i32", 2, true, Int16Array],
|
|
4300
|
+
float16: ["float16", "f16", 2, false, Uint16Array],
|
|
4301
|
+
float32: ["float32", "f32", 4, false, Float32Array],
|
|
4302
|
+
uint32: ["uint32", "u32", 4, false, Uint32Array],
|
|
4303
|
+
sint32: ["sint32", "i32", 4, false, Int32Array]
|
|
4304
|
+
};
|
|
4305
|
+
|
|
4306
|
+
// dist/shadertypes/shader-types/shader-block-layout.js
|
|
4307
|
+
function makeShaderBlockLayout(uniformTypes, options = {}) {
|
|
4308
|
+
const copiedUniformTypes = { ...uniformTypes };
|
|
4309
|
+
const layout = options.layout ?? "std140";
|
|
4310
|
+
const fields = {};
|
|
4311
|
+
let size = 0;
|
|
4312
|
+
for (const [key, uniformType] of Object.entries(copiedUniformTypes)) {
|
|
4313
|
+
size = addToLayout(fields, key, uniformType, size, layout);
|
|
4314
|
+
}
|
|
4315
|
+
size = alignTo(size, getTypeAlignment(copiedUniformTypes, layout));
|
|
4316
|
+
return {
|
|
4317
|
+
layout,
|
|
4318
|
+
byteLength: size * 4,
|
|
4319
|
+
uniformTypes: copiedUniformTypes,
|
|
4320
|
+
fields
|
|
4321
|
+
};
|
|
4322
|
+
}
|
|
4323
|
+
function getLeafLayoutInfo(type, layout) {
|
|
4324
|
+
const resolvedType = resolveVariableShaderTypeAlias(type);
|
|
4325
|
+
const decodedType = getVariableShaderTypeInfo(resolvedType);
|
|
4326
|
+
const matrixMatch = /^mat(\d)x(\d)<.+>$/.exec(resolvedType);
|
|
4327
|
+
if (matrixMatch) {
|
|
4328
|
+
const columns = Number(matrixMatch[1]);
|
|
4329
|
+
const rows = Number(matrixMatch[2]);
|
|
4330
|
+
const columnInfo = getVectorLayoutInfo(rows, resolvedType, decodedType.type, layout);
|
|
4331
|
+
const columnStride = getMatrixColumnStride(columnInfo.size, columnInfo.alignment, layout);
|
|
4332
|
+
return {
|
|
4333
|
+
alignment: columnInfo.alignment,
|
|
4334
|
+
size: columns * columnStride,
|
|
4335
|
+
components: columns * rows,
|
|
4336
|
+
columns,
|
|
4337
|
+
rows,
|
|
4338
|
+
columnStride,
|
|
4339
|
+
shaderType: resolvedType,
|
|
4340
|
+
type: decodedType.type
|
|
4341
|
+
};
|
|
4342
|
+
}
|
|
4343
|
+
const vectorMatch = /^vec(\d)<.+>$/.exec(resolvedType);
|
|
4344
|
+
if (vectorMatch) {
|
|
4345
|
+
return getVectorLayoutInfo(Number(vectorMatch[1]), resolvedType, decodedType.type, layout);
|
|
4346
|
+
}
|
|
4347
|
+
return {
|
|
4348
|
+
alignment: 1,
|
|
4349
|
+
size: 1,
|
|
4350
|
+
components: 1,
|
|
4351
|
+
columns: 1,
|
|
4352
|
+
rows: 1,
|
|
4353
|
+
columnStride: 1,
|
|
4354
|
+
shaderType: resolvedType,
|
|
4355
|
+
type: decodedType.type
|
|
4356
|
+
};
|
|
4357
|
+
}
|
|
4358
|
+
function isCompositeShaderTypeStruct(value) {
|
|
4359
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
4360
|
+
}
|
|
4361
|
+
function addToLayout(fields, name2, type, offset, layout) {
|
|
4362
|
+
if (typeof type === "string") {
|
|
4363
|
+
const info = getLeafLayoutInfo(type, layout);
|
|
4364
|
+
const alignedOffset = alignTo(offset, info.alignment);
|
|
4365
|
+
fields[name2] = {
|
|
4366
|
+
offset: alignedOffset,
|
|
4367
|
+
...info
|
|
4368
|
+
};
|
|
4369
|
+
return alignedOffset + info.size;
|
|
4370
|
+
}
|
|
4371
|
+
if (Array.isArray(type)) {
|
|
4372
|
+
if (Array.isArray(type[0])) {
|
|
4373
|
+
throw new Error(`Nested arrays are not supported for ${name2}`);
|
|
4374
|
+
}
|
|
4375
|
+
const elementType = type[0];
|
|
4376
|
+
const length = type[1];
|
|
4377
|
+
const stride = getArrayStride(elementType, layout);
|
|
4378
|
+
const arrayOffset = alignTo(offset, getTypeAlignment(type, layout));
|
|
4379
|
+
for (let i = 0; i < length; i++) {
|
|
4380
|
+
addToLayout(fields, `${name2}[${i}]`, elementType, arrayOffset + i * stride, layout);
|
|
4381
|
+
}
|
|
4382
|
+
return arrayOffset + stride * length;
|
|
4383
|
+
}
|
|
4384
|
+
if (isCompositeShaderTypeStruct(type)) {
|
|
4385
|
+
const structAlignment = getTypeAlignment(type, layout);
|
|
4386
|
+
let structOffset = alignTo(offset, structAlignment);
|
|
4387
|
+
for (const [memberName, memberType] of Object.entries(type)) {
|
|
4388
|
+
structOffset = addToLayout(fields, `${name2}.${memberName}`, memberType, structOffset, layout);
|
|
4389
|
+
}
|
|
4390
|
+
return alignTo(structOffset, structAlignment);
|
|
4391
|
+
}
|
|
4392
|
+
throw new Error(`Unsupported CompositeShaderType for ${name2}`);
|
|
4393
|
+
}
|
|
4394
|
+
function getTypeSize(type, layout) {
|
|
4395
|
+
if (typeof type === "string") {
|
|
4396
|
+
return getLeafLayoutInfo(type, layout).size;
|
|
4397
|
+
}
|
|
4398
|
+
if (Array.isArray(type)) {
|
|
4399
|
+
const elementType = type[0];
|
|
4400
|
+
const length = type[1];
|
|
4401
|
+
if (Array.isArray(elementType)) {
|
|
4402
|
+
throw new Error("Nested arrays are not supported");
|
|
4403
|
+
}
|
|
4404
|
+
return getArrayStride(elementType, layout) * length;
|
|
4405
|
+
}
|
|
4406
|
+
let size = 0;
|
|
4407
|
+
for (const memberType of Object.values(type)) {
|
|
4408
|
+
const compositeMemberType = memberType;
|
|
4409
|
+
size = alignTo(size, getTypeAlignment(compositeMemberType, layout));
|
|
4410
|
+
size += getTypeSize(compositeMemberType, layout);
|
|
4411
|
+
}
|
|
4412
|
+
return alignTo(size, getTypeAlignment(type, layout));
|
|
4413
|
+
}
|
|
4414
|
+
function getTypeAlignment(type, layout) {
|
|
4415
|
+
if (typeof type === "string") {
|
|
4416
|
+
return getLeafLayoutInfo(type, layout).alignment;
|
|
4417
|
+
}
|
|
4418
|
+
if (Array.isArray(type)) {
|
|
4419
|
+
const elementType = type[0];
|
|
4420
|
+
const elementAlignment = getTypeAlignment(elementType, layout);
|
|
4421
|
+
return uses16ByteArrayAlignment(layout) ? Math.max(elementAlignment, 4) : elementAlignment;
|
|
4422
|
+
}
|
|
4423
|
+
let maxAlignment = 1;
|
|
4424
|
+
for (const memberType of Object.values(type)) {
|
|
4425
|
+
const memberAlignment = getTypeAlignment(memberType, layout);
|
|
4426
|
+
maxAlignment = Math.max(maxAlignment, memberAlignment);
|
|
4427
|
+
}
|
|
4428
|
+
return uses16ByteStructAlignment(layout) ? Math.max(maxAlignment, 4) : maxAlignment;
|
|
4429
|
+
}
|
|
4430
|
+
function getVectorLayoutInfo(components, shaderType, type, layout) {
|
|
4431
|
+
return {
|
|
4432
|
+
alignment: components === 2 ? 2 : 4,
|
|
4433
|
+
size: components === 3 ? 3 : components,
|
|
4434
|
+
components,
|
|
4435
|
+
columns: 1,
|
|
4436
|
+
rows: components,
|
|
4437
|
+
columnStride: components === 3 ? 3 : components,
|
|
4438
|
+
shaderType,
|
|
4439
|
+
type
|
|
4440
|
+
};
|
|
4441
|
+
}
|
|
4442
|
+
function getArrayStride(elementType, layout) {
|
|
4443
|
+
const elementSize = getTypeSize(elementType, layout);
|
|
4444
|
+
const elementAlignment = getTypeAlignment(elementType, layout);
|
|
4445
|
+
return getArrayLikeStride(elementSize, elementAlignment, layout);
|
|
4446
|
+
}
|
|
4447
|
+
function getArrayLikeStride(size, alignment, layout) {
|
|
4448
|
+
return alignTo(size, uses16ByteArrayAlignment(layout) ? 4 : alignment);
|
|
4449
|
+
}
|
|
4450
|
+
function getMatrixColumnStride(size, alignment, layout) {
|
|
4451
|
+
return layout === "std140" ? 4 : alignTo(size, alignment);
|
|
4452
|
+
}
|
|
4453
|
+
function uses16ByteArrayAlignment(layout) {
|
|
4454
|
+
return layout === "std140" || layout === "wgsl-uniform";
|
|
4455
|
+
}
|
|
4456
|
+
function uses16ByteStructAlignment(layout) {
|
|
4457
|
+
return layout === "std140" || layout === "wgsl-uniform";
|
|
4458
|
+
}
|
|
4459
|
+
|
|
2725
4460
|
// dist/utils/array-utils-flat.js
|
|
2726
4461
|
var arrayBuffer;
|
|
2727
4462
|
function getScratchArrayBuffer(byteLength) {
|
|
@@ -2746,88 +4481,192 @@ function isNumberArray(value) {
|
|
|
2746
4481
|
return isTypedArray(value);
|
|
2747
4482
|
}
|
|
2748
4483
|
|
|
2749
|
-
// dist/portable/
|
|
2750
|
-
var
|
|
2751
|
-
|
|
2752
|
-
layout
|
|
2753
|
-
/**
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
constructor(
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
4484
|
+
// dist/portable/shader-block-writer.js
|
|
4485
|
+
var ShaderBlockWriter = class {
|
|
4486
|
+
/** Layout metadata used to flatten and serialize values. */
|
|
4487
|
+
layout;
|
|
4488
|
+
/**
|
|
4489
|
+
* Creates a writer for a precomputed shader-block layout.
|
|
4490
|
+
*/
|
|
4491
|
+
constructor(layout) {
|
|
4492
|
+
this.layout = layout;
|
|
4493
|
+
}
|
|
4494
|
+
/**
|
|
4495
|
+
* Returns `true` if the flattened layout contains the given field.
|
|
4496
|
+
*/
|
|
4497
|
+
has(name2) {
|
|
4498
|
+
return Boolean(this.layout.fields[name2]);
|
|
4499
|
+
}
|
|
4500
|
+
/**
|
|
4501
|
+
* Returns offset and size metadata for a flattened field.
|
|
4502
|
+
*/
|
|
4503
|
+
get(name2) {
|
|
4504
|
+
const entry = this.layout.fields[name2];
|
|
4505
|
+
return entry ? { offset: entry.offset, size: entry.size } : void 0;
|
|
4506
|
+
}
|
|
4507
|
+
/**
|
|
4508
|
+
* Flattens nested composite values into leaf-path values understood by {@link UniformBlock}.
|
|
4509
|
+
*
|
|
4510
|
+
* Top-level values may be supplied either in nested object form matching the
|
|
4511
|
+
* declared composite shader types or as already-flattened leaf-path values.
|
|
4512
|
+
*/
|
|
4513
|
+
getFlatUniformValues(uniformValues) {
|
|
4514
|
+
const flattenedUniformValues = {};
|
|
4515
|
+
for (const [name2, value] of Object.entries(uniformValues)) {
|
|
4516
|
+
const uniformType = this.layout.uniformTypes[name2];
|
|
4517
|
+
if (uniformType) {
|
|
4518
|
+
this._flattenCompositeValue(flattenedUniformValues, name2, uniformType, value);
|
|
4519
|
+
} else if (this.layout.fields[name2]) {
|
|
4520
|
+
flattenedUniformValues[name2] = value;
|
|
4521
|
+
}
|
|
4522
|
+
}
|
|
4523
|
+
return flattenedUniformValues;
|
|
4524
|
+
}
|
|
4525
|
+
/**
|
|
4526
|
+
* Serializes the supplied values into buffer-backed binary data.
|
|
4527
|
+
*
|
|
4528
|
+
* The returned view length matches {@link ShaderBlockLayout.byteLength}, which
|
|
4529
|
+
* is the exact packed size of the block.
|
|
4530
|
+
*/
|
|
2772
4531
|
getData(uniformValues) {
|
|
2773
|
-
const
|
|
4532
|
+
const buffer = getScratchArrayBuffer(this.layout.byteLength);
|
|
4533
|
+
new Uint8Array(buffer, 0, this.layout.byteLength).fill(0);
|
|
2774
4534
|
const typedArrays = {
|
|
2775
|
-
i32: new Int32Array(
|
|
2776
|
-
u32: new Uint32Array(
|
|
2777
|
-
f32: new Float32Array(
|
|
2778
|
-
|
|
2779
|
-
f16: new Uint16Array(arrayBuffer2)
|
|
4535
|
+
i32: new Int32Array(buffer),
|
|
4536
|
+
u32: new Uint32Array(buffer),
|
|
4537
|
+
f32: new Float32Array(buffer),
|
|
4538
|
+
f16: new Uint16Array(buffer)
|
|
2780
4539
|
};
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
4540
|
+
const flattenedUniformValues = this.getFlatUniformValues(uniformValues);
|
|
4541
|
+
for (const [name2, value] of Object.entries(flattenedUniformValues)) {
|
|
4542
|
+
this._writeLeafValue(typedArrays, name2, value);
|
|
4543
|
+
}
|
|
4544
|
+
return new Uint8Array(buffer, 0, this.layout.byteLength);
|
|
4545
|
+
}
|
|
4546
|
+
/**
|
|
4547
|
+
* Recursively flattens nested values using the declared composite shader type.
|
|
4548
|
+
*/
|
|
4549
|
+
_flattenCompositeValue(flattenedUniformValues, baseName, uniformType, value) {
|
|
4550
|
+
if (value === void 0) {
|
|
4551
|
+
return;
|
|
4552
|
+
}
|
|
4553
|
+
if (typeof uniformType === "string" || this.layout.fields[baseName]) {
|
|
4554
|
+
flattenedUniformValues[baseName] = value;
|
|
4555
|
+
return;
|
|
4556
|
+
}
|
|
4557
|
+
if (Array.isArray(uniformType)) {
|
|
4558
|
+
const elementType = uniformType[0];
|
|
4559
|
+
const length = uniformType[1];
|
|
4560
|
+
if (Array.isArray(elementType)) {
|
|
4561
|
+
throw new Error(`Nested arrays are not supported for ${baseName}`);
|
|
2786
4562
|
}
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
4563
|
+
if (typeof elementType === "string" && isNumberArray(value)) {
|
|
4564
|
+
this._flattenPackedArray(flattenedUniformValues, baseName, elementType, length, value);
|
|
4565
|
+
return;
|
|
4566
|
+
}
|
|
4567
|
+
if (!Array.isArray(value)) {
|
|
4568
|
+
log.warn(`Unsupported uniform array value for ${baseName}:`, value)();
|
|
4569
|
+
return;
|
|
4570
|
+
}
|
|
4571
|
+
for (let index = 0; index < Math.min(value.length, length); index++) {
|
|
4572
|
+
const elementValue = value[index];
|
|
4573
|
+
if (elementValue === void 0) {
|
|
2792
4574
|
continue;
|
|
2793
4575
|
}
|
|
2794
|
-
|
|
2795
|
-
}
|
|
2796
|
-
|
|
2797
|
-
|
|
4576
|
+
this._flattenCompositeValue(flattenedUniformValues, `${baseName}[${index}]`, elementType, elementValue);
|
|
4577
|
+
}
|
|
4578
|
+
return;
|
|
4579
|
+
}
|
|
4580
|
+
if (isCompositeShaderTypeStruct(uniformType) && isCompositeUniformObject(value)) {
|
|
4581
|
+
for (const [key, subValue] of Object.entries(value)) {
|
|
4582
|
+
if (subValue === void 0) {
|
|
2798
4583
|
continue;
|
|
2799
4584
|
}
|
|
2800
|
-
|
|
4585
|
+
const nestedName = `${baseName}.${key}`;
|
|
4586
|
+
this._flattenCompositeValue(flattenedUniformValues, nestedName, uniformType[key], subValue);
|
|
2801
4587
|
}
|
|
4588
|
+
return;
|
|
2802
4589
|
}
|
|
2803
|
-
|
|
4590
|
+
log.warn(`Unsupported uniform value for ${baseName}:`, value)();
|
|
2804
4591
|
}
|
|
2805
|
-
/**
|
|
2806
|
-
|
|
2807
|
-
|
|
4592
|
+
/**
|
|
4593
|
+
* Expands tightly packed numeric arrays into per-element leaf fields.
|
|
4594
|
+
*/
|
|
4595
|
+
_flattenPackedArray(flattenedUniformValues, baseName, elementType, length, value) {
|
|
4596
|
+
const numericValue = value;
|
|
4597
|
+
const elementLayout = getLeafLayoutInfo(elementType, this.layout.layout);
|
|
4598
|
+
const packedElementLength = elementLayout.components;
|
|
4599
|
+
for (let index = 0; index < length; index++) {
|
|
4600
|
+
const start = index * packedElementLength;
|
|
4601
|
+
if (start >= numericValue.length) {
|
|
4602
|
+
break;
|
|
4603
|
+
}
|
|
4604
|
+
if (packedElementLength === 1) {
|
|
4605
|
+
flattenedUniformValues[`${baseName}[${index}]`] = Number(numericValue[start]);
|
|
4606
|
+
} else {
|
|
4607
|
+
flattenedUniformValues[`${baseName}[${index}]`] = sliceNumericArray(value, start, start + packedElementLength);
|
|
4608
|
+
}
|
|
4609
|
+
}
|
|
2808
4610
|
}
|
|
2809
|
-
/**
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
4611
|
+
/**
|
|
4612
|
+
* Writes one flattened leaf value into its typed-array view.
|
|
4613
|
+
*/
|
|
4614
|
+
_writeLeafValue(typedArrays, name2, value) {
|
|
4615
|
+
const entry = this.layout.fields[name2];
|
|
4616
|
+
if (!entry) {
|
|
4617
|
+
log.warn(`Uniform ${name2} not found in layout`)();
|
|
4618
|
+
return;
|
|
4619
|
+
}
|
|
4620
|
+
const { type, components, columns, rows, offset, columnStride } = entry;
|
|
4621
|
+
const array = typedArrays[type];
|
|
4622
|
+
if (components === 1) {
|
|
4623
|
+
array[offset] = Number(value);
|
|
4624
|
+
return;
|
|
4625
|
+
}
|
|
4626
|
+
const sourceValue = value;
|
|
4627
|
+
if (columns === 1) {
|
|
4628
|
+
for (let componentIndex = 0; componentIndex < components; componentIndex++) {
|
|
4629
|
+
array[offset + componentIndex] = Number(sourceValue[componentIndex] ?? 0);
|
|
4630
|
+
}
|
|
4631
|
+
return;
|
|
4632
|
+
}
|
|
4633
|
+
let sourceIndex = 0;
|
|
4634
|
+
for (let columnIndex = 0; columnIndex < columns; columnIndex++) {
|
|
4635
|
+
const columnOffset = offset + columnIndex * columnStride;
|
|
4636
|
+
for (let rowIndex = 0; rowIndex < rows; rowIndex++) {
|
|
4637
|
+
array[columnOffset + rowIndex] = Number(sourceValue[sourceIndex++] ?? 0);
|
|
4638
|
+
}
|
|
4639
|
+
}
|
|
2813
4640
|
}
|
|
2814
4641
|
};
|
|
4642
|
+
function isCompositeUniformObject(value) {
|
|
4643
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value) && !ArrayBuffer.isView(value);
|
|
4644
|
+
}
|
|
4645
|
+
function sliceNumericArray(value, start, end) {
|
|
4646
|
+
return Array.prototype.slice.call(value, start, end);
|
|
4647
|
+
}
|
|
2815
4648
|
|
|
2816
4649
|
// dist/utils/array-equal.js
|
|
4650
|
+
var MAX_ELEMENTWISE_ARRAY_COMPARE_LENGTH = 128;
|
|
2817
4651
|
function arrayEqual(a, b, limit = 16) {
|
|
2818
|
-
if (a
|
|
2819
|
-
return
|
|
4652
|
+
if (a === b) {
|
|
4653
|
+
return true;
|
|
2820
4654
|
}
|
|
2821
4655
|
const arrayA = a;
|
|
2822
4656
|
const arrayB = b;
|
|
2823
|
-
if (!isNumberArray(arrayA)) {
|
|
4657
|
+
if (!isNumberArray(arrayA) || !isNumberArray(arrayB)) {
|
|
2824
4658
|
return false;
|
|
2825
4659
|
}
|
|
2826
|
-
if (
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
4660
|
+
if (arrayA.length !== arrayB.length) {
|
|
4661
|
+
return false;
|
|
4662
|
+
}
|
|
4663
|
+
const maxCompareLength = Math.min(limit, MAX_ELEMENTWISE_ARRAY_COMPARE_LENGTH);
|
|
4664
|
+
if (arrayA.length > maxCompareLength) {
|
|
4665
|
+
return false;
|
|
4666
|
+
}
|
|
4667
|
+
for (let i = 0; i < arrayA.length; ++i) {
|
|
4668
|
+
if (arrayB[i] !== arrayA[i]) {
|
|
4669
|
+
return false;
|
|
2831
4670
|
}
|
|
2832
4671
|
}
|
|
2833
4672
|
return true;
|
|
@@ -2891,24 +4730,33 @@ var UniformBlock = class {
|
|
|
2891
4730
|
};
|
|
2892
4731
|
|
|
2893
4732
|
// dist/portable/uniform-store.js
|
|
4733
|
+
var minUniformBufferSize = 1024;
|
|
2894
4734
|
var UniformStore = class {
|
|
4735
|
+
/** Device used to infer layout and allocate buffers. */
|
|
4736
|
+
device;
|
|
2895
4737
|
/** Stores the uniform values for each uniform block */
|
|
2896
4738
|
uniformBlocks = /* @__PURE__ */ new Map();
|
|
2897
|
-
/**
|
|
2898
|
-
|
|
4739
|
+
/** Flattened layout metadata for each block. */
|
|
4740
|
+
shaderBlockLayouts = /* @__PURE__ */ new Map();
|
|
4741
|
+
/** Serializers for block-backed uniform data. */
|
|
4742
|
+
shaderBlockWriters = /* @__PURE__ */ new Map();
|
|
2899
4743
|
/** Actual buffer for the blocks */
|
|
2900
4744
|
uniformBuffers = /* @__PURE__ */ new Map();
|
|
2901
4745
|
/**
|
|
2902
|
-
*
|
|
2903
|
-
* @param blocks
|
|
4746
|
+
* Creates a new {@link UniformStore} for the supplied device and block definitions.
|
|
2904
4747
|
*/
|
|
2905
|
-
constructor(blocks) {
|
|
4748
|
+
constructor(device, blocks) {
|
|
4749
|
+
this.device = device;
|
|
2906
4750
|
for (const [bufferName, block] of Object.entries(blocks)) {
|
|
2907
4751
|
const uniformBufferName = bufferName;
|
|
2908
|
-
const
|
|
2909
|
-
|
|
4752
|
+
const shaderBlockLayout = makeShaderBlockLayout(block.uniformTypes ?? {}, {
|
|
4753
|
+
layout: block.layout ?? getDefaultUniformBufferLayout(device)
|
|
4754
|
+
});
|
|
4755
|
+
const shaderBlockWriter = new ShaderBlockWriter(shaderBlockLayout);
|
|
4756
|
+
this.shaderBlockLayouts.set(uniformBufferName, shaderBlockLayout);
|
|
4757
|
+
this.shaderBlockWriters.set(uniformBufferName, shaderBlockWriter);
|
|
2910
4758
|
const uniformBlock = new UniformBlock({ name: bufferName });
|
|
2911
|
-
uniformBlock.setUniforms(block.defaultUniforms || {});
|
|
4759
|
+
uniformBlock.setUniforms(shaderBlockWriter.getFlatUniformValues(block.defaultUniforms || {}));
|
|
2912
4760
|
this.uniformBlocks.set(uniformBufferName, uniformBlock);
|
|
2913
4761
|
}
|
|
2914
4762
|
}
|
|
@@ -2920,36 +4768,52 @@ var UniformStore = class {
|
|
|
2920
4768
|
}
|
|
2921
4769
|
/**
|
|
2922
4770
|
* Set uniforms
|
|
2923
|
-
*
|
|
4771
|
+
*
|
|
4772
|
+
* Makes all group properties partial and eagerly propagates changes to any
|
|
4773
|
+
* managed GPU buffers.
|
|
2924
4774
|
*/
|
|
2925
4775
|
setUniforms(uniforms) {
|
|
2926
4776
|
var _a;
|
|
2927
4777
|
for (const [blockName, uniformValues] of Object.entries(uniforms)) {
|
|
2928
|
-
|
|
4778
|
+
const uniformBufferName = blockName;
|
|
4779
|
+
const shaderBlockWriter = this.shaderBlockWriters.get(uniformBufferName);
|
|
4780
|
+
const flattenedUniforms = shaderBlockWriter == null ? void 0 : shaderBlockWriter.getFlatUniformValues(uniformValues || {});
|
|
4781
|
+
(_a = this.uniformBlocks.get(uniformBufferName)) == null ? void 0 : _a.setUniforms(flattenedUniforms || {});
|
|
2929
4782
|
}
|
|
2930
4783
|
this.updateUniformBuffers();
|
|
2931
4784
|
}
|
|
2932
|
-
/**
|
|
4785
|
+
/**
|
|
4786
|
+
* Returns the allocation size for the named uniform buffer.
|
|
4787
|
+
*
|
|
4788
|
+
* This may exceed the packed layout size because minimum buffer-size policy is
|
|
4789
|
+
* applied at the store layer.
|
|
4790
|
+
*/
|
|
2933
4791
|
getUniformBufferByteLength(uniformBufferName) {
|
|
2934
4792
|
var _a;
|
|
2935
|
-
|
|
4793
|
+
const packedByteLength = ((_a = this.shaderBlockLayouts.get(uniformBufferName)) == null ? void 0 : _a.byteLength) || 0;
|
|
4794
|
+
return Math.max(packedByteLength, minUniformBufferSize);
|
|
2936
4795
|
}
|
|
2937
|
-
/**
|
|
4796
|
+
/**
|
|
4797
|
+
* Returns packed binary data that can be uploaded to the named uniform buffer.
|
|
4798
|
+
*
|
|
4799
|
+
* The returned view length matches the packed block size and is not padded to
|
|
4800
|
+
* the store's minimum allocation size.
|
|
4801
|
+
*/
|
|
2938
4802
|
getUniformBufferData(uniformBufferName) {
|
|
2939
|
-
var _a
|
|
4803
|
+
var _a;
|
|
2940
4804
|
const uniformValues = ((_a = this.uniformBlocks.get(uniformBufferName)) == null ? void 0 : _a.getAllUniforms()) || {};
|
|
2941
|
-
|
|
4805
|
+
const shaderBlockWriter = this.shaderBlockWriters.get(uniformBufferName);
|
|
4806
|
+
return (shaderBlockWriter == null ? void 0 : shaderBlockWriter.getData(uniformValues)) || new Uint8Array(0);
|
|
2942
4807
|
}
|
|
2943
4808
|
/**
|
|
2944
|
-
* Creates an unmanaged uniform buffer
|
|
2945
|
-
* The new buffer is initialized with current / supplied values
|
|
4809
|
+
* Creates an unmanaged uniform buffer initialized with the current or supplied values.
|
|
2946
4810
|
*/
|
|
2947
|
-
createUniformBuffer(
|
|
4811
|
+
createUniformBuffer(uniformBufferName, uniforms) {
|
|
2948
4812
|
if (uniforms) {
|
|
2949
4813
|
this.setUniforms(uniforms);
|
|
2950
4814
|
}
|
|
2951
4815
|
const byteLength = this.getUniformBufferByteLength(uniformBufferName);
|
|
2952
|
-
const uniformBuffer = device.createBuffer({
|
|
4816
|
+
const uniformBuffer = this.device.createBuffer({
|
|
2953
4817
|
usage: Buffer2.UNIFORM | Buffer2.COPY_DST,
|
|
2954
4818
|
byteLength
|
|
2955
4819
|
});
|
|
@@ -2957,11 +4821,11 @@ var UniformStore = class {
|
|
|
2957
4821
|
uniformBuffer.write(uniformBufferData);
|
|
2958
4822
|
return uniformBuffer;
|
|
2959
4823
|
}
|
|
2960
|
-
/**
|
|
2961
|
-
getManagedUniformBuffer(
|
|
4824
|
+
/** Returns the managed uniform buffer for the named block. */
|
|
4825
|
+
getManagedUniformBuffer(uniformBufferName) {
|
|
2962
4826
|
if (!this.uniformBuffers.get(uniformBufferName)) {
|
|
2963
4827
|
const byteLength = this.getUniformBufferByteLength(uniformBufferName);
|
|
2964
|
-
const uniformBuffer = device.createBuffer({
|
|
4828
|
+
const uniformBuffer = this.device.createBuffer({
|
|
2965
4829
|
usage: Buffer2.UNIFORM | Buffer2.COPY_DST,
|
|
2966
4830
|
byteLength
|
|
2967
4831
|
});
|
|
@@ -2969,7 +4833,11 @@ var UniformStore = class {
|
|
|
2969
4833
|
}
|
|
2970
4834
|
return this.uniformBuffers.get(uniformBufferName);
|
|
2971
4835
|
}
|
|
2972
|
-
/**
|
|
4836
|
+
/**
|
|
4837
|
+
* Updates every managed uniform buffer whose source uniforms have changed.
|
|
4838
|
+
*
|
|
4839
|
+
* @returns The first redraw reason encountered, or `false` if nothing changed.
|
|
4840
|
+
*/
|
|
2973
4841
|
updateUniformBuffers() {
|
|
2974
4842
|
let reason = false;
|
|
2975
4843
|
for (const uniformBufferName of this.uniformBlocks.keys()) {
|
|
@@ -2981,7 +4849,11 @@ var UniformStore = class {
|
|
|
2981
4849
|
}
|
|
2982
4850
|
return reason;
|
|
2983
4851
|
}
|
|
2984
|
-
/**
|
|
4852
|
+
/**
|
|
4853
|
+
* Updates one managed uniform buffer if its corresponding block is dirty.
|
|
4854
|
+
*
|
|
4855
|
+
* @returns The redraw reason for the update, or `false` if no write occurred.
|
|
4856
|
+
*/
|
|
2985
4857
|
updateUniformBuffer(uniformBufferName) {
|
|
2986
4858
|
var _a;
|
|
2987
4859
|
const uniformBlock = this.uniformBlocks.get(uniformBufferName);
|
|
@@ -2998,8 +4870,49 @@ var UniformStore = class {
|
|
|
2998
4870
|
return reason;
|
|
2999
4871
|
}
|
|
3000
4872
|
};
|
|
4873
|
+
function getDefaultUniformBufferLayout(device) {
|
|
4874
|
+
return device.type === "webgpu" ? "wgsl-uniform" : "std140";
|
|
4875
|
+
}
|
|
4876
|
+
|
|
4877
|
+
// dist/shadertypes/texture-types/texture-layout.js
|
|
4878
|
+
function getTextureImageView(arrayBuffer2, memoryLayout, format, image = 0) {
|
|
4879
|
+
const formatInfo = textureFormatDecoder.getInfo(format);
|
|
4880
|
+
const bytesPerComponent = formatInfo.bytesPerPixel / formatInfo.components;
|
|
4881
|
+
const { bytesPerImage } = memoryLayout;
|
|
4882
|
+
const offset = bytesPerImage * image;
|
|
4883
|
+
const totalPixels = memoryLayout.bytesPerImage / bytesPerComponent;
|
|
4884
|
+
switch (format) {
|
|
4885
|
+
case "rgba8unorm":
|
|
4886
|
+
case "bgra8unorm":
|
|
4887
|
+
case "rgba8uint":
|
|
4888
|
+
return new Uint8Array(arrayBuffer2, offset, totalPixels);
|
|
4889
|
+
case "r8unorm":
|
|
4890
|
+
return new Uint8Array(arrayBuffer2, offset, totalPixels);
|
|
4891
|
+
case "r16uint":
|
|
4892
|
+
case "rgba16uint":
|
|
4893
|
+
return new Uint16Array(arrayBuffer2, offset, totalPixels);
|
|
4894
|
+
case "r32uint":
|
|
4895
|
+
case "rgba32uint":
|
|
4896
|
+
return new Uint32Array(arrayBuffer2, offset, totalPixels);
|
|
4897
|
+
case "r32float":
|
|
4898
|
+
return new Float32Array(arrayBuffer2, offset, totalPixels);
|
|
4899
|
+
case "rgba16float":
|
|
4900
|
+
return new Uint16Array(arrayBuffer2, offset, totalPixels);
|
|
4901
|
+
case "rgba32float":
|
|
4902
|
+
return new Float32Array(arrayBuffer2, offset, totalPixels);
|
|
4903
|
+
default:
|
|
4904
|
+
throw new Error(`Unsupported format: ${format}`);
|
|
4905
|
+
}
|
|
4906
|
+
}
|
|
4907
|
+
function setTextureImageData(arrayBuffer2, memoryLayout, format, data, image = 0) {
|
|
4908
|
+
const offset = 0;
|
|
4909
|
+
const totalPixels = memoryLayout.bytesPerImage / memoryLayout.bytesPerPixel;
|
|
4910
|
+
const subArray = data.subarray(0, totalPixels);
|
|
4911
|
+
const typedArray = getTextureImageView(arrayBuffer2, memoryLayout, format, image);
|
|
4912
|
+
typedArray.set(subArray, offset);
|
|
4913
|
+
}
|
|
3001
4914
|
|
|
3002
|
-
// dist/shadertypes/
|
|
4915
|
+
// dist/shadertypes/texture-types/pixel-utils.js
|
|
3003
4916
|
function readPixel(pixelData, x, y, bitsPerChannel) {
|
|
3004
4917
|
if (x < 0 || x >= pixelData.width || y < 0 || y >= pixelData.height) {
|
|
3005
4918
|
throw new Error("Coordinates out of bounds.");
|
|
@@ -3009,7 +4922,7 @@ function readPixel(pixelData, x, y, bitsPerChannel) {
|
|
|
3009
4922
|
let bitOffsetWithinPixel = 0;
|
|
3010
4923
|
const channels = [];
|
|
3011
4924
|
for (let i = 0; i < 4; i++) {
|
|
3012
|
-
const bits = bitsPerChannel[i];
|
|
4925
|
+
const bits = bitsPerChannel[i] ?? 0;
|
|
3013
4926
|
if (bits <= 0) {
|
|
3014
4927
|
channels.push(0);
|
|
3015
4928
|
} else {
|
|
@@ -3018,14 +4931,14 @@ function readPixel(pixelData, x, y, bitsPerChannel) {
|
|
|
3018
4931
|
bitOffsetWithinPixel += bits;
|
|
3019
4932
|
}
|
|
3020
4933
|
}
|
|
3021
|
-
return [channels[0], channels[1], channels[2], channels[3]];
|
|
4934
|
+
return [channels[0] ?? 0, channels[1] ?? 0, channels[2] ?? 0, channels[3] ?? 0];
|
|
3022
4935
|
}
|
|
3023
4936
|
function writePixel(dataView, bitOffset, bitsPerChannel, pixel) {
|
|
3024
4937
|
let currentBitOffset = bitOffset;
|
|
3025
4938
|
for (let channel = 0; channel < 4; channel++) {
|
|
3026
|
-
const bits = bitsPerChannel[channel];
|
|
4939
|
+
const bits = bitsPerChannel[channel] ?? 0;
|
|
3027
4940
|
const maxValue = (1 << bits) - 1;
|
|
3028
|
-
const channelValue = pixel[channel] & maxValue;
|
|
4941
|
+
const channelValue = (pixel[channel] ?? 0) & maxValue;
|
|
3029
4942
|
writeBitsToDataView(dataView, currentBitOffset, bits, channelValue);
|
|
3030
4943
|
currentBitOffset += bits;
|
|
3031
4944
|
}
|