@jbrowse/render-core 5.0.0-beta.11 → 5.0.0-beta.14
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/OverlayCanvas.d.ts +3 -2
- package/esm/OverlayCanvas.js +4 -2
- package/esm/RenderCanvas.d.ts +4 -3
- package/esm/RenderCanvas.js +4 -2
- package/esm/ScrollLockedOverlay.d.ts +2 -2
- package/esm/ScrollLockedOverlay.js +3 -2
- package/esm/blockClipUtils.d.ts +5 -5
- package/esm/blockClipUtils.js +4 -3
- package/esm/canvas2dUtils.d.ts +15 -21
- package/esm/canvas2dUtils.js +25 -55
- package/esm/colorRampLut.d.ts +2 -2
- package/esm/colorRampLut.js +2 -2
- package/esm/coverageBand.d.ts +0 -1
- package/esm/coverageBand.js +0 -5
- package/esm/coverageBandBuffers.d.ts +8 -5
- package/esm/createRenderingBackend.d.ts +1 -1
- package/esm/displayPhase.d.ts +5 -9
- package/esm/displayPhase.js +2 -2
- package/esm/hal/mockHal.d.ts +3 -4
- package/esm/hal/mockHal.js +5 -4
- package/esm/hal/types.d.ts +5 -5
- package/esm/hal/webgl2Hal.d.ts +4 -1
- package/esm/hal/webgl2Hal.js +18 -6
- package/esm/hal/webgpuHal.js +2 -2
- package/esm/linkFeet.d.ts +4 -0
- package/esm/linkFeet.js +7 -0
- package/esm/marks/barMark.d.ts +1 -1
- package/esm/marks/barMark.js +4 -2
- package/esm/marks/colorFill.d.ts +4 -4
- package/esm/marks/colorFill.js +4 -4
- package/esm/marks/connectorMark.d.ts +48 -0
- package/esm/marks/connectorMark.js +285 -0
- package/esm/marks/drawAgainstHit.d.ts +1 -1
- package/esm/marks/drawAgainstHit.js +4 -4
- package/esm/marks/glyphPaint.d.ts +5 -4
- package/esm/marks/glyphPaint.js +17 -7
- package/esm/marks/index.d.ts +8 -5
- package/esm/marks/index.js +6 -4
- package/esm/marks/lineMark.d.ts +47 -7
- package/esm/marks/lineMark.js +53 -39
- package/esm/marks/linkMark.d.ts +43 -6
- package/esm/marks/linkMark.js +118 -21
- package/esm/marks/markBackend.d.ts +1 -1
- package/esm/marks/markBackend.js +1 -1
- package/esm/marks/markPlan.d.ts +4 -3
- package/esm/marks/markPlan.js +5 -4
- package/esm/marks/markRamp.d.ts +11 -11
- package/esm/marks/markRamp.js +9 -9
- package/esm/marks/pointMark.d.ts +11 -5
- package/esm/marks/pointMark.js +34 -9
- package/esm/marks/rowLane.d.ts +4 -2
- package/esm/marks/rowLane.js +7 -3
- package/esm/marks/rowTable.d.ts +5 -5
- package/esm/marks/rowTable.js +4 -4
- package/esm/marks/ruleMark.js +1 -0
- package/esm/marks/spanMark.d.ts +8 -7
- package/esm/marks/spanMark.js +3 -3
- package/esm/marks/types.d.ts +8 -5
- package/esm/marks/types.js +8 -1
- package/esm/perRegionRenderingBackend.d.ts +1 -1
- package/esm/perRegionRenderingBackend.js +1 -1
- package/esm/regionDataMap.d.ts +2 -2
- package/esm/regionDataMap.js +2 -2
- package/esm/shaders/barMark.glsl.generated.d.ts +1 -1
- package/esm/shaders/barMark.glsl.generated.js +1 -1
- package/esm/shaders/barMark.wgsl.generated.d.ts +1 -1
- package/esm/shaders/barMark.wgsl.generated.js +1 -1
- package/esm/shaders/capsule.js.generated.d.ts +1 -1
- package/esm/shaders/capsule.js.generated.js +2 -2
- package/esm/shaders/connectorMark.consts.generated.d.ts +11 -0
- package/esm/shaders/connectorMark.consts.generated.js +13 -0
- package/esm/shaders/{coverageIndicator.generated.d.ts → connectorMark.generated.d.ts} +2 -1
- package/esm/shaders/connectorMark.generated.js +8 -0
- package/esm/shaders/connectorMark.glsl.generated.d.ts +2 -0
- package/esm/shaders/connectorMark.glsl.generated.js +4 -0
- package/esm/shaders/connectorMark.iface.generated.d.ts +88 -0
- package/esm/shaders/connectorMark.iface.generated.js +1194 -0
- package/esm/shaders/connectorMark.js.generated.d.ts +5 -0
- package/esm/shaders/connectorMark.js.generated.js +47 -0
- package/esm/shaders/connectorMark.wgsl.generated.d.ts +1 -0
- package/esm/shaders/connectorMark.wgsl.generated.js +3 -0
- package/esm/shaders/coverageInterbase.glsl.generated.d.ts +1 -1
- package/esm/shaders/coverageInterbase.glsl.generated.js +1 -1
- package/esm/shaders/coverageInterbase.wgsl.generated.d.ts +1 -1
- package/esm/shaders/coverageInterbase.wgsl.generated.js +1 -1
- package/esm/shaders/curveDistance.js.generated.d.ts +4 -0
- package/esm/shaders/curveDistance.js.generated.js +113 -0
- package/esm/shaders/insertionGlyph.generated.d.ts +6 -0
- package/esm/shaders/insertionGlyph.generated.js +8 -0
- package/esm/shaders/lineCenterMark.glsl.generated.d.ts +2 -2
- package/esm/shaders/lineCenterMark.glsl.generated.js +2 -2
- package/esm/shaders/lineCenterMark.iface.generated.d.ts +11 -9
- package/esm/shaders/lineCenterMark.iface.generated.js +20 -18
- package/esm/shaders/lineCenterMark.wgsl.generated.d.ts +1 -1
- package/esm/shaders/lineCenterMark.wgsl.generated.js +1 -1
- package/esm/shaders/lineCommon.js.generated.d.ts +1 -0
- package/esm/shaders/lineCommon.js.generated.js +20 -0
- package/esm/shaders/lineStepMark.glsl.generated.d.ts +2 -2
- package/esm/shaders/lineStepMark.glsl.generated.js +2 -2
- package/esm/shaders/lineStepMark.iface.generated.d.ts +11 -9
- package/esm/shaders/lineStepMark.iface.generated.js +20 -18
- package/esm/shaders/lineStepMark.wgsl.generated.d.ts +1 -1
- package/esm/shaders/lineStepMark.wgsl.generated.js +1 -1
- package/esm/shaders/linkMark.consts.generated.d.ts +1 -0
- package/esm/shaders/linkMark.consts.generated.js +1 -0
- package/esm/shaders/linkMark.glsl.generated.d.ts +2 -2
- package/esm/shaders/linkMark.glsl.generated.js +2 -2
- package/esm/shaders/linkMark.js.generated.d.ts +4 -2
- package/esm/shaders/linkMark.js.generated.js +33 -4
- package/esm/shaders/linkMark.wgsl.generated.d.ts +1 -1
- package/esm/shaders/linkMark.wgsl.generated.js +1 -1
- package/esm/shaders/pointMark.glsl.generated.d.ts +1 -1
- package/esm/shaders/pointMark.glsl.generated.js +1 -1
- package/esm/shaders/pointMark.iface.generated.d.ts +10 -8
- package/esm/shaders/pointMark.iface.generated.js +18 -16
- package/esm/shaders/pointMark.wgsl.generated.d.ts +1 -1
- package/esm/shaders/pointMark.wgsl.generated.js +1 -1
- package/esm/shaders/spanMark.glsl.generated.d.ts +1 -1
- package/esm/shaders/spanMark.glsl.generated.js +1 -1
- package/esm/shaders/spanMark.wgsl.generated.d.ts +1 -1
- package/esm/shaders/spanMark.wgsl.generated.js +1 -1
- package/esm/slangPass.d.ts +5 -3
- package/esm/slangPass.js +2 -2
- package/package.json +7 -4
- package/src/shaders/arcHull.test.ts +87 -0
- package/src/shaders/barMark.glsl.generated.ts +1 -1
- package/src/shaders/barMark.slang +2 -2
- package/src/shaders/barMark.wgsl.generated.ts +1 -1
- package/src/shaders/capsule.js.generated.ts +2 -2
- package/src/shaders/capsule.slang +69 -24
- package/src/shaders/clipStrip.slang +1 -1
- package/src/shaders/colorPack.slang +2 -2
- package/src/shaders/colorRampLut.slang +7 -7
- package/src/shaders/connectorMark.consts.generated.ts +24 -0
- package/src/shaders/connectorMark.generated.ts +12 -0
- package/src/shaders/connectorMark.glsl.generated.ts +6 -0
- package/src/shaders/connectorMark.iface.generated.ts +1270 -0
- package/src/shaders/connectorMark.js.generated.ts +52 -0
- package/src/shaders/connectorMark.slang +287 -0
- package/src/shaders/connectorMark.wgsl.generated.ts +4 -0
- package/src/shaders/coverageBand.slang +10 -12
- package/src/shaders/coverageInterbase.glsl.generated.ts +1 -1
- package/src/shaders/coverageInterbase.slang +24 -21
- package/src/shaders/coverageInterbase.wgsl.generated.ts +1 -1
- package/src/shaders/coverageSnp.slang +1 -1
- package/src/shaders/curveDistance.js.generated.ts +112 -0
- package/src/shaders/curveDistance.slang +104 -1
- package/src/shaders/farDome.test.ts +117 -0
- package/src/shaders/hpClampFloor.test.ts +0 -4
- package/src/shaders/insertionGlyph.generated.ts +14 -0
- package/src/shaders/insertionGlyph.slang +59 -0
- package/src/shaders/lineCenterMark.glsl.generated.ts +2 -2
- package/src/shaders/lineCenterMark.iface.generated.ts +21 -18
- package/src/shaders/lineCenterMark.slang +19 -23
- package/src/shaders/lineCenterMark.wgsl.generated.ts +1 -1
- package/src/shaders/lineCommon.js.generated.ts +20 -0
- package/src/shaders/lineCommon.slang +18 -8
- package/src/shaders/lineStepMark.glsl.generated.ts +2 -2
- package/src/shaders/lineStepMark.iface.generated.ts +21 -18
- package/src/shaders/lineStepMark.slang +10 -6
- package/src/shaders/lineStepMark.wgsl.generated.ts +1 -1
- package/src/shaders/linkMark.consts.generated.ts +2 -0
- package/src/shaders/linkMark.glsl.generated.ts +2 -2
- package/src/shaders/linkMark.js.generated.ts +30 -4
- package/src/shaders/linkMark.slang +67 -24
- package/src/shaders/linkMark.wgsl.generated.ts +1 -1
- package/src/shaders/markColor.slang +10 -10
- package/src/shaders/pointMark.glsl.generated.ts +1 -1
- package/src/shaders/pointMark.iface.generated.ts +19 -16
- package/src/shaders/pointMark.slang +12 -8
- package/src/shaders/pointMark.wgsl.generated.ts +1 -1
- package/src/shaders/rowRect.slang +3 -3
- package/src/shaders/rowTable.slang +12 -8
- package/src/shaders/scoreScale.slang +1 -1
- package/src/shaders/spanMark.glsl.generated.ts +1 -1
- package/src/shaders/spanMark.slang +5 -5
- package/src/shaders/spanMark.wgsl.generated.ts +1 -1
- package/src/shaders/viewRegion.slang +13 -0
- package/esm/shaders/coverageIndicator.generated.js +0 -7
- package/esm/shaders/coverageIndicator.glsl.generated.d.ts +0 -2
- package/esm/shaders/coverageIndicator.glsl.generated.js +0 -4
- package/esm/shaders/coverageIndicator.iface.generated.d.ts +0 -85
- package/esm/shaders/coverageIndicator.iface.generated.js +0 -114
- package/esm/shaders/coverageIndicator.wgsl.generated.d.ts +0 -1
- package/esm/shaders/coverageIndicator.wgsl.generated.js +0 -3
- package/src/shaders/coverageIndicator.generated.ts +0 -11
- package/src/shaders/coverageIndicator.glsl.generated.ts +0 -6
- package/src/shaders/coverageIndicator.iface.generated.ts +0 -172
- package/src/shaders/coverageIndicator.slang +0 -61
- package/src/shaders/coverageIndicator.wgsl.generated.ts +0 -4
package/esm/marks/markPlan.d.ts
CHANGED
|
@@ -18,8 +18,9 @@ export interface MarkPlan<TRegion, TState extends MarkFrame> {
|
|
|
18
18
|
}
|
|
19
19
|
/**
|
|
20
20
|
* Resolve which marks draw this frame. Throws for an enabled mark the plan
|
|
21
|
-
* form cannot carry — one with a `band
|
|
22
|
-
*
|
|
23
|
-
* would draw what
|
|
21
|
+
* form cannot carry — one with a `band`, a `paintsBlock` or a per-draw
|
|
22
|
+
* `verticesPerInstance` — since a plan neither scissors, asks the block
|
|
23
|
+
* anything nor sizes a draw, and without the throw the GPU would draw what
|
|
24
|
+
* Canvas2D declines, or a chevron a line.
|
|
24
25
|
*/
|
|
25
26
|
export declare function planMarks<TRegion, TState extends MarkFrame>(marks: readonly Mark<TRegion, TState>[], state: TState): MarkPlan<TRegion, TState>;
|
package/esm/marks/markPlan.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Resolve which marks draw this frame. Throws for an enabled mark the plan
|
|
3
|
-
* form cannot carry — one with a `band
|
|
4
|
-
*
|
|
5
|
-
* would draw what
|
|
3
|
+
* form cannot carry — one with a `band`, a `paintsBlock` or a per-draw
|
|
4
|
+
* `verticesPerInstance` — since a plan neither scissors, asks the block
|
|
5
|
+
* anything nor sizes a draw, and without the throw the GPU would draw what
|
|
6
|
+
* Canvas2D declines, or a chevron a line.
|
|
6
7
|
*/
|
|
7
8
|
export function planMarks(marks, state) {
|
|
8
9
|
const enabled = [];
|
|
@@ -10,7 +11,7 @@ export function planMarks(marks, state) {
|
|
|
10
11
|
for (const mark of marks) {
|
|
11
12
|
if (!mark.enabled || mark.enabled(state)) {
|
|
12
13
|
if (!mark.planned) {
|
|
13
|
-
throw new Error(`mark ${mark.pass.id} declares a band or a
|
|
14
|
+
throw new Error(`mark ${mark.pass.id} declares a band, a block gate or a per-draw vertex count, which a frame plan does not carry; draw it through drawMarks`);
|
|
14
15
|
}
|
|
15
16
|
enabled.push(mark);
|
|
16
17
|
passes.push(mark.planned);
|
package/esm/marks/markRamp.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { MarkColorScale, MarkThreshold } from './types.ts';
|
|
2
2
|
/**
|
|
3
|
-
* A
|
|
3
|
+
* A color channel as a shape reads it: `color`, the packed ABGR the worker
|
|
4
4
|
* resolved — one per instance, or one number for all of them — or
|
|
5
5
|
* `colorValue`, the raw values a frame's {@link MarkColorScale} turns into
|
|
6
|
-
*
|
|
6
|
+
* colors here. A shape reading a scale declares both optional and asks
|
|
7
7
|
* {@link colorBits} for the GPU and {@link paintColors} for Canvas2D.
|
|
8
8
|
*/
|
|
9
9
|
export interface ColorChannel {
|
|
@@ -19,13 +19,13 @@ interface RampBake {
|
|
|
19
19
|
scale: MarkColorScale;
|
|
20
20
|
colors: Uint32Array;
|
|
21
21
|
}
|
|
22
|
-
/** Whether a
|
|
22
|
+
/** Whether a color scale is a threshold rather than a ramp. */
|
|
23
23
|
export declare function isThreshold(scale: MarkColorScale): scale is MarkThreshold;
|
|
24
24
|
type Rgba = [number, number, number, number];
|
|
25
25
|
type Bands = [Rgba, Rgba, Rgba, Rgba, Rgba, Rgba, Rgba, Rgba, Rgba];
|
|
26
26
|
/**
|
|
27
|
-
* `markColor.slang`'s uniforms for a frame's
|
|
28
|
-
* mode, a ramp's domain and middle, and a threshold's cuts and band
|
|
27
|
+
* `markColor.slang`'s uniforms for a frame's color scale, or for none: the
|
|
28
|
+
* mode, a ramp's domain and middle, and a threshold's cuts and band colors.
|
|
29
29
|
* Every valued shape's uniform block carries the set.
|
|
30
30
|
*/
|
|
31
31
|
export declare function rampUniforms(scale: MarkColorScale | undefined): {
|
|
@@ -40,8 +40,8 @@ export declare function rampUniforms(scale: MarkColorScale | undefined): {
|
|
|
40
40
|
/**
|
|
41
41
|
* The 4-byte instance lane, for the packer. Under a scale it is the value's
|
|
42
42
|
* float32 bits viewed as the `uint` the attribute declares — the reinterpret
|
|
43
|
-
* `markColor.slang`'s `asfloat` undoes, and the reason a quantitative
|
|
44
|
-
* adds no lane. A constant
|
|
43
|
+
* `markColor.slang`'s `asfloat` undoes, and the reason a quantitative color
|
|
44
|
+
* adds no lane. A constant color fills a lane for the pack alone, which the
|
|
45
45
|
* payload never holds.
|
|
46
46
|
*/
|
|
47
47
|
export declare function colorBits(c: ColorChannel, count: number): ArrayLike<number>;
|
|
@@ -63,12 +63,12 @@ export declare function keepRampValues(values: Float32Array, keep: (value: numbe
|
|
|
63
63
|
*/
|
|
64
64
|
export declare function thresholdBandOf(value: number, cuts: readonly number[]): number;
|
|
65
65
|
/**
|
|
66
|
-
* The packed
|
|
66
|
+
* The packed colors a painter fills with. Under a scale the values are baked
|
|
67
67
|
* against it once and kept on the payload, so a repaint at an unchanged scale
|
|
68
68
|
* — every pan and every hover — walks no values and the painters' fill
|
|
69
|
-
* batching still sees runs of one
|
|
70
|
-
* scale type, the ramp's bytes or a threshold's cuts or
|
|
71
|
-
* constant
|
|
69
|
+
* batching still sees runs of one color. The bake reruns when the domain, the
|
|
70
|
+
* scale type, the ramp's bytes or a threshold's cuts or colors move. A
|
|
71
|
+
* constant color expands once and is kept the same way.
|
|
72
72
|
*/
|
|
73
73
|
export declare function paintColors(c: ColorChannel, count: number, scale: MarkColorScale | undefined): ArrayLike<number>;
|
|
74
74
|
export {};
|
package/esm/marks/markRamp.js
CHANGED
|
@@ -3,7 +3,7 @@ import { rampMidT } from '../shaders/colorRampLut.js.generated.js';
|
|
|
3
3
|
import { MAX_COLOR_BANDS, MAX_COLOR_CUTS, RAMP_LINEAR, RAMP_LOG, RAMP_NONE, RAMP_NOT_A_NUMBER_COLOR, RAMP_NO_VALUE_BITS, RAMP_NO_VALUE_COLOR, RAMP_THRESHOLD, } from '../shaders/markColor.generated.js';
|
|
4
4
|
import { normalizeScore } from '../shaders/scoreScale.js.generated.js';
|
|
5
5
|
const NO_COLORS = new Uint32Array(0);
|
|
6
|
-
/** Whether a
|
|
6
|
+
/** Whether a color scale is a threshold rather than a ramp. */
|
|
7
7
|
export function isThreshold(scale) {
|
|
8
8
|
return 'cuts' in scale;
|
|
9
9
|
}
|
|
@@ -31,8 +31,8 @@ function quad(values, from) {
|
|
|
31
31
|
];
|
|
32
32
|
}
|
|
33
33
|
/**
|
|
34
|
-
* `markColor.slang`'s uniforms for a frame's
|
|
35
|
-
* mode, a ramp's domain and middle, and a threshold's cuts and band
|
|
34
|
+
* `markColor.slang`'s uniforms for a frame's color scale, or for none: the
|
|
35
|
+
* mode, a ramp's domain and middle, and a threshold's cuts and band colors.
|
|
36
36
|
* Every valued shape's uniform block carries the set.
|
|
37
37
|
*/
|
|
38
38
|
export function rampUniforms(scale) {
|
|
@@ -69,8 +69,8 @@ export function rampUniforms(scale) {
|
|
|
69
69
|
/**
|
|
70
70
|
* The 4-byte instance lane, for the packer. Under a scale it is the value's
|
|
71
71
|
* float32 bits viewed as the `uint` the attribute declares — the reinterpret
|
|
72
|
-
* `markColor.slang`'s `asfloat` undoes, and the reason a quantitative
|
|
73
|
-
* adds no lane. A constant
|
|
72
|
+
* `markColor.slang`'s `asfloat` undoes, and the reason a quantitative color
|
|
73
|
+
* adds no lane. A constant color fills a lane for the pack alone, which the
|
|
74
74
|
* payload never holds.
|
|
75
75
|
*/
|
|
76
76
|
export function colorBits(c, count) {
|
|
@@ -129,12 +129,12 @@ function sameScale(a, b) {
|
|
|
129
129
|
midNormOf(a) === midNormOf(b));
|
|
130
130
|
}
|
|
131
131
|
/**
|
|
132
|
-
* The packed
|
|
132
|
+
* The packed colors a painter fills with. Under a scale the values are baked
|
|
133
133
|
* against it once and kept on the payload, so a repaint at an unchanged scale
|
|
134
134
|
* — every pan and every hover — walks no values and the painters' fill
|
|
135
|
-
* batching still sees runs of one
|
|
136
|
-
* scale type, the ramp's bytes or a threshold's cuts or
|
|
137
|
-
* constant
|
|
135
|
+
* batching still sees runs of one color. The bake reruns when the domain, the
|
|
136
|
+
* scale type, the ramp's bytes or a threshold's cuts or colors move. A
|
|
137
|
+
* constant color expands once and is kept the same way.
|
|
138
138
|
*/
|
|
139
139
|
export function paintColors(c, count, scale) {
|
|
140
140
|
const { colorValue, color } = c;
|
package/esm/marks/pointMark.d.ts
CHANGED
|
@@ -6,18 +6,21 @@ import type { MarkFrame, MarkColorScale, MarkShape } from './types.ts';
|
|
|
6
6
|
import type { MarkValueScale } from './valueScale.ts';
|
|
7
7
|
/**
|
|
8
8
|
* The `point` shape's channels: a glyph per instance at the centre of
|
|
9
|
-
* `x`..`x2`, on the `y` scale.
|
|
9
|
+
* `x`..`x2`, on the `y` scale, at 0 where `y` is absent. `glyph` is one per
|
|
10
|
+
* instance or one for all of them, as `color` is.
|
|
10
11
|
*/
|
|
11
12
|
export interface PointChannels extends ColorChannel, RowChannel {
|
|
12
13
|
x: Uint32Array;
|
|
13
14
|
x2: Uint32Array;
|
|
14
|
-
y
|
|
15
|
-
glyph: Uint8Array;
|
|
15
|
+
y?: Float32Array;
|
|
16
|
+
glyph: Uint8Array | number;
|
|
16
17
|
count: number;
|
|
17
18
|
}
|
|
18
|
-
/**
|
|
19
|
+
/** The channels cut down to instance `i`, for its own painter to trace alone. */
|
|
20
|
+
export declare function pointInstance(c: PointChannels, i: number): PointChannels;
|
|
21
|
+
/** What the point and rule shapes share: a value scale, rows and a color scale. */
|
|
19
22
|
export interface ValuedMarkParams extends RowParams, MarkValueScale {
|
|
20
|
-
/** The quantitative
|
|
23
|
+
/** The quantitative color scale, for a mark whose color is a ramp or a threshold. */
|
|
21
24
|
colorScale?: MarkColorScale;
|
|
22
25
|
/**
|
|
23
26
|
* How far inside the plot the value range ends, so a mark at a domain
|
|
@@ -29,6 +32,8 @@ export interface ValuedMarkParams extends RowParams, MarkValueScale {
|
|
|
29
32
|
export interface PointParams extends ValuedMarkParams {
|
|
30
33
|
/** Glyph diameter in CSS px. */
|
|
31
34
|
diameterPx: number;
|
|
35
|
+
/** The triangle's height in CSS px, where it is not `diameterPx`. */
|
|
36
|
+
triangleHeightPx?: number;
|
|
32
37
|
}
|
|
33
38
|
/**
|
|
34
39
|
* The point shader's uniforms, which the rule shape draws through too:
|
|
@@ -36,6 +41,7 @@ export interface PointParams extends ValuedMarkParams {
|
|
|
36
41
|
*/
|
|
37
42
|
export declare function writePointUniforms(scratch: ArrayBuffer, clip: BlockClipResult, block: RenderBlock, frame: MarkFrame, params: ValuedMarkParams, shape: {
|
|
38
43
|
radiusPx: number;
|
|
44
|
+
triangleRadiusYPx: number;
|
|
39
45
|
rule: boolean;
|
|
40
46
|
minWidthPx: number;
|
|
41
47
|
}): void;
|
package/esm/marks/pointMark.js
CHANGED
|
@@ -7,10 +7,24 @@ import { slangPass } from '../slangPass.js';
|
|
|
7
7
|
import { abgrToCssRgba } from './colorFill.js';
|
|
8
8
|
import { appendGlyph, glyphBox } from './glyphPaint.js';
|
|
9
9
|
import { inkAtPoint, nearestInk } from './markHit.js';
|
|
10
|
-
import { colorBits, paintColors, rampUniforms } from './markRamp.js';
|
|
10
|
+
import { colorBits, instanceColor, paintColors, rampUniforms, } from './markRamp.js';
|
|
11
11
|
import { valueWindow } from './nearestMarkHit.js';
|
|
12
12
|
import { bandHeightPx, rowColor, rowLane, rowSlot, rowTableKeys, rowTableTextures, } from './rowLane.js';
|
|
13
13
|
import { valueScaleUniforms } from './valueScale.js';
|
|
14
|
+
const NO_VALUES = new Float32Array(0);
|
|
15
|
+
/** The channels cut down to instance `i`, for its own painter to trace alone. */
|
|
16
|
+
export function pointInstance(c, i) {
|
|
17
|
+
const { glyph } = c;
|
|
18
|
+
return {
|
|
19
|
+
x: c.x.subarray(i, i + 1),
|
|
20
|
+
x2: c.x2.subarray(i, i + 1),
|
|
21
|
+
y: c.y?.subarray(i, i + 1),
|
|
22
|
+
glyph: typeof glyph === 'number' ? glyph : glyph.subarray(i, i + 1),
|
|
23
|
+
row: c.row?.subarray(i, i + 1),
|
|
24
|
+
color: instanceColor(c.color, i),
|
|
25
|
+
count: 1,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
14
28
|
/**
|
|
15
29
|
* The point shader's uniforms, which the rule shape draws through too:
|
|
16
30
|
* `radiusPx` is half a glyph or half a rule's thickness.
|
|
@@ -29,6 +43,7 @@ export function writePointUniforms(scratch, clip, block, frame, params, shape) {
|
|
|
29
43
|
// stretched ellipses on hi-DPI.
|
|
30
44
|
viewportWidth: clip.scissorW,
|
|
31
45
|
radiusPx: shape.radiusPx,
|
|
46
|
+
triangleRadiusYPx: shape.triangleRadiusYPx,
|
|
32
47
|
rowHeight: bandHeightPx(params, frame.canvasHeight),
|
|
33
48
|
rowOffsetPx: params.rowOffsetPx ?? 0,
|
|
34
49
|
reverse: params.reverse ? 1 : 0,
|
|
@@ -43,11 +58,21 @@ export const pointMark = {
|
|
|
43
58
|
id: 'point',
|
|
44
59
|
pass: {
|
|
45
60
|
...slangPass({ id: 'point', mod: shader }),
|
|
46
|
-
pack: c => shader.packInstances({
|
|
61
|
+
pack: c => shader.packInstances({
|
|
62
|
+
x: c.x,
|
|
63
|
+
x2: c.x2,
|
|
64
|
+
y: c.y ?? (c.count === 0 ? NO_VALUES : new Float32Array(c.count)),
|
|
65
|
+
glyph: typeof c.glyph === 'number'
|
|
66
|
+
? new Uint8Array(c.count).fill(c.glyph)
|
|
67
|
+
: c.glyph,
|
|
68
|
+
color: colorBits(c, c.count),
|
|
69
|
+
row: rowLane(c.row, c.count),
|
|
70
|
+
}, c.count),
|
|
47
71
|
},
|
|
48
72
|
writeUniforms(scratch, clip, block, frame, params) {
|
|
49
73
|
writePointUniforms(scratch, clip, block, frame, params, {
|
|
50
74
|
radiusPx: params.diameterPx / 2,
|
|
75
|
+
triangleRadiusYPx: (params.triangleHeightPx ?? params.diameterPx) / 2,
|
|
51
76
|
rule: false,
|
|
52
77
|
minWidthPx: 0,
|
|
53
78
|
});
|
|
@@ -59,7 +84,7 @@ export const pointMark = {
|
|
|
59
84
|
return;
|
|
60
85
|
}
|
|
61
86
|
const color = paintColors(channels, count, params.colorScale);
|
|
62
|
-
const { diameterPx, domain, insetPx = 0, rowOffsetPx: top = 0, rowTable: table, } = params;
|
|
87
|
+
const { diameterPx, triangleHeightPx = diameterPx, domain, insetPx = 0, rowOffsetPx: top = 0, rowTable: table, } = params;
|
|
63
88
|
const reverse = params.reverse ? 1 : 0;
|
|
64
89
|
const band = bandHeightPx(params, frame.canvasHeight);
|
|
65
90
|
const domainMin = domain[0];
|
|
@@ -81,8 +106,8 @@ export const pointMark = {
|
|
|
81
106
|
ctx.fillStyle = abgrToCssRgba(abgr);
|
|
82
107
|
}
|
|
83
108
|
path.add();
|
|
84
|
-
const yPx = pointRowYPx(rowBandTopPx(top, band, slot), band, reverse, pointYPx(y[i], domainMin, domainMax, band, st, insetPx, c));
|
|
85
|
-
appendGlyph(ctx, glyph[i], (bpToPx(x[i]) + bpToPx(x2[i])) / 2, yPx, diameterPx);
|
|
109
|
+
const yPx = pointRowYPx(rowBandTopPx(top, band, slot), band, reverse, pointYPx(y ? y[i] : 0, domainMin, domainMax, band, st, insetPx, c));
|
|
110
|
+
appendGlyph(ctx, typeof glyph === 'number' ? glyph : glyph[i], (bpToPx(x[i]) + bpToPx(x2[i])) / 2, yPx, diameterPx, triangleHeightPx);
|
|
86
111
|
}
|
|
87
112
|
path.flush();
|
|
88
113
|
},
|
|
@@ -93,12 +118,12 @@ export const pointMark = {
|
|
|
93
118
|
if (slot === undefined) {
|
|
94
119
|
return undefined;
|
|
95
120
|
}
|
|
96
|
-
const { diameterPx, domain, insetPx = 0 } = params;
|
|
121
|
+
const { diameterPx, triangleHeightPx, domain, insetPx = 0 } = params;
|
|
97
122
|
const bpToPx = makeBpMapper(block);
|
|
98
123
|
const band = bandHeightPx(params, frame.canvasHeight);
|
|
99
124
|
const { valueScaleType: st, valueSymlogConstant: c } = valueScaleUniforms(params);
|
|
100
|
-
const cy = pointRowYPx(rowBandTopPx(params.rowOffsetPx ?? 0, band, slot), band, params.reverse ? 1 : 0, pointYPx(y[i], domain[0], domain[1], band, st, insetPx, c));
|
|
101
|
-
return glyphBox(glyph[i], (bpToPx(x[i]) + bpToPx(x2[i])) / 2, cy, diameterPx);
|
|
125
|
+
const cy = pointRowYPx(rowBandTopPx(params.rowOffsetPx ?? 0, band, slot), band, params.reverse ? 1 : 0, pointYPx(y ? y[i] : 0, domain[0], domain[1], band, st, insetPx, c));
|
|
126
|
+
return glyphBox(typeof glyph === 'number' ? glyph : glyph[i], (bpToPx(x[i]) + bpToPx(x2[i])) / 2, cy, diameterPx, triangleHeightPx);
|
|
102
127
|
},
|
|
103
128
|
// Its own rather than the one `ink` implies: a dense plot stacks glyphs
|
|
104
129
|
// whose boxes all contain the cursor at distance 0, and the one under the
|
|
@@ -117,7 +142,7 @@ export const pointMark = {
|
|
|
117
142
|
if (slot === undefined) {
|
|
118
143
|
return undefined;
|
|
119
144
|
}
|
|
120
|
-
const cy = pointRowYPx(rowBandTopPx(top, band, slot), band, reverse, pointYPx(y[i], domainMin, domainMax, band, st, insetPx, c));
|
|
145
|
+
const cy = pointRowYPx(rowBandTopPx(top, band, slot), band, reverse, pointYPx(y ? y[i] : 0, domainMin, domainMax, band, st, insetPx, c));
|
|
121
146
|
return inkAtPoint(xPx, yPx, (bpToPx(x[i]) + bpToPx(x2[i])) / 2, cy);
|
|
122
147
|
});
|
|
123
148
|
},
|
package/esm/marks/rowLane.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ export interface RowParams {
|
|
|
15
15
|
rowOffsetPx?: number;
|
|
16
16
|
/**
|
|
17
17
|
* The table `row` is read through as a key: its drawn slot, hidden, or a
|
|
18
|
-
*
|
|
18
|
+
* color override. Absent, `row` is the slot.
|
|
19
19
|
*/
|
|
20
20
|
rowTable?: RowTable;
|
|
21
21
|
}
|
|
@@ -35,5 +35,7 @@ export declare function bandHeightPx(params: RowParams, canvasHeight: number): n
|
|
|
35
35
|
export declare function keySlot(key: number, table: RowTable | undefined): number | undefined;
|
|
36
36
|
/** The slot instance `i` is drawn on, undefined where the table hides its key. */
|
|
37
37
|
export declare function rowSlot(row: Uint32Array | undefined, i: number, table: RowTable | undefined): number | undefined;
|
|
38
|
-
/**
|
|
38
|
+
/** Instance `i`'s key's color override, undefined where it keeps its own. */
|
|
39
|
+
export declare function rowColorOverride(row: Uint32Array | undefined, i: number, table: RowTable | undefined): number | undefined;
|
|
40
|
+
/** The color instance `i` is drawn in: its key's override, else `color`. */
|
|
39
41
|
export declare function rowColor(color: number, row: Uint32Array | undefined, i: number, table: RowTable | undefined): number;
|
package/esm/marks/rowLane.js
CHANGED
|
@@ -33,9 +33,13 @@ export function keySlot(key, table) {
|
|
|
33
33
|
export function rowSlot(row, i, table) {
|
|
34
34
|
return keySlot(rowKey(row, i), table);
|
|
35
35
|
}
|
|
36
|
-
/**
|
|
37
|
-
export function
|
|
36
|
+
/** Instance `i`'s key's color override, undefined where it keeps its own. */
|
|
37
|
+
export function rowColorOverride(row, i, table) {
|
|
38
38
|
const key = rowKey(row, i);
|
|
39
39
|
const override = table && key < table.keys ? table.color[key] : NO_ROW_COLOR;
|
|
40
|
-
return override >>> 24 === 0 ?
|
|
40
|
+
return override >>> 24 === 0 ? undefined : override;
|
|
41
|
+
}
|
|
42
|
+
/** The color instance `i` is drawn in: its key's override, else `color`. */
|
|
43
|
+
export function rowColor(color, row, i, table) {
|
|
44
|
+
return rowColorOverride(row, i, table) ?? color;
|
|
41
45
|
}
|
package/esm/marks/rowTable.d.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import type { MarkTexels } from './types.ts';
|
|
2
2
|
/** The `slot` a hidden key holds. */
|
|
3
3
|
export declare const HIDDEN_ROW = 4294967295;
|
|
4
|
-
/** The `color` a key with no override holds: alpha 0, the instance's own
|
|
4
|
+
/** The `color` a key with no override holds: alpha 0, the instance's own color. */
|
|
5
5
|
export declare const NO_ROW_COLOR = 0;
|
|
6
6
|
/**
|
|
7
7
|
* The row axis as a pass reads it: each key's drawn slot or `HIDDEN_ROW`, its
|
|
8
|
-
* packed ABGR
|
|
8
|
+
* packed ABGR color override or `NO_ROW_COLOR`, and the RGBA8 texture the
|
|
9
9
|
* vertex stage samples for the same answers (`shaders/rowTable.slang` has the
|
|
10
10
|
* layout). One object, so the shader, the painter, the ink and the hit test
|
|
11
11
|
* cannot place a key differently. Immutable: a reorder, focus, hide or
|
|
12
|
-
*
|
|
12
|
+
* recolor builds a new one, and the backend uploads on identity.
|
|
13
13
|
*/
|
|
14
14
|
export interface RowTable {
|
|
15
15
|
readonly keys: number;
|
|
@@ -20,7 +20,7 @@ export interface RowTable {
|
|
|
20
20
|
/**
|
|
21
21
|
* The table for `slot[key]` and `color[key]`, both indexed by key: `slot` is
|
|
22
22
|
* `HIDDEN_ROW` where the key draws nothing, `color` is `NO_ROW_COLOR` where the
|
|
23
|
-
* instance keeps its own
|
|
23
|
+
* instance keeps its own color, an override alpha 0 being none. Both arrays
|
|
24
24
|
* are held, not copied. Each key's texel sits where the shader's own twins
|
|
25
25
|
* put it.
|
|
26
26
|
*/
|
|
@@ -29,7 +29,7 @@ export declare function buildRowTable(slot: Uint32Array, color?: Uint32Array): R
|
|
|
29
29
|
* The keys a display's rows carry across every region: a name's key is
|
|
30
30
|
* assigned the first time it is asked for and never moves, so a region encoded
|
|
31
31
|
* against the registry stays valid as later regions add names and the table
|
|
32
|
-
* alone follows the reader's order, focus and
|
|
32
|
+
* alone follows the reader's order, focus and colors. Grows only.
|
|
33
33
|
*/
|
|
34
34
|
export declare class RowKeys {
|
|
35
35
|
private readonly index;
|
package/esm/marks/rowTable.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { rowTablePlaneHeight, rowTableTexelX, rowTableTexelY, rowTableWidth, } from '../shaders/rowTable.js.generated.js';
|
|
2
2
|
/** The `slot` a hidden key holds. */
|
|
3
3
|
export const HIDDEN_ROW = 0xffffffff;
|
|
4
|
-
/** The `color` a key with no override holds: alpha 0, the instance's own
|
|
4
|
+
/** The `color` a key with no override holds: alpha 0, the instance's own color. */
|
|
5
5
|
export const NO_ROW_COLOR = 0;
|
|
6
6
|
const MAX_SLOT = 0xffffff;
|
|
7
7
|
/**
|
|
8
8
|
* The table for `slot[key]` and `color[key]`, both indexed by key: `slot` is
|
|
9
9
|
* `HIDDEN_ROW` where the key draws nothing, `color` is `NO_ROW_COLOR` where the
|
|
10
|
-
* instance keeps its own
|
|
10
|
+
* instance keeps its own color, an override alpha 0 being none. Both arrays
|
|
11
11
|
* are held, not copied. Each key's texel sits where the shader's own twins
|
|
12
12
|
* put it.
|
|
13
13
|
*/
|
|
14
14
|
export function buildRowTable(slot, color = new Uint32Array(slot.length)) {
|
|
15
15
|
const keys = slot.length;
|
|
16
16
|
if (color.length !== keys) {
|
|
17
|
-
throw new Error(`buildRowTable: ${keys} slots but ${color.length}
|
|
17
|
+
throw new Error(`buildRowTable: ${keys} slots but ${color.length} colors; both are per key`);
|
|
18
18
|
}
|
|
19
19
|
const width = rowTableWidth(keys);
|
|
20
20
|
const plane = rowTablePlaneHeight(keys);
|
|
@@ -51,7 +51,7 @@ export function buildRowTable(slot, color = new Uint32Array(slot.length)) {
|
|
|
51
51
|
* The keys a display's rows carry across every region: a name's key is
|
|
52
52
|
* assigned the first time it is asked for and never moves, so a region encoded
|
|
53
53
|
* against the registry stays valid as later regions add names and the table
|
|
54
|
-
* alone follows the reader's order, focus and
|
|
54
|
+
* alone follows the reader's order, focus and colors. Grows only.
|
|
55
55
|
*/
|
|
56
56
|
export class RowKeys {
|
|
57
57
|
index = new Map();
|
package/esm/marks/ruleMark.js
CHANGED
|
@@ -59,6 +59,7 @@ export const ruleMark = {
|
|
|
59
59
|
writeUniforms(scratch, clip, block, frame, params) {
|
|
60
60
|
writePointUniforms(scratch, clip, block, frame, params, {
|
|
61
61
|
radiusPx: params.sizePx / 2,
|
|
62
|
+
triangleRadiusYPx: params.sizePx / 2,
|
|
62
63
|
rule: true,
|
|
63
64
|
minWidthPx: params.minWidthPx,
|
|
64
65
|
});
|
package/esm/marks/spanMark.d.ts
CHANGED
|
@@ -2,8 +2,8 @@ import type { ColorChannel } from './markRamp.ts';
|
|
|
2
2
|
import type { RowTable } from './rowTable.ts';
|
|
3
3
|
import type { MarkColorScale, MarkShape } from './types.ts';
|
|
4
4
|
/**
|
|
5
|
-
* The `span` shape's channels: a
|
|
6
|
-
* band belonging to `row`, its
|
|
5
|
+
* The `span` shape's channels: a colored rectangle from `x` to `x2` on the
|
|
6
|
+
* band belonging to `row`, its color packed or, under a color scale, the
|
|
7
7
|
* value it resolves from.
|
|
8
8
|
*/
|
|
9
9
|
export interface SpanChannels extends ColorChannel {
|
|
@@ -14,7 +14,7 @@ export interface SpanChannels extends ColorChannel {
|
|
|
14
14
|
count: number;
|
|
15
15
|
}
|
|
16
16
|
export interface SpanParams {
|
|
17
|
-
/** The quantitative
|
|
17
|
+
/** The quantitative color scale, for a span whose color is a ramp or a threshold. */
|
|
18
18
|
colorScale?: MarkColorScale;
|
|
19
19
|
/** CSS px per row. */
|
|
20
20
|
rowHeight: number;
|
|
@@ -26,16 +26,17 @@ export interface SpanParams {
|
|
|
26
26
|
*/
|
|
27
27
|
minWidthPx: number;
|
|
28
28
|
/**
|
|
29
|
-
* CSS px the **painter alone** adds to each span's
|
|
30
|
-
*
|
|
31
|
-
*
|
|
29
|
+
* CSS px the **painter alone** adds to each span's edge facing the next span
|
|
30
|
+
* painted — the left edge on a reversed block — closing the hairline two
|
|
31
|
+
* antialiased `fillRect`s leave where tiling runs meet on a fractional pixel.
|
|
32
|
+
* The GPU pass needs none, and the ink excludes it.
|
|
32
33
|
*/
|
|
33
34
|
seamPx: number;
|
|
34
35
|
/** Rows-area scroll offset in CSS px; 0 for a canvas sized to its content. */
|
|
35
36
|
scrollTop: number;
|
|
36
37
|
/**
|
|
37
38
|
* The table `row` is read through as a key: its drawn slot, hidden, or a
|
|
38
|
-
*
|
|
39
|
+
* color override. Absent, `row` is the slot.
|
|
39
40
|
*/
|
|
40
41
|
rowTable?: RowTable;
|
|
41
42
|
}
|
package/esm/marks/spanMark.js
CHANGED
|
@@ -25,7 +25,7 @@ function spanFrame(block, params) {
|
|
|
25
25
|
height: drawnRowHeightPx(rowHeight, rowProportion),
|
|
26
26
|
};
|
|
27
27
|
}
|
|
28
|
-
function placeSpan(c, g, i) {
|
|
28
|
+
function placeSpan(c, g, i, seamPx = 0) {
|
|
29
29
|
const slot = rowSlot(c.row, i, g.table);
|
|
30
30
|
if (slot === undefined) {
|
|
31
31
|
return false;
|
|
@@ -33,7 +33,7 @@ function placeSpan(c, g, i) {
|
|
|
33
33
|
const xa = projectBp(g, c.x[i]);
|
|
34
34
|
const xb = projectBp(g, c.x2[i]);
|
|
35
35
|
const width = Math.max(g.minWidthPx, Math.abs(xb - xa));
|
|
36
|
-
g.left = spanLeft(xa, xb, width);
|
|
36
|
+
g.left = spanLeft(xa, xb, width + seamPx);
|
|
37
37
|
g.top = g.bandOffsetPx + g.rowHeight * slot - g.scrollTop;
|
|
38
38
|
g.width = width;
|
|
39
39
|
return true;
|
|
@@ -66,7 +66,7 @@ export const spanMark = {
|
|
|
66
66
|
const g = spanFrame(block, params);
|
|
67
67
|
const setFill = makeAbgrFill(ctx);
|
|
68
68
|
for (let i = 0; i < count; i++) {
|
|
69
|
-
if (placeSpan(channels, g, i)) {
|
|
69
|
+
if (placeSpan(channels, g, i, seamPx)) {
|
|
70
70
|
setFill(rowColor(color[i], row, i, g.table));
|
|
71
71
|
ctx.fillRect(g.left, g.top, g.width + seamPx, g.height);
|
|
72
72
|
}
|
package/esm/marks/types.d.ts
CHANGED
|
@@ -32,7 +32,7 @@ export interface MarkContext2D extends ClipContext2D {
|
|
|
32
32
|
drawImage?(image: CanvasImageSource, sx: number, sy: number, sw: number, sh: number, dx: number, dy: number, dw: number, dh: number): void;
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
35
|
-
* A canvas a mark's pass samples in place of a
|
|
35
|
+
* A canvas a mark's pass samples in place of a color ramp. Hand a fresh object
|
|
36
36
|
* per repaint: the backend uploads on identity.
|
|
37
37
|
*/
|
|
38
38
|
export interface MarkImage {
|
|
@@ -60,7 +60,7 @@ export type MarkTextures = Readonly<Record<string, MarkTexture | undefined>>;
|
|
|
60
60
|
export type MarkFrame = FrameDimensions;
|
|
61
61
|
export type MarkValueScaleType = 'linear' | 'log' | 'symlog';
|
|
62
62
|
/**
|
|
63
|
-
* The
|
|
63
|
+
* The color scale a ramp channel's raw `colorValue`s resolve through each
|
|
64
64
|
* frame, with the 256-entry RGBA LUT the pass's sampler binds: straight, its
|
|
65
65
|
* middle stop at the middle, and `mid`, where a diverging ramp puts that stop,
|
|
66
66
|
* read through a uniform.
|
|
@@ -76,13 +76,13 @@ export interface MarkRamp {
|
|
|
76
76
|
* A threshold a value channel's raw `colorValue`s resolve through each frame:
|
|
77
77
|
* the ascending cut points, at most `MAX_COLOR_CUTS` of them, and one packed
|
|
78
78
|
* ABGR per interval between them, `cuts.length + 1` in all. The cuts and
|
|
79
|
-
*
|
|
79
|
+
* colors ride uniforms, so an edit moves them and uploads no instance bytes.
|
|
80
80
|
*/
|
|
81
81
|
export interface MarkThreshold {
|
|
82
82
|
cuts: readonly number[];
|
|
83
83
|
colors: Uint32Array;
|
|
84
84
|
}
|
|
85
|
-
/** The scale a quantitative
|
|
85
|
+
/** The scale a quantitative color channel resolves through: a ramp or a threshold. */
|
|
86
86
|
export type MarkColorScale = MarkRamp | MarkThreshold;
|
|
87
87
|
/** A horizontal strip of the canvas, in CSS px down from its top edge. */
|
|
88
88
|
export interface MarkBand {
|
|
@@ -220,7 +220,10 @@ export interface Mark<TRegion, TState extends MarkFrame> {
|
|
|
220
220
|
* frame and every other consumer per block, before any lens.
|
|
221
221
|
*/
|
|
222
222
|
readonly enabled?: (state: TState) => boolean;
|
|
223
|
-
/**
|
|
223
|
+
/**
|
|
224
|
+
* The pass a frame plan draws; undefined with a `band`, a `paintsBlock` or
|
|
225
|
+
* a per-draw `verticesPerInstance`, none of which a plan carries.
|
|
226
|
+
*/
|
|
224
227
|
readonly planned?: PlannedPass;
|
|
225
228
|
drawRegion(hal: GpuHal, scratch: ArrayBuffer, block: RenderBlock, clip: BlockClipResult, region: TRegion, state: TState, regionKey: number, staged?: StagedUniforms, textures?: TextureBinder): void;
|
|
226
229
|
paintBlock(ctx: MarkContext2D, region: TRegion, block: RenderBlock, state: TState): void;
|
package/esm/marks/types.js
CHANGED
|
@@ -37,7 +37,9 @@ export function defineMark(spec) {
|
|
|
37
37
|
throw new Error(`mark ${shape.id} draws off ${lender.id}'s buffer but declares a different instance struct`);
|
|
38
38
|
}
|
|
39
39
|
const bufferOf = lender?.id;
|
|
40
|
-
const planned = band || shape.paintsBlock
|
|
40
|
+
const planned = band || shape.paintsBlock || shape.verticesPerInstance
|
|
41
|
+
? undefined
|
|
42
|
+
: { id: shape.pass.id, bufferOf };
|
|
41
43
|
// `channels` gates `params`: a union payload's params lens may only read its
|
|
42
44
|
// own kind of region.
|
|
43
45
|
function resolve(region, block, state) {
|
|
@@ -104,6 +106,11 @@ export function defineMark(spec) {
|
|
|
104
106
|
hal.setScissor(clip.pxX, scissor.top, clip.pxW, scissor.height);
|
|
105
107
|
}
|
|
106
108
|
if (staged?.writer !== shape.writeUniforms || staged.params !== params) {
|
|
109
|
+
// A generated packer drops whatever lands past the end of a short
|
|
110
|
+
// buffer, which draws the pass from zeros with nothing said.
|
|
111
|
+
if (scratch.byteLength < shape.pass.uniformByteSize) {
|
|
112
|
+
throw new Error(`${shape.pass.id} writes ${shape.pass.uniformByteSize} bytes of uniforms into a ${scratch.byteLength}-byte scratch`);
|
|
113
|
+
}
|
|
107
114
|
shape.writeUniforms(scratch, clip, block, state, p);
|
|
108
115
|
hal.writeUniforms(scratch);
|
|
109
116
|
if (staged) {
|
|
@@ -66,7 +66,7 @@ export declare abstract class Canvas2DPerRegionRenderingBackend<UploadData, Rend
|
|
|
66
66
|
* `prepareCanvas`'s `clearRect` as the whole of it, which is transparent.
|
|
67
67
|
* Synteny is the one display that overrides: its indel wedges pre-blend
|
|
68
68
|
* against a KNOWN ground and only agree with the base ribbon beside them over
|
|
69
|
-
* a destination that really is that
|
|
69
|
+
* a destination that really is that color.
|
|
70
70
|
*/
|
|
71
71
|
protected clearColor(_state: RenderState): ClearColor | undefined;
|
|
72
72
|
/**
|
|
@@ -37,7 +37,7 @@ export class Canvas2DPerRegionRenderingBackend extends Canvas2DRenderingBackendB
|
|
|
37
37
|
* `prepareCanvas`'s `clearRect` as the whole of it, which is transparent.
|
|
38
38
|
* Synteny is the one display that overrides: its indel wedges pre-blend
|
|
39
39
|
* against a KNOWN ground and only agree with the base ribbon beside them over
|
|
40
|
-
* a destination that really is that
|
|
40
|
+
* a destination that really is that color.
|
|
41
41
|
*/
|
|
42
42
|
clearColor(_state) {
|
|
43
43
|
return undefined;
|
package/esm/regionDataMap.d.ts
CHANGED
|
@@ -7,8 +7,8 @@ export declare function isCheckedAtTheStore(map: ReadonlyMap<unknown, unknown>):
|
|
|
7
7
|
* ADR-060.
|
|
8
8
|
*
|
|
9
9
|
* **Shallow, and that follows from an invariant the codebase already states**:
|
|
10
|
-
* per-region values are freshly constructed and never mutated (
|
|
11
|
-
*
|
|
10
|
+
* per-region values are freshly constructed and never mutated (ADR-060;
|
|
11
|
+
* backends diff by reference identity). Nothing inside an entry can
|
|
12
12
|
* therefore change, so the deep enhancer's field-level atoms can never fire —
|
|
13
13
|
* they are unreachable reactivity, not a safety margin. What they do cost is
|
|
14
14
|
* paid on every insert and every read:
|
package/esm/regionDataMap.js
CHANGED
|
@@ -17,8 +17,8 @@ export function isCheckedAtTheStore(map) {
|
|
|
17
17
|
* ADR-060.
|
|
18
18
|
*
|
|
19
19
|
* **Shallow, and that follows from an invariant the codebase already states**:
|
|
20
|
-
* per-region values are freshly constructed and never mutated (
|
|
21
|
-
*
|
|
20
|
+
* per-region values are freshly constructed and never mutated (ADR-060;
|
|
21
|
+
* backends diff by reference identity). Nothing inside an entry can
|
|
22
22
|
* therefore change, so the deep enhancer's field-level atoms can never fire —
|
|
23
23
|
* they are unreachable reactivity, not a safety margin. What they do cost is
|
|
24
24
|
* paid on every insert and every read:
|