@jbrowse/render-core 5.0.0-beta.2 → 5.0.0-beta.4

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.
Files changed (114) hide show
  1. package/esm/RenderLifecycleMixin.d.ts +20 -1
  2. package/esm/RenderLifecycleMixin.js +25 -2
  3. package/esm/canvas2dUtils.d.ts +25 -0
  4. package/esm/canvas2dUtils.js +27 -0
  5. package/esm/colorRampLut.d.ts +4 -4
  6. package/esm/colorRampLut.js +4 -4
  7. package/esm/computePipeline.d.ts +13 -0
  8. package/esm/computePipeline.js +55 -0
  9. package/esm/coverageBand.d.ts +0 -1
  10. package/esm/coverageBand.js +0 -1
  11. package/esm/coverageBandBuffers.d.ts +0 -6
  12. package/esm/coverageBandBuffers.js +1 -13
  13. package/esm/createRenderingBackend.d.ts +14 -18
  14. package/esm/createRenderingBackend.js +4 -2
  15. package/esm/encodeMemo.d.ts +14 -0
  16. package/esm/encodeMemo.js +48 -0
  17. package/esm/gpuDevice.d.ts +9 -0
  18. package/esm/gpuDevice.js +12 -3
  19. package/esm/graphicsCapabilities.d.ts +18 -15
  20. package/esm/graphicsCapabilities.js +23 -16
  21. package/esm/hal/createHal.d.ts +1 -2
  22. package/esm/hal/createHal.js +14 -4
  23. package/esm/hal/deviceGpuCache.js +2 -2
  24. package/esm/hal/gpuHalBase.d.ts +1 -1
  25. package/esm/hal/gpuHalBase.js +2 -3
  26. package/esm/hal/mockHal.d.ts +0 -1
  27. package/esm/hal/mockHal.js +0 -10
  28. package/esm/hal/regionRegistry.d.ts +0 -1
  29. package/esm/hal/regionRegistry.js +3 -15
  30. package/esm/hal/types.d.ts +5 -1
  31. package/esm/hal/webgl2Hal.d.ts +1 -1
  32. package/esm/hal/webgl2Hal.js +2 -2
  33. package/esm/hal/webgpuHal.d.ts +2 -2
  34. package/esm/hal/webgpuHal.js +19 -16
  35. package/esm/installUpload.d.ts +4 -1
  36. package/esm/installUpload.js +7 -39
  37. package/esm/instanceCache.d.ts +10 -7
  38. package/esm/instanceCache.js +14 -15
  39. package/esm/mapUploadSync.d.ts +0 -8
  40. package/esm/mapUploadSync.js +0 -1
  41. package/esm/marks/colorFill.d.ts +17 -0
  42. package/esm/marks/colorFill.js +26 -0
  43. package/esm/marks/drawAgainstHit.d.ts +47 -0
  44. package/esm/marks/drawAgainstHit.js +140 -0
  45. package/esm/marks/glyphPaint.d.ts +16 -0
  46. package/esm/marks/glyphPaint.js +41 -0
  47. package/esm/marks/index.d.ts +9 -0
  48. package/esm/marks/index.js +6 -0
  49. package/esm/marks/markBackend.d.ts +87 -0
  50. package/esm/marks/markBackend.js +137 -0
  51. package/esm/marks/markHit.d.ts +25 -0
  52. package/esm/marks/markHit.js +46 -0
  53. package/esm/marks/markPaint.d.ts +13 -0
  54. package/esm/marks/markPaint.js +18 -0
  55. package/esm/marks/pointMark.d.ts +24 -0
  56. package/esm/marks/pointMark.js +91 -0
  57. package/esm/marks/spanMark.d.ts +45 -0
  58. package/esm/marks/spanMark.js +59 -0
  59. package/esm/marks/types.d.ts +216 -0
  60. package/esm/marks/types.js +146 -0
  61. package/esm/perRegionRenderingBackend.d.ts +15 -3
  62. package/esm/perRegionRenderingBackend.js +26 -3
  63. package/esm/regionDataMap.d.ts +2 -2
  64. package/esm/regionDataMap.js +2 -2
  65. package/esm/renderBlock.d.ts +14 -0
  66. package/esm/renderBlock.js +25 -0
  67. package/esm/renderingBackendBase.d.ts +11 -14
  68. package/esm/renderingBackendBase.js +7 -7
  69. package/esm/shaders/capsule.js.generated.d.ts +1 -0
  70. package/esm/shaders/capsule.js.generated.js +11 -0
  71. package/esm/shaders/coverageBar.generated.d.ts +2 -2
  72. package/esm/shaders/coverageBar.generated.js +2 -2
  73. package/esm/shaders/coverageMod.generated.d.ts +2 -2
  74. package/esm/shaders/coverageMod.generated.js +2 -2
  75. package/esm/shaders/coverageSnp.generated.d.ts +2 -2
  76. package/esm/shaders/coverageSnp.generated.js +2 -2
  77. package/esm/shaders/pointMark.consts.generated.d.ts +4 -0
  78. package/esm/shaders/pointMark.consts.generated.js +6 -0
  79. package/esm/shaders/pointMark.generated.d.ts +5 -0
  80. package/esm/shaders/pointMark.generated.js +7 -0
  81. package/esm/shaders/pointMark.iface.generated.d.ts +55 -0
  82. package/esm/shaders/pointMark.iface.generated.js +100 -0
  83. package/esm/shaders/pointMark.js.generated.d.ts +2 -0
  84. package/esm/shaders/pointMark.js.generated.js +19 -0
  85. package/esm/shaders/spanMark.generated.d.ts +4 -0
  86. package/esm/shaders/spanMark.generated.js +6 -0
  87. package/esm/shaders/spanMark.iface.generated.d.ts +58 -0
  88. package/esm/shaders/spanMark.iface.generated.js +122 -0
  89. package/esm/sharedBackendKey.d.ts +18 -0
  90. package/esm/{keyedRenderingBackend.js → sharedBackendKey.js} +5 -0
  91. package/esm/slangPass.d.ts +2 -0
  92. package/esm/slangPass.js +2 -0
  93. package/package.json +14 -4
  94. package/src/shaders/capsule.js.generated.ts +14 -0
  95. package/src/shaders/capsule.slang +12 -4
  96. package/src/shaders/colorPack.slang +5 -1
  97. package/src/shaders/coverageBand.slang +38 -15
  98. package/src/shaders/coverageBar.generated.ts +2 -2
  99. package/src/shaders/coverageBar.slang +9 -0
  100. package/src/shaders/coverageMod.generated.ts +2 -2
  101. package/src/shaders/coverageSnp.generated.ts +2 -2
  102. package/src/shaders/hpmath.slang +7 -1
  103. package/src/shaders/pointMark.consts.generated.ts +10 -0
  104. package/src/shaders/pointMark.generated.ts +12 -0
  105. package/src/shaders/pointMark.iface.generated.ts +146 -0
  106. package/src/shaders/pointMark.js.generated.ts +25 -0
  107. package/src/shaders/pointMark.slang +205 -0
  108. package/src/shaders/rowRect.slang +7 -8
  109. package/src/shaders/spanMark.generated.ts +10 -0
  110. package/src/shaders/spanMark.iface.generated.ts +168 -0
  111. package/src/shaders/spanMark.slang +22 -0
  112. package/esm/globalRenderingBackend.d.ts +0 -90
  113. package/esm/globalRenderingBackend.js +0 -53
  114. package/esm/keyedRenderingBackend.d.ts +0 -41
