Merge pull request #428 from twpayne/gc-optimizations

GC optimizations
This commit is contained in:
Tom Payne
2013-03-25 03:54:15 -07:00
13 changed files with 128 additions and 124 deletions

View File

@@ -155,22 +155,21 @@ ol.renderer.canvas.TileLayer.prototype.renderFrame =
tilesToDrawByZ, getTileIfLoaded);
var allTilesLoaded = true;
var tile, tileCoord, tileState, x, y;
var tile, tileState, x, y;
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
tileCoord = new ol.TileCoord(z, x, y);
tile = tileSource.getTile(tileCoord, tileGrid, projection);
tile = tileSource.getTile(z, x, y, tileGrid, projection);
tileState = tile.getState();
if (tileState == ol.TileState.LOADED || tileState == ol.TileState.EMPTY) {
tilesToDrawByZ[z][tileCoord.toString()] = tile;
tilesToDrawByZ[z][tile.tileCoord.toString()] = tile;
continue;
} else if (tileState == ol.TileState.ERROR) {
continue;
}
allTilesLoaded = false;
tileGrid.forEachTileCoordParentTileRange(tileCoord, findLoadedTiles);
tileGrid.forEachTileCoordParentTileRange(tile.tileCoord, findLoadedTiles);
}
}
@@ -191,9 +190,8 @@ ol.renderer.canvas.TileLayer.prototype.renderFrame =
if (currentZ == z) {
for (tileCoordKey in tilesToDraw) {
tile = tilesToDraw[tileCoordKey];
tileCoord = tile.tileCoord;
index = (tileCoord.y - tileRange.minY) * tileRangeWidth +
(tileCoord.x - tileRange.minX);
index = (tile.tileCoord.y - tileRange.minY) * tileRangeWidth +
(tile.tileCoord.x - tileRange.minX);
if (this.renderedTiles_[index] != tile) {
x = tileSize.width * (tile.tileCoord.x - tileRange.minX);
y = tileSize.height * (tileRange.maxY - tile.tileCoord.y);

View File

@@ -112,15 +112,14 @@ ol.renderer.dom.TileLayer.prototype.renderFrame =
tilesToDrawByZ, getTileIfLoaded);
var allTilesLoaded = true;
var tile, tileCoord, tileState, x, y;
var tile, tileState, x, y;
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
tileCoord = new ol.TileCoord(z, x, y);
tile = tileSource.getTile(tileCoord, tileGrid, projection);
tile = tileSource.getTile(z, x, y, tileGrid, projection);
tileState = tile.getState();
if (tileState == ol.TileState.LOADED) {
tilesToDrawByZ[z][tileCoord.toString()] = tile;
tilesToDrawByZ[z][tile.tileCoord.toString()] = tile;
continue;
} else if (tileState == ol.TileState.ERROR ||
tileState == ol.TileState.EMPTY) {
@@ -128,7 +127,7 @@ ol.renderer.dom.TileLayer.prototype.renderFrame =
}
allTilesLoaded = false;
tileGrid.forEachTileCoordParentTileRange(tileCoord, findLoadedTiles);
tileGrid.forEachTileCoordParentTileRange(tile.tileCoord, findLoadedTiles);
}

View File

@@ -9,7 +9,6 @@ goog.require('ol.Image');
goog.require('ol.ImageState');
goog.require('ol.Object');
goog.require('ol.Tile');
goog.require('ol.TileCoord');
goog.require('ol.TileRange');
goog.require('ol.TileState');
goog.require('ol.layer.Layer');
@@ -258,12 +257,13 @@ ol.renderer.Layer.prototype.updateUsedTiles =
* @param {ol.source.TileSource} tileSource Tile source.
* @param {ol.tilegrid.TileGrid} tileGrid Tile grid.
* @param {ol.Projection} projection Projection.
* @return {function(ol.TileCoord): ol.Tile} Returns a tile if it is loaded.
* @return {function(number, number, number): ol.Tile} Returns a tile if it is
* loaded.
*/
ol.renderer.Layer.prototype.createGetTileIfLoadedFunction =
function(isLoadedFunction, tileSource, tileGrid, projection) {
return function(tileCoord) {
var tile = tileSource.getTile(tileCoord, tileGrid, projection);
return function(z, x, y) {
var tile = tileSource.getTile(z, x, y, tileGrid, projection);
return isLoadedFunction(tile) ? tile : null;
};
};
@@ -307,7 +307,7 @@ ol.renderer.Layer.prototype.manageTilePyramid =
}
var wantedTiles = frameState.wantedTiles[tileSourceKey];
var tileQueue = frameState.tileQueue;
var tile, tileCenter, tileCoord, tileRange, tileResolution, x, y, z;
var tile, tileCenter, tileRange, tileResolution, x, y, z;
// FIXME this should loop up to tileGrid's minZ when implemented
for (z = currentZ; z >= 0; --z) {
tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z);
@@ -315,15 +315,14 @@ ol.renderer.Layer.prototype.manageTilePyramid =
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
if (ol.PREEMPTIVELY_LOAD_LOW_RESOLUTION_TILES || z == currentZ) {
tileCoord = new ol.TileCoord(z, x, y);
tile = tileSource.getTile(tileCoord, tileGrid, projection);
tile = tileSource.getTile(z, x, y, tileGrid, projection);
if (tile.getState() == ol.TileState.IDLE) {
tileCenter = tileGrid.getTileCoordCenter(tileCoord);
wantedTiles[tileCoord.toString()] = true;
tileCenter = tileGrid.getTileCoordCenter(tile.tileCoord);
wantedTiles[tile.tileCoord.toString()] = true;
tileQueue.enqueue(tile, tileSourceKey, tileCenter, tileResolution);
}
} else {
tileSource.useTile(z + '/' + x + '/' + y);
tileSource.useTile(z, x, y);
}
}
}

