Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize and simplify symbol placement code #12351

Merged
merged 13 commits into from
Nov 14, 2022
3 changes: 2 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"parserOptions": {
"sourceType": "module",
"requireConfigFile": false,
"ecmaVersion": 2016,
"babelOptions": {
"presets": ["@babel/preset-flow"]
}
Expand Down Expand Up @@ -179,4 +180,4 @@
"es6": true,
"browser": false
}
}
}
7 changes: 3 additions & 4 deletions src/data/array_types.js
Original file line number Diff line number Diff line change
Expand Up @@ -1182,10 +1182,9 @@ register(GlyphOffsetArray, 'GlyphOffsetArray');
/**
* @private
*/
export class SymbolLineVertexArray extends StructArrayLayout3i6 {
getx(index: number): number { return this.int16[index * 3 + 0]; }
gety(index: number): number { return this.int16[index * 3 + 1]; }
gettileUnitDistanceFromAnchor(index: number): number { return this.int16[index * 3 + 2]; }
export class SymbolLineVertexArray extends StructArrayLayout2i4 {
getx(index: number): number { return this.int16[index * 2 + 0]; }
gety(index: number): number { return this.int16[index * 2 + 1]; }
}

register(SymbolLineVertexArray, 'SymbolLineVertexArray');
Expand Down
3 changes: 1 addition & 2 deletions src/data/bucket/symbol_attributes.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,5 @@ export const glyphOffset: StructArrayLayout = createLayout([

export const lineVertex: StructArrayLayout = createLayout([
{type: 'Int16', name: 'x'},
{type: 'Int16', name: 'y'},
{type: 'Int16', name: 'tileUnitDistanceFromAnchor'}
{type: 'Int16', name: 'y'}
karimnaaji marked this conversation as resolved.
Show resolved Hide resolved
]);
133 changes: 49 additions & 84 deletions src/data/bucket/symbol_bucket.js
Original file line number Diff line number Diff line change
Expand Up @@ -666,28 +666,11 @@ class SymbolBucket implements Bucket {
}
}

addToLineVertexArray(anchor: Anchor, line: any): LineVertexRange {
addToLineVertexArray(anchor: Anchor, line: Array<Point>): LineVertexRange {
const lineStartIndex = this.lineVertexArray.length;
const segment = anchor.segment;
if (segment !== undefined) {
let sumForwardLength = anchor.dist(line[segment + 1]);
let sumBackwardLength = anchor.dist(line[segment]);
const vertices = {};
for (let i = segment + 1; i < line.length; i++) {
vertices[i] = {x: line[i].x, y: line[i].y, tileUnitDistanceFromAnchor: sumForwardLength};
if (i < line.length - 1) {
sumForwardLength += line[i + 1].dist(line[i]);
}
}
for (let i = segment || 0; i >= 0; i--) {
vertices[i] = {x: line[i].x, y: line[i].y, tileUnitDistanceFromAnchor: sumBackwardLength};
if (i > 0) {
sumBackwardLength += line[i - 1].dist(line[i]);
}
}
for (let i = 0; i < line.length; i++) {
const vertex = vertices[i];
this.lineVertexArray.emplaceBack(vertex.x, vertex.y, vertex.tileUnitDistanceFromAnchor);
if (anchor.segment !== undefined) {
for (const {x, y} of line) {
this.lineVertexArray.emplaceBack(x, y);
}
}
return {
Expand Down Expand Up @@ -733,14 +716,14 @@ class SymbolBucket implements Bucket {
addVertex(layoutVertexArray, tileAnchor.x, tileAnchor.y, br.x, y + br.y, tex.x + tex.w, tex.y + tex.h, sizeVertex, isSDF, pixelOffsetBR.x, pixelOffsetBR.y, minFontScaleX, minFontScaleY);

if (globe) {
const globeAnchor = globe.anchor;
const up = globe.up;
addGlobeVertex(globeExtVertexArray, globeAnchor.x, globeAnchor.y, globeAnchor.z, up[0], up[1], up[2]);
addGlobeVertex(globeExtVertexArray, globeAnchor.x, globeAnchor.y, globeAnchor.z, up[0], up[1], up[2]);
addGlobeVertex(globeExtVertexArray, globeAnchor.x, globeAnchor.y, globeAnchor.z, up[0], up[1], up[2]);
addGlobeVertex(globeExtVertexArray, globeAnchor.x, globeAnchor.y, globeAnchor.z, up[0], up[1], up[2]);

addDynamicAttributes(arrays.dynamicLayoutVertexArray, globeAnchor.x, globeAnchor.y, globeAnchor.z, angle);
const {x, y, z} = globe.anchor;
const [ux, uy, uz] = globe.up;
addGlobeVertex(globeExtVertexArray, x, y, z, ux, uy, uz);
addGlobeVertex(globeExtVertexArray, x, y, z, ux, uy, uz);
addGlobeVertex(globeExtVertexArray, x, y, z, ux, uy, uz);
addGlobeVertex(globeExtVertexArray, x, y, z, ux, uy, uz);

addDynamicAttributes(arrays.dynamicLayoutVertexArray, x, y, z, angle);
} else {
addDynamicAttributes(arrays.dynamicLayoutVertexArray, tileAnchor.x, tileAnchor.y, tileAnchor.z, angle);
}
Expand Down Expand Up @@ -867,14 +850,14 @@ class SymbolBucket implements Bucket {
instance.leftJustifiedTextSymbolIndex : instance.verticalPlacedTextSymbolIndex >= 0 ?
instance.verticalPlacedTextSymbolIndex : boxIndex;

const symbol: any = this.text.placedSymbolArray.get(symbolIndex);
const symbol = this.text.placedSymbolArray.get(symbolIndex);
const featureSize = symbolSize.evaluateSizeForFeature(this.textSizeData, textSize, symbol) / ONE_EM;

return this.tilePixelRatio * featureSize;
}

getSymbolInstanceIconSize(iconSize: any, zoom: number, iconIndex: number): number {
const symbol: any = this.icon.placedSymbolArray.get(iconIndex);
const symbol = this.icon.placedSymbolArray.get(iconIndex);
const featureSize = symbolSize.evaluateSizeForFeature(this.iconSizeData, iconSize, symbol);

return this.tilePixelRatio * featureSize;
Expand Down Expand Up @@ -940,32 +923,27 @@ class SymbolBucket implements Bucket {
iconStartIndex: number, iconEndIndex: number,
verticalIconStartIndex: number, verticalIconEndIndex: number): CollisionArrays {

// Only one box allowed per instance
const collisionArrays = {};
for (let k = textStartIndex; k < textEndIndex; k++) {
const box: CollisionBox = (collisionBoxArray.get(k): any);
collisionArrays.textBox = {x1: box.x1, y1: box.y1, x2: box.x2, y2: box.y2, padding: box.padding, projectedAnchorX: box.projectedAnchorX, projectedAnchorY: box.projectedAnchorY, projectedAnchorZ: box.projectedAnchorZ, tileAnchorX: box.tileAnchorX, tileAnchorY: box.tileAnchorY};
collisionArrays.textFeatureIndex = box.featureIndex;
break; // Only one box allowed per instance
if (textStartIndex < textEndIndex) {
const {x1, y1, x2, y2, padding, projectedAnchorX, projectedAnchorY, projectedAnchorZ, tileAnchorX, tileAnchorY, featureIndex} = collisionBoxArray.get(textStartIndex);
collisionArrays.textBox = {x1, y1, x2, y2, padding, projectedAnchorX, projectedAnchorY, projectedAnchorZ, tileAnchorX, tileAnchorY};
collisionArrays.textFeatureIndex = featureIndex;
}
for (let k = verticalTextStartIndex; k < verticalTextEndIndex; k++) {
const box: CollisionBox = (collisionBoxArray.get(k): any);
collisionArrays.verticalTextBox = {x1: box.x1, y1: box.y1, x2: box.x2, y2: box.y2, padding: box.padding, projectedAnchorX: box.projectedAnchorX, projectedAnchorY: box.projectedAnchorY, projectedAnchorZ: box.projectedAnchorZ, tileAnchorX: box.tileAnchorX, tileAnchorY: box.tileAnchorY};
collisionArrays.verticalTextFeatureIndex = box.featureIndex;
break; // Only one box allowed per instance
if (verticalTextStartIndex < verticalTextEndIndex) {
const {x1, y1, x2, y2, padding, projectedAnchorX, projectedAnchorY, projectedAnchorZ, tileAnchorX, tileAnchorY, featureIndex} = collisionBoxArray.get(verticalTextStartIndex);
collisionArrays.verticalTextBox = {x1, y1, x2, y2, padding, projectedAnchorX, projectedAnchorY, projectedAnchorZ, tileAnchorX, tileAnchorY};
collisionArrays.verticalTextFeatureIndex = featureIndex;
}
for (let k = iconStartIndex; k < iconEndIndex; k++) {
// An icon can only have one box now, so this indexing is a bit vestigial...
const box: CollisionBox = (collisionBoxArray.get(k): any);
collisionArrays.iconBox = {x1: box.x1, y1: box.y1, x2: box.x2, y2: box.y2, padding: box.padding, projectedAnchorX: box.projectedAnchorX, projectedAnchorY: box.projectedAnchorY, projectedAnchorZ: box.projectedAnchorZ, tileAnchorX: box.tileAnchorX, tileAnchorY: box.tileAnchorY};
collisionArrays.iconFeatureIndex = box.featureIndex;
break; // Only one box allowed per instance
if (iconStartIndex < iconEndIndex) {
const {x1, y1, x2, y2, padding, projectedAnchorX, projectedAnchorY, projectedAnchorZ, tileAnchorX, tileAnchorY, featureIndex} = collisionBoxArray.get(iconStartIndex);
collisionArrays.iconBox = {x1, y1, x2, y2, padding, projectedAnchorX, projectedAnchorY, projectedAnchorZ, tileAnchorX, tileAnchorY};
collisionArrays.iconFeatureIndex = featureIndex;
}
for (let k = verticalIconStartIndex; k < verticalIconEndIndex; k++) {
// An icon can only have one box now, so this indexing is a bit vestigial...
const box: CollisionBox = (collisionBoxArray.get(k): any);
collisionArrays.verticalIconBox = {x1: box.x1, y1: box.y1, x2: box.x2, y2: box.y2, padding: box.padding, projectedAnchorX: box.projectedAnchorX, projectedAnchorY: box.projectedAnchorY, projectedAnchorZ: box.projectedAnchorZ, tileAnchorX: box.tileAnchorX, tileAnchorY: box.tileAnchorY};
collisionArrays.verticalIconFeatureIndex = box.featureIndex;
break; // Only one box allowed per instance
if (verticalIconStartIndex < verticalIconEndIndex) {
const {x1, y1, x2, y2, padding, projectedAnchorX, projectedAnchorY, projectedAnchorZ, tileAnchorX, tileAnchorY, featureIndex} = collisionBoxArray.get(verticalIconStartIndex);
collisionArrays.verticalIconBox = {x1, y1, x2, y2, padding, projectedAnchorX, projectedAnchorY, projectedAnchorZ, tileAnchorX, tileAnchorY};
collisionArrays.verticalIconFeatureIndex = featureIndex;
}
return collisionArrays;
}
Expand Down Expand Up @@ -1035,10 +1013,7 @@ class SymbolBucket implements Bucket {
featureIndexes.push(symbolInstance.featureIndex);
}

result.sort((aIndex, bIndex) => {
return (rotatedYs[aIndex] - rotatedYs[bIndex]) ||
(featureIndexes[bIndex] - featureIndexes[aIndex]);
});
result.sort((aIndex, bIndex) => (rotatedYs[aIndex] - rotatedYs[bIndex]) || (featureIndexes[bIndex] - featureIndexes[aIndex]));

return result;
}
Expand Down Expand Up @@ -1078,33 +1053,23 @@ class SymbolBucket implements Bucket {
this.featureSortOrder = [];

for (const i of this.symbolInstanceIndexes) {
const symbolInstance = this.symbolInstances.get(i);
this.featureSortOrder.push(symbolInstance.featureIndex);

[
symbolInstance.rightJustifiedTextSymbolIndex,
symbolInstance.centerJustifiedTextSymbolIndex,
symbolInstance.leftJustifiedTextSymbolIndex
].forEach((index, i, array) => {
// Only add a given index the first time it shows up,
// to avoid duplicate opacity entries when multiple justifications
// share the same glyphs.
if (index >= 0 && array.indexOf(index) === i) {
this.addIndicesForPlacedSymbol(this.text, index);
}
});

if (symbolInstance.verticalPlacedTextSymbolIndex >= 0) {
this.addIndicesForPlacedSymbol(this.text, symbolInstance.verticalPlacedTextSymbolIndex);
}

if (symbolInstance.placedIconSymbolIndex >= 0) {
this.addIndicesForPlacedSymbol(this.icon, symbolInstance.placedIconSymbolIndex);
}

if (symbolInstance.verticalPlacedIconSymbolIndex >= 0) {
this.addIndicesForPlacedSymbol(this.icon, symbolInstance.verticalPlacedIconSymbolIndex);
}
const symbol = this.symbolInstances.get(i);
this.featureSortOrder.push(symbol.featureIndex);
const {
rightJustifiedTextSymbolIndex: right, centerJustifiedTextSymbolIndex: center,
leftJustifiedTextSymbolIndex: left, verticalPlacedTextSymbolIndex: vertical,
placedIconSymbolIndex: icon, verticalPlacedIconSymbolIndex: iconVertical
} = symbol;

// Only add a given index the first time it shows up, to avoid duplicate
// opacity entries when multiple justifications share the same glyphs.
if (right >= 0) this.addIndicesForPlacedSymbol(this.text, right);
if (center >= 0 && center !== right) this.addIndicesForPlacedSymbol(this.text, center);
if (left >= 0 && left !== center && left !== right) this.addIndicesForPlacedSymbol(this.text, left);

if (vertical >= 0) this.addIndicesForPlacedSymbol(this.text, vertical);
if (icon >= 0) this.addIndicesForPlacedSymbol(this.icon, icon);
if (iconVertical >= 0) this.addIndicesForPlacedSymbol(this.icon, iconVertical);
}

if (this.text.indexBuffer) this.text.indexBuffer.updateData(this.text.indexArray);
Expand Down
Loading