Webgl points renderer / slight improvements following review

Also fixes a lint error.
This commit is contained in:
Olivier Guyot
2019-11-04 09:41:12 +01:00
parent af15cfb815
commit 7da86ae71f
3 changed files with 43 additions and 23 deletions

View File

@@ -287,30 +287,50 @@ class WebGLPointsLayerRenderer extends WebGLLayerRenderer {
*/ */
this.featureCache_ = {}; this.featureCache_ = {};
/**
* Amount of features in the cache.
* @type {number}
* @private
*/
this.featureCount_ = 0;
const source = this.getLayer().getSource(); const source = this.getLayer().getSource();
this.sourceListenKeys_ = [ this.sourceListenKeys_ = [
listen(source, VectorEventType.ADDFEATURE, this.handleSourceFeatureChanged_, this), listen(source, VectorEventType.ADDFEATURE, this.handleSourceFeatureAdded_, this),
listen(source, VectorEventType.CHANGEFEATURE, this.handleSourceFeatureChanged_, this), listen(source, VectorEventType.CHANGEFEATURE, this.handleSourceFeatureChanged_, this),
listen(source, VectorEventType.REMOVEFEATURE, this.handleSourceFeatureDelete_, this) listen(source, VectorEventType.REMOVEFEATURE, this.handleSourceFeatureDelete_, this)
]; ];
source.getFeatures().forEach(function(feature) { source.forEachFeature(function(feature) {
const uid = getUid(feature); this.featureCache_[getUid(feature)] = {
this.featureCache_[uid] = {
feature: feature, feature: feature,
properties: feature.getProperties(), properties: feature.getProperties(),
geometry: feature.getGeometry() geometry: feature.getGeometry()
}; };
this.featureCount_++;
}.bind(this)); }.bind(this));
} }
/**
* @param {import("../../source/Vector.js").VectorSourceEvent} event Event.
* @private
*/
handleSourceFeatureAdded_(event) {
const feature = event.feature;
this.featureCache_[getUid(feature)] = {
feature: feature,
properties: feature.getProperties(),
geometry: feature.getGeometry()
};
this.featureCount_++;
}
/** /**
* @param {import("../../source/Vector.js").VectorSourceEvent} event Event. * @param {import("../../source/Vector.js").VectorSourceEvent} event Event.
* @private * @private
*/ */
handleSourceFeatureChanged_(event) { handleSourceFeatureChanged_(event) {
const feature = event.feature; const feature = event.feature;
const uid = getUid(feature); this.featureCache_[getUid(feature)] = {
this.featureCache_[uid] = {
feature: feature, feature: feature,
properties: feature.getProperties(), properties: feature.getProperties(),
geometry: feature.getGeometry() geometry: feature.getGeometry()
@@ -323,8 +343,8 @@ class WebGLPointsLayerRenderer extends WebGLLayerRenderer {
*/ */
handleSourceFeatureDelete_(event) { handleSourceFeatureDelete_(event) {
const feature = event.feature; const feature = event.feature;
const uid = getUid(feature); delete this.featureCache_[getUid(feature)];
delete this.featureCache_[uid]; this.featureCount_--;
} }
/** /**
@@ -403,32 +423,29 @@ class WebGLPointsLayerRenderer extends WebGLLayerRenderer {
const projectionTransform = createTransform(); const projectionTransform = createTransform();
this.helper.makeProjectionTransform(frameState, projectionTransform); this.helper.makeProjectionTransform(frameState, projectionTransform);
const featureUids = Object.keys(this.featureCache_);
// here we anticipate the amount of render instructions that we well generate // here we anticipate the amount of render instructions that we well generate
// this can be done since we know that for normal render we only have x, y as base instructions, // this can be done since we know that for normal render we only have x, y as base instructions,
// and x, y, r, g, b, a and featureUid for hit render instructions // and x, y, r, g, b, a and featureUid for hit render instructions
// and we also know the amount of custom attributes to append to these // and we also know the amount of custom attributes to append to these
const totalInstructionsCount = (2 + this.customAttributes.length) * featureUids.length; const totalInstructionsCount = (2 + this.customAttributes.length) * this.featureCount_;
if (!this.renderInstructions_ || this.renderInstructions_.length !== totalInstructionsCount) { if (!this.renderInstructions_ || this.renderInstructions_.length !== totalInstructionsCount) {
this.renderInstructions_ = new Float32Array(totalInstructionsCount); this.renderInstructions_ = new Float32Array(totalInstructionsCount);
} }
if (this.hitDetectionEnabled_) { if (this.hitDetectionEnabled_) {
const totalHitInstructionsCount = (7 + this.customAttributes.length) * featureUids.length; const totalHitInstructionsCount = (7 + this.customAttributes.length) * this.featureCount_;
if (!this.hitRenderInstructions_ || this.hitRenderInstructions_.length !== totalHitInstructionsCount) { if (!this.hitRenderInstructions_ || this.hitRenderInstructions_.length !== totalHitInstructionsCount) {
this.hitRenderInstructions_ = new Float32Array(totalHitInstructionsCount); this.hitRenderInstructions_ = new Float32Array(totalHitInstructionsCount);
} }
} }
// loop on features to fill the buffer // loop on features to fill the buffer
let featureUid, featureCache, geometry; let featureCache, geometry;
const tmpCoords = []; const tmpCoords = [];
const tmpColor = []; const tmpColor = [];
let renderIndex = 0; let renderIndex = 0;
let hitIndex = 0; let hitIndex = 0;
let hitColor; let hitColor;
for (let i = 0; i < featureUids.length; i++) { for (const featureUid in this.featureCache_) {
featureUid = featureUids[i];
featureCache = this.featureCache_[featureUid]; featureCache = this.featureCache_[featureUid];
geometry = /** @type {import("../../geom").Point} */(featureCache.geometry); geometry = /** @type {import("../../geom").Point} */(featureCache.geometry);
if (!geometry || geometry.getType() !== GeometryType.POINT) { if (!geometry || geometry.getType() !== GeometryType.POINT) {

View File

@@ -123,7 +123,10 @@ class WebGLRenderTarget {
*/ */
readPixel(x, y) { readPixel(x, y) {
if (x < 0 || y < 0 || x > this.size_[0] || y >= this.size_[1]) { if (x < 0 || y < 0 || x > this.size_[0] || y >= this.size_[1]) {
tmpArray4[0] = tmpArray4[1] = tmpArray4[2] = tmpArray4[3] = 0; tmpArray4[0] = 0;
tmpArray4[1] = 0;
tmpArray4[2] = 0;
tmpArray4[3] = 0;
return tmpArray4; return tmpArray4;
} }

View File

@@ -425,7 +425,7 @@ describe('ol.renderer.webgl.PointsLayer', function() {
vertexShader: simpleVertexShader, vertexShader: simpleVertexShader,
fragmentShader: simpleFragmentShader fragmentShader: simpleFragmentShader
}); });
expect(Object.keys(renderer.featureCache_).length).to.be(0); expect(renderer.featureCount_).to.be(0);
}); });
it('contains the features initially present in the source', function() { it('contains the features initially present in the source', function() {
@@ -434,7 +434,7 @@ describe('ol.renderer.webgl.PointsLayer', function() {
vertexShader: simpleVertexShader, vertexShader: simpleVertexShader,
fragmentShader: simpleFragmentShader fragmentShader: simpleFragmentShader
}); });
expect(Object.keys(renderer.featureCache_).length).to.be(3); expect(renderer.featureCount_).to.be(3);
expect(getCache(features[0], renderer).feature).to.be(features[0]); expect(getCache(features[0], renderer).feature).to.be(features[0]);
expect(getCache(features[0], renderer).geometry).to.be(features[0].getGeometry()); expect(getCache(features[0], renderer).geometry).to.be(features[0].getGeometry());
expect(getCache(features[0], renderer).properties['test']).to.be(features[0].get('test')); expect(getCache(features[0], renderer).properties['test']).to.be(features[0].get('test'));
@@ -453,10 +453,10 @@ describe('ol.renderer.webgl.PointsLayer', function() {
}); });
source.addFeature(features[0]); source.addFeature(features[0]);
expect(Object.keys(renderer.featureCache_).length).to.be(1); expect(renderer.featureCount_).to.be(1);
source.addFeature(features[1]); source.addFeature(features[1]);
expect(Object.keys(renderer.featureCache_).length).to.be(2); expect(renderer.featureCount_).to.be(2);
expect(getCache(features[0], renderer).feature).to.be(features[0]); expect(getCache(features[0], renderer).feature).to.be(features[0]);
expect(getCache(features[0], renderer).geometry).to.be(features[0].getGeometry()); expect(getCache(features[0], renderer).geometry).to.be(features[0].getGeometry());
@@ -473,10 +473,10 @@ describe('ol.renderer.webgl.PointsLayer', function() {
}); });
source.addFeatures(features); source.addFeatures(features);
expect(Object.keys(renderer.featureCache_).length).to.be(3); expect(renderer.featureCount_).to.be(3);
source.removeFeature(features[1]); source.removeFeature(features[1]);
expect(Object.keys(renderer.featureCache_).length).to.be(2); expect(renderer.featureCount_).to.be(2);
expect(getCache(features[0], renderer).feature).to.be(features[0]); expect(getCache(features[0], renderer).feature).to.be(features[0]);
expect(getCache(features[0], renderer).geometry).to.be(features[0].getGeometry()); expect(getCache(features[0], renderer).geometry).to.be(features[0].getGeometry());
@@ -496,7 +496,7 @@ describe('ol.renderer.webgl.PointsLayer', function() {
features[0].set('test', 'updated'); features[0].set('test', 'updated');
features[0].set('added', true); features[0].set('added', true);
features[0].getGeometry().setCoordinates([10, 20]); features[0].getGeometry().setCoordinates([10, 20]);
expect(Object.keys(renderer.featureCache_).length).to.be(3); expect(renderer.featureCount_).to.be(3);
expect(getCache(features[0], renderer).feature).to.be(features[0]); expect(getCache(features[0], renderer).feature).to.be(features[0]);
expect(getCache(features[0], renderer).geometry.getCoordinates()).to.eql([10, 20]); expect(getCache(features[0], renderer).geometry.getCoordinates()).to.eql([10, 20]);