Rework tile image render queue
This commit is contained in:
@@ -146,8 +146,11 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
|
|||||||
* @param {import("../../VectorRenderTile.js").default} tile Tile.
|
* @param {import("../../VectorRenderTile.js").default} tile Tile.
|
||||||
* @param {number} pixelRatio Pixel ratio.
|
* @param {number} pixelRatio Pixel ratio.
|
||||||
* @param {import("../../proj/Projection").default} projection Projection.
|
* @param {import("../../proj/Projection").default} projection Projection.
|
||||||
|
* @param {boolean} queue Queue tile for rendering.
|
||||||
|
* @return {boolean} Tile needs to be rendered.
|
||||||
*/
|
*/
|
||||||
prepareTile(tile, pixelRatio, projection) {
|
prepareTile(tile, pixelRatio, projection, queue) {
|
||||||
|
let render = false;
|
||||||
const tileUid = getUid(tile);
|
const tileUid = getUid(tile);
|
||||||
const state = tile.getState();
|
const state = tile.getState();
|
||||||
if (((state === TileState.LOADED && tile.hifi) ||
|
if (((state === TileState.LOADED && tile.hifi) ||
|
||||||
@@ -159,9 +162,13 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
|
|||||||
if (state === TileState.LOADED || state === TileState.ERROR) {
|
if (state === TileState.LOADED || state === TileState.ERROR) {
|
||||||
this.updateExecutorGroup_(tile, pixelRatio, projection);
|
this.updateExecutorGroup_(tile, pixelRatio, projection);
|
||||||
if (this.tileImageNeedsRender_(tile, pixelRatio, projection)) {
|
if (this.tileImageNeedsRender_(tile, pixelRatio, projection)) {
|
||||||
this.renderTileImageQueue_[tileUid] = tile;
|
render = true;
|
||||||
|
if (queue) {
|
||||||
|
this.renderTileImageQueue_[tileUid] = tile;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return render;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -177,7 +184,7 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
|
|||||||
tile.wantedResolution = resolution;
|
tile.wantedResolution = resolution;
|
||||||
const tileUid = getUid(tile);
|
const tileUid = getUid(tile);
|
||||||
if (!(tileUid in this.tileListenerKeys_)) {
|
if (!(tileUid in this.tileListenerKeys_)) {
|
||||||
const listenerKey = listen(tile, EventType.CHANGE, this.prepareTile.bind(this, tile, pixelRatio, projection));
|
const listenerKey = listen(tile, EventType.CHANGE, this.prepareTile.bind(this, tile, pixelRatio, projection, true));
|
||||||
this.tileListenerKeys_[tileUid] = listenerKey;
|
this.tileListenerKeys_[tileUid] = listenerKey;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -186,7 +193,10 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
|
|||||||
if (hifi || !tile.wantedResolution) {
|
if (hifi || !tile.wantedResolution) {
|
||||||
tile.wantedResolution = resolution;
|
tile.wantedResolution = resolution;
|
||||||
}
|
}
|
||||||
this.prepareTile(tile, pixelRatio, projection);
|
const render = this.prepareTile(tile, pixelRatio, projection, false);
|
||||||
|
if (render) {
|
||||||
|
this.renderTileImage_(tile, frameState);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return tile;
|
return tile;
|
||||||
}
|
}
|
||||||
@@ -383,20 +393,27 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
|
|||||||
renderFrame(frameState, layerState, target) {
|
renderFrame(frameState, layerState, target) {
|
||||||
const viewHints = frameState.viewHints;
|
const viewHints = frameState.viewHints;
|
||||||
const hifi = !(viewHints[ViewHint.ANIMATING] || viewHints[ViewHint.INTERACTING]);
|
const hifi = !(viewHints[ViewHint.ANIMATING] || viewHints[ViewHint.INTERACTING]);
|
||||||
this.renderTileImages_(hifi, frameState);
|
this.renderQueuedTileImages_(hifi, frameState);
|
||||||
|
|
||||||
super.renderFrame(frameState, layerState, target);
|
super.renderFrame(frameState, layerState, target);
|
||||||
|
|
||||||
const layer = /** @type {import("../../layer/VectorTile.js").default} */ (this.getLayer());
|
const layer = /** @type {import("../../layer/VectorTile.js").default} */ (this.getLayer());
|
||||||
const renderMode = layer.getRenderMode();
|
const renderMode = layer.getRenderMode();
|
||||||
|
|
||||||
if (renderMode === VectorTileRenderType.IMAGE) {
|
if (renderMode === VectorTileRenderType.IMAGE) {
|
||||||
return this.container;
|
return this.container;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const source = layer.getSource();
|
||||||
|
// Unqueue tiles from the image queue when we don't need any more
|
||||||
|
const usedTiles = frameState.usedTiles[getUid(source)];
|
||||||
|
for (const tileUid in this.renderTileImageQueue_) {
|
||||||
|
if (!(tileUid in usedTiles)) {
|
||||||
|
delete this.renderTileImageQueue_[tileUid];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const context = this.overlayContext_;
|
const context = this.overlayContext_;
|
||||||
const declutterReplays = layer.getDeclutter() ? {} : null;
|
const declutterReplays = layer.getDeclutter() ? {} : null;
|
||||||
const source = layer.getSource();
|
|
||||||
const replayTypes = VECTOR_REPLAYS[renderMode];
|
const replayTypes = VECTOR_REPLAYS[renderMode];
|
||||||
const pixelRatio = frameState.pixelRatio;
|
const pixelRatio = frameState.pixelRatio;
|
||||||
const rotation = frameState.viewState.rotation;
|
const rotation = frameState.viewState.rotation;
|
||||||
@@ -488,16 +505,17 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
|
|||||||
* @param {boolean} hifi We have time to render a high fidelity map image.
|
* @param {boolean} hifi We have time to render a high fidelity map image.
|
||||||
* @param {import('../../PluggableMap.js').FrameState} frameState Frame state.
|
* @param {import('../../PluggableMap.js').FrameState} frameState Frame state.
|
||||||
*/
|
*/
|
||||||
renderTileImages_(hifi, frameState) {
|
renderQueuedTileImages_(hifi, frameState) {
|
||||||
|
// When we don't have time to render hifi, only render tiles until we have used up
|
||||||
|
// half of the frame budget of 16 ms
|
||||||
for (const uid in this.renderTileImageQueue_) {
|
for (const uid in this.renderTileImageQueue_) {
|
||||||
|
if (!hifi && Date.now() - frameState.time > 8) {
|
||||||
|
frameState.animate = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
const tile = this.renderTileImageQueue_[uid];
|
const tile = this.renderTileImageQueue_[uid];
|
||||||
delete this.renderTileImageQueue_[uid];
|
delete this.renderTileImageQueue_[uid];
|
||||||
const layer = /** @type {import("../../layer/VectorTile.js").default} */ (this.getLayer());
|
this.renderTileImage_(tile, frameState);
|
||||||
const viewState = frameState.viewState;
|
|
||||||
const tileGrid = layer.getSource().getTileGridForProjection(viewState.projection);
|
|
||||||
const tileResolution = tileGrid.getResolution(tile.tileCoord[0]);
|
|
||||||
const renderPixelRatio = frameState.pixelRatio / tile.wantedResolution * tileResolution;
|
|
||||||
this.renderTileImage_(tile, frameState.pixelRatio, renderPixelRatio, viewState.projection);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -545,24 +563,29 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {import("../../VectorRenderTile.js").default} tile Tile.
|
* @param {import("../../VectorRenderTile.js").default} tile Tile.
|
||||||
* @param {number} pixelRatio Pixel ratio.
|
* @param {import("../../PluggableMap").FrameState} frameState Frame state.
|
||||||
* @param {number} renderPixelRatio Render pixel ratio.
|
|
||||||
* @param {import("../../proj/Projection.js").default} projection Projection.
|
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
renderTileImage_(tile, pixelRatio, renderPixelRatio, projection) {
|
renderTileImage_(tile, frameState) {
|
||||||
const layer = /** @type {import("../../layer/VectorTile.js").default} */ (this.getLayer());
|
const layer = /** @type {import("../../layer/VectorTile.js").default} */ (this.getLayer());
|
||||||
const replayState = tile.getReplayState(layer);
|
const replayState = tile.getReplayState(layer);
|
||||||
const revision = layer.getRevision();
|
const revision = layer.getRevision();
|
||||||
const executorGroups = tile.executorGroups[getUid(layer)];
|
const executorGroups = tile.executorGroups[getUid(layer)];
|
||||||
replayState.renderedTileRevision = revision;
|
replayState.renderedTileRevision = revision;
|
||||||
replayState.renderedTileZ = tile.sourceZ;
|
replayState.renderedTileZ = tile.sourceZ;
|
||||||
|
|
||||||
const tileCoord = tile.wrappedTileCoord;
|
const tileCoord = tile.wrappedTileCoord;
|
||||||
const z = tileCoord[0];
|
const z = tileCoord[0];
|
||||||
const source = layer.getSource();
|
const source = layer.getSource();
|
||||||
|
let pixelRatio = frameState.pixelRatio;
|
||||||
|
const viewState = frameState.viewState;
|
||||||
|
const projection = viewState.projection;
|
||||||
const tileGrid = source.getTileGridForProjection(projection);
|
const tileGrid = source.getTileGridForProjection(projection);
|
||||||
|
const tileResolution = tileGrid.getResolution(tile.tileCoord[0]);
|
||||||
|
const renderPixelRatio = frameState.pixelRatio / tile.wantedResolution * tileResolution;
|
||||||
const resolution = tileGrid.getResolution(z);
|
const resolution = tileGrid.getResolution(z);
|
||||||
const context = tile.getContext(layer);
|
const context = tile.getContext(layer);
|
||||||
|
|
||||||
// Increase tile size when overzooming for low pixel ratio, to avoid blurry tiles
|
// Increase tile size when overzooming for low pixel ratio, to avoid blurry tiles
|
||||||
pixelRatio = Math.max(pixelRatio, renderPixelRatio / pixelRatio);
|
pixelRatio = Math.max(pixelRatio, renderPixelRatio / pixelRatio);
|
||||||
const size = source.getTilePixelSize(z, pixelRatio, projection);
|
const size = source.getTilePixelSize(z, pixelRatio, projection);
|
||||||
|
|||||||
Reference in New Issue
Block a user