Skip to content

Commit

Permalink
[transferrable symbol buffer] declare new StructArrayTypes for Symbol…
Browse files Browse the repository at this point in the history
…Instances and SymbolQuads

create SymbolInstancesArray StructArrayType

add symbolinstances and quads to struct arrays

populate symbolInstanceBuffer and symbolQuadsBuffer

transfer symbol buffers from worker --> main thread

add symbolInstances and symbolQuads to tile.js
  • Loading branch information
Molly Lloyd committed Jun 6, 2016
1 parent 3df6868 commit 92fbfb8
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 0 deletions.
60 changes: 60 additions & 0 deletions js/data/bucket/symbol_bucket.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ function SymbolBucket(options) {
this.showCollisionBoxes = options.showCollisionBoxes;
this.overscaling = options.overscaling;
this.collisionBoxArray = options.collisionBoxArray;
this.symbolQuadsArray = options.symbolQuadsArray;
this.symbolInstancesArray = options.symbolInstancesArray;

this.sdfIcons = options.sdfIcons;
this.iconsNeedLinear = options.iconsNeedLinear;
Expand Down Expand Up @@ -327,6 +329,11 @@ SymbolBucket.prototype.addFeature = function(lines, shapedText, shapedIcon, feat
iconBoxScale, iconPadding, iconAlongLine));
}
}

for (var k = 0; k < this.symbolInstances.length; k++) {
this.addSymbolInstance(this.symbolInstances[k]);
}

};

SymbolBucket.prototype.anchorIsTooClose = function(text, repeatDistance, anchor) {
Expand Down Expand Up @@ -558,3 +565,56 @@ function SymbolInstance(anchor, line, shapedText, shapedIcon, layout, addToBuffe
shapedIcon, iconBoxScale, iconPadding, iconAlongLine, true);
}
}

SymbolBucket.prototype.addSymbolInstance = function(symbolInstance) {
var startGlyphIndex, endGlyphIndex, iconQuadIndex;
var quads = symbolInstance.glyphQuads ? symbolInstance.glyphQuads : [];
for (var i = 0; i < quads.length; i++) {
if (i === 0) {
startGlyphIndex = this.addSymbolQuad(quads[i]);
} else if (i === quads.length - 1) {
endGlyphIndex = this.addSymbolQuad(quads[i]);
} else {
this.addSymbolQuad(quads[i]);
}
}

if (symbolInstance.iconQuads && symbolInstance.iconQuads.length === 1) {
iconQuadIndex = this.addSymbolQuad(symbolInstance.iconQuads[0]);
}

return this.symbolInstancesArray.emplaceBack(
startGlyphIndex || -1,
endGlyphIndex || -1,
iconQuadIndex || -1,
symbolInstance.x,
symbolInstance.y,
symbolInstance.index);

};

SymbolBucket.prototype.addSymbolQuad = function(symbolQuad) {
return this.symbolQuadsArray.emplaceBack(
// anchorPoints
symbolQuad.anchorPoint.x,
symbolQuad.anchorPoint.y,
// corners
symbolQuad.tl.x,
symbolQuad.tl.y,
symbolQuad.tr.x,
symbolQuad.tr.y,
symbolQuad.bl.x,
symbolQuad.bl.y,
symbolQuad.br.x,
symbolQuad.br.y,
// texture
symbolQuad.tex.h,
symbolQuad.tex.w,
symbolQuad.tex.x,
symbolQuad.tex.y,
//angle
symbolQuad.angle,
// scales
symbolQuad.minScale,
symbolQuad.maxScale);
};
6 changes: 6 additions & 0 deletions js/source/tile.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ var GeoJSONFeature = require('../util/vectortile_to_geojson');
var featureFilter = require('feature-filter');
var CollisionTile = require('../symbol/collision_tile');
var CollisionBoxArray = require('../symbol/collision_box');
var SymbolInstancesArray = require('../symbol/symbol_instances');
var SymbolQuadsArray = require('../symbol/symbol_quads');

module.exports = Tile;

