Avoid creating unnecessary images during rendering

This commit is contained in:
Tim Schaub
2015-02-16 15:07:47 -07:00
parent 2cf1fe5552
commit e5432f7cb5
6 changed files with 178 additions and 203 deletions

View File

@@ -287,11 +287,7 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame =
/** @type {Array.<ol.Tile>} */
var tilesToClear = [];
var getTileIfLoaded = this.createGetTileIfLoadedFunction(function(tile) {
return !goog.isNull(tile) && tile.getState() == ol.TileState.LOADED;
}, tileSource, pixelRatio, projection);
var findLoadedTiles = goog.bind(tileSource.findLoadedTiles, tileSource,
tilesToDrawByZ, getTileIfLoaded);
var findLoadedTiles = this.createLoadedTileFinder(tileSource, tilesToDrawByZ);
var useInterimTilesOnError = tileLayer.getUseInterimTilesOnError();

View File

@@ -128,11 +128,7 @@ ol.renderer.dom.TileLayer.prototype.prepareFrame =
var tilesToDrawByZ = {};
tilesToDrawByZ[z] = {};
var getTileIfLoaded = this.createGetTileIfLoadedFunction(function(tile) {
return !goog.isNull(tile) && tile.getState() == ol.TileState.LOADED;
}, tileSource, pixelRatio, projection);
var findLoadedTiles = goog.bind(tileSource.findLoadedTiles, tileSource,
tilesToDrawByZ, getTileIfLoaded);
var findLoadedTiles = this.createLoadedTileFinder(tileSource, tilesToDrawByZ);
var useInterimTilesOnError = tileLayer.getUseInterimTilesOnError();

View File

@@ -85,6 +85,33 @@ ol.renderer.Layer.prototype.forEachLayerAtPixel =
ol.renderer.Layer.prototype.hasFeatureAtCoordinate = goog.functions.FALSE;
/**
* Create a function that adds loaded tiles to the tile lookup.
* @param {ol.source.Tile} source Tile source.
* @param {Object.<number, Object.<string, ol.Tile>>} tiles Lookup of loaded
* tiles by zoom level.
* @return {function(number, ol.TileRange):boolean} A function that can be
* called with a zoom level and a tile range to add loaded tiles to the
* lookup.
* @protected
*/
ol.renderer.Layer.prototype.createLoadedTileFinder = function(source, tiles) {
/**
* @param {number} zoom Zoom level.
* @param {ol.TileRange} tileRange Tile range.
* @return {boolean} The tile range is fully loaded.
*/
return function(zoom, tileRange) {
return source.forEachLoadedTile(zoom, tileRange, function(tile) {
if (!tiles[zoom]) {
tiles[zoom] = {};
}
tiles[zoom][tile.tileCoord.toString()] = tile;
});
};
};
/**
* @protected
* @return {ol.layer.Layer} Layer.

View File

@@ -94,6 +94,40 @@ ol.renderer.webgl.TileLayer.prototype.disposeInternal = function() {
};
/**
* Create a function that adds loaded tiles to the tile lookup.
* @param {ol.source.Tile} source Tile source.
* @param {Object.<number, Object.<string, ol.Tile>>} tiles Lookup of loaded
* tiles by zoom level.
* @return {function(number, ol.TileRange):boolean} A function that can be
* called with a zoom level and a tile range to add loaded tiles to the
* lookup.
* @protected
*/
ol.renderer.webgl.TileLayer.prototype.createLoadedTileFinder =
function(source, tiles) {
var mapRenderer = this.mapRenderer;
/**
* @param {number} zoom Zoom level.
* @param {ol.TileRange} tileRange Tile range.
* @return {boolean} The tile range is fully loaded.
*/
return function(zoom, tileRange) {
return source.forEachLoadedTile(zoom, tileRange, function(tile) {
var loaded = mapRenderer.isTileTextureLoaded(tile);
if (loaded) {
if (!tiles[zoom]) {
tiles[zoom] = {};
}
tiles[zoom][tile.tileCoord.toString()] = tile;
}
return loaded;
});
};
};
/**
* @inheritDoc
*/
@@ -190,12 +224,8 @@ ol.renderer.webgl.TileLayer.prototype.prepareFrame =
var tilesToDrawByZ = {};
tilesToDrawByZ[z] = {};
var getTileIfLoaded = this.createGetTileIfLoadedFunction(function(tile) {
return !goog.isNull(tile) && tile.getState() == ol.TileState.LOADED &&
mapRenderer.isTileTextureLoaded(tile);
}, tileSource, pixelRatio, projection);
var findLoadedTiles = goog.bind(tileSource.findLoadedTiles, tileSource,
tilesToDrawByZ, getTileIfLoaded);
var findLoadedTiles = this.createLoadedTileFinder(
tileSource, tilesToDrawByZ);
var useInterimTilesOnError = tileLayer.getUseInterimTilesOnError();
var allTilesLoaded = true;

View File

@@ -6,6 +6,7 @@ goog.require('ol.Attribution');
goog.require('ol.Extent');
goog.require('ol.TileCache');
goog.require('ol.TileRange');
goog.require('ol.TileState');
goog.require('ol.source.Source');
goog.require('ol.tilecoord');
goog.require('ol.tilegrid.TileGrid');
@@ -92,41 +93,33 @@ ol.source.Tile.prototype.expireCache = function(usedTiles) {
/**
* Look for loaded tiles over a given tile range and zoom level. Adds
* properties to the provided lookup representing key/tile pairs for already
* loaded tiles.
*
* @param {Object.<number, Object.<string, ol.Tile>>} loadedTilesByZ A lookup of
* loaded tiles by zoom level.
* @param {function(number, number, number): ol.Tile} getTileIfLoaded A function
* that returns the tile only if it is fully loaded.
* @param {number} z Zoom level.
* @param {ol.TileRange} tileRange Tile range.
* @param {function(ol.Tile):(boolean|undefined)} callback Called with each
* loaded tile. If the callback returns `false`, the tile will not be
* considered loaded.
* @return {boolean} The tile range is fully covered with loaded tiles.
*/
ol.source.Tile.prototype.findLoadedTiles = function(loadedTilesByZ,
getTileIfLoaded, z, tileRange) {
// FIXME this could be more efficient about filling partial holes
var fullyCovered = true;
var tile, tileCoordKey, x, y;
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
ol.source.Tile.prototype.forEachLoadedTile = function(z, tileRange, callback) {
var covered = true;
var tile, tileCoordKey, loaded;
for (var x = tileRange.minX; x <= tileRange.maxX; ++x) {
for (var y = tileRange.minY; y <= tileRange.maxY; ++y) {
tileCoordKey = this.getKeyZXY(z, x, y);
if (loadedTilesByZ[z] && loadedTilesByZ[z][tileCoordKey]) {
continue;
}
tile = getTileIfLoaded(z, x, y);
if (!goog.isNull(tile)) {
if (!loadedTilesByZ[z]) {
loadedTilesByZ[z] = {};
loaded = false;
if (this.tileCache.containsKey(tileCoordKey)) {
tile = /** @type {!ol.Tile} */ (this.tileCache.get(tileCoordKey));
loaded = tile.getState() === ol.TileState.LOADED;
if (loaded) {
loaded = (callback(tile) !== false);
}
loadedTilesByZ[z][tileCoordKey] = tile;
} else {
fullyCovered = false;
}
if (!loaded) {
covered = false;
}
}
}
return fullyCovered;
return covered;
};