diff --git a/src/ol/renderer/canvas/canvasmaprenderer.js b/src/ol/renderer/canvas/canvasmaprenderer.js index 69191c5bae..b5e6d80458 100644 --- a/src/ol/renderer/canvas/canvasmaprenderer.js +++ b/src/ol/renderer/canvas/canvasmaprenderer.js @@ -153,4 +153,6 @@ ol.renderer.canvas.Map.prototype.renderFrame = function(frameState) { this.renderedVisible_ = true; } + this.removeUnusedLayerRenderers(frameState); + }; diff --git a/src/ol/renderer/dom/dommaprenderer.js b/src/ol/renderer/dom/dommaprenderer.js index f821be3f07..4866a11763 100644 --- a/src/ol/renderer/dom/dommaprenderer.js +++ b/src/ol/renderer/dom/dommaprenderer.js @@ -93,5 +93,6 @@ ol.renderer.dom.Map.prototype.renderFrame = function(frameState) { } this.calculateMatrices2D(frameState); + this.removeUnusedLayerRenderers(frameState); }; diff --git a/src/ol/renderer/maprenderer.js b/src/ol/renderer/maprenderer.js index 870cb37fdb..70a36d840e 100644 --- a/src/ol/renderer/maprenderer.js +++ b/src/ol/renderer/maprenderer.js @@ -42,32 +42,27 @@ ol.renderer.Map = function(container, map) { /** * @private - * @type {Object.} + * @type {Object.} */ this.layerRenderers_ = {}; - // - // We listen to layer add/remove to add/remove layer renderers. - // - /** * @private * @type {?number} */ - this.mapLayersChangedListenerKey_ = - goog.events.listen( - map, ol.Object.getChangedEventType(ol.MapProperty.LAYERS), - this.handleLayersChanged_, false, this); + this.mapLayersChangedListenerKey_ = goog.events.listen( + map, ol.Object.getChangedEventType(ol.MapProperty.LAYERS), + this.handleLayersChanged_, false, this); /** * @private - * @type {Array.} + * @type {Array.} */ this.layersListenerKeys_ = null; /** * @private - * @type {Object.} + * @type {Object.} */ this.layerRendererChangeListenKeys_ = {}; @@ -75,17 +70,6 @@ ol.renderer.Map = function(container, map) { goog.inherits(ol.renderer.Map, goog.Disposable); -/** - * @param {ol.layer.Layer} layer Layer. - * @private - */ -ol.renderer.Map.prototype.addLayer_ = function(layer) { - var layerRenderer = this.createLayerRenderer(layer); - this.setLayerRenderer_(layer, layerRenderer); - this.getMap().render(); -}; - - /** * @param {ol.FrameState} frameState FrameState. * @protected @@ -136,9 +120,8 @@ ol.renderer.Map.prototype.disposeInternal = function() { goog.dispose(layerRenderer); }); goog.events.unlistenByKey(this.mapLayersChangedListenerKey_); - if (!goog.isNull(this.layersListenerKeys_)) { - goog.array.forEach(this.layersListenerKeys_, goog.events.unlistenByKey); - } + goog.object.forEach( + this.layerRendererChangeListenKeys_, goog.events.unlistenByKey); goog.base(this, 'disposeInternal'); }; @@ -155,10 +138,17 @@ ol.renderer.Map.prototype.getCanvas = goog.functions.NULL; * @return {ol.renderer.Layer} Layer renderer. */ ol.renderer.Map.prototype.getLayerRenderer = function(layer) { - var layerKey = goog.getUid(layer); - var layerRenderer = this.layerRenderers_[layerKey]; - goog.asserts.assert(goog.isDef(layerRenderer)); - return layerRenderer; + var layerKey = goog.getUid(layer).toString(); + if (layerKey in this.layerRenderers_) { + return this.layerRenderers_[layerKey]; + } else { + var layerRenderer = this.createLayerRenderer(layer); + this.layerRenderers_[layerKey] = layerRenderer; + this.layerRendererChangeListenKeys_[layerKey] = goog.events.listen( + layerRenderer, goog.events.EventType.CHANGE, + this.handleLayerRendererChange_, false, this); + return layerRenderer; + } }; @@ -193,24 +183,21 @@ ol.renderer.Map.prototype.handleLayerRendererChange_ = function(event) { * @private */ ol.renderer.Map.prototype.handleLayersAdd_ = function(collectionEvent) { - var layer = /** @type {ol.layer.Layer} */ (collectionEvent.elem); - this.addLayer_(layer); + this.getMap().render(); }; /** + * @param {goog.events.Event} event Event. * @private */ -ol.renderer.Map.prototype.handleLayersChanged_ = function() { - goog.disposeAll(goog.object.getValues(this.layerRenderers_)); - this.layerRenderers_ = {}; +ol.renderer.Map.prototype.handleLayersChanged_ = function(event) { if (!goog.isNull(this.layersListenerKeys_)) { goog.array.forEach(this.layersListenerKeys_, goog.events.unlistenByKey); this.layersListenerKeys_ = null; } var layers = this.getMap().getLayers(); if (goog.isDefAndNotNull(layers)) { - layers.forEach(this.addLayer_, this); this.layersListenerKeys_ = [ goog.events.listen(layers, ol.CollectionEventType.ADD, this.handleLayersAdd_, false, this), @@ -218,6 +205,7 @@ ol.renderer.Map.prototype.handleLayersChanged_ = function() { this.handleLayersRemove_, false, this) ]; } + this.getMap().render(); }; @@ -226,37 +214,23 @@ ol.renderer.Map.prototype.handleLayersChanged_ = function() { * @private */ ol.renderer.Map.prototype.handleLayersRemove_ = function(collectionEvent) { - var layer = /** @type {ol.layer.Layer} */ (collectionEvent.elem); - this.removeLayer_(layer); -}; - - -/** - * @param {ol.layer.Layer} layer Layer. - * @private - */ -ol.renderer.Map.prototype.removeLayer_ = function(layer) { - goog.dispose(this.removeLayerRenderer_(layer)); this.getMap().render(); }; /** - * @param {ol.layer.Layer} layer Layer. + * @param {string} layerKey Layer key. * @return {ol.renderer.Layer} Layer renderer. * @private */ -ol.renderer.Map.prototype.removeLayerRenderer_ = function(layer) { - var layerKey = goog.getUid(layer); - if (layerKey in this.layerRenderers_) { - var layerRenderer = this.layerRenderers_[layerKey]; - delete this.layerRenderers_[layerKey]; - goog.events.unlistenByKey(this.layerRendererChangeListenKeys_[layerKey]); - delete this.layerRendererChangeListenKeys_[layerKey]; - return layerRenderer; - } else { - return null; - } +ol.renderer.Map.prototype.removeLayerRendererByKey_ = function(layerKey) { + goog.asserts.assert(layerKey in this.layerRenderers_); + var layerRenderer = this.layerRenderers_[layerKey]; + delete this.layerRenderers_[layerKey]; + goog.asserts.assert(layerKey in this.layerRendererChangeListenKeys_); + goog.events.unlistenByKey(this.layerRendererChangeListenKeys_[layerKey]); + delete this.layerRendererChangeListenKeys_[layerKey]; + return layerRenderer; }; @@ -268,16 +242,23 @@ ol.renderer.Map.prototype.renderFrame = goog.nullFunction; /** - * @param {ol.layer.Layer} layer Layer. - * @param {ol.renderer.Layer} layerRenderer Layer renderer. - * @private + * @param {!ol.FrameState} frameState Frame state. + * @protected */ -ol.renderer.Map.prototype.setLayerRenderer_ = function(layer, layerRenderer) { - var layerKey = goog.getUid(layer); - goog.asserts.assert(!(layerKey in this.layerRenderers_)); - this.layerRenderers_[layerKey] = layerRenderer; - goog.asserts.assert(!(layerKey in this.layerRendererChangeListenKeys_)); - this.layerRendererChangeListenKeys_[layerKey] = goog.events.listen( - layerRenderer, goog.events.EventType.CHANGE, - this.handleLayerRendererChange_, false, this); +ol.renderer.Map.prototype.removeUnusedLayerRenderers = + function(frameState) { + var layerRenderersToRemove = {}; + var layerKey; + for (layerKey in this.layerRenderers_) { + layerRenderersToRemove[layerKey] = true; + } + var layersArray = frameState.layersArray; + var i; + for (i = 0; i < layersArray.length; ++i) { + layerKey = goog.getUid(layersArray[i]).toString(); + delete layerRenderersToRemove[layerKey]; + } + for (layerKey in layerRenderersToRemove) { + goog.dispose(this.removeLayerRendererByKey_(layerKey)); + } }; diff --git a/src/ol/renderer/webgl/webglmaprenderer.js b/src/ol/renderer/webgl/webglmaprenderer.js index 77b03c3d36..3aed6a4972 100644 --- a/src/ol/renderer/webgl/webglmaprenderer.js +++ b/src/ol/renderer/webgl/webglmaprenderer.js @@ -641,4 +641,6 @@ ol.renderer.webgl.Map.prototype.renderFrame = function(frameState) { frameState.animate = true; } + this.removeUnusedLayerRenderers(frameState); + };