Add interim tiles handling

This commit is contained in:
Andreas Hocevar
2021-07-27 00:36:18 +02:00
parent fd43b00118
commit 311247265b
2 changed files with 62 additions and 20 deletions
+32 -8
View File
@@ -160,6 +160,22 @@ class WebGLTileLayerRenderer extends WebGLLayerRenderer {
this.renderedOpacity_ = NaN; this.renderedOpacity_ = NaN;
} }
/**
* @protected
* @param {import("../../Tile.js").default} tile Tile.
* @return {boolean} Tile is drawable.
*/
isDrawableTile(tile) {
const tileLayer = this.getLayer();
const tileState = tile.getState();
const useInterimTilesOnError = tileLayer.getUseInterimTilesOnError();
return (
tileState == TileState.LOADED ||
tileState == TileState.EMPTY ||
(tileState == TileState.ERROR && !useInterimTilesOnError)
);
}
/** /**
* Determine whether render should be called. * Determine whether render should be called.
* @param {import("../../PluggableMap.js").FrameState} frameState Frame state. * @param {import("../../PluggableMap.js").FrameState} frameState Frame state.
@@ -222,30 +238,38 @@ class WebGLTileLayerRenderer extends WebGLLayerRenderer {
const tileCoord = createTileCoord(z, x, y, this.tempTileCoord_); const tileCoord = createTileCoord(z, x, y, this.tempTileCoord_);
const tileCoordKey = getTileCoordKey(tileCoord); const tileCoordKey = getTileCoordKey(tileCoord);
let tileTexture; let tileTexture, tile;
if (tileTextureCache.containsKey(tileCoordKey)) { if (tileTextureCache.containsKey(tileCoordKey)) {
tileTexture = tileTextureCache.get(tileCoordKey); tileTexture = tileTextureCache.get(tileCoordKey);
} else { tile = tileTexture.tile;
const tile = tileSource.getTile( }
if (!tileTexture || tileTexture.tile.key !== tileSource.getKey()) {
tile = tileSource.getTile(
z, z,
x, x,
y, y,
frameState.pixelRatio, frameState.pixelRatio,
viewState.projection viewState.projection
); );
tileTexture = new TileTexture(tile, tileGrid, this.helper); if (!tileTexture) {
tileTextureCache.set(tileCoordKey, tileTexture); tileTexture = new TileTexture(tile, tileGrid, this.helper);
tileTextureCache.set(tileCoordKey, tileTexture);
} else {
tileTexture.setTile(
this.isDrawableTile(tile) ? tile : tile.getInterimTile()
);
}
} }
addTileTextureToLookup(tileTexturesByZ, tileTexture, z); addTileTextureToLookup(tileTexturesByZ, tileTexture, z);
const tileQueueKey = tileTexture.tile.getKey(); const tileQueueKey = tile.getKey();
wantedTiles[tileQueueKey] = true; wantedTiles[tileQueueKey] = true;
if (tileTexture.tile.getState() === TileState.IDLE) { if (tile.getState() === TileState.IDLE) {
if (!frameState.tileQueue.isKeyQueued(tileQueueKey)) { if (!frameState.tileQueue.isKeyQueued(tileQueueKey)) {
frameState.tileQueue.enqueue([ frameState.tileQueue.enqueue([
tileTexture.tile, tile,
tileSourceKey, tileSourceKey,
tileGrid.getTileCoordCenter(tileCoord), tileGrid.getTileCoordCenter(tileCoord),
tileResolution, tileResolution,
+30 -12
View File
@@ -83,14 +83,24 @@ class TileTexture extends EventTarget {
constructor(tile, grid, helper) { constructor(tile, grid, helper) {
super(); super();
this.tile = tile; /**
* @type {import("../DataTile.js").default|import("../ImageTile.js").default}
*/
this.tile;
/**
* @type {Array<WebGLTexture>}
*/
this.textures = [];
this.handleTileChange_ = this.handleTileChange_.bind(this);
this.setTile(tile);
this.size = toSize(grid.getTileSize(tile.tileCoord[0])); this.size = toSize(grid.getTileSize(tile.tileCoord[0]));
this.loaded = tile.getState() === TileState.LOADED;
this.bandCount = NaN; this.bandCount = NaN;
this.helper_ = helper; this.helper_ = helper;
this.handleTileChange_ = this.handleTileChange_.bind(this);
const coords = new WebGLArrayBuffer(ARRAY_BUFFER, STATIC_DRAW); const coords = new WebGLArrayBuffer(ARRAY_BUFFER, STATIC_DRAW);
coords.fromArray([ coords.fromArray([
@@ -105,16 +115,24 @@ class TileTexture extends EventTarget {
]); ]);
helper.flushBufferData(coords); helper.flushBufferData(coords);
this.coords = coords; this.coords = coords;
}
/** /**
* @type {Array<WebGLTexture>} * @param {import("../DataTile.js").default|import("../ImageTile.js").default} tile Tile.
*/ */
this.textures = []; setTile(tile) {
if (tile !== this.tile) {
if (this.loaded) { if (this.tile) {
this.uploadTile_(); this.tile.removeEventListener(EventType.CHANGE, this.handleTileChange_);
} else { }
tile.addEventListener(EventType.CHANGE, this.handleTileChange_); this.tile = tile;
this.textures.length = 0;
this.loaded = tile.getState() === TileState.LOADED;
if (this.loaded) {
this.uploadTile_();
} else {
tile.addEventListener(EventType.CHANGE, this.handleTileChange_);
}
} }
} }