@jbrowse/render-core 5.0.0-beta.10 → 5.0.0-beta.11
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 +1 -1
- package/esm/RenderCanvas.js +1 -1
- package/esm/canvas2dUtils.js +1 -1
- package/esm/createRenderingBackend.d.ts +2 -2
- package/esm/createRenderingBackend.js +2 -2
- package/esm/graphicsCapabilities.js +1 -1
- package/esm/hal/createHal.js +1 -1
- package/esm/hal/deviceGpuCache.js +8 -11
- package/esm/hal/types.d.ts +0 -2
- package/esm/hal/webgl2Hal.d.ts +1 -1
- package/esm/hal/webgl2Hal.js +1 -4
- package/esm/hal/webgpuHal.js +2 -3
- package/esm/marks/index.d.ts +1 -1
- package/esm/marks/index.js +1 -1
- package/esm/marks/markRamp.d.ts +4 -2
- package/esm/marks/markRamp.js +14 -6
- package/esm/marks/rowSpanIndex.d.ts +3 -2
- package/esm/marks/rowSpanIndex.js +18 -8
- package/esm/slangPass.d.ts +5 -6
- package/package.json +2 -2
- package/src/shaders/capsule.slang +1 -1
- package/src/shaders/rowRect.slang +2 -2
package/esm/RenderCanvas.d.ts
CHANGED
|
@@ -25,7 +25,7 @@ export interface RenderCanvasHandle {
|
|
|
25
25
|
* render-prop body on the same value for the displays on the chrome, which it
|
|
26
26
|
* does *not* get for free from the `renderError` unmount (that covers only a
|
|
27
27
|
* reported loss — see the `canvasKey` note in useRenderingBackend.ts).
|
|
28
|
-
*
|
|
28
|
+
* GPU_DISPLAY_LIFECYCLE.md said so and ended with "any new consumer rendering its own
|
|
29
29
|
* banner must too" — a rule enforced by remembering to read the doc. Rendering
|
|
30
30
|
* the element here makes it structural instead: there is no way to mount this
|
|
31
31
|
* canvas without the key.
|
package/esm/RenderCanvas.js
CHANGED
|
@@ -16,7 +16,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
16
16
|
* render-prop body on the same value for the displays on the chrome, which it
|
|
17
17
|
* does *not* get for free from the `renderError` unmount (that covers only a
|
|
18
18
|
* reported loss — see the `canvasKey` note in useRenderingBackend.ts).
|
|
19
|
-
*
|
|
19
|
+
* GPU_DISPLAY_LIFECYCLE.md said so and ended with "any new consumer rendering its own
|
|
20
20
|
* banner must too" — a rule enforced by remembering to read the doc. Rendering
|
|
21
21
|
* the element here makes it structural instead: there is no way to mount this
|
|
22
22
|
* canvas without the key.
|
package/esm/canvas2dUtils.js
CHANGED
|
@@ -139,7 +139,7 @@ export function prepareCanvas(canvas, ctx, canvasWidth, canvasHeight) {
|
|
|
139
139
|
// `getContext('2d')` + null-guard + `prepareCanvas` ritual that every
|
|
140
140
|
// standalone 2D overlay otherwise hand-rolls in its draw effect — and the
|
|
141
141
|
// `prepareCanvas` DPR step is easy to omit, which renders blurry on Retina
|
|
142
|
-
// (see agent-docs/reference/
|
|
142
|
+
// (see agent-docs/reference/GPU_SHADERS.md §"Canvas scaling & hi-DPI").
|
|
143
143
|
// Returning the
|
|
144
144
|
// prepared ctx structurally prevents that omission.
|
|
145
145
|
export function getPreparedCanvas2D(canvas, width, height) {
|
|
@@ -40,9 +40,9 @@ export declare function createRenderingBackend<TRenderingBackend>(canvas: HTMLCa
|
|
|
40
40
|
* `DisplayChrome` machinery as a GPU display — the lifecycle is backend-
|
|
41
41
|
* agnostic, so nothing downstream knows or cares there's no HAL.
|
|
42
42
|
*
|
|
43
|
-
*
|
|
43
|
+
* No in-tree display uses it. Promote to the dual-path
|
|
44
44
|
* `createRenderingBackend` only once a profile shows Canvas2D can't keep 60fps
|
|
45
45
|
* at the display's real feature counts (≳100K features/frame — see
|
|
46
|
-
*
|
|
46
|
+
* agent-docs/reference/PLUGIN_ABI_STABILITY.md §Canvas2D or GPU).
|
|
47
47
|
*/
|
|
48
48
|
export declare function createCanvas2DBackend<TRenderingBackend>(canvas: HTMLCanvasElement, createCanvas2DRenderingBackend: (canvas: HTMLCanvasElement) => TRenderingBackend): Promise<TRenderingBackend>;
|
|
@@ -50,10 +50,10 @@ export async function createRenderingBackend(canvas, { passes, sampleCount = der
|
|
|
50
50
|
* `DisplayChrome` machinery as a GPU display — the lifecycle is backend-
|
|
51
51
|
* agnostic, so nothing downstream knows or cares there's no HAL.
|
|
52
52
|
*
|
|
53
|
-
*
|
|
53
|
+
* No in-tree display uses it. Promote to the dual-path
|
|
54
54
|
* `createRenderingBackend` only once a profile shows Canvas2D can't keep 60fps
|
|
55
55
|
* at the display's real feature counts (≳100K features/frame — see
|
|
56
|
-
*
|
|
56
|
+
* agent-docs/reference/PLUGIN_ABI_STABILITY.md §Canvas2D or GPU).
|
|
57
57
|
*/
|
|
58
58
|
export function createCanvas2DBackend(canvas, createCanvas2DRenderingBackend) {
|
|
59
59
|
return Promise.resolve(createCanvas2DRenderingBackend(canvas));
|
|
@@ -54,7 +54,7 @@ async function probeWebgpu() {
|
|
|
54
54
|
* moment this returns and the browser reclaims the context on GC, the same
|
|
55
55
|
* release the HAL relies on. A page that then reaches the 16-context ceiling
|
|
56
56
|
* evicts this one first (it is the oldest, and nothing draws to it or
|
|
57
|
-
* re-acquires it), so the eviction cascade in
|
|
57
|
+
* re-acquires it), so the eviction cascade in GPU_PORTABILITY.md cannot
|
|
58
58
|
* start here.
|
|
59
59
|
*
|
|
60
60
|
* The driver string comes off the same context, so it is free where it matters:
|
package/esm/hal/createHal.js
CHANGED
|
@@ -64,7 +64,7 @@ async function climbLadder(canvas, { passes, sampleCount, failures }) {
|
|
|
64
64
|
// volvox tracks, and *no scroll churn at all* — headless Chrome (SwiftShader),
|
|
65
65
|
// three runs each: WebGL2 blocks the main thread for 1.3-5.5 s in a single
|
|
66
66
|
// task and 2.1-8.8 s in total, while Canvas2D never exceeds 339 ms and never
|
|
67
|
-
// once produces a task over 500 ms.
|
|
67
|
+
// once produces a task over 500 ms. GPU_PORTABILITY.md has the churn case
|
|
68
68
|
// at ~25x; this is the floor, and it is the load-time pipeline build rather
|
|
69
69
|
// than the per-pass rebuild the churn number measures.
|
|
70
70
|
//
|
|
@@ -28,21 +28,18 @@ export function bindGroupLayoutEntries(bindings) {
|
|
|
28
28
|
});
|
|
29
29
|
}
|
|
30
30
|
function gpuBlendState(bs) {
|
|
31
|
-
// WebGPU rejects any factor but 'one' under max
|
|
32
|
-
//
|
|
31
|
+
// WebGPU rejects any factor but 'one' under max, which ignores them. Alpha
|
|
32
|
+
// accumulates as webgl2Hal's applyBlendState does.
|
|
33
33
|
const max = { srcFactor: 'one', dstFactor: 'one', operation: 'max' };
|
|
34
|
-
const min = { srcFactor: 'one', dstFactor: 'one', operation: 'min' };
|
|
35
34
|
const behind = { srcFactor: 'one-minus-dst-alpha', dstFactor: 'one' };
|
|
36
35
|
return bs.op === 'max'
|
|
37
36
|
? { color: max, alpha: max }
|
|
38
|
-
: bs.op === '
|
|
39
|
-
? { color:
|
|
40
|
-
:
|
|
41
|
-
|
|
42
|
-
: {
|
|
43
|
-
|
|
44
|
-
alpha: { srcFactor: 'one', dstFactor: 'one-minus-src-alpha' },
|
|
45
|
-
};
|
|
37
|
+
: bs.op === 'behind'
|
|
38
|
+
? { color: behind, alpha: behind }
|
|
39
|
+
: {
|
|
40
|
+
color: { srcFactor: bs.srcFactor, dstFactor: bs.dstFactor },
|
|
41
|
+
alpha: { srcFactor: 'one', dstFactor: 'one-minus-src-alpha' },
|
|
42
|
+
};
|
|
46
43
|
}
|
|
47
44
|
export function pipelineRecipe(desc, wgslSource, sampleCount) {
|
|
48
45
|
return {
|
package/esm/hal/types.d.ts
CHANGED
package/esm/hal/webgl2Hal.d.ts
CHANGED
|
@@ -43,7 +43,7 @@ export declare class WebGL2Hal extends GpuHalBase<RegionPassBuffer> implements G
|
|
|
43
43
|
* owns (`antialias` above one sample), so this HAL holds no separate target —
|
|
44
44
|
* releasing its samples means dropping the context, which costs a re-acquire
|
|
45
45
|
* against a hard 16-context ceiling and a full shader recompile per display.
|
|
46
|
-
* `agent-docs/reference/
|
|
46
|
+
* `agent-docs/reference/GPU_PORTABILITY.md` measured that trade and
|
|
47
47
|
* declined it; what makes the WebGPU side worth doing is that it pays
|
|
48
48
|
* neither.
|
|
49
49
|
*/
|
package/esm/hal/webgl2Hal.js
CHANGED
|
@@ -308,7 +308,7 @@ export class WebGL2Hal extends GpuHalBase {
|
|
|
308
308
|
* owns (`antialias` above one sample), so this HAL holds no separate target —
|
|
309
309
|
* releasing its samples means dropping the context, which costs a re-acquire
|
|
310
310
|
* against a hard 16-context ceiling and a full shader recompile per display.
|
|
311
|
-
* `agent-docs/reference/
|
|
311
|
+
* `agent-docs/reference/GPU_PORTABILITY.md` measured that trade and
|
|
312
312
|
* declined it; what makes the WebGPU side worth doing is that it pays
|
|
313
313
|
* neither.
|
|
314
314
|
*/
|
|
@@ -458,9 +458,6 @@ export class WebGL2Hal extends GpuHalBase {
|
|
|
458
458
|
if (bs?.op === 'max') {
|
|
459
459
|
gl.blendEquation(gl.MAX);
|
|
460
460
|
}
|
|
461
|
-
else if (bs?.op === 'min') {
|
|
462
|
-
gl.blendEquation(gl.MIN);
|
|
463
|
-
}
|
|
464
461
|
else if (bs?.op === 'behind') {
|
|
465
462
|
gl.blendEquation(gl.FUNC_ADD);
|
|
466
463
|
gl.blendFuncSeparate(gl.ONE_MINUS_DST_ALPHA, gl.ONE, gl.ONE_MINUS_DST_ALPHA, gl.ONE);
|
package/esm/hal/webgpuHal.js
CHANGED
|
@@ -60,9 +60,8 @@ async function buildPipeline(device, recipe, passId) {
|
|
|
60
60
|
multisample: recipe.sampleCount === 1 ? undefined : { count: recipe.sampleCount },
|
|
61
61
|
});
|
|
62
62
|
}
|
|
63
|
-
// Every declared pass up front, unlike WebGL2's first-draw link
|
|
64
|
-
//
|
|
65
|
-
// before it can paint". Each pass compiles as soon as its own WGSL arrives.
|
|
63
|
+
// Every declared pass up front, unlike WebGL2's first-draw link. Each pass
|
|
64
|
+
// compiles as soon as its own WGSL arrives.
|
|
66
65
|
async function resolvePipelines(device, descriptors, sampleCount) {
|
|
67
66
|
const built = await Promise.all(descriptors.map(async (desc) => {
|
|
68
67
|
const { WGSL_SOURCE } = await desc.source.wgsl();
|
package/esm/marks/index.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ export { appendGlyph, pointInsetPx } from './glyphPaint.ts';
|
|
|
14
14
|
export { recordPath } from './pathRecorder.ts';
|
|
15
15
|
export { abgrToCssRgba, makeAbgrFill } from './colorFill.ts';
|
|
16
16
|
export { RAMP_NOT_A_NUMBER_COLOR, RAMP_NO_VALUE_BITS, RAMP_NO_VALUE_COLOR, } from '../shaders/markColor.generated.ts';
|
|
17
|
-
export { instanceColor, isThreshold, keepRampValues, rampUniforms, rampValueBits, thresholdBandOf, } from './markRamp.ts';
|
|
17
|
+
export { instanceColor, isThreshold, keepRampValues, paintColors, rampUniforms, rampValueBits, thresholdBandOf, } from './markRamp.ts';
|
|
18
18
|
export { HIDDEN_ROW, NO_ROW_COLOR, RowKeys, buildRowTable } from './rowTable.ts';
|
|
19
19
|
export { keySlot, rowColor, rowSlot } from './rowLane.ts';
|
|
20
20
|
export { rowSpanIndex, spansInRow } from './rowSpanIndex.ts';
|
package/esm/marks/index.js
CHANGED
|
@@ -14,7 +14,7 @@ export { appendGlyph, pointInsetPx } from './glyphPaint.js';
|
|
|
14
14
|
export { recordPath } from './pathRecorder.js';
|
|
15
15
|
export { abgrToCssRgba, makeAbgrFill } from './colorFill.js';
|
|
16
16
|
export { RAMP_NOT_A_NUMBER_COLOR, RAMP_NO_VALUE_BITS, RAMP_NO_VALUE_COLOR, } from '../shaders/markColor.generated.js';
|
|
17
|
-
export { instanceColor, isThreshold, keepRampValues, rampUniforms, rampValueBits, thresholdBandOf, } from './markRamp.js';
|
|
17
|
+
export { instanceColor, isThreshold, keepRampValues, paintColors, rampUniforms, rampValueBits, thresholdBandOf, } from './markRamp.js';
|
|
18
18
|
export { HIDDEN_ROW, NO_ROW_COLOR, RowKeys, buildRowTable } from './rowTable.js';
|
|
19
19
|
export { keySlot, rowColor, rowSlot } from './rowLane.js';
|
|
20
20
|
export { rowSpanIndex, spansInRow } from './rowSpanIndex.js';
|
package/esm/marks/markRamp.d.ts
CHANGED
|
@@ -56,8 +56,10 @@ export declare function rampValueBits(values: Float32Array): Uint32Array<ArrayBu
|
|
|
56
56
|
*/
|
|
57
57
|
export declare function keepRampValues(values: Float32Array, keep: (value: number, index: number) => boolean): Float32Array<ArrayBuffer>;
|
|
58
58
|
/**
|
|
59
|
-
* The interval a value is in on a threshold: how many of the ascending
|
|
60
|
-
* is at or past, `thresholdIndex`'s rule and the shader's
|
|
59
|
+
* The interval a lane value is in on a threshold: how many of the ascending
|
|
60
|
+
* cuts it is at or past, `thresholdIndex`'s rule and the shader's
|
|
61
|
+
* `thresholdBand`. The value is a float32 and so is each cut in the shader's
|
|
62
|
+
* uniform, so a cut compares as one here: 0.7 off a lane is at a cut of 0.7.
|
|
61
63
|
*/
|
|
62
64
|
export declare function thresholdBandOf(value: number, cuts: readonly number[]): number;
|
|
63
65
|
/**
|
package/esm/marks/markRamp.js
CHANGED
|
@@ -99,13 +99,15 @@ export function keepRampValues(values, keep) {
|
|
|
99
99
|
return new Float32Array(kept.buffer, kept.byteOffset, kept.length);
|
|
100
100
|
}
|
|
101
101
|
/**
|
|
102
|
-
* The interval a value is in on a threshold: how many of the ascending
|
|
103
|
-
* is at or past, `thresholdIndex`'s rule and the shader's
|
|
102
|
+
* The interval a lane value is in on a threshold: how many of the ascending
|
|
103
|
+
* cuts it is at or past, `thresholdIndex`'s rule and the shader's
|
|
104
|
+
* `thresholdBand`. The value is a float32 and so is each cut in the shader's
|
|
105
|
+
* uniform, so a cut compares as one here: 0.7 off a lane is at a cut of 0.7.
|
|
104
106
|
*/
|
|
105
107
|
export function thresholdBandOf(value, cuts) {
|
|
106
108
|
let band = 0;
|
|
107
109
|
for (const cut of cuts) {
|
|
108
|
-
if (value >= cut) {
|
|
110
|
+
if (value >= Math.fround(cut)) {
|
|
109
111
|
band++;
|
|
110
112
|
}
|
|
111
113
|
}
|
|
@@ -150,9 +152,7 @@ export function paintColors(c, count, scale) {
|
|
|
150
152
|
const colors = new Uint32Array(count);
|
|
151
153
|
const bits = rampValueBits(colorValue);
|
|
152
154
|
const colorOf = isThreshold(scale)
|
|
153
|
-
? (
|
|
154
|
-
? scale.colors[thresholdBandOf(value, scale.cuts)]
|
|
155
|
-
: scale.colors[value > 0 ? scale.cuts.length : 0]
|
|
155
|
+
? thresholdColorOf(scale)
|
|
156
156
|
: rampColorOf(scale);
|
|
157
157
|
for (let i = 0; i < count; i++) {
|
|
158
158
|
const value = colorValue[i];
|
|
@@ -175,6 +175,14 @@ function constantColors(c, color, count) {
|
|
|
175
175
|
c.constantBake = colors;
|
|
176
176
|
return colors;
|
|
177
177
|
}
|
|
178
|
+
// The cuts the shader's uniform block holds, so Canvas2D paints a value past
|
|
179
|
+
// the last of them in the band the GPU does.
|
|
180
|
+
function thresholdColorOf(scale) {
|
|
181
|
+
const cuts = scale.cuts.slice(0, MAX_COLOR_CUTS);
|
|
182
|
+
return (value) => Number.isFinite(value)
|
|
183
|
+
? scale.colors[thresholdBandOf(value, cuts)]
|
|
184
|
+
: scale.colors[value > 0 ? cuts.length : 0];
|
|
185
|
+
}
|
|
178
186
|
function rampColorOf(ramp) {
|
|
179
187
|
const [min, max] = ramp.domain;
|
|
180
188
|
const log = ramp.scale === 'log';
|
|
@@ -16,8 +16,9 @@ export interface RowSpanIndex {
|
|
|
16
16
|
}
|
|
17
17
|
/**
|
|
18
18
|
* The index over `count` spans from `x` to `x2`, each in the row `row` names
|
|
19
|
-
* (row 0 where there is no lane)
|
|
20
|
-
*
|
|
19
|
+
* (row 0 where there is no lane), less those on `HIDDEN_ROW`, which no row
|
|
20
|
+
* holds. A counting sort by row, a sort of each row the input left out of
|
|
21
|
+
* start order, and one pass for the reach.
|
|
21
22
|
*/
|
|
22
23
|
export declare function rowSpanIndex(x: Uint32Array, x2: Uint32Array, row: Uint32Array | undefined, count?: number): RowSpanIndex;
|
|
23
24
|
/**
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { HIDDEN_ROW } from './rowTable.js';
|
|
1
2
|
const lowEnd = (x, x2, i) => Math.min(x[i], x2[i]);
|
|
2
3
|
const highEnd = (x, x2, i) => Math.max(x[i], x2[i]);
|
|
3
4
|
// A row that arrived nearly in start order, as `cells` writes one (an
|
|
@@ -53,22 +54,27 @@ function sortRow(order, from, to, x, x2) {
|
|
|
53
54
|
}
|
|
54
55
|
/**
|
|
55
56
|
* The index over `count` spans from `x` to `x2`, each in the row `row` names
|
|
56
|
-
* (row 0 where there is no lane)
|
|
57
|
-
*
|
|
57
|
+
* (row 0 where there is no lane), less those on `HIDDEN_ROW`, which no row
|
|
58
|
+
* holds. A counting sort by row, a sort of each row the input left out of
|
|
59
|
+
* start order, and one pass for the reach.
|
|
58
60
|
*/
|
|
59
61
|
export function rowSpanIndex(x, x2, row, count = x.length) {
|
|
60
62
|
let rows = 1;
|
|
61
63
|
if (row) {
|
|
62
64
|
for (let i = 0; i < count; i++) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
+
const r = row[i];
|
|
66
|
+
if (r !== HIDDEN_ROW && r + 1 > rows) {
|
|
67
|
+
rows = r + 1;
|
|
65
68
|
}
|
|
66
69
|
}
|
|
67
70
|
}
|
|
68
71
|
const rowStart = new Uint32Array(rows + 1);
|
|
69
72
|
if (row) {
|
|
70
73
|
for (let i = 0; i < count; i++) {
|
|
71
|
-
|
|
74
|
+
const r = row[i];
|
|
75
|
+
if (r !== HIDDEN_ROW) {
|
|
76
|
+
rowStart[r + 1]++;
|
|
77
|
+
}
|
|
72
78
|
}
|
|
73
79
|
for (let r = 0; r < rows; r++) {
|
|
74
80
|
rowStart[r + 1] = rowStart[r + 1] + rowStart[r];
|
|
@@ -77,11 +83,15 @@ export function rowSpanIndex(x, x2, row, count = x.length) {
|
|
|
77
83
|
else {
|
|
78
84
|
rowStart[1] = count;
|
|
79
85
|
}
|
|
80
|
-
const
|
|
86
|
+
const placed = rowStart[rows];
|
|
87
|
+
const order = new Uint32Array(placed);
|
|
81
88
|
if (row) {
|
|
82
89
|
const next = rowStart.slice(0, rows);
|
|
83
90
|
for (let i = 0; i < count; i++) {
|
|
84
|
-
|
|
91
|
+
const r = row[i];
|
|
92
|
+
if (r !== HIDDEN_ROW) {
|
|
93
|
+
order[next[r]++] = i;
|
|
94
|
+
}
|
|
85
95
|
}
|
|
86
96
|
}
|
|
87
97
|
else {
|
|
@@ -89,7 +99,7 @@ export function rowSpanIndex(x, x2, row, count = x.length) {
|
|
|
89
99
|
order[i] = i;
|
|
90
100
|
}
|
|
91
101
|
}
|
|
92
|
-
const reach = new Uint32Array(
|
|
102
|
+
const reach = new Uint32Array(placed);
|
|
93
103
|
for (let r = 0; r < rows; r++) {
|
|
94
104
|
const from = rowStart[r];
|
|
95
105
|
const to = rowStart[r + 1];
|
package/esm/slangPass.d.ts
CHANGED
|
@@ -20,12 +20,11 @@ export interface ShaderModule {
|
|
|
20
20
|
*
|
|
21
21
|
* - `verticesPerInstance` — the canvas chevron pass, whose count is the
|
|
22
22
|
* shader's `CHEVRON_VERTS` times a cap the *renderer* chooses.
|
|
23
|
-
* - `blendState` / `topology` —
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* the
|
|
27
|
-
*
|
|
28
|
-
* shader whose passes disagree declares neither and says which at each pass.
|
|
23
|
+
* - `blendState` / `topology` — no pass in the tree overrides these. Wiggle's
|
|
24
|
+
* step line and center line did while they shared one module and blended
|
|
25
|
+
* differently (src-over against max); each record now has its own module,
|
|
26
|
+
* and the center line's states `//! blend: max` itself. A shader whose passes
|
|
27
|
+
* disagree declares neither and says which at each pass.
|
|
29
28
|
* - `blend: false` — nothing disables blending today, which is why there is no
|
|
30
29
|
* `//! blend: none` to inherit it from.
|
|
31
30
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jbrowse/render-core",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.11",
|
|
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": [
|
|
@@ -95,7 +95,7 @@
|
|
|
95
95
|
"./useTabVisibilityRerender": "./esm/useTabVisibilityRerender.js"
|
|
96
96
|
},
|
|
97
97
|
"dependencies": {
|
|
98
|
-
"@jbrowse/mobx-state-tree": "^6.
|
|
98
|
+
"@jbrowse/mobx-state-tree": "^6.7.0",
|
|
99
99
|
"mobx": "^7.0.5"
|
|
100
100
|
},
|
|
101
101
|
"peerDependencies": {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// `capsuleDist` and nowhere else: the edge ramp over that distance is
|
|
3
3
|
// `antialias`'s one `edgeCoverage`, shared with every butt-capped stroke in the
|
|
4
4
|
// tree. Consumers, and which half each takes:
|
|
5
|
-
// agent-docs/reference/
|
|
5
|
+
// agent-docs/reference/SHADER_JS_CODEGEN.md.
|
|
6
6
|
//
|
|
7
7
|
// `capsuleQuadLocal` pads by exactly `aaHalfPx(dpr)` past the ink. Pad less and
|
|
8
8
|
// the ramp is clipped at the quad edge — coverage falls to 0.5 at the boundary,
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
// are sparse intervals with nothing beside them, so it floors; MAF's cells
|
|
18
18
|
// never gap and it passes 0; wiggle density tiles at most zooms and gaps where
|
|
19
19
|
// its source does, so it floors and pays nothing for it on the tiling. Both
|
|
20
|
-
// halves measured — `agent-docs/reference/
|
|
20
|
+
// halves measured — `agent-docs/reference/MAF_LARGE_BLOCKS.md`.
|
|
21
21
|
//! export-consts: MIN_DRAWN_ROW_PX, MULTI_ROW_MIN_CELL_PX
|
|
22
22
|
//! js-export: drawnRowHeightPx, rowBandOffsetPx
|
|
23
23
|
module rowRect;
|
|
@@ -68,7 +68,7 @@ public struct RowRectVsOut {
|
|
|
68
68
|
// There is no X-axis twin. A row is a container the reader is counting, so
|
|
69
69
|
// losing one loses a species; a cell is a sample of a tiling, so losing one to
|
|
70
70
|
// the blend is the honest answer and flooring it invents ink
|
|
71
|
-
// (`agent-docs/reference/
|
|
71
|
+
// (`agent-docs/reference/MAF_LARGE_BLOCKS.md`). The caller that does want an X
|
|
72
72
|
// floor names its own width, below.
|
|
73
73
|
static const float MIN_DRAWN_ROW_PX = 1.0;
|
|
74
74
|
|