More cleanup in the WebGL tile layer's dispose method

This commit is contained in:
Tim Schaub
2021-09-23 11:05:16 +00:00
parent 2ebbee2340
commit a332842540
6 changed files with 61 additions and 0 deletions

View File

@@ -348,6 +348,11 @@ class Layer extends BaseLayer {
* Clean up.
*/
disposeInternal() {
if (this.renderer_) {
this.renderer_.dispose();
delete this.renderer_;
}
this.setSource(null);
super.disposeInternal();
}

View File

@@ -255,6 +255,9 @@ function parseStyle(style, bandCount) {
* property on the layer object; for example, setting `title: 'My Title'` in the
* options means that `title` is observable, and has get/set accessors.
*
* **Important**: after removing a `WebGLTile` layer from your map, call `layer.dispose()`
* to clean up underlying resources.
*
* @extends BaseTileLayer<import("../source/DataTile.js").default|import("../source/TileImage.js").default>
* @api
*/
@@ -320,4 +323,11 @@ class WebGLTileLayer extends BaseTileLayer {
}
}
/**
* Clean up underlying WebGL resources.
* @function
* @api
*/
WebGLTileLayer.prototype.dispose;
export default WebGLTileLayer;

View File

@@ -77,6 +77,8 @@ class WebGLLayerRenderer extends LayerRenderer {
*/
disposeInternal() {
this.helper.dispose();
delete this.helper;
super.disposeInternal();
}

View File

@@ -181,6 +181,11 @@ class WebGLTileLayerRenderer extends WebGLLayerRenderer {
this.indices_ = indices;
const cacheSize = options.cacheSize !== undefined ? options.cacheSize : 512;
/**
* @type {import("../../structs/LRUCache.js").default<import("../../webgl/TileTexture.js").default>}
* @private
*/
this.tileTextureCache_ = new LRUCache(cacheSize);
this.renderedOpacity_ = NaN;
@@ -533,6 +538,29 @@ class WebGLTileLayerRenderer extends WebGLLayerRenderer {
}
return covered;
}
/**
* Clean up.
*/
disposeInternal() {
const helper = this.helper;
const gl = helper.getGL();
helper.deleteBuffer(this.indices_);
delete this.indices_;
gl.deleteProgram(this.program_);
delete this.program_;
const tileTextureCache = this.tileTextureCache_;
tileTextureCache.forEach(function (tileTexture) {
tileTexture.dispose();
});
tileTextureCache.clear();
delete this.tileTextureCache_;
super.disposeInternal();
}
}
/**

View File

@@ -442,6 +442,13 @@ class WebGLHelper extends Disposable {
ContextEventType.RESTORED,
this.boundHandleWebGLContextRestored_
);
const extension = this.gl_.getExtension('WEBGL_lose_context');
if (extension) {
extension.loseContext();
}
delete this.gl_;
delete this.canvas_;
}
/**

View File

@@ -50,6 +50,15 @@ describe('ol/layer/WebGLTile', function () {
document.body.removeChild(target);
});
describe('dispose()', () => {
it('calls dispose on the renderer', () => {
const renderer = layer.getRenderer();
const spy = sinon.spy(renderer, 'dispose');
layer.dispose();
expect(spy.called).to.be(true);
});
});
it('creates fragment and vertex shaders', function () {
const compileShaderSpy = sinon.spy(WebGLHelper.prototype, 'compileShader');
layer.createRenderer();