@jbrowse/render-core 5.0.0-beta.13 → 5.0.0-beta.15
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 +1 -2
- package/esm/coverageBand.js +1 -6
- 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 +15 -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/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 +6 -3
- package/esm/marks/index.js +5 -3
- package/esm/marks/lineMark.d.ts +44 -10
- package/esm/marks/lineMark.js +20 -19
- package/esm/marks/linkMark.d.ts +22 -5
- package/esm/marks/linkMark.js +103 -25
- package/esm/marks/markBackend.d.ts +1 -1
- package/esm/marks/markBackend.js +1 -1
- 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 +3 -3
- package/esm/marks/rowLane.js +2 -2
- 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 +4 -4
- package/esm/marks/types.d.ts +4 -4
- package/esm/marks/types.js +5 -0
- 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/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 +3 -0
- package/esm/shaders/curveDistance.js.generated.js +104 -0
- package/esm/shaders/lineCenterMark.glsl.generated.d.ts +2 -2
- package/esm/shaders/lineCenterMark.glsl.generated.js +2 -2
- package/esm/shaders/lineCenterMark.wgsl.generated.d.ts +1 -1
- package/esm/shaders/lineCenterMark.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 +2 -1
- package/esm/shaders/linkMark.js.generated.js +30 -1
- 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/package.json +7 -4
- package/src/shaders/arcHull.test.ts +87 -0
- package/src/shaders/barMark.slang +2 -2
- 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 +100 -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/lineCenterMark.glsl.generated.ts +2 -2
- package/src/shaders/lineCenterMark.slang +14 -22
- package/src/shaders/lineCenterMark.wgsl.generated.ts +1 -1
- package/src/shaders/lineCommon.slang +10 -10
- package/src/shaders/lineStepMark.slang +5 -5
- 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 +27 -1
- package/src/shaders/linkMark.slang +58 -18
- 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 +7 -7
- package/src/shaders/scoreScale.slang +1 -1
- package/src/shaders/spanMark.slang +5 -5
- 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/OverlayCanvas.d.ts
CHANGED
|
@@ -21,9 +21,10 @@
|
|
|
21
21
|
* `inset: 0` therefore drew everything at twice its x on a retina display and
|
|
22
22
|
* dropped the right half off the edge, while looking entirely plausible.
|
|
23
23
|
*/
|
|
24
|
-
|
|
24
|
+
declare const OverlayCanvas: ({ width, height, draw, 'data-testid': testId, }: {
|
|
25
25
|
width: number;
|
|
26
26
|
height: number;
|
|
27
27
|
draw: (ctx: CanvasRenderingContext2D) => void;
|
|
28
28
|
'data-testid'?: string;
|
|
29
|
-
})
|
|
29
|
+
}) => import("react").JSX.Element;
|
|
30
|
+
export default OverlayCanvas;
|
package/esm/OverlayCanvas.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useRef } from 'react';
|
|
3
|
+
import { observer } from 'mobx-react';
|
|
3
4
|
import { getPreparedCanvas2D } from './canvas2dUtils.js';
|
|
4
5
|
/**
|
|
5
6
|
* An absolutely-positioned, non-interactive Canvas2D layer that composites over
|
|
@@ -24,7 +25,7 @@ import { getPreparedCanvas2D } from './canvas2dUtils.js';
|
|
|
24
25
|
* `inset: 0` therefore drew everything at twice its x on a retina display and
|
|
25
26
|
* dropped the right half off the edge, while looking entirely plausible.
|
|
26
27
|
*/
|
|
27
|
-
|
|
28
|
+
const OverlayCanvas = observer(function OverlayCanvas({ width, height, draw, 'data-testid': testId, }) {
|
|
28
29
|
const canvasRef = useRef(null);
|
|
29
30
|
useEffect(() => {
|
|
30
31
|
const ctx = getPreparedCanvas2D(canvasRef.current, width, height);
|
|
@@ -40,4 +41,5 @@ export default function OverlayCanvas({ width, height, draw, 'data-testid': test
|
|
|
40
41
|
height,
|
|
41
42
|
pointerEvents: 'none',
|
|
42
43
|
} }));
|
|
43
|
-
}
|
|
44
|
+
});
|
|
45
|
+
export default OverlayCanvas;
|
package/esm/RenderCanvas.d.ts
CHANGED
|
@@ -42,7 +42,7 @@ export interface RenderCanvasHandle {
|
|
|
42
42
|
* shared canvas repaints unconditionally, so `canvasDrawn` says nothing
|
|
43
43
|
* (ADR-009's scope clause) — so `drawn` is passed at the call site.
|
|
44
44
|
*/
|
|
45
|
-
|
|
45
|
+
declare const RenderCanvas: ({ handle, drawn, phase, ...canvasProps }: {
|
|
46
46
|
handle: RenderCanvasHandle;
|
|
47
47
|
/**
|
|
48
48
|
* Whether this canvas holds finished content — each view's own `settled`, the
|
|
@@ -59,7 +59,7 @@ export default function RenderCanvas({ handle, drawn, phase, ...canvasProps }: {
|
|
|
59
59
|
drawn: boolean;
|
|
60
60
|
/**
|
|
61
61
|
* The surface's own mutually-exclusive state, published as
|
|
62
|
-
* `data-display-phase` — the same attribute `
|
|
62
|
+
* `data-display-phase` — the same attribute `DisplayChrome` gives every
|
|
63
63
|
* LGV display, and the same split of meaning: `drawn` above is FINISHED
|
|
64
64
|
* CONTENT, this is still WORKING, and an error separates them.
|
|
65
65
|
*
|
|
@@ -73,4 +73,5 @@ export default function RenderCanvas({ handle, drawn, phase, ...canvasProps }: {
|
|
|
73
73
|
* display's phase; `comparativeSurfacePhase` is where that ranking lives.
|
|
74
74
|
*/
|
|
75
75
|
phase: DisplayStatusPhase;
|
|
76
|
-
} & Omit<ComponentPropsWithoutRef<'canvas'>, 'ref'>)
|
|
76
|
+
} & Omit<ComponentPropsWithoutRef<'canvas'>, 'ref'>) => import("react").JSX.Element;
|
|
77
|
+
export default RenderCanvas;
|
package/esm/RenderCanvas.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { observer } from 'mobx-react';
|
|
2
3
|
/**
|
|
3
4
|
* The `<canvas>` for a rendering backend owned **outside** `DisplayChrome` — the
|
|
4
5
|
* sanctioned drop-to-primitive path for the non-LGV views (dotplot, the synteny
|
|
@@ -33,6 +34,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
33
34
|
* shared canvas repaints unconditionally, so `canvasDrawn` says nothing
|
|
34
35
|
* (ADR-009's scope clause) — so `drawn` is passed at the call site.
|
|
35
36
|
*/
|
|
36
|
-
|
|
37
|
+
const RenderCanvas = observer(function RenderCanvas({ handle, drawn, phase, ...canvasProps }) {
|
|
37
38
|
return (_jsx("canvas", { "data-display-drawn": drawn, "data-display-phase": phase, ref: handle.canvasRef, ...canvasProps }, handle.canvasKey));
|
|
38
|
-
}
|
|
39
|
+
});
|
|
40
|
+
export default RenderCanvas;
|
|
@@ -17,7 +17,7 @@ import React from 'react';
|
|
|
17
17
|
* is none so mouse events fall through to the canvas; interactive children
|
|
18
18
|
* re-enable `pointerEvents:auto`.
|
|
19
19
|
*/
|
|
20
|
-
export declare
|
|
20
|
+
export declare const ScrollLockedOverlay: ({ scrollTop, viewportHeight, contentHeight, children, }: {
|
|
21
21
|
/** the model's scroll offset — the same value the GPU shader paints from */
|
|
22
22
|
scrollTop: number;
|
|
23
23
|
/** the visible viewport height (clips overflow) */
|
|
@@ -25,4 +25,4 @@ export declare function ScrollLockedOverlay({ scrollTop, viewportHeight, content
|
|
|
25
25
|
/** the full scrollable content height (the children's coordinate space) */
|
|
26
26
|
contentHeight: number;
|
|
27
27
|
children: React.ReactNode;
|
|
28
|
-
})
|
|
28
|
+
}) => React.JSX.Element;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import React from 'react';
|
|
3
|
+
import { observer } from 'mobx-react';
|
|
3
4
|
/**
|
|
4
5
|
* DOM overlay layer for a display that scrolls a fixed GPU canvas virtually (a
|
|
5
6
|
* `VerticalScrollbar` overlay + `useVirtualScrollWheel`, everything positioned
|
|
@@ -18,7 +19,7 @@ import React from 'react';
|
|
|
18
19
|
* is none so mouse events fall through to the canvas; interactive children
|
|
19
20
|
* re-enable `pointerEvents:auto`.
|
|
20
21
|
*/
|
|
21
|
-
export function ScrollLockedOverlay({ scrollTop, viewportHeight, contentHeight, children, }) {
|
|
22
|
+
export const ScrollLockedOverlay = observer(function ScrollLockedOverlay({ scrollTop, viewportHeight, contentHeight, children, }) {
|
|
22
23
|
return (_jsx("div", { style: {
|
|
23
24
|
position: 'absolute',
|
|
24
25
|
top: 0,
|
|
@@ -39,4 +40,4 @@ export function ScrollLockedOverlay({ scrollTop, viewportHeight, contentHeight,
|
|
|
39
40
|
height: contentHeight,
|
|
40
41
|
transform: `translateY(${-scrollTop}px)`,
|
|
41
42
|
}, children: children }) }));
|
|
42
|
-
}
|
|
43
|
+
});
|
package/esm/blockClipUtils.d.ts
CHANGED
|
@@ -8,12 +8,12 @@ export interface BlockClipResult {
|
|
|
8
8
|
pxW: number;
|
|
9
9
|
pxH: number;
|
|
10
10
|
/**
|
|
11
|
-
* The
|
|
12
|
-
* not `getDpr()
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* that can be 0.
|
|
11
|
+
* The scale the backing store ACTUALLY got on each axis — `hal.resize`'s
|
|
12
|
+
* answer, not `getDpr()`, which a clamped or browser-shrunk canvas departs
|
|
13
|
+
* from. A renderer working in device px reads these rather than dividing
|
|
14
|
+
* `pxH` by a height that can be 0.
|
|
16
15
|
*/
|
|
16
|
+
scaleX: number;
|
|
17
17
|
scaleY: number;
|
|
18
18
|
bpStartHi: number;
|
|
19
19
|
bpStartLo: number;
|
package/esm/blockClipUtils.js
CHANGED
|
@@ -43,9 +43,9 @@ export function writeBpRangeUniforms(uniformF32, offsetF32, clip, reversed) {
|
|
|
43
43
|
uniformF32[offsetF32 + 2] = len;
|
|
44
44
|
}
|
|
45
45
|
export function clipBlock(block, canvasWidth, canvasHeight,
|
|
46
|
-
// The scale the backing store actually got, per axis (`hal.resize`)
|
|
47
|
-
//
|
|
48
|
-
//
|
|
46
|
+
// The scale the backing store actually got, per axis (`hal.resize`). A
|
|
47
|
+
// capped canvas or a browser-shrunk WebGL drawing buffer falls below
|
|
48
|
+
// `getDpr()` on either axis, and the two axes can differ.
|
|
49
49
|
scale) {
|
|
50
50
|
const clamp = clampBlockScissor(block.screenStartPx, block.screenEndPx, canvasWidth);
|
|
51
51
|
if (!clamp) {
|
|
@@ -90,6 +90,7 @@ scale) {
|
|
|
90
90
|
pxX,
|
|
91
91
|
pxW,
|
|
92
92
|
pxH,
|
|
93
|
+
scaleX: scale.x,
|
|
93
94
|
scaleY: scale.y,
|
|
94
95
|
bpStartHi,
|
|
95
96
|
bpStartLo,
|
package/esm/canvas2dUtils.d.ts
CHANGED
|
@@ -17,40 +17,34 @@ export declare const MAX_DPR = 2;
|
|
|
17
17
|
* geometry at a different scale than the canvas it lands on.
|
|
18
18
|
*
|
|
19
19
|
* Two places legitimately want something other than this and should keep saying
|
|
20
|
-
* so explicitly: `createSvgRasterCanvas`
|
|
21
|
-
*
|
|
20
|
+
* so explicitly: `createSvgRasterCanvas` rasterizes at 2x because export goes
|
|
21
|
+
* to a file, and the analytics / error-report paths read the raw
|
|
22
22
|
* global because they are reporting the device, not drawing on it.
|
|
23
23
|
*/
|
|
24
24
|
export declare function getDpr(): number;
|
|
25
25
|
export declare const MAX_CANVAS_DIM_PX = 8192;
|
|
26
26
|
/**
|
|
27
27
|
* The largest CSS-px extent a canvas may take on one axis before its backing
|
|
28
|
-
* store (`× dpr`)
|
|
28
|
+
* store (`× dpr`) reaches {@link MAX_CANVAS_DIM_PX}.
|
|
29
29
|
*
|
|
30
30
|
* For displays that size a canvas to their **content** rather than to a
|
|
31
|
-
* viewport
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* frame, WebGL clamps and paints at the wrong scale, and the Canvas2D fallback
|
|
36
|
-
* stretches its top slice over the whole track.
|
|
31
|
+
* viewport, a row stack that grows with the row count. Past it the canvas still
|
|
32
|
+
* draws, at a reduced resolution on that axis (`syncCanvasSize` reports the
|
|
33
|
+
* scale it got), so the cap is about keeping the rows legible: MAF scrolls its
|
|
34
|
+
* overflow into a viewport, and multi-row divides the cap across its rows.
|
|
37
35
|
*
|
|
38
36
|
* A function, not a constant: `getDpr()` follows the window, so a display
|
|
39
37
|
* reading this into a computed re-derives it when the window moves to another
|
|
40
|
-
* screen.
|
|
41
|
-
* viewport, the multi-row painting divides the cap across its rows so they thin
|
|
42
|
-
* out and all stay on screen.
|
|
38
|
+
* screen.
|
|
43
39
|
*/
|
|
44
40
|
export declare function maxCanvasCssPx(): number;
|
|
45
41
|
/**
|
|
46
42
|
* The ratio a canvas's backing store ACTUALLY has to its CSS box, per axis.
|
|
47
43
|
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
* rejected outright. See ARCHITECTURAL_LIMITS.md §"A canvas past
|
|
53
|
-
* MAX_CANVAS_DIM_PX renders wrong, not smaller".
|
|
44
|
+
* `getDpr()` on both axes until `backingSize` caps the store, and below it
|
|
45
|
+
* after, so every device-px rect a renderer hands the GPU derives from this.
|
|
46
|
+
* See ARCHITECTURAL_LIMITS.md §"A canvas past
|
|
47
|
+
* the backing-store caps draws at reduced resolution".
|
|
54
48
|
*/
|
|
55
49
|
export interface CanvasScale {
|
|
56
50
|
x: number;
|
|
@@ -78,9 +72,9 @@ export declare function devicePxSpan(cssStart: number, cssEnd: number, dpr: numb
|
|
|
78
72
|
* band clamped to zero height is the caller's cue to skip its passes.
|
|
79
73
|
*
|
|
80
74
|
* `dpr` is the scale the canvas ACTUALLY got (`hal.resize`'s return), not
|
|
81
|
-
* `getDpr()`:
|
|
82
|
-
*
|
|
83
|
-
* than the target.
|
|
75
|
+
* `getDpr()`: a backing store capped at `MAX_CANVAS_DIM_PX`, or a WebGL drawing
|
|
76
|
+
* buffer the browser shrank, falls below it, and a band built from the true
|
|
77
|
+
* ratio is then taller than the target.
|
|
84
78
|
*/
|
|
85
79
|
export declare function devicePxBand(top: number, height: number, dpr: number, bufH: number): {
|
|
86
80
|
top: number;
|
package/esm/canvas2dUtils.js
CHANGED
|
@@ -17,8 +17,8 @@ export const MAX_DPR = 2;
|
|
|
17
17
|
* geometry at a different scale than the canvas it lands on.
|
|
18
18
|
*
|
|
19
19
|
* Two places legitimately want something other than this and should keep saying
|
|
20
|
-
* so explicitly: `createSvgRasterCanvas`
|
|
21
|
-
*
|
|
20
|
+
* so explicitly: `createSvgRasterCanvas` rasterizes at 2x because export goes
|
|
21
|
+
* to a file, and the analytics / error-report paths read the raw
|
|
22
22
|
* global because they are reporting the device, not drawing on it.
|
|
23
23
|
*/
|
|
24
24
|
export function getDpr() {
|
|
@@ -26,62 +26,36 @@ export function getDpr() {
|
|
|
26
26
|
? 1
|
|
27
27
|
: Math.min(devicePixelRatio, MAX_DPR);
|
|
28
28
|
}
|
|
29
|
-
//
|
|
30
|
-
//
|
|
31
|
-
//
|
|
32
|
-
//
|
|
33
|
-
// hardware), Safari/Chrome cap the dimension. 8192 is under all of these, so a
|
|
34
|
-
// canvas whose backing store stays within it on both axes can't throw. Callers
|
|
35
|
-
// that can produce arbitrarily tall/wide content (e.g. the MAF rows canvas with
|
|
36
|
-
// hundreds of species) bound their CSS size against `MAX_CANVAS_DIM_PX / dpr`.
|
|
29
|
+
// Ceiling on one backing-store dimension. Browsers throw `InvalidStateError:
|
|
30
|
+
// Canvas exceeds max size` past their own limit, and a WebGL implementation
|
|
31
|
+
// caps a texture at MAX_TEXTURE_SIZE, at least 8192 on essentially all real
|
|
32
|
+
// hardware. 8192 is under all of them.
|
|
37
33
|
export const MAX_CANVAS_DIM_PX = 8192;
|
|
38
34
|
/**
|
|
39
35
|
* The largest CSS-px extent a canvas may take on one axis before its backing
|
|
40
|
-
* store (`× dpr`)
|
|
36
|
+
* store (`× dpr`) reaches {@link MAX_CANVAS_DIM_PX}.
|
|
41
37
|
*
|
|
42
38
|
* For displays that size a canvas to their **content** rather than to a
|
|
43
|
-
* viewport
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
* frame, WebGL clamps and paints at the wrong scale, and the Canvas2D fallback
|
|
48
|
-
* stretches its top slice over the whole track.
|
|
39
|
+
* viewport, a row stack that grows with the row count. Past it the canvas still
|
|
40
|
+
* draws, at a reduced resolution on that axis (`syncCanvasSize` reports the
|
|
41
|
+
* scale it got), so the cap is about keeping the rows legible: MAF scrolls its
|
|
42
|
+
* overflow into a viewport, and multi-row divides the cap across its rows.
|
|
49
43
|
*
|
|
50
44
|
* A function, not a constant: `getDpr()` follows the window, so a display
|
|
51
45
|
* reading this into a computed re-derives it when the window moves to another
|
|
52
|
-
* screen.
|
|
53
|
-
* viewport, the multi-row painting divides the cap across its rows so they thin
|
|
54
|
-
* out and all stay on screen.
|
|
46
|
+
* screen.
|
|
55
47
|
*/
|
|
56
48
|
export function maxCanvasCssPx() {
|
|
57
49
|
return MAX_CANVAS_DIM_PX / getDpr();
|
|
58
50
|
}
|
|
59
|
-
|
|
60
|
-
//
|
|
61
|
-
//
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
// `cssPx * getDpr()` by `clipBlock` and friends, against the true dpr rather
|
|
68
|
-
// than the effective one — can now exceed the backing store (WebGL clamps
|
|
69
|
-
// silently, WebGPU rejects the rect and blanks the frame). So model-level
|
|
70
|
-
// sizing must keep canvases within the limit on its own: any display sizing a
|
|
71
|
-
// canvas to its *content* rather than its viewport bounds itself with
|
|
72
|
-
// `maxCanvasCssPx()` above. Registered in
|
|
73
|
-
// agent-docs/reference/ARCHITECTURAL_LIMITS.md with the effective-dpr fix that
|
|
74
|
-
// retires it.
|
|
75
|
-
function backingPx(cssSize, dpr, axis) {
|
|
76
|
-
const value = Math.round(cssSize * dpr);
|
|
77
|
-
if (value > MAX_CANVAS_DIM_PX) {
|
|
78
|
-
if (!warnedCanvasClamp) {
|
|
79
|
-
warnedCanvasClamp = true;
|
|
80
|
-
console.warn(`Canvas ${axis} ${value}px exceeds the safe limit ${MAX_CANVAS_DIM_PX}px and was clamped`);
|
|
81
|
-
}
|
|
82
|
-
return MAX_CANVAS_DIM_PX;
|
|
83
|
-
}
|
|
84
|
-
return value;
|
|
51
|
+
// CSS px → backing-store px, each axis under MAX_CANVAS_DIM_PX. Every device-px
|
|
52
|
+
// rect derives from the scale this leaves (`syncCanvasSize`, `prepareCanvas`),
|
|
53
|
+
// so a capped canvas draws whole at a lower resolution on that axis.
|
|
54
|
+
function backingSize(cssWidth, cssHeight, dpr) {
|
|
55
|
+
return {
|
|
56
|
+
width: Math.min(Math.round(cssWidth * dpr), MAX_CANVAS_DIM_PX),
|
|
57
|
+
height: Math.min(Math.round(cssHeight * dpr), MAX_CANVAS_DIM_PX),
|
|
58
|
+
};
|
|
85
59
|
}
|
|
86
60
|
function effectiveScale(cssPx, backing) {
|
|
87
61
|
// A zero-width or zero-height canvas has no ratio to report; the true dpr is
|
|
@@ -93,9 +67,7 @@ function effectiveScale(cssPx, backing) {
|
|
|
93
67
|
// ended up with — both HAL impls and any 2D-canvas backend use this so the dpr
|
|
94
68
|
// math and style-vs-attribute logic live in one place.
|
|
95
69
|
export function syncCanvasSize(canvas, width, height) {
|
|
96
|
-
const
|
|
97
|
-
const pw = backingPx(width, dpr, 'width');
|
|
98
|
-
const ph = backingPx(height, dpr, 'height');
|
|
70
|
+
const { width: pw, height: ph } = backingSize(width, height, getDpr());
|
|
99
71
|
const changed = canvas.width !== pw || canvas.height !== ph;
|
|
100
72
|
if (changed) {
|
|
101
73
|
canvas.width = pw;
|
|
@@ -120,9 +92,7 @@ export function syncCanvasSize(canvas, width, height) {
|
|
|
120
92
|
};
|
|
121
93
|
}
|
|
122
94
|
export function prepareCanvas(canvas, ctx, canvasWidth, canvasHeight) {
|
|
123
|
-
const
|
|
124
|
-
const bufW = backingPx(canvasWidth, dpr, 'width');
|
|
125
|
-
const bufH = backingPx(canvasHeight, dpr, 'height');
|
|
95
|
+
const { width: bufW, height: bufH } = backingSize(canvasWidth, canvasHeight, getDpr());
|
|
126
96
|
if (canvas.width !== bufW || canvas.height !== bufH) {
|
|
127
97
|
canvas.width = bufW;
|
|
128
98
|
canvas.height = bufH;
|
|
@@ -175,9 +145,9 @@ export function devicePxSpan(cssStart, cssEnd, dpr) {
|
|
|
175
145
|
* band clamped to zero height is the caller's cue to skip its passes.
|
|
176
146
|
*
|
|
177
147
|
* `dpr` is the scale the canvas ACTUALLY got (`hal.resize`'s return), not
|
|
178
|
-
* `getDpr()`:
|
|
179
|
-
*
|
|
180
|
-
* than the target.
|
|
148
|
+
* `getDpr()`: a backing store capped at `MAX_CANVAS_DIM_PX`, or a WebGL drawing
|
|
149
|
+
* buffer the browser shrank, falls below it, and a band built from the true
|
|
150
|
+
* ratio is then taller than the target.
|
|
181
151
|
*/
|
|
182
152
|
export function devicePxBand(top, height, dpr, bufH) {
|
|
183
153
|
const span = devicePxSpan(top, top + height, dpr);
|
package/esm/colorRampLut.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import type { GpuHal } from './hal/index.ts';
|
|
2
2
|
/**
|
|
3
|
-
* Entries in a
|
|
3
|
+
* Entries in a color-ramp LUT, and so the width of the texture every ramp
|
|
4
4
|
* consumer binds. Off the shader that samples it: `rampColor` divides by this
|
|
5
5
|
* to land entry i on its own texel center, so a table built to a different
|
|
6
6
|
* number is a half-shade of drift at every entry.
|
|
7
7
|
*/
|
|
8
8
|
export declare const COLOR_RAMP_LUT_ENTRIES = 256;
|
|
9
9
|
/**
|
|
10
|
-
* Upload a 256-entry RGBA
|
|
10
|
+
* Upload a 256-entry RGBA color-ramp LUT as each named pass's 256×1 texture —
|
|
11
11
|
* the runtime half of the shared ramp mechanism whose shader half is
|
|
12
12
|
* `shaders/colorRampLut.slang`. Called by `createMarkBackend` alone now, for
|
|
13
13
|
* every mark declaring a `texture`: hic, LD's two shader variants and wiggle
|
package/esm/colorRampLut.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { RAMP_LUT_ENTRIES } from './shaders/colorRampLut.generated.js';
|
|
2
2
|
/**
|
|
3
|
-
* Entries in a
|
|
3
|
+
* Entries in a color-ramp LUT, and so the width of the texture every ramp
|
|
4
4
|
* consumer binds. Off the shader that samples it: `rampColor` divides by this
|
|
5
5
|
* to land entry i on its own texel center, so a table built to a different
|
|
6
6
|
* number is a half-shade of drift at every entry.
|
|
7
7
|
*/
|
|
8
8
|
export const COLOR_RAMP_LUT_ENTRIES = RAMP_LUT_ENTRIES;
|
|
9
9
|
/**
|
|
10
|
-
* Upload a 256-entry RGBA
|
|
10
|
+
* Upload a 256-entry RGBA color-ramp LUT as each named pass's 256×1 texture —
|
|
11
11
|
* the runtime half of the shared ramp mechanism whose shader half is
|
|
12
12
|
* `shaders/colorRampLut.slang`. Called by `createMarkBackend` alone now, for
|
|
13
13
|
* every mark declaring a `texture`: hic, LD's two shader variants and wiggle
|
package/esm/coverageBand.d.ts
CHANGED
|
@@ -55,7 +55,6 @@ export declare const COVERAGE_CLIP_PASS: InstancePass<Pick<CoverageBandBuffers,
|
|
|
55
55
|
export declare const COVERAGE_SNP_PASS: InstancePass<Pick<CoverageBandBuffers, 'snpPackedBuffer'>>;
|
|
56
56
|
export declare const COVERAGE_MOD_PASS: InstancePass<CoverageBandModBuffer>;
|
|
57
57
|
export declare const COVERAGE_INTERBASE_PASS: InstancePass<Pick<CoverageBandBuffers, 'interbasePackedBuffer'>>;
|
|
58
|
-
export declare const COVERAGE_INDICATOR_PASS: InstancePass<Pick<CoverageBandBuffers, 'indicatorPackedBuffer'>>;
|
|
59
58
|
/** Palette slots the band paints by name, each a packed ABGR u32. */
|
|
60
59
|
export interface CoverageBandColors {
|
|
61
60
|
coverage: number;
|
|
@@ -97,7 +96,7 @@ export interface CoverageBandUniformValues {
|
|
|
97
96
|
binSize: number;
|
|
98
97
|
/** `interbaseBarHeightPx` — the one rule the draw, the hit test and this share. */
|
|
99
98
|
interbaseHeight: number;
|
|
100
|
-
|
|
99
|
+
minAlleleFraction: number;
|
|
101
100
|
colors: CoverageBandColors;
|
|
102
101
|
}
|
|
103
102
|
/**
|
package/esm/coverageBand.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import * as coverageBarShader from './shaders/coverageBar.generated.js';
|
|
2
2
|
import * as coverageClipShader from './shaders/coverageClip.generated.js';
|
|
3
|
-
import * as coverageIndicatorShader from './shaders/coverageIndicator.generated.js';
|
|
4
3
|
import * as coverageInterbaseShader from './shaders/coverageInterbase.generated.js';
|
|
5
4
|
import * as coverageModShader from './shaders/coverageMod.generated.js';
|
|
6
5
|
import * as coverageSnpShader from './shaders/coverageSnp.generated.js';
|
|
@@ -72,10 +71,6 @@ export const COVERAGE_INTERBASE_PASS = {
|
|
|
72
71
|
...slangPass({ id: 'interbase', mod: coverageInterbaseShader }),
|
|
73
72
|
pack: data => data.interbasePackedBuffer,
|
|
74
73
|
};
|
|
75
|
-
export const COVERAGE_INDICATOR_PASS = {
|
|
76
|
-
...slangPass({ id: 'indicator', mod: coverageIndicatorShader }),
|
|
77
|
-
pack: data => data.indicatorPackedBuffer,
|
|
78
|
-
};
|
|
79
74
|
/**
|
|
80
75
|
* Fill the coverage band's uniform buffer. Total-write (the generated packer),
|
|
81
76
|
* so a field left out is a compile error rather than last frame's value.
|
|
@@ -103,7 +98,7 @@ export function writeCoverageBandUniforms(buf, v) {
|
|
|
103
98
|
coverageSymlogConstant: v.symlogConstant,
|
|
104
99
|
binSize: v.binSize,
|
|
105
100
|
interbaseHeight: v.interbaseHeight,
|
|
106
|
-
snpMinFreq: v.
|
|
101
|
+
snpMinFreq: v.minAlleleFraction,
|
|
107
102
|
reversed: v.reversed ? 1 : 0,
|
|
108
103
|
coverageScaleType: v.scaleType,
|
|
109
104
|
colorCoverage: colors.coverage,
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The
|
|
3
|
-
* `coverageBand.slang`'s passes read
|
|
2
|
+
* The coverage-band buffers a producer packs per region: three in the layouts
|
|
3
|
+
* `coverageBand.slang`'s passes read, and the indicator triangles' positions
|
|
4
|
+
* and type codes, which the point mark reads. Every field is filled by
|
|
4
5
|
* `@jbrowse/alignments-core` — `packCoverageBinsForGpu`, `computeSNPCoverage`
|
|
5
|
-
* and `computeInterbaseCoverage` (which emits the last
|
|
6
|
-
* these by running that pipeline, not by shaping them itself.
|
|
6
|
+
* and `computeInterbaseCoverage` (which emits the last three) — so a display
|
|
7
|
+
* gets these by running that pipeline, not by shaping them itself.
|
|
7
8
|
*
|
|
8
9
|
* Structural rather than nominal, and named after the layout rather than after
|
|
9
10
|
* either display: the alignments worker's `CoverageUploadData` and the MAF
|
|
@@ -19,5 +20,7 @@ export interface CoverageBandBuffers {
|
|
|
19
20
|
coveragePackedBuffer: ArrayBuffer;
|
|
20
21
|
snpPackedBuffer: ArrayBuffer;
|
|
21
22
|
interbasePackedBuffer: ArrayBuffer;
|
|
22
|
-
|
|
23
|
+
indicatorPositions: Uint32Array;
|
|
24
|
+
/** 1 insertion, 2 softclip, 3 hardclip: the most common event there. */
|
|
25
|
+
indicatorTypes: Float32Array;
|
|
23
26
|
}
|
|
@@ -14,7 +14,7 @@ export interface RenderingBackendOptions<TRenderingBackend> {
|
|
|
14
14
|
* that leans on MSAA holds its display at 4. Passing it overrides the
|
|
15
15
|
* derivation in either direction.
|
|
16
16
|
*
|
|
17
|
-
* The cost is one
|
|
17
|
+
* The cost is one color attachment the size of the canvas — an empty 600px
|
|
18
18
|
* track pays what a full one does, and eight ordinary tracks on a retina
|
|
19
19
|
* panel hold 109.7 MiB nothing counts (ARCHITECTURAL_LIMITS.md §"The MSAA
|
|
20
20
|
* target is the largest per-display allocation"); 1 allocates none. Whether a
|
package/esm/displayPhase.d.ts
CHANGED
|
@@ -18,13 +18,9 @@
|
|
|
18
18
|
*/
|
|
19
19
|
export type DisplayPhase = 'renderError' | DisplayStatusPhase;
|
|
20
20
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* (the backend hook's `retry()`), which is exactly the line between the shared
|
|
25
|
-
* status chrome and the GPU chrome wrapped around it: `DisplayStatusChrome`
|
|
26
|
-
* takes this, `DisplayChrome` takes the wider union and peels off `renderError`
|
|
27
|
-
* before delegating.
|
|
21
|
+
* Every phase except the one that reports a backend failure: what a surface
|
|
22
|
+
* with no rendering backend of its own publishes (the comparative views'
|
|
23
|
+
* shared canvas, the circular view's chords).
|
|
28
24
|
*/
|
|
29
25
|
export type DisplayStatusPhase = 'tooLarge' | 'error' | DisplayActivityPhase;
|
|
30
26
|
/**
|
|
@@ -127,8 +123,8 @@ export interface DisplayActivityInputs {
|
|
|
127
123
|
*/
|
|
128
124
|
export declare function computeActivityPhase({ isMinimized, fetchInert, viewportEmpty, isLoading, fetchCanceled, awaitingDependentData, rendersCanvas, canvasDrawn, }: DisplayActivityInputs, viewportCurrent: () => boolean, hostMounted?: () => boolean): DisplayActivityPhase;
|
|
129
125
|
/**
|
|
130
|
-
* The same ranking minus `renderError`, for a
|
|
131
|
-
*
|
|
126
|
+
* The same ranking minus `renderError`, for a surface with no rendering backend
|
|
127
|
+
* of its own to fail. `computeDisplayPhase` delegates here, so the
|
|
132
128
|
* order lives in one place.
|
|
133
129
|
*/
|
|
134
130
|
export declare function computeDisplayStatusPhase({ regionTooLarge, error }: DisplayStatusPhaseInputs, activity: () => DisplayActivityPhase): DisplayStatusPhase;
|
package/esm/displayPhase.js
CHANGED
|
@@ -48,8 +48,8 @@ export function computeActivityPhase({ isMinimized, fetchInert, viewportEmpty, i
|
|
|
48
48
|
: 'ready';
|
|
49
49
|
}
|
|
50
50
|
/**
|
|
51
|
-
* The same ranking minus `renderError`, for a
|
|
52
|
-
*
|
|
51
|
+
* The same ranking minus `renderError`, for a surface with no rendering backend
|
|
52
|
+
* of its own to fail. `computeDisplayPhase` delegates here, so the
|
|
53
53
|
* order lives in one place.
|
|
54
54
|
*/
|
|
55
55
|
export function computeDisplayStatusPhase({ regionTooLarge, error }, activity) {
|
package/esm/hal/mockHal.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { GpuHalBase } from './gpuHalBase.ts';
|
|
2
|
+
import type { CanvasScale } from '../canvas2dUtils.ts';
|
|
2
3
|
import type { GpuHal, PipelineDescriptor, ShaderSource, TextureBinding, TextureSource } from './types.ts';
|
|
3
4
|
/** Text for a pass built only for a `MockHal`, which never loads it. */
|
|
4
5
|
export declare const MOCK_SHADER_SOURCE: ShaderSource;
|
|
@@ -99,10 +100,8 @@ export declare class MockHal extends GpuHalBase<MockBuffer> implements GpuHal {
|
|
|
99
100
|
private record;
|
|
100
101
|
errorHandler: ((error: Error) => void) | null;
|
|
101
102
|
setErrorHandler(handler: (error: Error) => void): void;
|
|
102
|
-
resize(width: number, height: number):
|
|
103
|
-
|
|
104
|
-
y: number;
|
|
105
|
-
};
|
|
103
|
+
resize(width: number, height: number): CanvasScale;
|
|
104
|
+
reportedScale: CanvasScale | undefined;
|
|
106
105
|
releaseRenderTargets(): void;
|
|
107
106
|
uploadBuffer(regionKey: number, passId: string, data: ArrayBuffer | ArrayBufferView, count: number): void;
|
|
108
107
|
deleteBuffer(regionKey: number, passId: string): void;
|
package/esm/hal/mockHal.js
CHANGED
|
@@ -108,11 +108,12 @@ export class MockHal extends GpuHalBase {
|
|
|
108
108
|
}
|
|
109
109
|
this.record('resize', width, height);
|
|
110
110
|
// The real HALs report the scale their backing store actually got, and
|
|
111
|
-
// every device-px rect a renderer builds comes from this
|
|
112
|
-
//
|
|
113
|
-
//
|
|
114
|
-
return { x: getDpr(), y: getDpr() };
|
|
111
|
+
// every device-px rect a renderer builds comes from this. `getDpr()` is the
|
|
112
|
+
// unclamped answer; `reportedScale` stands in for a clamped canvas or a
|
|
113
|
+
// drawing buffer the browser shrank.
|
|
114
|
+
return this.reportedScale ?? { x: getDpr(), y: getDpr() };
|
|
115
115
|
}
|
|
116
|
+
reportedScale = undefined;
|
|
116
117
|
releaseRenderTargets() {
|
|
117
118
|
this.record('releaseRenderTargets');
|
|
118
119
|
}
|
package/esm/hal/types.d.ts
CHANGED
|
@@ -20,7 +20,7 @@ export interface VertexAttributeLayout {
|
|
|
20
20
|
* 4" — standard sample patterns are defined for no other count), so this is the
|
|
21
21
|
* API's constraint rather than a policy of ours, and 2 is not an option to add.
|
|
22
22
|
*
|
|
23
|
-
* At 4 the HAL allocates a multisampled
|
|
23
|
+
* At 4 the HAL allocates a multisampled color attachment the size of the
|
|
24
24
|
* canvas and resolves it into the canvas texture; at 1 it allocates **nothing**
|
|
25
25
|
* and draws straight into the canvas texture. The bytes are canvas area x dpr²
|
|
26
26
|
* x samples x 4, unrelated to how much data the display holds, which is why
|
|
@@ -119,10 +119,10 @@ export interface GpuHal {
|
|
|
119
119
|
readonly uniformByteSize: number;
|
|
120
120
|
/**
|
|
121
121
|
* Size the canvas, and report the scale its backing store actually got.
|
|
122
|
-
* Callers derive every device-px rect from
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
122
|
+
* Callers derive every device-px rect from that scale. It differs from
|
|
123
|
+
* `getDpr()` past the backing-store caps in `canvas2dUtils.ts` and where
|
|
124
|
+
* a browser shrinks a WebGL drawing buffer, and a rect built from the true
|
|
125
|
+
* dpr then lands outside the target.
|
|
126
126
|
*/
|
|
127
127
|
resize(width: number, height: number): CanvasScale;
|
|
128
128
|
/**
|
package/esm/hal/webgl2Hal.d.ts
CHANGED
|
@@ -37,7 +37,10 @@ export declare class WebGL2Hal extends GpuHalBase<RegionPassBuffer> implements G
|
|
|
37
37
|
protected destroyBuffer(buf: RegionPassBuffer): void;
|
|
38
38
|
private link;
|
|
39
39
|
private getPass;
|
|
40
|
-
resize(width: number, height: number):
|
|
40
|
+
resize(width: number, height: number): {
|
|
41
|
+
x: number;
|
|
42
|
+
y: number;
|
|
43
|
+
};
|
|
41
44
|
/**
|
|
42
45
|
* Nothing to give back. WebGL2 multisamples in the drawing buffer the context
|
|
43
46
|
* owns (`antialias` above one sample), so this HAL holds no separate target —
|