diff --git a/src/ol/render/webgl/BatchRenderer.js b/src/ol/render/webgl/BatchRenderer.js index 3de9c69305..c41d030cd0 100644 --- a/src/ol/render/webgl/BatchRenderer.js +++ b/src/ol/render/webgl/BatchRenderer.js @@ -73,15 +73,16 @@ class AbstractBatchRenderer { * @param {import("./MixedGeometryBatch.js").GeometryBatch} batch Geometry batch * @param {import("../../PluggableMap").FrameState} frameState Frame state. * @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 batch.renderInstructionsTransform = this.helper_.makeProjectionTransform( frameState, createTransform() ); 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 * @param {import("./MixedGeometryBatch.js").GeometryBatch} batch Geometry batch * @param {import("../../geom/GeometryType.js").default} geometryType Geometry type + * @param {function(): void} callback Function called once the render buffers are updated * @protected */ - generateBuffers_(batch, geometryType) { + generateBuffers_(batch, geometryType, callback) { const messageId = workerMessageCounter++; let messageType; @@ -192,7 +194,7 @@ class AbstractBatchRenderer { received.renderInstructions ); - // TODO: call layer.changed somehow for the layer to rerender!!!1 + callback(); }.bind(this); this.worker_.addEventListener('message', handleMessage); diff --git a/src/ol/renderer/webgl/VectorLayer.js b/src/ol/renderer/webgl/VectorLayer.js index 507af098ef..ba8dcd42c5 100644 --- a/src/ol/renderer/webgl/VectorLayer.js +++ b/src/ol/renderer/webgl/VectorLayer.js @@ -303,20 +303,31 @@ class WebGLVectorLayerRenderer extends WebGLLayerRenderer { const extent = buffer(frameState.extent, renderBuffer * resolution); 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.batch_.polygonBatch, frameState, - GeometryType.POLYGON + GeometryType.POLYGON, + rebuildCb ); this.lineStringRenderer_.rebuild( this.batch_.lineStringBatch, frameState, - GeometryType.LINE_STRING + GeometryType.LINE_STRING, + rebuildCb ); this.pointRenderer_.rebuild( this.batch_.pointBatch, frameState, - GeometryType.POINT + GeometryType.POINT, + rebuildCb ); this.previousExtent_ = frameState.extent.slice(); } diff --git a/test/browser/spec/ol/render/webgl/batchrenderer.test.js b/test/browser/spec/ol/render/webgl/batchrenderer.test.js index fa00eee520..6c7a7a629c 100644 --- a/test/browser/spec/ol/render/webgl/batchrenderer.test.js +++ b/test/browser/spec/ol/render/webgl/batchrenderer.test.js @@ -98,12 +98,15 @@ describe('Batch renderers', function () { }); }); describe('#rebuild', function () { + let rebuildCb; beforeEach(function (done) { sinon.spy(helper, 'flushBufferData'); + rebuildCb = sinon.spy(); batchRenderer.rebuild( mixedBatch.pointBatch, SAMPLE_FRAMESTATE, - GeometryType.POINT + GeometryType.POINT, + rebuildCb ); // wait for worker response for our specific message worker.addEventListener('message', function (event) { @@ -134,6 +137,9 @@ describe('Batch renderers', function () { 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 () { let transform; @@ -196,12 +202,15 @@ describe('Batch renderers', function () { }); }); describe('#rebuild', function () { + let rebuildCb; beforeEach(function (done) { sinon.spy(helper, 'flushBufferData'); + rebuildCb = sinon.spy(); batchRenderer.rebuild( mixedBatch.lineStringBatch, SAMPLE_FRAMESTATE, - GeometryType.LINE_STRING + GeometryType.LINE_STRING, + rebuildCb ); // wait for worker response for our specific message worker.addEventListener('message', function (event) { @@ -231,6 +240,9 @@ describe('Batch renderers', function () { ).to.be.greaterThan(0); 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 () { + let rebuildCb; beforeEach(function (done) { sinon.spy(helper, 'flushBufferData'); + rebuildCb = sinon.spy(); batchRenderer.rebuild( mixedBatch.polygonBatch, SAMPLE_FRAMESTATE, - GeometryType.POLYGON + GeometryType.POLYGON, + rebuildCb ); // wait for worker response for our specific message worker.addEventListener('message', function (event) { @@ -285,6 +300,9 @@ describe('Batch renderers', function () { ).to.be.greaterThan(0); expect(helper.flushBufferData.calledTwice).to.be(true); }); + it('calls the provided callback', function () { + expect(rebuildCb.calledOnce).to.be(true); + }); }); }); });