@363045841yyt/klinechart-core 0.9.0-alpha.0 → 0.9.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/controllers/createChartController.d.ts.map +1 -1
- package/dist/controllers/createChartController.js +31 -13
- package/dist/controllers/createChartController.js.map +1 -1
- package/dist/controllers/index.d.ts +1 -0
- package/dist/controllers/index.d.ts.map +1 -1
- package/dist/controllers/index.js.map +1 -1
- package/dist/controllers/types.d.ts +12 -0
- package/dist/controllers/types.d.ts.map +1 -1
- package/dist/engine/chart.d.ts +29 -11
- package/dist/engine/chart.d.ts.map +1 -1
- package/dist/engine/chart.js +147 -25
- package/dist/engine/chart.js.map +1 -1
- package/dist/engine/controller/interaction.d.ts +29 -4
- package/dist/engine/controller/interaction.d.ts.map +1 -1
- package/dist/engine/controller/interaction.js +78 -31
- package/dist/engine/controller/interaction.js.map +1 -1
- package/dist/engine/data/incrementalLoadHint.d.ts.map +1 -1
- package/dist/engine/data/incrementalLoadHint.js +5 -1
- package/dist/engine/data/incrementalLoadHint.js.map +1 -1
- package/dist/engine/drawing/DrawingState.d.ts +19 -34
- package/dist/engine/drawing/DrawingState.d.ts.map +1 -1
- package/dist/engine/drawing/DrawingState.js +110 -92
- package/dist/engine/drawing/DrawingState.js.map +1 -1
- package/dist/engine/drawing/index.d.ts +4 -1
- package/dist/engine/drawing/index.d.ts.map +1 -1
- package/dist/engine/drawing/index.js +9 -4
- package/dist/engine/drawing/index.js.map +1 -1
- package/dist/engine/drawing/interaction.d.ts +9 -29
- package/dist/engine/drawing/interaction.d.ts.map +1 -1
- package/dist/engine/drawing/interaction.js +23 -40
- package/dist/engine/drawing/interaction.js.map +1 -1
- package/dist/engine/indicators/chartIndicatorManager.d.ts.map +1 -1
- package/dist/engine/indicators/chartIndicatorManager.js +4 -12
- package/dist/engine/indicators/chartIndicatorManager.js.map +1 -1
- package/dist/engine/layout/chartPaneLayout.d.ts +0 -2
- package/dist/engine/layout/chartPaneLayout.d.ts.map +1 -1
- package/dist/engine/layout/chartPaneLayout.js +5 -9
- package/dist/engine/layout/chartPaneLayout.js.map +1 -1
- package/dist/engine/layout/pane.d.ts +0 -39
- package/dist/engine/layout/pane.d.ts.map +1 -1
- package/dist/engine/layout/pane.js +0 -9
- package/dist/engine/layout/pane.js.map +1 -1
- package/dist/engine/paneRenderer.d.ts +1 -10
- package/dist/engine/paneRenderer.d.ts.map +1 -1
- package/dist/engine/paneRenderer.js +2 -19
- package/dist/engine/paneRenderer.js.map +1 -1
- package/dist/engine/render/chartRenderer.d.ts +49 -8
- package/dist/engine/render/chartRenderer.d.ts.map +1 -1
- package/dist/engine/render/chartRenderer.js +143 -72
- package/dist/engine/render/chartRenderer.js.map +1 -1
- package/dist/engine/renderers/Indicator/atr.js +3 -13
- package/dist/engine/renderers/Indicator/atr.js.map +1 -1
- package/dist/engine/renderers/Indicator/boll.d.ts.map +1 -1
- package/dist/engine/renderers/Indicator/boll.js +12 -24
- package/dist/engine/renderers/Indicator/boll.js.map +1 -1
- package/dist/engine/renderers/Indicator/cci.js +6 -13
- package/dist/engine/renderers/Indicator/cci.js.map +1 -1
- package/dist/engine/renderers/Indicator/chaikinVol.js +3 -11
- package/dist/engine/renderers/Indicator/chaikinVol.js.map +1 -1
- package/dist/engine/renderers/Indicator/cmf.js +3 -11
- package/dist/engine/renderers/Indicator/cmf.js.map +1 -1
- package/dist/engine/renderers/Indicator/dema.js +3 -11
- package/dist/engine/renderers/Indicator/dema.js.map +1 -1
- package/dist/engine/renderers/Indicator/donchian.js +3 -11
- package/dist/engine/renderers/Indicator/donchian.js.map +1 -1
- package/dist/engine/renderers/Indicator/ene.d.ts.map +1 -1
- package/dist/engine/renderers/Indicator/ene.js +12 -24
- package/dist/engine/renderers/Indicator/ene.js.map +1 -1
- package/dist/engine/renderers/Indicator/expma.d.ts.map +1 -1
- package/dist/engine/renderers/Indicator/expma.js +5 -11
- package/dist/engine/renderers/Indicator/expma.js.map +1 -1
- package/dist/engine/renderers/Indicator/fastk.js +6 -13
- package/dist/engine/renderers/Indicator/fastk.js.map +1 -1
- package/dist/engine/renderers/Indicator/fib.js +3 -11
- package/dist/engine/renderers/Indicator/fib.js.map +1 -1
- package/dist/engine/renderers/Indicator/hma.js +3 -11
- package/dist/engine/renderers/Indicator/hma.js.map +1 -1
- package/dist/engine/renderers/Indicator/hv.js +3 -11
- package/dist/engine/renderers/Indicator/hv.js.map +1 -1
- package/dist/engine/renderers/Indicator/ichimoku.js +24 -18
- package/dist/engine/renderers/Indicator/ichimoku.js.map +1 -1
- package/dist/engine/renderers/Indicator/kama.js +3 -11
- package/dist/engine/renderers/Indicator/kama.js.map +1 -1
- package/dist/engine/renderers/Indicator/keltner.js +3 -11
- package/dist/engine/renderers/Indicator/keltner.js.map +1 -1
- package/dist/engine/renderers/Indicator/kst.js +9 -17
- package/dist/engine/renderers/Indicator/kst.js.map +1 -1
- package/dist/engine/renderers/Indicator/ma.d.ts.map +1 -1
- package/dist/engine/renderers/Indicator/ma.js +10 -21
- package/dist/engine/renderers/Indicator/ma.js.map +1 -1
- package/dist/engine/renderers/Indicator/macd.js +14 -44
- package/dist/engine/renderers/Indicator/macd.js.map +1 -1
- package/dist/engine/renderers/Indicator/mfi.js +3 -11
- package/dist/engine/renderers/Indicator/mfi.js.map +1 -1
- package/dist/engine/renderers/Indicator/mom.js +6 -13
- package/dist/engine/renderers/Indicator/mom.js.map +1 -1
- package/dist/engine/renderers/Indicator/obv.js +3 -11
- package/dist/engine/renderers/Indicator/obv.js.map +1 -1
- package/dist/engine/renderers/Indicator/parkinson.js +3 -11
- package/dist/engine/renderers/Indicator/parkinson.js.map +1 -1
- package/dist/engine/renderers/Indicator/pvt.js +3 -11
- package/dist/engine/renderers/Indicator/pvt.js.map +1 -1
- package/dist/engine/renderers/Indicator/roc.js +3 -11
- package/dist/engine/renderers/Indicator/roc.js.map +1 -1
- package/dist/engine/renderers/Indicator/rsi.js +12 -20
- package/dist/engine/renderers/Indicator/rsi.js.map +1 -1
- package/dist/engine/renderers/Indicator/shared/webglBand.d.ts +0 -2
- package/dist/engine/renderers/Indicator/shared/webglBand.d.ts.map +1 -1
- package/dist/engine/renderers/Indicator/shared/webglBand.js +0 -6
- package/dist/engine/renderers/Indicator/shared/webglBand.js.map +1 -1
- package/dist/engine/renderers/Indicator/stoch.js +9 -17
- package/dist/engine/renderers/Indicator/stoch.js.map +1 -1
- package/dist/engine/renderers/Indicator/tema.js +3 -11
- package/dist/engine/renderers/Indicator/tema.js.map +1 -1
- package/dist/engine/renderers/Indicator/trix.js +3 -11
- package/dist/engine/renderers/Indicator/trix.js.map +1 -1
- package/dist/engine/renderers/Indicator/vma.js +3 -11
- package/dist/engine/renderers/Indicator/vma.js.map +1 -1
- package/dist/engine/renderers/Indicator/vwap.js +3 -11
- package/dist/engine/renderers/Indicator/vwap.js.map +1 -1
- package/dist/engine/renderers/Indicator/wma.js +3 -11
- package/dist/engine/renderers/Indicator/wma.js.map +1 -1
- package/dist/engine/renderers/Indicator/wmsr.js +6 -13
- package/dist/engine/renderers/Indicator/wmsr.js.map +1 -1
- package/dist/engine/renderers/candle.d.ts.map +1 -1
- package/dist/engine/renderers/candle.js +21 -28
- package/dist/engine/renderers/candle.js.map +1 -1
- package/dist/engine/renderers/candleViaRenderer.d.ts +19 -0
- package/dist/engine/renderers/candleViaRenderer.d.ts.map +1 -0
- package/dist/engine/renderers/candleViaRenderer.js +15 -0
- package/dist/engine/renderers/candleViaRenderer.js.map +1 -0
- package/dist/engine/renderers/linesViaRenderer.d.ts +55 -0
- package/dist/engine/renderers/linesViaRenderer.d.ts.map +1 -0
- package/dist/engine/renderers/linesViaRenderer.js +169 -0
- package/dist/engine/renderers/linesViaRenderer.js.map +1 -0
- package/dist/engine/renderers/rectsViaRenderer.d.ts +18 -0
- package/dist/engine/renderers/rectsViaRenderer.d.ts.map +1 -0
- package/dist/engine/renderers/rectsViaRenderer.js +63 -0
- package/dist/engine/renderers/rectsViaRenderer.js.map +1 -0
- package/dist/engine/renderers/subVolume.js +7 -26
- package/dist/engine/renderers/subVolume.js.map +1 -1
- package/dist/engine/renderers/timeAxis.js +1 -1
- package/dist/engine/renderers/timeAxis.js.map +1 -1
- package/dist/engine/state/chartStateKernel.d.ts +11 -2
- package/dist/engine/state/chartStateKernel.d.ts.map +1 -1
- package/dist/engine/state/chartStateKernel.js +28 -12
- package/dist/engine/state/chartStateKernel.js.map +1 -1
- package/dist/engine/state/index.d.ts +1 -1
- package/dist/engine/state/index.d.ts.map +1 -1
- package/dist/engine/state/index.js +1 -1
- package/dist/engine/state/index.js.map +1 -1
- package/dist/engine/state/interactionState.d.ts +15 -7
- package/dist/engine/state/interactionState.d.ts.map +1 -1
- package/dist/engine/state/interactionState.js +55 -60
- package/dist/engine/state/interactionState.js.map +1 -1
- package/dist/engine/state/rendererState.d.ts +14 -0
- package/dist/engine/state/rendererState.d.ts.map +1 -0
- package/dist/engine/state/rendererState.js +25 -0
- package/dist/engine/state/rendererState.js.map +1 -0
- package/dist/engine/state/themeState.d.ts +11 -4
- package/dist/engine/state/themeState.d.ts.map +1 -1
- package/dist/engine/state/themeState.js +13 -5
- package/dist/engine/state/themeState.js.map +1 -1
- package/dist/engine/state/viewportState.d.ts.map +1 -1
- package/dist/engine/state/viewportState.js +7 -3
- package/dist/engine/state/viewportState.js.map +1 -1
- package/dist/engine/subPaneManager.d.ts.map +1 -1
- package/dist/engine/subPaneManager.js +2 -10
- package/dist/engine/subPaneManager.js.map +1 -1
- package/dist/foundation/config/chartSettings.d.ts +16 -4
- package/dist/foundation/config/chartSettings.d.ts.map +1 -1
- package/dist/foundation/config/chartSettings.js +21 -6
- package/dist/foundation/config/chartSettings.js.map +1 -1
- package/dist/foundation/plugin/index.d.ts +0 -1
- package/dist/foundation/plugin/index.d.ts.map +1 -1
- package/dist/foundation/plugin/rendererPluginManager.d.ts +1 -22
- package/dist/foundation/plugin/rendererPluginManager.d.ts.map +1 -1
- package/dist/foundation/plugin/rendererPluginManager.js +0 -84
- package/dist/foundation/plugin/rendererPluginManager.js.map +1 -1
- package/dist/foundation/plugin/types.d.ts +11 -17
- package/dist/foundation/plugin/types.d.ts.map +1 -1
- package/dist/foundation/plugin/types.js.map +1 -1
- package/dist/foundation/reactivity/frameTransaction.d.ts +71 -0
- package/dist/foundation/reactivity/frameTransaction.d.ts.map +1 -0
- package/dist/foundation/reactivity/frameTransaction.js +170 -0
- package/dist/foundation/reactivity/frameTransaction.js.map +1 -0
- package/dist/foundation/reactivity/index.d.ts +4 -2
- package/dist/foundation/reactivity/index.d.ts.map +1 -1
- package/dist/foundation/reactivity/index.js +2 -1
- package/dist/foundation/reactivity/index.js.map +1 -1
- package/dist/foundation/reactivity/signal.d.ts +20 -0
- package/dist/foundation/reactivity/signal.d.ts.map +1 -1
- package/dist/foundation/reactivity/signal.js +27 -0
- package/dist/foundation/reactivity/signal.js.map +1 -1
- package/dist/foundation/tokens/theme-dark.d.ts.map +1 -1
- package/dist/foundation/tokens/theme-dark.js +2 -1
- package/dist/foundation/tokens/theme-dark.js.map +1 -1
- package/dist/foundation/tokens/theme-light.d.ts.map +1 -1
- package/dist/foundation/tokens/theme-light.js +2 -1
- package/dist/foundation/tokens/theme-light.js.map +1 -1
- package/dist/rendering/render/Renderer.d.ts +29 -14
- package/dist/rendering/render/Renderer.d.ts.map +1 -1
- package/dist/rendering/render/Renderer.js +3 -10
- package/dist/rendering/render/Renderer.js.map +1 -1
- package/dist/rendering/render/SurfaceBackend.d.ts +5 -7
- package/dist/rendering/render/SurfaceBackend.d.ts.map +1 -1
- package/dist/rendering/render/SurfaceBackend.js +5 -7
- package/dist/rendering/render/SurfaceBackend.js.map +1 -1
- package/dist/rendering/render/createCanvas2DRenderer.d.ts +3 -0
- package/dist/rendering/render/createCanvas2DRenderer.d.ts.map +1 -0
- package/dist/rendering/render/createCanvas2DRenderer.js +74 -0
- package/dist/rendering/render/createCanvas2DRenderer.js.map +1 -0
- package/dist/rendering/render/createDefaultRendererHost.d.ts +4 -0
- package/dist/rendering/render/createDefaultRendererHost.d.ts.map +1 -0
- package/dist/rendering/render/createDefaultRendererHost.js +54 -0
- package/dist/rendering/render/createDefaultRendererHost.js.map +1 -0
- package/dist/rendering/render/createWebGLRenderer.d.ts.map +1 -1
- package/dist/rendering/render/createWebGLRenderer.js +42 -80
- package/dist/rendering/render/createWebGLRenderer.js.map +1 -1
- package/dist/rendering/render/createWebGPURenderer.d.ts +11 -0
- package/dist/rendering/render/createWebGPURenderer.d.ts.map +1 -0
- package/dist/rendering/render/createWebGPURenderer.js +619 -0
- package/dist/rendering/render/createWebGPURenderer.js.map +1 -0
- package/dist/rendering/render/createWebGPUSurfaceBackend.d.ts +15 -0
- package/dist/rendering/render/createWebGPUSurfaceBackend.d.ts.map +1 -0
- package/dist/rendering/render/createWebGPUSurfaceBackend.js +92 -0
- package/dist/rendering/render/createWebGPUSurfaceBackend.js.map +1 -0
- package/dist/rendering/render/frameMetrics.d.ts +19 -0
- package/dist/rendering/render/frameMetrics.d.ts.map +1 -0
- package/dist/rendering/render/frameMetrics.js +43 -0
- package/dist/rendering/render/frameMetrics.js.map +1 -0
- package/dist/rendering/render/index.d.ts +10 -0
- package/dist/rendering/render/index.d.ts.map +1 -1
- package/dist/rendering/render/index.js +6 -0
- package/dist/rendering/render/index.js.map +1 -1
- package/dist/rendering/render/rendererHost.d.ts +34 -0
- package/dist/rendering/render/rendererHost.d.ts.map +1 -0
- package/dist/rendering/render/rendererHost.js +144 -0
- package/dist/rendering/render/rendererHost.js.map +1 -0
- package/dist/rendering/render/webgpuResourceTable.d.ts +25 -0
- package/dist/rendering/render/webgpuResourceTable.d.ts.map +1 -0
- package/dist/rendering/render/webgpuResourceTable.js +54 -0
- package/dist/rendering/render/webgpuResourceTable.js.map +1 -0
- package/dist/rendering/scene/createLayerFromPlugin.d.ts.map +1 -1
- package/dist/rendering/scene/createLayerFromPlugin.js +10 -2
- package/dist/rendering/scene/createLayerFromPlugin.js.map +1 -1
- package/dist/rendering/scene/layerRegistry.d.ts +3 -5
- package/dist/rendering/scene/layerRegistry.d.ts.map +1 -1
- package/dist/rendering/scene/layerRegistry.js +1 -1
- package/dist/rendering/scene/layerRegistry.js.map +1 -1
- package/dist/rendering/scene/retainedScene.d.ts +60 -0
- package/dist/rendering/scene/retainedScene.d.ts.map +1 -0
- package/dist/rendering/scene/retainedScene.js +42 -0
- package/dist/rendering/scene/retainedScene.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -1
- package/src/__tests__/signal.test.ts +47 -1
- package/src/controllers/__tests__/createChartController.theme.test.ts +102 -0
- package/src/controllers/createChartController.ts +36 -12
- package/src/controllers/index.ts +5 -0
- package/src/controllers/types.ts +14 -0
- package/src/engine/__tests__/chart.dpr.test.ts +64 -0
- package/src/engine/__tests__/paneRenderer.resize.test.ts +0 -7
- package/src/engine/__tests__/renderSinglePath.test.ts +121 -0
- package/src/engine/chart.ts +172 -25
- package/src/engine/controller/__tests__/interaction.dpr.test.ts +45 -41
- package/src/engine/controller/interaction.ts +81 -30
- package/src/engine/data/__tests__/chartDataManager.incrementalLoad.test.ts +1 -0
- package/src/engine/data/incrementalLoadHint.ts +6 -1
- package/src/engine/drawing/DrawingState.ts +107 -89
- package/src/engine/drawing/__tests__/drawingState.workCopy.test.ts +95 -36
- package/src/engine/drawing/__tests__/drawingStore.projection.test.ts +22 -0
- package/src/engine/drawing/index.ts +12 -4
- package/src/engine/drawing/interaction.ts +25 -40
- package/src/engine/indicators/chartIndicatorManager.ts +6 -16
- package/src/engine/layout/chartPaneLayout.ts +6 -11
- package/src/engine/layout/pane.ts +0 -44
- package/src/engine/paneRenderer.ts +3 -34
- package/src/engine/render/chartRenderer.ts +181 -81
- package/src/engine/renderers/Indicator/atr.ts +5 -17
- package/src/engine/renderers/Indicator/boll.ts +15 -26
- package/src/engine/renderers/Indicator/cci.ts +7 -17
- package/src/engine/renderers/Indicator/chaikinVol.ts +3 -15
- package/src/engine/renderers/Indicator/cmf.ts +3 -15
- package/src/engine/renderers/Indicator/dema.ts +3 -15
- package/src/engine/renderers/Indicator/donchian.ts +3 -12
- package/src/engine/renderers/Indicator/ene.ts +15 -25
- package/src/engine/renderers/Indicator/expma.ts +4 -13
- package/src/engine/renderers/Indicator/fastk.ts +7 -17
- package/src/engine/renderers/Indicator/fib.ts +3 -12
- package/src/engine/renderers/Indicator/hma.ts +3 -15
- package/src/engine/renderers/Indicator/hv.ts +3 -15
- package/src/engine/renderers/Indicator/ichimoku.ts +21 -24
- package/src/engine/renderers/Indicator/kama.ts +3 -15
- package/src/engine/renderers/Indicator/keltner.ts +3 -12
- package/src/engine/renderers/Indicator/kst.ts +9 -20
- package/src/engine/renderers/Indicator/ma.ts +9 -21
- package/src/engine/renderers/Indicator/macd.ts +27 -102
- package/src/engine/renderers/Indicator/mfi.ts +3 -15
- package/src/engine/renderers/Indicator/mom.ts +7 -17
- package/src/engine/renderers/Indicator/obv.ts +3 -15
- package/src/engine/renderers/Indicator/parkinson.ts +3 -15
- package/src/engine/renderers/Indicator/pvt.ts +3 -15
- package/src/engine/renderers/Indicator/roc.ts +3 -15
- package/src/engine/renderers/Indicator/rsi.ts +12 -23
- package/src/engine/renderers/Indicator/shared/webglBand.ts +0 -13
- package/src/engine/renderers/Indicator/stoch.ts +9 -20
- package/src/engine/renderers/Indicator/tema.ts +3 -15
- package/src/engine/renderers/Indicator/trix.ts +3 -12
- package/src/engine/renderers/Indicator/vma.ts +3 -15
- package/src/engine/renderers/Indicator/vwap.ts +3 -15
- package/src/engine/renderers/Indicator/wma.ts +3 -15
- package/src/engine/renderers/Indicator/wmsr.ts +7 -17
- package/src/engine/renderers/__tests__/candle.sceneRenderer.test.ts +208 -0
- package/src/engine/renderers/__tests__/candleViaRenderer.test.ts +100 -0
- package/src/engine/renderers/__tests__/linesViaRenderer.test.ts +263 -0
- package/src/engine/renderers/__tests__/rectsViaRenderer.test.ts +87 -0
- package/src/engine/renderers/candle.ts +26 -69
- package/src/engine/renderers/candleViaRenderer.ts +38 -0
- package/src/engine/renderers/linesViaRenderer.ts +226 -0
- package/src/engine/renderers/rectsViaRenderer.ts +83 -0
- package/src/engine/renderers/subVolume.ts +9 -61
- package/src/engine/renderers/timeAxis.ts +1 -1
- package/src/engine/state/__tests__/effectiveTheme.test.ts +49 -0
- package/src/engine/state/__tests__/rendererState.test.ts +36 -0
- package/src/engine/state/__tests__/settingsState.test.ts +1 -1
- package/src/engine/state/chartStateKernel.ts +38 -17
- package/src/engine/state/index.ts +6 -1
- package/src/engine/state/interactionState.ts +73 -102
- package/src/engine/state/rendererState.ts +32 -0
- package/src/engine/state/themeState.ts +15 -8
- package/src/engine/state/viewportState.ts +6 -3
- package/src/engine/subPaneManager.ts +2 -16
- package/src/foundation/config/__tests__/chartSettings.test.ts +25 -0
- package/src/foundation/config/chartSettings.ts +24 -7
- package/src/foundation/plugin/index.ts +0 -1
- package/src/foundation/plugin/rendererPluginManager.ts +0 -99
- package/src/foundation/plugin/types.ts +11 -18
- package/src/foundation/reactivity/__tests__/frameTransaction.test.ts +306 -0
- package/src/foundation/reactivity/frameTransaction.ts +239 -0
- package/src/foundation/reactivity/index.ts +8 -0
- package/src/foundation/reactivity/signal.ts +39 -0
- package/src/foundation/tokens/__tests__/__snapshots__/baseline.test.ts.snap +2 -2
- package/src/foundation/tokens/theme-dark.ts +2 -1
- package/src/foundation/tokens/theme-light.ts +2 -1
- package/src/rendering/render/Renderer.ts +27 -14
- package/src/rendering/render/SurfaceBackend.ts +5 -7
- package/src/rendering/render/__tests__/canvas2DRenderer.test.ts +34 -0
- package/src/rendering/render/__tests__/contract.test.ts +2 -2
- package/src/rendering/render/__tests__/frameMetrics.test.ts +24 -0
- package/src/rendering/render/__tests__/rendererHost.test.ts +157 -0
- package/src/rendering/render/__tests__/webglRenderer.fallback.test.ts +14 -74
- package/src/rendering/render/__tests__/webglRenderer.test.ts +64 -6
- package/src/rendering/render/__tests__/webgpuRenderer.test.ts +370 -0
- package/src/rendering/render/__tests__/webgpuResourceTable.test.ts +62 -0
- package/src/rendering/render/__tests__/webgpuSurfaceBackend.test.ts +120 -0
- package/src/rendering/render/createCanvas2DRenderer.ts +83 -0
- package/src/rendering/render/createDefaultRendererHost.ts +74 -0
- package/src/rendering/render/createWebGLRenderer.ts +41 -87
- package/src/rendering/render/createWebGPURenderer.ts +677 -0
- package/src/rendering/render/createWebGPUSurfaceBackend.ts +106 -0
- package/src/rendering/render/frameMetrics.ts +54 -0
- package/src/rendering/render/index.ts +30 -0
- package/src/rendering/render/rendererHost.ts +210 -0
- package/src/rendering/render/webgpuResourceTable.ts +87 -0
- package/src/rendering/scene/__tests__/layerFromPlugin.test.ts +29 -2
- package/src/rendering/scene/__tests__/retainedScene.test.ts +59 -0
- package/src/rendering/scene/createLayerFromPlugin.ts +9 -2
- package/src/rendering/scene/layerRegistry.ts +4 -6
- package/src/rendering/scene/retainedScene.ts +101 -0
- package/src/version.ts +1 -1
|
@@ -2,12 +2,9 @@
|
|
|
2
2
|
* High-level renderer interface — the drawing primitives the chart's
|
|
3
3
|
* scene layers (candles, volume, indicators, drawings) call into.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* be refactored to fit behind it in a follow-up PR (this file ships
|
|
9
|
-
* the contract first; the legacy code is unchanged until the next
|
|
10
|
-
* step is approved).
|
|
5
|
+
* WebGL (`createWebGLRenderer`) implements this contract today; P1 WebGPU
|
|
6
|
+
* will implement the same surface. Call sites only use sceneRenderer
|
|
7
|
+
* (fail-closed boolean → Canvas2D), never dual-path surfaces.
|
|
11
8
|
*
|
|
12
9
|
* Design notes:
|
|
13
10
|
* - `drawInstances` is the workhorse: render N copies of a unit geometry
|
|
@@ -22,10 +19,6 @@
|
|
|
22
19
|
* - `setUniforms` is intentionally schemaless on the interface — the
|
|
23
20
|
* uniform layout is owned by each shader/program. Callers pass a
|
|
24
21
|
* structured object that the backend translates into uniform writes.
|
|
25
|
-
*
|
|
26
|
-
* This file is **pure interface** in this PR; behaviour comes in the
|
|
27
|
-
* next two PRs (Scale interfaces, then a Renderer impl that wraps
|
|
28
|
-
* the existing WebGL primitives).
|
|
29
22
|
*/
|
|
30
23
|
|
|
31
24
|
import type { SurfaceBackend, SurfaceRegion } from './SurfaceBackend'
|
|
@@ -65,12 +58,24 @@ export type DrawInstancesParams = {
|
|
|
65
58
|
uniforms?: Record<string, unknown>
|
|
66
59
|
}
|
|
67
60
|
|
|
61
|
+
export type DrawLineStrip = {
|
|
62
|
+
points: ReadonlyArray<{ x: number; y: number }>
|
|
63
|
+
color: string
|
|
64
|
+
width?: number
|
|
65
|
+
}
|
|
66
|
+
|
|
68
67
|
export type DrawLinesParams = {
|
|
69
68
|
pipeline: PipelineHandle
|
|
70
|
-
|
|
71
|
-
|
|
69
|
+
/**
|
|
70
|
+
* 单 strip 路径:vertices 为交错 x,y Float32。
|
|
71
|
+
* 若提供 strips,则忽略 vertices/vertexCount,一次 GPU 提交多条(避免 MSAA 逐条 clear)。
|
|
72
|
+
*/
|
|
73
|
+
vertices?: BufferHandle
|
|
74
|
+
vertexCount?: number
|
|
72
75
|
/** Line strip vs disconnected segments. */
|
|
73
76
|
topology?: 'strip' | 'list'
|
|
77
|
+
/** 多色折线批量(推荐 MA 等多周期) */
|
|
78
|
+
strips?: ReadonlyArray<DrawLineStrip>
|
|
74
79
|
uniforms?: Record<string, unknown>
|
|
75
80
|
}
|
|
76
81
|
|
|
@@ -117,8 +122,16 @@ export interface Renderer {
|
|
|
117
122
|
// --- frame ---
|
|
118
123
|
|
|
119
124
|
beginFrame(region: SurfaceRegion): void
|
|
120
|
-
|
|
121
|
-
|
|
125
|
+
/**
|
|
126
|
+
* 返回 true 表示本批已成功提交 GPU(或 instanceCount<=0 无需绘制)。
|
|
127
|
+
* 返回 false 表示未画上(无 surface / pipeline 不匹配 / 资源缺失)——调用方应 fail-closed 走 2D。
|
|
128
|
+
*/
|
|
129
|
+
drawInstances(params: DrawInstancesParams): boolean
|
|
130
|
+
/**
|
|
131
|
+
* 返回 true 表示本批折线/填充已成功提交 GPU。
|
|
132
|
+
* 返回 false 表示未画上——调用方应 fail-closed 走 2D。
|
|
133
|
+
*/
|
|
134
|
+
drawLines(params: DrawLinesParams): boolean
|
|
122
135
|
/** WebGPU only — WebGL implementations MUST throw. Caller checks caps first. */
|
|
123
136
|
dispatchCompute(params: DispatchComputeParams): void
|
|
124
137
|
endFrame(): void
|
|
@@ -2,22 +2,20 @@
|
|
|
2
2
|
* Low-level GPU surface backend.
|
|
3
3
|
*
|
|
4
4
|
* Abstracts canvas + context lifecycle, viewport / scissor regions, clear,
|
|
5
|
-
* compositing into a 2D canvas overlay, and teardown.
|
|
6
|
-
*
|
|
7
|
-
* P1 WebGPU
|
|
5
|
+
* compositing into a 2D canvas overlay, and teardown. WebGL
|
|
6
|
+
* (`createWebGLSurfaceBackend` over SharedWebGLSurface) implements this today;
|
|
7
|
+
* P1 WebGPU will implement the same contract.
|
|
8
8
|
*
|
|
9
9
|
* This file is **pure interface** — no implementation. It exists so that:
|
|
10
10
|
*
|
|
11
|
-
* 1.
|
|
12
|
-
* (see `createLegacyWebGLBackend` below) without changing any behaviour.
|
|
11
|
+
* 1. WebGL can adapt SharedWebGLSurface behind a stable contract.
|
|
13
12
|
* 2. P1's WebGPU implementation has a fixed target to write against.
|
|
14
13
|
* 3. The higher-level `Renderer` (`./Renderer.ts`) can compose a backend
|
|
15
14
|
* without knowing which GPU API it sits on.
|
|
16
15
|
*
|
|
17
16
|
* Design notes:
|
|
18
17
|
* - All region coordinates are in **logical pixels** with the surface
|
|
19
|
-
* responsible for DPR scaling internally
|
|
20
|
-
* `WebGLRegion` semantics so the legacy adapter is a transparent pass-through.
|
|
18
|
+
* responsible for DPR scaling internally (same semantics as WebGLRegion).
|
|
21
19
|
* - `compositeTo` takes a 2D `CanvasRenderingContext2D` because the chart's
|
|
22
20
|
* final composition target is a 2D overlay canvas — WebGL/WebGPU pixels
|
|
23
21
|
* are drawn into the overlay via `drawImage`. Future paths that bypass
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
|
|
3
|
+
import { createCanvas2DRenderer } from '../createCanvas2DRenderer'
|
|
4
|
+
|
|
5
|
+
describe('createCanvas2DRenderer', () => {
|
|
6
|
+
it('fails closed so business renderers use Canvas2D', () => {
|
|
7
|
+
const renderer = createCanvas2DRenderer()
|
|
8
|
+
const buffer = renderer.createBuffer('instance', 16)
|
|
9
|
+
const pipeline = renderer.createPipeline({ type: 'candle' })
|
|
10
|
+
|
|
11
|
+
expect(renderer.caps.name).toBe('canvas2d')
|
|
12
|
+
expect(renderer.surface.isAvailable()).toBe(false)
|
|
13
|
+
expect(
|
|
14
|
+
renderer.drawInstances({
|
|
15
|
+
pipeline,
|
|
16
|
+
vertices: buffer,
|
|
17
|
+
instances: buffer,
|
|
18
|
+
instanceCount: 1,
|
|
19
|
+
vertexCount: 6,
|
|
20
|
+
}),
|
|
21
|
+
).toBe(false)
|
|
22
|
+
expect(renderer.drawLines({ pipeline, strips: [] })).toBe(false)
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
it('has an idempotent disposed lifecycle', () => {
|
|
26
|
+
const renderer = createCanvas2DRenderer()
|
|
27
|
+
|
|
28
|
+
renderer.dispose()
|
|
29
|
+
renderer.dispose()
|
|
30
|
+
|
|
31
|
+
expect(() => renderer.createBuffer('vertex', 8)).toThrow('Renderer is disposed')
|
|
32
|
+
expect(() => renderer.createComputePipeline({})).toThrow('compute not supported')
|
|
33
|
+
})
|
|
34
|
+
})
|
|
@@ -109,8 +109,8 @@ function makeMockRenderer(surface: SurfaceBackend, computeSupported: boolean): R
|
|
|
109
109
|
},
|
|
110
110
|
destroyComputePipeline: () => {},
|
|
111
111
|
beginFrame: () => {},
|
|
112
|
-
drawInstances: () =>
|
|
113
|
-
drawLines: () =>
|
|
112
|
+
drawInstances: () => true,
|
|
113
|
+
drawLines: () => true,
|
|
114
114
|
dispatchCompute: () => {
|
|
115
115
|
if (!computeSupported) {
|
|
116
116
|
throw new Error('dispatchCompute requires a backend with caps.compute === true')
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
|
|
3
|
+
import { createFrameMetrics, getFrameMetrics, resetFrameMetrics } from '../frameMetrics'
|
|
4
|
+
|
|
5
|
+
describe('frameMetrics', () => {
|
|
6
|
+
it('counts submits uploads and buffer creates per frame', () => {
|
|
7
|
+
resetFrameMetrics()
|
|
8
|
+
const m = createFrameMetrics()
|
|
9
|
+
m.beginFrame()
|
|
10
|
+
m.recordBufferCreate()
|
|
11
|
+
m.recordUpload(64)
|
|
12
|
+
m.recordDraw()
|
|
13
|
+
m.recordSubmit()
|
|
14
|
+
m.recordComposite()
|
|
15
|
+
m.endFrame()
|
|
16
|
+
expect(getFrameMetrics()).toMatchObject({
|
|
17
|
+
bufferCreateCount: 1,
|
|
18
|
+
bufferUploadBytes: 64,
|
|
19
|
+
drawCallCount: 1,
|
|
20
|
+
queueSubmitCount: 1,
|
|
21
|
+
compositeCount: 1,
|
|
22
|
+
})
|
|
23
|
+
})
|
|
24
|
+
})
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from 'vitest'
|
|
2
|
+
|
|
3
|
+
import type { Renderer } from '../Renderer'
|
|
4
|
+
import { createCanvas2DRenderer } from '../createCanvas2DRenderer'
|
|
5
|
+
import { createRendererHost, type RendererBackend } from '../rendererHost'
|
|
6
|
+
|
|
7
|
+
function deferred<T>() {
|
|
8
|
+
let resolve!: (value: T) => void
|
|
9
|
+
const promise = new Promise<T>((done) => {
|
|
10
|
+
resolve = done
|
|
11
|
+
})
|
|
12
|
+
return { promise, resolve }
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function makeRenderer(backend: RendererBackend): Renderer {
|
|
16
|
+
const renderer = createCanvas2DRenderer()
|
|
17
|
+
return {
|
|
18
|
+
...renderer,
|
|
19
|
+
caps: { ...renderer.caps, name: backend === 'webgl' ? 'webgl2' : backend },
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
describe('RendererHost', () => {
|
|
24
|
+
it('degrades WebGPU to WebGL without changing the requested preference', async () => {
|
|
25
|
+
const webgl = makeRenderer('webgl')
|
|
26
|
+
const onRuntimeChange = vi.fn()
|
|
27
|
+
const host = await createRendererHost('webgpu', {
|
|
28
|
+
createWebGPU: async () => {
|
|
29
|
+
throw new Error('adapter unavailable')
|
|
30
|
+
},
|
|
31
|
+
createWebGL: () => webgl,
|
|
32
|
+
createCanvas: createCanvas2DRenderer,
|
|
33
|
+
onRuntimeChange,
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
expect(host.renderer).toBe(webgl)
|
|
37
|
+
expect(host.runtime).toEqual({
|
|
38
|
+
effective: 'webgl',
|
|
39
|
+
status: 'degraded',
|
|
40
|
+
error: 'adapter unavailable',
|
|
41
|
+
})
|
|
42
|
+
expect(onRuntimeChange).toHaveBeenLastCalledWith(host.runtime)
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
it('degrades WebGL to Canvas when WebGL is unavailable', async () => {
|
|
46
|
+
const host = await createRendererHost('webgl', {
|
|
47
|
+
createWebGPU: () => makeRenderer('webgpu'),
|
|
48
|
+
createWebGL: () => {
|
|
49
|
+
throw new Error('WebGL2 unavailable')
|
|
50
|
+
},
|
|
51
|
+
createCanvas: createCanvas2DRenderer,
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
expect(host.renderer.caps.name).toBe('canvas2d')
|
|
55
|
+
expect(host.runtime).toEqual({
|
|
56
|
+
effective: 'canvas',
|
|
57
|
+
status: 'degraded',
|
|
58
|
+
error: 'WebGL2 unavailable',
|
|
59
|
+
})
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
it('keeps the active renderer while a replacement is prepared', async () => {
|
|
63
|
+
const pending = deferred<Renderer>()
|
|
64
|
+
const webgl = makeRenderer('webgl')
|
|
65
|
+
const webgpu = makeRenderer('webgpu')
|
|
66
|
+
const host = await createRendererHost('webgl', {
|
|
67
|
+
createWebGPU: () => pending.promise,
|
|
68
|
+
createWebGL: () => webgl,
|
|
69
|
+
createCanvas: createCanvas2DRenderer,
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
const switching = host.switchTo('webgpu')
|
|
73
|
+
|
|
74
|
+
expect(host.renderer).toBe(webgl)
|
|
75
|
+
expect(host.runtime.status).toBe('switching')
|
|
76
|
+
|
|
77
|
+
pending.resolve(webgpu)
|
|
78
|
+
await switching
|
|
79
|
+
|
|
80
|
+
expect(host.renderer).toBe(webgpu)
|
|
81
|
+
expect(host.runtime).toEqual({ effective: 'webgpu', status: 'ready', error: null })
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
it('preserves the surface size when switching renderers', async () => {
|
|
85
|
+
const webgl = makeRenderer('webgl')
|
|
86
|
+
const webgpu = makeRenderer('webgpu')
|
|
87
|
+
const resizeWebGL = vi.spyOn(webgl.surface, 'resize')
|
|
88
|
+
const resizeWebGPU = vi.spyOn(webgpu.surface, 'resize')
|
|
89
|
+
const host = await createRendererHost('webgl', {
|
|
90
|
+
createWebGPU: () => webgpu,
|
|
91
|
+
createWebGL: () => webgl,
|
|
92
|
+
createCanvas: createCanvas2DRenderer,
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
host.resize(960, 540, 1.5)
|
|
96
|
+
await host.switchTo('webgpu')
|
|
97
|
+
|
|
98
|
+
expect(resizeWebGL).toHaveBeenCalledWith(960, 540, 1.5)
|
|
99
|
+
expect(resizeWebGPU).toHaveBeenCalledWith(960, 540, 1.5)
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
it('disposes a stale renderer created by an older switch', async () => {
|
|
103
|
+
const pending = deferred<Renderer>()
|
|
104
|
+
const stale = makeRenderer('webgpu')
|
|
105
|
+
const staleDispose = vi.spyOn(stale, 'dispose')
|
|
106
|
+
const host = await createRendererHost('canvas', {
|
|
107
|
+
createWebGPU: () => pending.promise,
|
|
108
|
+
createWebGL: () => makeRenderer('webgl'),
|
|
109
|
+
createCanvas: createCanvas2DRenderer,
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
const oldSwitch = host.switchTo('webgpu')
|
|
113
|
+
await host.switchTo('canvas')
|
|
114
|
+
pending.resolve(stale)
|
|
115
|
+
await oldSwitch
|
|
116
|
+
|
|
117
|
+
expect(staleDispose).toHaveBeenCalledOnce()
|
|
118
|
+
expect(host.runtime.effective).toBe('canvas')
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
it('disposes a renderer that arrives after the host is disposed', async () => {
|
|
122
|
+
const pending = deferred<Renderer>()
|
|
123
|
+
const late = makeRenderer('webgpu')
|
|
124
|
+
const lateDispose = vi.spyOn(late, 'dispose')
|
|
125
|
+
const host = await createRendererHost('canvas', {
|
|
126
|
+
createWebGPU: () => pending.promise,
|
|
127
|
+
createWebGL: () => makeRenderer('webgl'),
|
|
128
|
+
createCanvas: createCanvas2DRenderer,
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
const switching = host.switchTo('webgpu')
|
|
132
|
+
host.dispose()
|
|
133
|
+
pending.resolve(late)
|
|
134
|
+
await switching
|
|
135
|
+
|
|
136
|
+
expect(lateDispose).toHaveBeenCalledOnce()
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
it('degrades the active WebGPU renderer after device loss', async () => {
|
|
140
|
+
const webgpu = makeRenderer('webgpu')
|
|
141
|
+
const webgl = makeRenderer('webgl')
|
|
142
|
+
const host = await createRendererHost('webgpu', {
|
|
143
|
+
createWebGPU: () => webgpu,
|
|
144
|
+
createWebGL: () => webgl,
|
|
145
|
+
createCanvas: createCanvas2DRenderer,
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
await host.handleDeviceLost('device reset')
|
|
149
|
+
|
|
150
|
+
expect(host.renderer).toBe(webgl)
|
|
151
|
+
expect(host.runtime).toEqual({
|
|
152
|
+
effective: 'webgl',
|
|
153
|
+
status: 'degraded',
|
|
154
|
+
error: 'device reset',
|
|
155
|
+
})
|
|
156
|
+
})
|
|
157
|
+
})
|
|
@@ -54,50 +54,16 @@ function createMockSharedWebGLSurface() {
|
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
function makeMockFallbackCtx() {
|
|
58
|
-
return {
|
|
59
|
-
beginPath: vi.fn(),
|
|
60
|
-
moveTo: vi.fn(),
|
|
61
|
-
lineTo: vi.fn(),
|
|
62
|
-
closePath: vi.fn(),
|
|
63
|
-
fill: vi.fn(),
|
|
64
|
-
stroke: vi.fn(),
|
|
65
|
-
fillStyle: '',
|
|
66
|
-
strokeStyle: '',
|
|
67
|
-
lineWidth: 1,
|
|
68
|
-
fillRect: vi.fn(),
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
57
|
beforeEach(() => {
|
|
73
58
|
vi.clearAllMocks()
|
|
74
59
|
})
|
|
75
60
|
|
|
76
|
-
describe('
|
|
77
|
-
it('setFallbackContext stores the context and dpr', () => {
|
|
78
|
-
const surface = createMockSurfaceBackend()
|
|
79
|
-
const glSurface = createMockSharedWebGLSurface()
|
|
80
|
-
const renderer = createWebGLRenderer(surface, glSurface as any)
|
|
81
|
-
const ctx = makeMockFallbackCtx()
|
|
82
|
-
|
|
83
|
-
expect(() => (renderer as any).setFallbackContext(ctx, 2)).not.toThrow()
|
|
84
|
-
})
|
|
85
|
-
|
|
86
|
-
it('setFallbackContext with null clears the fallback', () => {
|
|
87
|
-
const surface = createMockSurfaceBackend()
|
|
88
|
-
const glSurface = createMockSharedWebGLSurface()
|
|
89
|
-
const renderer = createWebGLRenderer(surface, glSurface as any)
|
|
90
|
-
|
|
91
|
-
expect(() => (renderer as any).setFallbackContext(null, 1)).not.toThrow()
|
|
92
|
-
})
|
|
93
|
-
|
|
61
|
+
describe('fail-closed when GPU surfaces unavailable', () => {
|
|
94
62
|
describe('drawLines — line type', () => {
|
|
95
|
-
it('
|
|
63
|
+
it('returns false when lineSurface unavailable', () => {
|
|
96
64
|
const surface = createMockSurfaceBackend()
|
|
97
65
|
const glSurface = createMockSharedWebGLSurface()
|
|
98
66
|
const renderer = createWebGLRenderer(surface, glSurface as any)
|
|
99
|
-
const ctx = makeMockFallbackCtx()
|
|
100
|
-
;(renderer as any).setFallbackContext(ctx, 1)
|
|
101
67
|
|
|
102
68
|
renderer.beginFrame({ x: 0, y: 0, width: 100, height: 100, dpr: 1 })
|
|
103
69
|
|
|
@@ -106,23 +72,17 @@ describe('Canvas2D fallback', () => {
|
|
|
106
72
|
const verts = new Float32Array([10, 20, 30, 40, 50, 60])
|
|
107
73
|
renderer.writeBuffer(vertexBuf, verts)
|
|
108
74
|
|
|
109
|
-
renderer.drawLines({
|
|
75
|
+
const ok = renderer.drawLines({
|
|
110
76
|
pipeline,
|
|
111
77
|
vertices: vertexBuf,
|
|
112
78
|
vertexCount: 3,
|
|
113
79
|
uniforms: { color: '#00ff00', scrollLeft: 5, lineWidth: 2 },
|
|
114
80
|
})
|
|
115
81
|
|
|
116
|
-
expect(
|
|
117
|
-
expect(ctx.moveTo).toHaveBeenCalledWith(5, 20)
|
|
118
|
-
expect(ctx.lineTo).toHaveBeenCalledWith(25, 40)
|
|
119
|
-
expect(ctx.lineTo).toHaveBeenCalledWith(45, 60)
|
|
120
|
-
expect(ctx.strokeStyle).toBe('#00ff00')
|
|
121
|
-
expect(ctx.lineWidth).toBe(2)
|
|
122
|
-
expect(ctx.stroke).toHaveBeenCalledTimes(1)
|
|
82
|
+
expect(ok).toBe(false)
|
|
123
83
|
})
|
|
124
84
|
|
|
125
|
-
it('
|
|
85
|
+
it('returns false on drawLines with no lineSurface', () => {
|
|
126
86
|
const surface = createMockSurfaceBackend()
|
|
127
87
|
const glSurface = createMockSharedWebGLSurface()
|
|
128
88
|
const renderer = createWebGLRenderer(surface, glSurface as any)
|
|
@@ -132,19 +92,15 @@ describe('Canvas2D fallback', () => {
|
|
|
132
92
|
const vertexBuf = renderer.createBuffer('vertex', 256)
|
|
133
93
|
renderer.writeBuffer(vertexBuf, new Float32Array([0, 0, 100, 100]))
|
|
134
94
|
|
|
135
|
-
expect(()
|
|
136
|
-
renderer.drawLines({ pipeline, vertices: vertexBuf, vertexCount: 2 }),
|
|
137
|
-
).not.toThrow()
|
|
95
|
+
expect(renderer.drawLines({ pipeline, vertices: vertexBuf, vertexCount: 2 })).toBe(false)
|
|
138
96
|
})
|
|
139
97
|
})
|
|
140
98
|
|
|
141
99
|
describe('drawLines — fill type', () => {
|
|
142
|
-
it('
|
|
100
|
+
it('returns false when lineSurface unavailable', () => {
|
|
143
101
|
const surface = createMockSurfaceBackend()
|
|
144
102
|
const glSurface = createMockSharedWebGLSurface()
|
|
145
103
|
const renderer = createWebGLRenderer(surface, glSurface as any)
|
|
146
|
-
const ctx = makeMockFallbackCtx()
|
|
147
|
-
;(renderer as any).setFallbackContext(ctx, 1)
|
|
148
104
|
|
|
149
105
|
renderer.beginFrame({ x: 0, y: 0, width: 100, height: 100, dpr: 1 })
|
|
150
106
|
|
|
@@ -153,33 +109,22 @@ describe('Canvas2D fallback', () => {
|
|
|
153
109
|
const verts = new Float32Array([0, 100, 0, 50, 100, 100, 100, 50, 200, 100, 200, 50])
|
|
154
110
|
renderer.writeBuffer(vertexBuf, verts)
|
|
155
111
|
|
|
156
|
-
renderer.drawLines({
|
|
112
|
+
const ok = renderer.drawLines({
|
|
157
113
|
pipeline,
|
|
158
114
|
vertices: vertexBuf,
|
|
159
115
|
vertexCount: 6,
|
|
160
116
|
uniforms: { color: '#0000ff', scrollLeft: 5 },
|
|
161
117
|
})
|
|
162
118
|
|
|
163
|
-
expect(
|
|
164
|
-
expect(ctx.moveTo).toHaveBeenCalledWith(-5, 100)
|
|
165
|
-
expect(ctx.lineTo).toHaveBeenCalledWith(95, 100)
|
|
166
|
-
expect(ctx.lineTo).toHaveBeenCalledWith(195, 100)
|
|
167
|
-
expect(ctx.lineTo).toHaveBeenCalledWith(195, 50)
|
|
168
|
-
expect(ctx.lineTo).toHaveBeenCalledWith(95, 50)
|
|
169
|
-
expect(ctx.lineTo).toHaveBeenCalledWith(-5, 50)
|
|
170
|
-
expect(ctx.closePath).toHaveBeenCalledTimes(1)
|
|
171
|
-
expect(ctx.fillStyle).toBe('#0000ff')
|
|
172
|
-
expect(ctx.fill).toHaveBeenCalledTimes(1)
|
|
119
|
+
expect(ok).toBe(false)
|
|
173
120
|
})
|
|
174
121
|
})
|
|
175
122
|
|
|
176
123
|
describe('drawInstances', () => {
|
|
177
|
-
it('
|
|
124
|
+
it('returns false when candleSurface unavailable', () => {
|
|
178
125
|
const surface = createMockSurfaceBackend()
|
|
179
126
|
const glSurface = createMockSharedWebGLSurface()
|
|
180
127
|
const renderer = createWebGLRenderer(surface, glSurface as any)
|
|
181
|
-
const ctx = makeMockFallbackCtx()
|
|
182
|
-
;(renderer as any).setFallbackContext(ctx, 1)
|
|
183
128
|
|
|
184
129
|
renderer.beginFrame({ x: 0, y: 0, width: 100, height: 100, dpr: 1 })
|
|
185
130
|
|
|
@@ -188,7 +133,7 @@ describe('Canvas2D fallback', () => {
|
|
|
188
133
|
const rects = new Float32Array([10, 20, 30, 40, 60, 70, 20, 10])
|
|
189
134
|
renderer.writeBuffer(instanceBuf, rects)
|
|
190
135
|
|
|
191
|
-
renderer.drawInstances({
|
|
136
|
+
const ok = renderer.drawInstances({
|
|
192
137
|
pipeline,
|
|
193
138
|
vertices: instanceBuf,
|
|
194
139
|
instances: instanceBuf,
|
|
@@ -197,20 +142,15 @@ describe('Canvas2D fallback', () => {
|
|
|
197
142
|
uniforms: { color: '#ff0000', scrollLeft: 5 },
|
|
198
143
|
})
|
|
199
144
|
|
|
200
|
-
expect(
|
|
201
|
-
expect(ctx.fillRect).toHaveBeenNthCalledWith(1, 5, 20, 30, 40)
|
|
202
|
-
expect(ctx.fillRect).toHaveBeenNthCalledWith(2, 55, 70, 20, 10)
|
|
203
|
-
expect(ctx.fillStyle).toBe('#ff0000')
|
|
145
|
+
expect(ok).toBe(false)
|
|
204
146
|
})
|
|
205
147
|
})
|
|
206
148
|
|
|
207
149
|
describe('dispose behaviour', () => {
|
|
208
|
-
it('after dispose,
|
|
150
|
+
it('after dispose, draw calls are no-ops / false', () => {
|
|
209
151
|
const surface = createMockSurfaceBackend()
|
|
210
152
|
const glSurface = createMockSharedWebGLSurface()
|
|
211
153
|
const renderer = createWebGLRenderer(surface, glSurface as any)
|
|
212
|
-
const ctx = makeMockFallbackCtx()
|
|
213
|
-
;(renderer as any).setFallbackContext(ctx, 1)
|
|
214
154
|
|
|
215
155
|
const pipeline = renderer.createPipeline({ type: 'line' })
|
|
216
156
|
const vertexBuf = renderer.createBuffer('vertex', 256)
|
|
@@ -221,7 +161,7 @@ describe('Canvas2D fallback', () => {
|
|
|
221
161
|
expect(() =>
|
|
222
162
|
renderer.drawLines({ pipeline, vertices: vertexBuf, vertexCount: 2 }),
|
|
223
163
|
).not.toThrow()
|
|
224
|
-
expect(
|
|
164
|
+
expect(renderer.drawLines({ pipeline, vertices: vertexBuf, vertexCount: 2 })).toBe(false)
|
|
225
165
|
})
|
|
226
166
|
})
|
|
227
167
|
})
|
|
@@ -198,7 +198,7 @@ describe('createWebGLRenderer', () => {
|
|
|
198
198
|
renderer.writeBuffer(instanceBuf, rects)
|
|
199
199
|
|
|
200
200
|
const vertices = renderer.createBuffer('vertex', 48)
|
|
201
|
-
renderer.drawInstances({
|
|
201
|
+
const ok = renderer.drawInstances({
|
|
202
202
|
pipeline,
|
|
203
203
|
vertices,
|
|
204
204
|
instances: instanceBuf,
|
|
@@ -207,6 +207,7 @@ describe('createWebGLRenderer', () => {
|
|
|
207
207
|
uniforms: { color: '#ff0000', scrollLeft: 0 },
|
|
208
208
|
})
|
|
209
209
|
|
|
210
|
+
expect(ok).toBe(true)
|
|
210
211
|
expect(mocks.mockDrawRectBuffer).toHaveBeenCalledTimes(1)
|
|
211
212
|
const args = mocks.mockDrawRectBuffer.mock.calls[0]
|
|
212
213
|
expect(args[0]).toBeInstanceOf(Float32Array)
|
|
@@ -215,37 +216,56 @@ describe('createWebGLRenderer', () => {
|
|
|
215
216
|
expect(args[3]).toBe(0)
|
|
216
217
|
})
|
|
217
218
|
|
|
218
|
-
it('
|
|
219
|
+
it('returns true without GPU when instanceCount is zero', () => {
|
|
219
220
|
const { renderer } = makeRenderer()
|
|
220
221
|
renderer.beginFrame({ x: 0, y: 0, width: 100, height: 100, dpr: 1 })
|
|
221
222
|
const pipeline = renderer.createPipeline({ type: 'candle' })
|
|
222
223
|
const buf = renderer.createBuffer('instance', 64)
|
|
223
224
|
renderer.writeBuffer(buf, new Float32Array([0, 0, 50, 50]))
|
|
224
|
-
renderer.drawInstances({
|
|
225
|
+
const ok = renderer.drawInstances({
|
|
225
226
|
pipeline,
|
|
226
227
|
vertices: buf,
|
|
227
228
|
instances: buf,
|
|
228
229
|
instanceCount: 0,
|
|
229
230
|
vertexCount: 6,
|
|
230
231
|
})
|
|
232
|
+
expect(ok).toBe(true)
|
|
231
233
|
expect(mocks.mockDrawRectBuffer).not.toHaveBeenCalled()
|
|
232
234
|
})
|
|
233
235
|
|
|
234
|
-
it('
|
|
236
|
+
it('returns false when pipeline type mismatch (line -> instances)', () => {
|
|
235
237
|
const { renderer } = makeRenderer()
|
|
236
238
|
renderer.beginFrame({ x: 0, y: 0, width: 100, height: 100, dpr: 1 })
|
|
237
239
|
const pipeline = renderer.createPipeline({ type: 'line' })
|
|
238
240
|
const buf = renderer.createBuffer('instance', 64)
|
|
239
241
|
renderer.writeBuffer(buf, new Float32Array([0, 0, 50, 50]))
|
|
240
|
-
renderer.drawInstances({
|
|
242
|
+
const ok = renderer.drawInstances({
|
|
241
243
|
pipeline,
|
|
242
244
|
vertices: buf,
|
|
243
245
|
instances: buf,
|
|
244
246
|
instanceCount: 1,
|
|
245
247
|
vertexCount: 6,
|
|
246
248
|
})
|
|
249
|
+
expect(ok).toBe(false)
|
|
247
250
|
expect(mocks.mockDrawRectBuffer).not.toHaveBeenCalled()
|
|
248
251
|
})
|
|
252
|
+
|
|
253
|
+
it('returns false when drawRectBuffer fails', () => {
|
|
254
|
+
mocks.mockDrawRectBuffer.mockReturnValueOnce(false)
|
|
255
|
+
const { renderer } = makeRenderer()
|
|
256
|
+
renderer.beginFrame({ x: 0, y: 0, width: 100, height: 100, dpr: 1 })
|
|
257
|
+
const pipeline = renderer.createPipeline({ type: 'candle' })
|
|
258
|
+
const buf = renderer.createBuffer('instance', 64)
|
|
259
|
+
renderer.writeBuffer(buf, new Float32Array([0, 0, 50, 50]))
|
|
260
|
+
const ok = renderer.drawInstances({
|
|
261
|
+
pipeline,
|
|
262
|
+
vertices: buf,
|
|
263
|
+
instances: buf,
|
|
264
|
+
instanceCount: 1,
|
|
265
|
+
vertexCount: 6,
|
|
266
|
+
})
|
|
267
|
+
expect(ok).toBe(false)
|
|
268
|
+
})
|
|
249
269
|
})
|
|
250
270
|
|
|
251
271
|
describe('drawLines', () => {
|
|
@@ -258,7 +278,7 @@ describe('createWebGLRenderer', () => {
|
|
|
258
278
|
const verts = new Float32Array([10, 20, 30, 40, 50, 60])
|
|
259
279
|
renderer.writeBuffer(vertexBuf, verts)
|
|
260
280
|
|
|
261
|
-
renderer.drawLines({
|
|
281
|
+
const ok = renderer.drawLines({
|
|
262
282
|
pipeline,
|
|
263
283
|
vertices: vertexBuf,
|
|
264
284
|
vertexCount: 3,
|
|
@@ -266,6 +286,7 @@ describe('createWebGLRenderer', () => {
|
|
|
266
286
|
uniforms: { color: '#00ff00', scrollLeft: 10, lineWidth: 1 },
|
|
267
287
|
})
|
|
268
288
|
|
|
289
|
+
expect(ok).toBe(true)
|
|
269
290
|
expect(mocks.mockDrawLineStrips).toHaveBeenCalledTimes(1)
|
|
270
291
|
const args = mocks.mockDrawLineStrips.mock.calls[0]
|
|
271
292
|
expect(args[0]).toHaveLength(1)
|
|
@@ -275,6 +296,43 @@ describe('createWebGLRenderer', () => {
|
|
|
275
296
|
expect(args[1]).toBe(10)
|
|
276
297
|
})
|
|
277
298
|
|
|
299
|
+
it('batches multiple strips in one drawLineStrips call', () => {
|
|
300
|
+
const { renderer } = makeRenderer()
|
|
301
|
+
renderer.beginFrame({ x: 0, y: 0, width: 800, height: 600, dpr: 1 })
|
|
302
|
+
const pipeline = renderer.createPipeline({ type: 'line' })
|
|
303
|
+
const ok = renderer.drawLines({
|
|
304
|
+
pipeline,
|
|
305
|
+
strips: [
|
|
306
|
+
{
|
|
307
|
+
points: [
|
|
308
|
+
{ x: 0, y: 0 },
|
|
309
|
+
{ x: 1, y: 1 },
|
|
310
|
+
],
|
|
311
|
+
color: '#f00',
|
|
312
|
+
width: 1,
|
|
313
|
+
},
|
|
314
|
+
{
|
|
315
|
+
points: [
|
|
316
|
+
{ x: 0, y: 2 },
|
|
317
|
+
{ x: 1, y: 3 },
|
|
318
|
+
{ x: 2, y: 2 },
|
|
319
|
+
],
|
|
320
|
+
color: '#0f0',
|
|
321
|
+
width: 2,
|
|
322
|
+
},
|
|
323
|
+
],
|
|
324
|
+
uniforms: { scrollLeft: 5 },
|
|
325
|
+
})
|
|
326
|
+
expect(ok).toBe(true)
|
|
327
|
+
expect(mocks.mockDrawLineStrips).toHaveBeenCalledTimes(1)
|
|
328
|
+
const lines = mocks.mockDrawLineStrips.mock.calls[0]![0]
|
|
329
|
+
expect(lines).toHaveLength(2)
|
|
330
|
+
expect(lines[0].color).toBe('#f00')
|
|
331
|
+
expect(lines[1].color).toBe('#0f0')
|
|
332
|
+
expect(lines[1].width).toBe(2)
|
|
333
|
+
expect(mocks.mockDrawLineStrips.mock.calls[0]![1]).toBe(5)
|
|
334
|
+
})
|
|
335
|
+
|
|
278
336
|
it('delegates to line surface drawFilledBand for fill pipeline', () => {
|
|
279
337
|
const { renderer } = makeRenderer()
|
|
280
338
|
renderer.beginFrame({ x: 0, y: 0, width: 800, height: 600, dpr: 2 })
|