Skip to content

Commit

Permalink
Prevent empty buffers from being created for debug data
Browse files Browse the repository at this point in the history
We currently create a a lot of empty buffers for debug data, which end up being unused in most cases (In a crowded label areas this can easily reach ~1000 empty vertex buffer handles after panning for a few seconds)

For one map load on chrome, the observed time taken for the creation of these empty buffers:

In symbol_bucket.js SymbolBucket.constructor, creation of object textCollisionBox, iconCollisionBox, textCollisionCircle, iconCollisionCircle

2.8Ghz i7 (macbook 2019)
Average: 27.14285771932681 us
Total: 1330.0000282470137 us

2.4Ghz i5 (macbook 2011)
Average: 140.6338028093006 us
Total: 9984.999999460342 us

Galaxy s6 (smaller viewport)
Average: 195.83333333865008 us
Total: 4700.000000127602 us

In symbol_bucket.js SymbolBucket.upload, upload for textCollisionBox, iconCollisionBox, textCollisionCircle, iconCollisionCircle

2.8Ghz i7 (macbook 2019)
Average: 78.65079290543993 us
Total: 4954.999953042716 us

2.4Ghz i5 (macbook 2011)
Average: 171.74604175009377 us
Total: 10819.999999625097 us

Galaxy s6 (smaller viewport)
Average: 191.66666666471124 us
Total: 4599.99999995307 us
  • Loading branch information
karimnaaji committed Jan 28, 2020
1 parent 8cd474e commit f354b71
Showing 1 changed file with 39 additions and 13 deletions.
52 changes: 39 additions & 13 deletions src/data/bucket/symbol_bucket.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,18 @@ export class SymbolBuffers {
this.placedSymbolArray = new PlacedSymbolArray();
}

isEmpty() {
return this.layoutVertexArray.length === 0 &&
this.indexArray.length === 0 &&
this.dynamicLayoutVertexArray.length === 0 &&
this.opacityVertexArray.length === 0;
}

upload(context: Context, dynamicIndexBuffer: boolean, upload?: boolean, update?: boolean) {
if (this.isEmpty()) {
return;
}

if (upload) {
this.layoutVertexBuffer = context.createVertexBuffer(this.layoutVertexArray, symbolLayoutAttributes.members);
this.indexBuffer = context.createIndexBuffer(this.indexArray, dynamicIndexBuffer);
Expand Down Expand Up @@ -376,11 +387,6 @@ class SymbolBucket implements Bucket {
this.text = new SymbolBuffers(new ProgramConfigurationSet(symbolLayoutAttributes.members, this.layers, this.zoom, property => /^text/.test(property)));
this.icon = new SymbolBuffers(new ProgramConfigurationSet(symbolLayoutAttributes.members, this.layers, this.zoom, property => /^icon/.test(property)));

this.textCollisionBox = new CollisionBuffers(CollisionBoxLayoutArray, collisionBoxLayout.members, LineIndexArray);
this.iconCollisionBox = new CollisionBuffers(CollisionBoxLayoutArray, collisionBoxLayout.members, LineIndexArray);
this.textCollisionCircle = new CollisionBuffers(CollisionCircleLayoutArray, collisionCircleLayout.members, TriangleIndexArray);
this.iconCollisionCircle = new CollisionBuffers(CollisionCircleLayoutArray, collisionCircleLayout.members, TriangleIndexArray);

this.glyphOffsetArray = new GlyphOffsetArray();
this.lineVertexArray = new SymbolLineVertexArray();
this.symbolInstances = new SymbolInstanceArray();
Expand Down Expand Up @@ -539,7 +545,7 @@ class SymbolBucket implements Bucket {
}

upload(context: Context) {
if (!this.uploaded) {
if (!this.uploaded && this.hasDebugData()) {
this.textCollisionBox.upload(context);
this.iconCollisionBox.upload(context);
this.textCollisionCircle.upload(context);
Expand All @@ -550,15 +556,22 @@ class SymbolBucket implements Bucket {
this.uploaded = true;
}

destroy() {
this.text.destroy();
this.icon.destroy();
destroyDebugData() {
this.textCollisionBox.destroy();
this.iconCollisionBox.destroy();
this.textCollisionCircle.destroy();
this.iconCollisionCircle.destroy();
}

destroy() {
this.text.destroy();
this.icon.destroy();

if (this.hasDebugData()) {
this.destroyDebugData();
}
}

addToLineVertexArray(anchor: Anchor, line: any) {
const lineStartIndex = this.lineVertexArray.length;
if (anchor.segment !== undefined) {
Expand Down Expand Up @@ -752,6 +765,15 @@ class SymbolBucket implements Bucket {
}

generateCollisionDebugBuffers() {
if (this.hasDebugData()) {
this.destroyDebugData();
}

this.textCollisionBox = new CollisionBuffers(CollisionBoxLayoutArray, collisionBoxLayout.members, LineIndexArray);
this.iconCollisionBox = new CollisionBuffers(CollisionBoxLayoutArray, collisionBoxLayout.members, LineIndexArray);
this.textCollisionCircle = new CollisionBuffers(CollisionCircleLayoutArray, collisionCircleLayout.members, TriangleIndexArray);
this.iconCollisionCircle = new CollisionBuffers(CollisionCircleLayoutArray, collisionCircleLayout.members, TriangleIndexArray);

for (let i = 0; i < this.symbolInstances.length; i++) {
const symbolInstance = this.symbolInstances.get(i);
this.addDebugCollisionBoxes(symbolInstance.textBoxStartIndex, symbolInstance.textBoxEndIndex, symbolInstance, true);
Expand Down Expand Up @@ -840,20 +862,24 @@ class SymbolBucket implements Bucket {
return this.icon.segments.get().length > 0;
}

hasDebugData() {
return this.textCollisionBox && this.iconCollisionBox && this.textCollisionCircle && this.iconCollisionCircle;
}

hasTextCollisionBoxData() {
return this.textCollisionBox.segments.get().length > 0;
return this.hasDebugData() && this.textCollisionBox.segments.get().length > 0;
}

hasIconCollisionBoxData() {
return this.iconCollisionBox.segments.get().length > 0;
return this.hasDebugData() && this.iconCollisionBox.segments.get().length > 0;
}

hasTextCollisionCircleData() {
return this.textCollisionCircle.segments.get().length > 0;
return this.hasDebugData() && this.textCollisionCircle.segments.get().length > 0;
}

hasIconCollisionCircleData() {
return this.iconCollisionCircle.segments.get().length > 0;
return this.hasDebugData() && this.iconCollisionCircle.segments.get().length > 0;
}

addIndicesForPlacedSymbol(iconOrText: SymbolBuffers, placedSymbolIndex: number) {
Expand Down

0 comments on commit f354b71

Please sign in to comment.