From cd2b01c02395dc5b91cc0d575681a1c5e86be812 Mon Sep 17 00:00:00 2001 From: Stepan Kuzmin Date: Fri, 28 Apr 2023 18:09:35 +0300 Subject: [PATCH] Don't retain children raster tiles --- src/render/draw_raster.js | 7 ++++--- src/source/source_cache.js | 4 ++-- src/source/tile.js | 28 ++++++++++++++++++---------- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/render/draw_raster.js b/src/render/draw_raster.js index 808f83c6111..4e01e2856d8 100644 --- a/src/render/draw_raster.js +++ b/src/render/draw_raster.js @@ -33,18 +33,20 @@ function drawRaster(painter: Painter, sourceCache: SourceCache, layer: RasterSty const [stencilModes, coords] = source instanceof ImageSource || renderingToTexture ? [{}, tileIDs] : painter.stencilConfigForOverlap(tileIDs); + const rasterFadeDuration = isInitialLoad ? 0 : layer.paint.get('raster-fade-duration'); const minTileZ = coords[coords.length - 1].overscaledZ; const align = !painter.options.moving; for (const coord of coords) { + const tile = sourceCache.getTile(coord); + if (renderingToTexture && !(tile && tile.hasData())) continue; + // Set the lower zoom level to sublayer 0, and higher zoom levels to higher sublayers // Use gl.LESS to prevent double drawing in areas where tiles overlap. const depthMode = renderingToTexture ? DepthMode.disabled : painter.depthModeForSublayer(coord.overscaledZ - minTileZ, layer.paint.get('raster-opacity') === 1 ? DepthMode.ReadWrite : DepthMode.ReadOnly, gl.LESS); const unwrappedTileID = coord.toUnwrapped(); - const tile = sourceCache.getTile(coord); - if (renderingToTexture && !(tile && tile.hasData())) continue; const projMatrix = (renderingToTexture) ? coord.projMatrix : painter.transform.calculateProjMatrix(unwrappedTileID, align); @@ -53,7 +55,6 @@ function drawRaster(painter: Painter, sourceCache: SourceCache, layer: RasterSty painter.terrain.stencilModeForRTTOverlap(coord) : stencilModes[coord.overscaledZ]; - const rasterFadeDuration = isInitialLoad ? 0 : layer.paint.get('raster-fade-duration'); tile.registerFadeDuration(rasterFadeDuration); const parentTile = sourceCache.findLoadedParent(coord, 0); diff --git a/src/source/source_cache.js b/src/source/source_cache.js index a1afffb650c..7a756c11430 100644 --- a/src/source/source_cache.js +++ b/src/source/source_cache.js @@ -542,7 +542,7 @@ class SourceCache extends Evented { assert(tileID.key === +id); const tile = this._tiles[id]; - if (!tile || (tile.fadeEndTime && tile.fadeEndTime <= browser.now())) continue; + if (!tile || tile.fadeFinished()) continue; // if the tile is loaded but still fading in, find parents to cross-fade with it const parentTile = this.findLoadedParent(tileID, Math.max(tileID.overscaledZ - SourceCache.maxOverzooming, this._source.minzoom)); @@ -925,7 +925,7 @@ class SourceCache extends Evented { if (isRasterType(this._source.type)) { for (const id in this._tiles) { const tile = this._tiles[id]; - if (tile.fadeEndTime !== undefined && tile.fadeEndTime >= browser.now()) { + if (!tile.fadeFinished()) { return true; } } diff --git a/src/source/tile.js b/src/source/tile.js index bcafa476bba..6b00a13e438 100644 --- a/src/source/tile.js +++ b/src/source/tile.js @@ -107,11 +107,11 @@ class Tile { lineAtlasTexture: Texture; glyphAtlasImage: ?AlphaImage; glyphAtlasTexture: Texture; - expirationTime: any; + expirationTime: ?number; expiredRequestCount: number; state: TileState; - timeAdded: any; - fadeEndTime: any; + timeAdded: number; + fadeEndTime: number; collisionBoxArray: ?CollisionBoxArray; redoWhenDone: boolean; showCollisionBoxes: boolean; @@ -162,7 +162,7 @@ class Tile { * @param size * @private */ - constructor(tileID: OverscaledTileID, size: number, tileZoom: number, painter: any, isRaster?: boolean) { + constructor(tileID: OverscaledTileID, size: number, tileZoom: number, painter: ?Painter, isRaster?: boolean) { this.tileID = tileID; this.uid = uniqueId(); this.uses = 0; @@ -197,6 +197,10 @@ class Tile { this.fadeEndTime = fadeEndTime; } + fadeFinished(): boolean { + return !this.fadeEndTime || this.fadeEndTime < browser.now(); + } + wasRequested(): boolean { return this.state === 'errored' || this.state === 'loaded' || this.state === 'reloading'; } @@ -218,7 +222,7 @@ class Tile { * @returns {undefined} * @private */ - loadVectorData(data: ?WorkerTileResult, painter: any, justReloaded: ?boolean) { + loadVectorData(data: ?WorkerTileResult, painter: Painter, justReloaded: ?boolean) { this.unloadVectorData(); this.state = 'loaded'; @@ -275,7 +279,10 @@ class Tile { this.queryPadding = 0; for (const id in this.buckets) { const bucket = this.buckets[id]; - this.queryPadding = Math.max(this.queryPadding, painter.style.getLayer(id).queryRadius(bucket)); + const layer = painter.style.getLayer(id); + this.queryPadding = layer ? + Math.max(this.queryPadding, layer.queryRadius(bucket)) : + this.queryPadding; } if (data.imageAtlas) { @@ -495,21 +502,22 @@ class Tile { this.expirationTime = new Date(data.expires).getTime(); } - if (this.expirationTime) { + const expirationTime = this.expirationTime; + if (expirationTime) { const now = Date.now(); let isExpired = false; - if (this.expirationTime > now) { + if (expirationTime > now) { isExpired = false; } else if (!prior) { isExpired = true; - } else if (this.expirationTime < prior) { + } else if (expirationTime < prior) { // Expiring date is going backwards: // fall back to exponential backoff isExpired = true; } else { - const delta = this.expirationTime - prior; + const delta = expirationTime - prior; if (!delta) { // Server is serving the same expired resource over and over: fall