@genome-spy/core 0.20.0 → 0.21.0
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/dist/index.js +38 -38
- package/dist/schema.json +0 -3
- package/package.json +2 -2
- package/src/gl/dataToVertices.js +43 -46
- package/src/gl/includes/common.glsl +12 -12
- package/src/gl/includes/picking.fragment.glsl +0 -2
- package/src/gl/includes/picking.vertex.glsl +0 -2
- package/src/marks/link.js +32 -39
- package/src/marks/mark.js +167 -98
- package/src/marks/pointMark.js +28 -59
- package/src/marks/rectMark.js +38 -33
- package/src/marks/rule.js +31 -21
- package/src/marks/text.js +18 -14
- package/src/spec/mark.d.ts +0 -3
- package/src/utils/binnedIndex.js +147 -0
- package/src/utils/binnedIndex.test.js +73 -0
- package/src/view/axisView.js +0 -4
- package/src/view/renderingContext/deferredViewRenderingContext.js +3 -1
- package/src/view/renderingContext/simpleViewRenderingContext.js +3 -1
- package/src/utils/binnedRangeIndex.js +0 -83
package/src/marks/mark.js
CHANGED
|
@@ -4,10 +4,11 @@ import {
|
|
|
4
4
|
createUniformBlockInfo,
|
|
5
5
|
createVertexArrayInfo,
|
|
6
6
|
setAttribInfoBufferFromArray,
|
|
7
|
+
setBlockUniforms,
|
|
7
8
|
setUniformBlock,
|
|
8
9
|
setUniforms,
|
|
9
10
|
} from "twgl.js";
|
|
10
|
-
import { isDiscrete } from "vega-scale";
|
|
11
|
+
import { isContinuous, isDiscrete } from "vega-scale";
|
|
11
12
|
import createEncoders, {
|
|
12
13
|
isChannelDefWithScale,
|
|
13
14
|
isDatumDef,
|
|
@@ -32,6 +33,7 @@ import { getCachedOrCall } from "../utils/propertyCacher";
|
|
|
32
33
|
import { createProgram } from "../gl/webGLHelper";
|
|
33
34
|
import coalesceProperties from "../utils/propertyCoalescer";
|
|
34
35
|
import { isScalar } from "../utils/variableTools";
|
|
36
|
+
import { InternMap } from "internmap";
|
|
35
37
|
|
|
36
38
|
export const SAMPLE_FACET_UNIFORM = "SAMPLE_FACET_UNIFORM";
|
|
37
39
|
export const SAMPLE_FACET_TEXTURE = "SAMPLE_FACET_TEXTURE";
|
|
@@ -77,6 +79,12 @@ export default class Mark {
|
|
|
77
79
|
/** @type {import("twgl.js").UniformBlockInfo} WebGL buffers */
|
|
78
80
|
this.domainUniformInfo = undefined;
|
|
79
81
|
|
|
82
|
+
/** @type {import("twgl.js").UniformBlockInfo} WebGL buffers */
|
|
83
|
+
this.viewUniformInfo = undefined;
|
|
84
|
+
|
|
85
|
+
/** @type {RangeMap<any>} keep track of facet locations within the vertex array */
|
|
86
|
+
this.rangeMap = new RangeMap();
|
|
87
|
+
|
|
80
88
|
// TODO: Implement https://vega.github.io/vega-lite/docs/config.html
|
|
81
89
|
/** @type {MarkConfig} */
|
|
82
90
|
this.defaultProperties = {
|
|
@@ -399,9 +407,21 @@ export default class Mark {
|
|
|
399
407
|
);
|
|
400
408
|
}
|
|
401
409
|
|
|
410
|
+
this.viewUniformInfo = createUniformBlockInfo(
|
|
411
|
+
this.gl,
|
|
412
|
+
this.programInfo,
|
|
413
|
+
"View"
|
|
414
|
+
);
|
|
415
|
+
|
|
402
416
|
this.gl.useProgram(this.programInfo.program);
|
|
403
417
|
|
|
404
418
|
this._setDatums();
|
|
419
|
+
|
|
420
|
+
setUniforms(this.programInfo, {
|
|
421
|
+
// left pos, left height, right pos, right height
|
|
422
|
+
uSampleFacet: [0, 1, 0, 1],
|
|
423
|
+
uTransitionOffset: 0.0,
|
|
424
|
+
});
|
|
405
425
|
}
|
|
406
426
|
|
|
407
427
|
_setDatums() {
|
|
@@ -535,21 +555,27 @@ export default class Mark {
|
|
|
535
555
|
* and scales) and buffers.
|
|
536
556
|
*
|
|
537
557
|
* @param {import("../view/rendering").GlobalRenderingOptions} options
|
|
558
|
+
* @returns {(() => void)[]}
|
|
538
559
|
*/
|
|
539
560
|
// eslint-disable-next-line complexity
|
|
540
561
|
prepareRender(options) {
|
|
541
562
|
const glHelper = this.glHelper;
|
|
542
563
|
const gl = this.gl;
|
|
543
564
|
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
this.gl,
|
|
547
|
-
this.programInfo,
|
|
548
|
-
this.bufferInfo
|
|
549
|
-
);
|
|
550
|
-
}
|
|
565
|
+
/** @type {(() => void)[]} */
|
|
566
|
+
const ops = [];
|
|
551
567
|
|
|
552
|
-
|
|
568
|
+
ops.push(() => {
|
|
569
|
+
if (!this.vertexArrayInfo) {
|
|
570
|
+
this.vertexArrayInfo = createVertexArrayInfo(
|
|
571
|
+
this.gl,
|
|
572
|
+
this.programInfo,
|
|
573
|
+
this.bufferInfo
|
|
574
|
+
);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
gl.useProgram(this.programInfo.program);
|
|
578
|
+
});
|
|
553
579
|
|
|
554
580
|
if (this.domainUniformInfo) {
|
|
555
581
|
// TODO: Only update the domains that have changed
|
|
@@ -572,19 +598,24 @@ export default class Mark {
|
|
|
572
598
|
|
|
573
599
|
if (resolution) {
|
|
574
600
|
const scale = resolution.getScale();
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
601
|
+
|
|
602
|
+
ops.push(() => {
|
|
603
|
+
const domain = isDiscrete(scale.type)
|
|
604
|
+
? [0, scale.domain().length]
|
|
605
|
+
: scale.domain();
|
|
606
|
+
|
|
607
|
+
setter(
|
|
608
|
+
isHighPrecisionScale(scale.type)
|
|
609
|
+
? toHighPrecisionDomainUniform(domain)
|
|
610
|
+
: domain
|
|
611
|
+
);
|
|
612
|
+
});
|
|
584
613
|
}
|
|
585
614
|
}
|
|
586
615
|
|
|
587
|
-
|
|
616
|
+
ops.push(() =>
|
|
617
|
+
setUniformBlock(gl, this.programInfo, this.domainUniformInfo)
|
|
618
|
+
);
|
|
588
619
|
}
|
|
589
620
|
|
|
590
621
|
for (const [channel, channelDef] of Object.entries(this.encoding)) {
|
|
@@ -599,52 +630,56 @@ export default class Mark {
|
|
|
599
630
|
|
|
600
631
|
const texture = glHelper.rangeTextures.get(resolution);
|
|
601
632
|
if (texture) {
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
633
|
+
ops.push(() =>
|
|
634
|
+
setUniforms(this.programInfo, {
|
|
635
|
+
[RANGE_TEXTURE_PREFIX + channel]: texture,
|
|
636
|
+
})
|
|
637
|
+
);
|
|
605
638
|
}
|
|
606
639
|
}
|
|
607
640
|
}
|
|
608
641
|
|
|
609
642
|
if (this.getSampleFacetMode() == SAMPLE_FACET_TEXTURE) {
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
643
|
+
ops.push(() => {
|
|
644
|
+
/** @type {WebGLTexture} */
|
|
645
|
+
let facetTexture;
|
|
646
|
+
for (const view of this.unitView.getAncestors()) {
|
|
647
|
+
facetTexture = view.getSampleFacetTexture();
|
|
648
|
+
if (facetTexture) {
|
|
649
|
+
break;
|
|
650
|
+
}
|
|
616
651
|
}
|
|
617
|
-
}
|
|
618
652
|
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
653
|
+
if (!facetTexture) {
|
|
654
|
+
throw new Error("No facet texture available. This is bug.");
|
|
655
|
+
}
|
|
622
656
|
|
|
623
|
-
|
|
624
|
-
|
|
657
|
+
setUniforms(this.programInfo, {
|
|
658
|
+
uSampleFacetTexture: facetTexture,
|
|
659
|
+
});
|
|
625
660
|
});
|
|
626
661
|
}
|
|
627
662
|
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
uTransitionOffset: 0.0,
|
|
641
|
-
});
|
|
663
|
+
// TODO: Rendering of the mark should be completely skipped if it doesn't
|
|
664
|
+
// participate picking
|
|
665
|
+
const picking =
|
|
666
|
+
(options.picking ?? false) && this.isPickingParticipant();
|
|
667
|
+
|
|
668
|
+
// Note: the block is sent to GPU in setViewport(), which is repeated for each facet
|
|
669
|
+
ops.push(() =>
|
|
670
|
+
setBlockUniforms(this.viewUniformInfo, {
|
|
671
|
+
uViewOpacity: this.unitView.getEffectiveOpacity(),
|
|
672
|
+
uPickingEnabled: picking,
|
|
673
|
+
})
|
|
674
|
+
);
|
|
642
675
|
|
|
643
676
|
if (this.opaque || options.picking) {
|
|
644
|
-
gl.disable(gl.BLEND);
|
|
677
|
+
ops.push(() => gl.disable(gl.BLEND));
|
|
645
678
|
} else {
|
|
646
|
-
gl.enable(gl.BLEND);
|
|
679
|
+
ops.push(() => gl.enable(gl.BLEND));
|
|
647
680
|
}
|
|
681
|
+
|
|
682
|
+
return ops;
|
|
648
683
|
}
|
|
649
684
|
|
|
650
685
|
/**
|
|
@@ -706,58 +741,56 @@ export default class Mark {
|
|
|
706
741
|
/**
|
|
707
742
|
* @param {DrawFunction} draw A function that draws a range of vertices
|
|
708
743
|
* @param {import("./Mark").MarkRenderingOptions} options
|
|
709
|
-
* @param {function():Map<string, import("../gl/dataToVertices").RangeEntry>} rangeMapSource
|
|
710
744
|
*/
|
|
711
|
-
createRenderCallback(draw, options
|
|
745
|
+
createRenderCallback(draw, options) {
|
|
712
746
|
// eslint-disable-next-line consistent-this
|
|
713
747
|
const self = this;
|
|
714
748
|
|
|
715
749
|
/** @type {function(import("../gl/dataToVertices").RangeEntry):void} rangeEntry */
|
|
716
750
|
let drawWithRangeEntry;
|
|
717
751
|
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
752
|
+
const scale = this.unitView.getScaleResolution("x")?.getScale();
|
|
753
|
+
const continuous = scale && isContinuous(scale.type);
|
|
754
|
+
const domainStartOffset = ["index", "locus"].includes(scale?.type)
|
|
755
|
+
? -1
|
|
756
|
+
: 0;
|
|
757
|
+
|
|
758
|
+
/** @type {[number, number]} Recycle to ease garbage collector's work */
|
|
759
|
+
const arr = [0, 0];
|
|
760
|
+
|
|
761
|
+
drawWithRangeEntry = (rangeEntry) => {
|
|
762
|
+
if (continuous && rangeEntry.xIndex) {
|
|
763
|
+
const domain = scale.domain();
|
|
764
|
+
const vertexIndices = rangeEntry.xIndex(
|
|
765
|
+
domain[0] + domainStartOffset,
|
|
766
|
+
domain[1],
|
|
767
|
+
arr
|
|
768
|
+
);
|
|
769
|
+
const offset = vertexIndices[0];
|
|
770
|
+
const count = vertexIndices[1] - offset;
|
|
771
|
+
if (count > 0) {
|
|
772
|
+
draw(offset, count);
|
|
735
773
|
}
|
|
736
|
-
}
|
|
737
|
-
} else {
|
|
738
|
-
drawWithRangeEntry = (rangeEntry) =>
|
|
774
|
+
} else {
|
|
739
775
|
draw(rangeEntry.offset, rangeEntry.count);
|
|
740
|
-
}
|
|
741
|
-
|
|
742
|
-
if (this.properties.dynamicData) {
|
|
743
|
-
return function renderDynamic() {
|
|
744
|
-
const rangeEntry = rangeMapSource().get(options.facetId);
|
|
745
|
-
if (rangeEntry && rangeEntry.count) {
|
|
746
|
-
if (self.prepareSampleFacetRendering(options)) {
|
|
747
|
-
drawWithRangeEntry(rangeEntry);
|
|
748
|
-
}
|
|
749
|
-
}
|
|
750
|
-
};
|
|
751
|
-
} else {
|
|
752
|
-
const rangeEntry = rangeMapSource()?.get(options.facetId);
|
|
753
|
-
if (rangeEntry && rangeEntry.count) {
|
|
754
|
-
return function renderStatic() {
|
|
755
|
-
if (self.prepareSampleFacetRendering(options)) {
|
|
756
|
-
drawWithRangeEntry(rangeEntry);
|
|
757
|
-
}
|
|
758
|
-
};
|
|
759
776
|
}
|
|
760
|
-
}
|
|
777
|
+
};
|
|
778
|
+
|
|
779
|
+
const rangeEntry = this.rangeMap.get(options.facetId);
|
|
780
|
+
|
|
781
|
+
return options.sampleFacetRenderingOptions
|
|
782
|
+
? function renderSampleFacetRange() {
|
|
783
|
+
if (rangeEntry.count) {
|
|
784
|
+
if (self.prepareSampleFacetRendering(options)) {
|
|
785
|
+
drawWithRangeEntry(rangeEntry);
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
: function renderRange() {
|
|
790
|
+
if (rangeEntry.count) {
|
|
791
|
+
drawWithRangeEntry(rangeEntry);
|
|
792
|
+
}
|
|
793
|
+
};
|
|
761
794
|
}
|
|
762
795
|
|
|
763
796
|
/**
|
|
@@ -839,7 +872,7 @@ export default class Mark {
|
|
|
839
872
|
uViewScale,
|
|
840
873
|
};
|
|
841
874
|
} else {
|
|
842
|
-
// Viewport comprises
|
|
875
|
+
// Viewport comprises the full canvas
|
|
843
876
|
gl.viewport(
|
|
844
877
|
0,
|
|
845
878
|
0,
|
|
@@ -862,15 +895,15 @@ export default class Mark {
|
|
|
862
895
|
};
|
|
863
896
|
}
|
|
864
897
|
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
setUniforms(this.programInfo, {
|
|
898
|
+
setBlockUniforms(this.viewUniformInfo, {
|
|
899
|
+
...uniforms,
|
|
869
900
|
uViewportSize: [coords.width, coords.height],
|
|
901
|
+
uDevicePixelRatio: this.glHelper.dpr,
|
|
870
902
|
});
|
|
871
903
|
|
|
872
|
-
|
|
904
|
+
setUniformBlock(this.gl, this.programInfo, this.viewUniformInfo);
|
|
873
905
|
|
|
906
|
+
// TODO: Optimize: don't set viewport and stuff if rect is outside clipRect or screen
|
|
874
907
|
return clippedCoords.height > 0 && clippedCoords.width > 0;
|
|
875
908
|
}
|
|
876
909
|
|
|
@@ -888,3 +921,39 @@ export default class Mark {
|
|
|
888
921
|
// override
|
|
889
922
|
}
|
|
890
923
|
}
|
|
924
|
+
|
|
925
|
+
/**
|
|
926
|
+
* @augments {InternMap<K, import("../gl/dataToVertices").RangeEntry>}
|
|
927
|
+
* @template K
|
|
928
|
+
*/
|
|
929
|
+
class RangeMap extends InternMap {
|
|
930
|
+
constructor() {
|
|
931
|
+
super([], JSON.stringify);
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
/**
|
|
935
|
+
* @param {K} key
|
|
936
|
+
*/
|
|
937
|
+
get(key) {
|
|
938
|
+
let value = super.get(key);
|
|
939
|
+
if (value === undefined) {
|
|
940
|
+
value = {
|
|
941
|
+
offset: 0,
|
|
942
|
+
count: 0,
|
|
943
|
+
xIndex: undefined,
|
|
944
|
+
};
|
|
945
|
+
super.set(key, value);
|
|
946
|
+
}
|
|
947
|
+
return value;
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
/**
|
|
951
|
+
*
|
|
952
|
+
* @param {Map<K, import("../gl/dataToVertices").RangeEntry>} anotherMap
|
|
953
|
+
*/
|
|
954
|
+
migrateEntries(anotherMap) {
|
|
955
|
+
for (const [key, value] of anotherMap.entries()) {
|
|
956
|
+
Object.assign(this.get(key), value);
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
}
|
package/src/marks/pointMark.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { drawBufferInfo, setBuffersAndAttributes, setUniforms } from "twgl.js";
|
|
2
|
-
import {
|
|
3
|
-
import { zoomLinear } from "vega-util";
|
|
2
|
+
import { quantileSorted } from "d3-array";
|
|
4
3
|
import { PointVertexBuilder } from "../gl/dataToVertices";
|
|
5
4
|
import VERTEX_SHADER from "../gl/point.vertex.glsl";
|
|
6
5
|
import FRAGMENT_SHADER from "../gl/point.fragment.glsl";
|
|
@@ -156,7 +155,7 @@ export default class PointMark extends Mark {
|
|
|
156
155
|
builder.addBatches(collector.facetBatches);
|
|
157
156
|
|
|
158
157
|
const vertexData = builder.toArrays();
|
|
159
|
-
this.rangeMap
|
|
158
|
+
this.rangeMap.migrateEntries(vertexData.rangeMap);
|
|
160
159
|
this.updateBufferInfo(vertexData);
|
|
161
160
|
}
|
|
162
161
|
|
|
@@ -210,44 +209,25 @@ export default class PointMark extends Mark {
|
|
|
210
209
|
* @param {import("../view/rendering").GlobalRenderingOptions} options
|
|
211
210
|
*/
|
|
212
211
|
prepareRender(options) {
|
|
213
|
-
super.prepareRender(options);
|
|
212
|
+
const ops = super.prepareRender(options);
|
|
214
213
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
214
|
+
ops.push(() =>
|
|
215
|
+
setUniforms(this.programInfo, {
|
|
216
|
+
uMaxPointSize: this._getMaxPointSize(),
|
|
217
|
+
uScaleFactor: this._getGeometricScaleFactor(),
|
|
218
|
+
uSemanticThreshold: this.getSemanticThreshold(),
|
|
219
|
+
})
|
|
220
|
+
);
|
|
220
221
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
222
|
+
ops.push(() =>
|
|
223
|
+
setBuffersAndAttributes(
|
|
224
|
+
this.gl,
|
|
225
|
+
this.programInfo,
|
|
226
|
+
this.vertexArrayInfo
|
|
227
|
+
)
|
|
225
228
|
);
|
|
226
229
|
|
|
227
|
-
|
|
228
|
-
const xEncoder = this.encoders.x;
|
|
229
|
-
if (xEncoder && !xEncoder.constant) {
|
|
230
|
-
const bisect = bisector(xEncoder.accessor).left;
|
|
231
|
-
const visibleDomain = this.unitView
|
|
232
|
-
.getScaleResolution("x")
|
|
233
|
-
.getScale()
|
|
234
|
-
.domain();
|
|
235
|
-
|
|
236
|
-
// A hack to include points that are just beyond the borders. TODO: Compute based on maxPointSize
|
|
237
|
-
const paddedDomain = zoomLinear(visibleDomain, null, 1.01);
|
|
238
|
-
|
|
239
|
-
/** @param {any[]} facetId */
|
|
240
|
-
this._findIndices = (facetId) => {
|
|
241
|
-
const data = this.unitView
|
|
242
|
-
.getCollector()
|
|
243
|
-
.facetBatches.get(facetId);
|
|
244
|
-
|
|
245
|
-
return [
|
|
246
|
-
bisect(data, paddedDomain[0]),
|
|
247
|
-
bisect(data, paddedDomain[paddedDomain.length - 1]),
|
|
248
|
-
];
|
|
249
|
-
};
|
|
250
|
-
}
|
|
230
|
+
return ops;
|
|
251
231
|
}
|
|
252
232
|
|
|
253
233
|
/**
|
|
@@ -256,27 +236,16 @@ export default class PointMark extends Mark {
|
|
|
256
236
|
render(options) {
|
|
257
237
|
const gl = this.gl;
|
|
258
238
|
|
|
259
|
-
return this.createRenderCallback(
|
|
260
|
-
(
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
gl,
|
|
271
|
-
this.vertexArrayInfo,
|
|
272
|
-
gl.POINTS,
|
|
273
|
-
length,
|
|
274
|
-
offset + lower
|
|
275
|
-
);
|
|
276
|
-
}
|
|
277
|
-
},
|
|
278
|
-
options,
|
|
279
|
-
() => this.rangeMap
|
|
280
|
-
);
|
|
239
|
+
return this.createRenderCallback((offset, count) => {
|
|
240
|
+
if (count) {
|
|
241
|
+
drawBufferInfo(
|
|
242
|
+
gl,
|
|
243
|
+
this.vertexArrayInfo,
|
|
244
|
+
gl.POINTS,
|
|
245
|
+
count,
|
|
246
|
+
offset
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
}, options);
|
|
281
250
|
}
|
|
282
251
|
}
|
package/src/marks/rectMark.js
CHANGED
|
@@ -146,6 +146,25 @@ export default class RectMark extends Mark {
|
|
|
146
146
|
);
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
+
finalizeGraphicsInitialization() {
|
|
150
|
+
super.finalizeGraphicsInitialization();
|
|
151
|
+
|
|
152
|
+
this.gl.useProgram(this.programInfo.program);
|
|
153
|
+
|
|
154
|
+
const props = this.properties;
|
|
155
|
+
|
|
156
|
+
setUniforms(this.programInfo, {
|
|
157
|
+
uMinSize: [props.minWidth, props.minHeight], // in pixels
|
|
158
|
+
uMinOpacity: props.minOpacity,
|
|
159
|
+
uCornerRadii: [
|
|
160
|
+
props.cornerRadiusTopRight ?? props.cornerRadius,
|
|
161
|
+
props.cornerRadiusBottomRight ?? props.cornerRadius,
|
|
162
|
+
props.cornerRadiusTopLeft ?? props.cornerRadius,
|
|
163
|
+
props.cornerRadiusBottomLeft ?? props.cornerRadius,
|
|
164
|
+
],
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
|
|
149
168
|
updateGraphicsData() {
|
|
150
169
|
const collector = this.unitView.getCollector();
|
|
151
170
|
const numItems = collector.getItemCount();
|
|
@@ -155,13 +174,12 @@ export default class RectMark extends Mark {
|
|
|
155
174
|
encoders: this.encoders,
|
|
156
175
|
attributes: this.getAttributes(),
|
|
157
176
|
numItems,
|
|
158
|
-
buildXIndex: this.properties.buildIndex,
|
|
159
177
|
});
|
|
160
178
|
|
|
161
179
|
builder.addBatches(collector.facetBatches);
|
|
162
180
|
|
|
163
181
|
const vertexData = builder.toArrays();
|
|
164
|
-
this.rangeMap
|
|
182
|
+
this.rangeMap.migrateEntries(vertexData.rangeMap);
|
|
165
183
|
this.updateBufferInfo(vertexData);
|
|
166
184
|
}
|
|
167
185
|
|
|
@@ -169,26 +187,17 @@ export default class RectMark extends Mark {
|
|
|
169
187
|
* @param {import("../view/rendering").GlobalRenderingOptions} options
|
|
170
188
|
*/
|
|
171
189
|
prepareRender(options) {
|
|
172
|
-
super.prepareRender(options);
|
|
190
|
+
const ops = super.prepareRender(options);
|
|
173
191
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
props.cornerRadiusTopRight ?? props.cornerRadius,
|
|
181
|
-
props.cornerRadiusBottomRight ?? props.cornerRadius,
|
|
182
|
-
props.cornerRadiusTopLeft ?? props.cornerRadius,
|
|
183
|
-
props.cornerRadiusBottomLeft ?? props.cornerRadius,
|
|
184
|
-
],
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
setBuffersAndAttributes(
|
|
188
|
-
this.gl,
|
|
189
|
-
this.programInfo,
|
|
190
|
-
this.vertexArrayInfo
|
|
192
|
+
ops.push(() =>
|
|
193
|
+
setBuffersAndAttributes(
|
|
194
|
+
this.gl,
|
|
195
|
+
this.programInfo,
|
|
196
|
+
this.vertexArrayInfo
|
|
197
|
+
)
|
|
191
198
|
);
|
|
199
|
+
|
|
200
|
+
return ops;
|
|
192
201
|
}
|
|
193
202
|
|
|
194
203
|
/**
|
|
@@ -197,19 +206,15 @@ export default class RectMark extends Mark {
|
|
|
197
206
|
render(options) {
|
|
198
207
|
const gl = this.gl;
|
|
199
208
|
|
|
200
|
-
return this.createRenderCallback(
|
|
201
|
-
(
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
},
|
|
210
|
-
options,
|
|
211
|
-
() => this.rangeMap
|
|
212
|
-
);
|
|
209
|
+
return this.createRenderCallback((offset, count) => {
|
|
210
|
+
drawBufferInfo(
|
|
211
|
+
gl,
|
|
212
|
+
this.vertexArrayInfo,
|
|
213
|
+
gl.TRIANGLE_STRIP,
|
|
214
|
+
count,
|
|
215
|
+
offset
|
|
216
|
+
);
|
|
217
|
+
}, options);
|
|
213
218
|
}
|
|
214
219
|
|
|
215
220
|
/**
|