Skip to content

Commit e5432f7

Browse files
committed
Avoid creating unnecessary images during rendering
1 parent 2cf1fe5 commit e5432f7

File tree

6 files changed

+169
-194
lines changed

6 files changed

+169
-194
lines changed

src/ol/renderer/canvas/canvastilelayerrenderer.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -287,11 +287,7 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame =
287287
/** @type {Array.<ol.Tile>} */
288288
var tilesToClear = [];
289289

290-
var getTileIfLoaded = this.createGetTileIfLoadedFunction(function(tile) {
291-
return !goog.isNull(tile) && tile.getState() == ol.TileState.LOADED;
292-
}, tileSource, pixelRatio, projection);
293-
var findLoadedTiles = goog.bind(tileSource.findLoadedTiles, tileSource,
294-
tilesToDrawByZ, getTileIfLoaded);
290+
var findLoadedTiles = this.createLoadedTileFinder(tileSource, tilesToDrawByZ);
295291

296292
var useInterimTilesOnError = tileLayer.getUseInterimTilesOnError();
297293

src/ol/renderer/dom/domtilelayerrenderer.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -128,11 +128,7 @@ ol.renderer.dom.TileLayer.prototype.prepareFrame =
128128
var tilesToDrawByZ = {};
129129
tilesToDrawByZ[z] = {};
130130

131-
var getTileIfLoaded = this.createGetTileIfLoadedFunction(function(tile) {
132-
return !goog.isNull(tile) && tile.getState() == ol.TileState.LOADED;
133-
}, tileSource, pixelRatio, projection);
134-
var findLoadedTiles = goog.bind(tileSource.findLoadedTiles, tileSource,
135-
tilesToDrawByZ, getTileIfLoaded);
131+
var findLoadedTiles = this.createLoadedTileFinder(tileSource, tilesToDrawByZ);
136132

137133
var useInterimTilesOnError = tileLayer.getUseInterimTilesOnError();
138134

src/ol/renderer/layerrenderer.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,33 @@ ol.renderer.Layer.prototype.forEachLayerAtPixel =
8585
ol.renderer.Layer.prototype.hasFeatureAtCoordinate = goog.functions.FALSE;
8686

8787

88+
/**
89+
* Create a function that adds loaded tiles to the tile lookup.
90+
* @param {ol.source.Tile} source Tile source.
91+
* @param {Object.<number, Object.<string, ol.Tile>>} tiles Lookup of loaded
92+
* tiles by zoom level.
93+
* @return {function(number, ol.TileRange):boolean} A function that can be
94+
* called with a zoom level and a tile range to add loaded tiles to the
95+
* lookup.
96+
* @protected
97+
*/
98+
ol.renderer.Layer.prototype.createLoadedTileFinder = function(source, tiles) {
99+
/**
100+
* @param {number} zoom Zoom level.
101+
* @param {ol.TileRange} tileRange Tile range.
102+
* @return {boolean} The tile range is fully loaded.
103+
*/
104+
return function(zoom, tileRange) {
105+
return source.forEachLoadedTile(zoom, tileRange, function(tile) {
106+
if (!tiles[zoom]) {
107+
tiles[zoom] = {};
108+
}
109+
tiles[zoom][tile.tileCoord.toString()] = tile;
110+
});
111+
};
112+
};
113+
114+
88115
/**
89116
* @protected
90117
* @return {ol.layer.Layer} Layer.

src/ol/renderer/webgl/webgltilelayerrenderer.js

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,40 @@ ol.renderer.webgl.TileLayer.prototype.disposeInternal = function() {
9494
};
9595

9696

97+
/**
98+
* Create a function that adds loaded tiles to the tile lookup.
99+
* @param {ol.source.Tile} source Tile source.
100+
* @param {Object.<number, Object.<string, ol.Tile>>} tiles Lookup of loaded
101+
* tiles by zoom level.
102+
* @return {function(number, ol.TileRange):boolean} A function that can be
103+
* called with a zoom level and a tile range to add loaded tiles to the
104+
* lookup.
105+
* @protected
106+
*/
107+
ol.renderer.webgl.TileLayer.prototype.createLoadedTileFinder =
108+
function(source, tiles) {
109+
var mapRenderer = this.mapRenderer;
110+
111+
/**
112+
* @param {number} zoom Zoom level.
113+
* @param {ol.TileRange} tileRange Tile range.
114+
* @return {boolean} The tile range is fully loaded.
115+
*/
116+
return function(zoom, tileRange) {
117+
return source.forEachLoadedTile(zoom, tileRange, function(tile) {
118+
var loaded = mapRenderer.isTileTextureLoaded(tile);
119+
if (loaded) {
120+
if (!tiles[zoom]) {
121+
tiles[zoom] = {};
122+
}
123+
tiles[zoom][tile.tileCoord.toString()] = tile;
124+
}
125+
return loaded;
126+
});
127+
};
128+
};
129+
130+
97131
/**
98132
* @inheritDoc
99133
*/
@@ -190,12 +224,8 @@ ol.renderer.webgl.TileLayer.prototype.prepareFrame =
190224
var tilesToDrawByZ = {};
191225
tilesToDrawByZ[z] = {};
192226