Expand Down Expand Up @@ -50,6 +52,8 @@ Tile.prototype = {

this.collisionBoxArray = new CollisionBoxArray(data.collisionBoxArray);
this.collisionTile = new CollisionTile(data.collisionTile, this.collisionBoxArray);
this.symbolInstancesArray = new SymbolInstancesArray(data.symbolInstancesArray);
this.symbolQuadsArray = new SymbolQuadsArray(data.symbolQuadsArray);
this.featureIndex = new FeatureIndex(data.featureIndex, data.rawTileData, this.collisionTile);
this.rawTileData = data.rawTileData;
this.buckets = unserializeBuckets(data.buckets, style);
Expand Down Expand Up @@ -97,6 +101,8 @@ Tile.prototype = {
}

this.collisionBoxArray = null;
this.symbolQuadsArray = null;
this.symbolInstancesArray = null;
this.collisionTile = null;
this.featureIndex = null;
this.rawTileData = null;
Expand Down
10 changes: 10 additions & 0 deletions js/source/worker_tile.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ var Bucket = require('../data/bucket');
var CollisionBoxArray = require('../symbol/collision_box');
var DictionaryCoder = require('../util/dictionary_coder');
var util = require('../util/util');
var SymbolInstancesArray = require('../symbol/symbol_instances');
var SymbolQuadsArray = require('../symbol/symbol_quads');

module.exports = WorkerTile;

Expand All @@ -27,6 +29,8 @@ WorkerTile.prototype.parse = function(data, layerFamilies, actor, rawTileData, c
this.data = data;

this.collisionBoxArray = new CollisionBoxArray();
this.symbolInstancesArray = new SymbolInstancesArray();
this.symbolQuadsArray = new SymbolQuadsArray();
var collisionTile = new CollisionTile(this.angle, this.pitch, this.collisionBoxArray);
var featureIndex = new FeatureIndex(this.coord, this.overscaling, collisionTile, data.layers);
var sourceLayerCoder = new DictionaryCoder(data.layers ? Object.keys(data.layers).sort() : ['_geojsonTileLayer']);
Expand Down Expand Up @@ -61,6 +65,8 @@ WorkerTile.prototype.parse = function(data, layerFamilies, actor, rawTileData, c
overscaling: this.overscaling,
showCollisionBoxes: this.showCollisionBoxes,
collisionBoxArray: this.collisionBoxArray,
symbolQuadsArray: this.symbolQuadsArray,
symbolInstancesArray: this.symbolInstancesArray,
sourceLayerIndex: sourceLayerCoder.encode(layer.sourceLayer || '_geojsonTileLayer')
});
bucket.createFilter();
Expand Down Expand Up @@ -207,6 +213,8 @@ WorkerTile.prototype.parse = function(data, layerFamilies, actor, rawTileData, c
var featureIndex_ = featureIndex.serialize();
var collisionTile_ = collisionTile.serialize();
var collisionBoxArray = tile.collisionBoxArray.serialize();
var symbolInstancesArray = tile.symbolInstancesArray.serialize();
var symbolQuadsArray = tile.symbolQuadsArray.serialize();
var transferables = [rawTileData].concat(featureIndex_.transferables).concat(collisionTile_.transferables);

var nonEmptyBuckets = buckets.filter(isBucketEmpty);
Expand All @@ -217,6 +225,8 @@ WorkerTile.prototype.parse = function(data, layerFamilies, actor, rawTileData, c
featureIndex: featureIndex_.data,
collisionTile: collisionTile_.data,
collisionBoxArray: collisionBoxArray,
symbolInstancesArray: symbolInstancesArray,
symbolQuadsArray: symbolQuadsArray,
rawTileData: rawTileData
}, getTransferables(nonEmptyBuckets).concat(transferables));
}
Expand Down
37 changes: 37 additions & 0 deletions js/symbol/symbol_instances.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
'use strict';

var StructArrayType = require('../util/struct_array');
var util = require('../util/util');
var Point = require('point-geometry');

/*
*
* A StructArray implementation of symbolInstances from data/bucket/symbol_bucket.js
* this will allow symbolInstances to be transferred between the worker and main threads
*
* @class SymbolInstanceArray
* @private
*/

var SymbolInstancesArray = module.exports = new StructArrayType({
members: [
// the indices of the glyph quads applicable to this particular symbol instance
{ type: 'Int16', name: 'glyphQuadsStart' },
{ type: 'Int16', name: 'glyphQuadsEnd' },
{ type: 'Int16', name: 'iconQuadIndex' },

// each symbolInstance is centered around the anchor point
{ type: 'Int16', name: 'anchorPointX' },
{ type: 'Int16', name: 'anchorPointY' },

// index
{type: 'Int8', name: 'index'}
]
});

util.extendAll(SymbolInstancesArray.prototype.StructType.prototype, {
get anchorPoint() {
return new Point(this.anchorPointX, this.anchorPointY);
}
});

56 changes: 56 additions & 0 deletions js/symbol/symbol_quads.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
'use strict';

var StructArrayType = require('../util/struct_array');
var util = require('../util/util');
var Point = require('point-geometry');

// notes from ansis on slack:
// it would be best if they are added to a buffer in advance so that they are only created once. There would be a separate buffer with all the individual collision boxes and then SymbolInstance would store the beginning and end indexes of a feature's collisionboxes. CollisionFeature wouldn't really exist as a standalone thing, it would just be a range of boxes in the big collision box buffer

/*
*
* A StructArray implementation of glyphQuad from symbol/quads
* this will allow glyph quads to be transferred between the worker and main threads along with the rest of
* the symbolInstances
*
* @class SymbolQuadsArray
* @private
*/

var SymbolQuadsArray = module.exports = new StructArrayType({
members: [
// the quad is centered around the anchor point
{ type: 'Int16', name: 'anchorPointX' },
{ type: 'Int16', name: 'anchorPointY' },

// the offsets of the tl (top-left), tr, bl, br corners from the anchor point
// do these need to be floats?
{ type: 'Int16', name: 'tlX' },
{ type: 'Int16', name: 'tlY' },
{ type: 'Int16', name: 'trX' },
{ type: 'Int16', name: 'trY' },
{ type: 'Int16', name: 'blX' },
{ type: 'Int16', name: 'blY' },
{ type: 'Int16', name: 'brX' },
{ type: 'Int16', name: 'brY' },

// texture coordinates (height, width, x, and y)
{ type: 'Int16', name: 'texH' },
{ type: 'Int16', name: 'texW' },
{ type: 'Int16', name: 'texX' },
{ type: 'Int16', name: 'texY' },

//the angle of the label at it's center, not the angle of this quad.
{ type: 'Float32', name: 'angle' },

// quad is only valid for scales < maxScale && scale > minScale.
{ type: 'Float32', name: 'maxScale' },
{ type: 'Float32', name: 'minScale' }
]
});

util.extendAll(SymbolQuadsArray.prototype.StructType.prototype, {
get anchorPoint() {
return new Point(this.anchorPointX, this.anchorPointY);
}
});

0 comments on commit 92fbfb8

Please sign in to comment.