Adapt the batch renderers to trigger a repaint after buffer rebuild

This commit is contained in:
Olivier Guyot
2022-05-04 11:15:30 +02:00
parent 8769ea519e
commit 9e35acaa0a
3 changed files with 41 additions and 10 deletions

View File

@@ -73,15 +73,16 @@ class AbstractBatchRenderer {
* @param {import("./MixedGeometryBatch.js").GeometryBatch} batch Geometry batch * @param {import("./MixedGeometryBatch.js").GeometryBatch} batch Geometry batch
* @param {import("../../PluggableMap").FrameState} frameState Frame state. * @param {import("../../PluggableMap").FrameState} frameState Frame state.
* @param {import("../../geom/GeometryType.js").default} geometryType Geometry type * @param {import("../../geom/GeometryType.js").default} geometryType Geometry type
* @param {function(): void} callback Function called once the render buffers are updated
*/ */
rebuild(batch, frameState, geometryType) { rebuild(batch, frameState, geometryType, callback) {
// store transform for rendering instructions // store transform for rendering instructions
batch.renderInstructionsTransform = this.helper_.makeProjectionTransform( batch.renderInstructionsTransform = this.helper_.makeProjectionTransform(
frameState, frameState,
createTransform() createTransform()
); );
this.generateRenderInstructions_(batch); this.generateRenderInstructions_(batch);
this.generateBuffers_(batch, geometryType); this.generateBuffers_(batch, geometryType, callback);
} }
/** /**
@@ -123,9 +124,10 @@ class AbstractBatchRenderer {
* This is asynchronous: webgl buffers wil _not_ be updated right away * This is asynchronous: webgl buffers wil _not_ be updated right away
* @param {import("./MixedGeometryBatch.js").GeometryBatch} batch Geometry batch * @param {import("./MixedGeometryBatch.js").GeometryBatch} batch Geometry batch
* @param {import("../../geom/GeometryType.js").default} geometryType Geometry type * @param {import("../../geom/GeometryType.js").default} geometryType Geometry type
* @param {function(): void} callback Function called once the render buffers are updated
* @protected * @protected
*/ */
generateBuffers_(batch, geometryType) { generateBuffers_(batch, geometryType, callback) {
const messageId = workerMessageCounter++; const messageId = workerMessageCounter++;
let messageType; let messageType;
@@ -192,7 +194,7 @@ class AbstractBatchRenderer {
received.renderInstructions received.renderInstructions
); );
// TODO: call layer.changed somehow for the layer to rerender!!!1 callback();
}.bind(this); }.bind(this);
this.worker_.addEventListener('message', handleMessage); this.worker_.addEventListener('message', handleMessage);

View File

@@ -303,20 +303,31 @@ class WebGLVectorLayerRenderer extends WebGLLayerRenderer {
const extent = buffer(frameState.extent, renderBuffer * resolution); const extent = buffer(frameState.extent, renderBuffer * resolution);
vectorSource.loadFeatures(extent, resolution, projection); vectorSource.loadFeatures(extent, resolution, projection);
this.ready = false;
let remaining = 3;
const rebuildCb = () => {
remaining--;
this.ready = remaining <= 0;
this.getLayer().changed();
};
this.polygonRenderer_.rebuild( this.polygonRenderer_.rebuild(
this.batch_.polygonBatch, this.batch_.polygonBatch,
frameState, frameState,
GeometryType.POLYGON GeometryType.POLYGON,
rebuildCb
); );
this.lineStringRenderer_.rebuild( this.lineStringRenderer_.rebuild(
this.batch_.lineStringBatch, this.batch_.lineStringBatch,
frameState, frameState,
GeometryType.LINE_STRING GeometryType.LINE_STRING,
rebuildCb
); );
this.pointRenderer_.rebuild( this.pointRenderer_.rebuild(
this.batch_.pointBatch, this.batch_.pointBatch,
frameState, frameState,
GeometryType.POINT GeometryType.POINT,
rebuildCb
); );
this.previousExtent_ = frameState.extent.slice(); this.previousExtent_ = frameState.extent.slice();
} }

