@jbrowse/render-core 4.3.0 → 5.0.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/RenderCanvas.d.ts +2 -2
- package/esm/RenderLifecycleMixin.d.ts +52 -20
- package/esm/RenderLifecycleMixin.js +89 -23
- package/esm/canvas2dUtils.d.ts +90 -23
- package/esm/canvas2dUtils.js +119 -36
- package/esm/colorRampLut.d.ts +5 -5
- package/esm/colorRampLut.js +6 -6
- package/esm/computePipeline.d.ts +14 -0
- package/esm/computePipeline.js +62 -0
- package/esm/contractReports.d.ts +54 -0
- package/esm/contractReports.js +112 -0
- package/esm/coverageBand.d.ts +13 -8
- package/esm/coverageBand.js +15 -5
- package/esm/coverageBandBuffers.d.ts +2 -9
- package/esm/coverageBandBuffers.js +1 -13
- package/esm/createRenderingBackend.d.ts +14 -18
- package/esm/createRenderingBackend.js +4 -2
- package/esm/displayPhase.d.ts +83 -104
- package/esm/displayPhase.js +42 -82
- package/esm/encodeMemo.d.ts +14 -0
- package/esm/encodeMemo.js +48 -0
- package/esm/gpuContextLostError.d.ts +30 -0
- package/esm/gpuContextLostError.js +40 -0
- package/esm/gpuDevice.d.ts +29 -10
- package/esm/gpuDevice.js +35 -16
- package/esm/graphicsCapabilities.d.ts +27 -19
- package/esm/graphicsCapabilities.js +40 -18
- package/esm/hal/createHal.d.ts +4 -5
- package/esm/hal/createHal.js +14 -4
- package/esm/hal/deviceGpuCache.d.ts +25 -30
- package/esm/hal/deviceGpuCache.js +88 -97
- package/esm/hal/gpuHalBase.d.ts +5 -4
- package/esm/hal/gpuHalBase.js +25 -14
- package/esm/hal/index.d.ts +2 -2
- package/esm/hal/index.js +1 -1
- package/esm/hal/mockHal.d.ts +15 -10
- package/esm/hal/mockHal.js +31 -18
- package/esm/hal/oomReporter.d.ts +7 -0
- package/esm/hal/oomReporter.js +10 -0
- package/esm/hal/passIds.d.ts +8 -7
- package/esm/hal/passIds.js +11 -10
- package/esm/hal/regionRegistry.d.ts +0 -1
- package/esm/hal/regionRegistry.js +3 -15
- package/esm/hal/types.d.ts +55 -18
- package/esm/hal/webgl2Hal.d.ts +23 -6
- package/esm/hal/webgl2Hal.js +161 -155
- package/esm/hal/webgpuHal.d.ts +29 -13
- package/esm/hal/webgpuHal.js +221 -153
- package/esm/installUpload.d.ts +16 -3
- package/esm/installUpload.js +13 -41
- package/esm/instanceCache.d.ts +10 -7
- package/esm/instanceCache.js +14 -15
- package/esm/instancePass.d.ts +2 -1
- package/esm/mapUploadSync.d.ts +2 -10
- package/esm/mapUploadSync.js +2 -3
- package/esm/marks/barMark.d.ts +30 -0
- package/esm/marks/barMark.js +149 -0
- package/esm/marks/colorFill.d.ts +17 -0
- package/esm/marks/colorFill.js +26 -0
- package/esm/marks/drawAgainstHit.d.ts +113 -0
- package/esm/marks/drawAgainstHit.js +407 -0
- package/esm/marks/ellipseDistance.d.ts +10 -0
- package/esm/marks/ellipseDistance.js +136 -0
- package/esm/marks/glyphPaint.d.ts +36 -0
- package/esm/marks/glyphPaint.js +77 -0
- package/esm/marks/index.d.ts +33 -0
- package/esm/marks/index.js +20 -0
- package/esm/marks/lineMark.d.ts +37 -0
- package/esm/marks/lineMark.js +416 -0
- package/esm/marks/linkMark.d.ts +76 -0
- package/esm/marks/linkMark.js +585 -0
- package/esm/marks/markBackend.d.ts +118 -0
- package/esm/marks/markBackend.js +196 -0
- package/esm/marks/markHit.d.ts +32 -0
- package/esm/marks/markHit.js +61 -0
- package/esm/marks/markInk.d.ts +18 -0
- package/esm/marks/markInk.js +71 -0
- package/esm/marks/markPaint.d.ts +14 -0
- package/esm/marks/markPaint.js +32 -0
- package/esm/marks/markPlan.d.ts +25 -0
- package/esm/marks/markPlan.js +20 -0
- package/esm/marks/markRamp.d.ts +72 -0
- package/esm/marks/markRamp.js +197 -0
- package/esm/marks/nearestMarkHit.d.ts +55 -0
- package/esm/marks/nearestMarkHit.js +158 -0
- package/esm/marks/pathRecorder.d.ts +14 -0
- package/esm/marks/pathRecorder.js +80 -0
- package/esm/marks/pointMark.d.ts +42 -0
- package/esm/marks/pointMark.js +125 -0
- package/esm/marks/rowLane.d.ts +39 -0
- package/esm/marks/rowLane.js +41 -0
- package/esm/marks/rowSpanIndex.d.ts +29 -0
- package/esm/marks/rowSpanIndex.js +141 -0
- package/esm/marks/rowTable.d.ts +41 -0
- package/esm/marks/rowTable.js +75 -0
- package/esm/marks/ruleMark.d.ts +21 -0
- package/esm/marks/ruleMark.js +91 -0
- package/esm/marks/spanMark.d.ts +42 -0
- package/esm/marks/spanMark.js +81 -0
- package/esm/marks/types.d.ts +261 -0
- package/esm/marks/types.js +175 -0
- package/esm/marks/valueScale.d.ts +23 -0
- package/esm/marks/valueScale.js +11 -0
- package/esm/namedReactions.d.ts +3 -4
- package/esm/namedReactions.js +3 -4
- package/esm/perRegionRenderingBackend.d.ts +21 -3
- package/esm/perRegionRenderingBackend.js +37 -3
- package/esm/regionDataMap.d.ts +2 -2
- package/esm/regionDataMap.js +25 -23
- package/esm/renderBlock.d.ts +14 -0
- package/esm/renderBlock.js +25 -0
- package/esm/renderingBackendBase.d.ts +20 -14
- package/esm/renderingBackendBase.js +12 -7
- package/esm/scoreScale.d.ts +27 -0
- package/esm/scoreScale.js +88 -0
- package/esm/shaders/barMark.generated.d.ts +3 -0
- package/esm/shaders/barMark.generated.js +7 -0
- package/esm/shaders/barMark.glsl.generated.d.ts +2 -0
- package/esm/shaders/barMark.glsl.generated.js +4 -0
- package/esm/shaders/barMark.iface.generated.d.ts +90 -0
- package/esm/shaders/barMark.iface.generated.js +205 -0
- package/esm/shaders/barMark.wgsl.generated.d.ts +1 -0
- package/esm/shaders/barMark.wgsl.generated.js +3 -0
- package/esm/shaders/capsule.js.generated.d.ts +1 -0
- package/esm/shaders/capsule.js.generated.js +11 -0
- package/esm/shaders/clipStrip.generated.d.ts +2 -0
- package/esm/shaders/clipStrip.generated.js +4 -0
- package/esm/shaders/clipStrip.js.generated.d.ts +1 -0
- package/esm/shaders/clipStrip.js.generated.js +21 -0
- package/esm/shaders/colorRampLut.js.generated.d.ts +1 -0
- package/esm/shaders/colorRampLut.js.generated.js +17 -0
- package/esm/shaders/coverageBar.generated.d.ts +2 -3
- package/esm/shaders/coverageBar.generated.js +4 -3
- package/esm/shaders/coverageBar.glsl.generated.d.ts +2 -0
- package/esm/shaders/coverageBar.glsl.generated.js +4 -0
- package/esm/shaders/coverageBar.iface.generated.js +1 -1
- package/esm/shaders/coverageBar.wgsl.generated.d.ts +1 -0
- package/esm/shaders/coverageBar.wgsl.generated.js +3 -0
- package/esm/shaders/coverageClip.generated.d.ts +3 -0
- package/esm/shaders/coverageClip.generated.js +7 -0
- package/esm/shaders/coverageClip.glsl.generated.d.ts +2 -0
- package/esm/shaders/coverageClip.glsl.generated.js +4 -0
- package/esm/shaders/coverageClip.iface.generated.d.ts +85 -0
- package/esm/shaders/coverageClip.iface.generated.js +114 -0
- package/esm/shaders/coverageClip.wgsl.generated.d.ts +1 -0
- package/esm/shaders/coverageClip.wgsl.generated.js +3 -0
- package/esm/shaders/coverageIndicator.generated.d.ts +2 -3
- package/esm/shaders/coverageIndicator.generated.js +4 -3
- package/esm/shaders/coverageIndicator.glsl.generated.d.ts +2 -0
- package/esm/shaders/coverageIndicator.glsl.generated.js +4 -0
- package/esm/shaders/coverageIndicator.iface.generated.js +1 -1
- package/esm/shaders/coverageIndicator.wgsl.generated.d.ts +1 -0
- package/esm/shaders/coverageIndicator.wgsl.generated.js +3 -0
- package/esm/shaders/coverageInterbase.generated.d.ts +2 -3
- package/esm/shaders/coverageInterbase.generated.js +4 -3
- package/esm/shaders/coverageInterbase.glsl.generated.d.ts +2 -0
- package/esm/shaders/coverageInterbase.glsl.generated.js +4 -0
- package/esm/shaders/coverageInterbase.iface.generated.js +1 -1
- package/esm/shaders/coverageInterbase.wgsl.generated.d.ts +1 -0
- package/esm/shaders/coverageInterbase.wgsl.generated.js +3 -0
- package/esm/shaders/coverageMod.generated.d.ts +2 -3
- package/esm/shaders/coverageMod.generated.js +4 -3
- package/esm/shaders/coverageMod.glsl.generated.d.ts +2 -0
- package/esm/shaders/coverageMod.glsl.generated.js +4 -0
- package/esm/shaders/coverageMod.iface.generated.js +1 -1
- package/esm/shaders/coverageMod.wgsl.generated.d.ts +1 -0
- package/esm/shaders/coverageMod.wgsl.generated.js +3 -0
- package/esm/shaders/coverageSnp.generated.d.ts +2 -3
- package/esm/shaders/coverageSnp.generated.js +4 -3
- package/esm/shaders/coverageSnp.glsl.generated.d.ts +2 -0
- package/esm/shaders/coverageSnp.glsl.generated.js +4 -0
- package/esm/shaders/coverageSnp.iface.generated.js +1 -1
- package/esm/shaders/coverageSnp.wgsl.generated.d.ts +1 -0
- package/esm/shaders/coverageSnp.wgsl.generated.js +3 -0
- package/esm/shaders/curveDistance.js.generated.d.ts +5 -0
- package/esm/shaders/curveDistance.js.generated.js +87 -0
- package/esm/shaders/hpmath.js.generated.d.ts +2 -1
- package/esm/shaders/hpmath.js.generated.js +5 -2
- package/esm/shaders/lineCenterMark.generated.d.ts +3 -0
- package/esm/shaders/lineCenterMark.generated.js +7 -0
- package/esm/shaders/lineCenterMark.glsl.generated.d.ts +2 -0
- package/esm/shaders/lineCenterMark.glsl.generated.js +4 -0
- package/esm/shaders/lineCenterMark.iface.generated.d.ts +104 -0
- package/esm/shaders/lineCenterMark.iface.generated.js +237 -0
- package/esm/shaders/lineCenterMark.wgsl.generated.d.ts +1 -0
- package/esm/shaders/lineCenterMark.wgsl.generated.js +3 -0
- package/esm/shaders/lineCommon.generated.d.ts +2 -0
- package/esm/shaders/lineCommon.generated.js +4 -0
- package/esm/shaders/lineStepMark.generated.d.ts +3 -0
- package/esm/shaders/lineStepMark.generated.js +7 -0
- package/esm/shaders/lineStepMark.glsl.generated.d.ts +2 -0
- package/esm/shaders/lineStepMark.glsl.generated.js +4 -0
- package/esm/shaders/lineStepMark.iface.generated.d.ts +98 -0
- package/esm/shaders/lineStepMark.iface.generated.js +225 -0
- package/esm/shaders/lineStepMark.wgsl.generated.d.ts +1 -0
- package/esm/shaders/lineStepMark.wgsl.generated.js +3 -0
- package/esm/shaders/linkMark.consts.generated.d.ts +14 -0
- package/esm/shaders/linkMark.consts.generated.js +16 -0
- package/esm/shaders/linkMark.generated.d.ts +4 -0
- package/esm/shaders/linkMark.generated.js +8 -0
- package/esm/shaders/linkMark.glsl.generated.d.ts +2 -0
- package/esm/shaders/linkMark.glsl.generated.js +4 -0
- package/esm/shaders/linkMark.iface.generated.d.ts +142 -0
- package/esm/shaders/linkMark.iface.generated.js +1829 -0
- package/esm/shaders/linkMark.js.generated.d.ts +7 -0
- package/esm/shaders/linkMark.js.generated.js +159 -0
- package/esm/shaders/linkMark.wgsl.generated.d.ts +1 -0
- package/esm/shaders/linkMark.wgsl.generated.js +3 -0
- package/esm/shaders/markColor.generated.d.ts +9 -0
- package/esm/shaders/markColor.generated.js +11 -0
- package/esm/shaders/pointGlyph.js.generated.d.ts +2 -0
- package/esm/shaders/pointGlyph.js.generated.js +15 -0
- package/esm/shaders/pointMark.consts.generated.d.ts +7 -0
- package/esm/shaders/pointMark.consts.generated.js +9 -0
- package/esm/shaders/pointMark.generated.d.ts +4 -0
- package/esm/shaders/pointMark.generated.js +8 -0
- package/esm/shaders/pointMark.glsl.generated.d.ts +2 -0
- package/esm/shaders/pointMark.glsl.generated.js +4 -0
- package/esm/shaders/pointMark.iface.generated.d.ts +98 -0
- package/esm/shaders/pointMark.iface.generated.js +219 -0
- package/esm/shaders/pointMark.js.generated.d.ts +3 -0
- package/esm/shaders/pointMark.js.generated.js +93 -0
- package/esm/shaders/pointMark.wgsl.generated.d.ts +1 -0
- package/esm/shaders/pointMark.wgsl.generated.js +3 -0
- package/esm/shaders/rowRect.generated.d.ts +0 -1
- package/esm/shaders/rowRect.generated.js +0 -1
- package/esm/shaders/rowTable.generated.d.ts +1 -0
- package/esm/shaders/rowTable.generated.js +3 -0
- package/esm/shaders/rowTable.js.generated.d.ts +5 -0
- package/esm/shaders/rowTable.js.generated.js +29 -0
- package/esm/shaders/scoreScale.generated.d.ts +2 -0
- package/esm/shaders/scoreScale.generated.js +4 -0
- package/esm/shaders/scoreScale.js.generated.d.ts +1 -0
- package/esm/shaders/scoreScale.js.generated.js +50 -23
- package/esm/shaders/spanMark.generated.d.ts +3 -0
- package/esm/shaders/spanMark.generated.js +7 -0
- package/esm/shaders/spanMark.glsl.generated.d.ts +2 -0
- package/esm/shaders/spanMark.glsl.generated.js +4 -0
- package/esm/shaders/spanMark.iface.generated.d.ts +81 -0
- package/esm/shaders/spanMark.iface.generated.js +215 -0
- package/esm/shaders/spanMark.wgsl.generated.d.ts +1 -0
- package/esm/shaders/spanMark.wgsl.generated.js +3 -0
- package/esm/sharedBackendKey.d.ts +18 -0
- package/esm/{keyedRenderingBackend.js → sharedBackendKey.js} +5 -0
- package/esm/slangPass.d.ts +18 -11
- package/esm/slangPass.js +12 -4
- package/esm/useGraphicsCapabilities.d.ts +1 -1
- package/esm/useGraphicsCapabilities.js +1 -1
- package/esm/useRenderingBackend.d.ts +13 -13
- package/esm/useRenderingBackend.js +58 -20
- package/esm/webgpuUtils.d.ts +3 -11
- package/esm/webgpuUtils.js +12 -33
- package/package.json +32 -7
- package/src/shaders/antialias.slang +46 -0
- package/src/shaders/arcHull.test.ts +267 -0
- package/src/shaders/barMark.generated.ts +11 -0
- package/src/shaders/barMark.glsl.generated.ts +6 -0
- package/src/shaders/barMark.iface.generated.ts +285 -0
- package/src/shaders/barMark.slang +167 -0
- package/src/shaders/barMark.wgsl.generated.ts +4 -0
- package/src/shaders/capsule.js.generated.ts +14 -0
- package/src/shaders/capsule.slang +12 -4
- package/src/shaders/clipStrip.generated.ts +6 -0
- package/src/shaders/clipStrip.js.generated.ts +22 -0
- package/src/shaders/clipStrip.slang +34 -0
- package/src/shaders/clipStrip.test.ts +39 -0
- package/src/shaders/colorPack.slang +5 -1
- package/src/shaders/colorRampLut.js.generated.ts +22 -0
- package/src/shaders/colorRampLut.slang +15 -1
- package/src/shaders/coverageBand.slang +64 -32
- package/src/shaders/coverageBar.generated.ts +6 -5
- package/src/shaders/coverageBar.glsl.generated.ts +6 -0
- package/src/shaders/coverageBar.iface.generated.ts +1 -1
- package/src/shaders/coverageBar.slang +10 -10
- package/src/shaders/coverageBar.wgsl.generated.ts +4 -0
- package/src/shaders/coverageClip.generated.ts +11 -0
- package/src/shaders/coverageClip.glsl.generated.ts +6 -0
- package/src/shaders/coverageClip.iface.generated.ts +172 -0
- package/src/shaders/coverageClip.slang +38 -0
- package/src/shaders/coverageClip.wgsl.generated.ts +4 -0
- package/src/shaders/coverageIndicator.generated.ts +6 -5
- package/src/shaders/coverageIndicator.glsl.generated.ts +6 -0
- package/src/shaders/coverageIndicator.iface.generated.ts +1 -1
- package/src/shaders/coverageIndicator.wgsl.generated.ts +4 -0
- package/src/shaders/coverageInterbase.generated.ts +6 -5
- package/src/shaders/coverageInterbase.glsl.generated.ts +6 -0
- package/src/shaders/coverageInterbase.iface.generated.ts +1 -1
- package/src/shaders/coverageInterbase.wgsl.generated.ts +4 -0
- package/src/shaders/coverageMod.generated.ts +6 -5
- package/src/shaders/coverageMod.glsl.generated.ts +6 -0
- package/src/shaders/coverageMod.iface.generated.ts +1 -1
- package/src/shaders/coverageMod.wgsl.generated.ts +4 -0
- package/src/shaders/coverageSnp.generated.ts +6 -5
- package/src/shaders/coverageSnp.glsl.generated.ts +6 -0
- package/src/shaders/coverageSnp.iface.generated.ts +1 -1
- package/src/shaders/coverageSnp.wgsl.generated.ts +4 -0
- package/src/shaders/curveDistance.js.generated.ts +91 -0
- package/src/shaders/curveDistance.slang +265 -0
- package/src/shaders/hpClampFloor.test.ts +87 -0
- package/src/shaders/hpmath.js.generated.ts +6 -2
- package/src/shaders/hpmath.slang +100 -48
- package/src/shaders/insetValueScale.test.ts +67 -0
- package/src/shaders/lineCenterMark.generated.ts +11 -0
- package/src/shaders/lineCenterMark.glsl.generated.ts +6 -0
- package/src/shaders/lineCenterMark.iface.generated.ts +328 -0
- package/src/shaders/lineCenterMark.slang +127 -0
- package/src/shaders/lineCenterMark.wgsl.generated.ts +4 -0
- package/src/shaders/lineCommon.generated.ts +6 -0
- package/src/shaders/lineCommon.slang +102 -0
- package/src/shaders/lineStepMark.generated.ts +11 -0
- package/src/shaders/lineStepMark.glsl.generated.ts +6 -0
- package/src/shaders/lineStepMark.iface.generated.ts +311 -0
- package/src/shaders/lineStepMark.slang +125 -0
- package/src/shaders/lineStepMark.wgsl.generated.ts +4 -0
- package/src/shaders/linkMark.consts.generated.ts +30 -0
- package/src/shaders/linkMark.generated.ts +12 -0
- package/src/shaders/linkMark.glsl.generated.ts +6 -0
- package/src/shaders/linkMark.iface.generated.ts +1954 -0
- package/src/shaders/linkMark.js.generated.ts +167 -0
- package/src/shaders/linkMark.slang +439 -0
- package/src/shaders/linkMark.wgsl.generated.ts +4 -0
- package/src/shaders/markColor.generated.ts +20 -0
- package/src/shaders/markColor.slang +128 -0
- package/src/shaders/pointGlyph.js.generated.ts +20 -0
- package/src/shaders/pointGlyph.slang +23 -7
- package/src/shaders/pointGlyphPad.test.ts +242 -0
- package/src/shaders/pointMark.consts.generated.ts +16 -0
- package/src/shaders/pointMark.generated.ts +12 -0
- package/src/shaders/pointMark.glsl.generated.ts +6 -0
- package/src/shaders/pointMark.iface.generated.ts +304 -0
- package/src/shaders/pointMark.js.generated.ts +99 -0
- package/src/shaders/pointMark.slang +227 -0
- package/src/shaders/pointMark.wgsl.generated.ts +4 -0
- package/src/shaders/rowRect.generated.ts +0 -2
- package/src/shaders/rowRect.slang +39 -58
- package/src/shaders/rowTable.generated.ts +4 -0
- package/src/shaders/rowTable.js.generated.ts +37 -0
- package/src/shaders/rowTable.slang +98 -0
- package/src/shaders/scoreScale.generated.ts +6 -0
- package/src/shaders/scoreScale.js.generated.ts +48 -23
- package/src/shaders/scoreScale.slang +49 -55
- package/src/shaders/sdEllipse.test.ts +211 -0
- package/src/shaders/spanMark.generated.ts +11 -0
- package/src/shaders/spanMark.glsl.generated.ts +6 -0
- package/src/shaders/spanMark.iface.generated.ts +289 -0
- package/src/shaders/spanMark.slang +77 -0
- package/src/shaders/spanMark.wgsl.generated.ts +4 -0
- package/src/shaders/valueScale.slang +26 -0
- package/src/shaders/wideCircleLeg.test.ts +85 -0
- package/esm/globalRenderingBackend.d.ts +0 -90
- package/esm/globalRenderingBackend.js +0 -53
- package/esm/keyedRenderingBackend.d.ts +0 -41
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
2
|
import { isAlive, isStateTreeNode } from '@jbrowse/mobx-state-tree';
|
|
3
|
+
import { createGpuContextLostError, createGpuDeviceLostError, } from './gpuContextLostError.js';
|
|
3
4
|
import { onDeviceLost } from './gpuDevice.js';
|
|
4
5
|
import { RecoveryBudget } from './recoveryBudget.js';
|
|
5
6
|
import { useTabVisibilityRerender } from './useTabVisibilityRerender.js';
|
|
@@ -23,30 +24,41 @@ const CONTEXT_RECOVER_BASE_MS = 1000;
|
|
|
23
24
|
// causes (GPU crash, driver reset) and needs no banner at all. Nothing is
|
|
24
25
|
// aborted when the window expires, so this is not a readiness cap.
|
|
25
26
|
export const CONTEXT_LOST_REPORT_GRACE_MS = 400;
|
|
26
|
-
const CONTEXT_LOST_MESSAGE = 'WebGL context lost. The browser reclaimed the GPU context for this display, ' +
|
|
27
|
-
'usually because too many GPU-rendered views are open at once.';
|
|
28
|
-
const DEVICE_LOST_MESSAGE = 'WebGPU device lost. The GPU device backing this display went away and kept ' +
|
|
29
|
-
'going away after several attempts to rebuild on a fresh one.';
|
|
30
27
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* offering it for render errors whose remedy differs (an over-allocation says to
|
|
34
|
-
* zoom in).
|
|
28
|
+
* How far past its scroll port a canvas keeps its GPU targets, as a fraction of
|
|
29
|
+
* the port on each edge.
|
|
35
30
|
*
|
|
36
|
-
* A
|
|
37
|
-
*
|
|
31
|
+
* A band, where `useViewVisibility`'s hard window deliberately has none, and the
|
|
32
|
+
* reason that file gives does not reach here. There the band roughly doubles
|
|
33
|
+
* live WebGL2 contexts against a hard ceiling of 16, so it costs a resource the
|
|
34
|
+
* page runs out of; here it costs bytes, and bytes have no cliff. What the band
|
|
35
|
+
* buys is the frame: intersection callbacks are delivered after the frame that
|
|
36
|
+
* moved the canvas has painted, so a hard edge shows one blank frame on the way
|
|
37
|
+
* back in. Repainting a quarter of a port early puts the redraw several frames
|
|
38
|
+
* ahead of the pixels at any ordinary scroll speed.
|
|
38
39
|
*/
|
|
39
|
-
export
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
40
|
+
export const OFFSCREEN_RELEASE_BAND = '25%';
|
|
41
|
+
/**
|
|
42
|
+
* The nearest ancestor that scrolls `el`, which is what the observer has to be
|
|
43
|
+
* rooted at. Rooting at the viewport would make {@link OFFSCREEN_RELEASE_BAND}
|
|
44
|
+
* inert: an observer clips the target against every scrolling ancestor before
|
|
45
|
+
* it intersects the root box the margin expands, and JBrowse's views scroll
|
|
46
|
+
* inside a container in all three hosts (the classic stack, a workspace panel,
|
|
47
|
+
* a bounded embed). Null where nothing above it scrolls, which is the page-
|
|
48
|
+
* scrolling embed, and there the viewport root takes the margin directly.
|
|
49
|
+
*/
|
|
50
|
+
function scrollPortOf(el) {
|
|
51
|
+
let node = el.parentElement;
|
|
52
|
+
while (node) {
|
|
53
|
+
const { overflowY } = getComputedStyle(node);
|
|
54
|
+
if (overflowY === 'auto' || overflowY === 'scroll') {
|
|
55
|
+
return node;
|
|
56
|
+
}
|
|
57
|
+
node = node.parentElement;
|
|
58
|
+
}
|
|
59
|
+
return null;
|
|
49
60
|
}
|
|
61
|
+
export { createGpuContextLostError, createGpuDeviceLostError, createGpuSurfaceLostError, isGpuContextLostError, } from './gpuContextLostError.js';
|
|
50
62
|
/**
|
|
51
63
|
* The display's recovery budget, created on first read. Reached through the ref
|
|
52
64
|
* at every use site rather than unwrapped once in the hook body: the unwrapped
|
|
@@ -375,6 +387,32 @@ export function useRenderingBackend(factory, model) {
|
|
|
375
387
|
}
|
|
376
388
|
return undefined;
|
|
377
389
|
}, [canvas, contextVersion, factory, model]);
|
|
390
|
+
// Watch the canvas rather than the track container: the canvas is the element
|
|
391
|
+
// whose size the released targets were allocated for, so this is the one
|
|
392
|
+
// signal for every display in every view, with no view-level plumbing. Where
|
|
393
|
+
// `IntersectionObserver` is missing (jsdom, SSR) nothing ever sets the flag
|
|
394
|
+
// and the display draws exactly as it did before.
|
|
395
|
+
useEffect(() => {
|
|
396
|
+
if (canvas && typeof IntersectionObserver !== 'undefined') {
|
|
397
|
+
const observer = new IntersectionObserver(entries => {
|
|
398
|
+
const entry = entries.at(-1);
|
|
399
|
+
if (entry && nodeAlive(model)) {
|
|
400
|
+
model.setOffScreen(!entry.isIntersecting);
|
|
401
|
+
}
|
|
402
|
+
}, {
|
|
403
|
+
root: scrollPortOf(canvas),
|
|
404
|
+
rootMargin: `${OFFSCREEN_RELEASE_BAND} 0px`,
|
|
405
|
+
});
|
|
406
|
+
observer.observe(canvas);
|
|
407
|
+
return () => {
|
|
408
|
+
observer.disconnect();
|
|
409
|
+
if (nodeAlive(model)) {
|
|
410
|
+
model.setOffScreen(false);
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
return undefined;
|
|
415
|
+
}, [canvas, model]);
|
|
378
416
|
useTabVisibilityRerender(() => {
|
|
379
417
|
if (nodeAlive(model)) {
|
|
380
418
|
model.renderNow();
|
package/esm/webgpuUtils.d.ts
CHANGED
|
@@ -1,15 +1,7 @@
|
|
|
1
|
+
import type { ShaderStage } from './hal/types.ts';
|
|
1
2
|
export declare const STANDARD_BLEND_STATE: GPUBlendState;
|
|
2
|
-
/**
|
|
3
|
-
|
|
4
|
-
* This bind group is intended for use with shaders generated by Slang,
|
|
5
|
-
* which typically place uniforms at binding index 1.
|
|
6
|
-
* @param device - The GPUDevice.
|
|
7
|
-
* @param layout - `DeviceLayouts.uniformOnlyBindGroupLayout`.
|
|
8
|
-
* @param uniformBuffer - The GPUBuffer containing the uniform data.
|
|
9
|
-
* @param uniformVisibleSize - The visible size of the uniform buffer.
|
|
10
|
-
* @returns The GPUBindGroup.
|
|
11
|
-
*/
|
|
12
|
-
export declare function createUniformOnlyBindGroup(device: GPUDevice, layout: GPUBindGroupLayout, uniformBuffer: GPUBuffer, uniformVisibleSize: number): GPUBindGroup;
|
|
3
|
+
/** A layout entry's `visibility`: the stages its shader reads the binding in. */
|
|
4
|
+
export declare function stageVisibility(stages: readonly ShaderStage[]): number;
|
|
13
5
|
export declare function createVertexBuffer(device: GPUDevice, data: ArrayBuffer | ArrayBufferView): GPUBuffer;
|
|
14
6
|
/**
|
|
15
7
|
* Converts one entry of a pass's vertex input layout to a WebGPU vertex format
|
package/esm/webgpuUtils.js
CHANGED
|
@@ -19,39 +19,18 @@ export const STANDARD_BLEND_STATE = {
|
|
|
19
19
|
operation: 'add',
|
|
20
20
|
},
|
|
21
21
|
};
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
* which typically place uniforms at binding index 1.
|
|
35
|
-
* @param device - The GPUDevice.
|
|
36
|
-
* @param layout - `DeviceLayouts.uniformOnlyBindGroupLayout`.
|
|
37
|
-
* @param uniformBuffer - The GPUBuffer containing the uniform data.
|
|
38
|
-
* @param uniformVisibleSize - The visible size of the uniform buffer.
|
|
39
|
-
* @returns The GPUBindGroup.
|
|
40
|
-
*/
|
|
41
|
-
export function createUniformOnlyBindGroup(device, layout, uniformBuffer, uniformVisibleSize) {
|
|
42
|
-
return device.createBindGroup({
|
|
43
|
-
layout,
|
|
44
|
-
entries: [
|
|
45
|
-
{
|
|
46
|
-
binding: 1, // Standard binding for uniforms generated by Slang codegen.
|
|
47
|
-
resource: {
|
|
48
|
-
buffer: uniformBuffer,
|
|
49
|
-
offset: 0,
|
|
50
|
-
size: uniformVisibleSize,
|
|
51
|
-
},
|
|
52
|
-
},
|
|
53
|
-
],
|
|
54
|
-
});
|
|
22
|
+
const STAGE_FLAG = {
|
|
23
|
+
vertex: 'VERTEX',
|
|
24
|
+
fragment: 'FRAGMENT',
|
|
25
|
+
compute: 'COMPUTE',
|
|
26
|
+
};
|
|
27
|
+
/** A layout entry's `visibility`: the stages its shader reads the binding in. */
|
|
28
|
+
export function stageVisibility(stages) {
|
|
29
|
+
let mask = 0;
|
|
30
|
+
for (const stage of stages) {
|
|
31
|
+
mask |= GPUShaderStage[STAGE_FLAG[stage]];
|
|
32
|
+
}
|
|
33
|
+
return mask;
|
|
55
34
|
}
|
|
56
35
|
export function createVertexBuffer(device, data) {
|
|
57
36
|
const buf = device.createBuffer({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jbrowse/render-core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0-beta.10",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "GPU/Canvas2D rendering primitives for JBrowse displays: the HAL, the draw-lifecycle mixin, per-region/global backend bases, and the React backend hooks",
|
|
6
6
|
"keywords": [
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"directory": "packages/render-core"
|
|
20
20
|
},
|
|
21
21
|
"author": "JBrowse Team",
|
|
22
|
-
"//files": "src/shaders ships the shared .slang modules (hpmath, antialias, capsule, colorPack, coverageBand, diagonalGrid, pointGlyph, rowRect, scoreScale) that any shader imports, plus the coverage-band entry-point passes drawn by two plugins. @jbrowse/shader-tools resolves its include path here, so an out-of-tree plugin can compile its own .slang against them.",
|
|
22
|
+
"//files": "src/shaders ships the shared .slang modules (hpmath, antialias, capsule, colorPack, coverageBand, diagonalGrid, markColor, pointGlyph, rowRect, scoreScale, valueScale) that any shader imports, plus the coverage-band entry-point passes drawn by two plugins. @jbrowse/shader-tools resolves its include path here, so an out-of-tree plugin can compile its own .slang against them.",
|
|
23
23
|
"files": [
|
|
24
24
|
"esm",
|
|
25
25
|
"src/shaders"
|
|
@@ -31,47 +31,72 @@
|
|
|
31
31
|
"./canvas2dUtils": "./esm/canvas2dUtils.js",
|
|
32
32
|
"./canvasContext": "./esm/canvasContext.js",
|
|
33
33
|
"./colorRampLut": "./esm/colorRampLut.js",
|
|
34
|
+
"./contractReports": "./esm/contractReports.js",
|
|
34
35
|
"./coverageBand": "./esm/coverageBand.js",
|
|
36
|
+
"./computePipeline": "./esm/computePipeline.js",
|
|
35
37
|
"./coverageBandBuffers": "./esm/coverageBandBuffers.js",
|
|
36
38
|
"./createRenderingBackend": "./esm/createRenderingBackend.js",
|
|
37
39
|
"./displayPhase": "./esm/displayPhase.js",
|
|
38
|
-
"./
|
|
40
|
+
"./encodeMemo": "./esm/encodeMemo.js",
|
|
39
41
|
"./gpuDevice": "./esm/gpuDevice.js",
|
|
40
42
|
"./graphicsCapabilities": "./esm/graphicsCapabilities.js",
|
|
41
43
|
"./hal": "./esm/hal/index.js",
|
|
42
44
|
"./installUpload": "./esm/installUpload.js",
|
|
43
45
|
"./instanceCache": "./esm/instanceCache.js",
|
|
44
46
|
"./instancePass": "./esm/instancePass.js",
|
|
45
|
-
"./
|
|
47
|
+
"./marks": "./esm/marks/index.js",
|
|
48
|
+
"./marks/ellipseDistance": "./esm/marks/ellipseDistance.js",
|
|
49
|
+
"./marks/backend": "./esm/marks/markBackend.js",
|
|
50
|
+
"./marks/colorFill": "./esm/marks/colorFill.js",
|
|
51
|
+
"./marks/drawAgainstHit": "./esm/marks/drawAgainstHit.js",
|
|
52
|
+
"./marks/glyphPaint": "./esm/marks/glyphPaint.js",
|
|
53
|
+
"./marks/hit": "./esm/marks/markHit.js",
|
|
46
54
|
"./namedReactions": "./esm/namedReactions.js",
|
|
47
55
|
"./OverlayCanvas": "./esm/OverlayCanvas.js",
|
|
48
56
|
"./perRegionRenderingBackend": "./esm/perRegionRenderingBackend.js",
|
|
49
57
|
"./regionDataMap": "./esm/regionDataMap.js",
|
|
50
58
|
"./renderBlock": "./esm/renderBlock.js",
|
|
51
59
|
"./renderingBackendBase": "./esm/renderingBackendBase.js",
|
|
60
|
+
"./scoreScale": "./esm/scoreScale.js",
|
|
52
61
|
"./ScrollLockedOverlay": "./esm/ScrollLockedOverlay.js",
|
|
62
|
+
"./sharedBackendKey": "./esm/sharedBackendKey.js",
|
|
53
63
|
"./shaders/antialias": "./esm/shaders/antialias.js.generated.js",
|
|
64
|
+
"./shaders/barMarkIface": "./esm/shaders/barMark.iface.generated.js",
|
|
65
|
+
"./shaders/capsule": "./esm/shaders/capsule.js.generated.js",
|
|
54
66
|
"./shaders/capsuleConsts": "./esm/shaders/capsule.generated.js",
|
|
55
|
-
"./shaders/
|
|
67
|
+
"./shaders/clipStrip": "./esm/shaders/clipStrip.js.generated.js",
|
|
68
|
+
"./shaders/clipStripConsts": "./esm/shaders/clipStrip.generated.js",
|
|
69
|
+
"./shaders/colorRampLut": "./esm/shaders/colorRampLut.js.generated.js",
|
|
56
70
|
"./shaders/coverageBar": "./esm/shaders/coverageBar.generated.js",
|
|
57
71
|
"./shaders/coverageIndicator": "./esm/shaders/coverageIndicator.generated.js",
|
|
58
72
|
"./shaders/coverageInterbase": "./esm/shaders/coverageInterbase.generated.js",
|
|
59
73
|
"./shaders/coverageMod": "./esm/shaders/coverageMod.generated.js",
|
|
60
74
|
"./shaders/coverageSnp": "./esm/shaders/coverageSnp.generated.js",
|
|
75
|
+
"./shaders/curveDistance": "./esm/shaders/curveDistance.js.generated.js",
|
|
61
76
|
"./shaders/hpmath": "./esm/shaders/hpmath.js.generated.js",
|
|
77
|
+
"./shaders/linkMark": "./esm/shaders/linkMark.js.generated.js",
|
|
78
|
+
"./shaders/lineCenterMarkIface": "./esm/shaders/lineCenterMark.iface.generated.js",
|
|
79
|
+
"./shaders/lineCommonConsts": "./esm/shaders/lineCommon.generated.js",
|
|
80
|
+
"./shaders/lineStepMarkIface": "./esm/shaders/lineStepMark.iface.generated.js",
|
|
81
|
+
"./shaders/linkMarkConsts": "./esm/shaders/linkMark.consts.generated.js",
|
|
62
82
|
"./shaders/pointGlyph": "./esm/shaders/pointGlyph.js.generated.js",
|
|
63
83
|
"./shaders/pointGlyphConsts": "./esm/shaders/pointGlyph.generated.js",
|
|
84
|
+
"./shaders/pointMark": "./esm/shaders/pointMark.js.generated.js",
|
|
85
|
+
"./shaders/pointMarkIface": "./esm/shaders/pointMark.iface.generated.js",
|
|
86
|
+
"./shaders/markColorConsts": "./esm/shaders/markColor.generated.js",
|
|
87
|
+
"./shaders/pointMarkConsts": "./esm/shaders/pointMark.consts.generated.js",
|
|
64
88
|
"./shaders/rowRect": "./esm/shaders/rowRect.js.generated.js",
|
|
65
89
|
"./shaders/rowRectConsts": "./esm/shaders/rowRect.generated.js",
|
|
66
90
|
"./shaders/scoreScale": "./esm/shaders/scoreScale.js.generated.js",
|
|
91
|
+
"./shaders/spanMarkIface": "./esm/shaders/spanMark.iface.generated.js",
|
|
67
92
|
"./slangPass": "./esm/slangPass.js",
|
|
68
93
|
"./useGraphicsCapabilities": "./esm/useGraphicsCapabilities.js",
|
|
69
94
|
"./useRenderingBackend": "./esm/useRenderingBackend.js",
|
|
70
95
|
"./useTabVisibilityRerender": "./esm/useTabVisibilityRerender.js"
|
|
71
96
|
},
|
|
72
97
|
"dependencies": {
|
|
73
|
-
"@jbrowse/mobx-state-tree": "^6.
|
|
74
|
-
"mobx": "^7.0.
|
|
98
|
+
"@jbrowse/mobx-state-tree": "^6.6.1",
|
|
99
|
+
"mobx": "^7.0.5"
|
|
75
100
|
},
|
|
76
101
|
"peerDependencies": {
|
|
77
102
|
"react": ">=19.0.0"
|
|
@@ -52,6 +52,8 @@
|
|
|
52
52
|
// and then agreeing with its own copy, which is what dotplotCapsulePad.test.ts
|
|
53
53
|
// and syntenyFillPad.test.ts each did.
|
|
54
54
|
//! js-export: aaPx, aaHalfPx, aaRamp, edgeCoverage
|
|
55
|
+
//! js-skip: dashCoverageAt — one axis along: the other two backends dash through setLineDash and stroke-dasharray, which take the period rather than a coverage, so what they must agree on is each mark's dash and gap lengths
|
|
56
|
+
//! js-skip: dashCoverage — the dpr wrapper over dashCoverageAt, so it inherits that entry's reason exactly
|
|
55
57
|
module antialias;
|
|
56
58
|
|
|
57
59
|
// Width of a ramp covering exactly one output pixel, in CSS px. THE conversion
|
|
@@ -110,3 +112,47 @@ public float edgeCoverage(float signedInkCssPx, float dpr) {
|
|
|
110
112
|
public float glyphEdgeAlpha(float coverage) {
|
|
111
113
|
return aaRamp(coverage, aaGradient(coverage));
|
|
112
114
|
}
|
|
115
|
+
|
|
116
|
+
// Coverage of a `dashPx` on / `gapPx` off pattern at `coord` CSS px along the
|
|
117
|
+
// mark, with the ON run starting at coord 0 — the phase `ctx.setLineDash` and
|
|
118
|
+
// `stroke-dasharray` give, so the three backends dash alike.
|
|
119
|
+
//
|
|
120
|
+
// The rotation is what makes both ends soft, and both halves of it were got
|
|
121
|
+
// wrong here before. Measuring `min(phase, dashPx - phase)` straight off the
|
|
122
|
+
// wrap ramps a dash's TRAILING edge and steps its LEADING edge 0 -> 0.5 in no
|
|
123
|
+
// distance at all; rotating the run to the middle of the period fixes that but
|
|
124
|
+
// then ramping over a constant 1 CSS px is two device px on a dpr=2 display —
|
|
125
|
+
// twice the softness of the sides of the very same line. Centring the run at
|
|
126
|
+
// half a period puts the wrap deep in the gap where nothing is drawn, and
|
|
127
|
+
// `aaPx(dpr)` is the sides' own ramp.
|
|
128
|
+
//
|
|
129
|
+
// The reduction is `t - period * floor(t / period)` rather than the obvious
|
|
130
|
+
// `frac(t / period) * period`, which are the same number only in exact
|
|
131
|
+
// arithmetic. `frac` drops the integer part BEFORE multiplying back, so what
|
|
132
|
+
// the quotient lost to rounding survives and gets scaled by the period;
|
|
133
|
+
// subtracting the floored multiple keeps it, because THAT subtraction is exact
|
|
134
|
+
// — its operands are within a period of each other, so nothing falls off the
|
|
135
|
+
// end. Same op count, once `frac`'s own `floor` is counted.
|
|
136
|
+
//
|
|
137
|
+
// This is not a visible fix and don't sell it as one: swept against the old
|
|
138
|
+
// spelling in float32 over both passes' whole coordinate range at dpr 1-4, the
|
|
139
|
+
// two differ by at most 9.8e-4 of alpha and not one 8-bit pixel changes.
|
|
140
|
+
//
|
|
141
|
+
// It is a refereeable one, which the old spelling was not. check-oracle takes
|
|
142
|
+
// every emittable scalar signature, not only the `//! js-export`ed ones, so a
|
|
143
|
+
// scalar core here is swept whether or not anything imports it — and the `frac`
|
|
144
|
+
// spelling missed the 1e-5 relative on 18 of its 2400 tuples, including
|
|
145
|
+
// in-domain ones like `(255, 2.5, 0.5, 0.25)`, a real screen px at dpr=4. The
|
|
146
|
+
// choice was a function nobody can check or a one-line change that costs
|
|
147
|
+
// nothing, so: the dash geometry is now under the CI gate.
|
|
148
|
+
public float dashCoverageAt(
|
|
149
|
+
float coord, float dashPx, float gapPx, float aaPx) {
|
|
150
|
+
float period = dashPx + gapPx;
|
|
151
|
+
float shifted = coord + gapPx * 0.5;
|
|
152
|
+
float phase = shifted - period * floor(shifted / period);
|
|
153
|
+
return aaRamp(dashPx * 0.5 - abs(phase - period * 0.5), aaPx);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
public float dashCoverage(float coord, float dashPx, float gapPx, float dpr) {
|
|
157
|
+
return dashCoverageAt(coord, dashPx, gapPx, aaPx(dpr));
|
|
158
|
+
}
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
// The arc hull has to cover every point the fragment paints above the band's
|
|
2
|
+
// anchor, or the rasterizer hard-cuts ink that no sample count is left to
|
|
3
|
+
// smooth — `linkMark.slang` declares `//! coverage: analytic`. Ink is sampled
|
|
4
|
+
// along the curve's normals, which reach every point within the pad, and each
|
|
5
|
+
// sample is tested against the strip's triangles as `linkMark.slang` emits
|
|
6
|
+
// them. The vertices come from `curveDistance.slang`'s
|
|
7
|
+
// own emitted twins.
|
|
8
|
+
import { ellipseDistance } from '../marks/ellipseDistance.ts'
|
|
9
|
+
import { aaHalfPx, edgeCoverage } from './antialias.js.generated.ts'
|
|
10
|
+
import {
|
|
11
|
+
distToWideCirclePx,
|
|
12
|
+
ellipseHullPoint,
|
|
13
|
+
wideCircleHullPoint,
|
|
14
|
+
wideCircleLeg,
|
|
15
|
+
wideCircleLegStep,
|
|
16
|
+
} from './curveDistance.js.generated.ts'
|
|
17
|
+
import { LINK_CURVE_SEGMENTS } from './linkMark.consts.generated.ts'
|
|
18
|
+
|
|
19
|
+
type Pt = readonly [number, number]
|
|
20
|
+
type Tri = readonly [Pt, Pt, Pt]
|
|
21
|
+
|
|
22
|
+
// Float64 rounding, and the band's anchor row: `sin(PI)` leaves the far foot's
|
|
23
|
+
// vertices 1e-15 px off the baseline, and no pixel centre sits that low.
|
|
24
|
+
const EXACT = 1e-9
|
|
25
|
+
|
|
26
|
+
// `arcStrokeHalfPx` / `linkStrokeWidthPx`: no arc is thinner than 1.5 device px.
|
|
27
|
+
const strokeHalfPx = (dpr: number, lineWidthPx: number) =>
|
|
28
|
+
Math.max(lineWidthPx, 1.5 / dpr) / 2
|
|
29
|
+
|
|
30
|
+
function inTri(p: Pt, [a, b, c]: Tri) {
|
|
31
|
+
const d1 = (p[0] - b[0]) * (a[1] - b[1]) - (a[0] - b[0]) * (p[1] - b[1])
|
|
32
|
+
const d2 = (p[0] - c[0]) * (b[1] - c[1]) - (b[0] - c[0]) * (p[1] - c[1])
|
|
33
|
+
const d3 = (p[0] - a[0]) * (c[1] - a[1]) - (c[0] - a[0]) * (p[1] - a[1])
|
|
34
|
+
return !((d1 < 0 || d2 < 0 || d3 < 0) && (d1 > 0 || d2 > 0 || d3 > 0))
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Vertex pairs in the order `vs_main` emits them, inner flank first.
|
|
38
|
+
function stripTriangles(pairs: (readonly [Pt, Pt])[]) {
|
|
39
|
+
const verts = pairs.flat()
|
|
40
|
+
const tris: Tri[] = []
|
|
41
|
+
for (let i = 0; i + 2 < verts.length; i++) {
|
|
42
|
+
tris.push([verts[i]!, verts[i + 1]!, verts[i + 2]!])
|
|
43
|
+
}
|
|
44
|
+
return tris
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Buckets the triangles by x so a sample tests only its neighbours.
|
|
48
|
+
function coverIndex(tris: Tri[]) {
|
|
49
|
+
const xs = tris.flatMap(t => t.map(p => p[0]))
|
|
50
|
+
const lo = Math.min(...xs)
|
|
51
|
+
const width = Math.max((Math.max(...xs) - lo) / 4096, 1e-9)
|
|
52
|
+
const buckets = new Map<number, Tri[]>()
|
|
53
|
+
for (const t of tris) {
|
|
54
|
+
const tx = t.map(p => p[0])
|
|
55
|
+
const b0 = Math.floor((Math.min(...tx) - lo) / width)
|
|
56
|
+
const b1 = Math.floor((Math.max(...tx) - lo) / width)
|
|
57
|
+
for (let b = b0; b <= b1; b++) {
|
|
58
|
+
const list = buckets.get(b) ?? []
|
|
59
|
+
list.push(t)
|
|
60
|
+
buckets.set(b, list)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return (p: Pt) =>
|
|
64
|
+
(buckets.get(Math.floor((p[0] - lo) / width)) ?? []).some(t => inTri(p, t))
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function worstUncovered(
|
|
68
|
+
covered: (p: Pt) => boolean,
|
|
69
|
+
samples: Iterable<Pt>,
|
|
70
|
+
alpha: (p: Pt) => number,
|
|
71
|
+
) {
|
|
72
|
+
let worst = 0
|
|
73
|
+
for (const p of samples) {
|
|
74
|
+
if (!covered(p)) {
|
|
75
|
+
worst = Math.max(worst, alpha(p))
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return worst
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// A far leg's chords sag by thousandths of a px, so the offsets close in on
|
|
82
|
+
// both edges of the ink as well as crossing it.
|
|
83
|
+
const OFFSETS = [
|
|
84
|
+
...Array.from({ length: 21 }, (_, j) => j / 10 - 1),
|
|
85
|
+
...Array.from({ length: 24 }, (_, k) => 1 - 2 ** -(k + 1)).flatMap(t => [
|
|
86
|
+
t,
|
|
87
|
+
-t,
|
|
88
|
+
]),
|
|
89
|
+
]
|
|
90
|
+
|
|
91
|
+
function* alongNormals(
|
|
92
|
+
count: number,
|
|
93
|
+
pad: number,
|
|
94
|
+
at: (u: number) => readonly [Pt, Pt],
|
|
95
|
+
keep: (p: Pt) => boolean,
|
|
96
|
+
) {
|
|
97
|
+
for (let i = 0; i <= count; i++) {
|
|
98
|
+
const [p, n] = at(i / count)
|
|
99
|
+
for (const offset of OFFSETS) {
|
|
100
|
+
const t = pad * offset
|
|
101
|
+
const q = [p[0] + n[0] * t, p[1] + n[1] * t] as const
|
|
102
|
+
if (keep(q)) {
|
|
103
|
+
yield q
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function worstOnDome(
|
|
110
|
+
rx: number,
|
|
111
|
+
ry: number,
|
|
112
|
+
dpr: number,
|
|
113
|
+
lineWidthPx: number,
|
|
114
|
+
segs: number,
|
|
115
|
+
) {
|
|
116
|
+
const half = strokeHalfPx(dpr, lineWidthPx)
|
|
117
|
+
const pad = half + aaHalfPx(dpr)
|
|
118
|
+
const h = Math.PI / (2 * segs)
|
|
119
|
+
const vertex = (seg: number, flankPad: number) => {
|
|
120
|
+
const a = (seg / segs) * Math.PI
|
|
121
|
+
return ellipseHullPoint(
|
|
122
|
+
Math.cos(a),
|
|
123
|
+
Math.sin(a),
|
|
124
|
+
Math.cos(h),
|
|
125
|
+
Math.sin(h),
|
|
126
|
+
rx,
|
|
127
|
+
ry,
|
|
128
|
+
flankPad,
|
|
129
|
+
)
|
|
130
|
+
}
|
|
131
|
+
const pairs: (readonly [Pt, Pt])[] = []
|
|
132
|
+
for (let seg = 0; seg <= segs; seg++) {
|
|
133
|
+
pairs.push([vertex(seg, -pad), vertex(seg, pad)])
|
|
134
|
+
}
|
|
135
|
+
const samples = alongNormals(
|
|
136
|
+
2000,
|
|
137
|
+
pad,
|
|
138
|
+
u => {
|
|
139
|
+
const a = u * Math.PI
|
|
140
|
+
const g = Math.hypot(ry * Math.cos(a), rx * Math.sin(a)) || 1
|
|
141
|
+
return [
|
|
142
|
+
[rx * Math.cos(a), ry * Math.sin(a)],
|
|
143
|
+
[(ry * Math.cos(a)) / g, (rx * Math.sin(a)) / g],
|
|
144
|
+
]
|
|
145
|
+
},
|
|
146
|
+
p => p[1] > EXACT,
|
|
147
|
+
)
|
|
148
|
+
return worstUncovered(coverIndex(stripTriangles(pairs)), samples, p =>
|
|
149
|
+
edgeCoverage(half - ellipseDistance(p[0], p[1], rx, ry), dpr),
|
|
150
|
+
)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Each leg in its own foot frame, which is how `vs_main` mirrors them.
|
|
154
|
+
function worstOnLegs(
|
|
155
|
+
r: number,
|
|
156
|
+
reachPx: number,
|
|
157
|
+
dpr: number,
|
|
158
|
+
lineWidthPx: number,
|
|
159
|
+
segs: number,
|
|
160
|
+
) {
|
|
161
|
+
const half = strokeHalfPx(dpr, lineWidthPx)
|
|
162
|
+
const pad = half + aaHalfPx(dpr)
|
|
163
|
+
const sweep = Math.asin(Math.min(1, (reachPx + pad) / r))
|
|
164
|
+
const legs = new Map<number, (readonly [Pt, Pt])[]>()
|
|
165
|
+
for (let seg = 0; seg <= segs; seg++) {
|
|
166
|
+
const [side, b] = wideCircleLeg(seg, segs, sweep)
|
|
167
|
+
const cosHalf = Math.cos(0.5 * wideCircleLegStep(seg, segs, sweep))
|
|
168
|
+
const at = (flankPad: number) =>
|
|
169
|
+
wideCircleHullPoint(Math.sin(b), Math.sin(b / 2), cosHalf, r, flankPad)
|
|
170
|
+
legs.set(side, [...(legs.get(side) ?? []), [at(-pad), at(pad)]])
|
|
171
|
+
}
|
|
172
|
+
let worst = 0
|
|
173
|
+
for (const pairs of legs.values()) {
|
|
174
|
+
const samples = alongNormals(
|
|
175
|
+
2000,
|
|
176
|
+
pad,
|
|
177
|
+
u => {
|
|
178
|
+
const b = u * sweep
|
|
179
|
+
return [
|
|
180
|
+
[-2 * r * Math.sin(b / 2) ** 2, r * Math.sin(b)],
|
|
181
|
+
[Math.cos(b), Math.sin(b)],
|
|
182
|
+
]
|
|
183
|
+
},
|
|
184
|
+
p => p[1] > EXACT && p[1] <= reachPx,
|
|
185
|
+
)
|
|
186
|
+
worst = Math.max(
|
|
187
|
+
worst,
|
|
188
|
+
worstUncovered(coverIndex(stripTriangles(pairs)), samples, p =>
|
|
189
|
+
edgeCoverage(half - distToWideCirclePx(p[0], p[1], r), dpr),
|
|
190
|
+
),
|
|
191
|
+
)
|
|
192
|
+
}
|
|
193
|
+
return worst
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Flat domes fold the inner offset at their feet, tall ones at their apex:
|
|
197
|
+
// `linkRadiiPx` ties ry to the band and rx to the pair, so either can win.
|
|
198
|
+
const DOMES = [
|
|
199
|
+
[1266, 25],
|
|
200
|
+
[1900, 12],
|
|
201
|
+
[633, 25],
|
|
202
|
+
[200, 25],
|
|
203
|
+
[1266, 114],
|
|
204
|
+
[3000, 8],
|
|
205
|
+
[1266, 0.5],
|
|
206
|
+
[40, 25],
|
|
207
|
+
[10, 10],
|
|
208
|
+
[10, 75],
|
|
209
|
+
[1, 100],
|
|
210
|
+
] as const
|
|
211
|
+
|
|
212
|
+
test.each(DOMES)('a %sx%s dome covers all of its ink', (rx, ry) => {
|
|
213
|
+
for (const dpr of [1, 1.5, 2]) {
|
|
214
|
+
for (const lineWidthPx of [0.5, 2, 6]) {
|
|
215
|
+
expect(
|
|
216
|
+
worstOnDome(rx, ry, dpr, lineWidthPx, LINK_CURVE_SEGMENTS),
|
|
217
|
+
).toBeLessThan(EXACT)
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
})
|
|
221
|
+
|
|
222
|
+
test.each([32, 128])('the dome is covered at %i segments too', segs => {
|
|
223
|
+
for (const [rx, ry] of DOMES) {
|
|
224
|
+
expect(worstOnDome(rx, ry, 2, 1, segs)).toBeLessThan(EXACT)
|
|
225
|
+
}
|
|
226
|
+
})
|
|
227
|
+
|
|
228
|
+
test.each([
|
|
229
|
+
[1900, 150],
|
|
230
|
+
[1900, 500],
|
|
231
|
+
[20000, 500],
|
|
232
|
+
[3e6, 150],
|
|
233
|
+
] as const)(
|
|
234
|
+
'a far pair at r=%s through a %spx reach covers its legs',
|
|
235
|
+
(r, reach) => {
|
|
236
|
+
for (const dpr of [1, 2]) {
|
|
237
|
+
for (const lineWidthPx of [1, 6]) {
|
|
238
|
+
expect(
|
|
239
|
+
worstOnLegs(r, reach, dpr, lineWidthPx, LINK_CURVE_SEGMENTS),
|
|
240
|
+
).toBeLessThan(EXACT)
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
},
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
// A collapsed band (`arcAvailH` floors at 0) hands the dome ry 0, where the
|
|
247
|
+
// foot's two normals are exactly opposed.
|
|
248
|
+
test('a zero-height dome stays finite', () => {
|
|
249
|
+
const h = Math.PI / (2 * LINK_CURVE_SEGMENTS)
|
|
250
|
+
for (let seg = 0; seg <= LINK_CURVE_SEGMENTS; seg++) {
|
|
251
|
+
const a = (seg / LINK_CURVE_SEGMENTS) * Math.PI
|
|
252
|
+
for (const pad of [0.625, -0.625]) {
|
|
253
|
+
const [x, y] = ellipseHullPoint(
|
|
254
|
+
Math.cos(a),
|
|
255
|
+
Math.sin(a),
|
|
256
|
+
Math.cos(h),
|
|
257
|
+
Math.sin(h),
|
|
258
|
+
1266,
|
|
259
|
+
0,
|
|
260
|
+
pad,
|
|
261
|
+
)
|
|
262
|
+
expect(Number.isFinite(x)).toBe(true)
|
|
263
|
+
expect(Number.isFinite(y)).toBe(true)
|
|
264
|
+
expect(Math.abs(x)).toBeLessThan(1e4)
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
})
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// AUTO-GENERATED by packages/shader-tools/src/shader-codegen from barMark.slang.
|
|
2
|
+
// Do not edit. Run `pnpm gen:shaders` to regenerate.
|
|
3
|
+
|
|
4
|
+
import type { ShaderSource } from '@jbrowse/render-core/hal'
|
|
5
|
+
|
|
6
|
+
export * from './barMark.iface.generated.ts'
|
|
7
|
+
|
|
8
|
+
export const SOURCE: ShaderSource = {
|
|
9
|
+
wgsl: () => import('./barMark.wgsl.generated.ts'),
|
|
10
|
+
glsl: () => import('./barMark.glsl.generated.ts'),
|
|
11
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// AUTO-GENERATED by packages/shader-tools/src/shader-codegen from barMark.slang.
|
|
2
|
+
// Do not edit. Run `pnpm gen:shaders` to regenerate.
|
|
3
|
+
|
|
4
|
+
export const GLSL_VERTEX = "#version 300 es\nprecision highp float;\nprecision highp int;\nprecision highp sampler2D;\n\n\n\nlayout(std140) uniform Uniforms\n{\n vec3 bpRangeX_0;\n float canvasHeight_0;\n float domainMin_0;\n float domainMax_0;\n int valueScaleType_0;\n float valueSymlogConstant_0;\n int rampMode_0;\n float rampMin_0;\n float rampMax_0;\n float rampMidNorm_0;\n int colorCutCount_0;\n vec4 colorCuts_0[2];\n vec4 colorBands_0[9];\n float originYPx_0;\n float rowHeight_0;\n float rowBandPx_0;\n float rowOffsetPx_0;\n float zero_0;\n float minCellDenomPx_0;\n float minWidthPx_0;\n float devicePixelRatio_0;\n int rowTableKeys_0;\n}u_0;\n\nuniform sampler2D u_colorRamp;\n\n\nuniform sampler2D u_rowTable;\n\n\nvec4 unpackRGBA_0(uint c_0)\n{\n\n return vec4(float((c_0 >> 0U) & 255U), float((c_0 >> 8U) & 255U), float((c_0 >> 16U) & 255U), float((c_0 >> 24U) & 255U)) / 255.0;\n}\n\n\nfloat rampMidT_0(float t_0, float mid_0)\n{\n\n float _S1 = max(mid_0, 1.0 - mid_0);\n return clamp((t_0 + (_S1 - mid_0)) / (2.0 * _S1), 0.0, 1.0);\n}\n\n\nfloat colorCutAt_0(int i_0, vec4 cutsLo_0, vec4 cutsHi_0)\n{\n\n float _S2;\n if(i_0 < 4)\n {\n\n _S2 = cutsLo_0[i_0];\n\n }\n else\n {\n\n _S2 = cutsHi_0[i_0 - 4];\n\n }\n\n return _S2;\n}\n\n\nint thresholdBand_0(float value_0, int cutCount_0, vec4 cutsLo_1, vec4 cutsHi_1)\n{\n\n int band_0 = 0;\n\n int i_1 = 0;\n\n for(;;)\n {\n\n if(i_1 < cutCount_0)\n {\n }\n else\n {\n\n break;\n }\n\n if(value_0 >= (colorCutAt_0(i_1, cutsLo_1, cutsHi_1)))\n {\n\n band_0 = i_1 + 1;\n\n }\n\n i_1 = i_1 + 1;\n\n }\n\n return band_0;\n}\n\n\nfloat log1pf_0(float x_0)\n{\n\n float u_1 = 1.0 + x_0;\n\n float _S3;\n if(u_1 == 1.0)\n {\n\n _S3 = x_0;\n\n }\n else\n {\n\n _S3 = log(u_1) * (x_0 / (u_1 - 1.0));\n\n }\n\n return _S3;\n}\n\nfloat symlogTransform_0(float x_1, float c_1)\n{\n\n return float((int(sign((x_1))))) * log1pf_0(abs(x_1 / c_1));\n}\n\n\nfloat normalizeScoreUnclamped_0(float score_0, float domainMin_1, float domainMax_1, int scaleType_0, float symlogConstant_0)\n{\n\n float tMax_0;\n\n float tMin_0;\n\n float t_1;\n\n\n\n if(scaleType_0 == 2)\n {\n\n float _S4 = symlogTransform_0(score_0, symlogConstant_0);\n float _S5 = symlogTransform_0(domainMin_1, symlogConstant_0);\n\n tMax_0 = symlogTransform_0(domainMax_1, symlogConstant_0);\n\n tMin_0 = _S5;\n\n t_1 = _S4;\n\n }\n else\n {\n\n if(scaleType_0 == 1)\n {\n if(domainMin_1 > 0.0)\n {\n\n tMax_0 = domainMin_1;\n\n }\n else\n {\n\n tMax_0 = 1.0;\n\n }\n float _S6 = log2(max(score_0, tMax_0));\n float _S7 = log2(tMax_0);\n\n tMax_0 = log2(max(domainMax_1, tMax_0));\n\n tMin_0 = _S7;\n\n t_1 = _S6;\n\n }\n else\n {\n\n tMax_0 = domainMax_1;\n\n tMin_0 = domainMin_1;\n\n t_1 = score_0;\n\n }\n\n }\n\n float tRange_0 = tMax_0 - tMin_0;\n if(tRange_0 <= 0.0)\n {\n\n if(t_1 > tMin_0)\n {\n\n tMax_0 = 1.0;\n\n }\n else\n {\n\n tMax_0 = 0.0;\n\n }\n\n return tMax_0;\n }\n return (t_1 - tMin_0) / tRange_0;\n}\n\nfloat normalizeScore_0(float score_1, float domainMin_2, float domainMax_2, int scaleType_1, float symlogConstant_1)\n{\n\n return clamp(normalizeScoreUnclamped_0(score_1, domainMin_2, domainMax_2, scaleType_1, symlogConstant_1), 0.0, 1.0);\n}\n\n\nuint rowTableWidth_0(uint keys_0)\n{\n\n return max(min(keys_0, 2048U), 1U);\n}\n\nuint rowTablePlaneHeight_0(uint keys_1)\n{\n\n uint w_0 = rowTableWidth_0(keys_1);\n uint _S8 = (keys_1 + w_0 - 1U) / w_0;\n\n return max(_S8, 1U);\n}\n\nuint rowTableTexelX_0(uint key_0, uint keys_2)\n{\n\n uint _S9 = key_0 % rowTableWidth_0(keys_2);\n\n return _S9;\n}\n\n\nuint rowTableTexelY_0(uint key_1, uint keys_3)\n{\n\n uint _S10 = key_1 / rowTableWidth_0(keys_3);\n\n return _S10;\n}\n\n\nuint byteOf_0(float channel_0)\n{\n\n return uint(channel_0 * 255.0 + 0.5);\n}\n\n\nvec2 hpSplitUint_0(uint value_1)\n{\n\n uint lo_0 = value_1 & 4095U;\n\n return vec2(float(value_1 - lo_0), float(lo_0));\n}\n\n\nfloat hpToClipX_0(vec2 splitPos_0, vec3 bpRange_0, float hpZero_0)\n{\n\n float floorBp_0 = -3.00000000549775576e+38 + hpZero_0;\n float step_0 = 2.0 / bpRange_0.z;\n\n\n return dot(vec3(-1.0, max(splitPos_0.x - bpRange_0.x, floorBp_0), max(splitPos_0.y - bpRange_0.y, floorBp_0)), vec3(1.0, step_0, step_0));\n}\n\n\nfloat pxToClipLen_0(float px_0, float size_0)\n{\n\n return px_0 * 2.0 / size_0;\n}\n\n\nfloat extendToMinWidthPx_0(float x1_0, float x2_0, float minWidth_0)\n{\n\n float dx_0 = x2_0 - x1_0;\n\n float _S11;\n if((abs(dx_0)) < minWidth_0)\n {\n\n if(dx_0 < 0.0)\n {\n\n _S11 = - minWidth_0;\n\n }\n else\n {\n\n _S11 = minWidth_0;\n\n }\n\n _S11 = x1_0 + _S11;\n\n }\n else\n {\n\n _S11 = x2_0;\n\n }\n\n return _S11;\n}\n\nfloat extendToMinWidthX_0(float x1_1, float x2_1, float minWidthPx_1, float canvasWidth_0)\n{\n\n return extendToMinWidthPx_0(x1_1, x2_1, pxToClipLen_0(minWidthPx_1, canvasWidth_0));\n}\n\n\nvec2 quadLocal_0(uint vid_0)\n{\n\n uint v_0 = vid_0 % 6U;\n\n bool _S12 = v_0 == 0U;\n\n bool _S13;\n\n if(_S12)\n {\n\n _S13 = true;\n\n }\n else\n {\n\n _S13 = v_0 == 2U;\n\n }\n\n if(_S13)\n {\n\n _S13 = true;\n\n }\n else\n {\n\n _S13 = v_0 == 3U;\n\n }\n\n float _S14;\n\n if(_S13)\n {\n\n _S14 = 0.0;\n\n }\n else\n {\n\n _S14 = 1.0;\n\n }\n if(_S12)\n {\n\n _S13 = true;\n\n }\n else\n {\n\n _S13 = v_0 == 1U;\n\n }\n\n if(_S13)\n {\n\n _S13 = true;\n\n }\n else\n {\n\n _S13 = v_0 == 4U;\n\n }\n\n float _S15;\n\n if(_S13)\n {\n\n _S15 = 0.0;\n\n }\n else\n {\n\n _S15 = 1.0;\n\n }\n\n return vec2(_S14, _S15);\n}\n\n\nfloat rowBandTopPx_0(float rowOffsetPx_1, float rowHeight_1, uint slot_0)\n{\n\n return rowOffsetPx_1 + rowHeight_1 * float(slot_0);\n}\n\n\nfloat aaPx_0(float dpr_0)\n{\n\n return 1.0 / max(dpr_0, 1.0);\n}\n\n\nfloat aaHalfPx_0(float dpr_1)\n{\n\n return 0.5 * aaPx_0(dpr_1);\n}\n\n\nfloat barAaPx_0()\n{\n\n return 2.0 * aaHalfPx_0(u_0.devicePixelRatio_0);\n}\n\n\nint clipSide_0(float value_2, float domainMin_3, float domainMax_3, int scaleType_2)\n{\n\n float tolerance_0 = (domainMax_3 - domainMin_3) * 0.00000999999974738;\n if(value_2 > (domainMax_3 + tolerance_0))\n {\n\n return 1;\n }\n\n bool _S16;\n\n if(value_2 < (domainMin_3 - tolerance_0))\n {\n\n _S16 = scaleType_2 != 1;\n\n }\n else\n {\n\n _S16 = false;\n\n }\n\n if(_S16)\n {\n\n return -1;\n }\n return 0;\n}\n\n\nfloat yPxToClipY_0(float yPx_0, float canvasHeight_1)\n{\n\n return 1.0 - yPx_0 / canvasHeight_1 * 2.0;\n}\n\n\nfloat valueToYPxScaled_0(float value_3, float domainMin_4, float domainMax_4, float h_0, int scaleType_3, float symlogConstant_2)\n{\n\n return (1.0 - normalizeScore_0(value_3, domainMin_4, domainMax_4, scaleType_3, symlogConstant_2)) * h_0;\n}\n\n\nout vec4 v_color;\n\n\nout vec2 v_barInkPx;\n\n\nlayout(location = 0)\nin uint a_x;\n\n\nlayout(location = 1)\nin uint a_x2;\n\n\nlayout(location = 2)\nin float a_y;\n\n\nlayout(location = 3)\nin uint a_color;\n\n\nlayout(location = 4)\nin uint a_row;\n\n\nstruct VsOut_0\n{\n vec4 position_0;\n vec4 color_0;\n vec2 barInkPx_0;\n};\n\n\nvec4 rampColor_0(float _S17)\n{\n\n return (textureLod((u_colorRamp), (vec2((clamp(_S17, 0.0, 1.0) * 255.0 + 0.5) / 256.0, 0.5)), (0.0)));\n}\n\n\nvec4 markScaleColor_0(uint _S18, int _S19, float _S20, float _S21, float _S22, int _S23, vec4 _S24, vec4 _S25)\n{\n\n if(_S19 == 0)\n {\n\n return unpackRGBA_0(_S18);\n }\n if(_S18 == 2143289345U)\n {\n\n return unpackRGBA_0(4289703855U);\n }\n\n int scaleType_4;\n\n if((_S18 & 2139095040U) == 2139095040U)\n {\n\n if((_S18 & 8388607U) != 0U)\n {\n\n return unpackRGBA_0(4286611584U);\n }\n\n bool negative_0 = (_S18 & 2147483648U) != 0U;\n if(_S19 == 3)\n {\n\n if(negative_0)\n {\n\n scaleType_4 = 0;\n\n }\n else\n {\n\n scaleType_4 = _S23;\n\n }\n\n return u_0.colorBands_0[scaleType_4];\n }\n\n float _S26;\n\n if(negative_0)\n {\n\n _S26 = 0.0;\n\n }\n else\n {\n\n _S26 = 1.0;\n\n }\n\n return rampColor_0(rampMidT_0(_S26, _S22));\n }\n float value_4 = uintBitsToFloat(_S18);\n if(_S19 == 3)\n {\n\n return u_0.colorBands_0[thresholdBand_0(value_4, _S23, _S24, _S25)];\n }\n if(_S19 == 2)\n {\n\n scaleType_4 = 1;\n\n }\n else\n {\n\n scaleType_4 = 0;\n\n }\n return rampColor_0(rampMidT_0(normalizeScore_0(value_4, _S20, _S21, scaleType_4, 1.0), _S22));\n}\n\n\nstruct RowPlacement_0\n{\n bool hidden_0;\n uint slot_1;\n vec4 color_1;\n};\n\n\nRowPlacement_0 rowTableLookup_0(uint _S27, int _S28, vec4 _S29)\n{\n\n RowPlacement_0 p_0;\n p_0.hidden_0 = false;\n p_0.slot_1 = _S27;\n p_0.color_1 = _S29;\n if(_S28 < 0)\n {\n\n return p_0;\n }\n uint n_0 = uint(_S28);\n if(_S27 >= n_0)\n {\n\n p_0.hidden_0 = true;\n return p_0;\n }\n uint h_1 = rowTablePlaneHeight_0(n_0);\n uint _S30 = rowTableTexelX_0(_S27, n_0);\n\n float u_2 = (float(_S30) + 0.5) / float(rowTableWidth_0(n_0));\n float rows_0 = float(2U * h_1);\n uint y_0 = rowTableTexelY_0(_S27, n_0);\n vec4 s_0 = (textureLod((u_rowTable), (vec2(u_2, (float(y_0) + 0.5) / rows_0)), (0.0)));\n if((s_0.w) < 0.5)\n {\n\n p_0.hidden_0 = true;\n return p_0;\n }\n p_0.slot_1 = ((byteOf_0(s_0.x)) | ((byteOf_0(s_0.y)) << 8)) | ((byteOf_0(s_0.z)) << 16);\n vec4 c_2 = (textureLod((u_rowTable), (vec2(u_2, (float(y_0 + h_1) + 0.5) / rows_0)), (0.0)));\n\n vec4 _S31;\n if((c_2.w) > 0.0)\n {\n\n _S31 = c_2;\n\n }\n else\n {\n\n _S31 = _S29;\n\n }\n\n p_0.color_1 = _S31;\n return p_0;\n}\n\n\nfloat bpToClipX_0(uint _S32)\n{\n\n return hpToClipX_0(hpSplitUint_0(_S32), u_0.bpRangeX_0, u_0.zero_0);\n}\n\n\nvoid main()\n{\n\n VsOut_0 o_0;\n\n RowPlacement_0 _S33 = rowTableLookup_0(a_row, u_0.rowTableKeys_0, markScaleColor_0(a_color, u_0.rampMode_0, u_0.rampMin_0, u_0.rampMax_0, u_0.rampMidNorm_0, u_0.colorCutCount_0, u_0.colorCuts_0[0], u_0.colorCuts_0[1]));\n\n\n if(_S33.hidden_0)\n {\n\n o_0.position_0 = vec4(2.0, 2.0, 0.0, 1.0);\n o_0.color_0 = vec4(0.0);\n o_0.barInkPx_0 = vec2(0.0);\n VsOut_0 _S34 = o_0;\n\n gl_Position = o_0.position_0;\n\n v_color = _S34.color_0;\n\n v_barInkPx = _S34.barInkPx_0;\n\n return;\n }\n\n float _S35 = bpToClipX_0(a_x);\n\n\n\n float sx2_0 = extendToMinWidthX_0(_S35, bpToClipX_0(a_x2), u_0.minWidthPx_0, u_0.minCellDenomPx_0);\n vec2 q_0 = quadLocal_0(uint(gl_VertexID));\n\n float bandTop_0 = rowBandTopPx_0(u_0.rowOffsetPx_0, u_0.rowHeight_0, _S33.slot_1);\n float padPx_0 = barAaPx_0();\n\n if(uint(gl_VertexID) >= 6U)\n {\n\n int side_0 = clipSide_0(a_y, u_0.domainMin_0, u_0.domainMax_0, u_0.valueScaleType_0);\n if(side_0 == 0)\n {\n\n o_0.position_0 = vec4(2.0, 2.0, 0.0, 1.0);\n o_0.color_0 = vec4(0.0);\n o_0.barInkPx_0 = vec2(0.0);\n VsOut_0 _S36 = o_0;\n\n gl_Position = o_0.position_0;\n\n v_color = _S36.color_0;\n\n v_barInkPx = _S36.barInkPx_0;\n\n return;\n }\n\n float stripTop_0;\n\n if(side_0 > 0)\n {\n\n stripTop_0 = bandTop_0;\n\n }\n else\n {\n\n stripTop_0 = bandTop_0 + u_0.rowBandPx_0 - 2.0;\n\n }\n float stripBot_0 = stripTop_0 + 2.0;\n float sy_0 = mix(stripBot_0 + padPx_0, stripTop_0 - padPx_0, q_0.y);\n o_0.position_0 = vec4(mix(_S35, sx2_0, q_0.x), yPxToClipY_0(sy_0, u_0.canvasHeight_0), 0.0, 1.0);\n o_0.color_0 = vec4(unpackRGBA_0(4280821958U).xyz, 1.0);\n o_0.barInkPx_0 = vec2(sy_0 - stripTop_0, sy_0 - stripBot_0);\n VsOut_0 _S37 = o_0;\n\n gl_Position = o_0.position_0;\n\n v_color = _S37.color_0;\n\n v_barInkPx = _S37.barInkPx_0;\n\n return;\n }\n\n float valueY_0 = bandTop_0 + valueToYPxScaled_0(a_y, u_0.domainMin_0, u_0.domainMax_0, u_0.rowBandPx_0, u_0.valueScaleType_0, u_0.valueSymlogConstant_0);\n float originY_0 = bandTop_0 + u_0.originYPx_0;\n float _S38 = min(valueY_0, originY_0);\n float _S39 = max(valueY_0, originY_0);\n float vy_0 = mix(_S39 + padPx_0, _S38 - padPx_0, q_0.y);\n\n o_0.position_0 = vec4(mix(_S35, sx2_0, q_0.x), yPxToClipY_0(vy_0, u_0.canvasHeight_0), 0.0, 1.0);\n o_0.color_0 = _S33.color_1;\n o_0.barInkPx_0 = vec2(vy_0 - _S38, vy_0 - _S39);\n VsOut_0 _S40 = o_0;\n\n gl_Position = o_0.position_0;\n\n v_color = _S40.color_0;\n\n v_barInkPx = _S40.barInkPx_0;\n\n return;\n}\n\n"
|
|
5
|
+
|
|
6
|
+
export const GLSL_FRAGMENT = "#version 300 es\nprecision highp float;\nprecision highp int;\nprecision highp sampler2D;\n\n\n\nlayout(std140) uniform Uniforms\n{\n vec3 bpRangeX_0;\n float canvasHeight_0;\n float domainMin_0;\n float domainMax_0;\n int valueScaleType_0;\n float valueSymlogConstant_0;\n int rampMode_0;\n float rampMin_0;\n float rampMax_0;\n float rampMidNorm_0;\n int colorCutCount_0;\n vec4 colorCuts_0[2];\n vec4 colorBands_0[9];\n float originYPx_0;\n float rowHeight_0;\n float rowBandPx_0;\n float rowOffsetPx_0;\n float zero_0;\n float minCellDenomPx_0;\n float minWidthPx_0;\n float devicePixelRatio_0;\n int rowTableKeys_0;\n}u_0;\n\nfloat aaPx_0(float dpr_0)\n{\n\n return 1.0 / max(dpr_0, 1.0);\n}\n\n\nfloat aaHalfPx_0(float dpr_1)\n{\n\n return 0.5 * aaPx_0(dpr_1);\n}\n\n\nfloat barAaPx_0()\n{\n\n return 2.0 * aaHalfPx_0(u_0.devicePixelRatio_0);\n}\n\n\nfloat aaRamp_0(float signedInk_0, float widthPx_0)\n{\n\n return clamp(signedInk_0 / widthPx_0 + 0.5, 0.0, 1.0);\n}\n\n\nlayout(location = 0)\nout vec4 entryPointParam_fs_main_0;\n\n\nin vec4 v_color;\n\n\nin vec2 v_barInkPx;\n\n\nvoid main()\n{\n\n float aaPx_1 = barAaPx_0();\n float alpha_0 = aaRamp_0(v_barInkPx.x, aaPx_1) - aaRamp_0(v_barInkPx.y, aaPx_1);\n if(alpha_0 <= 0.0)\n {\n\n discard;\n\n }\n\n entryPointParam_fs_main_0 = vec4(v_color.xyz, v_color.w * alpha_0);\n\n return;\n}\n\n"
|