Skip to content

Commit

Permalink
Stability improvement: iterate layers->styles instead of styles->layers
Browse files Browse the repository at this point in the history
Performance improvement: don't recalculate matrices for each layer
  • Loading branch information
ChrisLoer committed Jul 13, 2017
1 parent 3a8db93 commit 161c018
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 62 deletions.
7 changes: 5 additions & 2 deletions src/source/source_cache.js
Original file line number Diff line number Diff line change
Expand Up @@ -586,11 +586,14 @@ class SourceCache extends Evented {
return tileResults;
}

redoPlacement(viewportCollisionTile, layer) {
redoPlacement(viewportCollisionTile, layer, posMatrices, transform) {
const ids = this.getIds();
for (let i = 0; i < ids.length; i++) {
const tile = this.getTileByID(ids[i]);
tile.redoPlacement(this._source, viewportCollisionTile, layer);
if (!posMatrices[i]) {
posMatrices[i] = transform.calculatePosMatrix(tile.coord, tile.sourceMaxZoom);
}
tile.redoPlacement(this._source, viewportCollisionTile, layer, posMatrices[i]);
}
}

Expand Down
59 changes: 5 additions & 54 deletions src/source/tile.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,62 +157,25 @@ class Tile {
this.state = 'unloaded';
}

redoPlacement(source: any, collisionTile: ?CollisionTile, layer: any) {
redoPlacement(source: any, collisionTile: ?CollisionTile, layer: any, posMatrix: Float32Array) {
if (source.type !== 'vector' && source.type !== 'geojson') {
return;
}
if (this.state !== 'loaded') {
this.redoWhenDone = true;
return;
}
/*
if (!this.collisionTile) { // empty tile
return;
}
*/

const cameraToTileDistance = source.map.transform.cameraToTileDistance(this);
/*
if (this.angle === source.map.transform.angle &&
this.pitch === source.map.transform.pitch &&
this.cameraToCenterDistance === source.map.transform.cameraToCenterDistance &&
this.showCollisionBoxes === source.map.showCollisionBoxes) {
if (this.cameraToTileDistance === cameraToTileDistance) {
return;
} else if (this.pitch < 25) {
// At low pitch tile distance doesn't affect placement very
// much, so we skip the cost of redoPlacement
// However, we might as well store the latest value of
// cameraToTileDistance in case a redoPlacement request
// is already queued.
this.cameraToTileDistance = cameraToTileDistance;
return;
}
}
*/

this.zoom = source.map.transform.zoom;
this.angle = source.map.transform.angle;
this.pitch = source.map.transform.pitch;
this.cameraToCenterDistance = source.map.transform.cameraToCenterDistance;
this.cameraToTileDistance = cameraToTileDistance;
this.showCollisionBoxes = source.map.showCollisionBoxes;
this.placementSource = source;
this.matrix = source.map.transform.calculatePosMatrix(this.coord, this.sourceMaxZoom);

this.state = 'reloading';

collisionTile.setMatrix(this.matrix);
collisionTile.setMatrix(posMatrix);
collisionTile.setCollisionBoxArray(this.collisionBoxArray);

const symbolBuckets = [];
const style = this.placementSource.map.style;

const bucket = this.getBucket(layer);

if (bucket) {
//recalculateLayers(bucket, this.zoom);
bucket.place(collisionTile, this.showCollisionBoxes, this.zoom, pixelsToTileUnits(this, 1, source.map.transform.zoom));
bucket.place(collisionTile, this.showCollisionBoxes, source.map.transform.zoom, pixelsToTileUnits(this, 1, source.map.transform.zoom));
symbolBuckets.push(bucket);
}

Expand All @@ -221,22 +184,10 @@ class Tile {
collisionTile: collisionTile
};

/*
this.placementSource.dispatcher.send('redoPlacement', {
type: this.placementSource.type,
uid: this.uid,
source: this.placementSource.id,
angle: this.angle,
pitch: this.pitch,
cameraToCenterDistance: this.cameraToCenterDistance,
cameraToTileDistance: this.cameraToTileDistance,
showCollisionBoxes: this.showCollisionBoxes
}, (_, data) => {
*/
this.reloadSymbolData(data);
if (this.placementSource.map.showCollisionBoxes) this.placementSource.fire('data', {tile: this, coord: this.coord, dataType: 'source'});
//if (this.placementSource.map.showCollisionBoxes) this.placementSource.fire('data', {tile: this, coord: this.coord, dataType: 'source'});
// HACK this is nescessary to fix https://github.com/mapbox/mapbox-gl-js/issues/2986
if (this.placementSource.map) this.placementSource.map.painter.tileExtentVAO.vao = null;
if (source.map) source.map.painter.tileExtentVAO.vao = null;

this.state = 'loaded';

Expand Down
18 changes: 12 additions & 6 deletions src/style/style.js
Original file line number Diff line number Diff line change
Expand Up @@ -867,12 +867,18 @@ class Style extends Evented {
console.time('redo placement');
this.viewportCollisionTile = new CollisionTile(transform);

for (const id in this.sourceCaches) {
for (let i = this._order.length - 1; i >= 0; i--) {
const layerId = this._order[i];
const layer = this._layers[layerId];
if (layer.type !== 'symbol') continue;
this.sourceCaches[id].redoPlacement(this.viewportCollisionTile, layer);
const posMatrices = {};

for (let i = this._order.length - 1; i >= 0; i--) {
const layerId = this._order[i];
const layer = this._layers[layerId];
if (layer.type !== 'symbol') continue;

for (const id in this.sourceCaches) {
if (!posMatrices[id]) {
posMatrices[id] = {};
}
this.sourceCaches[id].redoPlacement(this.viewportCollisionTile, layer, posMatrices[id], transform);
}
}
console.timeEnd('redo placement');
Expand Down

0 comments on commit 161c018

Please sign in to comment.