View File

@@ -12,7 +12,6 @@ goog.require('goog.webgl');
goog.require('ol.Extent');
goog.require('ol.Size');
goog.require('ol.Tile');
goog.require('ol.TileCoord');
goog.require('ol.TileRange');
goog.require('ol.TileState');
goog.require('ol.layer.TileLayer');
@@ -214,19 +213,18 @@ ol.renderer.webgl.TileLayer.prototype.renderFrame =
var tilesToLoad = new goog.structs.PriorityQueue();
var allTilesLoaded = true;
var deltaX, deltaY, priority, tile, tileCenter, tileCoord, tileState, x, y;
var deltaX, deltaY, priority, tile, tileCenter, tileState, x, y;
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
tileCoord = new ol.TileCoord(z, x, y);
tile = tileSource.getTile(tileCoord, tileGrid, projection);
tile = tileSource.getTile(z, x, y, tileGrid, projection);
tileState = tile.getState();
if (tileState == ol.TileState.LOADED) {
if (mapRenderer.isTileTextureLoaded(tile)) {
tilesToDrawByZ[z][tileCoord.toString()] = tile;
tilesToDrawByZ[z][tile.tileCoord.toString()] = tile;
continue;
} else {
tileCenter = tileGrid.getTileCoordCenter(tileCoord);
tileCenter = tileGrid.getTileCoordCenter(tile.tileCoord);
deltaX = tileCenter.x - center.x;
deltaY = tileCenter.y - center.y;
priority = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
@@ -238,7 +236,8 @@ ol.renderer.webgl.TileLayer.prototype.renderFrame =
}
allTilesLoaded = false;
tileGrid.forEachTileCoordParentTileRange(tileCoord, findLoadedTiles);
tileGrid.forEachTileCoordParentTileRange(
tile.tileCoord, findLoadedTiles);
}

View File