@@ -0,0 +1,168 @@
1
+ // AUTO-GENERATED by packages/shader-tools/src/shader-codegen from spanMark.slang.
2
+ // Do not edit. Run `pnpm gen:shaders` to regenerate.
3
+
4
+ import type { VertexAttributeLayout, ShaderBinding } from '@jbrowse/render-core/hal'
5
+
6
+ export const BINDINGS: readonly ShaderBinding[] = [
7
+ { index: 1, kind: 'uniform', name: 'u' },
8
+ ]
9
+
10
+ export const VERTS_PER_INSTANCE = 6
11
+
12
+ export const UNIFORMS_SIZE_BYTES = 48
13
+
14
+ // Word indices into a Float32Array view over the uniform buffer.
15
+ export const UNIFORM_OFFSET_F32 = {
16
+ bpRangeX: 0,
17
+ canvasHeight: 3,
18
+ minCellDenomPx: 4,
19
+ minCellPx: 5,
20
+ zero: 6,
21
+ rowHeight: 7,
22
+ rowProportion: 8,
23
+ scrollTop: 9,
24
+ } as const
25
+
26
+
27
+ export interface Uniforms {
28
+ bpRangeX: [number, number, number]
29
+ canvasHeight: number
30
+ minCellDenomPx: number
31
+ minCellPx: number
32
+ zero: number
33
+ rowHeight: number
34
+ rowProportion: number
35
+ scrollTop: number
36
+ }
37
+
38
+ export function writeUniforms(buf: ArrayBuffer, uniforms: Uniforms) {
39
+ const f32 = new Float32Array(buf)
40
+ f32[0] = uniforms.bpRangeX[0]
41
+ f32[1] = uniforms.bpRangeX[1]
42
+ f32[2] = uniforms.bpRangeX[2]
43
+ f32[3] = uniforms.canvasHeight
44
+ f32[4] = uniforms.minCellDenomPx
45
+ f32[5] = uniforms.minCellPx
46
+ f32[6] = uniforms.zero
47
+ f32[7] = uniforms.rowHeight
48
+ f32[8] = uniforms.rowProportion
49
+ f32[9] = uniforms.scrollTop
50
+ }
51
+
52
+ export const INSTANCE_STRIDE_BYTES = 16
53
+ export const INSTANCE_STRIDE_WORDS = 4
54
+
55
+ // Word indices into a Uint32Array view over the instance buffer.
56
+ export const INSTANCE_OFFSET_U32 = {
57
+ x: 0,
58
+ x2: 1,
59
+ row: 2,
60
+ color: 3,
61
+ } as const
62
+
63
+ export const VERTEX_ATTRIBUTES: readonly VertexAttributeLayout[] = [
64
+ { name: 'a_x', components: 1, type: 'uint', offsetBytes: 0, integer: true },
65
+ { name: 'a_x2', components: 1, type: 'uint', offsetBytes: 4, integer: true },
66
+ { name: 'a_row', components: 1, type: 'uint', offsetBytes: 8, integer: true },
67
+ { name: 'a_color', components: 1, type: 'uint', offsetBytes: 12, integer: true },
68
+ ]
69
+
70
+ export interface InstanceArrays {
71
+ x: ArrayLike<number>
72
+ x2: ArrayLike<number>
73
+ row: ArrayLike<number>
74
+ color: ArrayLike<number>
75
+ }
76
+
77
+ export function packInstances(
78
+ arrays: InstanceArrays,
79
+ numInstances: number,
80
+ buf: ArrayBuffer = new ArrayBuffer(numInstances * INSTANCE_STRIDE_BYTES),
81
+ ) {
82
+ const u32 = new Uint32Array(buf)
83
+ const { x, x2, row, color } = arrays
84
+ for (let i = 0; i < numInstances; i++) {
85
+ const o = i * INSTANCE_STRIDE_WORDS
86
+ u32[o + 0] = x[i]!
87
+ u32[o + 1] = x2[i]!
88
+ u32[o + 2] = row[i]!
89
+ u32[o + 3] = color[i]!
90
+ }
91
+ return buf
92
+ }
93
+
94
+ // Instance `i`'s `x`.
95
+ export function getInstanceX(u32: Uint32Array, i: number) {
96
+ return u32[i * INSTANCE_STRIDE_WORDS]!
97
+ }
98
+
99
+ export function setInstanceX(u32: Uint32Array, i: number, v: number) {
100
+ u32[i * INSTANCE_STRIDE_WORDS] = v
101
+ }
102
+
103
+ // Instance `i`'s `x2`.
104
+ export function getInstanceX2(u32: Uint32Array, i: number) {
105
+ return u32[i * INSTANCE_STRIDE_WORDS + 1]!
106
+ }
107
+
108
+ export function setInstanceX2(u32: Uint32Array, i: number, v: number) {
109
+ u32[i * INSTANCE_STRIDE_WORDS + 1] = v
110
+ }
111
+
112
+ // Instance `i`'s `row`.
113
+ export function getInstanceRow(u32: Uint32Array, i: number) {
114
+ return u32[i * INSTANCE_STRIDE_WORDS + 2]!
115
+ }
116
+
117
+ export function setInstanceRow(u32: Uint32Array, i: number, v: number) {
118
+ u32[i * INSTANCE_STRIDE_WORDS + 2] = v
119
+ }
120
+
121
+ // Instance `i`'s `color`.
122
+ export function getInstanceColor(u32: Uint32Array, i: number) {
123
+ return u32[i * INSTANCE_STRIDE_WORDS + 3]!
124
+ }
125
+
126
+ export function setInstanceColor(u32: Uint32Array, i: number, v: number) {
127
+ u32[i * INSTANCE_STRIDE_WORDS + 3] = v
128
+ }
129
+
130
+ // Appends instances one at a time, for an encoder that cannot say up front
131
+ // how many it will emit. Seed the constructor with an upper bound and the
132
+ // common path allocates exactly once; the doubling is a correctness
133
+ // backstop, not the expected route.
134
+ export class InstanceWriter {
135
+ private buf: ArrayBuffer
136
+ private u32: Uint32Array
137
+ private capacity: number
138
+ count = 0
139
+
140
+ constructor(capacity: number) {
141
+ this.capacity = Math.max(1, capacity)
142
+ this.buf = new ArrayBuffer(this.capacity * INSTANCE_STRIDE_BYTES)
143
+ this.u32 = new Uint32Array(this.buf)
144
+ }
145
+
146
+ push(x: number, x2: number, row: number, color: number) {
147
+ if (this.count === this.capacity) {
148
+ this.capacity *= 2
149
+ const grown = new ArrayBuffer(this.capacity * INSTANCE_STRIDE_BYTES)
150
+ new Uint8Array(grown).set(new Uint8Array(this.buf))
151
+ this.buf = grown
152
+ this.u32 = new Uint32Array(grown)
153
+ }
154
+ const o = this.count * INSTANCE_STRIDE_WORDS
155
+ this.u32[o] = x
156
+ this.u32[o + 1] = x2
157
+ this.u32[o + 2] = row
158
+ this.u32[o + 3] = color
159
+ this.count++
160
+ }
161
+
162
+ // A right-sized COPY, not a subarray view — see the class comment. Skipped
163
+ // entirely when the seed turned out to be exact, which is the common path.
164
+ finish() {
165
+ const used = this.count * INSTANCE_STRIDE_BYTES
166
+ return used === this.buf.byteLength ? this.buf : this.buf.slice(0, used)
167
+ }
168
+ }
@@ -0,0 +1,22 @@
1
+ // The `span` mark shape: one instance is a coloured rectangle spanning
2
+ // [x, x2) in absolute genomic coords, on the row band given by the `row`
3
+ // channel. The geometry — row band, hp clip-x span, min-width widening — is
4
+ // `rowRect`'s; this is the entry point that makes it a pass a mark can draw.
5
+ //! targets: wgsl, glsl
6
+ //! instance-writer
7
+
8
+ import rowRect;
9
+
10
+ public static const uint VERTS_PER_INSTANCE = 6u;
11
+
12
+ [[vk::binding(1, 0)]] ConstantBuffer<RowRectUniforms> u;
13
+
14
+ [shader("vertex")]
15
+ RowRectVsOut vs_main(RowRectInstance inst, uint vid : SV_VertexID) {
16
+ return rowRectVertex(inst, vid, u);
17
+ }
18
+
19
+ [shader("fragment")]
20
+ float4 fs_main(RowRectVsOut v) : SV_Target {
21
+ return v.color;
22
+ }
@@ -1,90 +0,0 @@
1
- import { Canvas2DRenderingBackendBase, GpuRenderingBackendBase } from './renderingBackendBase.ts';
2
- import type { FrameDimensions, RenderingBackend } from './renderingBackendBase.ts';
3
- /**
4
- * Shared contract for monolithic GPU backends (HiC, LD, multi-variant
5
- * matrix) — displays with no region partitioning. One payload under the
6
- * `data` key, one draw per frame. Render receives the data directly so
7
- * Canvas2D backends stay stateless; GPU backends use `upload` to push bytes
8
- * into a HAL buffer and ignore the `data` arg at render time.
9
- *
10
- * A display with a second upload beside the payload — HiC's and LD's colour
11
- * ramp texture, derived from a setting rather than the fetch — widens `Key`
12
- * and `Cell` so `upload` takes both cells and tells them apart, while `render`
13
- * is still handed the payload alone.
14
- */
15
- export interface GlobalRenderingBackend<UploadData, RenderState, Key extends string = 'data', Cell = UploadData> extends RenderingBackend {
16
- upload(key: Key, data: Cell): void;
17
- release(key: Key): void;
18
- /**
19
- * Paint one frame and report whether real content reached the canvas — the
20
- * monolithic twin of `PerRegionRenderingBackend.renderBlocks`, and it answers
21
- * for the same reason. `RenderLifecycleMixin` flips `canvasDrawn` (the loading
22
- * scrim, `data-display-drawn`, every browser test's wait) only on `true`, so a
23
- * tick that drew nothing must say so.
24
- *
25
- * **This used to return `void`, and the answer was the display's to give.**
26
- * Each of the three wrote the same six lines — "data is here, so return
27
- * `true`" — beside a renderer whose own guard was strictly narrower: a color
28
- * ramp that had not arrived, a zero instance count, an empty HAL buffer. Two
29
- * expressions of one fact, and the one that could see what actually happened
30
- * was not the one being asked. LD's model even carried a comment explaining
31
- * the workaround, which is the usual sign that a signature is wrong rather
32
- * than a caller.
33
- */
34
- render(data: UploadData | null, state: RenderState): boolean;
35
- }
36
- /**
37
- * Canvas2D-side base for `GlobalRenderingBackend` implementations. Inherits the
38
- * `canvas` + 2D context (and no-op `dispose`) from
39
- * `Canvas2DRenderingBackendBase`; stubs `upload` (no-op — data flows through
40
- * `render`).
41
- *
42
- * `render` is concrete and runs `prepareCanvas` (DPR-aware backing-store sizing)
43
- * before handing off to the abstract `draw`, exactly as
44
- * `Canvas2DPerRegionRenderingBackend` does — so a renderer here can no more
45
- * forget it and paint blurry on hi-DPI than one over there can. All three
46
- * subclasses opened with that same call and none of them had to.
47
- *
48
- * A null payload still prepares (and so clears) the canvas, then skips the
49
- * draw: that is the frame where a refetch is in flight and the old picture must
50
- * not stay up.
51
- */
52
- export declare abstract class Canvas2DGlobalRenderingBackend<UploadData, RenderState extends FrameDimensions, Key extends string = 'data', Cell = UploadData> extends Canvas2DRenderingBackendBase implements GlobalRenderingBackend<UploadData, RenderState, Key, Cell> {
53
- upload(_key: Key, _cell: Cell): void;
54
- release(_key: Key): void;
55
- render(data: UploadData | null, state: RenderState): boolean;
56
- /**
57
- * Paint `data` into `this.ctx` (already DPR-prepared) and answer whether
58
- * anything reached it. Delegates to the plugin's pure `drawXxxBlocks`
59
- * function, the one SVG export shares.
60
- */
61
- protected abstract draw(data: UploadData, state: RenderState): boolean;
62
- }
63
- /**
64
- * GPU-side base for `GlobalRenderingBackend` implementations. Inherits the
65
- * `hal` reference, the pre-allocated uniform scratch buffer, and the
66
- * HAL-delegating `dispose` from `GpuRenderingBackendBase`. Subclasses implement
67
- * `upload` and `draw`.
68
- *
69
- * `render` is the frame scaffold the per-region base has always had and this
70
- * one did not: resize the backing store, `beginFrame`/`endFrame`, and hand the
71
- * middle to `draw`. **The pairing is the point.** `beginFrame` is what clears
72
- * the canvas, so a frame that draws nothing still has to open and close one or
73
- * the last picture stays up — and with each subclass writing its own scaffold,
74
- * that invariant held three times by hand.
75
- *
76
- * `release` is a no-op by default: a payload leaving the map is answered by
77
- * `render` being handed `null`, and `beginFrame` clears the last picture. A
78
- * subclass whose buffers are worth freeing early overrides it.
79
- */
80
- export declare abstract class GpuGlobalRenderingBackend<UploadData, RenderState extends FrameDimensions, Key extends string = 'data', Cell = UploadData> extends GpuRenderingBackendBase implements GlobalRenderingBackend<UploadData, RenderState, Key, Cell> {
81
- abstract upload(key: Key, data: Cell): void;
82
- release(): void;
83
- render(data: UploadData | null, state: RenderState): boolean;
84
- /**
85
- * Write uniforms and issue the draw passes for one frame, inside an already-
86
- * open `beginFrame`/`endFrame`. Return whether anything was drawn — a buffer
87
- * the upload has not filled yet is the ordinary reason not to.
88
- */
89
- protected abstract draw(data: UploadData, state: RenderState): boolean;
90
- }
@@ -1,53 +0,0 @@
1
- import { prepareCanvas } from './canvas2dUtils.js';
2
- import { Canvas2DRenderingBackendBase, GpuRenderingBackendBase, } from './renderingBackendBase.js';
3
- /**
4
- * Canvas2D-side base for `GlobalRenderingBackend` implementations. Inherits the
5
- * `canvas` + 2D context (and no-op `dispose`) from
6
- * `Canvas2DRenderingBackendBase`; stubs `upload` (no-op — data flows through
7
- * `render`).
8
- *
9
- * `render` is concrete and runs `prepareCanvas` (DPR-aware backing-store sizing)
10
- * before handing off to the abstract `draw`, exactly as
11
- * `Canvas2DPerRegionRenderingBackend` does — so a renderer here can no more
12
- * forget it and paint blurry on hi-DPI than one over there can. All three
13
- * subclasses opened with that same call and none of them had to.
14
- *
15
- * A null payload still prepares (and so clears) the canvas, then skips the
16
- * draw: that is the frame where a refetch is in flight and the old picture must
17
- * not stay up.
18
- */
19
- export class Canvas2DGlobalRenderingBackend extends Canvas2DRenderingBackendBase {
20
- upload(_key, _cell) { }
21
- release(_key) { }
22
- render(data, state) {
23
- prepareCanvas(this.canvas, this.ctx, state.canvasWidth, state.canvasHeight);
24
- return data !== null && this.draw(data, state);
25
- }
26
- }
27
- /**
28
- * GPU-side base for `GlobalRenderingBackend` implementations. Inherits the
29
- * `hal` reference, the pre-allocated uniform scratch buffer, and the
30
- * HAL-delegating `dispose` from `GpuRenderingBackendBase`. Subclasses implement
31
- * `upload` and `draw`.
32
- *
33
- * `render` is the frame scaffold the per-region base has always had and this
34
- * one did not: resize the backing store, `beginFrame`/`endFrame`, and hand the
35
- * middle to `draw`. **The pairing is the point.** `beginFrame` is what clears
36
- * the canvas, so a frame that draws nothing still has to open and close one or
37
- * the last picture stays up — and with each subclass writing its own scaffold,
38
- * that invariant held three times by hand.
39
- *
40
- * `release` is a no-op by default: a payload leaving the map is answered by
41
- * `render` being handed `null`, and `beginFrame` clears the last picture. A
42
- * subclass whose buffers are worth freeing early overrides it.
43
- */
44
- export class GpuGlobalRenderingBackend extends GpuRenderingBackendBase {
45
- release() { }
46
- render(data, state) {
47
- this.hal.resize(state.canvasWidth, state.canvasHeight);
48
- this.hal.beginFrame(0, 0, 0, 0);
49
- const painted = data !== null && this.draw(data, state);
50
- this.hal.endFrame();
51
- return painted;
52
- }
53
- }
@@ -1,41 +0,0 @@
1
- import type { RenderingBackend } from './renderingBackendBase.ts';
2
- /**
3
- * Shared contract for **keyed shared-canvas** backends — one canvas painting
4
- * several displays at once, each holding its own uploaded buffer under its own
5
- * key. Dotplot (a key per display in the view) and multi-LGV synteny (a key per
6
- * track level) are the two.
7
- *
8
- * The third shape beside per-region and monolithic, and genuinely neither:
9
- * per-region drives off `renderBlocks(blocks, regions, state)` with the model's
10
- * data map handed back each frame, and monolithic is one payload under the `data` key
11
- * with no key at all. These key their uploads and render every key in one
12
- * frame from state the caller assembled, so they own the map.
13
- *
14
- * Unlike the other two this is an interface with no abstract class under it:
15
- * the shared *state* (`hal` + uniform scratch, or `canvas` + 2D context) is
16
- * `GpuRenderingBackendBase` / `Canvas2DRenderingBackendBase`, which every keyed
17
- * backend extends, and there is no shared *behavior* on top — the render loops
18
- * genuinely differ. An empty abstract class between them would only be a place
19
- * to look.
20
- */
21
- export interface KeyedRenderingBackend<UploadData, RenderState> extends RenderingBackend {
22
- /** CSS-pixel size of the shared canvas. */
23
- resize(width: number, height: number): void;
24
- upload(key: number, data: UploadData): void;
25
- release(key: number): void;
26
- /** Paint every key the state names. */
27
- render(state: RenderState): void;
28
- }
29
- /**
30
- * Stable 32-bit slot for a display on a backend it shares with siblings, hashed
31
- * from its MST node id (djb2). Collisions are vanishingly rare at display
32
- * cardinalities, and the alternative — coordinating integer slots between
33
- * displays that don't know about each other — is worse.
34
- *
35
- * Key by this, never by the display's index in its parent's list. An index
36
- * renumbers when a sibling is hidden or reordered, which hands the survivor a
37
- * slot holding another display's bytes: the keyed diff sees a changed
38
- * reference and re-uploads every later display's whole buffer, and any frame
39
- * drawn between the two mistakes one display's geometry for another's.
40
- */
41
- export declare function sharedBackendKey(id: string): number;