Merge pull request #498 from twpayne/boost-tile-loading
Boost tile loading
This commit is contained in:
+25
-23
@@ -83,18 +83,6 @@ ol.ENABLE_DOM = true;
|
|||||||
ol.ENABLE_WEBGL = true;
|
ol.ENABLE_WEBGL = true;
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @define {number} Maximum number of simultaneously loading tiles.
|
|
||||||
*/
|
|
||||||
ol.MAXIMUM_TILES_LOADING = 8;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @define {number} Maximum new tile loads per frame.
|
|
||||||
*/
|
|
||||||
ol.MAXIMUM_NEW_TILE_LOADS_PER_FRAME = 2;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum {string}
|
* @enum {string}
|
||||||
*/
|
*/
|
||||||
@@ -304,7 +292,6 @@ ol.Map = function(options) {
|
|||||||
* @type {ol.TileQueue}
|
* @type {ol.TileQueue}
|
||||||
*/
|
*/
|
||||||
this.tileQueue_ = new ol.TileQueue(
|
this.tileQueue_ = new ol.TileQueue(
|
||||||
ol.MAXIMUM_TILES_LOADING,
|
|
||||||
goog.bind(this.getTilePriority, this),
|
goog.bind(this.getTilePriority, this),
|
||||||
goog.bind(this.handleTileChange_, this));
|
goog.bind(this.handleTileChange_, this));
|
||||||
|
|
||||||
@@ -587,23 +574,38 @@ ol.Map.prototype.handleMapBrowserEvent = function(mapBrowserEvent) {
|
|||||||
*/
|
*/
|
||||||
ol.Map.prototype.handlePostRender = function() {
|
ol.Map.prototype.handlePostRender = function() {
|
||||||
|
|
||||||
// Limit the number of tile loads if animating or interacting.
|
|
||||||
var limit = (1 << 30) - 1; // a large enough integer
|
|
||||||
var frameState = this.frameState_;
|
var frameState = this.frameState_;
|
||||||
if (!goog.isNull(frameState)) {
|
|
||||||
var hints = frameState.viewHints;
|
// Manage the tile queue
|
||||||
if (hints[ol.ViewHint.ANIMATING] || hints[ol.ViewHint.INTERACTING]) {
|
// Image loads are expensive and a limited resource, so try to use them
|
||||||
limit = ol.MAXIMUM_NEW_TILE_LOADS_PER_FRAME;
|
// efficiently:
|
||||||
|
// * When the view is static we allow a large number of parallel tile loads
|
||||||
|
// to complete the frame as quickly as possible.
|
||||||
|
// * When animating or interacting, image loads can cause janks, so we reduce
|
||||||
|
// the maximum number of loads per frame and limit the number of parallel
|
||||||
|
// tile loads to remain reactive to view changes and to reduce the chance of
|
||||||
|
// loading tiles that will quickly disappear from view.
|
||||||
|
var tileQueue = this.tileQueue_;
|
||||||
|
if (!tileQueue.isEmpty()) {
|
||||||
|
var maxTotalLoading = 16;
|
||||||
|
var maxNewLoads = maxTotalLoading;
|
||||||
|
if (!goog.isNull(frameState)) {
|
||||||
|
var hints = frameState.viewHints;
|
||||||
|
if (hints[ol.ViewHint.ANIMATING] || hints[ol.ViewHint.INTERACTING]) {
|
||||||
|
maxTotalLoading = 8;
|
||||||
|
maxNewLoads = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tileQueue.getTilesLoading() < maxTotalLoading) {
|
||||||
|
tileQueue.reprioritize(); // FIXME only call if view has changed
|
||||||
|
tileQueue.loadMoreTiles(maxTotalLoading, maxNewLoads);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.tileQueue_.reprioritize(); // FIXME only call if needed
|
|
||||||
this.tileQueue_.loadMoreTiles(limit);
|
|
||||||
|
|
||||||
var postRenderFunctions = this.postRenderFunctions_;
|
var postRenderFunctions = this.postRenderFunctions_;
|
||||||
var i;
|
var i;
|
||||||
for (i = 0; i < postRenderFunctions.length; ++i) {
|
for (i = 0; i < postRenderFunctions.length; ++i) {
|
||||||
postRenderFunctions[i](this, this.frameState_);
|
postRenderFunctions[i](this, frameState);
|
||||||
}
|
}
|
||||||
postRenderFunctions.length = 0;
|
postRenderFunctions.length = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
+19
-18
@@ -1,6 +1,7 @@
|
|||||||
goog.provide('ol.TilePriorityFunction');
|
goog.provide('ol.TilePriorityFunction');
|
||||||
goog.provide('ol.TileQueue');
|
goog.provide('ol.TileQueue');
|
||||||
|
|
||||||
|
goog.require('goog.asserts');
|
||||||
goog.require('goog.events');
|
goog.require('goog.events');
|
||||||
goog.require('goog.events.EventType');
|
goog.require('goog.events.EventType');
|
||||||
goog.require('ol.Coordinate');
|
goog.require('ol.Coordinate');
|
||||||
@@ -18,15 +19,12 @@ ol.TilePriorityFunction;
|
|||||||
/**
|
/**
|
||||||
* @constructor
|
* @constructor
|
||||||
* @extends {ol.structs.PriorityQueue}
|
* @extends {ol.structs.PriorityQueue}
|
||||||
* @param {number} maxTilesLoading Maximum number of simultaneously loading
|
|
||||||
* tiles.
|
|
||||||
* @param {ol.TilePriorityFunction} tilePriorityFunction
|
* @param {ol.TilePriorityFunction} tilePriorityFunction
|
||||||
* Tile priority function.
|
* Tile priority function.
|
||||||
* @param {Function} tileChangeCallback
|
* @param {Function} tileChangeCallback
|
||||||
* Function called on each tile change event.
|
* Function called on each tile change event.
|
||||||
*/
|
*/
|
||||||
ol.TileQueue =
|
ol.TileQueue = function(tilePriorityFunction, tileChangeCallback) {
|
||||||
function(maxTilesLoading, tilePriorityFunction, tileChangeCallback) {
|
|
||||||
|
|
||||||
goog.base(
|
goog.base(
|
||||||
this,
|
this,
|
||||||
@@ -51,12 +49,6 @@ ol.TileQueue =
|
|||||||
*/
|
*/
|
||||||
this.tileChangeCallback_ = tileChangeCallback;
|
this.tileChangeCallback_ = tileChangeCallback;
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {number}
|
|
||||||
*/
|
|
||||||
this.maxTilesLoading_ = maxTilesLoading;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @type {number}
|
* @type {number}
|
||||||
@@ -67,6 +59,14 @@ ol.TileQueue =
|
|||||||
goog.inherits(ol.TileQueue, ol.structs.PriorityQueue);
|
goog.inherits(ol.TileQueue, ol.structs.PriorityQueue);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {number} Number of tiles loading.
|
||||||
|
*/
|
||||||
|
ol.TileQueue.prototype.getTilesLoading = function() {
|
||||||
|
return this.tilesLoading_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @protected
|
* @protected
|
||||||
*/
|
*/
|
||||||
@@ -77,18 +77,19 @@ ol.TileQueue.prototype.handleTileChange = function() {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {number} limit Maximum number of new tiles to load.
|
* @param {number} maxTotalLoading Maximum number tiles to load simultaneously.
|
||||||
|
* @param {number} maxNewLoads Maximum number of new tiles to load.
|
||||||
*/
|
*/
|
||||||
ol.TileQueue.prototype.loadMoreTiles = function(limit) {
|
ol.TileQueue.prototype.loadMoreTiles = function(maxTotalLoading, maxNewLoads) {
|
||||||
var tile;
|
var newLoads = Math.min(
|
||||||
while (limit > 0 &&
|
maxTotalLoading - this.getTilesLoading(), maxNewLoads, this.getCount());
|
||||||
!this.isEmpty() &&
|
goog.asserts.assert(newLoads > 0);
|
||||||
this.tilesLoading_ < this.maxTilesLoading_) {
|
var i, tile;
|
||||||
|
for (i = 0; i < newLoads; ++i) {
|
||||||
tile = /** @type {ol.Tile} */ (this.dequeue()[0]);
|
tile = /** @type {ol.Tile} */ (this.dequeue()[0]);
|
||||||
goog.events.listenOnce(tile, goog.events.EventType.CHANGE,
|
goog.events.listenOnce(tile, goog.events.EventType.CHANGE,
|
||||||
this.handleTileChange, false, this);
|
this.handleTileChange, false, this);
|
||||||
tile.load();
|
tile.load();
|
||||||
++this.tilesLoading_;
|
|
||||||
--limit;
|
|
||||||
}
|
}
|
||||||
|
this.tilesLoading_ += newLoads;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user