From e3711c277e6ac64e82dff63efd71ec6b1dc701f0 Mon Sep 17 00:00:00 2001 From: Lucas Wojciechowski Date: Thu, 3 Nov 2016 12:25:58 -0700 Subject: [PATCH 1/3] Ensure images always fade in completely, remove "raster-fade-duration" --- js/render/draw_raster.js | 5 ++--- js/source/image_source.js | 2 ++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/js/render/draw_raster.js b/js/render/draw_raster.js index d3c3367541e..87909b0f315 100644 --- a/js/render/draw_raster.js +++ b/js/render/draw_raster.js @@ -47,7 +47,7 @@ function drawRasterTile(painter, sourceCache, layer, coord) { gl.uniform3fv(program.u_spin_weights, spinWeights(layer.paint['raster-hue-rotate'])); const parentTile = tile.sourceCache && tile.sourceCache.findLoadedParent(coord, 0, {}), - opacities = getOpacities(tile, parentTile, layer, painter.transform); + opacities = getOpacities(tile, parentTile, layer, painter.transform, painter.style.rasterFadeDuration); let parentScaleBy, parentTL; @@ -103,9 +103,8 @@ function saturationFactor(saturation) { -saturation; } -function getOpacities(tile, parentTile, layer, transform) { +function getOpacities(tile, parentTile, layer, transform, fadeDuration) { const opacities = [1, 0]; - const fadeDuration = layer.paint['raster-fade-duration']; if (tile.sourceCache && fadeDuration > 0) { const now = Date.now(); diff --git a/js/source/image_source.js b/js/source/image_source.js index fcaf13c9667..3d120a6dee4 100644 --- a/js/source/image_source.js +++ b/js/source/image_source.js @@ -156,6 +156,8 @@ class ImageSource extends Evented { gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image); + this.map.animationLoop.set(this.tile.timeAdded + this.map.style.rasterFadeDuration - Date.now()); + } else if (image instanceof window.HTMLVideoElement) { gl.bindTexture(gl.TEXTURE_2D, this.tile.texture); gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, image); From da7add6e3b459222442467bef48b8fb1a5cae771 Mon Sep 17 00:00:00 2001 From: Lucas Wojciechowski Date: Thu, 3 Nov 2016 12:58:51 -0700 Subject: [PATCH 2/3] Restore "raster-fade-duration" functionality --- js/render/draw_raster.js | 7 +++++-- js/source/image_source.js | 1 - js/source/raster_tile_source.js | 2 -- js/source/source_cache.js | 7 +++---- js/source/tile.js | 8 ++++++++ js/style/style.js | 1 - test/js/source/source_cache.test.js | 16 +++++++++++----- 7 files changed, 27 insertions(+), 15 deletions(-) diff --git a/js/render/draw_raster.js b/js/render/draw_raster.js index 87909b0f315..0bf3cf0fdf7 100644 --- a/js/render/draw_raster.js +++ b/js/render/draw_raster.js @@ -36,6 +36,8 @@ function drawRasterTile(painter, sourceCache, layer, coord) { const tile = sourceCache.getTile(coord); const posMatrix = painter.transform.calculatePosMatrix(coord, sourceCache.getSource().maxzoom); + tile.setAnimationLoop(painter.style.animationLoop, layer.paint['raster-fade-duration']); + const program = painter.useProgram('raster'); gl.uniformMatrix4fv(program.u_matrix, false, posMatrix); @@ -47,7 +49,7 @@ function drawRasterTile(painter, sourceCache, layer, coord) { gl.uniform3fv(program.u_spin_weights, spinWeights(layer.paint['raster-hue-rotate'])); const parentTile = tile.sourceCache && tile.sourceCache.findLoadedParent(coord, 0, {}), - opacities = getOpacities(tile, parentTile, layer, painter.transform, painter.style.rasterFadeDuration); + opacities = getOpacities(tile, parentTile, layer, painter.transform); let parentScaleBy, parentTL; @@ -103,8 +105,9 @@ function saturationFactor(saturation) { -saturation; } -function getOpacities(tile, parentTile, layer, transform, fadeDuration) { +function getOpacities(tile, parentTile, layer, transform) { const opacities = [1, 0]; + const fadeDuration = layer.paint['raster-fade-duration']; if (tile.sourceCache && fadeDuration > 0) { const now = Date.now(); diff --git a/js/source/image_source.js b/js/source/image_source.js index 3d120a6dee4..abf82269b58 100644 --- a/js/source/image_source.js +++ b/js/source/image_source.js @@ -156,7 +156,6 @@ class ImageSource extends Evented { gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image); - this.map.animationLoop.set(this.tile.timeAdded + this.map.style.rasterFadeDuration - Date.now()); } else if (image instanceof window.HTMLVideoElement) { gl.bindTexture(gl.TEXTURE_2D, this.tile.texture); diff --git a/js/source/raster_tile_source.js b/js/source/raster_tile_source.js index 388ad38186b..c6e8cbafab2 100644 --- a/js/source/raster_tile_source.js +++ b/js/source/raster_tile_source.js @@ -82,8 +82,6 @@ class RasterTileSource extends Evented { } gl.generateMipmap(gl.TEXTURE_2D); - this.map.animationLoop.set(this.map.style.rasterFadeDuration); - tile.state = 'loaded'; callback(null); diff --git a/js/source/source_cache.js b/js/source/source_cache.js index e515f816dd0..49d0d3fe535 100644 --- a/js/source/source_cache.js +++ b/js/source/source_cache.js @@ -42,7 +42,7 @@ class SourceCache extends Evented { if (this._sourceLoaded && event.dataType === 'source') { this.reload(); if (this.transform) { - this.update(this.transform, this.map && this.map.style.rasterFadeDuration); + this.update(this.transform); } } }); @@ -278,7 +278,7 @@ class SourceCache extends Evented { * are inside the viewport. * @private */ - update(transform, fadeDuration) { + update(transform) { if (!this._sourceLoaded) { return; } let i; let coord; @@ -295,7 +295,6 @@ class SourceCache extends Evented { // the most ideal tile for the current viewport. This may include tiles like // parent or child tiles that are *already* loaded. const retain = {}; - const now = new Date().getTime(); // Covered is a list of retained tiles who's areas are full covered by other, // better, retained tiles. They are not drawn separately. @@ -339,7 +338,7 @@ class SourceCache extends Evented { const id = ids[k]; coord = TileCoord.fromID(id); tile = this._tiles[id]; - if (tile && tile.timeAdded > now - (fadeDuration || 0)) { + if (tile && tile.animationLoopEndTime >= Date.now()) { // This tile is still fading in. Find tiles to cross-fade with it. if (this.findLoadedChildren(coord, maxCoveringZoom, retain)) { retain[id] = true; diff --git a/js/source/tile.js b/js/source/tile.js index 12da031868a..38d08c8458f 100644 --- a/js/source/tile.js +++ b/js/source/tile.js @@ -41,6 +41,14 @@ class Tile { this.state = 'loading'; } + setAnimationLoop(animationLoop, t) { + this.animationLoopEndTime = t + Date.now(); + if (this.animationLoopId !== undefined) { + animationLoop.cancel(this.animationLoopId); + } + this.animationLoopId = animationLoop.set(t); + } + /** * Given a data object with a 'buffers' property, load it into * this tile's elementGroups and buffers properties and set loaded diff --git a/js/style/style.js b/js/style/style.js index 151879e883a..bca5a28c1c3 100644 --- a/js/style/style.js +++ b/js/style/style.js @@ -221,7 +221,6 @@ class Style extends Evented { this._updateZoomHistory(z); - this.rasterFadeDuration = 300; for (const layerId in this._layers) { const layer = this._layers[layerId]; diff --git a/test/js/source/source_cache.test.js b/test/js/source/source_cache.test.js index 5777bacd68c..c415239e688 100644 --- a/test/js/source/source_cache.test.js +++ b/test/js/source/source_cache.test.js @@ -2,6 +2,7 @@ const test = require('mapbox-gl-js-test').test; const SourceCache = require('../../../js/source/source_cache'); +const AnimationLoop = require('../../../js/style/animation_loop'); const Source = require('../../../js/source/source'); const TileCoord = require('../../../js/source/tile_coord'); const Transform = require('../../../js/geo/transform'); @@ -378,17 +379,19 @@ test('SourceCache#update', (t) => { const transform = new Transform(); transform.resize(511, 511); transform.zoom = 2; + const animationLoop = new AnimationLoop(); const sourceCache = createSourceCache({ loadTile: function(tile, callback) { tile.timeAdded = Infinity; tile.state = 'loaded'; + tile.setAnimationLoop(animationLoop, 100); callback(); } }); sourceCache.on('source.load', () => { - sourceCache.update(transform, 100); + sourceCache.update(transform); t.deepEqual(sourceCache.getIds(), [ new TileCoord(2, 1, 1).id, new TileCoord(2, 2, 1).id, @@ -397,7 +400,7 @@ test('SourceCache#update', (t) => { ]); transform.zoom = 0; - sourceCache.update(transform, 100); + sourceCache.update(transform); t.deepEqual(sourceCache.getRenderableIds().length, 5); t.end(); @@ -409,22 +412,25 @@ test('SourceCache#update', (t) => { transform.resize(511, 511); transform.zoom = 0; + const animationLoop = new AnimationLoop(); + const sourceCache = createSourceCache({ loadTile: function(tile, callback) { tile.timeAdded = Infinity; tile.state = 'loaded'; + tile.setAnimationLoop(animationLoop, 100); callback(); } }); sourceCache.on('source.load', () => { - sourceCache.update(transform, 100); + sourceCache.update(transform); transform.zoom = 2; - sourceCache.update(transform, 100); + sourceCache.update(transform); transform.zoom = 1; - sourceCache.update(transform, 100); + sourceCache.update(transform); t.equal(sourceCache._coveredTiles[(new TileCoord(0, 0, 0).id)], true); t.end(); From a79ea3175ac9fd67681d5b705d2e3bce9010636b Mon Sep 17 00:00:00 2001 From: Lucas Wojciechowski Date: Thu, 3 Nov 2016 13:13:54 -0700 Subject: [PATCH 3/3] Remove unnecessary whitespace change --- js/source/image_source.js | 1 - 1 file changed, 1 deletion(-) diff --git a/js/source/image_source.js b/js/source/image_source.js index abf82269b58..fcaf13c9667 100644 --- a/js/source/image_source.js +++ b/js/source/image_source.js @@ -156,7 +156,6 @@ class ImageSource extends Evented { gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image); - } else if (image instanceof window.HTMLVideoElement) { gl.bindTexture(gl.TEXTURE_2D, this.tile.texture); gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, image);