193-
var getTileIfLoaded = this.createGetTileIfLoadedFunction(function(tile) {
194-
return !goog.isNull(tile) && tile.getState() == ol.TileState.LOADED &&
195-
mapRenderer.isTileTextureLoaded(tile);
196-
}, tileSource, pixelRatio, projection);
197-
var findLoadedTiles = goog.bind(tileSource.findLoadedTiles, tileSource,
198-
tilesToDrawByZ, getTileIfLoaded);
227+
var findLoadedTiles = this.createLoadedTileFinder(
228+
tileSource, tilesToDrawByZ);
199229

200230
var useInterimTilesOnError = tileLayer.getUseInterimTilesOnError();
201231
var allTilesLoaded = true;

src/ol/source/tilesource.js

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ goog.require('ol.Attribution');
66
goog.require('ol.Extent');
77
goog.require('ol.TileCache');
88
goog.require('ol.TileRange');
9+
goog.require('ol.TileState');
910
goog.require('ol.source.Source');
1011
goog.require('ol.tilecoord');
1112
goog.require('ol.tilegrid.TileGrid');
@@ -92,41 +93,33 @@ ol.source.Tile.prototype.expireCache = function(usedTiles) {
9293

9394

9495
/**
95-
* Look for loaded tiles over a given tile range and zoom level. Adds
96-
* properties to the provided lookup representing key/tile pairs for already
97-
* loaded tiles.
98-
*
99-
* @param {Object.<number, Object.<string, ol.Tile>>} loadedTilesByZ A lookup of
100-
* loaded tiles by zoom level.
101-
* @param {function(number, number, number): ol.Tile} getTileIfLoaded A function
102-
* that returns the tile only if it is fully loaded.
10396
* @param {number} z Zoom level.
10497
* @param {ol.TileRange} tileRange Tile range.
98+
* @param {function(ol.Tile):(boolean|undefined)} callback Called with each
99+
* loaded tile. If the callback returns `false`, the tile will not be
100+
* considered loaded.
105101
* @return {boolean} The tile range is fully covered with loaded tiles.
106102
*/
107-
ol.source.Tile.prototype.findLoadedTiles = function(loadedTilesByZ,
108-
getTileIfLoaded, z, tileRange) {
109-
// FIXME this could be more efficient about filling partial holes
110-
var fullyCovered = true;
111-
var tile, tileCoordKey, x, y;
112-
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
113-
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
103+
ol.source.Tile.prototype.forEachLoadedTile = function(z, tileRange, callback) {
104+
var covered = true;
105+
var tile, tileCoordKey, loaded;
106+
for (var x = tileRange.minX; x <= tileRange.maxX; ++x) {
107+
for (var y = tileRange.minY; y <= tileRange.maxY; ++y) {
114108
tileCoordKey = this.getKeyZXY(z, x, y);
115-
if (loadedTilesByZ[z] && loadedTilesByZ[z][tileCoordKey]) {
116-
continue;
117-
}
118-
tile = getTileIfLoaded(z, x, y);
119-
if (!goog.isNull(tile)) {
120-
if (!loadedTilesByZ[z]) {
121-
loadedTilesByZ[z] = {};
109+
loaded = false;
110+
if (this.tileCache.containsKey(tileCoordKey)) {
111+
tile = /** @type {!ol.Tile} */ (this.tileCache.get(tileCoordKey));
112+
loaded = tile.getState() === ol.TileState.LOADED;
113+
if (loaded) {
114+
loaded = (callback(tile) !== false);
122115
}
123-
loadedTilesByZ[z][tileCoordKey] = tile;
124-
} else {
125-
fullyCovered = false;
116+
}
117+
if (!loaded) {
118+
covered = false;
126119
}
127120
}
128121
}
129-
return fullyCovered;
122+
return covered;
130123
};
131124

132125

0 commit comments

Comments
 (0)