View File

@@ -98,12 +98,15 @@ describe('Batch renderers', function () {
}); });
}); });
describe('#rebuild', function () { describe('#rebuild', function () {
let rebuildCb;
beforeEach(function (done) { beforeEach(function (done) {
sinon.spy(helper, 'flushBufferData'); sinon.spy(helper, 'flushBufferData');
rebuildCb = sinon.spy();
batchRenderer.rebuild( batchRenderer.rebuild(
mixedBatch.pointBatch, mixedBatch.pointBatch,
SAMPLE_FRAMESTATE, SAMPLE_FRAMESTATE,
GeometryType.POINT GeometryType.POINT,
rebuildCb
); );
// wait for worker response for our specific message // wait for worker response for our specific message
worker.addEventListener('message', function (event) { worker.addEventListener('message', function (event) {
@@ -134,6 +137,9 @@ describe('Batch renderers', function () {
0.2, 0, 0, 0.2, 0, -2, 0.2, 0, 0, 0.2, 0, -2,
]); ]);
}); });
it('calls the provided callback', function () {
expect(rebuildCb.calledOnce).to.be(true);
});
}); });
describe('#render (from parent)', function () { describe('#render (from parent)', function () {
let transform; let transform;
@@ -196,12 +202,15 @@ describe('Batch renderers', function () {
}); });
}); });
describe('#rebuild', function () { describe('#rebuild', function () {
let rebuildCb;
beforeEach(function (done) { beforeEach(function (done) {
sinon.spy(helper, 'flushBufferData'); sinon.spy(helper, 'flushBufferData');
rebuildCb = sinon.spy();
batchRenderer.rebuild( batchRenderer.rebuild(
mixedBatch.lineStringBatch, mixedBatch.lineStringBatch,
SAMPLE_FRAMESTATE, SAMPLE_FRAMESTATE,
GeometryType.LINE_STRING GeometryType.LINE_STRING,
rebuildCb
); );
// wait for worker response for our specific message // wait for worker response for our specific message
worker.addEventListener('message', function (event) { worker.addEventListener('message', function (event) {
@@ -231,6 +240,9 @@ describe('Batch renderers', function () {
).to.be.greaterThan(0); ).to.be.greaterThan(0);
expect(helper.flushBufferData.calledTwice).to.be(true); expect(helper.flushBufferData.calledTwice).to.be(true);
}); });
it('calls the provided callback', function () {
expect(rebuildCb.calledOnce).to.be(true);
});
}); });
}); });
@@ -253,12 +265,15 @@ describe('Batch renderers', function () {
}); });
}); });
describe('#rebuild', function () { describe('#rebuild', function () {
let rebuildCb;
beforeEach(function (done) { beforeEach(function (done) {
sinon.spy(helper, 'flushBufferData'); sinon.spy(helper, 'flushBufferData');
rebuildCb = sinon.spy();
batchRenderer.rebuild( batchRenderer.rebuild(
mixedBatch.polygonBatch, mixedBatch.polygonBatch,
SAMPLE_FRAMESTATE, SAMPLE_FRAMESTATE,
GeometryType.POLYGON GeometryType.POLYGON,
rebuildCb
); );
// wait for worker response for our specific message // wait for worker response for our specific message
worker.addEventListener('message', function (event) { worker.addEventListener('message', function (event) {
@@ -285,6 +300,9 @@ describe('Batch renderers', function () {
).to.be.greaterThan(0); ).to.be.greaterThan(0);
expect(helper.flushBufferData.calledTwice).to.be(true); expect(helper.flushBufferData.calledTwice).to.be(true);
}); });
it('calls the provided callback', function () {
expect(rebuildCb.calledOnce).to.be(true);
});
}); });
}); });
}); });