From 8016d212a0e5ce976bfccc93b2683ae2e3c992c2 Mon Sep 17 00:00:00 2001 From: Ansis Brammanis Date: Wed, 22 Nov 2017 11:43:22 -0500 Subject: [PATCH] skip symbol fading for tiles immediately after reload The new symbol fading was causing flickering for symbols animated with `setData`. When the new location of the symbol was far enough away from the old it would not identify them as being the same icon, resulting in fading. Solving this properly would include figuring out a good way to fix this matching problem. Instead, this commit works around the problem by skipping fading for any tiles that have just been reloaded. --- src/source/tile.js | 9 ++++++++- src/symbol/symbol_placement.js | 12 +++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/source/tile.js b/src/source/tile.js index c2434a36395..166b5274eb4 100644 --- a/src/source/tile.js +++ b/src/source/tile.js @@ -81,6 +81,7 @@ class Tile { texture: any; refreshedUponExpiration: boolean; reloadCallback: any; + justReloaded: boolean; /** * @param {TileCoord} coord @@ -169,6 +170,10 @@ class Tile { * @private */ unloadVectorData() { + if (this.state === 'reloading') { + this.justReloaded = true; + } + for (const id in this.buckets) { this.buckets[id].destroy(); } @@ -225,7 +230,7 @@ class Tile { for (const id in this.buckets) { const bucket = this.buckets[id]; if (bucket instanceof SymbolBucket) { - updateOpacities(bucket, collisionFadeTimes); + updateOpacities(bucket, collisionFadeTimes, this.justReloaded); bucket.sortFeatures(angle); } } @@ -235,6 +240,8 @@ class Tile { if (this.featureIndex) { this.featureIndex.setCollisionIndex(collisionIndex); } + + this.justReloaded = false; } getBucket(layer: StyleLayer) { diff --git a/src/symbol/symbol_placement.js b/src/symbol/symbol_placement.js index 629a0aad542..61b7c24fb90 100644 --- a/src/symbol/symbol_placement.js +++ b/src/symbol/symbol_placement.js @@ -15,7 +15,7 @@ module.exports = { performSymbolPlacement: performSymbolPlacement }; -function updateOpacity(symbolInstance: SymbolInstance, opacityState: OpacityState, targetOpacity: number, opacityUpdateTime: number, collisionFadeTimes: any) { +function updateOpacity(symbolInstance: SymbolInstance, opacityState: OpacityState, targetOpacity: number, opacityUpdateTime: number, collisionFadeTimes: any, instant: boolean) { if (symbolInstance.isDuplicate) { opacityState.opacity = 0; opacityState.targetOpacity = 0; @@ -24,7 +24,9 @@ function updateOpacity(symbolInstance: SymbolInstance, opacityState: OpacityStat collisionFadeTimes.latestStart = opacityUpdateTime; } const increment = collisionFadeTimes.duration ? ((opacityUpdateTime - opacityState.time) / collisionFadeTimes.duration) : 1; - opacityState.opacity = Math.max(0, Math.min(1, opacityState.opacity + (opacityState.targetOpacity === 1 ? increment : -increment))); + opacityState.opacity = instant ? + targetOpacity : + Math.max(0, Math.min(1, opacityState.opacity + (opacityState.targetOpacity === 1 ? increment : -increment))); opacityState.targetOpacity = targetOpacity; opacityState.time = opacityUpdateTime; } @@ -56,7 +58,7 @@ function packOpacity(opacityState: OpacityState): number { opacityBits * shift1 + targetBit; } -function updateOpacities(bucket: SymbolBucket, collisionFadeTimes: any) { +function updateOpacities(bucket: SymbolBucket, collisionFadeTimes: any, instant: boolean) { const glyphOpacityArray = bucket.text && bucket.text.opacityVertexArray; const iconOpacityArray = bucket.icon && bucket.icon.opacityVertexArray; if (glyphOpacityArray) glyphOpacityArray.clear(); @@ -75,7 +77,7 @@ function updateOpacities(bucket: SymbolBucket, collisionFadeTimes: any) { const targetOpacity = symbolInstance.placedText ? 1.0 : 0.0; const opacityState = symbolInstance.textOpacityState; const initialHidden = opacityState.opacity === 0 && opacityState.targetOpacity === 0; - updateOpacity(symbolInstance, opacityState, targetOpacity, bucket.fadeStartTime, collisionFadeTimes); + updateOpacity(symbolInstance, opacityState, targetOpacity, bucket.fadeStartTime, collisionFadeTimes, instant); const nowHidden = opacityState.opacity === 0 && opacityState.targetOpacity === 0; if (initialHidden !== nowHidden) { for (const placedTextSymbolIndex of symbolInstance.placedTextSymbolIndices) { @@ -98,7 +100,7 @@ function updateOpacities(bucket: SymbolBucket, collisionFadeTimes: any) { if (hasIcon) { const targetOpacity = symbolInstance.placedIcon ? 1.0 : 0.0; const opacityState = symbolInstance.iconOpacityState; - updateOpacity(symbolInstance, opacityState, targetOpacity, bucket.fadeStartTime, collisionFadeTimes); + updateOpacity(symbolInstance, opacityState, targetOpacity, bucket.fadeStartTime, collisionFadeTimes, instant); const opacityEntryCount = symbolInstance.numIconVertices / 4; const packedOpacity = packOpacity(opacityState); for (let i = 0; i < opacityEntryCount; i++) {