@luma.gl/effects 7.4.0-alpha.2 → 9.1.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +10 -1
- package/README.md +2 -2
- package/dist/dist.dev.js +3458 -0
- package/dist/dist.min.js +18 -30
- package/dist/index.cjs +1724 -0
- package/dist/index.cjs.map +7 -0
- package/dist/index.d.ts +40 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/passes/postprocessing/fxaa/fxaa.d.ts +15 -0
- package/dist/passes/postprocessing/fxaa/fxaa.d.ts.map +1 -0
- package/{src/shader-modules → dist/passes/postprocessing}/fxaa/fxaa.js +18 -14
- package/dist/passes/postprocessing/fxaa/fxaa.js.map +1 -0
- package/dist/passes/postprocessing/image-adjust-filters/brightnesscontrast.d.ts +43 -0
- package/dist/passes/postprocessing/image-adjust-filters/brightnesscontrast.d.ts.map +1 -0
- package/dist/passes/postprocessing/image-adjust-filters/brightnesscontrast.js +68 -0
- package/dist/passes/postprocessing/image-adjust-filters/brightnesscontrast.js.map +1 -0
- package/dist/passes/postprocessing/image-adjust-filters/denoise.d.ts +43 -0
- package/dist/passes/postprocessing/image-adjust-filters/denoise.d.ts.map +1 -0
- package/dist/passes/postprocessing/image-adjust-filters/denoise.js +74 -0
- package/dist/passes/postprocessing/image-adjust-filters/denoise.js.map +1 -0
- package/dist/passes/postprocessing/image-adjust-filters/huesaturation.d.ts +46 -0
- package/dist/passes/postprocessing/image-adjust-filters/huesaturation.d.ts.map +1 -0
- package/dist/passes/postprocessing/image-adjust-filters/huesaturation.js +101 -0
- package/dist/passes/postprocessing/image-adjust-filters/huesaturation.js.map +1 -0
- package/dist/passes/postprocessing/image-adjust-filters/noise.d.ts +33 -0
- package/dist/passes/postprocessing/image-adjust-filters/noise.d.ts.map +1 -0
- package/dist/passes/postprocessing/image-adjust-filters/noise.js +58 -0
- package/dist/passes/postprocessing/image-adjust-filters/noise.js.map +1 -0
- package/dist/passes/postprocessing/image-adjust-filters/sepia.d.ts +29 -0
- package/dist/passes/postprocessing/image-adjust-filters/sepia.d.ts.map +1 -0
- package/dist/passes/postprocessing/image-adjust-filters/sepia.js +44 -0
- package/dist/passes/postprocessing/image-adjust-filters/sepia.js.map +1 -0
- package/dist/passes/postprocessing/image-adjust-filters/vibrance.d.ts +29 -0
- package/dist/passes/postprocessing/image-adjust-filters/vibrance.d.ts.map +1 -0
- package/dist/passes/postprocessing/image-adjust-filters/vibrance.js +35 -0
- package/dist/passes/postprocessing/image-adjust-filters/vibrance.js.map +1 -0
- package/dist/passes/postprocessing/image-adjust-filters/vignette.d.ts +44 -0
- package/dist/passes/postprocessing/image-adjust-filters/vignette.d.ts.map +1 -0
- package/dist/passes/postprocessing/image-adjust-filters/vignette.js +39 -0
- package/dist/passes/postprocessing/image-adjust-filters/vignette.js.map +1 -0
- package/dist/passes/postprocessing/image-blur-filters/tiltshift.d.ts +79 -0
- package/dist/passes/postprocessing/image-blur-filters/tiltshift.d.ts.map +1 -0
- package/dist/passes/postprocessing/image-blur-filters/tiltshift.js +111 -0
- package/dist/passes/postprocessing/image-blur-filters/tiltshift.js.map +1 -0
- package/dist/passes/postprocessing/image-blur-filters/triangleblur.d.ts +56 -0
- package/dist/passes/postprocessing/image-blur-filters/triangleblur.d.ts.map +1 -0
- package/dist/passes/postprocessing/image-blur-filters/triangleblur.js +65 -0
- package/dist/passes/postprocessing/image-blur-filters/triangleblur.js.map +1 -0
- package/dist/passes/postprocessing/image-blur-filters/zoomblur.d.ts +42 -0
- package/dist/passes/postprocessing/image-blur-filters/zoomblur.d.ts.map +1 -0
- package/dist/passes/postprocessing/image-blur-filters/zoomblur.js +59 -0
- package/dist/passes/postprocessing/image-blur-filters/zoomblur.js.map +1 -0
- package/dist/passes/postprocessing/image-fun-filters/colorhalftone.d.ts +52 -0
- package/dist/passes/postprocessing/image-fun-filters/colorhalftone.d.ts.map +1 -0
- package/dist/passes/postprocessing/image-fun-filters/colorhalftone.js +64 -0
- package/dist/passes/postprocessing/image-fun-filters/colorhalftone.js.map +1 -0
- package/dist/passes/postprocessing/image-fun-filters/dotscreen.d.ts +50 -0
- package/dist/passes/postprocessing/image-fun-filters/dotscreen.d.ts.map +1 -0
- package/dist/passes/postprocessing/image-fun-filters/dotscreen.js +50 -0
- package/dist/passes/postprocessing/image-fun-filters/dotscreen.js.map +1 -0
- package/dist/passes/postprocessing/image-fun-filters/edgework.d.ts +54 -0
- package/dist/passes/postprocessing/image-fun-filters/edgework.d.ts.map +1 -0
- package/dist/passes/postprocessing/image-fun-filters/edgework.js +101 -0
- package/dist/passes/postprocessing/image-fun-filters/edgework.js.map +1 -0
- package/dist/passes/postprocessing/image-fun-filters/hexagonalpixelate.d.ts +43 -0
- package/dist/passes/postprocessing/image-fun-filters/hexagonalpixelate.d.ts.map +1 -0
- package/dist/passes/postprocessing/image-fun-filters/hexagonalpixelate.js +68 -0
- package/dist/passes/postprocessing/image-fun-filters/hexagonalpixelate.js.map +1 -0
- package/dist/passes/postprocessing/image-fun-filters/ink.d.ts +40 -0
- package/dist/passes/postprocessing/image-fun-filters/ink.d.ts.map +1 -0
- package/dist/passes/postprocessing/image-fun-filters/ink.js +52 -0
- package/dist/passes/postprocessing/image-fun-filters/ink.js.map +1 -0
- package/dist/passes/postprocessing/image-fun-filters/magnify.d.ts +45 -0
- package/dist/passes/postprocessing/image-fun-filters/magnify.d.ts.map +1 -0
- package/dist/passes/postprocessing/image-fun-filters/magnify.js +49 -0
- package/dist/passes/postprocessing/image-fun-filters/magnify.js.map +1 -0
- package/dist/passes/postprocessing/image-warp-filters/bulgepinch.d.ts +49 -0
- package/dist/passes/postprocessing/image-warp-filters/bulgepinch.d.ts.map +1 -0
- package/dist/passes/postprocessing/image-warp-filters/bulgepinch.js +56 -0
- package/dist/passes/postprocessing/image-warp-filters/bulgepinch.js.map +1 -0
- package/dist/passes/postprocessing/image-warp-filters/swirl.d.ts +50 -0
- package/dist/passes/postprocessing/image-warp-filters/swirl.d.ts.map +1 -0
- package/dist/passes/postprocessing/image-warp-filters/swirl.js +57 -0
- package/dist/passes/postprocessing/image-warp-filters/swirl.js.map +1 -0
- package/dist/passes/postprocessing/image-warp-filters/warp.d.ts +8 -0
- package/dist/passes/postprocessing/image-warp-filters/warp.d.ts.map +1 -0
- package/dist/passes/postprocessing/image-warp-filters/warp.js +21 -0
- package/dist/passes/postprocessing/image-warp-filters/warp.js.map +1 -0
- package/package.json +37 -13
- package/src/index.ts +99 -0
- package/src/passes/postprocessing/fxaa/fxaa.ts +694 -0
- package/src/passes/postprocessing/image-adjust-filters/brightnesscontrast.ts +81 -0
- package/src/passes/postprocessing/image-adjust-filters/denoise.ts +97 -0
- package/src/passes/postprocessing/image-adjust-filters/huesaturation.ts +120 -0
- package/src/passes/postprocessing/image-adjust-filters/noise.ts +73 -0
- package/src/passes/postprocessing/image-adjust-filters/sepia.ts +54 -0
- package/src/passes/postprocessing/image-adjust-filters/vibrance.ts +48 -0
- package/src/passes/postprocessing/image-adjust-filters/vignette.ts +58 -0
- package/src/passes/postprocessing/image-blur-filters/tiltshift.ts +135 -0
- package/src/passes/postprocessing/image-blur-filters/triangleblur.ts +84 -0
- package/src/passes/postprocessing/image-blur-filters/zoomblur.ts +75 -0
- package/src/passes/postprocessing/image-fun-filters/colorhalftone.ts +85 -0
- package/src/passes/postprocessing/image-fun-filters/dotscreen.ts +70 -0
- package/src/passes/postprocessing/image-fun-filters/edgework.ts +120 -0
- package/src/passes/postprocessing/image-fun-filters/hexagonalpixelate.ts +86 -0
- package/src/passes/postprocessing/image-fun-filters/ink.ts +73 -0
- package/src/passes/postprocessing/image-fun-filters/magnify.ts +70 -0
- package/src/passes/postprocessing/image-warp-filters/bulgepinch.ts +72 -0
- package/src/passes/postprocessing/image-warp-filters/swirl.ts +77 -0
- package/src/passes/postprocessing/image-warp-filters/warp.ts +28 -0
- package/dist/dist.js +0 -3621
- package/dist/es5/experimental/passes/outline-pass.js +0 -125
- package/dist/es5/experimental/passes/outline-pass.js.map +0 -1
- package/dist/es5/experimental/passes/ssao-pass.js +0 -133
- package/dist/es5/experimental/passes/ssao-pass.js.map +0 -1
- package/dist/es5/experimental/shader-modules/convolution.js +0 -46
- package/dist/es5/experimental/shader-modules/convolution.js.map +0 -1
- package/dist/es5/experimental/shader-modules/depth.js +0 -27
- package/dist/es5/experimental/shader-modules/depth.js.map +0 -1
- package/dist/es5/experimental/shader-modules/pack.js +0 -19
- package/dist/es5/experimental/shader-modules/pack.js.map +0 -1
- package/dist/es5/experimental/shader-modules/ssao.js +0 -32
- package/dist/es5/experimental/shader-modules/ssao.js.map +0 -1
- package/dist/es5/index.js +0 -184
- package/dist/es5/index.js.map +0 -1
- package/dist/es5/shader-modules/adjust-filters/brightnesscontrast.js +0 -29
- package/dist/es5/shader-modules/adjust-filters/brightnesscontrast.js.map +0 -1
- package/dist/es5/shader-modules/adjust-filters/denoise.js +0 -29
- package/dist/es5/shader-modules/adjust-filters/denoise.js.map +0 -1
- package/dist/es5/shader-modules/adjust-filters/huesaturation.js +0 -29
- package/dist/es5/shader-modules/adjust-filters/huesaturation.js.map +0 -1
- package/dist/es5/shader-modules/adjust-filters/noise.js +0 -24
- package/dist/es5/shader-modules/adjust-filters/noise.js.map +0 -1
- package/dist/es5/shader-modules/adjust-filters/sepia.js +0 -24
- package/dist/es5/shader-modules/adjust-filters/sepia.js.map +0 -1
- package/dist/es5/shader-modules/adjust-filters/vibrance.js +0 -24
- package/dist/es5/shader-modules/adjust-filters/vibrance.js.map +0 -1
- package/dist/es5/shader-modules/adjust-filters/vignette.js +0 -29
- package/dist/es5/shader-modules/adjust-filters/vignette.js.map +0 -1
- package/dist/es5/shader-modules/blur-filters/tiltshift.js +0 -49
- package/dist/es5/shader-modules/blur-filters/tiltshift.js.map +0 -1
- package/dist/es5/shader-modules/blur-filters/triangleblur.js +0 -42
- package/dist/es5/shader-modules/blur-filters/triangleblur.js.map +0 -1
- package/dist/es5/shader-modules/blur-filters/zoomblur.js +0 -31
- package/dist/es5/shader-modules/blur-filters/zoomblur.js.map +0 -1
- package/dist/es5/shader-modules/fun-filters/colorhalftone.js +0 -31
- package/dist/es5/shader-modules/fun-filters/colorhalftone.js.map +0 -1
- package/dist/es5/shader-modules/fun-filters/dotscreen.js +0 -31
- package/dist/es5/shader-modules/fun-filters/dotscreen.js.map +0 -1
- package/dist/es5/shader-modules/fun-filters/edgework.js +0 -42
- package/dist/es5/shader-modules/fun-filters/edgework.js.map +0 -1
- package/dist/es5/shader-modules/fun-filters/hexagonalpixelate.js +0 -29
- package/dist/es5/shader-modules/fun-filters/hexagonalpixelate.js.map +0 -1
- package/dist/es5/shader-modules/fun-filters/ink.js +0 -24
- package/dist/es5/shader-modules/fun-filters/ink.js.map +0 -1
- package/dist/es5/shader-modules/fxaa/fxaa.js +0 -47
- package/dist/es5/shader-modules/fxaa/fxaa.js.map +0 -1
- package/dist/es5/shader-modules/utils/random.js +0 -13
- package/dist/es5/shader-modules/utils/random.js.map +0 -1
- package/dist/es5/shader-modules/warp-filters/bulgepinch.js +0 -36
- package/dist/es5/shader-modules/warp-filters/bulgepinch.js.map +0 -1
- package/dist/es5/shader-modules/warp-filters/swirl.js +0 -36
- package/dist/es5/shader-modules/warp-filters/swirl.js.map +0 -1
- package/dist/es5/shader-modules/warp-filters/warp.js +0 -13
- package/dist/es5/shader-modules/warp-filters/warp.js.map +0 -1
- package/dist/es6/experimental/passes/outline-pass.js +0 -48
- package/dist/es6/experimental/passes/outline-pass.js.map +0 -1
- package/dist/es6/experimental/passes/ssao-pass.js +0 -76
- package/dist/es6/experimental/passes/ssao-pass.js.map +0 -1
- package/dist/es6/experimental/shader-modules/convolution.js +0 -37
- package/dist/es6/experimental/shader-modules/convolution.js.map +0 -1
- package/dist/es6/experimental/shader-modules/depth.js +0 -13
- package/dist/es6/experimental/shader-modules/depth.js.map +0 -1
- package/dist/es6/experimental/shader-modules/pack.js +0 -10
- package/dist/es6/experimental/shader-modules/pack.js.map +0 -1
- package/dist/es6/experimental/shader-modules/ssao.js +0 -21
- package/dist/es6/experimental/shader-modules/ssao.js.map +0 -1
- package/dist/es6/index.js +0 -23
- package/dist/es6/index.js.map +0 -1
- package/dist/es6/shader-modules/adjust-filters/brightnesscontrast.js +0 -22
- package/dist/es6/shader-modules/adjust-filters/brightnesscontrast.js.map +0 -1
- package/dist/es6/shader-modules/adjust-filters/denoise.js +0 -20
- package/dist/es6/shader-modules/adjust-filters/denoise.js.map +0 -1
- package/dist/es6/shader-modules/adjust-filters/huesaturation.js +0 -22
- package/dist/es6/shader-modules/adjust-filters/huesaturation.js.map +0 -1
- package/dist/es6/shader-modules/adjust-filters/noise.js +0 -17
- package/dist/es6/shader-modules/adjust-filters/noise.js.map +0 -1
- package/dist/es6/shader-modules/adjust-filters/sepia.js +0 -17
- package/dist/es6/shader-modules/adjust-filters/sepia.js.map +0 -1
- package/dist/es6/shader-modules/adjust-filters/vibrance.js +0 -17
- package/dist/es6/shader-modules/adjust-filters/vibrance.js.map +0 -1
- package/dist/es6/shader-modules/adjust-filters/vignette.js +0 -22
- package/dist/es6/shader-modules/adjust-filters/vignette.js.map +0 -1
- package/dist/es6/shader-modules/blur-filters/tiltshift.js +0 -38
- package/dist/es6/shader-modules/blur-filters/tiltshift.js.map +0 -1
- package/dist/es6/shader-modules/blur-filters/triangleblur.js +0 -31
- package/dist/es6/shader-modules/blur-filters/triangleblur.js.map +0 -1
- package/dist/es6/shader-modules/blur-filters/zoomblur.js +0 -20
- package/dist/es6/shader-modules/blur-filters/zoomblur.js.map +0 -1
- package/dist/es6/shader-modules/fun-filters/colorhalftone.js +0 -24
- package/dist/es6/shader-modules/fun-filters/colorhalftone.js.map +0 -1
- package/dist/es6/shader-modules/fun-filters/dotscreen.js +0 -24
- package/dist/es6/shader-modules/fun-filters/dotscreen.js.map +0 -1
- package/dist/es6/shader-modules/fun-filters/edgework.js +0 -31
- package/dist/es6/shader-modules/fun-filters/edgework.js.map +0 -1
- package/dist/es6/shader-modules/fun-filters/hexagonalpixelate.js +0 -22
- package/dist/es6/shader-modules/fun-filters/hexagonalpixelate.js.map +0 -1
- package/dist/es6/shader-modules/fun-filters/ink.js +0 -17
- package/dist/es6/shader-modules/fun-filters/ink.js.map +0 -1
- package/dist/es6/shader-modules/fxaa/fxaa.js +0 -39
- package/dist/es6/shader-modules/fxaa/fxaa.js.map +0 -1
- package/dist/es6/shader-modules/utils/random.js +0 -6
- package/dist/es6/shader-modules/utils/random.js.map +0 -1
- package/dist/es6/shader-modules/warp-filters/bulgepinch.js +0 -25
- package/dist/es6/shader-modules/warp-filters/bulgepinch.js.map +0 -1
- package/dist/es6/shader-modules/warp-filters/swirl.js +0 -25
- package/dist/es6/shader-modules/warp-filters/swirl.js.map +0 -1
- package/dist/es6/shader-modules/warp-filters/warp.js +0 -6
- package/dist/es6/shader-modules/warp-filters/warp.js.map +0 -1
- package/dist/esm/experimental/passes/outline-pass.js +0 -114
- package/dist/esm/experimental/passes/outline-pass.js.map +0 -1
- package/dist/esm/experimental/passes/ssao-pass.js +0 -120
- package/dist/esm/experimental/passes/ssao-pass.js.map +0 -1
- package/dist/esm/experimental/shader-modules/convolution.js +0 -39
- package/dist/esm/experimental/shader-modules/convolution.js.map +0 -1
- package/dist/esm/experimental/shader-modules/depth.js +0 -16
- package/dist/esm/experimental/shader-modules/depth.js.map +0 -1
- package/dist/esm/experimental/shader-modules/pack.js +0 -12
- package/dist/esm/experimental/shader-modules/pack.js.map +0 -1
- package/dist/esm/experimental/shader-modules/ssao.js +0 -21
- package/dist/esm/experimental/shader-modules/ssao.js.map +0 -1
- package/dist/esm/index.js +0 -23
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/shader-modules/adjust-filters/brightnesscontrast.js +0 -22
- package/dist/esm/shader-modules/adjust-filters/brightnesscontrast.js.map +0 -1
- package/dist/esm/shader-modules/adjust-filters/denoise.js +0 -22
- package/dist/esm/shader-modules/adjust-filters/denoise.js.map +0 -1
- package/dist/esm/shader-modules/adjust-filters/huesaturation.js +0 -22
- package/dist/esm/shader-modules/adjust-filters/huesaturation.js.map +0 -1
- package/dist/esm/shader-modules/adjust-filters/noise.js +0 -17
- package/dist/esm/shader-modules/adjust-filters/noise.js.map +0 -1
- package/dist/esm/shader-modules/adjust-filters/sepia.js +0 -17
- package/dist/esm/shader-modules/adjust-filters/sepia.js.map +0 -1
- package/dist/esm/shader-modules/adjust-filters/vibrance.js +0 -17
- package/dist/esm/shader-modules/adjust-filters/vibrance.js.map +0 -1
- package/dist/esm/shader-modules/adjust-filters/vignette.js +0 -22
- package/dist/esm/shader-modules/adjust-filters/vignette.js.map +0 -1
- package/dist/esm/shader-modules/blur-filters/tiltshift.js +0 -38
- package/dist/esm/shader-modules/blur-filters/tiltshift.js.map +0 -1
- package/dist/esm/shader-modules/blur-filters/triangleblur.js +0 -31
- package/dist/esm/shader-modules/blur-filters/triangleblur.js.map +0 -1
- package/dist/esm/shader-modules/blur-filters/zoomblur.js +0 -20
- package/dist/esm/shader-modules/blur-filters/zoomblur.js.map +0 -1
- package/dist/esm/shader-modules/fun-filters/colorhalftone.js +0 -24
- package/dist/esm/shader-modules/fun-filters/colorhalftone.js.map +0 -1
- package/dist/esm/shader-modules/fun-filters/dotscreen.js +0 -24
- package/dist/esm/shader-modules/fun-filters/dotscreen.js.map +0 -1
- package/dist/esm/shader-modules/fun-filters/edgework.js +0 -31
- package/dist/esm/shader-modules/fun-filters/edgework.js.map +0 -1
- package/dist/esm/shader-modules/fun-filters/hexagonalpixelate.js +0 -22
- package/dist/esm/shader-modules/fun-filters/hexagonalpixelate.js.map +0 -1
- package/dist/esm/shader-modules/fun-filters/ink.js +0 -17
- package/dist/esm/shader-modules/fun-filters/ink.js.map +0 -1
- package/dist/esm/shader-modules/fxaa/fxaa.js +0 -39
- package/dist/esm/shader-modules/fxaa/fxaa.js.map +0 -1
- package/dist/esm/shader-modules/utils/random.js +0 -6
- package/dist/esm/shader-modules/utils/random.js.map +0 -1
- package/dist/esm/shader-modules/warp-filters/bulgepinch.js +0 -25
- package/dist/esm/shader-modules/warp-filters/bulgepinch.js.map +0 -1
- package/dist/esm/shader-modules/warp-filters/swirl.js +0 -25
- package/dist/esm/shader-modules/warp-filters/swirl.js.map +0 -1
- package/dist/esm/shader-modules/warp-filters/warp.js +0 -6
- package/dist/esm/shader-modules/warp-filters/warp.js.map +0 -1
- package/src/experimental/passes/outline-pass.js +0 -58
- package/src/experimental/passes/ssao-pass.js +0 -73
- package/src/experimental/passes/ssao-pass.md +0 -15
- package/src/experimental/shader-modules/convolution.js +0 -96
- package/src/experimental/shader-modules/convolution.md +0 -15
- package/src/experimental/shader-modules/depth.js +0 -84
- package/src/experimental/shader-modules/depth.md +0 -76
- package/src/experimental/shader-modules/pack.js +0 -32
- package/src/experimental/shader-modules/pack.md +0 -15
- package/src/experimental/shader-modules/ssao.js +0 -183
- package/src/experimental/shader-modules/ssao.md +0 -4
- package/src/index.js +0 -35
- package/src/shader-modules/adjust-filters/brightnesscontrast.js +0 -38
- package/src/shader-modules/adjust-filters/denoise.js +0 -49
- package/src/shader-modules/adjust-filters/huesaturation.js +0 -57
- package/src/shader-modules/adjust-filters/noise.js +0 -36
- package/src/shader-modules/adjust-filters/sepia.js +0 -37
- package/src/shader-modules/adjust-filters/vibrance.js +0 -32
- package/src/shader-modules/adjust-filters/vignette.js +0 -33
- package/src/shader-modules/blur-filters/tiltshift.js +0 -105
- package/src/shader-modules/blur-filters/triangleblur.js +0 -55
- package/src/shader-modules/blur-filters/zoomblur.js +0 -56
- package/src/shader-modules/fun-filters/colorhalftone.js +0 -60
- package/src/shader-modules/fun-filters/dotscreen.js +0 -45
- package/src/shader-modules/fun-filters/edgework.js +0 -84
- package/src/shader-modules/fun-filters/hexagonalpixelate.js +0 -63
- package/src/shader-modules/fun-filters/ink.js +0 -49
- package/src/shader-modules/utils/random.js +0 -12
- package/src/shader-modules/warp-filters/bulgepinch.js +0 -52
- package/src/shader-modules/warp-filters/swirl.js +0 -55
- package/src/shader-modules/warp-filters/warp.js +0 -19
package/dist/dist.dev.js
ADDED
|
@@ -0,0 +1,3458 @@
|
|
|
1
|
+
(function webpackUniversalModuleDefinition(root, factory) {
|
|
2
|
+
if (typeof exports === 'object' && typeof module === 'object')
|
|
3
|
+
module.exports = factory();
|
|
4
|
+
else if (typeof define === 'function' && define.amd) define([], factory);
|
|
5
|
+
else if (typeof exports === 'object') exports['luma'] = factory();
|
|
6
|
+
else root['luma'] = factory();})(globalThis, function () {
|
|
7
|
+
"use strict";
|
|
8
|
+
var __exports__ = (() => {
|
|
9
|
+
var __create = Object.create;
|
|
10
|
+
var __defProp = Object.defineProperty;
|
|
11
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
12
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
13
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
14
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
15
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
16
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
17
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
18
|
+
};
|
|
19
|
+
var __export = (target, all) => {
|
|
20
|
+
for (var name2 in all)
|
|
21
|
+
__defProp(target, name2, { get: all[name2], enumerable: true });
|
|
22
|
+
};
|
|
23
|
+
var __copyProps = (to, from, except, desc) => {
|
|
24
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
25
|
+
for (let key of __getOwnPropNames(from))
|
|
26
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
27
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
28
|
+
}
|
|
29
|
+
return to;
|
|
30
|
+
};
|
|
31
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
32
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
33
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
34
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
35
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
36
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
37
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
38
|
+
mod
|
|
39
|
+
));
|
|
40
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
41
|
+
var __publicField = (obj, key, value) => {
|
|
42
|
+
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
43
|
+
return value;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// external-global-plugin:@luma.gl/shadertools
|
|
47
|
+
var require_shadertools = __commonJS({
|
|
48
|
+
"external-global-plugin:@luma.gl/shadertools"(exports, module) {
|
|
49
|
+
module.exports = globalThis.luma;
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// bundle.ts
|
|
54
|
+
var bundle_exports = {};
|
|
55
|
+
__export(bundle_exports, {
|
|
56
|
+
Adapter: () => Adapter,
|
|
57
|
+
Buffer: () => Buffer2,
|
|
58
|
+
CanvasContext: () => CanvasContext,
|
|
59
|
+
CommandBuffer: () => CommandBuffer,
|
|
60
|
+
CommandEncoder: () => CommandEncoder,
|
|
61
|
+
ComputePass: () => ComputePass,
|
|
62
|
+
ComputePipeline: () => ComputePipeline,
|
|
63
|
+
Device: () => Device,
|
|
64
|
+
DeviceFeatures: () => DeviceFeatures,
|
|
65
|
+
DeviceLimits: () => DeviceLimits,
|
|
66
|
+
ExternalTexture: () => ExternalTexture,
|
|
67
|
+
Framebuffer: () => Framebuffer,
|
|
68
|
+
QuerySet: () => QuerySet,
|
|
69
|
+
RenderPass: () => RenderPass,
|
|
70
|
+
RenderPipeline: () => RenderPipeline,
|
|
71
|
+
Resource: () => Resource,
|
|
72
|
+
Sampler: () => Sampler,
|
|
73
|
+
Shader: () => Shader,
|
|
74
|
+
Texture: () => Texture,
|
|
75
|
+
TextureView: () => TextureView,
|
|
76
|
+
TransformFeedback: () => TransformFeedback,
|
|
77
|
+
UniformBlock: () => UniformBlock,
|
|
78
|
+
UniformBufferLayout: () => UniformBufferLayout,
|
|
79
|
+
UniformStore: () => UniformStore,
|
|
80
|
+
VertexArray: () => VertexArray,
|
|
81
|
+
_BufferLayoutHelper: () => BufferLayoutHelper,
|
|
82
|
+
_getTextureFormatDefinition: () => getTextureFormatDefinition,
|
|
83
|
+
_getTextureFormatTable: () => getTextureFormatTable,
|
|
84
|
+
decodeShaderAttributeType: () => decodeShaderAttributeType,
|
|
85
|
+
decodeShaderUniformType: () => decodeShaderUniformType,
|
|
86
|
+
decodeTextureFormat: () => decodeTextureFormat,
|
|
87
|
+
decodeVertexFormat: () => decodeVertexFormat,
|
|
88
|
+
getAttributeInfosFromLayouts: () => getAttributeInfosFromLayouts,
|
|
89
|
+
getDataTypeFromTypedArray: () => getDataTypeFromTypedArray,
|
|
90
|
+
getScratchArray: () => getScratchArray,
|
|
91
|
+
getTextureFormatCapabilities: () => getTextureFormatCapabilities,
|
|
92
|
+
getTypedArrayFromDataType: () => getTypedArrayFromDataType,
|
|
93
|
+
getVertexFormatFromAttribute: () => getVertexFormatFromAttribute,
|
|
94
|
+
log: () => log,
|
|
95
|
+
luma: () => luma
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// ../../node_modules/@probe.gl/env/dist/lib/globals.js
|
|
99
|
+
var window_ = globalThis;
|
|
100
|
+
var document_ = globalThis.document || {};
|
|
101
|
+
var process_ = globalThis.process || {};
|
|
102
|
+
var console_ = globalThis.console;
|
|
103
|
+
var navigator_ = globalThis.navigator || {};
|
|
104
|
+
|
|
105
|
+
// ../../node_modules/@probe.gl/env/dist/lib/is-electron.js
|
|
106
|
+
function isElectron(mockUserAgent) {
|
|
107
|
+
if (typeof window !== "undefined" && window.process?.type === "renderer") {
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
if (typeof process !== "undefined" && Boolean(process.versions?.["electron"])) {
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
const realUserAgent = typeof navigator !== "undefined" && navigator.userAgent;
|
|
114
|
+
const userAgent = mockUserAgent || realUserAgent;
|
|
115
|
+
return Boolean(userAgent && userAgent.indexOf("Electron") >= 0);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// ../../node_modules/@probe.gl/env/dist/lib/is-browser.js
|
|
119
|
+
function isBrowser() {
|
|
120
|
+
const isNode = (
|
|
121
|
+
// @ts-expect-error
|
|
122
|
+
typeof process === "object" && String(process) === "[object process]" && !process?.browser
|
|
123
|
+
);
|
|
124
|
+
return !isNode || isElectron();
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// ../../node_modules/@probe.gl/env/dist/index.js
|
|
128
|
+
var VERSION = true ? "4.0.7" : "untranspiled source";
|
|
129
|
+
|
|
130
|
+
// ../../node_modules/@probe.gl/stats/dist/utils/hi-res-timestamp.js
|
|
131
|
+
function getHiResTimestamp() {
|
|
132
|
+
let timestamp;
|
|
133
|
+
if (typeof window !== "undefined" && window.performance) {
|
|
134
|
+
timestamp = window.performance.now();
|
|
135
|
+
} else if (typeof process !== "undefined" && process.hrtime) {
|
|
136
|
+
const timeParts = process.hrtime();
|
|
137
|
+
timestamp = timeParts[0] * 1e3 + timeParts[1] / 1e6;
|
|
138
|
+
} else {
|
|
139
|
+
timestamp = Date.now();
|
|
140
|
+
}
|
|
141
|
+
return timestamp;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// ../../node_modules/@probe.gl/stats/dist/lib/stat.js
|
|
145
|
+
var Stat = class {
|
|
146
|
+
constructor(name2, type) {
|
|
147
|
+
this.sampleSize = 1;
|
|
148
|
+
this.time = 0;
|
|
149
|
+
this.count = 0;
|
|
150
|
+
this.samples = 0;
|
|
151
|
+
this.lastTiming = 0;
|
|
152
|
+
this.lastSampleTime = 0;
|
|
153
|
+
this.lastSampleCount = 0;
|
|
154
|
+
this._count = 0;
|
|
155
|
+
this._time = 0;
|
|
156
|
+
this._samples = 0;
|
|
157
|
+
this._startTime = 0;
|
|
158
|
+
this._timerPending = false;
|
|
159
|
+
this.name = name2;
|
|
160
|
+
this.type = type;
|
|
161
|
+
this.reset();
|
|
162
|
+
}
|
|
163
|
+
reset() {
|
|
164
|
+
this.time = 0;
|
|
165
|
+
this.count = 0;
|
|
166
|
+
this.samples = 0;
|
|
167
|
+
this.lastTiming = 0;
|
|
168
|
+
this.lastSampleTime = 0;
|
|
169
|
+
this.lastSampleCount = 0;
|
|
170
|
+
this._count = 0;
|
|
171
|
+
this._time = 0;
|
|
172
|
+
this._samples = 0;
|
|
173
|
+
this._startTime = 0;
|
|
174
|
+
this._timerPending = false;
|
|
175
|
+
return this;
|
|
176
|
+
}
|
|
177
|
+
setSampleSize(samples) {
|
|
178
|
+
this.sampleSize = samples;
|
|
179
|
+
return this;
|
|
180
|
+
}
|
|
181
|
+
/** Call to increment count (+1) */
|
|
182
|
+
incrementCount() {
|
|
183
|
+
this.addCount(1);
|
|
184
|
+
return this;
|
|
185
|
+
}
|
|
186
|
+
/** Call to decrement count (-1) */
|
|
187
|
+
decrementCount() {
|
|
188
|
+
this.subtractCount(1);
|
|
189
|
+
return this;
|
|
190
|
+
}
|
|
191
|
+
/** Increase count */
|
|
192
|
+
addCount(value) {
|
|
193
|
+
this._count += value;
|
|
194
|
+
this._samples++;
|
|
195
|
+
this._checkSampling();
|
|
196
|
+
return this;
|
|
197
|
+
}
|
|
198
|
+
/** Decrease count */
|
|
199
|
+
subtractCount(value) {
|
|
200
|
+
this._count -= value;
|
|
201
|
+
this._samples++;
|
|
202
|
+
this._checkSampling();
|
|
203
|
+
return this;
|
|
204
|
+
}
|
|
205
|
+
/** Add an arbitrary timing and bump the count */
|
|
206
|
+
addTime(time) {
|
|
207
|
+
this._time += time;
|
|
208
|
+
this.lastTiming = time;
|
|
209
|
+
this._samples++;
|
|
210
|
+
this._checkSampling();
|
|
211
|
+
return this;
|
|
212
|
+
}
|
|
213
|
+
/** Start a timer */
|
|
214
|
+
timeStart() {
|
|
215
|
+
this._startTime = getHiResTimestamp();
|
|
216
|
+
this._timerPending = true;
|
|
217
|
+
return this;
|
|
218
|
+
}
|
|
219
|
+
/** End a timer. Adds to time and bumps the timing count. */
|
|
220
|
+
timeEnd() {
|
|
221
|
+
if (!this._timerPending) {
|
|
222
|
+
return this;
|
|
223
|
+
}
|
|
224
|
+
this.addTime(getHiResTimestamp() - this._startTime);
|
|
225
|
+
this._timerPending = false;
|
|
226
|
+
this._checkSampling();
|
|
227
|
+
return this;
|
|
228
|
+
}
|
|
229
|
+
getSampleAverageCount() {
|
|
230
|
+
return this.sampleSize > 0 ? this.lastSampleCount / this.sampleSize : 0;
|
|
231
|
+
}
|
|
232
|
+
/** Calculate average time / count for the previous window */
|
|
233
|
+
getSampleAverageTime() {
|
|
234
|
+
return this.sampleSize > 0 ? this.lastSampleTime / this.sampleSize : 0;
|
|
235
|
+
}
|
|
236
|
+
/** Calculate counts per second for the previous window */
|
|
237
|
+
getSampleHz() {
|
|
238
|
+
return this.lastSampleTime > 0 ? this.sampleSize / (this.lastSampleTime / 1e3) : 0;
|
|
239
|
+
}
|
|
240
|
+
getAverageCount() {
|
|
241
|
+
return this.samples > 0 ? this.count / this.samples : 0;
|
|
242
|
+
}
|
|
243
|
+
/** Calculate average time / count */
|
|
244
|
+
getAverageTime() {
|
|
245
|
+
return this.samples > 0 ? this.time / this.samples : 0;
|
|
246
|
+
}
|
|
247
|
+
/** Calculate counts per second */
|
|
248
|
+
getHz() {
|
|
249
|
+
return this.time > 0 ? this.samples / (this.time / 1e3) : 0;
|
|
250
|
+
}
|
|
251
|
+
_checkSampling() {
|
|
252
|
+
if (this._samples === this.sampleSize) {
|
|
253
|
+
this.lastSampleTime = this._time;
|
|
254
|
+
this.lastSampleCount = this._count;
|
|
255
|
+
this.count += this._count;
|
|
256
|
+
this.time += this._time;
|
|
257
|
+
this.samples += this._samples;
|
|
258
|
+
this._time = 0;
|
|
259
|
+
this._count = 0;
|
|
260
|
+
this._samples = 0;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
// ../../node_modules/@probe.gl/stats/dist/lib/stats.js
|
|
266
|
+
var Stats = class {
|
|
267
|
+
constructor(options) {
|
|
268
|
+
this.stats = {};
|
|
269
|
+
this.id = options.id;
|
|
270
|
+
this.stats = {};
|
|
271
|
+
this._initializeStats(options.stats);
|
|
272
|
+
Object.seal(this);
|
|
273
|
+
}
|
|
274
|
+
/** Acquire a stat. Create if it doesn't exist. */
|
|
275
|
+
get(name2, type = "count") {
|
|
276
|
+
return this._getOrCreate({ name: name2, type });
|
|
277
|
+
}
|
|
278
|
+
get size() {
|
|
279
|
+
return Object.keys(this.stats).length;
|
|
280
|
+
}
|
|
281
|
+
/** Reset all stats */
|
|
282
|
+
reset() {
|
|
283
|
+
for (const stat of Object.values(this.stats)) {
|
|
284
|
+
stat.reset();
|
|
285
|
+
}
|
|
286
|
+
return this;
|
|
287
|
+
}
|
|
288
|
+
forEach(fn) {
|
|
289
|
+
for (const stat of Object.values(this.stats)) {
|
|
290
|
+
fn(stat);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
getTable() {
|
|
294
|
+
const table = {};
|
|
295
|
+
this.forEach((stat) => {
|
|
296
|
+
table[stat.name] = {
|
|
297
|
+
time: stat.time || 0,
|
|
298
|
+
count: stat.count || 0,
|
|
299
|
+
average: stat.getAverageTime() || 0,
|
|
300
|
+
hz: stat.getHz() || 0
|
|
301
|
+
};
|
|
302
|
+
});
|
|
303
|
+
return table;
|
|
304
|
+
}
|
|
305
|
+
_initializeStats(stats = []) {
|
|
306
|
+
stats.forEach((stat) => this._getOrCreate(stat));
|
|
307
|
+
}
|
|
308
|
+
_getOrCreate(stat) {
|
|
309
|
+
const { name: name2, type } = stat;
|
|
310
|
+
let result = this.stats[name2];
|
|
311
|
+
if (!result) {
|
|
312
|
+
if (stat instanceof Stat) {
|
|
313
|
+
result = stat;
|
|
314
|
+
} else {
|
|
315
|
+
result = new Stat(name2, type);
|
|
316
|
+
}
|
|
317
|
+
this.stats[name2] = result;
|
|
318
|
+
}
|
|
319
|
+
return result;
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
// ../core/src/utils/stats-manager.ts
|
|
324
|
+
var StatsManager = class {
|
|
325
|
+
stats = /* @__PURE__ */ new Map();
|
|
326
|
+
getStats(name2) {
|
|
327
|
+
return this.get(name2);
|
|
328
|
+
}
|
|
329
|
+
get(name2) {
|
|
330
|
+
if (!this.stats.has(name2)) {
|
|
331
|
+
this.stats.set(name2, new Stats({ id: name2 }));
|
|
332
|
+
}
|
|
333
|
+
return this.stats.get(name2);
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
var lumaStats = new StatsManager();
|
|
337
|
+
|
|
338
|
+
// ../../node_modules/@probe.gl/log/dist/utils/local-storage.js
|
|
339
|
+
function getStorage(type) {
|
|
340
|
+
try {
|
|
341
|
+
const storage = window[type];
|
|
342
|
+
const x = "__storage_test__";
|
|
343
|
+
storage.setItem(x, x);
|
|
344
|
+
storage.removeItem(x);
|
|
345
|
+
return storage;
|
|
346
|
+
} catch (e) {
|
|
347
|
+
return null;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
var LocalStorage = class {
|
|
351
|
+
constructor(id, defaultConfig, type = "sessionStorage") {
|
|
352
|
+
this.storage = getStorage(type);
|
|
353
|
+
this.id = id;
|
|
354
|
+
this.config = defaultConfig;
|
|
355
|
+
this._loadConfiguration();
|
|
356
|
+
}
|
|
357
|
+
getConfiguration() {
|
|
358
|
+
return this.config;
|
|
359
|
+
}
|
|
360
|
+
setConfiguration(configuration) {
|
|
361
|
+
Object.assign(this.config, configuration);
|
|
362
|
+
if (this.storage) {
|
|
363
|
+
const serialized = JSON.stringify(this.config);
|
|
364
|
+
this.storage.setItem(this.id, serialized);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
// Get config from persistent store, if available
|
|
368
|
+
_loadConfiguration() {
|
|
369
|
+
let configuration = {};
|
|
370
|
+
if (this.storage) {
|
|
371
|
+
const serializedConfiguration = this.storage.getItem(this.id);
|
|
372
|
+
configuration = serializedConfiguration ? JSON.parse(serializedConfiguration) : {};
|
|
373
|
+
}
|
|
374
|
+
Object.assign(this.config, configuration);
|
|
375
|
+
return this;
|
|
376
|
+
}
|
|
377
|
+
};
|
|
378
|
+
|
|
379
|
+
// ../../node_modules/@probe.gl/log/dist/utils/formatters.js
|
|
380
|
+
function formatTime(ms) {
|
|
381
|
+
let formatted;
|
|
382
|
+
if (ms < 10) {
|
|
383
|
+
formatted = `${ms.toFixed(2)}ms`;
|
|
384
|
+
} else if (ms < 100) {
|
|
385
|
+
formatted = `${ms.toFixed(1)}ms`;
|
|
386
|
+
} else if (ms < 1e3) {
|
|
387
|
+
formatted = `${ms.toFixed(0)}ms`;
|
|
388
|
+
} else {
|
|
389
|
+
formatted = `${(ms / 1e3).toFixed(2)}s`;
|
|
390
|
+
}
|
|
391
|
+
return formatted;
|
|
392
|
+
}
|
|
393
|
+
function leftPad(string, length = 8) {
|
|
394
|
+
const padLength = Math.max(length - string.length, 0);
|
|
395
|
+
return `${" ".repeat(padLength)}${string}`;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// ../../node_modules/@probe.gl/log/dist/utils/color.js
|
|
399
|
+
var COLOR;
|
|
400
|
+
(function(COLOR2) {
|
|
401
|
+
COLOR2[COLOR2["BLACK"] = 30] = "BLACK";
|
|
402
|
+
COLOR2[COLOR2["RED"] = 31] = "RED";
|
|
403
|
+
COLOR2[COLOR2["GREEN"] = 32] = "GREEN";
|
|
404
|
+
COLOR2[COLOR2["YELLOW"] = 33] = "YELLOW";
|
|
405
|
+
COLOR2[COLOR2["BLUE"] = 34] = "BLUE";
|
|
406
|
+
COLOR2[COLOR2["MAGENTA"] = 35] = "MAGENTA";
|
|
407
|
+
COLOR2[COLOR2["CYAN"] = 36] = "CYAN";
|
|
408
|
+
COLOR2[COLOR2["WHITE"] = 37] = "WHITE";
|
|
409
|
+
COLOR2[COLOR2["BRIGHT_BLACK"] = 90] = "BRIGHT_BLACK";
|
|
410
|
+
COLOR2[COLOR2["BRIGHT_RED"] = 91] = "BRIGHT_RED";
|
|
411
|
+
COLOR2[COLOR2["BRIGHT_GREEN"] = 92] = "BRIGHT_GREEN";
|
|
412
|
+
COLOR2[COLOR2["BRIGHT_YELLOW"] = 93] = "BRIGHT_YELLOW";
|
|
413
|
+
COLOR2[COLOR2["BRIGHT_BLUE"] = 94] = "BRIGHT_BLUE";
|
|
414
|
+
COLOR2[COLOR2["BRIGHT_MAGENTA"] = 95] = "BRIGHT_MAGENTA";
|
|
415
|
+
COLOR2[COLOR2["BRIGHT_CYAN"] = 96] = "BRIGHT_CYAN";
|
|
416
|
+
COLOR2[COLOR2["BRIGHT_WHITE"] = 97] = "BRIGHT_WHITE";
|
|
417
|
+
})(COLOR || (COLOR = {}));
|
|
418
|
+
var BACKGROUND_INCREMENT = 10;
|
|
419
|
+
function getColor(color) {
|
|
420
|
+
if (typeof color !== "string") {
|
|
421
|
+
return color;
|
|
422
|
+
}
|
|
423
|
+
color = color.toUpperCase();
|
|
424
|
+
return COLOR[color] || COLOR.WHITE;
|
|
425
|
+
}
|
|
426
|
+
function addColor(string, color, background) {
|
|
427
|
+
if (!isBrowser && typeof string === "string") {
|
|
428
|
+
if (color) {
|
|
429
|
+
const colorCode = getColor(color);
|
|
430
|
+
string = `\x1B[${colorCode}m${string}\x1B[39m`;
|
|
431
|
+
}
|
|
432
|
+
if (background) {
|
|
433
|
+
const colorCode = getColor(background);
|
|
434
|
+
string = `\x1B[${colorCode + BACKGROUND_INCREMENT}m${string}\x1B[49m`;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
return string;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// ../../node_modules/@probe.gl/log/dist/utils/autobind.js
|
|
441
|
+
function autobind(obj, predefined = ["constructor"]) {
|
|
442
|
+
const proto = Object.getPrototypeOf(obj);
|
|
443
|
+
const propNames = Object.getOwnPropertyNames(proto);
|
|
444
|
+
const object = obj;
|
|
445
|
+
for (const key of propNames) {
|
|
446
|
+
const value = object[key];
|
|
447
|
+
if (typeof value === "function") {
|
|
448
|
+
if (!predefined.find((name2) => key === name2)) {
|
|
449
|
+
object[key] = value.bind(obj);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
// ../../node_modules/@probe.gl/log/dist/utils/assert.js
|
|
456
|
+
function assert(condition, message) {
|
|
457
|
+
if (!condition) {
|
|
458
|
+
throw new Error(message || "Assertion failed");
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
// ../../node_modules/@probe.gl/log/dist/utils/hi-res-timestamp.js
|
|
463
|
+
function getHiResTimestamp2() {
|
|
464
|
+
let timestamp;
|
|
465
|
+
if (isBrowser() && window_.performance) {
|
|
466
|
+
timestamp = window_?.performance?.now?.();
|
|
467
|
+
} else if ("hrtime" in process_) {
|
|
468
|
+
const timeParts = process_?.hrtime?.();
|
|
469
|
+
timestamp = timeParts[0] * 1e3 + timeParts[1] / 1e6;
|
|
470
|
+
} else {
|
|
471
|
+
timestamp = Date.now();
|
|
472
|
+
}
|
|
473
|
+
return timestamp;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
// ../../node_modules/@probe.gl/log/dist/log.js
|
|
477
|
+
var originalConsole = {
|
|
478
|
+
debug: isBrowser() ? console.debug || console.log : console.log,
|
|
479
|
+
log: console.log,
|
|
480
|
+
info: console.info,
|
|
481
|
+
warn: console.warn,
|
|
482
|
+
error: console.error
|
|
483
|
+
};
|
|
484
|
+
var DEFAULT_LOG_CONFIGURATION = {
|
|
485
|
+
enabled: true,
|
|
486
|
+
level: 0
|
|
487
|
+
};
|
|
488
|
+
function noop() {
|
|
489
|
+
}
|
|
490
|
+
var cache = {};
|
|
491
|
+
var ONCE = { once: true };
|
|
492
|
+
var Log = class {
|
|
493
|
+
constructor({ id } = { id: "" }) {
|
|
494
|
+
this.VERSION = VERSION;
|
|
495
|
+
this._startTs = getHiResTimestamp2();
|
|
496
|
+
this._deltaTs = getHiResTimestamp2();
|
|
497
|
+
this.userData = {};
|
|
498
|
+
this.LOG_THROTTLE_TIMEOUT = 0;
|
|
499
|
+
this.id = id;
|
|
500
|
+
this.userData = {};
|
|
501
|
+
this._storage = new LocalStorage(`__probe-${this.id}__`, DEFAULT_LOG_CONFIGURATION);
|
|
502
|
+
this.timeStamp(`${this.id} started`);
|
|
503
|
+
autobind(this);
|
|
504
|
+
Object.seal(this);
|
|
505
|
+
}
|
|
506
|
+
set level(newLevel) {
|
|
507
|
+
this.setLevel(newLevel);
|
|
508
|
+
}
|
|
509
|
+
get level() {
|
|
510
|
+
return this.getLevel();
|
|
511
|
+
}
|
|
512
|
+
isEnabled() {
|
|
513
|
+
return this._storage.config.enabled;
|
|
514
|
+
}
|
|
515
|
+
getLevel() {
|
|
516
|
+
return this._storage.config.level;
|
|
517
|
+
}
|
|
518
|
+
/** @return milliseconds, with fractions */
|
|
519
|
+
getTotal() {
|
|
520
|
+
return Number((getHiResTimestamp2() - this._startTs).toPrecision(10));
|
|
521
|
+
}
|
|
522
|
+
/** @return milliseconds, with fractions */
|
|
523
|
+
getDelta() {
|
|
524
|
+
return Number((getHiResTimestamp2() - this._deltaTs).toPrecision(10));
|
|
525
|
+
}
|
|
526
|
+
/** @deprecated use logLevel */
|
|
527
|
+
set priority(newPriority) {
|
|
528
|
+
this.level = newPriority;
|
|
529
|
+
}
|
|
530
|
+
/** @deprecated use logLevel */
|
|
531
|
+
get priority() {
|
|
532
|
+
return this.level;
|
|
533
|
+
}
|
|
534
|
+
/** @deprecated use logLevel */
|
|
535
|
+
getPriority() {
|
|
536
|
+
return this.level;
|
|
537
|
+
}
|
|
538
|
+
// Configure
|
|
539
|
+
enable(enabled = true) {
|
|
540
|
+
this._storage.setConfiguration({ enabled });
|
|
541
|
+
return this;
|
|
542
|
+
}
|
|
543
|
+
setLevel(level) {
|
|
544
|
+
this._storage.setConfiguration({ level });
|
|
545
|
+
return this;
|
|
546
|
+
}
|
|
547
|
+
/** return the current status of the setting */
|
|
548
|
+
get(setting) {
|
|
549
|
+
return this._storage.config[setting];
|
|
550
|
+
}
|
|
551
|
+
// update the status of the setting
|
|
552
|
+
set(setting, value) {
|
|
553
|
+
this._storage.setConfiguration({ [setting]: value });
|
|
554
|
+
}
|
|
555
|
+
/** Logs the current settings as a table */
|
|
556
|
+
settings() {
|
|
557
|
+
if (console.table) {
|
|
558
|
+
console.table(this._storage.config);
|
|
559
|
+
} else {
|
|
560
|
+
console.log(this._storage.config);
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
// Unconditional logging
|
|
564
|
+
assert(condition, message) {
|
|
565
|
+
if (!condition) {
|
|
566
|
+
throw new Error(message || "Assertion failed");
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
warn(message) {
|
|
570
|
+
return this._getLogFunction(0, message, originalConsole.warn, arguments, ONCE);
|
|
571
|
+
}
|
|
572
|
+
error(message) {
|
|
573
|
+
return this._getLogFunction(0, message, originalConsole.error, arguments);
|
|
574
|
+
}
|
|
575
|
+
/** Print a deprecation warning */
|
|
576
|
+
deprecated(oldUsage, newUsage) {
|
|
577
|
+
return this.warn(`\`${oldUsage}\` is deprecated and will be removed in a later version. Use \`${newUsage}\` instead`);
|
|
578
|
+
}
|
|
579
|
+
/** Print a removal warning */
|
|
580
|
+
removed(oldUsage, newUsage) {
|
|
581
|
+
return this.error(`\`${oldUsage}\` has been removed. Use \`${newUsage}\` instead`);
|
|
582
|
+
}
|
|
583
|
+
probe(logLevel, message) {
|
|
584
|
+
return this._getLogFunction(logLevel, message, originalConsole.log, arguments, {
|
|
585
|
+
time: true,
|
|
586
|
+
once: true
|
|
587
|
+
});
|
|
588
|
+
}
|
|
589
|
+
log(logLevel, message) {
|
|
590
|
+
return this._getLogFunction(logLevel, message, originalConsole.debug, arguments);
|
|
591
|
+
}
|
|
592
|
+
info(logLevel, message) {
|
|
593
|
+
return this._getLogFunction(logLevel, message, console.info, arguments);
|
|
594
|
+
}
|
|
595
|
+
once(logLevel, message) {
|
|
596
|
+
return this._getLogFunction(logLevel, message, originalConsole.debug || originalConsole.info, arguments, ONCE);
|
|
597
|
+
}
|
|
598
|
+
/** Logs an object as a table */
|
|
599
|
+
table(logLevel, table, columns) {
|
|
600
|
+
if (table) {
|
|
601
|
+
return this._getLogFunction(logLevel, table, console.table || noop, columns && [columns], {
|
|
602
|
+
tag: getTableHeader(table)
|
|
603
|
+
});
|
|
604
|
+
}
|
|
605
|
+
return noop;
|
|
606
|
+
}
|
|
607
|
+
time(logLevel, message) {
|
|
608
|
+
return this._getLogFunction(logLevel, message, console.time ? console.time : console.info);
|
|
609
|
+
}
|
|
610
|
+
timeEnd(logLevel, message) {
|
|
611
|
+
return this._getLogFunction(logLevel, message, console.timeEnd ? console.timeEnd : console.info);
|
|
612
|
+
}
|
|
613
|
+
timeStamp(logLevel, message) {
|
|
614
|
+
return this._getLogFunction(logLevel, message, console.timeStamp || noop);
|
|
615
|
+
}
|
|
616
|
+
group(logLevel, message, opts = { collapsed: false }) {
|
|
617
|
+
const options = normalizeArguments({ logLevel, message, opts });
|
|
618
|
+
const { collapsed } = opts;
|
|
619
|
+
options.method = (collapsed ? console.groupCollapsed : console.group) || console.info;
|
|
620
|
+
return this._getLogFunction(options);
|
|
621
|
+
}
|
|
622
|
+
groupCollapsed(logLevel, message, opts = {}) {
|
|
623
|
+
return this.group(logLevel, message, Object.assign({}, opts, { collapsed: true }));
|
|
624
|
+
}
|
|
625
|
+
groupEnd(logLevel) {
|
|
626
|
+
return this._getLogFunction(logLevel, "", console.groupEnd || noop);
|
|
627
|
+
}
|
|
628
|
+
// EXPERIMENTAL
|
|
629
|
+
withGroup(logLevel, message, func) {
|
|
630
|
+
this.group(logLevel, message)();
|
|
631
|
+
try {
|
|
632
|
+
func();
|
|
633
|
+
} finally {
|
|
634
|
+
this.groupEnd(logLevel)();
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
trace() {
|
|
638
|
+
if (console.trace) {
|
|
639
|
+
console.trace();
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
// PRIVATE METHODS
|
|
643
|
+
/** Deduces log level from a variety of arguments */
|
|
644
|
+
_shouldLog(logLevel) {
|
|
645
|
+
return this.isEnabled() && this.getLevel() >= normalizeLogLevel(logLevel);
|
|
646
|
+
}
|
|
647
|
+
_getLogFunction(logLevel, message, method, args, opts) {
|
|
648
|
+
if (this._shouldLog(logLevel)) {
|
|
649
|
+
opts = normalizeArguments({ logLevel, message, args, opts });
|
|
650
|
+
method = method || opts.method;
|
|
651
|
+
assert(method);
|
|
652
|
+
opts.total = this.getTotal();
|
|
653
|
+
opts.delta = this.getDelta();
|
|
654
|
+
this._deltaTs = getHiResTimestamp2();
|
|
655
|
+
const tag = opts.tag || opts.message;
|
|
656
|
+
if (opts.once && tag) {
|
|
657
|
+
if (!cache[tag]) {
|
|
658
|
+
cache[tag] = getHiResTimestamp2();
|
|
659
|
+
} else {
|
|
660
|
+
return noop;
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
message = decorateMessage(this.id, opts.message, opts);
|
|
664
|
+
return method.bind(console, message, ...opts.args);
|
|
665
|
+
}
|
|
666
|
+
return noop;
|
|
667
|
+
}
|
|
668
|
+
};
|
|
669
|
+
Log.VERSION = VERSION;
|
|
670
|
+
function normalizeLogLevel(logLevel) {
|
|
671
|
+
if (!logLevel) {
|
|
672
|
+
return 0;
|
|
673
|
+
}
|
|
674
|
+
let resolvedLevel;
|
|
675
|
+
switch (typeof logLevel) {
|
|
676
|
+
case "number":
|
|
677
|
+
resolvedLevel = logLevel;
|
|
678
|
+
break;
|
|
679
|
+
case "object":
|
|
680
|
+
resolvedLevel = logLevel.logLevel || logLevel.priority || 0;
|
|
681
|
+
break;
|
|
682
|
+
default:
|
|
683
|
+
return 0;
|
|
684
|
+
}
|
|
685
|
+
assert(Number.isFinite(resolvedLevel) && resolvedLevel >= 0);
|
|
686
|
+
return resolvedLevel;
|
|
687
|
+
}
|
|
688
|
+
function normalizeArguments(opts) {
|
|
689
|
+
const { logLevel, message } = opts;
|
|
690
|
+
opts.logLevel = normalizeLogLevel(logLevel);
|
|
691
|
+
const args = opts.args ? Array.from(opts.args) : [];
|
|
692
|
+
while (args.length && args.shift() !== message) {
|
|
693
|
+
}
|
|
694
|
+
switch (typeof logLevel) {
|
|
695
|
+
case "string":
|
|
696
|
+
case "function":
|
|
697
|
+
if (message !== void 0) {
|
|
698
|
+
args.unshift(message);
|
|
699
|
+
}
|
|
700
|
+
opts.message = logLevel;
|
|
701
|
+
break;
|
|
702
|
+
case "object":
|
|
703
|
+
Object.assign(opts, logLevel);
|
|
704
|
+
break;
|
|
705
|
+
default:
|
|
706
|
+
}
|
|
707
|
+
if (typeof opts.message === "function") {
|
|
708
|
+
opts.message = opts.message();
|
|
709
|
+
}
|
|
710
|
+
const messageType = typeof opts.message;
|
|
711
|
+
assert(messageType === "string" || messageType === "object");
|
|
712
|
+
return Object.assign(opts, { args }, opts.opts);
|
|
713
|
+
}
|
|
714
|
+
function decorateMessage(id, message, opts) {
|
|
715
|
+
if (typeof message === "string") {
|
|
716
|
+
const time = opts.time ? leftPad(formatTime(opts.total)) : "";
|
|
717
|
+
message = opts.time ? `${id}: ${time} ${message}` : `${id}: ${message}`;
|
|
718
|
+
message = addColor(message, opts.color, opts.background);
|
|
719
|
+
}
|
|
720
|
+
return message;
|
|
721
|
+
}
|
|
722
|
+
function getTableHeader(table) {
|
|
723
|
+
for (const key in table) {
|
|
724
|
+
for (const title in table[key]) {
|
|
725
|
+
return title || "untitled";
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
return "empty";
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
// ../../node_modules/@probe.gl/log/dist/init.js
|
|
732
|
+
globalThis.probe = {};
|
|
733
|
+
|
|
734
|
+
// ../../node_modules/@probe.gl/log/dist/index.js
|
|
735
|
+
var dist_default = new Log({ id: "@probe.gl/log" });
|
|
736
|
+
|
|
737
|
+
// ../core/src/utils/log.ts
|
|
738
|
+
var log = new Log({ id: "luma.gl" });
|
|
739
|
+
|
|
740
|
+
// ../core/src/utils/uid.ts
|
|
741
|
+
var uidCounters = {};
|
|
742
|
+
function uid(id = "id") {
|
|
743
|
+
uidCounters[id] = uidCounters[id] || 1;
|
|
744
|
+
const count = uidCounters[id]++;
|
|
745
|
+
return `${id}-${count}`;
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
// ../core/src/adapter/resources/resource.ts
|
|
749
|
+
var Resource = class {
|
|
750
|
+
toString() {
|
|
751
|
+
return `${this[Symbol.toStringTag] || this.constructor.name}:"${this.id}"`;
|
|
752
|
+
}
|
|
753
|
+
/** props.id, for debugging. */
|
|
754
|
+
id;
|
|
755
|
+
props;
|
|
756
|
+
userData = {};
|
|
757
|
+
_device;
|
|
758
|
+
/** Whether this resource has been destroyed */
|
|
759
|
+
destroyed = false;
|
|
760
|
+
/** For resources that allocate GPU memory */
|
|
761
|
+
allocatedBytes = 0;
|
|
762
|
+
/** Attached resources will be destroyed when this resource is destroyed. Tracks auto-created "sub" resources. */
|
|
763
|
+
_attachedResources = /* @__PURE__ */ new Set();
|
|
764
|
+
/**
|
|
765
|
+
* Create a new Resource. Called from Subclass
|
|
766
|
+
*/
|
|
767
|
+
constructor(device, props, defaultProps) {
|
|
768
|
+
if (!device) {
|
|
769
|
+
throw new Error("no device");
|
|
770
|
+
}
|
|
771
|
+
this._device = device;
|
|
772
|
+
this.props = selectivelyMerge(props, defaultProps);
|
|
773
|
+
const id = this.props.id !== "undefined" ? this.props.id : uid(this[Symbol.toStringTag]);
|
|
774
|
+
this.props.id = id;
|
|
775
|
+
this.id = id;
|
|
776
|
+
this.userData = this.props.userData || {};
|
|
777
|
+
this.addStats();
|
|
778
|
+
}
|
|
779
|
+
/**
|
|
780
|
+
* destroy can be called on any resource to release it before it is garbage collected.
|
|
781
|
+
*/
|
|
782
|
+
destroy() {
|
|
783
|
+
this.destroyResource();
|
|
784
|
+
}
|
|
785
|
+
/** @deprecated Use destroy() */
|
|
786
|
+
delete() {
|
|
787
|
+
this.destroy();
|
|
788
|
+
return this;
|
|
789
|
+
}
|
|
790
|
+
/**
|
|
791
|
+
* Combines a map of user props and default props, only including props from defaultProps
|
|
792
|
+
* @returns returns a map of overridden default props
|
|
793
|
+
*/
|
|
794
|
+
getProps() {
|
|
795
|
+
return this.props;
|
|
796
|
+
}
|
|
797
|
+
// ATTACHED RESOURCES
|
|
798
|
+
/**
|
|
799
|
+
* Attaches a resource. Attached resources are auto destroyed when this resource is destroyed
|
|
800
|
+
* Called automatically when sub resources are auto created but can be called by application
|
|
801
|
+
*/
|
|
802
|
+
attachResource(resource) {
|
|
803
|
+
this._attachedResources.add(resource);
|
|
804
|
+
}
|
|
805
|
+
/**
|
|
806
|
+
* Detach an attached resource. The resource will no longer be auto-destroyed when this resource is destroyed.
|
|
807
|
+
*/
|
|
808
|
+
detachResource(resource) {
|
|
809
|
+
this._attachedResources.delete(resource);
|
|
810
|
+
}
|
|
811
|
+
/**
|
|
812
|
+
* Destroys a resource (only if owned), and removes from the owned (auto-destroy) list for this resource.
|
|
813
|
+
*/
|
|
814
|
+
destroyAttachedResource(resource) {
|
|
815
|
+
if (this._attachedResources.delete(resource)) {
|
|
816
|
+
resource.destroy();
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
/** Destroy all owned resources. Make sure the resources are no longer needed before calling. */
|
|
820
|
+
destroyAttachedResources() {
|
|
821
|
+
for (const resource of Object.values(this._attachedResources)) {
|
|
822
|
+
resource.destroy();
|
|
823
|
+
}
|
|
824
|
+
this._attachedResources = /* @__PURE__ */ new Set();
|
|
825
|
+
}
|
|
826
|
+
// PROTECTED METHODS
|
|
827
|
+
/** Perform all destroy steps. Can be called by derived resources when overriding destroy() */
|
|
828
|
+
destroyResource() {
|
|
829
|
+
this.destroyAttachedResources();
|
|
830
|
+
this.removeStats();
|
|
831
|
+
this.destroyed = true;
|
|
832
|
+
}
|
|
833
|
+
/** Called by .destroy() to track object destruction. Subclass must call if overriding destroy() */
|
|
834
|
+
removeStats() {
|
|
835
|
+
const stats = this._device.statsManager.getStats("Resource Counts");
|
|
836
|
+
const name2 = this[Symbol.toStringTag];
|
|
837
|
+
stats.get(`${name2}s Active`).decrementCount();
|
|
838
|
+
}
|
|
839
|
+
/** Called by subclass to track memory allocations */
|
|
840
|
+
trackAllocatedMemory(bytes, name2 = this[Symbol.toStringTag]) {
|
|
841
|
+
const stats = this._device.statsManager.getStats("Resource Counts");
|
|
842
|
+
stats.get("GPU Memory").addCount(bytes);
|
|
843
|
+
stats.get(`${name2} Memory`).addCount(bytes);
|
|
844
|
+
this.allocatedBytes = bytes;
|
|
845
|
+
}
|
|
846
|
+
/** Called by subclass to track memory deallocations */
|
|
847
|
+
trackDeallocatedMemory(name2 = this[Symbol.toStringTag]) {
|
|
848
|
+
const stats = this._device.statsManager.getStats("Resource Counts");
|
|
849
|
+
stats.get("GPU Memory").subtractCount(this.allocatedBytes);
|
|
850
|
+
stats.get(`${name2} Memory`).subtractCount(this.allocatedBytes);
|
|
851
|
+
this.allocatedBytes = 0;
|
|
852
|
+
}
|
|
853
|
+
/** Called by resource constructor to track object creation */
|
|
854
|
+
addStats() {
|
|
855
|
+
const stats = this._device.statsManager.getStats("Resource Counts");
|
|
856
|
+
const name2 = this[Symbol.toStringTag];
|
|
857
|
+
stats.get("Resources Created").incrementCount();
|
|
858
|
+
stats.get(`${name2}s Created`).incrementCount();
|
|
859
|
+
stats.get(`${name2}s Active`).incrementCount();
|
|
860
|
+
}
|
|
861
|
+
};
|
|
862
|
+
/** Default properties for resource */
|
|
863
|
+
__publicField(Resource, "defaultProps", {
|
|
864
|
+
id: "undefined",
|
|
865
|
+
handle: void 0,
|
|
866
|
+
userData: void 0
|
|
867
|
+
});
|
|
868
|
+
function selectivelyMerge(props, defaultProps) {
|
|
869
|
+
const mergedProps = { ...defaultProps };
|
|
870
|
+
for (const key in props) {
|
|
871
|
+
if (props[key] !== void 0) {
|
|
872
|
+
mergedProps[key] = props[key];
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
return mergedProps;
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
// ../core/src/adapter/resources/buffer.ts
|
|
879
|
+
var _Buffer = class extends Resource {
|
|
880
|
+
get [Symbol.toStringTag]() {
|
|
881
|
+
return "Buffer";
|
|
882
|
+
}
|
|
883
|
+
/** The usage with which this buffer was created */
|
|
884
|
+
usage;
|
|
885
|
+
/** For index buffers, whether indices are 16 or 32 bit */
|
|
886
|
+
indexType;
|
|
887
|
+
/** "Time" of last update, can be used to check if redraw is needed */
|
|
888
|
+
updateTimestamp;
|
|
889
|
+
constructor(device, props) {
|
|
890
|
+
const deducedProps = { ...props };
|
|
891
|
+
if ((props.usage || 0) & _Buffer.INDEX && !props.indexType) {
|
|
892
|
+
if (props.data instanceof Uint32Array) {
|
|
893
|
+
deducedProps.indexType = "uint32";
|
|
894
|
+
} else if (props.data instanceof Uint16Array) {
|
|
895
|
+
deducedProps.indexType = "uint16";
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
delete deducedProps.data;
|
|
899
|
+
super(device, deducedProps, _Buffer.defaultProps);
|
|
900
|
+
this.usage = deducedProps.usage || 0;
|
|
901
|
+
this.indexType = deducedProps.indexType;
|
|
902
|
+
this.updateTimestamp = device.incrementTimestamp();
|
|
903
|
+
}
|
|
904
|
+
/**
|
|
905
|
+
* Create a copy of this Buffer with new byteLength, with same props but of the specified size.
|
|
906
|
+
* @note Does not copy contents of the cloned Buffer.
|
|
907
|
+
*/
|
|
908
|
+
clone(props) {
|
|
909
|
+
return this.device.createBuffer({ ...this.props, ...props });
|
|
910
|
+
}
|
|
911
|
+
/** Read data synchronously. @note WebGL2 only */
|
|
912
|
+
readSyncWebGL(byteOffset, byteLength) {
|
|
913
|
+
throw new Error("not implemented");
|
|
914
|
+
}
|
|
915
|
+
/** A partial CPU-side copy of the data in this buffer, for debugging purposes */
|
|
916
|
+
debugData = new ArrayBuffer(0);
|
|
917
|
+
/** This doesn't handle partial non-zero offset updates correctly */
|
|
918
|
+
_setDebugData(data, byteOffset, byteLength) {
|
|
919
|
+
const arrayBuffer2 = ArrayBuffer.isView(data) ? data.buffer : data;
|
|
920
|
+
const debugDataLength = Math.min(
|
|
921
|
+
data ? data.byteLength : byteLength,
|
|
922
|
+
_Buffer.DEBUG_DATA_MAX_LENGTH
|
|
923
|
+
);
|
|
924
|
+
if (arrayBuffer2 === null) {
|
|
925
|
+
this.debugData = new ArrayBuffer(debugDataLength);
|
|
926
|
+
} else if (byteOffset === 0 && byteLength === arrayBuffer2.byteLength) {
|
|
927
|
+
this.debugData = arrayBuffer2.slice(0, debugDataLength);
|
|
928
|
+
} else {
|
|
929
|
+
this.debugData = arrayBuffer2.slice(byteOffset, byteOffset + debugDataLength);
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
};
|
|
933
|
+
var Buffer2 = _Buffer;
|
|
934
|
+
__publicField(Buffer2, "defaultProps", {
|
|
935
|
+
...Resource.defaultProps,
|
|
936
|
+
usage: 0,
|
|
937
|
+
// Buffer.COPY_DST | Buffer.COPY_SRC
|
|
938
|
+
byteLength: 0,
|
|
939
|
+
byteOffset: 0,
|
|
940
|
+
data: null,
|
|
941
|
+
indexType: "uint16",
|
|
942
|
+
mappedAtCreation: false
|
|
943
|
+
});
|
|
944
|
+
// Usage Flags
|
|
945
|
+
__publicField(Buffer2, "MAP_READ", 1);
|
|
946
|
+
__publicField(Buffer2, "MAP_WRITE", 2);
|
|
947
|
+
__publicField(Buffer2, "COPY_SRC", 4);
|
|
948
|
+
__publicField(Buffer2, "COPY_DST", 8);
|
|
949
|
+
/** Index buffer */
|
|
950
|
+
__publicField(Buffer2, "INDEX", 16);
|
|
951
|
+
/** Vertex buffer */
|
|
952
|
+
__publicField(Buffer2, "VERTEX", 32);
|
|
953
|
+
/** Uniform buffer */
|
|
954
|
+
__publicField(Buffer2, "UNIFORM", 64);
|
|
955
|
+
/** Storage buffer */
|
|
956
|
+
__publicField(Buffer2, "STORAGE", 128);
|
|
957
|
+
__publicField(Buffer2, "INDIRECT", 256);
|
|
958
|
+
__publicField(Buffer2, "QUERY_RESOLVE", 512);
|
|
959
|
+
// PROTECTED METHODS (INTENDED FOR USE BY OTHER FRAMEWORK CODE ONLY)
|
|
960
|
+
/** Max amount of debug data saved. Two vec4's */
|
|
961
|
+
__publicField(Buffer2, "DEBUG_DATA_MAX_LENGTH", 32);
|
|
962
|
+
|
|
963
|
+
// ../core/src/gpu-type-utils/decode-data-type.ts
|
|
964
|
+
function decodeVertexType(type) {
|
|
965
|
+
const dataType = TYPE_MAP[type];
|
|
966
|
+
const bytes = getDataTypeBytes(dataType);
|
|
967
|
+
const normalized = type.includes("norm");
|
|
968
|
+
const integer = !normalized && !type.startsWith("float");
|
|
969
|
+
const signed = type.startsWith("s");
|
|
970
|
+
return {
|
|
971
|
+
dataType: TYPE_MAP[type],
|
|
972
|
+
byteLength: bytes,
|
|
973
|
+
integer,
|
|
974
|
+
signed,
|
|
975
|
+
normalized
|
|
976
|
+
};
|
|
977
|
+
}
|
|
978
|
+
function getDataTypeBytes(type) {
|
|
979
|
+
const bytes = TYPE_SIZES[type];
|
|
980
|
+
return bytes;
|
|
981
|
+
}
|
|
982
|
+
var TYPE_MAP = {
|
|
983
|
+
uint8: "uint8",
|
|
984
|
+
sint8: "sint8",
|
|
985
|
+
unorm8: "uint8",
|
|
986
|
+
snorm8: "sint8",
|
|
987
|
+
uint16: "uint16",
|
|
988
|
+
sint16: "sint16",
|
|
989
|
+
unorm16: "uint16",
|
|
990
|
+
snorm16: "sint16",
|
|
991
|
+
float16: "float16",
|
|
992
|
+
float32: "float32",
|
|
993
|
+
uint32: "uint32",
|
|
994
|
+
sint32: "sint32"
|
|
995
|
+
};
|
|
996
|
+
var TYPE_SIZES = {
|
|
997
|
+
uint8: 1,
|
|
998
|
+
sint8: 1,
|
|
999
|
+
uint16: 2,
|
|
1000
|
+
sint16: 2,
|
|
1001
|
+
float16: 2,
|
|
1002
|
+
float32: 4,
|
|
1003
|
+
uint32: 4,
|
|
1004
|
+
sint32: 4
|
|
1005
|
+
};
|
|
1006
|
+
|
|
1007
|
+
// ../core/src/gpu-type-utils/texture-format-table.ts
|
|
1008
|
+
var texture_compression_bc = "texture-compression-bc";
|
|
1009
|
+
var texture_compression_astc = "texture-compression-astc";
|
|
1010
|
+
var texture_compression_etc2 = "texture-compression-etc2";
|
|
1011
|
+
var texture_compression_etc1_webgl = "texture-compression-etc1-webgl";
|
|
1012
|
+
var texture_compression_pvrtc_webgl = "texture-compression-pvrtc-webgl";
|
|
1013
|
+
var texture_compression_atc_webgl = "texture-compression-atc-webgl";
|
|
1014
|
+
var float32_renderable = "float32-renderable-webgl";
|
|
1015
|
+
var float16_renderable = "float16-renderable-webgl";
|
|
1016
|
+
var rgb9e5ufloat_renderable = "rgb9e5ufloat-renderable-webgl";
|
|
1017
|
+
var snorm8_renderable = "snorm8-renderable-webgl";
|
|
1018
|
+
var norm16_renderable = "norm16-renderable-webgl";
|
|
1019
|
+
var snorm16_renderable = "snorm16-renderable-webgl";
|
|
1020
|
+
var float32_filterable = "float32-filterable";
|
|
1021
|
+
var float16_filterable = "float16-filterable-webgl";
|
|
1022
|
+
function getTextureFormatDefinition(format) {
|
|
1023
|
+
const info = TEXTURE_FORMAT_TABLE[format];
|
|
1024
|
+
if (!info) {
|
|
1025
|
+
throw new Error(`Unsupported texture format ${format}`);
|
|
1026
|
+
}
|
|
1027
|
+
return info;
|
|
1028
|
+
}
|
|
1029
|
+
function getTextureFormatTable() {
|
|
1030
|
+
return TEXTURE_FORMAT_TABLE;
|
|
1031
|
+
}
|
|
1032
|
+
var TEXTURE_FORMAT_TABLE = {
|
|
1033
|
+
// 8-bit formats
|
|
1034
|
+
"r8unorm": {},
|
|
1035
|
+
"r8snorm": { render: snorm8_renderable },
|
|
1036
|
+
"r8uint": {},
|
|
1037
|
+
"r8sint": {},
|
|
1038
|
+
// 16-bit formats
|
|
1039
|
+
"rg8unorm": {},
|
|
1040
|
+
"rg8snorm": { render: snorm8_renderable },
|
|
1041
|
+
"rg8uint": {},
|
|
1042
|
+
"rg8sint": {},
|
|
1043
|
+
"r16uint": {},
|
|
1044
|
+
"r16sint": {},
|
|
1045
|
+
"r16float": { render: float16_renderable, filter: "float16-filterable-webgl" },
|
|
1046
|
+
"r16unorm-webgl": { f: norm16_renderable },
|
|
1047
|
+
"r16snorm-webgl": { f: snorm16_renderable },
|
|
1048
|
+
// Packed 16-bit formats
|
|
1049
|
+
"rgba4unorm-webgl": { channels: "rgba", bitsPerChannel: [4, 4, 4, 4], packed: true },
|
|
1050
|
+
"rgb565unorm-webgl": { channels: "rgb", bitsPerChannel: [5, 6, 5, 0], packed: true },
|
|
1051
|
+
"rgb5a1unorm-webgl": { channels: "rgba", bitsPerChannel: [5, 5, 5, 1], packed: true },
|
|
1052
|
+
// 24-bit formats
|
|
1053
|
+
"rgb8unorm-webgl": {},
|
|
1054
|
+
"rgb8snorm-webgl": {},
|
|
1055
|
+
// 32-bit formats
|
|
1056
|
+
"rgba8unorm": {},
|
|
1057
|
+
"rgba8unorm-srgb": {},
|
|
1058
|
+
"rgba8snorm": { render: snorm8_renderable },
|
|
1059
|
+
"rgba8uint": {},
|
|
1060
|
+
"rgba8sint": {},
|
|
1061
|
+
// 32-bit, reverse colors, webgpu only
|
|
1062
|
+
"bgra8unorm": {},
|
|
1063
|
+
"bgra8unorm-srgb": {},
|
|
1064
|
+
"rg16uint": {},
|
|
1065
|
+
"rg16sint": {},
|
|
1066
|
+
"rg16float": { render: float16_renderable, filter: float16_filterable },
|
|
1067
|
+
"rg16unorm-webgl": { render: norm16_renderable },
|
|
1068
|
+
"rg16snorm-webgl": { render: snorm16_renderable },
|
|
1069
|
+
"r32uint": {},
|
|
1070
|
+
"r32sint": {},
|
|
1071
|
+
"r32float": { render: float32_renderable, filter: float32_filterable },
|
|
1072
|
+
// Packed 32 bit formats
|
|
1073
|
+
"rgb9e5ufloat": { channels: "rgb", packed: true, render: rgb9e5ufloat_renderable },
|
|
1074
|
+
// , filter: true},
|
|
1075
|
+
"rg11b10ufloat": { channels: "rgb", bitsPerChannel: [11, 11, 10, 0], packed: true, p: 1, render: float32_renderable },
|
|
1076
|
+
"rgb10a2unorm": { channels: "rgba", bitsPerChannel: [10, 10, 10, 2], packed: true, p: 1 },
|
|
1077
|
+
"rgb10a2uint": { channels: "rgba", bitsPerChannel: [10, 10, 10, 2], packed: true, p: 1 },
|
|
1078
|
+
// 48-bit formats
|
|
1079
|
+
"rgb16unorm-webgl": { f: norm16_renderable },
|
|
1080
|
+
// rgb not renderable
|
|
1081
|
+
"rgb16snorm-webgl": { f: norm16_renderable },
|
|
1082
|
+
// rgb not renderable
|
|
1083
|
+
// 64-bit formats
|
|
1084
|
+
"rg32uint": {},
|
|
1085
|
+
"rg32sint": {},
|
|
1086
|
+
"rg32float": { render: false, filter: float32_filterable },
|
|
1087
|
+
"rgba16uint": {},
|
|
1088
|
+
"rgba16sint": {},
|
|
1089
|
+
"rgba16float": { render: float16_renderable, filter: float16_filterable },
|
|
1090
|
+
"rgba16unorm-webgl": { render: norm16_renderable },
|
|
1091
|
+
"rgba16snorm-webgl": { render: snorm16_renderable },
|
|
1092
|
+
// 96-bit formats (deprecated!)
|
|
1093
|
+
"rgb32float-webgl": { render: float32_renderable, filter: float32_filterable },
|
|
1094
|
+
// 128-bit formats
|
|
1095
|
+
"rgba32uint": {},
|
|
1096
|
+
"rgba32sint": {},
|
|
1097
|
+
"rgba32float": { render: float32_renderable, filter: float32_filterable },
|
|
1098
|
+
// Depth/stencil
|
|
1099
|
+
// Depth and stencil formats
|
|
1100
|
+
stencil8: { attachment: "stencil", bitsPerChannel: [8, 0, 0, 0], dataType: "uint8" },
|
|
1101
|
+
"depth16unorm": { attachment: "depth", bitsPerChannel: [16, 0, 0, 0], dataType: "uint16" },
|
|
1102
|
+
"depth24plus": { attachment: "depth", bitsPerChannel: [24, 0, 0, 0], dataType: "uint32" },
|
|
1103
|
+
"depth32float": { attachment: "depth", bitsPerChannel: [32, 0, 0, 0], dataType: "float32" },
|
|
1104
|
+
// The depth component of the "depth24plus" and "depth24plus-stencil8" formats may be implemented as either a 24-bit depth value or a "depth32float" value.
|
|
1105
|
+
"depth24plus-stencil8": { attachment: "depth-stencil", bitsPerChannel: [24, 8, 0, 0], packed: true },
|
|
1106
|
+
// "depth32float-stencil8" feature
|
|
1107
|
+
"depth32float-stencil8": { attachment: "depth-stencil", bitsPerChannel: [32, 8, 0, 0], packed: true },
|
|
1108
|
+
// BC compressed formats: check device.features.has("texture-compression-bc");
|
|
1109
|
+
"bc1-rgb-unorm-webgl": { f: texture_compression_bc },
|
|
1110
|
+
"bc1-rgb-unorm-srgb-webgl": { f: texture_compression_bc },
|
|
1111
|
+
"bc1-rgba-unorm": { f: texture_compression_bc },
|
|
1112
|
+
"bc1-rgba-unorm-srgb": { f: texture_compression_bc },
|
|
1113
|
+
"bc2-rgba-unorm": { f: texture_compression_bc },
|
|
1114
|
+
"bc2-rgba-unorm-srgb": { f: texture_compression_bc },
|
|
1115
|
+
"bc3-rgba-unorm": { f: texture_compression_bc },
|
|
1116
|
+
"bc3-rgba-unorm-srgb": { f: texture_compression_bc },
|
|
1117
|
+
"bc4-r-unorm": { f: texture_compression_bc },
|
|
1118
|
+
"bc4-r-snorm": { f: texture_compression_bc },
|
|
1119
|
+
"bc5-rg-unorm": { f: texture_compression_bc },
|
|
1120
|
+
"bc5-rg-snorm": { f: texture_compression_bc },
|
|
1121
|
+
"bc6h-rgb-ufloat": { f: texture_compression_bc },
|
|
1122
|
+
"bc6h-rgb-float": { f: texture_compression_bc },
|
|
1123
|
+
"bc7-rgba-unorm": { f: texture_compression_bc },
|
|
1124
|
+
"bc7-rgba-unorm-srgb": { f: texture_compression_bc },
|
|
1125
|
+
// WEBGL_compressed_texture_etc: device.features.has("texture-compression-etc2")
|
|
1126
|
+
// Note: Supposedly guaranteed availability compressed formats in WebGL2, but through CPU decompression
|
|
1127
|
+
"etc2-rgb8unorm": { f: texture_compression_etc2 },
|
|
1128
|
+
"etc2-rgb8unorm-srgb": { f: texture_compression_etc2 },
|
|
1129
|
+
"etc2-rgb8a1unorm": { f: texture_compression_etc2 },
|
|
1130
|
+
"etc2-rgb8a1unorm-srgb": { f: texture_compression_etc2 },
|
|
1131
|
+
"etc2-rgba8unorm": { f: texture_compression_etc2 },
|
|
1132
|
+
"etc2-rgba8unorm-srgb": { f: texture_compression_etc2 },
|
|
1133
|
+
"eac-r11unorm": { f: texture_compression_etc2 },
|
|
1134
|
+
"eac-r11snorm": { f: texture_compression_etc2 },
|
|
1135
|
+
"eac-rg11unorm": { f: texture_compression_etc2 },
|
|
1136
|
+
"eac-rg11snorm": { f: texture_compression_etc2 },
|
|
1137
|
+
// X_ASTC compressed formats: device.features.has("texture-compression-astc")
|
|
1138
|
+
"astc-4x4-unorm": { f: texture_compression_astc },
|
|
1139
|
+
"astc-4x4-unorm-srgb": { f: texture_compression_astc },
|
|
1140
|
+
"astc-5x4-unorm": { f: texture_compression_astc },
|
|
1141
|
+
"astc-5x4-unorm-srgb": { f: texture_compression_astc },
|
|
1142
|
+
"astc-5x5-unorm": { f: texture_compression_astc },
|
|
1143
|
+
"astc-5x5-unorm-srgb": { f: texture_compression_astc },
|
|
1144
|
+
"astc-6x5-unorm": { f: texture_compression_astc },
|
|
1145
|
+
"astc-6x5-unorm-srgb": { f: texture_compression_astc },
|
|
1146
|
+
"astc-6x6-unorm": { f: texture_compression_astc },
|
|
1147
|
+
"astc-6x6-unorm-srgb": { f: texture_compression_astc },
|
|
1148
|
+
"astc-8x5-unorm": { f: texture_compression_astc },
|
|
1149
|
+
"astc-8x5-unorm-srgb": { f: texture_compression_astc },
|
|
1150
|
+
"astc-8x6-unorm": { f: texture_compression_astc },
|
|
1151
|
+
"astc-8x6-unorm-srgb": { f: texture_compression_astc },
|
|
1152
|
+
"astc-8x8-unorm": { f: texture_compression_astc },
|
|
1153
|
+
"astc-8x8-unorm-srgb": { f: texture_compression_astc },
|
|
1154
|
+
"astc-10x5-unorm": { f: texture_compression_astc },
|
|
1155
|
+
"astc-10x5-unorm-srgb": { f: texture_compression_astc },
|
|
1156
|
+
"astc-10x6-unorm": { f: texture_compression_astc },
|
|
1157
|
+
"astc-10x6-unorm-srgb": { f: texture_compression_astc },
|
|
1158
|
+
"astc-10x8-unorm": { f: texture_compression_astc },
|
|
1159
|
+
"astc-10x8-unorm-srgb": { f: texture_compression_astc },
|
|
1160
|
+
"astc-10x10-unorm": { f: texture_compression_astc },
|
|
1161
|
+
"astc-10x10-unorm-srgb": { f: texture_compression_astc },
|
|
1162
|
+
"astc-12x10-unorm": { f: texture_compression_astc },
|
|
1163
|
+
"astc-12x10-unorm-srgb": { f: texture_compression_astc },
|
|
1164
|
+
"astc-12x12-unorm": { f: texture_compression_astc },
|
|
1165
|
+
"astc-12x12-unorm-srgb": { f: texture_compression_astc },
|
|
1166
|
+
// WEBGL_compressed_texture_pvrtc
|
|
1167
|
+
"pvrtc-rgb4unorm-webgl": { f: texture_compression_pvrtc_webgl },
|
|
1168
|
+
"pvrtc-rgba4unorm-webgl": { f: texture_compression_pvrtc_webgl },
|
|
1169
|
+
"pvrtc-rbg2unorm-webgl": { f: texture_compression_pvrtc_webgl },
|
|
1170
|
+
"pvrtc-rgba2unorm-webgl": { f: texture_compression_pvrtc_webgl },
|
|
1171
|
+
// WEBGL_compressed_texture_etc1
|
|
1172
|
+
"etc1-rbg-unorm-webgl": { f: texture_compression_etc1_webgl },
|
|
1173
|
+
// WEBGL_compressed_texture_atc
|
|
1174
|
+
"atc-rgb-unorm-webgl": { f: texture_compression_atc_webgl },
|
|
1175
|
+
"atc-rgba-unorm-webgl": { f: texture_compression_atc_webgl },
|
|
1176
|
+
"atc-rgbai-unorm-webgl": { f: texture_compression_atc_webgl }
|
|
1177
|
+
};
|
|
1178
|
+
|
|
1179
|
+
// ../core/src/gpu-type-utils/decode-texture-format.ts
|
|
1180
|
+
var COMPRESSED_TEXTURE_FORMAT_PREFIXES = [
|
|
1181
|
+
"bc1",
|
|
1182
|
+
"bc2",
|
|
1183
|
+
"bc3",
|
|
1184
|
+
"bc4",
|
|
1185
|
+
"bc5",
|
|
1186
|
+
"bc6",
|
|
1187
|
+
"bc7",
|
|
1188
|
+
"etc1",
|
|
1189
|
+
"etc2",
|
|
1190
|
+
"eac",
|
|
1191
|
+
"atc",
|
|
1192
|
+
"astc",
|
|
1193
|
+
"pvrtc"
|
|
1194
|
+
];
|
|
1195
|
+
var RGB_FORMAT_REGEX = /^(r|rg|rgb|rgba|bgra)([0-9]*)([a-z]*)(-srgb)?(-webgl)?$/;
|
|
1196
|
+
function isTextureFormatCompressed(format) {
|
|
1197
|
+
return COMPRESSED_TEXTURE_FORMAT_PREFIXES.some((prefix) => format.startsWith(prefix));
|
|
1198
|
+
}
|
|
1199
|
+
function decodeTextureFormat(format) {
|
|
1200
|
+
let formatInfo = decodeTextureFormatUsingTable(format);
|
|
1201
|
+
if (isTextureFormatCompressed(format)) {
|
|
1202
|
+
formatInfo.channels = "rgb";
|
|
1203
|
+
formatInfo.components = 3;
|
|
1204
|
+
formatInfo.bytesPerPixel = 1;
|
|
1205
|
+
formatInfo.srgb = false;
|
|
1206
|
+
formatInfo.compressed = true;
|
|
1207
|
+
const blockSize = getCompressedTextureBlockSize(format);
|
|
1208
|
+
if (blockSize) {
|
|
1209
|
+
formatInfo.blockWidth = blockSize.blockWidth;
|
|
1210
|
+
formatInfo.blockHeight = blockSize.blockHeight;
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
const matches = RGB_FORMAT_REGEX.exec(format);
|
|
1214
|
+
if (matches) {
|
|
1215
|
+
const [, channels, length, type, srgb, suffix] = matches;
|
|
1216
|
+
const dataType = `${type}${length}`;
|
|
1217
|
+
const decodedType = decodeVertexType(dataType);
|
|
1218
|
+
const bits = decodedType.byteLength * 8;
|
|
1219
|
+
const components = channels.length;
|
|
1220
|
+
const bitsPerChannel = [
|
|
1221
|
+
bits,
|
|
1222
|
+
components >= 2 ? bits : 0,
|
|
1223
|
+
components >= 3 ? bits : 0,
|
|
1224
|
+
components >= 4 ? bits : 0
|
|
1225
|
+
];
|
|
1226
|
+
formatInfo = {
|
|
1227
|
+
format,
|
|
1228
|
+
attachment: formatInfo.attachment,
|
|
1229
|
+
dataType: decodedType.dataType,
|
|
1230
|
+
components,
|
|
1231
|
+
channels,
|
|
1232
|
+
integer: decodedType.integer,
|
|
1233
|
+
signed: decodedType.signed,
|
|
1234
|
+
normalized: decodedType.normalized,
|
|
1235
|
+
bitsPerChannel,
|
|
1236
|
+
bytesPerPixel: decodedType.byteLength * channels.length,
|
|
1237
|
+
packed: formatInfo.packed,
|
|
1238
|
+
srgb: formatInfo.srgb
|
|
1239
|
+
};
|
|
1240
|
+
if (suffix === "-webgl") {
|
|
1241
|
+
formatInfo.webgl = true;
|
|
1242
|
+
}
|
|
1243
|
+
if (srgb === "-srgb") {
|
|
1244
|
+
formatInfo.srgb = true;
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
if (format.endsWith("-webgl")) {
|
|
1248
|
+
formatInfo.webgl = true;
|
|
1249
|
+
}
|
|
1250
|
+
if (format.endsWith("-srgb")) {
|
|
1251
|
+
formatInfo.srgb = true;
|
|
1252
|
+
}
|
|
1253
|
+
return formatInfo;
|
|
1254
|
+
}
|
|
1255
|
+
function decodeTextureFormatUsingTable(format) {
|
|
1256
|
+
const info = getTextureFormatDefinition(format);
|
|
1257
|
+
const bytesPerPixel = info.bytesPerPixel || 1;
|
|
1258
|
+
const bitsPerChannel = info.bitsPerChannel || [8, 8, 8, 8];
|
|
1259
|
+
delete info.bitsPerChannel;
|
|
1260
|
+
delete info.bytesPerPixel;
|
|
1261
|
+
delete info.f;
|
|
1262
|
+
delete info.render;
|
|
1263
|
+
delete info.filter;
|
|
1264
|
+
delete info.blend;
|
|
1265
|
+
delete info.store;
|
|
1266
|
+
const formatInfo = {
|
|
1267
|
+
...info,
|
|
1268
|
+
format,
|
|
1269
|
+
attachment: info.attachment || "color",
|
|
1270
|
+
channels: info.channels || "r",
|
|
1271
|
+
components: info.components || info.channels?.length || 1,
|
|
1272
|
+
bytesPerPixel,
|
|
1273
|
+
bitsPerChannel,
|
|
1274
|
+
dataType: info.dataType || "uint8",
|
|
1275
|
+
srgb: info.srgb ?? false,
|
|
1276
|
+
packed: info.packed ?? false,
|
|
1277
|
+
webgl: info.webgl ?? false,
|
|
1278
|
+
integer: info.integer ?? false,
|
|
1279
|
+
signed: info.signed ?? false,
|
|
1280
|
+
normalized: info.normalized ?? false,
|
|
1281
|
+
compressed: info.compressed ?? false
|
|
1282
|
+
};
|
|
1283
|
+
return formatInfo;
|
|
1284
|
+
}
|
|
1285
|
+
function getCompressedTextureBlockSize(format) {
|
|
1286
|
+
const REGEX = /.*-(\d+)x(\d+)-.*/;
|
|
1287
|
+
const matches = REGEX.exec(format);
|
|
1288
|
+
if (matches) {
|
|
1289
|
+
const [, blockWidth, blockHeight] = matches;
|
|
1290
|
+
return { blockWidth: Number(blockWidth), blockHeight: Number(blockHeight) };
|
|
1291
|
+
}
|
|
1292
|
+
return null;
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1295
|
+
// ../core/src/gpu-type-utils/texture-format-capabilities.ts
|
|
1296
|
+
function getTextureFormatCapabilities(format) {
|
|
1297
|
+
const info = getTextureFormatDefinition(format);
|
|
1298
|
+
const formatCapabilities = {
|
|
1299
|
+
format,
|
|
1300
|
+
create: info.f ?? true,
|
|
1301
|
+
render: info.render ?? true,
|
|
1302
|
+
filter: info.filter ?? true,
|
|
1303
|
+
blend: info.blend ?? true,
|
|
1304
|
+
store: info.store ?? true
|
|
1305
|
+
};
|
|
1306
|
+
const formatInfo = decodeTextureFormat(format);
|
|
1307
|
+
const isDepthStencil = format.startsWith("depth") || format.startsWith("stencil");
|
|
1308
|
+
const isSigned = formatInfo?.signed;
|
|
1309
|
+
const isInteger = formatInfo?.integer;
|
|
1310
|
+
const isWebGLSpecific = formatInfo?.webgl;
|
|
1311
|
+
formatCapabilities.render &&= !isSigned;
|
|
1312
|
+
formatCapabilities.filter &&= !isDepthStencil && !isSigned && !isInteger && !isWebGLSpecific;
|
|
1313
|
+
return formatCapabilities;
|
|
1314
|
+
}
|
|
1315
|
+
|
|
1316
|
+
// ../core/src/adapter/device.ts
|
|
1317
|
+
var DeviceLimits = class {
|
|
1318
|
+
};
|
|
1319
|
+
var DeviceFeatures = class {
|
|
1320
|
+
features;
|
|
1321
|
+
disabledFeatures;
|
|
1322
|
+
constructor(features = [], disabledFeatures) {
|
|
1323
|
+
this.features = new Set(features);
|
|
1324
|
+
this.disabledFeatures = disabledFeatures || {};
|
|
1325
|
+
}
|
|
1326
|
+
*[Symbol.iterator]() {
|
|
1327
|
+
yield* this.features;
|
|
1328
|
+
}
|
|
1329
|
+
has(feature) {
|
|
1330
|
+
return !this.disabledFeatures?.[feature] && this.features.has(feature);
|
|
1331
|
+
}
|
|
1332
|
+
};
|
|
1333
|
+
var _Device = class {
|
|
1334
|
+
get [Symbol.toStringTag]() {
|
|
1335
|
+
return "Device";
|
|
1336
|
+
}
|
|
1337
|
+
constructor(props) {
|
|
1338
|
+
this.props = { ..._Device.defaultProps, ...props };
|
|
1339
|
+
this.id = this.props.id || uid(this[Symbol.toStringTag].toLowerCase());
|
|
1340
|
+
}
|
|
1341
|
+
/** id of this device, primarily for debugging */
|
|
1342
|
+
id;
|
|
1343
|
+
/** A copy of the device props */
|
|
1344
|
+
props;
|
|
1345
|
+
/** Available for the application to store data on the device */
|
|
1346
|
+
userData = {};
|
|
1347
|
+
/** stats */
|
|
1348
|
+
statsManager = lumaStats;
|
|
1349
|
+
/** An abstract timestamp used for change tracking */
|
|
1350
|
+
timestamp = 0;
|
|
1351
|
+
/** Used by other luma.gl modules to store data on the device */
|
|
1352
|
+
_lumaData = {};
|
|
1353
|
+
/** Determines what operations are supported on a texture format, checking against supported device features */
|
|
1354
|
+
getTextureFormatCapabilities(format) {
|
|
1355
|
+
const genericCapabilities = getTextureFormatCapabilities(format);
|
|
1356
|
+
const checkFeature = (featureOrBoolean) => (typeof featureOrBoolean === "string" ? this.features.has(featureOrBoolean) : featureOrBoolean) ?? true;
|
|
1357
|
+
const supported = checkFeature(genericCapabilities.create);
|
|
1358
|
+
const deviceCapabilities = {
|
|
1359
|
+
format,
|
|
1360
|
+
create: supported,
|
|
1361
|
+
render: supported && checkFeature(genericCapabilities.render),
|
|
1362
|
+
filter: supported && checkFeature(genericCapabilities.filter),
|
|
1363
|
+
blend: supported && checkFeature(genericCapabilities.blend),
|
|
1364
|
+
store: supported && checkFeature(genericCapabilities.store)
|
|
1365
|
+
};
|
|
1366
|
+
return this._getDeviceSpecificTextureFormatCapabilities(deviceCapabilities);
|
|
1367
|
+
}
|
|
1368
|
+
/** Check if device supports a specific texture format (creation and `nearest` sampling) */
|
|
1369
|
+
isTextureFormatSupported(format, capabilities) {
|
|
1370
|
+
return this.getTextureFormatCapabilities(format).create;
|
|
1371
|
+
}
|
|
1372
|
+
/** Check if linear filtering (sampler interpolation) is supported for a specific texture format */
|
|
1373
|
+
isTextureFormatFilterable(format) {
|
|
1374
|
+
return this.getTextureFormatCapabilities(format).filter;
|
|
1375
|
+
}
|
|
1376
|
+
/** Check if device supports rendering to a framebuffer color attachment of a specific texture format */
|
|
1377
|
+
isTextureFormatRenderable(format) {
|
|
1378
|
+
return this.getTextureFormatCapabilities(format).render;
|
|
1379
|
+
}
|
|
1380
|
+
/** Check if a specific texture format is GPU compressed */
|
|
1381
|
+
isTextureFormatCompressed(format) {
|
|
1382
|
+
return isTextureFormatCompressed(format);
|
|
1383
|
+
}
|
|
1384
|
+
/**
|
|
1385
|
+
* Trigger device loss.
|
|
1386
|
+
* @returns `true` if context loss could actually be triggered.
|
|
1387
|
+
* @note primarily intended for testing how application reacts to device loss
|
|
1388
|
+
*/
|
|
1389
|
+
loseDevice() {
|
|
1390
|
+
return false;
|
|
1391
|
+
}
|
|
1392
|
+
/** Report error (normally called for unhandled device errors) */
|
|
1393
|
+
reportError(error) {
|
|
1394
|
+
this.props.onError(error);
|
|
1395
|
+
}
|
|
1396
|
+
/** Returns the default / primary canvas context. Throws an error if no canvas context is available (a WebGPU compute device) */
|
|
1397
|
+
getDefaultCanvasContext() {
|
|
1398
|
+
if (!this.canvasContext) {
|
|
1399
|
+
throw new Error("Device has no default CanvasContext. See props.createCanvasContext");
|
|
1400
|
+
}
|
|
1401
|
+
return this.canvasContext;
|
|
1402
|
+
}
|
|
1403
|
+
createCommandEncoder(props = {}) {
|
|
1404
|
+
throw new Error("not implemented");
|
|
1405
|
+
}
|
|
1406
|
+
/** A monotonic counter for tracking buffer and texture updates */
|
|
1407
|
+
incrementTimestamp() {
|
|
1408
|
+
return this.timestamp++;
|
|
1409
|
+
}
|
|
1410
|
+
// Error Handling
|
|
1411
|
+
/** Report unhandled device errors */
|
|
1412
|
+
onError(error) {
|
|
1413
|
+
this.props.onError(error);
|
|
1414
|
+
}
|
|
1415
|
+
// DEPRECATED METHODS
|
|
1416
|
+
/** @deprecated Use getDefaultCanvasContext() */
|
|
1417
|
+
getCanvasContext() {
|
|
1418
|
+
return this.getDefaultCanvasContext();
|
|
1419
|
+
}
|
|
1420
|
+
// WebGL specific HACKS - enables app to remove webgl import
|
|
1421
|
+
// Use until we have a better way to handle these
|
|
1422
|
+
/** @deprecated - will be removed - should use command encoder */
|
|
1423
|
+
readPixelsToArrayWebGL(source, options) {
|
|
1424
|
+
throw new Error("not implemented");
|
|
1425
|
+
}
|
|
1426
|
+
/** @deprecated - will be removed - should use command encoder */
|
|
1427
|
+
readPixelsToBufferWebGL(source, options) {
|
|
1428
|
+
throw new Error("not implemented");
|
|
1429
|
+
}
|
|
1430
|
+
/** @deprecated - will be removed - should use WebGPU parameters (pipeline) */
|
|
1431
|
+
setParametersWebGL(parameters) {
|
|
1432
|
+
throw new Error("not implemented");
|
|
1433
|
+
}
|
|
1434
|
+
/** @deprecated - will be removed - should use WebGPU parameters (pipeline) */
|
|
1435
|
+
getParametersWebGL(parameters) {
|
|
1436
|
+
throw new Error("not implemented");
|
|
1437
|
+
}
|
|
1438
|
+
/** @deprecated - will be removed - should use WebGPU parameters (pipeline) */
|
|
1439
|
+
withParametersWebGL(parameters, func) {
|
|
1440
|
+
throw new Error("not implemented");
|
|
1441
|
+
}
|
|
1442
|
+
/** @deprecated - will be removed - should use clear arguments in RenderPass */
|
|
1443
|
+
clearWebGL(options) {
|
|
1444
|
+
throw new Error("not implemented");
|
|
1445
|
+
}
|
|
1446
|
+
/** @deprecated - will be removed - should use for debugging only */
|
|
1447
|
+
resetWebGL() {
|
|
1448
|
+
throw new Error("not implemented");
|
|
1449
|
+
}
|
|
1450
|
+
/** Subclasses use this to support .createBuffer() overloads */
|
|
1451
|
+
_normalizeBufferProps(props) {
|
|
1452
|
+
if (props instanceof ArrayBuffer || ArrayBuffer.isView(props)) {
|
|
1453
|
+
props = { data: props };
|
|
1454
|
+
}
|
|
1455
|
+
const newProps = { ...props };
|
|
1456
|
+
if ((props.usage || 0) & Buffer2.INDEX && !props.indexType) {
|
|
1457
|
+
if (props.data instanceof Uint32Array) {
|
|
1458
|
+
newProps.indexType = "uint32";
|
|
1459
|
+
} else if (props.data instanceof Uint16Array) {
|
|
1460
|
+
newProps.indexType = "uint16";
|
|
1461
|
+
} else {
|
|
1462
|
+
log.warn("indices buffer content must be of type uint16 or uint32")();
|
|
1463
|
+
}
|
|
1464
|
+
}
|
|
1465
|
+
return newProps;
|
|
1466
|
+
}
|
|
1467
|
+
};
|
|
1468
|
+
var Device = _Device;
|
|
1469
|
+
__publicField(Device, "defaultProps", {
|
|
1470
|
+
id: null,
|
|
1471
|
+
powerPreference: "high-performance",
|
|
1472
|
+
failIfMajorPerformanceCaveat: false,
|
|
1473
|
+
createCanvasContext: void 0,
|
|
1474
|
+
// WebGL specific
|
|
1475
|
+
webgl: {},
|
|
1476
|
+
// Callbacks
|
|
1477
|
+
onError: (error) => log.error(error.message)(),
|
|
1478
|
+
onResize: (context, info) => {
|
|
1479
|
+
const [width, height] = context.getPixelSize();
|
|
1480
|
+
const [prevWidth, prevHeight] = info.oldPixelSize;
|
|
1481
|
+
log.log(1, `${context} Resized ${prevWidth}x${prevHeight} => ${width}x${height}px`)();
|
|
1482
|
+
},
|
|
1483
|
+
onVisibilityChange: (context) => log.log(1, `${context} Visibility changed ${context.isVisible}`)(),
|
|
1484
|
+
onDevicePixelRatioChange: (context, info) => log.log(1, `${context} DPR changed ${info.oldRatio} => ${context.devicePixelRatio}`)(),
|
|
1485
|
+
// Debug flags
|
|
1486
|
+
debug: log.get("debug") || void 0,
|
|
1487
|
+
debugShaders: log.get("debug-shaders") || void 0,
|
|
1488
|
+
debugFramebuffers: Boolean(log.get("debug-framebuffers")),
|
|
1489
|
+
debugFactories: Boolean(log.get("debug-factories")),
|
|
1490
|
+
debugWebGL: Boolean(log.get("debug-webgl")),
|
|
1491
|
+
debugSpectorJS: void 0,
|
|
1492
|
+
// Note: log setting is queried by the spector.js code
|
|
1493
|
+
debugSpectorJSUrl: void 0,
|
|
1494
|
+
// Experimental
|
|
1495
|
+
_requestMaxLimits: true,
|
|
1496
|
+
_cacheShaders: false,
|
|
1497
|
+
_cachePipelines: false,
|
|
1498
|
+
_cacheDestroyPolicy: "unused",
|
|
1499
|
+
// TODO - Change these after confirming things work as expected
|
|
1500
|
+
_initializeFeatures: true,
|
|
1501
|
+
_disabledFeatures: {
|
|
1502
|
+
"compilation-status-async-webgl": true
|
|
1503
|
+
},
|
|
1504
|
+
_resourceDefaults: {},
|
|
1505
|
+
// INTERNAL
|
|
1506
|
+
_handle: void 0
|
|
1507
|
+
});
|
|
1508
|
+
|
|
1509
|
+
// ../core/src/adapter/luma.ts
|
|
1510
|
+
var isPage = isBrowser() && typeof document !== "undefined";
|
|
1511
|
+
var isPageLoaded = () => isPage && document.readyState === "complete";
|
|
1512
|
+
var STARTUP_MESSAGE = "set luma.log.level=1 (or higher) to trace rendering";
|
|
1513
|
+
var ERROR_MESSAGE = "No matching device found. Ensure `@luma.gl/webgl` and/or `@luma.gl/webgpu` modules are imported.";
|
|
1514
|
+
var _Luma = class {
|
|
1515
|
+
/** Global stats for all devices */
|
|
1516
|
+
stats = lumaStats;
|
|
1517
|
+
/**
|
|
1518
|
+
* Global log
|
|
1519
|
+
*
|
|
1520
|
+
* Assign luma.log.level in console to control logging: \
|
|
1521
|
+
* 0: none, 1: minimal, 2: verbose, 3: attribute/uniforms, 4: gl logs
|
|
1522
|
+
* luma.log.break[], set to gl funcs, luma.log.profile[] set to model names`;
|
|
1523
|
+
*/
|
|
1524
|
+
log = log;
|
|
1525
|
+
/** Version of luma.gl */
|
|
1526
|
+
VERSION = (
|
|
1527
|
+
// Version detection using build plugin
|
|
1528
|
+
// @ts-expect-error no-undef
|
|
1529
|
+
typeof __VERSION__ !== "undefined" ? __VERSION__ : "running from source"
|
|
1530
|
+
);
|
|
1531
|
+
spector;
|
|
1532
|
+
preregisteredAdapters = /* @__PURE__ */ new Map();
|
|
1533
|
+
constructor() {
|
|
1534
|
+
if (globalThis.luma) {
|
|
1535
|
+
if (globalThis.luma.VERSION !== this.VERSION) {
|
|
1536
|
+
log.error(`Found luma.gl ${globalThis.luma.VERSION} while initialzing ${this.VERSION}`)();
|
|
1537
|
+
log.error(`'yarn why @luma.gl/core' can help identify the source of the conflict`)();
|
|
1538
|
+
throw new Error(`luma.gl - multiple versions detected: see console log`);
|
|
1539
|
+
}
|
|
1540
|
+
log.error("This version of luma.gl has already been initialized")();
|
|
1541
|
+
}
|
|
1542
|
+
log.log(1, `${this.VERSION} - ${STARTUP_MESSAGE}`)();
|
|
1543
|
+
globalThis.luma = this;
|
|
1544
|
+
}
|
|
1545
|
+
registerAdapters(adapters) {
|
|
1546
|
+
for (const deviceClass of adapters) {
|
|
1547
|
+
this.preregisteredAdapters.set(deviceClass.type, deviceClass);
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
/** Get type strings for supported Devices */
|
|
1551
|
+
getSupportedAdapters(adapters = []) {
|
|
1552
|
+
const adapterMap = this.getAdapterMap(adapters);
|
|
1553
|
+
return Array.from(adapterMap).map(([, adapter]) => adapter).filter((adapter) => adapter.isSupported?.()).map((adapter) => adapter.type);
|
|
1554
|
+
}
|
|
1555
|
+
/** Get type strings for best available Device */
|
|
1556
|
+
getBestAvailableAdapter(adapters = []) {
|
|
1557
|
+
const adapterMap = this.getAdapterMap(adapters);
|
|
1558
|
+
if (adapterMap.get("webgpu")?.isSupported?.()) {
|
|
1559
|
+
return "webgpu";
|
|
1560
|
+
}
|
|
1561
|
+
if (adapterMap.get("webgl")?.isSupported?.()) {
|
|
1562
|
+
return "webgl";
|
|
1563
|
+
}
|
|
1564
|
+
return null;
|
|
1565
|
+
}
|
|
1566
|
+
setDefaultDeviceProps(props) {
|
|
1567
|
+
Object.assign(_Luma.defaultProps, props);
|
|
1568
|
+
}
|
|
1569
|
+
/** Creates a device. Asynchronously. */
|
|
1570
|
+
async createDevice(props = {}) {
|
|
1571
|
+
props = { ..._Luma.defaultProps, ...props };
|
|
1572
|
+
if (props.waitForPageLoad) {
|
|
1573
|
+
await _Luma.pageLoaded;
|
|
1574
|
+
}
|
|
1575
|
+
const adapterMap = this.getAdapterMap(props.adapters);
|
|
1576
|
+
let type = props.type || "";
|
|
1577
|
+
if (type === "best-available") {
|
|
1578
|
+
type = this.getBestAvailableAdapter(props.adapters) || type;
|
|
1579
|
+
}
|
|
1580
|
+
const adapters = this.getAdapterMap(props.adapters) || adapterMap;
|
|
1581
|
+
const adapter = adapters.get(type);
|
|
1582
|
+
const device = await adapter?.create?.(props);
|
|
1583
|
+
if (device) {
|
|
1584
|
+
return device;
|
|
1585
|
+
}
|
|
1586
|
+
throw new Error(ERROR_MESSAGE);
|
|
1587
|
+
}
|
|
1588
|
+
/** Attach to an existing GPU API handle (WebGL2RenderingContext or GPUDevice). */
|
|
1589
|
+
async attachDevice(props) {
|
|
1590
|
+
const adapters = this.getAdapterMap(props.adapters);
|
|
1591
|
+
let type = "";
|
|
1592
|
+
if (props.handle instanceof WebGL2RenderingContext) {
|
|
1593
|
+
type = "webgl";
|
|
1594
|
+
}
|
|
1595
|
+
if (props.createCanvasContext) {
|
|
1596
|
+
await _Luma.pageLoaded;
|
|
1597
|
+
}
|
|
1598
|
+
if (props.handle === null) {
|
|
1599
|
+
type = "unknown";
|
|
1600
|
+
}
|
|
1601
|
+
const adapter = adapters.get(type);
|
|
1602
|
+
const device = await adapter?.attach?.(null);
|
|
1603
|
+
if (device) {
|
|
1604
|
+
return device;
|
|
1605
|
+
}
|
|
1606
|
+
throw new Error(ERROR_MESSAGE);
|
|
1607
|
+
}
|
|
1608
|
+
/**
|
|
1609
|
+
* Override `HTMLCanvasContext.getCanvas()` to always create WebGL2 contexts with additional WebGL1 compatibility.
|
|
1610
|
+
* Useful when attaching luma to a context from an external library does not support creating WebGL2 contexts.
|
|
1611
|
+
*/
|
|
1612
|
+
enforceWebGL2(enforce = true, adapters = []) {
|
|
1613
|
+
const adapterMap = this.getAdapterMap(adapters);
|
|
1614
|
+
const webgl2Adapter = adapterMap.get("webgl");
|
|
1615
|
+
if (!webgl2Adapter) {
|
|
1616
|
+
log.warn("enforceWebGL2: webgl adapter not found")();
|
|
1617
|
+
}
|
|
1618
|
+
webgl2Adapter?.enforceWebGL2?.(enforce);
|
|
1619
|
+
}
|
|
1620
|
+
/** Convert a list of adapters to a map */
|
|
1621
|
+
getAdapterMap(adapters = []) {
|
|
1622
|
+
const map = new Map(this.preregisteredAdapters);
|
|
1623
|
+
for (const adapter of adapters) {
|
|
1624
|
+
map.set(adapter.type, adapter);
|
|
1625
|
+
}
|
|
1626
|
+
return map;
|
|
1627
|
+
}
|
|
1628
|
+
// DEPRECATED
|
|
1629
|
+
/** @deprecated Use registerAdapters */
|
|
1630
|
+
registerDevices(deviceClasses) {
|
|
1631
|
+
log.warn("luma.registerDevices() is deprecated, use luma.registerAdapters() instead");
|
|
1632
|
+
for (const deviceClass of deviceClasses) {
|
|
1633
|
+
const adapter = deviceClass.adapter;
|
|
1634
|
+
if (adapter) {
|
|
1635
|
+
this.preregisteredAdapters.set(adapter.type, adapter);
|
|
1636
|
+
}
|
|
1637
|
+
}
|
|
1638
|
+
}
|
|
1639
|
+
};
|
|
1640
|
+
var Luma = _Luma;
|
|
1641
|
+
__publicField(Luma, "defaultProps", {
|
|
1642
|
+
...Device.defaultProps,
|
|
1643
|
+
type: "best-available",
|
|
1644
|
+
adapters: void 0,
|
|
1645
|
+
waitForPageLoad: true
|
|
1646
|
+
});
|
|
1647
|
+
/**
|
|
1648
|
+
* Page load promise
|
|
1649
|
+
* Get a 'lazy' promise that resolves when the DOM is loaded.
|
|
1650
|
+
* @note Since there may be limitations on number of `load` event listeners,
|
|
1651
|
+
* it is recommended avoid calling this function until actually needed.
|
|
1652
|
+
* I.e. don't call it until you know that you will be looking up a string in the DOM.
|
|
1653
|
+
*/
|
|
1654
|
+
__publicField(Luma, "pageLoaded", getPageLoadPromise().then(() => {
|
|
1655
|
+
log.probe(2, "DOM is loaded")();
|
|
1656
|
+
}));
|
|
1657
|
+
var luma = new Luma();
|
|
1658
|
+
function getPageLoadPromise() {
|
|
1659
|
+
if (isPageLoaded() || typeof window === "undefined") {
|
|
1660
|
+
return Promise.resolve();
|
|
1661
|
+
}
|
|
1662
|
+
return new Promise((resolve) => {
|
|
1663
|
+
window.addEventListener("load", () => resolve());
|
|
1664
|
+
});
|
|
1665
|
+
}
|
|
1666
|
+
|
|
1667
|
+
// ../core/src/adapter/adapter.ts
|
|
1668
|
+
var Adapter = class {
|
|
1669
|
+
};
|
|
1670
|
+
|
|
1671
|
+
// ../core/src/adapter/canvas-context.ts
|
|
1672
|
+
var _CanvasContext = class {
|
|
1673
|
+
id;
|
|
1674
|
+
props;
|
|
1675
|
+
canvas;
|
|
1676
|
+
htmlCanvas;
|
|
1677
|
+
offscreenCanvas;
|
|
1678
|
+
type;
|
|
1679
|
+
_initializedResolvers = withResolvers();
|
|
1680
|
+
/** Promise that resolved once the resize observer has updated the pixel size */
|
|
1681
|
+
initialized;
|
|
1682
|
+
isInitialized = false;
|
|
1683
|
+
/** Visibility is automatically updated (via an IntersectionObserver) */
|
|
1684
|
+
isVisible = true;
|
|
1685
|
+
/** Device pixel ratio. Automatically updated via media queries */
|
|
1686
|
+
devicePixelRatio;
|
|
1687
|
+
/** Exact width of canvas in physical pixels (tracked by a ResizeObserver) */
|
|
1688
|
+
pixelWidth;
|
|
1689
|
+
/** Exact height of canvas in physical pixels (tracked by a ResizeObserver) */
|
|
1690
|
+
pixelHeight;
|
|
1691
|
+
/** Width of drawing buffer: automatically updated if props.autoResize is true */
|
|
1692
|
+
drawingBufferWidth;
|
|
1693
|
+
/** Height of drawing buffer: automatically updated if props.autoResize is true */
|
|
1694
|
+
drawingBufferHeight;
|
|
1695
|
+
_resizeObserver;
|
|
1696
|
+
_intersectionObserver;
|
|
1697
|
+
/** State used by luma.gl classes: TODO - remove */
|
|
1698
|
+
_canvasSizeInfo = { clientWidth: 0, clientHeight: 0, devicePixelRatio: 1 };
|
|
1699
|
+
toString() {
|
|
1700
|
+
return `${this[Symbol.toStringTag]}(${this.id})`;
|
|
1701
|
+
}
|
|
1702
|
+
constructor(props) {
|
|
1703
|
+
this.props = { ..._CanvasContext.defaultProps, ...props };
|
|
1704
|
+
props = this.props;
|
|
1705
|
+
this.initialized = this._initializedResolvers.promise;
|
|
1706
|
+
if (!isBrowser()) {
|
|
1707
|
+
this.canvas = { width: props.width || 1, height: props.height || 1 };
|
|
1708
|
+
} else if (!props.canvas) {
|
|
1709
|
+
this.canvas = createCanvasElement(props);
|
|
1710
|
+
} else if (typeof props.canvas === "string") {
|
|
1711
|
+
this.canvas = getCanvasFromDOM(props.canvas);
|
|
1712
|
+
} else {
|
|
1713
|
+
this.canvas = props.canvas;
|
|
1714
|
+
}
|
|
1715
|
+
if (this.canvas instanceof HTMLCanvasElement) {
|
|
1716
|
+
this.id = props.id || this.canvas.id;
|
|
1717
|
+
this.type = "html-canvas";
|
|
1718
|
+
this.htmlCanvas = this.canvas;
|
|
1719
|
+
} else if (this.canvas instanceof OffscreenCanvas) {
|
|
1720
|
+
this.id = props.id || "offscreen-canvas";
|
|
1721
|
+
this.type = "offscreen-canvas";
|
|
1722
|
+
this.offscreenCanvas = this.canvas;
|
|
1723
|
+
} else {
|
|
1724
|
+
this.id = props.id || "node-canvas-context";
|
|
1725
|
+
this.type = "node";
|
|
1726
|
+
}
|
|
1727
|
+
this.pixelWidth = this.canvas.width;
|
|
1728
|
+
this.pixelHeight = this.canvas.height;
|
|
1729
|
+
this.drawingBufferWidth = this.canvas.width;
|
|
1730
|
+
this.drawingBufferHeight = this.canvas.height;
|
|
1731
|
+
this.devicePixelRatio = globalThis.devicePixelRatio || 1;
|
|
1732
|
+
if (this.canvas instanceof HTMLCanvasElement) {
|
|
1733
|
+
this._intersectionObserver = new IntersectionObserver(
|
|
1734
|
+
(entries) => this._handleIntersection(entries)
|
|
1735
|
+
);
|
|
1736
|
+
this._intersectionObserver.observe(this.canvas);
|
|
1737
|
+
this._resizeObserver = new ResizeObserver((entries) => this._handleResize(entries));
|
|
1738
|
+
try {
|
|
1739
|
+
this._resizeObserver.observe(this.canvas, { box: "device-pixel-content-box" });
|
|
1740
|
+
} catch {
|
|
1741
|
+
this._resizeObserver.observe(this.canvas, { box: "content-box" });
|
|
1742
|
+
}
|
|
1743
|
+
setTimeout(() => this._observeDevicePixelRatio(), 0);
|
|
1744
|
+
}
|
|
1745
|
+
}
|
|
1746
|
+
// SIZE METHODS
|
|
1747
|
+
/**
|
|
1748
|
+
* Returns the size covered by the canvas in CSS pixels
|
|
1749
|
+
* @note This can be different from the actual device pixel size of a canvas due to DPR scaling, and rounding to integer pixels
|
|
1750
|
+
* @note This is independent of the canvas' internal drawing buffer size (.width, .height).
|
|
1751
|
+
*/
|
|
1752
|
+
getCSSSize() {
|
|
1753
|
+
if (this.canvas instanceof HTMLCanvasElement) {
|
|
1754
|
+
return [this.canvas.clientWidth, this.canvas.clientHeight];
|
|
1755
|
+
}
|
|
1756
|
+
return [this.pixelWidth, this.pixelHeight];
|
|
1757
|
+
}
|
|
1758
|
+
/**
|
|
1759
|
+
* Returns the size covered by the canvas in actual device pixels.
|
|
1760
|
+
* @note This can be different from the 'CSS' size of a canvas due to DPR scaling, and rounding to integer pixels
|
|
1761
|
+
* @note This is independent of the canvas' internal drawing buffer size (.width, .height).
|
|
1762
|
+
*/
|
|
1763
|
+
getPixelSize() {
|
|
1764
|
+
return [this.pixelWidth, this.pixelHeight];
|
|
1765
|
+
}
|
|
1766
|
+
/** Get the drawing buffer size (number of pixels GPU is rendering into, can be different from CSS size) */
|
|
1767
|
+
getDrawingBufferSize() {
|
|
1768
|
+
return [this.drawingBufferWidth, this.drawingBufferHeight];
|
|
1769
|
+
}
|
|
1770
|
+
/** Returns the biggest allowed framebuffer size. @todo Allow the application to limit this? */
|
|
1771
|
+
getMaxDrawingBufferSize() {
|
|
1772
|
+
const maxTextureDimension = this.device.limits.maxTextureDimension2D;
|
|
1773
|
+
return [maxTextureDimension, maxTextureDimension];
|
|
1774
|
+
}
|
|
1775
|
+
/** Update the canvas drawing buffer size. Called automatically if props.autoResize is true. */
|
|
1776
|
+
setDrawingBufferSize(width, height) {
|
|
1777
|
+
this.canvas.width = width;
|
|
1778
|
+
this.canvas.height = height;
|
|
1779
|
+
this.drawingBufferWidth = width;
|
|
1780
|
+
this.drawingBufferHeight = height;
|
|
1781
|
+
}
|
|
1782
|
+
/** @deprecated - TODO which values should we use for aspect */
|
|
1783
|
+
getAspect() {
|
|
1784
|
+
const [width, height] = this.getPixelSize();
|
|
1785
|
+
return width / height;
|
|
1786
|
+
}
|
|
1787
|
+
/**
|
|
1788
|
+
* Returns the current DPR (number of physical pixels per CSS pixel), if props.useDevicePixels is true
|
|
1789
|
+
* @note This can be a fractional (non-integer) number, e.g. when the user zooms in the browser.
|
|
1790
|
+
* @note This function handles the non-HTML canvas cases
|
|
1791
|
+
*/
|
|
1792
|
+
getDevicePixelRatio(useDevicePixels) {
|
|
1793
|
+
if (typeof OffscreenCanvas !== "undefined" && this.canvas instanceof OffscreenCanvas) {
|
|
1794
|
+
return 1;
|
|
1795
|
+
}
|
|
1796
|
+
useDevicePixels = useDevicePixels === void 0 ? this.props.useDevicePixels : useDevicePixels;
|
|
1797
|
+
if (!useDevicePixels || useDevicePixels <= 0) {
|
|
1798
|
+
return 1;
|
|
1799
|
+
}
|
|
1800
|
+
if (useDevicePixels === true) {
|
|
1801
|
+
const dpr = typeof window !== "undefined" && window.devicePixelRatio;
|
|
1802
|
+
return dpr || 1;
|
|
1803
|
+
}
|
|
1804
|
+
return useDevicePixels;
|
|
1805
|
+
}
|
|
1806
|
+
/**
|
|
1807
|
+
* Returns multiplier need to convert CSS size to Device size
|
|
1808
|
+
*/
|
|
1809
|
+
cssToDeviceRatio() {
|
|
1810
|
+
try {
|
|
1811
|
+
const [drawingBufferWidth] = this.getDrawingBufferSize();
|
|
1812
|
+
const { clientWidth } = this._canvasSizeInfo;
|
|
1813
|
+
return clientWidth ? drawingBufferWidth / clientWidth : 1;
|
|
1814
|
+
} catch {
|
|
1815
|
+
return 1;
|
|
1816
|
+
}
|
|
1817
|
+
}
|
|
1818
|
+
/**
|
|
1819
|
+
* Maps CSS pixel position to device pixel position
|
|
1820
|
+
*/
|
|
1821
|
+
cssToDevicePixels(cssPixel, yInvert = true) {
|
|
1822
|
+
const ratio = this.cssToDeviceRatio();
|
|
1823
|
+
const [width, height] = this.getDrawingBufferSize();
|
|
1824
|
+
return scalePixels(cssPixel, ratio, width, height, yInvert);
|
|
1825
|
+
}
|
|
1826
|
+
// IMPLEMENTATION
|
|
1827
|
+
/**
|
|
1828
|
+
* Allows subclass constructor to override the canvas id for auto created canvases.
|
|
1829
|
+
* This can really help when debugging DOM in apps that create multiple devices
|
|
1830
|
+
*/
|
|
1831
|
+
_setAutoCreatedCanvasId(id) {
|
|
1832
|
+
if (this.htmlCanvas?.id === "lumagl-auto-created-canvas") {
|
|
1833
|
+
this.htmlCanvas.id = id;
|
|
1834
|
+
}
|
|
1835
|
+
}
|
|
1836
|
+
/** reacts to our intersection observer */
|
|
1837
|
+
_handleIntersection(entries) {
|
|
1838
|
+
const entry = entries.find((entry_) => entry_.target === this.canvas);
|
|
1839
|
+
if (!entry) {
|
|
1840
|
+
return;
|
|
1841
|
+
}
|
|
1842
|
+
const isVisible = entry.isIntersecting;
|
|
1843
|
+
if (this.isVisible !== isVisible) {
|
|
1844
|
+
this.isVisible = isVisible;
|
|
1845
|
+
this.device.props.onVisibilityChange(this);
|
|
1846
|
+
}
|
|
1847
|
+
}
|
|
1848
|
+
/**
|
|
1849
|
+
* Reacts to an observed resize by using the most accurate pixel size information the browser can provide
|
|
1850
|
+
* @see https://web.dev/articles/device-pixel-content-box
|
|
1851
|
+
* @see https://webgpufundamentals.org/webgpu/lessons/webgpu-resizing-the-canvas.html
|
|
1852
|
+
*/
|
|
1853
|
+
_handleResize(entries) {
|
|
1854
|
+
const entry = entries.find((entry_) => entry_.target === this.canvas);
|
|
1855
|
+
if (!entry) {
|
|
1856
|
+
return;
|
|
1857
|
+
}
|
|
1858
|
+
const boxWidth = entry.devicePixelContentBoxSize?.[0].inlineSize || entry.contentBoxSize[0].inlineSize * devicePixelRatio;
|
|
1859
|
+
const boxHeight = entry.devicePixelContentBoxSize?.[0].blockSize || entry.contentBoxSize[0].blockSize * devicePixelRatio;
|
|
1860
|
+
const oldPixelSize = this.getPixelSize();
|
|
1861
|
+
const [maxPixelWidth, maxPixelHeight] = this.getMaxDrawingBufferSize();
|
|
1862
|
+
this.pixelWidth = Math.max(1, Math.min(boxWidth, maxPixelWidth));
|
|
1863
|
+
this.pixelHeight = Math.max(1, Math.min(boxHeight, maxPixelHeight));
|
|
1864
|
+
if (this.props.autoResize) {
|
|
1865
|
+
this.setDrawingBufferSize(this.pixelWidth, this.pixelHeight);
|
|
1866
|
+
this.updateSize(this.getDrawingBufferSize());
|
|
1867
|
+
}
|
|
1868
|
+
this._initializedResolvers.resolve();
|
|
1869
|
+
this.isInitialized = true;
|
|
1870
|
+
this.device.props.onResize(this, { oldPixelSize });
|
|
1871
|
+
}
|
|
1872
|
+
/** Monitor DPR changes */
|
|
1873
|
+
_observeDevicePixelRatio() {
|
|
1874
|
+
const oldRatio = this.devicePixelRatio;
|
|
1875
|
+
this.devicePixelRatio = window.devicePixelRatio;
|
|
1876
|
+
this.device.props.onDevicePixelRatioChange(this, { oldRatio });
|
|
1877
|
+
matchMedia(`(resolution: ${this.devicePixelRatio}dppx)`).addEventListener(
|
|
1878
|
+
"change",
|
|
1879
|
+
() => this._observeDevicePixelRatio(),
|
|
1880
|
+
{ once: true }
|
|
1881
|
+
);
|
|
1882
|
+
}
|
|
1883
|
+
/**
|
|
1884
|
+
* @deprecated Use devicePixelRatio to set canvas width and height
|
|
1885
|
+
* @note this is a raw port of luma.gl v8 code. Might be worth a review
|
|
1886
|
+
*/
|
|
1887
|
+
_setDevicePixelRatio(devicePixelRatio2, options = {}) {
|
|
1888
|
+
if (!this.htmlCanvas) {
|
|
1889
|
+
return;
|
|
1890
|
+
}
|
|
1891
|
+
let clientWidth = "width" in options ? options.width : this.htmlCanvas.clientWidth;
|
|
1892
|
+
let clientHeight = "height" in options ? options.height : this.htmlCanvas.clientHeight;
|
|
1893
|
+
if (!clientWidth || !clientHeight) {
|
|
1894
|
+
log.log(1, "Canvas clientWidth/clientHeight is 0")();
|
|
1895
|
+
devicePixelRatio2 = 1;
|
|
1896
|
+
clientWidth = this.htmlCanvas.width || 1;
|
|
1897
|
+
clientHeight = this.htmlCanvas.height || 1;
|
|
1898
|
+
}
|
|
1899
|
+
const cachedSize = this._canvasSizeInfo;
|
|
1900
|
+
if (cachedSize.clientWidth !== clientWidth || cachedSize.clientHeight !== clientHeight || cachedSize.devicePixelRatio !== devicePixelRatio2) {
|
|
1901
|
+
let clampedPixelRatio = devicePixelRatio2;
|
|
1902
|
+
const canvasWidth = Math.floor(clientWidth * clampedPixelRatio);
|
|
1903
|
+
const canvasHeight = Math.floor(clientHeight * clampedPixelRatio);
|
|
1904
|
+
this.htmlCanvas.width = canvasWidth;
|
|
1905
|
+
this.htmlCanvas.height = canvasHeight;
|
|
1906
|
+
const gl = this.device.gl;
|
|
1907
|
+
if (gl) {
|
|
1908
|
+
const [drawingBufferWidth, drawingBufferHeight] = this.getDrawingBufferSize();
|
|
1909
|
+
if (drawingBufferWidth !== canvasWidth || drawingBufferHeight !== canvasHeight) {
|
|
1910
|
+
clampedPixelRatio = Math.min(
|
|
1911
|
+
drawingBufferWidth / clientWidth,
|
|
1912
|
+
drawingBufferHeight / clientHeight
|
|
1913
|
+
);
|
|
1914
|
+
this.htmlCanvas.width = Math.floor(clientWidth * clampedPixelRatio);
|
|
1915
|
+
this.htmlCanvas.height = Math.floor(clientHeight * clampedPixelRatio);
|
|
1916
|
+
log.warn("Device pixel ratio clamped")();
|
|
1917
|
+
}
|
|
1918
|
+
this._canvasSizeInfo.clientWidth = clientWidth;
|
|
1919
|
+
this._canvasSizeInfo.clientHeight = clientHeight;
|
|
1920
|
+
this._canvasSizeInfo.devicePixelRatio = devicePixelRatio2;
|
|
1921
|
+
}
|
|
1922
|
+
}
|
|
1923
|
+
}
|
|
1924
|
+
};
|
|
1925
|
+
var CanvasContext = _CanvasContext;
|
|
1926
|
+
__publicField(CanvasContext, "defaultProps", {
|
|
1927
|
+
id: void 0,
|
|
1928
|
+
canvas: null,
|
|
1929
|
+
width: 800,
|
|
1930
|
+
height: 600,
|
|
1931
|
+
useDevicePixels: true,
|
|
1932
|
+
autoResize: true,
|
|
1933
|
+
container: null,
|
|
1934
|
+
visible: true,
|
|
1935
|
+
alphaMode: "opaque",
|
|
1936
|
+
colorSpace: "srgb"
|
|
1937
|
+
});
|
|
1938
|
+
function getContainer(container) {
|
|
1939
|
+
if (typeof container === "string") {
|
|
1940
|
+
const element = document.getElementById(container);
|
|
1941
|
+
if (!element) {
|
|
1942
|
+
throw new Error(`${container} is not an HTML element`);
|
|
1943
|
+
}
|
|
1944
|
+
return element;
|
|
1945
|
+
}
|
|
1946
|
+
if (container) {
|
|
1947
|
+
return container;
|
|
1948
|
+
}
|
|
1949
|
+
return document.body;
|
|
1950
|
+
}
|
|
1951
|
+
function getCanvasFromDOM(canvasId) {
|
|
1952
|
+
const canvas = document.getElementById(canvasId);
|
|
1953
|
+
if (!(canvas instanceof HTMLCanvasElement)) {
|
|
1954
|
+
throw new Error("Object is not a canvas element");
|
|
1955
|
+
}
|
|
1956
|
+
return canvas;
|
|
1957
|
+
}
|
|
1958
|
+
function createCanvasElement(props) {
|
|
1959
|
+
const { width, height } = props;
|
|
1960
|
+
const newCanvas = document.createElement("canvas");
|
|
1961
|
+
newCanvas.id = uid("lumagl-auto-created-canvas");
|
|
1962
|
+
newCanvas.width = width || 1;
|
|
1963
|
+
newCanvas.height = height || 1;
|
|
1964
|
+
newCanvas.style.width = Number.isFinite(width) ? `${width}px` : "100%";
|
|
1965
|
+
newCanvas.style.height = Number.isFinite(height) ? `${height}px` : "100%";
|
|
1966
|
+
if (!props?.visible) {
|
|
1967
|
+
newCanvas.style.visibility = "hidden";
|
|
1968
|
+
}
|
|
1969
|
+
const container = getContainer(props?.container || null);
|
|
1970
|
+
container.insertBefore(newCanvas, container.firstChild);
|
|
1971
|
+
return newCanvas;
|
|
1972
|
+
}
|
|
1973
|
+
function scalePixels(pixel, ratio, width, height, yInvert) {
|
|
1974
|
+
const point = pixel;
|
|
1975
|
+
const x = scaleX(point[0], ratio, width);
|
|
1976
|
+
let y = scaleY(point[1], ratio, height, yInvert);
|
|
1977
|
+
let t = scaleX(point[0] + 1, ratio, width);
|
|
1978
|
+
const xHigh = t === width - 1 ? t : t - 1;
|
|
1979
|
+
t = scaleY(point[1] + 1, ratio, height, yInvert);
|
|
1980
|
+
let yHigh;
|
|
1981
|
+
if (yInvert) {
|
|
1982
|
+
t = t === 0 ? t : t + 1;
|
|
1983
|
+
yHigh = y;
|
|
1984
|
+
y = t;
|
|
1985
|
+
} else {
|
|
1986
|
+
yHigh = t === height - 1 ? t : t - 1;
|
|
1987
|
+
}
|
|
1988
|
+
return {
|
|
1989
|
+
x,
|
|
1990
|
+
y,
|
|
1991
|
+
// when ratio < 1, current css pixel and next css pixel may point to same device pixel, set width/height to 1 in those cases.
|
|
1992
|
+
width: Math.max(xHigh - x + 1, 1),
|
|
1993
|
+
height: Math.max(yHigh - y + 1, 1)
|
|
1994
|
+
};
|
|
1995
|
+
}
|
|
1996
|
+
function scaleX(x, ratio, width) {
|
|
1997
|
+
const r = Math.min(Math.round(x * ratio), width - 1);
|
|
1998
|
+
return r;
|
|
1999
|
+
}
|
|
2000
|
+
function scaleY(y, ratio, height, yInvert) {
|
|
2001
|
+
return yInvert ? Math.max(0, height - 1 - Math.round(y * ratio)) : Math.min(Math.round(y * ratio), height - 1);
|
|
2002
|
+
}
|
|
2003
|
+
function withResolvers() {
|
|
2004
|
+
let resolve;
|
|
2005
|
+
let reject;
|
|
2006
|
+
const promise = new Promise((_resolve, _reject) => {
|
|
2007
|
+
resolve = _resolve;
|
|
2008
|
+
reject = _reject;
|
|
2009
|
+
});
|
|
2010
|
+
return { promise, resolve, reject };
|
|
2011
|
+
}
|
|
2012
|
+
|
|
2013
|
+
// ../core/src/adapter/resources/texture.ts
|
|
2014
|
+
var _Texture = class extends Resource {
|
|
2015
|
+
get [Symbol.toStringTag]() {
|
|
2016
|
+
return "Texture";
|
|
2017
|
+
}
|
|
2018
|
+
toString() {
|
|
2019
|
+
return `Texture(${this.id},${this.format},${this.width}x${this.height})`;
|
|
2020
|
+
}
|
|
2021
|
+
/** dimension of this texture */
|
|
2022
|
+
dimension;
|
|
2023
|
+
/** format of this texture */
|
|
2024
|
+
format;
|
|
2025
|
+
/** width in pixels of this texture */
|
|
2026
|
+
width;
|
|
2027
|
+
/** height in pixels of this texture */
|
|
2028
|
+
height;
|
|
2029
|
+
/** depth of this texture */
|
|
2030
|
+
depth;
|
|
2031
|
+
/** mip levels in this texture */
|
|
2032
|
+
mipLevels;
|
|
2033
|
+
/** "Time" of last update. Monotonically increasing timestamp. TODO move to AsyncTexture? */
|
|
2034
|
+
updateTimestamp;
|
|
2035
|
+
/** Do not use directly. Create with device.createTexture() */
|
|
2036
|
+
constructor(device, props) {
|
|
2037
|
+
props = _Texture.normalizeProps(device, props);
|
|
2038
|
+
super(device, props, _Texture.defaultProps);
|
|
2039
|
+
this.dimension = this.props.dimension;
|
|
2040
|
+
this.format = this.props.format;
|
|
2041
|
+
this.width = this.props.width;
|
|
2042
|
+
this.height = this.props.height;
|
|
2043
|
+
this.depth = this.props.depth;
|
|
2044
|
+
if (this.props.width === void 0 || this.props.height === void 0) {
|
|
2045
|
+
const size = _Texture.getTextureDataSize(this.props.data);
|
|
2046
|
+
this.width = size?.width || 1;
|
|
2047
|
+
this.height = size?.height || 1;
|
|
2048
|
+
}
|
|
2049
|
+
if (this.props.mipmaps && this.props.mipLevels === void 0) {
|
|
2050
|
+
this.props.mipLevels = "pyramid";
|
|
2051
|
+
}
|
|
2052
|
+
this.mipLevels = this.props.mipLevels === "pyramid" ? _Texture.getMipLevelCount(this.width, this.height) : this.props.mipLevels || 1;
|
|
2053
|
+
this.updateTimestamp = device.incrementTimestamp();
|
|
2054
|
+
}
|
|
2055
|
+
/**
|
|
2056
|
+
* Create a new texture with the same parameters and optionally, a different size
|
|
2057
|
+
* @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.
|
|
2058
|
+
* @note Does not copy contents of the texture
|
|
2059
|
+
*/
|
|
2060
|
+
clone(size) {
|
|
2061
|
+
return this.device.createTexture({ ...this.props, ...size });
|
|
2062
|
+
}
|
|
2063
|
+
/** Check if data is an external image */
|
|
2064
|
+
static isExternalImage(data) {
|
|
2065
|
+
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;
|
|
2066
|
+
}
|
|
2067
|
+
/** Determine size (width and height) of provided image data */
|
|
2068
|
+
static getExternalImageSize(data) {
|
|
2069
|
+
if (typeof ImageData !== "undefined" && data instanceof ImageData || typeof ImageBitmap !== "undefined" && data instanceof ImageBitmap || typeof HTMLCanvasElement !== "undefined" && data instanceof HTMLCanvasElement || typeof OffscreenCanvas !== "undefined" && data instanceof OffscreenCanvas) {
|
|
2070
|
+
return { width: data.width, height: data.height };
|
|
2071
|
+
}
|
|
2072
|
+
if (typeof HTMLImageElement !== "undefined" && data instanceof HTMLImageElement) {
|
|
2073
|
+
return { width: data.naturalWidth, height: data.naturalHeight };
|
|
2074
|
+
}
|
|
2075
|
+
if (typeof HTMLVideoElement !== "undefined" && data instanceof HTMLVideoElement) {
|
|
2076
|
+
return { width: data.videoWidth, height: data.videoHeight };
|
|
2077
|
+
}
|
|
2078
|
+
if (typeof VideoFrame !== "undefined" && data instanceof VideoFrame) {
|
|
2079
|
+
return { width: data.displayWidth, height: data.displayHeight };
|
|
2080
|
+
}
|
|
2081
|
+
throw new Error("Unknown image type");
|
|
2082
|
+
}
|
|
2083
|
+
/** Check if texture data is a typed array */
|
|
2084
|
+
static isTextureLevelData(data) {
|
|
2085
|
+
const typedArray = data?.data;
|
|
2086
|
+
return ArrayBuffer.isView(typedArray);
|
|
2087
|
+
}
|
|
2088
|
+
/** Get the size of the texture described by the provided TextureData */
|
|
2089
|
+
static getTextureDataSize(data) {
|
|
2090
|
+
if (!data) {
|
|
2091
|
+
return null;
|
|
2092
|
+
}
|
|
2093
|
+
if (ArrayBuffer.isView(data)) {
|
|
2094
|
+
return null;
|
|
2095
|
+
}
|
|
2096
|
+
if (Array.isArray(data)) {
|
|
2097
|
+
return _Texture.getTextureDataSize(data[0]);
|
|
2098
|
+
}
|
|
2099
|
+
if (_Texture.isExternalImage(data)) {
|
|
2100
|
+
return _Texture.getExternalImageSize(data);
|
|
2101
|
+
}
|
|
2102
|
+
if (data && typeof data === "object" && data.constructor === Object) {
|
|
2103
|
+
const textureDataArray = Object.values(data);
|
|
2104
|
+
const untypedData = textureDataArray[0];
|
|
2105
|
+
return { width: untypedData.width, height: untypedData.height };
|
|
2106
|
+
}
|
|
2107
|
+
throw new Error("texture size deduction failed");
|
|
2108
|
+
}
|
|
2109
|
+
/**
|
|
2110
|
+
* Normalize TextureData to an array of TextureLevelData / ExternalImages
|
|
2111
|
+
* @param data
|
|
2112
|
+
* @param options
|
|
2113
|
+
* @returns array of TextureLevelData / ExternalImages
|
|
2114
|
+
*/
|
|
2115
|
+
static normalizeTextureData(data, options) {
|
|
2116
|
+
let lodArray;
|
|
2117
|
+
if (ArrayBuffer.isView(data)) {
|
|
2118
|
+
lodArray = [
|
|
2119
|
+
{
|
|
2120
|
+
// ts-expect-error does data really need to be Uint8ClampedArray?
|
|
2121
|
+
data,
|
|
2122
|
+
width: options.width,
|
|
2123
|
+
height: options.height
|
|
2124
|
+
// depth: options.depth
|
|
2125
|
+
}
|
|
2126
|
+
];
|
|
2127
|
+
} else if (!Array.isArray(data)) {
|
|
2128
|
+
lodArray = [data];
|
|
2129
|
+
} else {
|
|
2130
|
+
lodArray = data;
|
|
2131
|
+
}
|
|
2132
|
+
return lodArray;
|
|
2133
|
+
}
|
|
2134
|
+
/** Calculate the number of mip levels for a texture of width and height */
|
|
2135
|
+
static getMipLevelCount(width, height) {
|
|
2136
|
+
return Math.floor(Math.log2(Math.max(width, height))) + 1;
|
|
2137
|
+
}
|
|
2138
|
+
/** Convert luma.gl cubemap face constants to depth index */
|
|
2139
|
+
static getCubeFaceDepth(face) {
|
|
2140
|
+
switch (face) {
|
|
2141
|
+
case "+X":
|
|
2142
|
+
return 0;
|
|
2143
|
+
case "-X":
|
|
2144
|
+
return 1;
|
|
2145
|
+
case "+Y":
|
|
2146
|
+
return 2;
|
|
2147
|
+
case "-Y":
|
|
2148
|
+
return 3;
|
|
2149
|
+
case "+Z":
|
|
2150
|
+
return 4;
|
|
2151
|
+
case "-Z":
|
|
2152
|
+
return 5;
|
|
2153
|
+
default:
|
|
2154
|
+
throw new Error(face);
|
|
2155
|
+
}
|
|
2156
|
+
}
|
|
2157
|
+
/** Ensure we have integer coordinates */
|
|
2158
|
+
static normalizeProps(device, props) {
|
|
2159
|
+
const newProps = { ...props };
|
|
2160
|
+
const overriddenDefaultProps = device?.props?._resourceDefaults?.texture || {};
|
|
2161
|
+
Object.assign(newProps, overriddenDefaultProps);
|
|
2162
|
+
const { width, height } = newProps;
|
|
2163
|
+
if (typeof width === "number") {
|
|
2164
|
+
newProps.width = Math.max(1, Math.ceil(width));
|
|
2165
|
+
}
|
|
2166
|
+
if (typeof height === "number") {
|
|
2167
|
+
newProps.height = Math.max(1, Math.ceil(height));
|
|
2168
|
+
}
|
|
2169
|
+
return newProps;
|
|
2170
|
+
}
|
|
2171
|
+
};
|
|
2172
|
+
var Texture = _Texture;
|
|
2173
|
+
__publicField(Texture, "COPY_SRC", 1);
|
|
2174
|
+
__publicField(Texture, "COPY_DST", 2);
|
|
2175
|
+
__publicField(Texture, "TEXTURE", 4);
|
|
2176
|
+
__publicField(Texture, "STORAGE", 8);
|
|
2177
|
+
__publicField(Texture, "RENDER_ATTACHMENT", 16);
|
|
2178
|
+
__publicField(Texture, "CubeFaces", ["+X", "-X", "+Y", "-Y", "+Z", "-Z"]);
|
|
2179
|
+
__publicField(Texture, "defaultProps", {
|
|
2180
|
+
...Resource.defaultProps,
|
|
2181
|
+
data: null,
|
|
2182
|
+
dimension: "2d",
|
|
2183
|
+
format: "rgba8unorm",
|
|
2184
|
+
width: void 0,
|
|
2185
|
+
height: void 0,
|
|
2186
|
+
depth: 1,
|
|
2187
|
+
mipmaps: false,
|
|
2188
|
+
compressed: false,
|
|
2189
|
+
usage: 0,
|
|
2190
|
+
mipLevels: void 0,
|
|
2191
|
+
samples: void 0,
|
|
2192
|
+
sampler: {},
|
|
2193
|
+
view: void 0,
|
|
2194
|
+
flipY: void 0
|
|
2195
|
+
});
|
|
2196
|
+
/** Default options */
|
|
2197
|
+
__publicField(Texture, "defaultCopyExternalImageOptions", {
|
|
2198
|
+
image: void 0,
|
|
2199
|
+
sourceX: 0,
|
|
2200
|
+
sourceY: 0,
|
|
2201
|
+
width: void 0,
|
|
2202
|
+
height: void 0,
|
|
2203
|
+
depth: 1,
|
|
2204
|
+
mipLevel: 0,
|
|
2205
|
+
x: 0,
|
|
2206
|
+
y: 0,
|
|
2207
|
+
z: 0,
|
|
2208
|
+
aspect: "all",
|
|
2209
|
+
colorSpace: "srgb",
|
|
2210
|
+
premultipliedAlpha: false,
|
|
2211
|
+
flipY: false
|
|
2212
|
+
});
|
|
2213
|
+
|
|
2214
|
+
// ../core/src/adapter/resources/texture-view.ts
|
|
2215
|
+
var _TextureView = class extends Resource {
|
|
2216
|
+
get [Symbol.toStringTag]() {
|
|
2217
|
+
return "TextureView";
|
|
2218
|
+
}
|
|
2219
|
+
/** Should not be constructed directly. Use `texture.createView(props)` */
|
|
2220
|
+
constructor(device, props) {
|
|
2221
|
+
super(device, props, _TextureView.defaultProps);
|
|
2222
|
+
}
|
|
2223
|
+
};
|
|
2224
|
+
var TextureView = _TextureView;
|
|
2225
|
+
__publicField(TextureView, "defaultProps", {
|
|
2226
|
+
...Resource.defaultProps,
|
|
2227
|
+
format: void 0,
|
|
2228
|
+
dimension: void 0,
|
|
2229
|
+
aspect: "all",
|
|
2230
|
+
baseMipLevel: 0,
|
|
2231
|
+
mipLevelCount: void 0,
|
|
2232
|
+
baseArrayLayer: 0,
|
|
2233
|
+
arrayLayerCount: void 0
|
|
2234
|
+
});
|
|
2235
|
+
|
|
2236
|
+
// ../core/src/adapter/resources/external-texture.ts
|
|
2237
|
+
var _ExternalTexture = class extends Resource {
|
|
2238
|
+
get [Symbol.toStringTag]() {
|
|
2239
|
+
return "ExternalTexture";
|
|
2240
|
+
}
|
|
2241
|
+
constructor(device, props) {
|
|
2242
|
+
super(device, props, _ExternalTexture.defaultProps);
|
|
2243
|
+
}
|
|
2244
|
+
};
|
|
2245
|
+
var ExternalTexture = _ExternalTexture;
|
|
2246
|
+
__publicField(ExternalTexture, "defaultProps", {
|
|
2247
|
+
...Resource.defaultProps,
|
|
2248
|
+
source: void 0,
|
|
2249
|
+
colorSpace: "srgb"
|
|
2250
|
+
});
|
|
2251
|
+
|
|
2252
|
+
// ../core/src/adapter-utils/format-compiler-log.ts
|
|
2253
|
+
function formatCompilerLog(shaderLog, source, options) {
|
|
2254
|
+
let formattedLog = "";
|
|
2255
|
+
const lines = source.split(/\r?\n/);
|
|
2256
|
+
const log2 = shaderLog.slice().sort((a, b) => a.lineNum - b.lineNum);
|
|
2257
|
+
switch (options?.showSourceCode || "no") {
|
|
2258
|
+
case "all":
|
|
2259
|
+
let currentMessage = 0;
|
|
2260
|
+
for (let lineNum = 1; lineNum <= lines.length; lineNum++) {
|
|
2261
|
+
formattedLog += getNumberedLine(lines[lineNum - 1], lineNum, options);
|
|
2262
|
+
while (log2.length > currentMessage && log2[currentMessage].lineNum === lineNum) {
|
|
2263
|
+
const message = log2[currentMessage++];
|
|
2264
|
+
formattedLog += formatCompilerMessage(message, lines, message.lineNum, {
|
|
2265
|
+
...options,
|
|
2266
|
+
inlineSource: false
|
|
2267
|
+
});
|
|
2268
|
+
}
|
|
2269
|
+
}
|
|
2270
|
+
return formattedLog;
|
|
2271
|
+
case "issues":
|
|
2272
|
+
case "no":
|
|
2273
|
+
for (const message of shaderLog) {
|
|
2274
|
+
formattedLog += formatCompilerMessage(message, lines, message.lineNum, {
|
|
2275
|
+
inlineSource: options?.showSourceCode !== "no"
|
|
2276
|
+
});
|
|
2277
|
+
}
|
|
2278
|
+
return formattedLog;
|
|
2279
|
+
}
|
|
2280
|
+
}
|
|
2281
|
+
function formatCompilerMessage(message, lines, lineNum, options) {
|
|
2282
|
+
if (options?.inlineSource) {
|
|
2283
|
+
const numberedLines = getNumberedLines(lines, lineNum);
|
|
2284
|
+
const positionIndicator = message.linePos > 0 ? `${" ".repeat(message.linePos + 5)}^^^
|
|
2285
|
+
` : "";
|
|
2286
|
+
return `
|
|
2287
|
+
${numberedLines}${positionIndicator}${message.type.toUpperCase()}: ${message.message}
|
|
2288
|
+
|
|
2289
|
+
`;
|
|
2290
|
+
}
|
|
2291
|
+
const color = message.type === "error" ? "red" : "#8B4000";
|
|
2292
|
+
return options?.html ? `<div class='luma-compiler-log-error' style="color:${color};"><b> ${message.type.toUpperCase()}: ${message.message}</b></div>` : `${message.type.toUpperCase()}: ${message.message}`;
|
|
2293
|
+
}
|
|
2294
|
+
function getNumberedLines(lines, lineNum, options) {
|
|
2295
|
+
let numberedLines = "";
|
|
2296
|
+
for (let lineIndex = lineNum - 2; lineIndex <= lineNum; lineIndex++) {
|
|
2297
|
+
const sourceLine = lines[lineIndex - 1];
|
|
2298
|
+
if (sourceLine !== void 0) {
|
|
2299
|
+
numberedLines += getNumberedLine(sourceLine, lineNum, options);
|
|
2300
|
+
}
|
|
2301
|
+
}
|
|
2302
|
+
return numberedLines;
|
|
2303
|
+
}
|
|
2304
|
+
function getNumberedLine(line, lineNum, options) {
|
|
2305
|
+
const escapedLine = options?.html ? escapeHTML(line) : line;
|
|
2306
|
+
return `${padLeft(String(lineNum), 4)}: ${escapedLine}${options?.html ? "<br/>" : "\n"}`;
|
|
2307
|
+
}
|
|
2308
|
+
function padLeft(string, paddedLength) {
|
|
2309
|
+
let result = "";
|
|
2310
|
+
for (let i = string.length; i < paddedLength; ++i) {
|
|
2311
|
+
result += " ";
|
|
2312
|
+
}
|
|
2313
|
+
return result + string;
|
|
2314
|
+
}
|
|
2315
|
+
function escapeHTML(unsafe) {
|
|
2316
|
+
return unsafe.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
2317
|
+
}
|
|
2318
|
+
|
|
2319
|
+
// ../core/src/adapter/resources/shader.ts
|
|
2320
|
+
var _Shader = class extends Resource {
|
|
2321
|
+
get [Symbol.toStringTag]() {
|
|
2322
|
+
return "Shader";
|
|
2323
|
+
}
|
|
2324
|
+
/** The stage of this shader */
|
|
2325
|
+
stage;
|
|
2326
|
+
/** The source code of this shader */
|
|
2327
|
+
source;
|
|
2328
|
+
/** The compilation status of the shader. 'pending' if compilation is asynchronous, and on production */
|
|
2329
|
+
compilationStatus = "pending";
|
|
2330
|
+
/** Create a new Shader instance */
|
|
2331
|
+
constructor(device, props) {
|
|
2332
|
+
props = { ...props, debugShaders: props.debugShaders || device.props.debugShaders || "errors" };
|
|
2333
|
+
super(device, { id: getShaderIdFromProps(props), ...props }, _Shader.defaultProps);
|
|
2334
|
+
this.stage = this.props.stage;
|
|
2335
|
+
this.source = this.props.source;
|
|
2336
|
+
}
|
|
2337
|
+
/** Get compiler log synchronously (WebGL only) */
|
|
2338
|
+
getCompilationInfoSync() {
|
|
2339
|
+
return null;
|
|
2340
|
+
}
|
|
2341
|
+
/** Get translated shader source in host platform's native language (HLSL, GLSL, and even GLSL ES), if available */
|
|
2342
|
+
getTranslatedSource() {
|
|
2343
|
+
return null;
|
|
2344
|
+
}
|
|
2345
|
+
// PORTABLE HELPERS
|
|
2346
|
+
/** In browser logging of errors */
|
|
2347
|
+
async debugShader() {
|
|
2348
|
+
const trigger = this.props.debugShaders;
|
|
2349
|
+
switch (trigger) {
|
|
2350
|
+
case "never":
|
|
2351
|
+
return;
|
|
2352
|
+
case "errors":
|
|
2353
|
+
if (this.compilationStatus === "success") {
|
|
2354
|
+
return;
|
|
2355
|
+
}
|
|
2356
|
+
break;
|
|
2357
|
+
case "warnings":
|
|
2358
|
+
case "always":
|
|
2359
|
+
break;
|
|
2360
|
+
}
|
|
2361
|
+
const messages = await this.getCompilationInfo();
|
|
2362
|
+
if (trigger === "warnings" && messages?.length === 0) {
|
|
2363
|
+
return;
|
|
2364
|
+
}
|
|
2365
|
+
this._displayShaderLog(messages);
|
|
2366
|
+
}
|
|
2367
|
+
// PRIVATE
|
|
2368
|
+
/**
|
|
2369
|
+
* In-browser UI logging of errors
|
|
2370
|
+
* TODO - this HTML formatting code should not be in Device, should be pluggable
|
|
2371
|
+
*/
|
|
2372
|
+
_displayShaderLog(messages) {
|
|
2373
|
+
if (typeof document === "undefined" || !document?.createElement) {
|
|
2374
|
+
return;
|
|
2375
|
+
}
|
|
2376
|
+
const shaderName = getShaderName(this.source);
|
|
2377
|
+
const shaderTitle = `${this.stage} ${shaderName}`;
|
|
2378
|
+
let htmlLog = formatCompilerLog(messages, this.source, { showSourceCode: "all", html: true });
|
|
2379
|
+
const translatedSource = this.getTranslatedSource();
|
|
2380
|
+
if (translatedSource) {
|
|
2381
|
+
htmlLog += `<br /><br /><h1>Translated Source</h1><br /><br /><code style="user-select:text;"><pre>${translatedSource}</pre></code>`;
|
|
2382
|
+
}
|
|
2383
|
+
const button = document.createElement("Button");
|
|
2384
|
+
button.innerHTML = `
|
|
2385
|
+
<h1>Shader Compilation Error in ${shaderTitle}</h1><br /><br />
|
|
2386
|
+
<code style="user-select:text;"><pre>
|
|
2387
|
+
${htmlLog}
|
|
2388
|
+
</pre></code>`;
|
|
2389
|
+
button.style.top = "10px";
|
|
2390
|
+
button.style.left = "10px";
|
|
2391
|
+
button.style.position = "absolute";
|
|
2392
|
+
button.style.zIndex = "9999";
|
|
2393
|
+
button.style.width = "100%";
|
|
2394
|
+
button.style.textAlign = "left";
|
|
2395
|
+
document.body.appendChild(button);
|
|
2396
|
+
const errors = document.getElementsByClassName("luma-compiler-log-error");
|
|
2397
|
+
errors[0]?.scrollIntoView();
|
|
2398
|
+
button.onclick = () => {
|
|
2399
|
+
const dataURI = `data:text/plain,${encodeURIComponent(this.source)}`;
|
|
2400
|
+
navigator.clipboard.writeText(dataURI);
|
|
2401
|
+
};
|
|
2402
|
+
}
|
|
2403
|
+
};
|
|
2404
|
+
var Shader = _Shader;
|
|
2405
|
+
__publicField(Shader, "defaultProps", {
|
|
2406
|
+
...Resource.defaultProps,
|
|
2407
|
+
language: "auto",
|
|
2408
|
+
stage: void 0,
|
|
2409
|
+
source: "",
|
|
2410
|
+
sourceMap: null,
|
|
2411
|
+
entryPoint: "main",
|
|
2412
|
+
debugShaders: void 0
|
|
2413
|
+
});
|
|
2414
|
+
function getShaderIdFromProps(props) {
|
|
2415
|
+
return getShaderName(props.source) || props.id || uid(`unnamed ${props.stage}-shader`);
|
|
2416
|
+
}
|
|
2417
|
+
function getShaderName(shader, defaultName = "unnamed") {
|
|
2418
|
+
const SHADER_NAME_REGEXP = /#define[\s*]SHADER_NAME[\s*]([A-Za-z0-9_-]+)[\s*]/;
|
|
2419
|
+
const match = SHADER_NAME_REGEXP.exec(shader);
|
|
2420
|
+
return match ? match[1] : defaultName;
|
|
2421
|
+
}
|
|
2422
|
+
|
|
2423
|
+
// ../core/src/adapter/resources/sampler.ts
|
|
2424
|
+
var _Sampler = class extends Resource {
|
|
2425
|
+
get [Symbol.toStringTag]() {
|
|
2426
|
+
return "Sampler";
|
|
2427
|
+
}
|
|
2428
|
+
constructor(device, props) {
|
|
2429
|
+
props = _Sampler.normalizeProps(device, props);
|
|
2430
|
+
super(device, props, _Sampler.defaultProps);
|
|
2431
|
+
}
|
|
2432
|
+
static normalizeProps(device, props) {
|
|
2433
|
+
const overriddenDefaultProps = device?.props?._resourceDefaults?.sampler || {};
|
|
2434
|
+
const newProps = { ...props, ...overriddenDefaultProps };
|
|
2435
|
+
return newProps;
|
|
2436
|
+
}
|
|
2437
|
+
};
|
|
2438
|
+
var Sampler = _Sampler;
|
|
2439
|
+
__publicField(Sampler, "defaultProps", {
|
|
2440
|
+
...Resource.defaultProps,
|
|
2441
|
+
type: "color-sampler",
|
|
2442
|
+
addressModeU: "clamp-to-edge",
|
|
2443
|
+
addressModeV: "clamp-to-edge",
|
|
2444
|
+
addressModeW: "clamp-to-edge",
|
|
2445
|
+
magFilter: "nearest",
|
|
2446
|
+
minFilter: "nearest",
|
|
2447
|
+
mipmapFilter: "none",
|
|
2448
|
+
lodMinClamp: 0,
|
|
2449
|
+
lodMaxClamp: 32,
|
|
2450
|
+
// Per WebGPU spec
|
|
2451
|
+
compare: "less-equal",
|
|
2452
|
+
maxAnisotropy: 1
|
|
2453
|
+
});
|
|
2454
|
+
|
|
2455
|
+
// ../core/src/adapter/resources/framebuffer.ts
|
|
2456
|
+
var _Framebuffer = class extends Resource {
|
|
2457
|
+
get [Symbol.toStringTag]() {
|
|
2458
|
+
return "Framebuffer";
|
|
2459
|
+
}
|
|
2460
|
+
/** Width of all attachments in this framebuffer */
|
|
2461
|
+
width;
|
|
2462
|
+
/** Height of all attachments in this framebuffer */
|
|
2463
|
+
height;
|
|
2464
|
+
constructor(device, props = {}) {
|
|
2465
|
+
super(device, props, _Framebuffer.defaultProps);
|
|
2466
|
+
this.width = this.props.width;
|
|
2467
|
+
this.height = this.props.height;
|
|
2468
|
+
}
|
|
2469
|
+
/**
|
|
2470
|
+
* Create a copy of this framebuffer with new attached textures, with same props but of the specified size.
|
|
2471
|
+
* @note Does not copy contents of the attached textures.
|
|
2472
|
+
*/
|
|
2473
|
+
clone(size) {
|
|
2474
|
+
const colorAttachments = this.colorAttachments.map(
|
|
2475
|
+
(colorAttachment) => colorAttachment.texture.clone(size)
|
|
2476
|
+
);
|
|
2477
|
+
const depthStencilAttachment = this.depthStencilAttachment && this.depthStencilAttachment.texture.clone(size);
|
|
2478
|
+
return this.device.createFramebuffer({ ...this.props, colorAttachments, depthStencilAttachment });
|
|
2479
|
+
}
|
|
2480
|
+
resize(size) {
|
|
2481
|
+
let updateSize = !size;
|
|
2482
|
+
if (size) {
|
|
2483
|
+
const [width, height] = Array.isArray(size) ? size : [size.width, size.height];
|
|
2484
|
+
updateSize = updateSize || height !== this.height || width !== this.width;
|
|
2485
|
+
this.width = width;
|
|
2486
|
+
this.height = height;
|
|
2487
|
+
}
|
|
2488
|
+
if (updateSize) {
|
|
2489
|
+
log.log(2, `Resizing framebuffer ${this.id} to ${this.width}x${this.height}`)();
|
|
2490
|
+
this.resizeAttachments(this.width, this.height);
|
|
2491
|
+
}
|
|
2492
|
+
}
|
|
2493
|
+
/** Auto creates any textures */
|
|
2494
|
+
autoCreateAttachmentTextures() {
|
|
2495
|
+
if (this.props.colorAttachments.length === 0 && !this.props.depthStencilAttachment) {
|
|
2496
|
+
throw new Error("Framebuffer has noattachments");
|
|
2497
|
+
}
|
|
2498
|
+
this.colorAttachments = this.props.colorAttachments.map((attachment2, index) => {
|
|
2499
|
+
if (typeof attachment2 === "string") {
|
|
2500
|
+
const texture = this.createColorTexture(attachment2, index);
|
|
2501
|
+
this.attachResource(texture);
|
|
2502
|
+
return texture.view;
|
|
2503
|
+
}
|
|
2504
|
+
if (attachment2 instanceof Texture) {
|
|
2505
|
+
return attachment2.view;
|
|
2506
|
+
}
|
|
2507
|
+
return attachment2;
|
|
2508
|
+
});
|
|
2509
|
+
const attachment = this.props.depthStencilAttachment;
|
|
2510
|
+
if (attachment) {
|
|
2511
|
+
if (typeof attachment === "string") {
|
|
2512
|
+
const texture = this.createDepthStencilTexture(attachment);
|
|
2513
|
+
this.attachResource(texture);
|
|
2514
|
+
this.depthStencilAttachment = texture.view;
|
|
2515
|
+
} else if (attachment instanceof Texture) {
|
|
2516
|
+
this.depthStencilAttachment = attachment.view;
|
|
2517
|
+
} else {
|
|
2518
|
+
this.depthStencilAttachment = attachment;
|
|
2519
|
+
}
|
|
2520
|
+
}
|
|
2521
|
+
}
|
|
2522
|
+
/** Create a color texture */
|
|
2523
|
+
createColorTexture(format, index) {
|
|
2524
|
+
return this.device.createTexture({
|
|
2525
|
+
id: `${this.id}-color-attachment-${index}`,
|
|
2526
|
+
usage: Texture.RENDER_ATTACHMENT,
|
|
2527
|
+
format,
|
|
2528
|
+
width: this.width,
|
|
2529
|
+
height: this.height,
|
|
2530
|
+
// TODO deprecated? - luma.gl v8 compatibility
|
|
2531
|
+
sampler: {
|
|
2532
|
+
magFilter: "linear",
|
|
2533
|
+
minFilter: "linear"
|
|
2534
|
+
}
|
|
2535
|
+
});
|
|
2536
|
+
}
|
|
2537
|
+
/** Create depth stencil texture */
|
|
2538
|
+
createDepthStencilTexture(format) {
|
|
2539
|
+
return this.device.createTexture({
|
|
2540
|
+
id: `${this.id}-depth-stencil-attachment`,
|
|
2541
|
+
usage: Texture.RENDER_ATTACHMENT,
|
|
2542
|
+
format,
|
|
2543
|
+
width: this.width,
|
|
2544
|
+
height: this.height,
|
|
2545
|
+
mipmaps: false
|
|
2546
|
+
});
|
|
2547
|
+
}
|
|
2548
|
+
/**
|
|
2549
|
+
* Default implementation of resize
|
|
2550
|
+
* Creates new textures with correct size for all attachments.
|
|
2551
|
+
* and destroys existing textures if owned
|
|
2552
|
+
*/
|
|
2553
|
+
resizeAttachments(width, height) {
|
|
2554
|
+
for (let i = 0; i < this.colorAttachments.length; ++i) {
|
|
2555
|
+
if (this.colorAttachments[i]) {
|
|
2556
|
+
const resizedTexture = this.colorAttachments[i].texture.clone({
|
|
2557
|
+
width,
|
|
2558
|
+
height
|
|
2559
|
+
});
|
|
2560
|
+
this.destroyAttachedResource(this.colorAttachments[i]);
|
|
2561
|
+
this.colorAttachments[i] = resizedTexture.view;
|
|
2562
|
+
this.attachResource(resizedTexture.view);
|
|
2563
|
+
}
|
|
2564
|
+
}
|
|
2565
|
+
if (this.depthStencilAttachment) {
|
|
2566
|
+
const resizedTexture = this.depthStencilAttachment.texture.clone({
|
|
2567
|
+
width,
|
|
2568
|
+
height
|
|
2569
|
+
});
|
|
2570
|
+
this.destroyAttachedResource(this.depthStencilAttachment);
|
|
2571
|
+
this.depthStencilAttachment = resizedTexture.view;
|
|
2572
|
+
this.attachResource(resizedTexture);
|
|
2573
|
+
}
|
|
2574
|
+
this.updateAttachments();
|
|
2575
|
+
}
|
|
2576
|
+
};
|
|
2577
|
+
var Framebuffer = _Framebuffer;
|
|
2578
|
+
__publicField(Framebuffer, "defaultProps", {
|
|
2579
|
+
...Resource.defaultProps,
|
|
2580
|
+
width: 1,
|
|
2581
|
+
height: 1,
|
|
2582
|
+
colorAttachments: [],
|
|
2583
|
+
// ['rgba8unorm'],
|
|
2584
|
+
depthStencilAttachment: null
|
|
2585
|
+
// 'depth24plus-stencil8'
|
|
2586
|
+
});
|
|
2587
|
+
|
|
2588
|
+
// ../core/src/adapter/resources/render-pipeline.ts
|
|
2589
|
+
var _RenderPipeline = class extends Resource {
|
|
2590
|
+
get [Symbol.toStringTag]() {
|
|
2591
|
+
return "RenderPipeline";
|
|
2592
|
+
}
|
|
2593
|
+
/** The merged layout */
|
|
2594
|
+
shaderLayout;
|
|
2595
|
+
/** Buffer map describing buffer interleaving etc */
|
|
2596
|
+
bufferLayout;
|
|
2597
|
+
/** The linking status of the pipeline. 'pending' if linking is asynchronous, and on production */
|
|
2598
|
+
linkStatus = "pending";
|
|
2599
|
+
/** The hash of the pipeline */
|
|
2600
|
+
hash = "";
|
|
2601
|
+
constructor(device, props) {
|
|
2602
|
+
super(device, props, _RenderPipeline.defaultProps);
|
|
2603
|
+
this.shaderLayout = this.props.shaderLayout;
|
|
2604
|
+
this.bufferLayout = this.props.bufferLayout || [];
|
|
2605
|
+
}
|
|
2606
|
+
// DEPRECATED METHODS
|
|
2607
|
+
/**
|
|
2608
|
+
* Uniforms
|
|
2609
|
+
* @deprecated Use uniforms buffers
|
|
2610
|
+
* @note textures, samplers and uniform buffers should be set via `setBindings()`, these are not considered uniforms.
|
|
2611
|
+
* @note In WebGL uniforms have a performance penalty, they are reset before each call to enable pipeline sharing.
|
|
2612
|
+
*/
|
|
2613
|
+
setUniformsWebGL(uniforms) {
|
|
2614
|
+
throw new Error("Use uniform blocks");
|
|
2615
|
+
}
|
|
2616
|
+
};
|
|
2617
|
+
var RenderPipeline = _RenderPipeline;
|
|
2618
|
+
__publicField(RenderPipeline, "defaultProps", {
|
|
2619
|
+
...Resource.defaultProps,
|
|
2620
|
+
vs: null,
|
|
2621
|
+
vertexEntryPoint: "vertexMain",
|
|
2622
|
+
vsConstants: {},
|
|
2623
|
+
fs: null,
|
|
2624
|
+
fragmentEntryPoint: "fragmentMain",
|
|
2625
|
+
fsConstants: {},
|
|
2626
|
+
shaderLayout: null,
|
|
2627
|
+
bufferLayout: [],
|
|
2628
|
+
topology: "triangle-list",
|
|
2629
|
+
colorAttachmentFormats: void 0,
|
|
2630
|
+
depthStencilAttachmentFormat: void 0,
|
|
2631
|
+
parameters: {},
|
|
2632
|
+
bindings: {},
|
|
2633
|
+
uniforms: {}
|
|
2634
|
+
});
|
|
2635
|
+
|
|
2636
|
+
// ../core/src/adapter/resources/render-pass.ts
|
|
2637
|
+
var _RenderPass = class extends Resource {
|
|
2638
|
+
get [Symbol.toStringTag]() {
|
|
2639
|
+
return "RenderPass";
|
|
2640
|
+
}
|
|
2641
|
+
constructor(device, props) {
|
|
2642
|
+
props = _RenderPass.normalizeProps(device, props);
|
|
2643
|
+
super(device, props, _RenderPass.defaultProps);
|
|
2644
|
+
}
|
|
2645
|
+
static normalizeProps(device, props) {
|
|
2646
|
+
const overriddenDefaultProps = device.props._resourceDefaults?.renderPass;
|
|
2647
|
+
const newProps = { ...overriddenDefaultProps, ...props };
|
|
2648
|
+
return newProps;
|
|
2649
|
+
}
|
|
2650
|
+
};
|
|
2651
|
+
var RenderPass = _RenderPass;
|
|
2652
|
+
/** TODO - should be [0, 0, 0, 0], update once deck.gl tests run clean */
|
|
2653
|
+
__publicField(RenderPass, "defaultClearColor", [0, 0, 0, 1]);
|
|
2654
|
+
/** Depth 1.0 represents the far plance */
|
|
2655
|
+
__publicField(RenderPass, "defaultClearDepth", 1);
|
|
2656
|
+
/** Clears all stencil bits */
|
|
2657
|
+
__publicField(RenderPass, "defaultClearStencil", 0);
|
|
2658
|
+
/** Default properties for RenderPass */
|
|
2659
|
+
__publicField(RenderPass, "defaultProps", {
|
|
2660
|
+
...Resource.defaultProps,
|
|
2661
|
+
framebuffer: null,
|
|
2662
|
+
parameters: void 0,
|
|
2663
|
+
clearColor: _RenderPass.defaultClearColor,
|
|
2664
|
+
clearColors: void 0,
|
|
2665
|
+
clearDepth: _RenderPass.defaultClearDepth,
|
|
2666
|
+
clearStencil: _RenderPass.defaultClearStencil,
|
|
2667
|
+
depthReadOnly: false,
|
|
2668
|
+
stencilReadOnly: false,
|
|
2669
|
+
discard: false,
|
|
2670
|
+
occlusionQuerySet: void 0,
|
|
2671
|
+
timestampQuerySet: void 0,
|
|
2672
|
+
beginTimestampIndex: void 0,
|
|
2673
|
+
endTimestampIndex: void 0
|
|
2674
|
+
});
|
|
2675
|
+
|
|
2676
|
+
// ../core/src/adapter/resources/compute-pipeline.ts
|
|
2677
|
+
var _ComputePipeline = class extends Resource {
|
|
2678
|
+
get [Symbol.toStringTag]() {
|
|
2679
|
+
return "ComputePipeline";
|
|
2680
|
+
}
|
|
2681
|
+
hash = "";
|
|
2682
|
+
/** The merged shader layout */
|
|
2683
|
+
shaderLayout;
|
|
2684
|
+
constructor(device, props) {
|
|
2685
|
+
super(device, props, _ComputePipeline.defaultProps);
|
|
2686
|
+
this.shaderLayout = props.shaderLayout;
|
|
2687
|
+
}
|
|
2688
|
+
};
|
|
2689
|
+
var ComputePipeline = _ComputePipeline;
|
|
2690
|
+
__publicField(ComputePipeline, "defaultProps", {
|
|
2691
|
+
...Resource.defaultProps,
|
|
2692
|
+
shader: void 0,
|
|
2693
|
+
entryPoint: void 0,
|
|
2694
|
+
constants: {},
|
|
2695
|
+
shaderLayout: void 0
|
|
2696
|
+
});
|
|
2697
|
+
|
|
2698
|
+
// ../core/src/adapter/resources/compute-pass.ts
|
|
2699
|
+
var _ComputePass = class extends Resource {
|
|
2700
|
+
get [Symbol.toStringTag]() {
|
|
2701
|
+
return "ComputePass";
|
|
2702
|
+
}
|
|
2703
|
+
constructor(device, props) {
|
|
2704
|
+
super(device, props, _ComputePass.defaultProps);
|
|
2705
|
+
}
|
|
2706
|
+
};
|
|
2707
|
+
var ComputePass = _ComputePass;
|
|
2708
|
+
__publicField(ComputePass, "defaultProps", {
|
|
2709
|
+
...Resource.defaultProps,
|
|
2710
|
+
timestampQuerySet: void 0,
|
|
2711
|
+
beginTimestampIndex: void 0,
|
|
2712
|
+
endTimestampIndex: void 0
|
|
2713
|
+
});
|
|
2714
|
+
|
|
2715
|
+
// ../core/src/adapter/resources/command-encoder.ts
|
|
2716
|
+
var _CommandEncoder = class extends Resource {
|
|
2717
|
+
get [Symbol.toStringTag]() {
|
|
2718
|
+
return "CommandEncoder";
|
|
2719
|
+
}
|
|
2720
|
+
constructor(device, props) {
|
|
2721
|
+
super(device, props, _CommandEncoder.defaultProps);
|
|
2722
|
+
}
|
|
2723
|
+
// TODO - luma.gl has these on the device, should we align with WebGPU API?
|
|
2724
|
+
// beginRenderPass(GPURenderPassDescriptor descriptor): GPURenderPassEncoder;
|
|
2725
|
+
// beginComputePass(optional GPUComputePassDescriptor descriptor = {}): GPUComputePassEncoder;
|
|
2726
|
+
};
|
|
2727
|
+
var CommandEncoder = _CommandEncoder;
|
|
2728
|
+
__publicField(CommandEncoder, "defaultProps", {
|
|
2729
|
+
...Resource.defaultProps,
|
|
2730
|
+
measureExecutionTime: void 0
|
|
2731
|
+
});
|
|
2732
|
+
|
|
2733
|
+
// ../core/src/adapter/resources/command-buffer.ts
|
|
2734
|
+
var _CommandBuffer = class extends Resource {
|
|
2735
|
+
get [Symbol.toStringTag]() {
|
|
2736
|
+
return "CommandBuffer";
|
|
2737
|
+
}
|
|
2738
|
+
constructor(device, props) {
|
|
2739
|
+
super(device, props, _CommandBuffer.defaultProps);
|
|
2740
|
+
}
|
|
2741
|
+
};
|
|
2742
|
+
var CommandBuffer = _CommandBuffer;
|
|
2743
|
+
__publicField(CommandBuffer, "defaultProps", {
|
|
2744
|
+
...Resource.defaultProps
|
|
2745
|
+
});
|
|
2746
|
+
|
|
2747
|
+
// ../core/src/gpu-type-utils/decode-attribute-type.ts
|
|
2748
|
+
function decodeShaderAttributeType(attributeType) {
|
|
2749
|
+
const [dataType, components] = TYPE_INFO[attributeType];
|
|
2750
|
+
const integer = dataType === "i32" || dataType === "u32";
|
|
2751
|
+
const signed = dataType !== "u32";
|
|
2752
|
+
const byteLength = TYPE_SIZES2[dataType] * components;
|
|
2753
|
+
const defaultVertexFormat = getCompatibleVertexFormat(dataType, components);
|
|
2754
|
+
return {
|
|
2755
|
+
dataType,
|
|
2756
|
+
components,
|
|
2757
|
+
defaultVertexFormat,
|
|
2758
|
+
byteLength,
|
|
2759
|
+
integer,
|
|
2760
|
+
signed
|
|
2761
|
+
};
|
|
2762
|
+
}
|
|
2763
|
+
function getCompatibleVertexFormat(dataType, components) {
|
|
2764
|
+
let vertexType;
|
|
2765
|
+
switch (dataType) {
|
|
2766
|
+
case "f32":
|
|
2767
|
+
vertexType = "float32";
|
|
2768
|
+
break;
|
|
2769
|
+
case "i32":
|
|
2770
|
+
vertexType = "sint32";
|
|
2771
|
+
break;
|
|
2772
|
+
case "u32":
|
|
2773
|
+
vertexType = "uint32";
|
|
2774
|
+
break;
|
|
2775
|
+
case "f16":
|
|
2776
|
+
return components <= 2 ? "float16x2" : "float16x4";
|
|
2777
|
+
}
|
|
2778
|
+
if (components === 1) {
|
|
2779
|
+
return vertexType;
|
|
2780
|
+
}
|
|
2781
|
+
return `${vertexType}x${components}`;
|
|
2782
|
+
}
|
|
2783
|
+
var TYPE_INFO = {
|
|
2784
|
+
f32: ["f32", 1],
|
|
2785
|
+
"vec2<f32>": ["f32", 2],
|
|
2786
|
+
"vec3<f32>": ["f32", 3],
|
|
2787
|
+
"vec4<f32>": ["f32", 4],
|
|
2788
|
+
f16: ["f16", 1],
|
|
2789
|
+
"vec2<f16>": ["f16", 2],
|
|
2790
|
+
"vec3<f16>": ["f16", 3],
|
|
2791
|
+
"vec4<f16>": ["f16", 4],
|
|
2792
|
+
i32: ["i32", 1],
|
|
2793
|
+
"vec2<i32>": ["i32", 2],
|
|
2794
|
+
"vec3<i32>": ["i32", 3],
|
|
2795
|
+
"vec4<i32>": ["i32", 4],
|
|
2796
|
+
u32: ["u32", 1],
|
|
2797
|
+
"vec2<u32>": ["u32", 2],
|
|
2798
|
+
"vec3<u32>": ["u32", 3],
|
|
2799
|
+
"vec4<u32>": ["u32", 4]
|
|
2800
|
+
};
|
|
2801
|
+
var TYPE_SIZES2 = {
|
|
2802
|
+
f32: 4,
|
|
2803
|
+
f16: 2,
|
|
2804
|
+
i32: 4,
|
|
2805
|
+
u32: 4
|
|
2806
|
+
// 'bool-webgl': 4,
|
|
2807
|
+
};
|
|
2808
|
+
|
|
2809
|
+
// ../core/src/gpu-type-utils/decode-vertex-format.ts
|
|
2810
|
+
function decodeVertexFormat(format) {
|
|
2811
|
+
let webglOnly;
|
|
2812
|
+
if (format.endsWith("-webgl")) {
|
|
2813
|
+
format.replace("-webgl", "");
|
|
2814
|
+
webglOnly = true;
|
|
2815
|
+
}
|
|
2816
|
+
const [type_, count] = format.split("x");
|
|
2817
|
+
const type = type_;
|
|
2818
|
+
const components = count ? parseInt(count) : 1;
|
|
2819
|
+
const decodedType = decodeVertexType(type);
|
|
2820
|
+
const result = {
|
|
2821
|
+
type,
|
|
2822
|
+
components,
|
|
2823
|
+
byteLength: decodedType.byteLength * components,
|
|
2824
|
+
integer: decodedType.integer,
|
|
2825
|
+
signed: decodedType.signed,
|
|
2826
|
+
normalized: decodedType.normalized
|
|
2827
|
+
};
|
|
2828
|
+
if (webglOnly) {
|
|
2829
|
+
result.webglOnly = true;
|
|
2830
|
+
}
|
|
2831
|
+
return result;
|
|
2832
|
+
}
|
|
2833
|
+
|
|
2834
|
+
// ../core/src/adapter-utils/get-attribute-from-layouts.ts
|
|
2835
|
+
function getAttributeInfosFromLayouts(shaderLayout, bufferLayout) {
|
|
2836
|
+
const attributeInfos = {};
|
|
2837
|
+
for (const attribute of shaderLayout.attributes) {
|
|
2838
|
+
const attributeInfo = getAttributeInfoFromLayouts(shaderLayout, bufferLayout, attribute.name);
|
|
2839
|
+
if (attributeInfo) {
|
|
2840
|
+
attributeInfos[attribute.name] = attributeInfo;
|
|
2841
|
+
}
|
|
2842
|
+
}
|
|
2843
|
+
return attributeInfos;
|
|
2844
|
+
}
|
|
2845
|
+
function getAttributeInfosByLocation(shaderLayout, bufferLayout, maxVertexAttributes = 16) {
|
|
2846
|
+
const attributeInfos = getAttributeInfosFromLayouts(shaderLayout, bufferLayout);
|
|
2847
|
+
const locationInfos = new Array(maxVertexAttributes).fill(null);
|
|
2848
|
+
for (const attributeInfo of Object.values(attributeInfos)) {
|
|
2849
|
+
locationInfos[attributeInfo.location] = attributeInfo;
|
|
2850
|
+
}
|
|
2851
|
+
return locationInfos;
|
|
2852
|
+
}
|
|
2853
|
+
function getAttributeInfoFromLayouts(shaderLayout, bufferLayout, name2) {
|
|
2854
|
+
const shaderDeclaration = getAttributeFromShaderLayout(shaderLayout, name2);
|
|
2855
|
+
const bufferMapping = getAttributeFromBufferLayout(
|
|
2856
|
+
bufferLayout,
|
|
2857
|
+
name2
|
|
2858
|
+
);
|
|
2859
|
+
if (!shaderDeclaration) {
|
|
2860
|
+
return null;
|
|
2861
|
+
}
|
|
2862
|
+
const attributeTypeInfo = decodeShaderAttributeType(shaderDeclaration.type);
|
|
2863
|
+
const vertexFormat = bufferMapping?.vertexFormat || attributeTypeInfo.defaultVertexFormat;
|
|
2864
|
+
const vertexFormatInfo = decodeVertexFormat(vertexFormat);
|
|
2865
|
+
return {
|
|
2866
|
+
attributeName: bufferMapping?.attributeName || shaderDeclaration.name,
|
|
2867
|
+
bufferName: bufferMapping?.bufferName || shaderDeclaration.name,
|
|
2868
|
+
location: shaderDeclaration.location,
|
|
2869
|
+
shaderType: shaderDeclaration.type,
|
|
2870
|
+
shaderDataType: attributeTypeInfo.dataType,
|
|
2871
|
+
shaderComponents: attributeTypeInfo.components,
|
|
2872
|
+
vertexFormat,
|
|
2873
|
+
bufferDataType: vertexFormatInfo.type,
|
|
2874
|
+
bufferComponents: vertexFormatInfo.components,
|
|
2875
|
+
// normalized is a property of the buffer's vertex format
|
|
2876
|
+
normalized: vertexFormatInfo.normalized,
|
|
2877
|
+
// integer is a property of the shader declaration
|
|
2878
|
+
integer: attributeTypeInfo.integer,
|
|
2879
|
+
stepMode: bufferMapping?.stepMode || shaderDeclaration.stepMode || "vertex",
|
|
2880
|
+
byteOffset: bufferMapping?.byteOffset || 0,
|
|
2881
|
+
byteStride: bufferMapping?.byteStride || 0
|
|
2882
|
+
};
|
|
2883
|
+
}
|
|
2884
|
+
function getAttributeFromShaderLayout(shaderLayout, name2) {
|
|
2885
|
+
const attribute = shaderLayout.attributes.find((attr) => attr.name === name2);
|
|
2886
|
+
if (!attribute) {
|
|
2887
|
+
log.warn(`shader layout attribute "${name2}" not present in shader`);
|
|
2888
|
+
}
|
|
2889
|
+
return attribute || null;
|
|
2890
|
+
}
|
|
2891
|
+
function getAttributeFromBufferLayout(bufferLayouts, name2) {
|
|
2892
|
+
checkBufferLayouts(bufferLayouts);
|
|
2893
|
+
let bufferLayoutInfo = getAttributeFromShortHand(bufferLayouts, name2);
|
|
2894
|
+
if (bufferLayoutInfo) {
|
|
2895
|
+
return bufferLayoutInfo;
|
|
2896
|
+
}
|
|
2897
|
+
bufferLayoutInfo = getAttributeFromAttributesList(bufferLayouts, name2);
|
|
2898
|
+
if (bufferLayoutInfo) {
|
|
2899
|
+
return bufferLayoutInfo;
|
|
2900
|
+
}
|
|
2901
|
+
log.warn(`layout for attribute "${name2}" not present in buffer layout`);
|
|
2902
|
+
return null;
|
|
2903
|
+
}
|
|
2904
|
+
function checkBufferLayouts(bufferLayouts) {
|
|
2905
|
+
for (const bufferLayout of bufferLayouts) {
|
|
2906
|
+
if (bufferLayout.attributes && bufferLayout.format || !bufferLayout.attributes && !bufferLayout.format) {
|
|
2907
|
+
log.warn(`BufferLayout ${name} must have either 'attributes' or 'format' field`);
|
|
2908
|
+
}
|
|
2909
|
+
}
|
|
2910
|
+
}
|
|
2911
|
+
function getAttributeFromShortHand(bufferLayouts, name2) {
|
|
2912
|
+
for (const bufferLayout of bufferLayouts) {
|
|
2913
|
+
if (bufferLayout.format && bufferLayout.name === name2) {
|
|
2914
|
+
return {
|
|
2915
|
+
attributeName: bufferLayout.name,
|
|
2916
|
+
bufferName: name2,
|
|
2917
|
+
stepMode: bufferLayout.stepMode,
|
|
2918
|
+
vertexFormat: bufferLayout.format,
|
|
2919
|
+
// If offset is needed, use `attributes` field.
|
|
2920
|
+
byteOffset: 0,
|
|
2921
|
+
byteStride: bufferLayout.byteStride || 0
|
|
2922
|
+
};
|
|
2923
|
+
}
|
|
2924
|
+
}
|
|
2925
|
+
return null;
|
|
2926
|
+
}
|
|
2927
|
+
function getAttributeFromAttributesList(bufferLayouts, name2) {
|
|
2928
|
+
for (const bufferLayout of bufferLayouts) {
|
|
2929
|
+
let byteStride = bufferLayout.byteStride;
|
|
2930
|
+
if (typeof bufferLayout.byteStride !== "number") {
|
|
2931
|
+
for (const attributeMapping2 of bufferLayout.attributes || []) {
|
|
2932
|
+
const info = decodeVertexFormat(attributeMapping2.format);
|
|
2933
|
+
byteStride += info.byteLength;
|
|
2934
|
+
}
|
|
2935
|
+
}
|
|
2936
|
+
const attributeMapping = bufferLayout.attributes?.find((mapping) => mapping.attribute === name2);
|
|
2937
|
+
if (attributeMapping) {
|
|
2938
|
+
return {
|
|
2939
|
+
attributeName: attributeMapping.attribute,
|
|
2940
|
+
bufferName: bufferLayout.name,
|
|
2941
|
+
stepMode: bufferLayout.stepMode,
|
|
2942
|
+
vertexFormat: attributeMapping.format,
|
|
2943
|
+
byteOffset: attributeMapping.byteOffset,
|
|
2944
|
+
// @ts-ignore
|
|
2945
|
+
byteStride
|
|
2946
|
+
};
|
|
2947
|
+
}
|
|
2948
|
+
}
|
|
2949
|
+
return null;
|
|
2950
|
+
}
|
|
2951
|
+
|
|
2952
|
+
// ../core/src/adapter/resources/vertex-array.ts
|
|
2953
|
+
var _VertexArray = class extends Resource {
|
|
2954
|
+
get [Symbol.toStringTag]() {
|
|
2955
|
+
return "VertexArray";
|
|
2956
|
+
}
|
|
2957
|
+
/** Max number of vertex attributes */
|
|
2958
|
+
maxVertexAttributes;
|
|
2959
|
+
/** Attribute infos indexed by location - TODO only needed by webgl module? */
|
|
2960
|
+
attributeInfos;
|
|
2961
|
+
/** Index buffer */
|
|
2962
|
+
indexBuffer = null;
|
|
2963
|
+
/** Attributes indexed by buffer slot */
|
|
2964
|
+
attributes;
|
|
2965
|
+
constructor(device, props) {
|
|
2966
|
+
super(device, props, _VertexArray.defaultProps);
|
|
2967
|
+
this.maxVertexAttributes = device.limits.maxVertexAttributes;
|
|
2968
|
+
this.attributes = new Array(this.maxVertexAttributes).fill(null);
|
|
2969
|
+
this.attributeInfos = getAttributeInfosByLocation(
|
|
2970
|
+
props.shaderLayout,
|
|
2971
|
+
props.bufferLayout,
|
|
2972
|
+
this.maxVertexAttributes
|
|
2973
|
+
);
|
|
2974
|
+
}
|
|
2975
|
+
// DEPRECATED METHODS
|
|
2976
|
+
/** @deprecated Set constant attributes (WebGL only) */
|
|
2977
|
+
setConstantWebGL(location, value) {
|
|
2978
|
+
throw new Error("constant attributes not supported");
|
|
2979
|
+
}
|
|
2980
|
+
};
|
|
2981
|
+
var VertexArray = _VertexArray;
|
|
2982
|
+
__publicField(VertexArray, "defaultProps", {
|
|
2983
|
+
...Resource.defaultProps,
|
|
2984
|
+
shaderLayout: void 0,
|
|
2985
|
+
bufferLayout: []
|
|
2986
|
+
});
|
|
2987
|
+
|
|
2988
|
+
// ../core/src/adapter/resources/transform-feedback.ts
|
|
2989
|
+
var _TransformFeedback = class extends Resource {
|
|
2990
|
+
get [Symbol.toStringTag]() {
|
|
2991
|
+
return "TransformFeedback";
|
|
2992
|
+
}
|
|
2993
|
+
constructor(device, props) {
|
|
2994
|
+
super(device, props, _TransformFeedback.defaultProps);
|
|
2995
|
+
}
|
|
2996
|
+
};
|
|
2997
|
+
var TransformFeedback = _TransformFeedback;
|
|
2998
|
+
__publicField(TransformFeedback, "defaultProps", {
|
|
2999
|
+
...Resource.defaultProps,
|
|
3000
|
+
layout: void 0,
|
|
3001
|
+
buffers: {}
|
|
3002
|
+
});
|
|
3003
|
+
|
|
3004
|
+
// ../core/src/adapter/resources/query-set.ts
|
|
3005
|
+
var _QuerySet = class extends Resource {
|
|
3006
|
+
get [Symbol.toStringTag]() {
|
|
3007
|
+
return "QuerySet";
|
|
3008
|
+
}
|
|
3009
|
+
constructor(device, props) {
|
|
3010
|
+
super(device, props, _QuerySet.defaultProps);
|
|
3011
|
+
}
|
|
3012
|
+
};
|
|
3013
|
+
var QuerySet = _QuerySet;
|
|
3014
|
+
__publicField(QuerySet, "defaultProps", {
|
|
3015
|
+
...Resource.defaultProps,
|
|
3016
|
+
type: void 0,
|
|
3017
|
+
count: void 0
|
|
3018
|
+
});
|
|
3019
|
+
|
|
3020
|
+
// ../core/src/gpu-type-utils/decode-shader-types.ts
|
|
3021
|
+
var UNIFORM_FORMATS = {
|
|
3022
|
+
f32: { type: "f32", components: 1 },
|
|
3023
|
+
i32: { type: "i32", components: 1 },
|
|
3024
|
+
u32: { type: "u32", components: 1 },
|
|
3025
|
+
// 'bool-webgl': {type: 'bool-webgl', components: 1},
|
|
3026
|
+
"vec2<f32>": { type: "f32", components: 2 },
|
|
3027
|
+
"vec3<f32>": { type: "f32", components: 3 },
|
|
3028
|
+
"vec4<f32>": { type: "f32", components: 4 },
|
|
3029
|
+
"vec2<i32>": { type: "i32", components: 2 },
|
|
3030
|
+
"vec3<i32>": { type: "i32", components: 3 },
|
|
3031
|
+
"vec4<i32>": { type: "i32", components: 4 },
|
|
3032
|
+
"vec2<u32>": { type: "u32", components: 2 },
|
|
3033
|
+
"vec3<u32>": { type: "u32", components: 3 },
|
|
3034
|
+
"vec4<u32>": { type: "u32", components: 4 },
|
|
3035
|
+
"mat2x2<f32>": { type: "f32", components: 4 },
|
|
3036
|
+
"mat2x3<f32>": { type: "f32", components: 6 },
|
|
3037
|
+
"mat2x4<f32>": { type: "f32", components: 8 },
|
|
3038
|
+
"mat3x2<f32>": { type: "f32", components: 6 },
|
|
3039
|
+
"mat3x3<f32>": { type: "f32", components: 9 },
|
|
3040
|
+
"mat3x4<f32>": { type: "f32", components: 12 },
|
|
3041
|
+
"mat4x2<f32>": { type: "f32", components: 8 },
|
|
3042
|
+
"mat4x3<f32>": { type: "f32", components: 12 },
|
|
3043
|
+
"mat4x4<f32>": { type: "f32", components: 16 }
|
|
3044
|
+
};
|
|
3045
|
+
function decodeShaderUniformType(format) {
|
|
3046
|
+
const decoded = UNIFORM_FORMATS[format];
|
|
3047
|
+
return decoded;
|
|
3048
|
+
}
|
|
3049
|
+
function alignTo(size, count) {
|
|
3050
|
+
switch (count) {
|
|
3051
|
+
case 1:
|
|
3052
|
+
return size;
|
|
3053
|
+
case 2:
|
|
3054
|
+
return size + size % 2;
|
|
3055
|
+
default:
|
|
3056
|
+
return size + (4 - size % 4) % 4;
|
|
3057
|
+
}
|
|
3058
|
+
}
|
|
3059
|
+
|
|
3060
|
+
// ../core/src/utils/array-utils-flat.ts
|
|
3061
|
+
var arrayBuffer;
|
|
3062
|
+
function getScratchArrayBuffer(byteLength) {
|
|
3063
|
+
if (!arrayBuffer || arrayBuffer.byteLength < byteLength) {
|
|
3064
|
+
arrayBuffer = new ArrayBuffer(byteLength);
|
|
3065
|
+
}
|
|
3066
|
+
return arrayBuffer;
|
|
3067
|
+
}
|
|
3068
|
+
function getScratchArray(Type, length) {
|
|
3069
|
+
const scratchArrayBuffer = getScratchArrayBuffer(Type.BYTES_PER_ELEMENT * length);
|
|
3070
|
+
return new Type(scratchArrayBuffer, 0, length);
|
|
3071
|
+
}
|
|
3072
|
+
|
|
3073
|
+
// ../core/src/utils/is-array.ts
|
|
3074
|
+
function isTypedArray(value) {
|
|
3075
|
+
return ArrayBuffer.isView(value) && !(value instanceof DataView);
|
|
3076
|
+
}
|
|
3077
|
+
function isNumberArray(value) {
|
|
3078
|
+
if (Array.isArray(value)) {
|
|
3079
|
+
return value.length === 0 || typeof value[0] === "number";
|
|
3080
|
+
}
|
|
3081
|
+
return isTypedArray(value);
|
|
3082
|
+
}
|
|
3083
|
+
|
|
3084
|
+
// ../core/src/portable/uniform-buffer-layout.ts
|
|
3085
|
+
var minBufferSize = 1024;
|
|
3086
|
+
var UniformBufferLayout = class {
|
|
3087
|
+
layout = {};
|
|
3088
|
+
/** number of bytes needed for buffer allocation */
|
|
3089
|
+
byteLength;
|
|
3090
|
+
/** Create a new UniformBufferLayout given a map of attributes. */
|
|
3091
|
+
constructor(uniformTypes) {
|
|
3092
|
+
let size = 0;
|
|
3093
|
+
for (const [key, uniformType] of Object.entries(uniformTypes)) {
|
|
3094
|
+
const typeAndComponents = decodeShaderUniformType(uniformType);
|
|
3095
|
+
const { type, components: count } = typeAndComponents;
|
|
3096
|
+
size = alignTo(size, count);
|
|
3097
|
+
const offset = size;
|
|
3098
|
+
size += count;
|
|
3099
|
+
this.layout[key] = { type, size: count, offset };
|
|
3100
|
+
}
|
|
3101
|
+
size += (4 - size % 4) % 4;
|
|
3102
|
+
const actualByteLength = size * 4;
|
|
3103
|
+
this.byteLength = Math.max(actualByteLength, minBufferSize);
|
|
3104
|
+
}
|
|
3105
|
+
/** Get the data for the complete buffer */
|
|
3106
|
+
getData(uniformValues) {
|
|
3107
|
+
const bufferSize = Math.max(this.byteLength, minBufferSize);
|
|
3108
|
+
const arrayBuffer2 = getScratchArrayBuffer(bufferSize);
|
|
3109
|
+
const typedArrays = {
|
|
3110
|
+
i32: new Int32Array(arrayBuffer2),
|
|
3111
|
+
u32: new Uint32Array(arrayBuffer2),
|
|
3112
|
+
f32: new Float32Array(arrayBuffer2),
|
|
3113
|
+
// TODO not implemented
|
|
3114
|
+
f16: new Uint16Array(arrayBuffer2)
|
|
3115
|
+
};
|
|
3116
|
+
for (const [name2, value] of Object.entries(uniformValues)) {
|
|
3117
|
+
const uniformLayout = this.layout[name2];
|
|
3118
|
+
if (!uniformLayout) {
|
|
3119
|
+
log.warn(`Supplied uniform value ${name2} not present in uniform block layout`)();
|
|
3120
|
+
continue;
|
|
3121
|
+
}
|
|
3122
|
+
const { type, size, offset } = uniformLayout;
|
|
3123
|
+
const typedArray = typedArrays[type];
|
|
3124
|
+
if (size === 1) {
|
|
3125
|
+
if (typeof value !== "number" && typeof value !== "boolean") {
|
|
3126
|
+
log.warn(
|
|
3127
|
+
`Supplied value for single component uniform ${name2} is not a number: ${value}`
|
|
3128
|
+
)();
|
|
3129
|
+
continue;
|
|
3130
|
+
}
|
|
3131
|
+
typedArray[offset] = Number(value);
|
|
3132
|
+
} else {
|
|
3133
|
+
if (!isNumberArray(value)) {
|
|
3134
|
+
log.warn(
|
|
3135
|
+
`Supplied value for multi component / array uniform ${name2} is not a numeric array: ${value}`
|
|
3136
|
+
)();
|
|
3137
|
+
continue;
|
|
3138
|
+
}
|
|
3139
|
+
typedArray.set(value, offset);
|
|
3140
|
+
}
|
|
3141
|
+
}
|
|
3142
|
+
return new Uint8Array(arrayBuffer2);
|
|
3143
|
+
}
|
|
3144
|
+
/** Does this layout have a field with specified name */
|
|
3145
|
+
has(name2) {
|
|
3146
|
+
return Boolean(this.layout[name2]);
|
|
3147
|
+
}
|
|
3148
|
+
/** Get offset and size for a field with specified name */
|
|
3149
|
+
get(name2) {
|
|
3150
|
+
const layout = this.layout[name2];
|
|
3151
|
+
return layout;
|
|
3152
|
+
}
|
|
3153
|
+
};
|
|
3154
|
+
|
|
3155
|
+
// ../core/src/utils/array-equal.ts
|
|
3156
|
+
function arrayEqual(a, b, limit = 16) {
|
|
3157
|
+
if (a !== b) {
|
|
3158
|
+
return false;
|
|
3159
|
+
}
|
|
3160
|
+
const arrayA = a;
|
|
3161
|
+
const arrayB = b;
|
|
3162
|
+
if (!isNumberArray(arrayA)) {
|
|
3163
|
+
return false;
|
|
3164
|
+
}
|
|
3165
|
+
if (isNumberArray(arrayB) && arrayA.length === arrayB.length) {
|
|
3166
|
+
for (let i = 0; i < arrayA.length; ++i) {
|
|
3167
|
+
if (arrayB[i] !== arrayA[i]) {
|
|
3168
|
+
return false;
|
|
3169
|
+
}
|
|
3170
|
+
}
|
|
3171
|
+
}
|
|
3172
|
+
return true;
|
|
3173
|
+
}
|
|
3174
|
+
function arrayCopy(a) {
|
|
3175
|
+
if (isNumberArray(a)) {
|
|
3176
|
+
return a.slice();
|
|
3177
|
+
}
|
|
3178
|
+
return a;
|
|
3179
|
+
}
|
|
3180
|
+
|
|
3181
|
+
// ../core/src/portable/uniform-block.ts
|
|
3182
|
+
var UniformBlock = class {
|
|
3183
|
+
name;
|
|
3184
|
+
uniforms = {};
|
|
3185
|
+
modifiedUniforms = {};
|
|
3186
|
+
modified = true;
|
|
3187
|
+
bindingLayout = {};
|
|
3188
|
+
needsRedraw = "initialized";
|
|
3189
|
+
constructor(props) {
|
|
3190
|
+
this.name = props?.name || "unnamed";
|
|
3191
|
+
if (props?.name && props?.shaderLayout) {
|
|
3192
|
+
const binding = props?.shaderLayout.bindings?.find(
|
|
3193
|
+
(binding_) => binding_.type === "uniform" && binding_.name === props?.name
|
|
3194
|
+
);
|
|
3195
|
+
if (!binding) {
|
|
3196
|
+
throw new Error(props?.name);
|
|
3197
|
+
}
|
|
3198
|
+
const uniformBlock = binding;
|
|
3199
|
+
for (const uniform of uniformBlock.uniforms || []) {
|
|
3200
|
+
this.bindingLayout[uniform.name] = uniform;
|
|
3201
|
+
}
|
|
3202
|
+
}
|
|
3203
|
+
}
|
|
3204
|
+
/** Set a map of uniforms */
|
|
3205
|
+
setUniforms(uniforms) {
|
|
3206
|
+
for (const [key, value] of Object.entries(uniforms)) {
|
|
3207
|
+
this._setUniform(key, value);
|
|
3208
|
+
if (!this.needsRedraw) {
|
|
3209
|
+
this.setNeedsRedraw(`${this.name}.${key}=${value}`);
|
|
3210
|
+
}
|
|
3211
|
+
}
|
|
3212
|
+
}
|
|
3213
|
+
setNeedsRedraw(reason) {
|
|
3214
|
+
this.needsRedraw = this.needsRedraw || reason;
|
|
3215
|
+
}
|
|
3216
|
+
/** Returns all uniforms */
|
|
3217
|
+
getAllUniforms() {
|
|
3218
|
+
this.modifiedUniforms = {};
|
|
3219
|
+
this.needsRedraw = false;
|
|
3220
|
+
return this.uniforms || {};
|
|
3221
|
+
}
|
|
3222
|
+
/** Set a single uniform */
|
|
3223
|
+
_setUniform(key, value) {
|
|
3224
|
+
if (arrayEqual(this.uniforms[key], value)) {
|
|
3225
|
+
return;
|
|
3226
|
+
}
|
|
3227
|
+
this.uniforms[key] = arrayCopy(value);
|
|
3228
|
+
this.modifiedUniforms[key] = true;
|
|
3229
|
+
this.modified = true;
|
|
3230
|
+
}
|
|
3231
|
+
};
|
|
3232
|
+
|
|
3233
|
+
// ../core/src/portable/uniform-store.ts
|
|
3234
|
+
var UniformStore = class {
|
|
3235
|
+
/** Stores the uniform values for each uniform block */
|
|
3236
|
+
uniformBlocks = /* @__PURE__ */ new Map();
|
|
3237
|
+
/** Can generate data for a uniform buffer for each block from data */
|
|
3238
|
+
uniformBufferLayouts = /* @__PURE__ */ new Map();
|
|
3239
|
+
/** Actual buffer for the blocks */
|
|
3240
|
+
uniformBuffers = /* @__PURE__ */ new Map();
|
|
3241
|
+
/**
|
|
3242
|
+
* Create a new UniformStore instance
|
|
3243
|
+
* @param blocks
|
|
3244
|
+
*/
|
|
3245
|
+
constructor(blocks) {
|
|
3246
|
+
for (const [bufferName, block] of Object.entries(blocks)) {
|
|
3247
|
+
const uniformBufferName = bufferName;
|
|
3248
|
+
const uniformBufferLayout = new UniformBufferLayout(block.uniformTypes || {});
|
|
3249
|
+
this.uniformBufferLayouts.set(uniformBufferName, uniformBufferLayout);
|
|
3250
|
+
const uniformBlock = new UniformBlock({ name: bufferName });
|
|
3251
|
+
uniformBlock.setUniforms(block.defaultUniforms || {});
|
|
3252
|
+
this.uniformBlocks.set(uniformBufferName, uniformBlock);
|
|
3253
|
+
}
|
|
3254
|
+
}
|
|
3255
|
+
/** Destroy any managed uniform buffers */
|
|
3256
|
+
destroy() {
|
|
3257
|
+
for (const uniformBuffer of this.uniformBuffers.values()) {
|
|
3258
|
+
uniformBuffer.destroy();
|
|
3259
|
+
}
|
|
3260
|
+
}
|
|
3261
|
+
/**
|
|
3262
|
+
* Set uniforms
|
|
3263
|
+
* Makes all properties partial
|
|
3264
|
+
*/
|
|
3265
|
+
setUniforms(uniforms) {
|
|
3266
|
+
for (const [blockName, uniformValues] of Object.entries(uniforms)) {
|
|
3267
|
+
this.uniformBlocks.get(blockName)?.setUniforms(uniformValues);
|
|
3268
|
+
}
|
|
3269
|
+
this.updateUniformBuffers();
|
|
3270
|
+
}
|
|
3271
|
+
/** Get the required minimum length of the uniform buffer */
|
|
3272
|
+
getUniformBufferByteLength(uniformBufferName) {
|
|
3273
|
+
return this.uniformBufferLayouts.get(uniformBufferName)?.byteLength || 0;
|
|
3274
|
+
}
|
|
3275
|
+
/** Get formatted binary memory that can be uploaded to a buffer */
|
|
3276
|
+
getUniformBufferData(uniformBufferName) {
|
|
3277
|
+
const uniformValues = this.uniformBlocks.get(uniformBufferName)?.getAllUniforms() || {};
|
|
3278
|
+
return this.uniformBufferLayouts.get(uniformBufferName)?.getData(uniformValues);
|
|
3279
|
+
}
|
|
3280
|
+
/**
|
|
3281
|
+
* Creates an unmanaged uniform buffer (umnanaged means that application is responsible for destroying it)
|
|
3282
|
+
* The new buffer is initialized with current / supplied values
|
|
3283
|
+
*/
|
|
3284
|
+
createUniformBuffer(device, uniformBufferName, uniforms) {
|
|
3285
|
+
if (uniforms) {
|
|
3286
|
+
this.setUniforms(uniforms);
|
|
3287
|
+
}
|
|
3288
|
+
const byteLength = this.getUniformBufferByteLength(uniformBufferName);
|
|
3289
|
+
const uniformBuffer = device.createBuffer({
|
|
3290
|
+
usage: Buffer2.UNIFORM | Buffer2.COPY_DST,
|
|
3291
|
+
byteLength
|
|
3292
|
+
});
|
|
3293
|
+
const uniformBufferData = this.getUniformBufferData(uniformBufferName);
|
|
3294
|
+
uniformBuffer.write(uniformBufferData);
|
|
3295
|
+
return uniformBuffer;
|
|
3296
|
+
}
|
|
3297
|
+
/** Get the managed uniform buffer. "managed" resources are destroyed when the uniformStore is destroyed. */
|
|
3298
|
+
getManagedUniformBuffer(device, uniformBufferName) {
|
|
3299
|
+
if (!this.uniformBuffers.get(uniformBufferName)) {
|
|
3300
|
+
const byteLength = this.getUniformBufferByteLength(uniformBufferName);
|
|
3301
|
+
const uniformBuffer = device.createBuffer({
|
|
3302
|
+
usage: Buffer2.UNIFORM | Buffer2.COPY_DST,
|
|
3303
|
+
byteLength
|
|
3304
|
+
});
|
|
3305
|
+
this.uniformBuffers.set(uniformBufferName, uniformBuffer);
|
|
3306
|
+
}
|
|
3307
|
+
return this.uniformBuffers.get(uniformBufferName);
|
|
3308
|
+
}
|
|
3309
|
+
/** Updates all uniform buffers where values have changed */
|
|
3310
|
+
updateUniformBuffers() {
|
|
3311
|
+
let reason = false;
|
|
3312
|
+
for (const uniformBufferName of this.uniformBlocks.keys()) {
|
|
3313
|
+
const bufferReason = this.updateUniformBuffer(uniformBufferName);
|
|
3314
|
+
reason ||= bufferReason;
|
|
3315
|
+
}
|
|
3316
|
+
if (reason) {
|
|
3317
|
+
log.log(3, `UniformStore.updateUniformBuffers(): ${reason}`)();
|
|
3318
|
+
}
|
|
3319
|
+
return reason;
|
|
3320
|
+
}
|
|
3321
|
+
/** Update one uniform buffer. Only updates if values have changed */
|
|
3322
|
+
updateUniformBuffer(uniformBufferName) {
|
|
3323
|
+
const uniformBlock = this.uniformBlocks.get(uniformBufferName);
|
|
3324
|
+
let uniformBuffer = this.uniformBuffers.get(uniformBufferName);
|
|
3325
|
+
let reason = false;
|
|
3326
|
+
if (uniformBuffer && uniformBlock?.needsRedraw) {
|
|
3327
|
+
reason ||= uniformBlock.needsRedraw;
|
|
3328
|
+
const uniformBufferData = this.getUniformBufferData(uniformBufferName);
|
|
3329
|
+
uniformBuffer = this.uniformBuffers.get(uniformBufferName);
|
|
3330
|
+
uniformBuffer?.write(uniformBufferData);
|
|
3331
|
+
const uniformValues = this.uniformBlocks.get(uniformBufferName)?.getAllUniforms();
|
|
3332
|
+
log.log(
|
|
3333
|
+
4,
|
|
3334
|
+
`Writing to uniform buffer ${String(uniformBufferName)}`,
|
|
3335
|
+
uniformBufferData,
|
|
3336
|
+
uniformValues
|
|
3337
|
+
)();
|
|
3338
|
+
}
|
|
3339
|
+
return reason;
|
|
3340
|
+
}
|
|
3341
|
+
};
|
|
3342
|
+
|
|
3343
|
+
// ../core/src/gpu-type-utils/vertex-format-from-attribute.ts
|
|
3344
|
+
function getDataTypeFromTypedArray(arrayOrType) {
|
|
3345
|
+
const type = ArrayBuffer.isView(arrayOrType) ? arrayOrType.constructor : arrayOrType;
|
|
3346
|
+
switch (type) {
|
|
3347
|
+
case Float32Array:
|
|
3348
|
+
return "float32";
|
|
3349
|
+
case Uint16Array:
|
|
3350
|
+
return "uint16";
|
|
3351
|
+
case Uint32Array:
|
|
3352
|
+
return "uint32";
|
|
3353
|
+
case Uint8Array:
|
|
3354
|
+
case Uint8ClampedArray:
|
|
3355
|
+
return "uint8";
|
|
3356
|
+
case Int8Array:
|
|
3357
|
+
return "sint8";
|
|
3358
|
+
case Int16Array:
|
|
3359
|
+
return "sint16";
|
|
3360
|
+
case Int32Array:
|
|
3361
|
+
return "sint32";
|
|
3362
|
+
default:
|
|
3363
|
+
throw new Error(type.constructor.name);
|
|
3364
|
+
}
|
|
3365
|
+
}
|
|
3366
|
+
function getTypedArrayFromDataType(dataType) {
|
|
3367
|
+
switch (dataType) {
|
|
3368
|
+
case "float32":
|
|
3369
|
+
return Float32Array;
|
|
3370
|
+
case "uint32":
|
|
3371
|
+
return Uint32Array;
|
|
3372
|
+
case "sint32":
|
|
3373
|
+
return Int32Array;
|
|
3374
|
+
case "uint16":
|
|
3375
|
+
case "unorm16":
|
|
3376
|
+
return Uint16Array;
|
|
3377
|
+
case "sint16":
|
|
3378
|
+
case "snorm16":
|
|
3379
|
+
return Int16Array;
|
|
3380
|
+
case "uint8":
|
|
3381
|
+
case "unorm8":
|
|
3382
|
+
return Uint8Array;
|
|
3383
|
+
case "sint8":
|
|
3384
|
+
case "snorm8":
|
|
3385
|
+
return Int8Array;
|
|
3386
|
+
default:
|
|
3387
|
+
throw new Error(dataType);
|
|
3388
|
+
}
|
|
3389
|
+
}
|
|
3390
|
+
function getVertexFormatFromAttribute(typedArray, size, normalized) {
|
|
3391
|
+
if (!size || size > 4) {
|
|
3392
|
+
throw new Error(`size ${size}`);
|
|
3393
|
+
}
|
|
3394
|
+
const components = size;
|
|
3395
|
+
let dataType = getDataTypeFromTypedArray(typedArray);
|
|
3396
|
+
if (dataType === "uint8" && normalized && components === 1) {
|
|
3397
|
+
return "unorm8-webgl";
|
|
3398
|
+
}
|
|
3399
|
+
if (dataType === "uint8" && normalized && components === 3) {
|
|
3400
|
+
return "unorm8x3-webgl";
|
|
3401
|
+
}
|
|
3402
|
+
if (dataType === "uint8" || dataType === "sint8") {
|
|
3403
|
+
if (components === 1 || components === 3) {
|
|
3404
|
+
throw new Error(`size: ${size}`);
|
|
3405
|
+
}
|
|
3406
|
+
if (normalized) {
|
|
3407
|
+
dataType = dataType.replace("int", "norm");
|
|
3408
|
+
}
|
|
3409
|
+
return `${dataType}x${components}`;
|
|
3410
|
+
}
|
|
3411
|
+
if (dataType === "uint16" || dataType === "sint16") {
|
|
3412
|
+
if (components === 1 || components === 3) {
|
|
3413
|
+
throw new Error(`size: ${size}`);
|
|
3414
|
+
}
|
|
3415
|
+
if (normalized) {
|
|
3416
|
+
dataType = dataType.replace("int", "norm");
|
|
3417
|
+
}
|
|
3418
|
+
return `${dataType}x${components}`;
|
|
3419
|
+
}
|
|
3420
|
+
if (components === 1) {
|
|
3421
|
+
return dataType;
|
|
3422
|
+
}
|
|
3423
|
+
return `${dataType}x${components}`;
|
|
3424
|
+
}
|
|
3425
|
+
|
|
3426
|
+
// ../core/src/adapter-utils/buffer-layout-helper.ts
|
|
3427
|
+
var BufferLayoutHelper = class {
|
|
3428
|
+
bufferLayouts;
|
|
3429
|
+
constructor(bufferLayouts) {
|
|
3430
|
+
this.bufferLayouts = bufferLayouts;
|
|
3431
|
+
}
|
|
3432
|
+
getBufferLayout(name2) {
|
|
3433
|
+
return this.bufferLayouts.find((layout) => layout.name === name2) || null;
|
|
3434
|
+
}
|
|
3435
|
+
/** Get attribute names from a BufferLayout */
|
|
3436
|
+
getAttributeNamesForBuffer(bufferLayout) {
|
|
3437
|
+
return bufferLayout.attributes ? bufferLayout.attributes?.map((layout) => layout.attribute) : [bufferLayout.name];
|
|
3438
|
+
}
|
|
3439
|
+
mergeBufferLayouts(bufferLayouts1, bufferLayouts2) {
|
|
3440
|
+
const mergedLayouts = [...bufferLayouts1];
|
|
3441
|
+
for (const attribute of bufferLayouts2) {
|
|
3442
|
+
const index = mergedLayouts.findIndex((attribute2) => attribute2.name === attribute.name);
|
|
3443
|
+
if (index < 0) {
|
|
3444
|
+
mergedLayouts.push(attribute);
|
|
3445
|
+
} else {
|
|
3446
|
+
mergedLayouts[index] = attribute;
|
|
3447
|
+
}
|
|
3448
|
+
}
|
|
3449
|
+
return mergedLayouts;
|
|
3450
|
+
}
|
|
3451
|
+
};
|
|
3452
|
+
|
|
3453
|
+
// bundle.ts
|
|
3454
|
+
__reExport(bundle_exports, __toESM(require_shadertools(), 1));
|
|
3455
|
+
return __toCommonJS(bundle_exports);
|
|
3456
|
+
})();
|
|
3457
|
+
return __exports__;
|
|
3458
|
+
});
|