From ff794a70716a4c280a3fa26faf9d95e583d4511a Mon Sep 17 00:00:00 2001 From: Vladimir Agafonkin Date: Thu, 30 May 2019 17:41:12 +0300 Subject: [PATCH] switch back to a more compact line attributes layout --- src/data/array_types.js | 34 +++++++++++++-------------- src/data/bucket/line_attributes.js | 2 +- src/data/bucket/line_bucket.js | 7 +++--- src/data/extent.js | 1 - src/shaders/line.vertex.glsl | 8 ++++--- src/shaders/line_gradient.vertex.glsl | 8 ++++--- src/shaders/line_pattern.vertex.glsl | 8 ++++--- src/shaders/line_sdf.vertex.glsl | 8 ++++--- 8 files changed, 40 insertions(+), 36 deletions(-) diff --git a/src/data/array_types.js b/src/data/array_types.js index aa22f10cd21..5d5a11ba83f 100644 --- a/src/data/array_types.js +++ b/src/data/array_types.js @@ -115,12 +115,12 @@ register('StructArrayLayout2i4i12', StructArrayLayout2i4i12); /** * Implementation of the StructArray layout: - * [0]: Int16[4] - * [8]: Uint8[4] + * [0]: Int16[2] + * [4]: Uint8[4] * * @private */ -class StructArrayLayout4i4ub12 extends StructArray { +class StructArrayLayout2i4ub8 extends StructArray { uint8: Uint8Array; int16: Int16Array; @@ -129,29 +129,27 @@ class StructArrayLayout4i4ub12 extends StructArray { this.int16 = new Int16Array(this.arrayBuffer); } - emplaceBack(v0: number, v1: number, v2: number, v3: number, v4: number, v5: number, v6: number, v7: number) { + emplaceBack(v0: number, v1: number, v2: number, v3: number, v4: number, v5: number) { const i = this.length; this.resize(i + 1); - return this.emplace(i, v0, v1, v2, v3, v4, v5, v6, v7); + return this.emplace(i, v0, v1, v2, v3, v4, v5); } - emplace(i: number, v0: number, v1: number, v2: number, v3: number, v4: number, v5: number, v6: number, v7: number) { - const o2 = i * 6; - const o1 = i * 12; + emplace(i: number, v0: number, v1: number, v2: number, v3: number, v4: number, v5: number) { + const o2 = i * 4; + const o1 = i * 8; this.int16[o2 + 0] = v0; this.int16[o2 + 1] = v1; - this.int16[o2 + 2] = v2; - this.int16[o2 + 3] = v3; - this.uint8[o1 + 8] = v4; - this.uint8[o1 + 9] = v5; - this.uint8[o1 + 10] = v6; - this.uint8[o1 + 11] = v7; + this.uint8[o1 + 4] = v2; + this.uint8[o1 + 5] = v3; + this.uint8[o1 + 6] = v4; + this.uint8[o1 + 7] = v5; return i; } } -StructArrayLayout4i4ub12.prototype.bytesPerElement = 12; -register('StructArrayLayout4i4ub12', StructArrayLayout4i4ub12); +StructArrayLayout2i4ub8.prototype.bytesPerElement = 8; +register('StructArrayLayout2i4ub8', StructArrayLayout2i4ub8); /** @@ -1131,7 +1129,7 @@ export { StructArrayLayout2i4, StructArrayLayout4i8, StructArrayLayout2i4i12, - StructArrayLayout4i4ub12, + StructArrayLayout2i4ub8, StructArrayLayout8ui16, StructArrayLayout4i4ui16, StructArrayLayout3f12, @@ -1155,7 +1153,7 @@ export { StructArrayLayout2i4 as FillLayoutArray, StructArrayLayout2i4i12 as FillExtrusionLayoutArray, StructArrayLayout2i4 as HeatmapLayoutArray, - StructArrayLayout4i4ub12 as LineLayoutArray, + StructArrayLayout2i4ub8 as LineLayoutArray, StructArrayLayout8ui16 as PatternLayoutArray, StructArrayLayout4i4ui16 as SymbolLayoutArray, StructArrayLayout3f12 as SymbolDynamicLayoutArray, diff --git a/src/data/bucket/line_attributes.js b/src/data/bucket/line_attributes.js index 50e1c55f9b3..55eed22e95a 100644 --- a/src/data/bucket/line_attributes.js +++ b/src/data/bucket/line_attributes.js @@ -2,7 +2,7 @@ import { createLayout } from '../../util/struct_array'; const lineLayoutAttributes = createLayout([ - {name: 'a_pos_normal', components: 4, type: 'Int16'}, + {name: 'a_pos_normal', components: 2, type: 'Int16'}, {name: 'a_data', components: 4, type: 'Uint8'} ], 4); diff --git a/src/data/bucket/line_bucket.js b/src/data/bucket/line_bucket.js index fc5bede7782..7068d817d3b 100644 --- a/src/data/bucket/line_bucket.js +++ b/src/data/bucket/line_bucket.js @@ -66,10 +66,9 @@ const MAX_LINE_DISTANCE = Math.pow(2, LINE_DISTANCE_BUFFER_BITS - 1) / LINE_DIST function addLineVertex(layoutVertexBuffer, point: Point, extrude: Point, round: boolean, up: boolean, dir: number, linesofar: number) { layoutVertexBuffer.emplaceBack( // a_pos_normal - point.x, - point.y, - round ? 1 : 0, - up ? 1 : -1, + // Encode round/up the least significant bits + (point.x << 1) + (round ? 1 : 0), + (point.y << 1) + (up ? 1 : 0), // a_data // add 128 to store a byte in an unsigned byte Math.round(EXTRUDE_SCALE * extrude.x) + 128, diff --git a/src/data/extent.js b/src/data/extent.js index a4e99634842..cff39b9981d 100644 --- a/src/data/extent.js +++ b/src/data/extent.js @@ -9,7 +9,6 @@ * * Vertex buffer store positions as signed 16 bit integers. * * One bit is lost for signedness to support tile buffers. * * One bit is lost because the line vertex buffer used to pack 1 bit of other data into the int. - * This is no longer the case but we're reserving this bit anyway. * * One bit is lost to support features extending past the extent on the right edge of the tile. * * This leaves us with 2^13 = 8192 * diff --git a/src/shaders/line.vertex.glsl b/src/shaders/line.vertex.glsl index cb66692cc3c..9334e2b72e1 100644 --- a/src/shaders/line.vertex.glsl +++ b/src/shaders/line.vertex.glsl @@ -6,7 +6,7 @@ // #define scale 63.0 #define scale 0.015873016 -attribute vec4 a_pos_normal; +attribute vec2 a_pos_normal; attribute vec4 a_data; uniform mat4 u_matrix; @@ -43,11 +43,13 @@ void main() { v_linesofar = (floor(a_data.z / 4.0) + a_data.w * 64.0) * 2.0; - vec2 pos = a_pos_normal.xy; + vec2 pos = floor(a_pos_normal * 0.5); // x is 1 if it's a round cap, 0 otherwise // y is 1 if the normal points up, and -1 if it points down - mediump vec2 normal = a_pos_normal.zw; + // We store these in the least significant bit of a_pos_normal + mediump vec2 normal = a_pos_normal - 2.0 * pos; + normal.y = normal.y * 2.0 - 1.0; v_normal = normal; // these transformations used to be applied in the JS and native code bases. diff --git a/src/shaders/line_gradient.vertex.glsl b/src/shaders/line_gradient.vertex.glsl index d7b35d9a1c5..98281e2843c 100644 --- a/src/shaders/line_gradient.vertex.glsl +++ b/src/shaders/line_gradient.vertex.glsl @@ -10,7 +10,7 @@ // #define scale 63.0 #define scale 0.015873016 -attribute vec4 a_pos_normal; +attribute vec2 a_pos_normal; attribute vec4 a_data; uniform mat4 u_matrix; @@ -45,11 +45,13 @@ void main() { v_lineprogress = (floor(a_data.z / 4.0) + a_data.w * 64.0) * 2.0 / MAX_LINE_DISTANCE; - vec2 pos = a_pos_normal.xy; + vec2 pos = floor(a_pos_normal * 0.5); // x is 1 if it's a round cap, 0 otherwise // y is 1 if the normal points up, and -1 if it points down - mediump vec2 normal = a_pos_normal.zw; + // We store these in the least significant bit of a_pos_normal + mediump vec2 normal = a_pos_normal - 2.0 * pos; + normal.y = normal.y * 2.0 - 1.0; v_normal = normal; // these transformations used to be applied in the JS and native code bases. diff --git a/src/shaders/line_pattern.vertex.glsl b/src/shaders/line_pattern.vertex.glsl index 2ac485f167b..6b4eb54c87a 100644 --- a/src/shaders/line_pattern.vertex.glsl +++ b/src/shaders/line_pattern.vertex.glsl @@ -10,7 +10,7 @@ // long distances for long segments. Use this value to unscale the distance. #define LINE_DISTANCE_SCALE 2.0 -attribute vec4 a_pos_normal; +attribute vec2 a_pos_normal; attribute vec4 a_data; uniform mat4 u_matrix; @@ -48,11 +48,13 @@ void main() { float a_direction = mod(a_data.z, 4.0) - 1.0; float a_linesofar = (floor(a_data.z / 4.0) + a_data.w * 64.0) * LINE_DISTANCE_SCALE; // float tileRatio = u_scale.y; - vec2 pos = a_pos_normal.xy; + vec2 pos = floor(a_pos_normal * 0.5); // x is 1 if it's a round cap, 0 otherwise // y is 1 if the normal points up, and -1 if it points down - mediump vec2 normal = a_pos_normal.zw; + // We store these in the least significant bit of a_pos_normal + mediump vec2 normal = a_pos_normal - 2.0 * pos; + normal.y = normal.y * 2.0 - 1.0; v_normal = normal; // these transformations used to be applied in the JS and native code bases. diff --git a/src/shaders/line_sdf.vertex.glsl b/src/shaders/line_sdf.vertex.glsl index 0c6bb632433..c85140ef7c4 100644 --- a/src/shaders/line_sdf.vertex.glsl +++ b/src/shaders/line_sdf.vertex.glsl @@ -10,7 +10,7 @@ // long distances for long segments. Use this value to unscale the distance. #define LINE_DISTANCE_SCALE 2.0 -attribute vec4 a_pos_normal; +attribute vec2 a_pos_normal; attribute vec4 a_data; uniform mat4 u_matrix; @@ -53,11 +53,13 @@ void main() { float a_direction = mod(a_data.z, 4.0) - 1.0; float a_linesofar = (floor(a_data.z / 4.0) + a_data.w * 64.0) * LINE_DISTANCE_SCALE; - vec2 pos = a_pos_normal.xy; + vec2 pos = floor(a_pos_normal * 0.5); // x is 1 if it's a round cap, 0 otherwise // y is 1 if the normal points up, and -1 if it points down - mediump vec2 normal = a_pos_normal.zw; + // We store these in the least significant bit of a_pos_normal + mediump vec2 normal = a_pos_normal - 2.0 * pos; + normal.y = normal.y * 2.0 - 1.0; v_normal = normal; // these transformations used to be applied in the JS and native code bases.