@@ -122,13 +122,13 @@ ol.source.DebugTileSource.prototype.expireCache = function(usedTiles) {
/**
* @inheritDoc
*/
ol.source.DebugTileSource.prototype.getTile = function(tileCoord) {
var key = tileCoord.toString();
if (this.tileCache_.containsKey(key)) {
return /** @type {!ol.DebugTile_} */ (this.tileCache_.get(key));
ol.source.DebugTileSource.prototype.getTile = function(z, x, y) {
var tileCoordKey = ol.TileCoord.getKeyZXY(z, x, y);
if (this.tileCache_.containsKey(tileCoordKey)) {
return /** @type {!ol.DebugTile_} */ (this.tileCache_.get(tileCoordKey));
} else {
var tile = new ol.DebugTile_(tileCoord, this.tileGrid);
this.tileCache_.set(key, tile);
var tile = new ol.DebugTile_(new ol.TileCoord(z, x, y), this.tileGrid);
this.tileCache_.set(tileCoordKey, tile);
return tile;
}
};

View File

@@ -7,6 +7,7 @@ goog.require('ol.ImageTile');
goog.require('ol.Projection');
goog.require('ol.Tile');
goog.require('ol.TileCache');
goog.require('ol.TileCoord');
goog.require('ol.TileState');
goog.require('ol.TileUrlFunction');
goog.require('ol.TileUrlFunctionType');
@@ -87,20 +88,21 @@ ol.source.ImageTileSource.prototype.expireCache = function(usedTiles) {
* @inheritDoc
*/
ol.source.ImageTileSource.prototype.getTile =
function(tileCoord, tileGrid, projection) {
var key = tileCoord.toString();
if (this.tileCache_.containsKey(key)) {
return /** @type {!ol.Tile} */ (this.tileCache_.get(key));
function(z, x, y, tileGrid, projection) {
var tileCoordKey = ol.TileCoord.getKeyZXY(z, x, y);
if (this.tileCache_.containsKey(tileCoordKey)) {
return /** @type {!ol.Tile} */ (this.tileCache_.get(tileCoordKey));
} else {
goog.asserts.assert(tileGrid);
goog.asserts.assert(projection);
var tileCoord = new ol.TileCoord(z, x, y);
var tileUrl = this.tileUrlFunction(tileCoord, tileGrid, projection);
var tile = new ol.ImageTile(
tileCoord,
goog.isDef(tileUrl) ? ol.TileState.IDLE : ol.TileState.EMPTY,
goog.isDef(tileUrl) ? tileUrl : '',
this.crossOrigin_);
this.tileCache_.set(key, tile);
this.tileCache_.set(tileCoordKey, tile);
return tile;
}
};
@@ -109,7 +111,8 @@ ol.source.ImageTileSource.prototype.getTile =
/**
* @inheritDoc
*/
ol.source.ImageTileSource.prototype.useTile = function(tileCoordKey) {
ol.source.ImageTileSource.prototype.useTile = function(z, x, y) {
var tileCoordKey = ol.TileCoord.getKeyZXY(z, x, y);
if (this.tileCache_.containsKey(tileCoordKey)) {
this.tileCache_.get(tileCoordKey);
}

View File

@@ -72,8 +72,8 @@ ol.source.TileSource.prototype.expireCache = goog.abstractMethod;
*
* @param {Object.<number, Object.<string, ol.Tile>>} loadedTilesByZ A lookup of
* loaded tiles by zoom level.
* @param {function(ol.TileCoord): ol.Tile} getTileIfLoaded A function that
* returns the tile only if it is fully loaded.
* @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.
* @return {boolean} The tile range is fully covered with loaded tiles.
@@ -82,15 +82,14 @@ ol.source.TileSource.prototype.findLoadedTiles = function(loadedTilesByZ,
getTileIfLoaded, z, tileRange) {
// FIXME this could be more efficient about filling partial holes
var fullyCovered = true;
var tile, tileCoord, tileCoordKey, x, y;
var tile, tileCoordKey, x, y;
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
tileCoord = new ol.TileCoord(z, x, y);
tileCoordKey = tileCoord.toString();
tileCoordKey = ol.TileCoord.getKeyZXY(z, x, y);
if (loadedTilesByZ[z] && loadedTilesByZ[z][tileCoordKey]) {
continue;
}
tile = getTileIfLoaded(tileCoord);
tile = getTileIfLoaded(z, x, y);
if (!goog.isNull(tile)) {
if (!loadedTilesByZ[z]) {
loadedTilesByZ[z] = {};
@@ -122,7 +121,9 @@ ol.source.TileSource.prototype.getResolutions = function() {
/**
* @param {ol.TileCoord} tileCoord Tile coordinate.
* @param {number} z Tile coordinate z.
* @param {number} x Tile coordinate x.
* @param {number} y Tile coordinate y.
* @param {ol.tilegrid.TileGrid=} opt_tileGrid Tile grid.
* @param {ol.Projection=} opt_projection Projection.
* @return {!ol.Tile} Tile.
@@ -140,6 +141,8 @@ ol.source.TileSource.prototype.getTileGrid = function() {
/**
* Marks a tile coord as being used, without triggering a load.
* @param {string} tileCoordKey Tile coordinate key.
* @param {number} z Tile coordinate z.
* @param {number} x Tile coordinate x.
* @param {number} y Tile coordinate y.
*/
ol.source.TileSource.prototype.useTile = goog.nullFunction;

View File

@@ -78,6 +78,17 @@ ol.TileCoord.createFromString = function(str) {
};
/**
* @param {number} z Z.
* @param {number} x X.
* @param {number} y Y.
* @return {string} Key.
*/
ol.TileCoord.getKeyZXY = function(z, x, y) {
return [z, x, y].join('/');
};
/**
* @return {number} Hash.
*/
@@ -112,5 +123,5 @@ ol.TileCoord.prototype.quadKey = function() {
* @return {string} String.
*/
ol.TileCoord.prototype.toString = function() {
return [this.z, this.x, this.y].join('/');
return ol.TileCoord.getKeyZXY(this.z, this.x, this.y);
};

View File

@@ -137,13 +137,12 @@ ol.tilegrid.TileGrid.prototype.getPixelBoundsForTileCoordAndResolution =
function(tileCoord, resolution) {
var scale = resolution / this.getResolution(tileCoord.z);
var tileSize = this.getTileSize(tileCoord.z);
tileSize = new ol.Size(tileSize.width / scale,
tileSize.height / scale);
var minX, maxX, minY, maxY;
minX = Math.round(tileCoord.x * tileSize.width);
maxX = Math.round((tileCoord.x + 1) * tileSize.width);
minY = Math.round(tileCoord.y * tileSize.height);
maxY = Math.round((tileCoord.y + 1) * tileSize.height);
var tileWidth = tileSize.width / scale;
var tileHeight = tileSize.height / scale;
var minX = Math.round(tileCoord.x * tileWidth);
var minY = Math.round(tileCoord.y * tileHeight);
var maxX = Math.round((tileCoord.x + 1) * tileWidth);
var maxY = Math.round((tileCoord.y + 1) * tileHeight);
return new ol.PixelBounds(minX, minY, maxX, maxY);
};
@@ -190,10 +189,10 @@ ol.tilegrid.TileGrid.prototype.getTileRangeExtent = function(z, tileRange) {
*/
ol.tilegrid.TileGrid.prototype.getTileRangeForExtentAndResolution = function(
extent, resolution) {
var min = this.getTileCoordForCoordAndResolution_(
new ol.Coordinate(extent.minX, extent.minY), resolution);
var max = this.getTileCoordForCoordAndResolution_(
new ol.Coordinate(extent.maxX, extent.maxY), resolution, true);
var min = this.getTileCoordForXYAndResolution_(
extent.minX, extent.minY, resolution, false);
var max = this.getTileCoordForXYAndResolution_(
extent.maxX, extent.maxY, resolution, true);
return new ol.TileRange(min.x, min.y, max.x, max.y);
};
@@ -250,38 +249,40 @@ ol.tilegrid.TileGrid.prototype.getTileCoordExtent = function(tileCoord) {
*/
ol.tilegrid.TileGrid.prototype.getTileCoordForCoordAndResolution = function(
coordinate, resolution) {
return this.getTileCoordForCoordAndResolution_(coordinate, resolution);
return this.getTileCoordForXYAndResolution_(
coordinate.x, coordinate.y, resolution, false);
};
/**
* @param {ol.Coordinate} coordinate Coordinate.
* @param {number} x X.
* @param {number} y Y.
* @param {number} resolution Resolution.
* @param {boolean=} opt_reverseIntersectionPolicy Instead of letting edge
* @param {boolean} reverseIntersectionPolicy Instead of letting edge
* intersections go to the higher tile coordinate, let edge intersections
* go to the lower tile coordinate.
* @return {ol.TileCoord} Tile coordinate.
* @private
*/
ol.tilegrid.TileGrid.prototype.getTileCoordForCoordAndResolution_ = function(
coordinate, resolution, opt_reverseIntersectionPolicy) {
ol.tilegrid.TileGrid.prototype.getTileCoordForXYAndResolution_ = function(
x, y, resolution, reverseIntersectionPolicy) {
var z = this.getZForResolution(resolution);
var scale = resolution / this.getResolution(z);
var origin = this.getOrigin(z);
var tileSize = this.getTileSize(z);
var x = scale * (coordinate.x - origin.x) / (resolution * tileSize.width);
var y = scale * (coordinate.y - origin.y) / (resolution * tileSize.height);
var tileCoordX = scale * (x - origin.x) / (resolution * tileSize.width);
var tileCoordY = scale * (y - origin.y) / (resolution * tileSize.height);
if (!opt_reverseIntersectionPolicy) {
x = Math.floor(x);
y = Math.floor(y);
if (reverseIntersectionPolicy) {
tileCoordX = Math.ceil(tileCoordX) - 1;
tileCoordY = Math.ceil(tileCoordY) - 1;
} else {
x = Math.ceil(x) - 1;
y = Math.ceil(y) - 1;
tileCoordX = Math.floor(tileCoordX);
tileCoordY = Math.floor(tileCoordY);
}
return new ol.TileCoord(z, x, y);
return new ol.TileCoord(z, tileCoordX, tileCoordY);
};
@@ -293,7 +294,8 @@ ol.tilegrid.TileGrid.prototype.getTileCoordForCoordAndResolution_ = function(
ol.tilegrid.TileGrid.prototype.getTileCoordForCoordAndZ =
function(coordinate, z) {
var resolution = this.getResolution(z);
return this.getTileCoordForCoordAndResolution_(coordinate, resolution);
return this.getTileCoordForXYAndResolution_(
coordinate.x, coordinate.y, resolution, false);
};

View File

@@ -39,18 +39,11 @@ goog.inherits(ol.tilegrid.XYZ, ol.tilegrid.TileGrid);
*/
ol.tilegrid.XYZ.prototype.forEachTileCoordParentTileRange =
function(tileCoord, callback, opt_obj) {
var x = tileCoord.x;
var y = tileCoord.y;
var z = tileCoord.z;
var tileRange;
while (true) {
z -= 1;
if (z < 0) {
break;
}
x >>= 1;
y >>= 1;
tileRange = new ol.TileRange(x, y, x, y);
var tileRange = new ol.TileRange(0, 0, tileCoord.x, tileCoord.y);
var z;
for (z = tileCoord.z - 1; z >= 0; --z) {
tileRange.minX = tileRange.maxX >>= 1;
tileRange.minY = tileRange.maxY >>= 1;
if (callback.call(opt_obj, z, tileRange)) {
break;
}