From 63b7b02f2c8eaadf47e62abe8093405efb8397c9 Mon Sep 17 00:00:00 2001 From: Lauren Budorick Date: Fri, 15 Dec 2017 10:36:34 -0800 Subject: [PATCH 01/11] Introduce state management for uniform bindings * Introduce uniform bining classes * Set uniforms and color/depth/stencil modes within Program#draw * Use drawElements exclusively (eliminate all uses of drawArrays) --- build/generate-struct-arrays.js | 5 + src/data/array_types.js | 33 ++- src/data/index_array_type.js | 12 +- src/data/program_configuration.js | 78 ++++--- src/data/segment.js | 10 + src/geo/transform.js | 2 +- src/gl/context.js | 4 +- src/gl/index_buffer.js | 4 +- src/gl/vertex_buffer.js | 4 +- src/render/draw_background.js | 49 ++--- src/render/draw_circle.js | 49 +---- src/render/draw_collision_debug.js | 38 +--- src/render/draw_debug.js | 46 ++-- src/render/draw_fill.js | 136 +++++------- src/render/draw_fill_extrusion.js | 119 ++++------- src/render/draw_heatmap.js | 67 ++---- src/render/draw_hillshade.js | 94 +++----- src/render/draw_line.js | 98 ++------- src/render/draw_raster.js | 78 ++----- src/render/draw_symbol.js | 119 ++++------- src/render/painter.js | 99 +++++---- src/render/pattern.js | 63 ------ src/render/program.js | 37 +++- src/render/program/background_program.js | 101 +++++++++ src/render/program/circle_program.js | 66 ++++++ src/render/program/clipping_mask_program.js | 20 ++ src/render/program/collision_program.js | 50 +++++ src/render/program/debug_program.js | 28 +++ src/render/program/fill_extrusion_program.js | 158 ++++++++++++++ src/render/program/fill_program.js | 157 ++++++++++++++ src/render/program/heatmap_program.js | 84 ++++++++ src/render/program/hillshade_program.js | 122 +++++++++++ src/render/program/line_program.js | 213 +++++++++++++++++++ src/render/program/pattern.js | 66 ++++++ src/render/program/program_uniforms.js | 42 ++++ src/render/program/raster_program.js | 93 ++++++++ src/render/program/symbol_program.js | 153 +++++++++++++ src/render/texture.js | 2 +- src/render/uniform_binding.js | 123 +++++++++++ src/render/vertex_array_object.js | 6 +- src/source/canvas_source.js | 6 +- src/source/image_source.js | 8 +- src/source/source_cache.js | 3 - src/source/video_source.js | 6 +- src/style-spec/util/color.js | 2 + test/unit/render/uniform_binding.test.js | 125 +++++++++++ 46 files changed, 2120 insertions(+), 758 deletions(-) delete mode 100644 src/render/pattern.js create mode 100644 src/render/program/background_program.js create mode 100644 src/render/program/circle_program.js create mode 100644 src/render/program/clipping_mask_program.js create mode 100644 src/render/program/collision_program.js create mode 100644 src/render/program/debug_program.js create mode 100644 src/render/program/fill_extrusion_program.js create mode 100644 src/render/program/fill_program.js create mode 100644 src/render/program/heatmap_program.js create mode 100644 src/render/program/hillshade_program.js create mode 100644 src/render/program/line_program.js create mode 100644 src/render/program/pattern.js create mode 100644 src/render/program/program_uniforms.js create mode 100644 src/render/program/raster_program.js create mode 100644 src/render/program/symbol_program.js create mode 100644 src/render/uniform_binding.js create mode 100644 test/unit/render/uniform_binding.test.js diff --git a/build/generate-struct-arrays.js b/build/generate-struct-arrays.js index e3ed0c2eff1..071f41e738c 100644 --- a/build/generate-struct-arrays.js +++ b/build/generate-struct-arrays.js @@ -185,6 +185,11 @@ createStructArrayType('line_index', createLayout([ { type: 'Uint16', name: 'vertices', components: 2 } ])); +// line strip index array +createStructArrayType('line_strip_index', createLayout([ + { type: 'Uint16', name: 'vertices', components: 1 } +])); + // paint vertex arrays // used by SourceBinder for float properties diff --git a/src/data/array_types.js b/src/data/array_types.js index 91096279e3d..635c0f83f10 100644 --- a/src/data/array_types.js +++ b/src/data/array_types.js @@ -709,6 +709,35 @@ StructArrayLayout2ui4.prototype.bytesPerElement = 4; register('StructArrayLayout2ui4', StructArrayLayout2ui4); +/** + * Implementation of the StructArray layout: + * [0]: Uint16[1] + * + * @private + */ +class StructArrayLayout1ui2 extends StructArray { + uint8: Uint8Array; + uint16: Uint16Array; + + _refreshViews() { + this.uint8 = new Uint8Array(this.arrayBuffer); + this.uint16 = new Uint16Array(this.arrayBuffer); + } + + emplaceBack(v0: number) { + const i = this.length; + this.resize(i + 1); + const o2 = i * 1; + this.uint16[o2 + 0] = v0; + return i; + } + +} + +StructArrayLayout1ui2.prototype.bytesPerElement = 2; +register('StructArrayLayout1ui2', StructArrayLayout1ui2); + + /** * Implementation of the StructArray layout: * [0]: Float32[2] @@ -1030,6 +1059,7 @@ export { StructArrayLayout1ul2ui8, StructArrayLayout3ui6, StructArrayLayout2ui4, + StructArrayLayout1ui2, StructArrayLayout2f8, StructArrayLayout4f16, StructArrayLayout2i4 as PosArray, @@ -1046,5 +1076,6 @@ export { StructArrayLayout2i2i2i12 as CollisionCircleLayoutArray, StructArrayLayout2ub4 as CollisionVertexArray, StructArrayLayout3ui6 as TriangleIndexArray, - StructArrayLayout2ui4 as LineIndexArray + StructArrayLayout2ui4 as LineIndexArray, + StructArrayLayout1ui2 as LineStripIndexArray }; diff --git a/src/data/index_array_type.js b/src/data/index_array_type.js index 0678a0fdc01..98db8a86b19 100644 --- a/src/data/index_array_type.js +++ b/src/data/index_array_type.js @@ -2,13 +2,15 @@ import { LineIndexArray, - TriangleIndexArray + TriangleIndexArray, + LineStripIndexArray } from './array_types'; /** - * An index array stores Uint16 indicies of vertexes in a corresponding vertex array. We use - * two kinds of index arrays: arrays storing groups of three indicies, forming triangles; and - * arrays storing pairs of indicies, forming line segments. + * An index array stores Uint16 indices of vertexes in a corresponding vertex array. We use + * three kinds of index arrays: arrays storing groups of three indices, forming triangles; + * arrays storing pairs of indices, forming line segments; and arrays storing single indices, + * forming a line strip. * @private */ -export {LineIndexArray, TriangleIndexArray}; +export {LineIndexArray, TriangleIndexArray, LineStripIndexArray}; diff --git a/src/data/program_configuration.js b/src/data/program_configuration.js index bb3eb38ae7e..ffc5d64f68c 100644 --- a/src/data/program_configuration.js +++ b/src/data/program_configuration.js @@ -7,6 +7,7 @@ import { register } from '../util/web_worker_transfer'; import { PossiblyEvaluatedPropertyValue } from '../style/properties'; import { StructArrayLayout1f4, StructArrayLayout2f8, StructArrayLayout4f16 } from './array_types'; import EvaluationParameters from '../style/evaluation_parameters'; +import { Uniform, Uniform1f, Uniform4fv } from '../render/uniform_binding'; import type Context from '../gl/context'; import type {TypedStyleLayer} from '../style/style_layer/typed_style_layer'; @@ -62,8 +63,11 @@ function packColor(color: Color): [number, number] { * * @private */ + interface Binder { statistics: { max: number }; + uniformName: string; + uniformBinding: ?$Subtype>; populatePaintArray(length: number, feature: Feature): void; updatePaintArray(start: number, length: number, feature: Feature, featureState: FeatureState): void; @@ -72,21 +76,22 @@ interface Binder { defines(): Array; - setUniforms(context: Context, - program: Program, - globals: GlobalProperties, - currentValue: PossiblyEvaluatedPropertyValue): void; + setUniforms(context: Context, program: Program<*>, invalidate: boolean, + globals: GlobalProperties, currentValue: PossiblyEvaluatedPropertyValue): void; } class ConstantBinder implements Binder { value: T; name: string; - type: string; statistics: { max: number }; + type: string; + uniformName: string; + uniformBinding: ?$Subtype>; constructor(value: T, name: string, type: string) { this.value = value; this.name = name; + this.uniformName = `u_${this.name}`; this.type = type; this.statistics = { max: -Infinity }; } @@ -100,25 +105,25 @@ class ConstantBinder implements Binder { upload() {} destroy() {} - setUniforms(context: Context, - program: Program, - globals: GlobalProperties, - currentValue: PossiblyEvaluatedPropertyValue) { - const value: any = currentValue.constantOr(this.value); - const gl = context.gl; - if (this.type === 'color') { - gl.uniform4f(program.uniforms[`u_${this.name}`], value.r, value.g, value.b, value.a); - } else { - gl.uniform1f(program.uniforms[`u_${this.name}`], value); + setUniforms(context: Context, program: Program<*>, invalidate: boolean, + globals: GlobalProperties, currentValue: PossiblyEvaluatedPropertyValue): void { + const value = currentValue.constantOr(this.value); + + if (!this.uniformBinding) { + this.uniformBinding = this.type === 'color' ? new Uniform4fv(context) : new Uniform1f(context); } + + this.uniformBinding.set(program.uniforms[this.uniformName], (value: any), invalidate); } } class SourceExpressionBinder implements Binder { expression: SourceExpression; name: string; + uniformName: string; type: string; statistics: { max: number }; + uniformBinding: ?Uniform1f; paintVertexArray: StructArray; paintVertexAttributes: Array; @@ -128,6 +133,7 @@ class SourceExpressionBinder implements Binder { this.expression = expression; this.name = name; this.type = type; + this.uniformName = `a_${name}`; this.statistics = { max: -Infinity }; const PaintVertexArray = type === 'color' ? StructArrayLayout2f8 : StructArrayLayout1f4; this.paintVertexAttributes = [{ @@ -199,18 +205,25 @@ class SourceExpressionBinder implements Binder { } } - setUniforms(context: Context, program: Program) { - context.gl.uniform1f(program.uniforms[`a_${this.name}_t`], 0); + setUniforms(context: Context, program: Program<*>, invalidate: boolean): void { + if (!this.uniformBinding) { + this.uniformBinding = new Uniform1f(context); + this.uniformBinding.set(program.uniforms[this.uniformName], 0); + } else if (invalidate) { + this.uniformBinding.set(program.uniforms[this.uniformName], 0, invalidate); + } } } class CompositeExpressionBinder implements Binder { expression: CompositeExpression; name: string; + uniformName: string; type: string; useIntegerZoom: boolean; zoom: number; statistics: { max: number }; + uniformBinding: ?Uniform1f; paintVertexArray: StructArray; paintVertexAttributes: Array; @@ -219,6 +232,7 @@ class CompositeExpressionBinder implements Binder { constructor(expression: CompositeExpression, name: string, type: string, useIntegerZoom: boolean, zoom: number) { this.expression = expression; this.name = name; + this.uniformName = `a_${this.name}_t`; this.type = type; this.useIntegerZoom = useIntegerZoom; this.zoom = zoom; @@ -306,8 +320,13 @@ class CompositeExpressionBinder implements Binder { } } - setUniforms(context: Context, program: Program, globals: GlobalProperties) { - context.gl.uniform1f(program.uniforms[`a_${this.name}_t`], this.interpolationFactor(globals.zoom)); + setUniforms(context: Context, program: Program<*>, invalidate: boolean, + globals: GlobalProperties): void { + if (!this.uniformBinding) { + this.uniformBinding = new Uniform1f(context); + } + + this.uniformBinding.set(program.uniforms[this.uniformName], this.interpolationFactor(globals.zoom), invalidate); } } @@ -335,6 +354,7 @@ export default class ProgramConfiguration { binders: { [string]: Binder }; cacheKey: string; layoutAttributes: Array; + program: ?Program<*>; _buffers: Array; @@ -432,17 +452,25 @@ export default class ProgramConfiguration { return result; } - setUniforms(context: Context, program: Program, properties: PossiblyEvaluated, globals: GlobalProperties) { + getPaintVertexBuffers(): Array { + return this._buffers; + } + + setUniforms(context: Context, program: Program<*>, properties: PossiblyEvaluated, globals: GlobalProperties, invalidate: boolean) { + // We maintain a reference here to the last Program used, and a reference + // on each Program to the last ProgramConfiguration used: if these match, + // we can assume the uniform bindings haven't changed, but if we're using + // a different ProgramConfiguration for the same Program or a different + // Program with the same ProgramConfiguration, our tracked uniform state + // won't be right, so we invalidate the old bindings here. + invalidate = invalidate || this.program !== program; + for (const property in this.binders) { const binder = this.binders[property]; - binder.setUniforms(context, program, globals, properties.get(property)); + binder.setUniforms(context, program, invalidate, globals, properties.get(property)); } } - getPaintVertexBuffers(): Array { - return this._buffers; - } - upload(context: Context) { for (const property in this.binders) { this.binders[property].upload(context); diff --git a/src/data/segment.js b/src/data/segment.js index 5cd8e3c1a1b..2aab0df686a 100644 --- a/src/data/segment.js +++ b/src/data/segment.js @@ -49,6 +49,16 @@ class SegmentVector { } } } + + static simpleSegment(vertexOffset: number, primitiveOffset: number, vertexLength: number, primitiveLength: number): SegmentVector { + return new SegmentVector([{ + vertexOffset: vertexOffset, + primitiveOffset: primitiveOffset, + vertexLength: vertexLength, + primitiveLength: primitiveLength, + vaos: {} + }]); + } } /* diff --git a/src/geo/transform.js b/src/geo/transform.js index 4ba14e5966a..e242d3482f4 100644 --- a/src/geo/transform.js +++ b/src/geo/transform.js @@ -28,7 +28,7 @@ class Transform { angle: number; rotationMatrix: Float64Array; zoomFraction: number; - pixelsToGLUnits: Array; + pixelsToGLUnits: [number, number]; cameraToCenterDistance: number; projMatrix: Float64Array; alignedProjMatrix: Float64Array; diff --git a/src/gl/context.js b/src/gl/context.js index cbbcf5e51b7..24ed780d0b1 100644 --- a/src/gl/context.js +++ b/src/gl/context.js @@ -10,7 +10,7 @@ import { deepEqual } from '../util/util'; import { ClearColor, ClearDepth, ClearStencil, ColorMask, DepthMask, StencilMask, StencilFunc, StencilOp, StencilTest, DepthRange, DepthTest, DepthFunc, Blend, BlendFunc, BlendColor, Program, ActiveTextureUnit, Viewport, BindFramebuffer, BindRenderbuffer, BindTexture, BindVertexBuffer, BindElementBuffer, BindVertexArrayOES, PixelStoreUnpack, PixelStoreUnpackPremultiplyAlpha } from './value'; -import type {TriangleIndexArray, LineIndexArray} from '../data/index_array_type'; +import type {TriangleIndexArray, LineIndexArray, LineStripIndexArray} from '../data/index_array_type'; import type { StructArray, StructArrayMember @@ -107,7 +107,7 @@ class Context { } - createIndexBuffer(array: TriangleIndexArray | LineIndexArray, dynamicDraw?: boolean) { + createIndexBuffer(array: TriangleIndexArray | LineIndexArray | LineStripIndexArray, dynamicDraw?: boolean) { return new IndexBuffer(this, array, dynamicDraw); } diff --git a/src/gl/index_buffer.js b/src/gl/index_buffer.js index 2bfdd72a824..e4ca6365453 100644 --- a/src/gl/index_buffer.js +++ b/src/gl/index_buffer.js @@ -2,7 +2,7 @@ import assert from 'assert'; import type {StructArray} from '../util/struct_array'; -import type {TriangleIndexArray, LineIndexArray} from '../data/index_array_type'; +import type {TriangleIndexArray, LineIndexArray, LineStripIndexArray} from '../data/index_array_type'; import type Context from '../gl/context'; @@ -11,7 +11,7 @@ class IndexBuffer { buffer: WebGLBuffer; dynamicDraw: boolean; - constructor(context: Context, array: TriangleIndexArray | LineIndexArray, dynamicDraw?: boolean) { + constructor(context: Context, array: TriangleIndexArray | LineIndexArray | LineStripIndexArray, dynamicDraw?: boolean) { this.context = context; const gl = context.gl; this.buffer = gl.createBuffer(); diff --git a/src/gl/vertex_buffer.js b/src/gl/vertex_buffer.js index d6294771832..72b9d09adba 100644 --- a/src/gl/vertex_buffer.js +++ b/src/gl/vertex_buffer.js @@ -69,7 +69,7 @@ class VertexBuffer { gl.bufferSubData(gl.ARRAY_BUFFER, 0, array.arrayBuffer); } - enableAttributes(gl: WebGLRenderingContext, program: Program) { + enableAttributes(gl: WebGLRenderingContext, program: Program<*>) { for (let j = 0; j < this.attributes.length; j++) { const member = this.attributes[j]; const attribIndex: number | void = program.attributes[member.name]; @@ -85,7 +85,7 @@ class VertexBuffer { * @param program The active WebGL program * @param vertexOffset Index of the starting vertex of the segment */ - setVertexAttribPointers(gl: WebGLRenderingContext, program: Program, vertexOffset: ?number) { + setVertexAttribPointers(gl: WebGLRenderingContext, program: Program<*>, vertexOffset: ?number) { for (let j = 0; j < this.attributes.length; j++) { const member = this.attributes[j]; const attribIndex: number | void = program.attributes[member.name]; diff --git a/src/render/draw_background.js b/src/render/draw_background.js index 60ced066058..5f81d90dae3 100644 --- a/src/render/draw_background.js +++ b/src/render/draw_background.js @@ -1,13 +1,11 @@ // @flow -import { - isPatternMissing, - setPatternUniforms, - prepare as preparePattern -} from './pattern'; - import StencilMode from '../gl/stencil_mode'; import DepthMode from '../gl/depth_mode'; +import { + backgroundUniformValues, + backgroundPatternUniformValues +} from './program/background_program'; import type Painter from './painter'; import type SourceCache from '../source/source_cache'; @@ -26,34 +24,33 @@ function drawBackground(painter: Painter, sourceCache: SourceCache, layer: Backg const transform = painter.transform; const tileSize = transform.tileSize; const image = layer.paint.get('background-pattern'); + if (painter.isPatternMissing(image)) return; const pass = (!image && color.a === 1 && opacity === 1) ? 'opaque' : 'translucent'; if (painter.renderPass !== pass) return; - context.setStencilMode(StencilMode.disabled); - context.setDepthMode(painter.depthModeForSublayer(0, pass === 'opaque' ? DepthMode.ReadWrite : DepthMode.ReadOnly)); - context.setColorMode(painter.colorModeForRenderPass()); + const stencilMode = StencilMode.disabled; + const depthMode = painter.depthModeForSublayer(0, pass === 'opaque' ? DepthMode.ReadWrite : DepthMode.ReadOnly); + const colorMode = painter.colorModeForRenderPass(); - let program; - if (image) { - if (isPatternMissing(image, painter)) return; - program = painter.useProgram('backgroundPattern'); - preparePattern(image, painter, program); - painter.tileExtentPatternVAO.bind(context, program, painter.tileExtentBuffer, []); - } else { - program = painter.useProgram('background'); - gl.uniform4f(program.uniforms.u_color, color.r, color.g, color.b, color.a); - painter.tileExtentVAO.bind(context, program, painter.tileExtentBuffer, []); - } + const program = painter.useProgram(image ? 'backgroundPattern' : 'background'); - gl.uniform1f(program.uniforms.u_opacity, opacity); const tileIDs = transform.coveringTiles({tileSize}); + if (image) { + context.activeTexture.set(gl.TEXTURE0); + painter.imageManager.bind(painter.context); + } + for (const tileID of tileIDs) { - if (image) { - setPatternUniforms({tileID, tileSize}, painter, program); - } - gl.uniformMatrix4fv(program.uniforms.u_matrix, false, painter.transform.calculatePosMatrix(tileID.toUnwrapped())); - gl.drawArrays(gl.TRIANGLE_STRIP, 0, painter.tileExtentBuffer.length); + const matrix = painter.transform.calculatePosMatrix(tileID.toUnwrapped()); + + const uniformValues = image ? + backgroundPatternUniformValues(matrix, opacity, painter, image, {tileID, tileSize}) : + backgroundUniformValues(matrix, opacity, color); + + program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, + uniformValues, layer.id, painter.tileExtentBuffer, + painter.quadTriangleIndexBuffer, painter.tileExtentSegments); } } diff --git a/src/render/draw_circle.js b/src/render/draw_circle.js index 9a80dfdd61f..34d86f7f0ff 100644 --- a/src/render/draw_circle.js +++ b/src/render/draw_circle.js @@ -1,9 +1,8 @@ // @flow -import pixelsToTileUnits from '../source/pixels_to_tile_units'; - import StencilMode from '../gl/stencil_mode'; import DepthMode from '../gl/depth_mode'; +import { circleUniformValues } from './program/circle_program'; import type Painter from './painter'; import type SourceCache from '../source/source_cache'; @@ -27,13 +26,12 @@ function drawCircles(painter: Painter, sourceCache: SourceCache, layer: CircleSt const context = painter.context; const gl = context.gl; - context.setDepthMode(painter.depthModeForSublayer(0, DepthMode.ReadOnly)); - // Allow circles to be drawn across boundaries, so that - // large circles are not clipped to tiles - context.setStencilMode(StencilMode.disabled); - context.setColorMode(painter.colorModeForRenderPass()); + const depthMode = painter.depthModeForSublayer(0, DepthMode.ReadOnly); + // Turn off stencil testing to allow circles to be drawn across boundaries, + // so that large circles are not clipped to tiles + const stencilMode = StencilMode.disabled; + const colorMode = painter.colorModeForRenderPass(); - let first = true; for (let i = 0; i < coords.length; i++) { const coord = coords[i]; @@ -41,39 +39,12 @@ function drawCircles(painter: Painter, sourceCache: SourceCache, layer: CircleSt const bucket: ?CircleBucket<*> = (tile.getBucket(layer): any); if (!bucket) continue; - const prevProgram = painter.context.program.get(); const programConfiguration = bucket.programConfigurations.get(layer.id); const program = painter.useProgram('circle', programConfiguration); - if (first || program.program !== prevProgram) { - programConfiguration.setUniforms(context, program, layer.paint, {zoom: painter.transform.zoom}); - first = false; - } - - gl.uniform1f(program.uniforms.u_camera_to_center_distance, painter.transform.cameraToCenterDistance); - gl.uniform1i(program.uniforms.u_scale_with_map, layer.paint.get('circle-pitch-scale') === 'map' ? 1 : 0); - if (layer.paint.get('circle-pitch-alignment') === 'map') { - gl.uniform1i(program.uniforms.u_pitch_with_map, 1); - const pixelRatio = pixelsToTileUnits(tile, 1, painter.transform.zoom); - gl.uniform2f(program.uniforms.u_extrude_scale, pixelRatio, pixelRatio); - } else { - gl.uniform1i(program.uniforms.u_pitch_with_map, 0); - gl.uniform2fv(program.uniforms.u_extrude_scale, painter.transform.pixelsToGLUnits); - } - - gl.uniformMatrix4fv(program.uniforms.u_matrix, false, painter.translatePosMatrix( - coord.posMatrix, - tile, - layer.paint.get('circle-translate'), - layer.paint.get('circle-translate-anchor') - )); - program.draw( - context, - gl.TRIANGLES, - layer.id, - bucket.layoutVertexBuffer, - bucket.indexBuffer, - bucket.segments, - programConfiguration); + program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, + circleUniformValues(painter, coord, tile, layer), layer.id, + bucket.layoutVertexBuffer, bucket.indexBuffer, bucket.segments, + layer.paint, painter.transform.zoom, programConfiguration); } } diff --git a/src/render/draw_collision_debug.js b/src/render/draw_collision_debug.js index 2a12ffb9fa7..ba78c5ee865 100644 --- a/src/render/draw_collision_debug.js +++ b/src/render/draw_collision_debug.js @@ -5,9 +5,9 @@ import type SourceCache from '../source/source_cache'; import type StyleLayer from '../style/style_layer'; import type {OverscaledTileID} from '../source/tile_id'; import type SymbolBucket from '../data/bucket/symbol_bucket'; -import pixelsToTileUnits from '../source/pixels_to_tile_units'; import DepthMode from '../gl/depth_mode'; import StencilMode from '../gl/stencil_mode'; +import { collisionUniformValues } from './program/collision_program'; export default drawCollisionDebug; @@ -16,10 +16,6 @@ function drawCollisionDebugGeometry(painter: Painter, sourceCache: SourceCache, const gl = context.gl; const program = drawCircles ? painter.useProgram('collisionCircle') : painter.useProgram('collisionBox'); - context.setDepthMode(DepthMode.disabled); - context.setStencilMode(StencilMode.disabled); - context.setColorMode(painter.colorModeForRenderPass()); - for (let i = 0; i < coords.length; i++) { const coord = coords[i]; const tile = sourceCache.getTile(coord); @@ -28,28 +24,16 @@ function drawCollisionDebugGeometry(painter: Painter, sourceCache: SourceCache, const buffers = drawCircles ? bucket.collisionCircle : bucket.collisionBox; if (!buffers) continue; - - gl.uniformMatrix4fv(program.uniforms.u_matrix, false, coord.posMatrix); - - gl.uniform1f(program.uniforms.u_camera_to_center_distance, painter.transform.cameraToCenterDistance); - const pixelRatio = pixelsToTileUnits(tile, 1, painter.transform.zoom); - const scale = Math.pow(2, painter.transform.zoom - tile.tileID.overscaledZ); - gl.uniform1f(program.uniforms.u_pixels_to_tile_units, pixelRatio); - gl.uniform2f(program.uniforms.u_extrude_scale, - painter.transform.pixelsToGLUnits[0] / (pixelRatio * scale), - painter.transform.pixelsToGLUnits[1] / (pixelRatio * scale)); - gl.uniform1f(program.uniforms.u_overscale_factor, tile.tileID.overscaleFactor()); - - program.draw( - context, - drawCircles ? gl.TRIANGLES : gl.LINES, - layer.id, - buffers.layoutVertexBuffer, - buffers.indexBuffer, - buffers.segments, - null, - buffers.collisionVertexBuffer, - null); + program.draw(context, drawCircles ? gl.TRIANGLES : gl.LINES, + DepthMode.disabled, StencilMode.disabled, + painter.colorModeForRenderPass(), + collisionUniformValues( + coord.posMatrix, + painter.transform, + tile), + layer.id, buffers.layoutVertexBuffer, buffers.indexBuffer, + buffers.segments, null, painter.transform.zoom, null, null, + buffers.collisionVertexBuffer); } } diff --git a/src/render/draw_debug.js b/src/render/draw_debug.js index e9fc0a4fae7..7bdbe19281b 100644 --- a/src/render/draw_debug.js +++ b/src/render/draw_debug.js @@ -2,11 +2,14 @@ import { mat4 } from 'gl-matrix'; import EXTENT from '../data/extent'; -import VertexArrayObject from './vertex_array_object'; import { PosArray } from '../data/array_types'; +import { LineIndexArray } from '../data/index_array_type'; import posAttributes from '../data/pos_attributes'; +import SegmentVector from '../data/segment'; import DepthMode from '../gl/depth_mode'; import StencilMode from '../gl/stencil_mode'; +import { debugUniformValues } from './program/debug_program'; +import Color from '../style-spec/util/color'; import type Painter from './painter'; import type SourceCache from '../source/source_cache'; @@ -27,24 +30,25 @@ function drawDebugTile(painter, sourceCache, coord) { const posMatrix = coord.posMatrix; const program = painter.useProgram('debug'); - context.setDepthMode(DepthMode.disabled); - context.setStencilMode(StencilMode.disabled); - context.setColorMode(painter.colorModeForRenderPass()); + const depthMode = DepthMode.disabled; + const stencilMode = StencilMode.disabled; + const colorMode = painter.colorModeForRenderPass(); + const id = '$debug'; - gl.uniformMatrix4fv(program.uniforms.u_matrix, false, posMatrix); - gl.uniform4f(program.uniforms.u_color, 1, 0, 0, 1); - painter.debugVAO.bind(context, program, painter.debugBuffer, []); - gl.drawArrays(gl.LINE_STRIP, 0, painter.debugBuffer.length); + program.draw(context, gl.LINE_STRIP, depthMode, stencilMode, colorMode, + debugUniformValues(posMatrix, Color.red), id, + painter.debugBuffer, painter.tileBorderIndexBuffer, painter.debugSegments); - const vertices = createTextVerticies(coord.toString(), 50, 200, 5); + const vertices = createTextVertices(coord.toString(), 50, 200, 5); const debugTextArray = new PosArray(); + const debugTextIndices = new LineIndexArray(); for (let v = 0; v < vertices.length; v += 2) { debugTextArray.emplaceBack(vertices[v], vertices[v + 1]); + debugTextIndices.emplaceBack(v, v + 1); } const debugTextBuffer = context.createVertexBuffer(debugTextArray, posAttributes.members); - const debugTextVAO = new VertexArrayObject(); - debugTextVAO.bind(context, program, debugTextBuffer, []); - gl.uniform4f(program.uniforms.u_color, 1, 1, 1, 1); + const debugTextIndexBuffer = context.createIndexBuffer(debugTextIndices); + const debugTextSegment = SegmentVector.simpleSegment(0, 0, debugTextArray.length / 2, debugTextArray.length / 2); // Draw the halo with multiple 1px lines instead of one wider line because // the gl spec doesn't guarantee support for lines with width > 1. @@ -53,13 +57,19 @@ function drawDebugTile(painter, sourceCache, coord) { const translations = [[-1, -1], [-1, 1], [1, -1], [1, 1]]; for (let i = 0; i < translations.length; i++) { const translation = translations[i]; - gl.uniformMatrix4fv(program.uniforms.u_matrix, false, mat4.translate([], posMatrix, [onePixel * translation[0], onePixel * translation[1], 0])); - gl.drawArrays(gl.LINES, 0, debugTextBuffer.length); + + program.draw(context, gl.LINES, depthMode, stencilMode, colorMode, + debugUniformValues( + mat4.translate([], posMatrix, [ + onePixel * translation[0], + onePixel * translation[1], 0]), + Color.white), + id, debugTextBuffer, debugTextIndexBuffer, debugTextSegment); } - gl.uniform4f(program.uniforms.u_color, 0, 0, 0, 1); - gl.uniformMatrix4fv(program.uniforms.u_matrix, false, posMatrix); - gl.drawArrays(gl.LINES, 0, debugTextBuffer.length); + program.draw(context, gl.LINES, depthMode, stencilMode, colorMode, + debugUniformValues(posMatrix, Color.black), id, + debugTextBuffer, debugTextIndexBuffer, debugTextSegment); } // Font data From Hershey Simplex Font @@ -162,7 +172,7 @@ const simplexFont = { "~": [24, [3, 6, 3, 8, 4, 11, 6, 12, 8, 12, 10, 11, 14, 8, 16, 7, 18, 7, 20, 8, 21, 10, -1, -1, 3, 8, 4, 10, 6, 11, 8, 11, 10, 10, 14, 7, 16, 6, 18, 6, 20, 7, 21, 10, 21, 12]] }; -function createTextVerticies(text, left, baseline, scale) { +function createTextVertices(text, left, baseline, scale) { scale = scale || 1; const strokes = []; diff --git a/src/render/draw_fill.js b/src/render/draw_fill.js index 4b53d588920..3c853898f33 100644 --- a/src/render/draw_fill.js +++ b/src/render/draw_fill.js @@ -1,20 +1,19 @@ // @flow -import { - isPatternMissing, - setPatternUniforms, - prepare as preparePattern -} from './pattern'; - import Color from '../style-spec/util/color'; import DepthMode from '../gl/depth_mode'; +import { + fillUniformValues, + fillPatternUniformValues, + fillOutlineUniformValues, + fillOutlinePatternUniformValues +} from './program/fill_program'; import type Painter from './painter'; import type SourceCache from '../source/source_cache'; import type FillStyleLayer from '../style/style_layer/fill_style_layer'; import type FillBucket from '../data/bucket/fill_bucket'; import type {OverscaledTileID} from '../source/tile_id'; -import type {CrossFaded} from '../style/cross_faded'; export default drawFill; @@ -26,8 +25,7 @@ function drawFill(painter: Painter, sourceCache: SourceCache, layer: FillStyleLa return; } - const context = painter.context; - context.setColorMode(painter.colorModeForRenderPass()); + const colorMode = painter.colorModeForRenderPass(); const pass = (!layer.paint.get('fill-pattern') && color.constantOr(Color.transparent).a === 1 && @@ -35,10 +33,9 @@ function drawFill(painter: Painter, sourceCache: SourceCache, layer: FillStyleLa // Draw fill if (painter.renderPass === pass) { - // Once we switch to earcut drawing we can pull most of the WebGL setup - // outside of this coords loop. - context.setDepthMode(painter.depthModeForSublayer(1, painter.renderPass === 'opaque' ? DepthMode.ReadWrite : DepthMode.ReadOnly)); - drawFillTiles(painter, sourceCache, layer, coords, drawFillTile); + const depthMode = painter.depthModeForSublayer( + 1, painter.renderPass === 'opaque' ? DepthMode.ReadWrite : DepthMode.ReadOnly); + drawFillTiles(painter, sourceCache, layer, coords, depthMode, colorMode, false); } // Draw stroke @@ -52,81 +49,62 @@ function drawFill(painter: Painter, sourceCache: SourceCache, layer: FillStyleLa // or stroke color is translucent. If we wouldn't clip to outside // the current shape, some pixels from the outline stroke overlapped // the (non-antialiased) fill. - context.setDepthMode(painter.depthModeForSublayer( - layer.getPaintProperty('fill-outline-color') ? 2 : 0, DepthMode.ReadOnly)); - drawFillTiles(painter, sourceCache, layer, coords, drawStrokeTile); + const depthMode = painter.depthModeForSublayer( + layer.getPaintProperty('fill-outline-color') ? 2 : 0, DepthMode.ReadOnly); + drawFillTiles(painter, sourceCache, layer, coords, depthMode, colorMode, true); } } -function drawFillTiles(painter, sourceCache, layer, coords, drawFn) { - if (isPatternMissing(layer.paint.get('fill-pattern'), painter)) return; +function drawFillTiles(painter, sourceCache, layer, coords, depthMode, colorMode, isOutline) { + const gl = painter.context.gl; - let firstTile = true; - for (const coord of coords) { - const tile = sourceCache.getTile(coord); - const bucket: ?FillBucket = (tile.getBucket(layer): any); - if (!bucket) continue; + const image = layer.paint.get('fill-pattern'); + if (painter.isPatternMissing(image)) return; + + let drawMode, programName, uniformValues, indexBuffer, segments; - painter.context.setStencilMode(painter.stencilModeForClipping(coord)); - drawFn(painter, sourceCache, layer, tile, coord, bucket, firstTile); - firstTile = false; + if (!isOutline) { + programName = image ? 'fillPattern' : 'fill'; + drawMode = gl.TRIANGLES; + } else { + programName = image && !layer.getPaintProperty('fill-outline-color') ? 'fillOutlinePattern' : 'fillOutline'; + drawMode = gl.LINES; } -} -function drawFillTile(painter, sourceCache, layer, tile, coord, bucket, firstTile) { - const gl = painter.context.gl; - const programConfiguration = bucket.programConfigurations.get(layer.id); - - const program = setFillProgram('fill', layer.paint.get('fill-pattern'), painter, programConfiguration, layer, tile, coord, firstTile); - - program.draw( - painter.context, - gl.TRIANGLES, - layer.id, - bucket.layoutVertexBuffer, - bucket.indexBuffer, - bucket.segments, - programConfiguration); -} + if (image) { + painter.context.activeTexture.set(gl.TEXTURE0); + painter.imageManager.bind(painter.context); + } -function drawStrokeTile(painter, sourceCache, layer, tile, coord, bucket, firstTile) { - const gl = painter.context.gl; - const programConfiguration = bucket.programConfigurations.get(layer.id); - const pattern = layer.getPaintProperty('fill-outline-color') ? null : layer.paint.get('fill-pattern'); - - const program = setFillProgram('fillOutline', pattern, painter, programConfiguration, layer, tile, coord, firstTile); - gl.uniform2f(program.uniforms.u_world, gl.drawingBufferWidth, gl.drawingBufferHeight); - - program.draw( - painter.context, - gl.LINES, - layer.id, - bucket.layoutVertexBuffer, - bucket.indexBuffer2, - bucket.segments2, - programConfiguration); -} + for (const coord of coords) { + const tile = sourceCache.getTile(coord); + const bucket: ?FillBucket = (tile.getBucket(layer): any); + if (!bucket) continue; -function setFillProgram(programId, pat: ?CrossFaded, painter, programConfiguration, layer, tile, coord, firstTile) { - let program; - const prevProgram = painter.context.program.get(); - if (!pat) { - program = painter.useProgram(programId, programConfiguration); - if (firstTile || program.program !== prevProgram) { - programConfiguration.setUniforms(painter.context, program, layer.paint, {zoom: painter.transform.zoom}); + const programConfiguration = bucket.programConfigurations.get(layer.id); + const program = painter.useProgram(programName, programConfiguration); + + const tileMatrix = painter.translatePosMatrix(coord.posMatrix, tile, + layer.paint.get('fill-translate'), layer.paint.get('fill-translate-anchor')); + + if (!isOutline) { + indexBuffer = bucket.indexBuffer; + segments = bucket.segments; + uniformValues = image ? + fillPatternUniformValues(tileMatrix, painter, image, tile) : + fillUniformValues(tileMatrix); + } else { + indexBuffer = bucket.indexBuffer2; + segments = bucket.segments2; + const drawingBufferSize = [gl.drawingBufferWidth, gl.drawingBufferHeight]; + uniformValues = (programName === 'fillOutlinePattern' && image) ? + fillOutlinePatternUniformValues(tileMatrix, painter, image, tile, drawingBufferSize) : + fillOutlineUniformValues(tileMatrix, drawingBufferSize); } - } else { - program = painter.useProgram(`${programId}Pattern`, programConfiguration); - if (firstTile || program.program !== prevProgram) { - programConfiguration.setUniforms(painter.context, program, layer.paint, {zoom: painter.transform.zoom}); - preparePattern(pat, painter, program); - } - setPatternUniforms(tile, painter, program); + + program.draw(painter.context, drawMode, depthMode, + painter.stencilModeForClipping(coord), colorMode, uniformValues, + layer.id, bucket.layoutVertexBuffer, indexBuffer, segments, + layer.paint, painter.transform.zoom, programConfiguration); } - painter.context.gl.uniformMatrix4fv(program.uniforms.u_matrix, false, painter.translatePosMatrix( - coord.posMatrix, tile, - layer.paint.get('fill-translate'), - layer.paint.get('fill-translate-anchor') - )); - return program; } diff --git a/src/render/draw_fill_extrusion.js b/src/render/draw_fill_extrusion.js index e418b81147f..184b19dc445 100644 --- a/src/render/draw_fill_extrusion.js +++ b/src/render/draw_fill_extrusion.js @@ -1,16 +1,14 @@ // @flow -import { mat3, mat4, vec3 } from 'gl-matrix'; - -import { - isPatternMissing, - setPatternUniforms, - prepare as preparePattern -} from './pattern'; import Texture from './texture'; import Color from '../style-spec/util/color'; import DepthMode from '../gl/depth_mode'; import StencilMode from '../gl/stencil_mode'; +import { + fillExtrusionUniformValues, + fillExtrusionPatternUniformValues, + extrusionTextureUniformValues +} from './program/fill_extrusion_program'; import type Painter from './painter'; import type SourceCache from '../source/source_cache'; @@ -28,15 +26,12 @@ function draw(painter: Painter, source: SourceCache, layer: FillExtrusionStyleLa if (painter.renderPass === 'offscreen') { drawToExtrusionFramebuffer(painter, layer); - let first = true; - for (const coord of coords) { - const tile = source.getTile(coord); - const bucket: ?FillExtrusionBucket = (tile.getBucket(layer): any); - if (!bucket) continue; + const depthMode = new DepthMode(painter.context.gl.LEQUAL, DepthMode.ReadWrite, [0, 1]), + stencilMode = StencilMode.disabled, + colorMode = painter.colorModeForRenderPass(); + + drawExtrusionTiles(painter, source, layer, coords, depthMode, stencilMode, colorMode); - drawExtrusion(painter, source, layer, tile, coord, bucket, first); - first = false; - } } else if (painter.renderPass === 'translucent') { drawExtrusionTexture(painter, layer); } @@ -69,10 +64,6 @@ function drawToExtrusionFramebuffer(painter, layer) { } context.clear({ color: Color.transparent }); - - context.setStencilMode(StencilMode.disabled); - context.setDepthMode(new DepthMode(gl.LEQUAL, DepthMode.ReadWrite, [0, 1])); - context.setColorMode(painter.colorModeForRenderPass()); } function drawExtrusionTexture(painter, layer) { @@ -81,83 +72,51 @@ function drawExtrusionTexture(painter, layer) { const context = painter.context; const gl = context.gl; - const program = painter.useProgram('extrusionTexture'); - - context.setStencilMode(StencilMode.disabled); - context.setDepthMode(DepthMode.disabled); - context.setColorMode(painter.colorModeForRenderPass()); context.activeTexture.set(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, renderedTexture.colorAttachment.get()); - gl.uniform1f(program.uniforms.u_opacity, layer.paint.get('fill-extrusion-opacity')); - gl.uniform1i(program.uniforms.u_image, 0); - - const matrix = mat4.create(); - mat4.ortho(matrix, 0, painter.width, painter.height, 0, 0, 1); - gl.uniformMatrix4fv(program.uniforms.u_matrix, false, matrix); - - gl.uniform2f(program.uniforms.u_world, gl.drawingBufferWidth, gl.drawingBufferHeight); - - painter.viewportVAO.bind(context, program, painter.viewportBuffer, []); - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + painter.useProgram('extrusionTexture').draw(context, gl.TRIANGLES, + DepthMode.disabled, StencilMode.disabled, + painter.colorModeForRenderPass(), + extrusionTextureUniformValues(painter, layer, 0), + layer.id, painter.viewportBuffer, painter.quadTriangleIndexBuffer, + painter.viewportSegments, layer.paint, painter.transform.zoom); } -function drawExtrusion(painter, source, layer, tile, coord, bucket, first) { +function drawExtrusionTiles(painter, source, layer, coords, depthMode, stencilMode, colorMode) { const context = painter.context; const gl = context.gl; const image = layer.paint.get('fill-extrusion-pattern'); + if (image) { + if (painter.isPatternMissing(image)) return; - const prevProgram = painter.context.program.get(); - const programConfiguration = bucket.programConfigurations.get(layer.id); - const program = painter.useProgram(image ? 'fillExtrusionPattern' : 'fillExtrusion', programConfiguration); - if (first || program.program !== prevProgram) { - programConfiguration.setUniforms(context, program, layer.paint, {zoom: painter.transform.zoom}); + context.activeTexture.set(gl.TEXTURE0); + painter.imageManager.bind(context); } - if (image) { - if (isPatternMissing(image, painter)) return; - preparePattern(image, painter, program); - setPatternUniforms(tile, painter, program); - gl.uniform1f(program.uniforms.u_height_factor, -Math.pow(2, coord.overscaledZ) / tile.tileSize / 8); - } + for (const coord of coords) { + const tile = source.getTile(coord); + const bucket: ?FillExtrusionBucket = (tile.getBucket(layer): any); + if (!bucket) continue; - painter.context.gl.uniformMatrix4fv(program.uniforms.u_matrix, false, painter.translatePosMatrix( - coord.posMatrix, - tile, - layer.paint.get('fill-extrusion-translate'), - layer.paint.get('fill-extrusion-translate-anchor') - )); - - setLight(program, painter); - - program.draw( - context, - gl.TRIANGLES, - layer.id, - bucket.layoutVertexBuffer, - bucket.indexBuffer, - bucket.segments, - programConfiguration); -} + const programConfiguration = bucket.programConfigurations.get(layer.id); + const program = painter.useProgram(image ? 'fillExtrusionPattern' : 'fillExtrusion', programConfiguration); -function setLight(program, painter) { - const gl = painter.context.gl; - const light = painter.style.light; + const matrix = painter.translatePosMatrix( + coord.posMatrix, + tile, + layer.paint.get('fill-extrusion-translate'), + layer.paint.get('fill-extrusion-translate-anchor')); - const _lp = light.properties.get('position'); - const lightPos = [_lp.x, _lp.y, _lp.z]; + const uniformValues = image ? + fillExtrusionPatternUniformValues(matrix, painter, coord, image, tile) : + fillExtrusionUniformValues(matrix, painter); - const lightMat = mat3.create(); - if (light.properties.get('anchor') === 'viewport') { - mat3.fromRotation(lightMat, -painter.transform.angle); + program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, + uniformValues, layer.id, bucket.layoutVertexBuffer, bucket.indexBuffer, + bucket.segments, layer.paint, painter.transform.zoom, + programConfiguration); } - vec3.transformMat3(lightPos, lightPos, lightMat); - - const color = light.properties.get('color'); - - gl.uniform3fv(program.uniforms.u_lightpos, (lightPos: Array)); - gl.uniform1f(program.uniforms.u_lightintensity, light.properties.get('intensity')); - gl.uniform3f(program.uniforms.u_lightcolor, color.r, color.g, color.b); } diff --git a/src/render/draw_heatmap.js b/src/render/draw_heatmap.js index 65100cd9f77..f90c302499d 100644 --- a/src/render/draw_heatmap.js +++ b/src/render/draw_heatmap.js @@ -1,13 +1,14 @@ // @flow -import { mat4 } from 'gl-matrix'; - import Texture from './texture'; -import pixelsToTileUnits from '../source/pixels_to_tile_units'; import Color from '../style-spec/util/color'; import DepthMode from '../gl/depth_mode'; import StencilMode from '../gl/stencil_mode'; import ColorMode from '../gl/color_mode'; +import { + heatmapUniformValues, + heatmapTextureUniformValues +} from './program/heatmap_program'; import type Painter from './painter'; import type SourceCache from '../source/source_cache'; @@ -26,20 +27,17 @@ function drawHeatmap(painter: Painter, sourceCache: SourceCache, layer: HeatmapS const context = painter.context; const gl = context.gl; - context.setDepthMode(painter.depthModeForSublayer(0, DepthMode.ReadOnly)); - + const depthMode = painter.depthModeForSublayer(0, DepthMode.ReadOnly); // Allow kernels to be drawn across boundaries, so that // large kernels are not clipped to tiles - context.setStencilMode(StencilMode.disabled); + const stencilMode = StencilMode.disabled; + // Turn on additive blending for kernels, which is a key aspect of kernel density estimation formula + const colorMode = new ColorMode([gl.ONE, gl.ONE], Color.transparent, [true, true, true, true]); bindFramebuffer(context, painter, layer); context.clear({ color: Color.transparent }); - // Turn on additive blending for kernels, which is a key aspect of kernel density estimation formula - context.setColorMode(new ColorMode([gl.ONE, gl.ONE], Color.transparent, [true, true, true, true])); - - let first = true; for (let i = 0; i < coords.length; i++) { const coord = coords[i]; @@ -52,27 +50,15 @@ function drawHeatmap(painter: Painter, sourceCache: SourceCache, layer: HeatmapS const bucket: ?HeatmapBucket = (tile.getBucket(layer): any); if (!bucket) continue; - const prevProgram = painter.context.program.get(); const programConfiguration = bucket.programConfigurations.get(layer.id); const program = painter.useProgram('heatmap', programConfiguration); const {zoom} = painter.transform; - if (first || program.program !== prevProgram) { - programConfiguration.setUniforms(painter.context, program, layer.paint, {zoom}); - first = false; - } - - gl.uniform1f(program.uniforms.u_extrude_scale, pixelsToTileUnits(tile, 1, zoom)); - - gl.uniform1f(program.uniforms.u_intensity, layer.paint.get('heatmap-intensity')); - gl.uniformMatrix4fv(program.uniforms.u_matrix, false, coord.posMatrix); - - program.draw( - context, - gl.TRIANGLES, - layer.id, - bucket.layoutVertexBuffer, - bucket.indexBuffer, - bucket.segments, + + program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, + heatmapUniformValues(coord.posMatrix, + tile, zoom, layer.paint.get('heatmap-intensity')), + layer.id, bucket.layoutVertexBuffer, bucket.indexBuffer, + bucket.segments, layer.paint, painter.transform.zoom, programConfiguration); } @@ -131,7 +117,6 @@ function renderTextureToMap(painter, layer) { const context = painter.context; const gl = context.gl; - // Here we bind two different textures from which we'll sample in drawing // heatmaps: the kernel texture, prepared in the offscreen pass, and a // color ramp texture. @@ -147,23 +132,9 @@ function renderTextureToMap(painter, layer) { } colorRampTexture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE); - context.setDepthMode(DepthMode.disabled); - context.setStencilMode(StencilMode.disabled); - - const program = painter.useProgram('heatmapTexture'); - - const opacity = layer.paint.get('heatmap-opacity'); - gl.uniform1f(program.uniforms.u_opacity, opacity); - gl.uniform1i(program.uniforms.u_image, 0); - gl.uniform1i(program.uniforms.u_color_ramp, 1); - - const matrix = mat4.create(); - mat4.ortho(matrix, 0, painter.width, painter.height, 0, 0, 1); - gl.uniformMatrix4fv(program.uniforms.u_matrix, false, matrix); - - gl.uniform2f(program.uniforms.u_world, gl.drawingBufferWidth, gl.drawingBufferHeight); - - painter.viewportVAO.bind(painter.context, program, painter.viewportBuffer, []); - - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + painter.useProgram('heatmapTexture').draw(context, gl.TRIANGLES, + DepthMode.disabled, StencilMode.disabled, painter.colorModeForRenderPass(), + heatmapTextureUniformValues(painter, layer, 0, 1), + layer.id, painter.viewportBuffer, painter.quadTriangleIndexBuffer, + painter.viewportSegments, layer.paint, painter.transform.zoom); } diff --git a/src/render/draw_hillshade.js b/src/render/draw_hillshade.js index 67ac555ef42..b724ca7dbbe 100644 --- a/src/render/draw_hillshade.js +++ b/src/render/draw_hillshade.js @@ -1,11 +1,12 @@ // @flow -import Coordinate from '../geo/coordinate'; import Texture from './texture'; -import EXTENT from '../data/extent'; -import { mat4 } from 'gl-matrix'; import StencilMode from '../gl/stencil_mode'; import DepthMode from '../gl/depth_mode'; +import { + hillshadeUniformValues, + hillshadeUniformPrepareValues +} from './program/hillshade_program'; import type Painter from './painter'; import type SourceCache from '../source/source_cache'; @@ -20,84 +21,50 @@ function drawHillshade(painter: Painter, sourceCache: SourceCache, layer: Hillsh const context = painter.context; const sourceMaxZoom = sourceCache.getSource().maxzoom; - context.setDepthMode(painter.depthModeForSublayer(0, DepthMode.ReadOnly)); - context.setStencilMode(StencilMode.disabled); - context.setColorMode(painter.colorModeForRenderPass()); + const depthMode = painter.depthModeForSublayer(0, DepthMode.ReadOnly); + const stencilMode = StencilMode.disabled; + const colorMode = painter.colorModeForRenderPass(); for (const tileID of tileIDs) { const tile = sourceCache.getTile(tileID); if (tile.needsHillshadePrepare && painter.renderPass === 'offscreen') { - prepareHillshade(painter, tile, sourceMaxZoom); + prepareHillshade(painter, tile, layer, sourceMaxZoom, depthMode, stencilMode, colorMode); continue; } else if (painter.renderPass === 'translucent') { - renderHillshade(painter, tile, layer); + renderHillshade(painter, tile, layer, depthMode, stencilMode, colorMode); } } context.viewport.set([0, 0, painter.width, painter.height]); } -function setLight(program, painter, layer) { - let azimuthal = layer.paint.get('hillshade-illumination-direction') * (Math.PI / 180); - // modify azimuthal angle by map rotation if light is anchored at the viewport - if (layer.paint.get('hillshade-illumination-anchor') === 'viewport') azimuthal -= painter.transform.angle; - painter.context.gl.uniform2f(program.uniforms.u_light, layer.paint.get('hillshade-exaggeration'), azimuthal); - -} - -function getTileLatRange(painter, tileID: OverscaledTileID) { - const coordinate0 = tileID.toCoordinate(); - const coordinate1 = new Coordinate(coordinate0.column, coordinate0.row + 1, coordinate0.zoom); - return [painter.transform.coordinateLocation(coordinate0).lat, painter.transform.coordinateLocation(coordinate1).lat]; -} - -function renderHillshade(painter, tile, layer) { +function renderHillshade(painter, tile, layer, depthMode, stencilMode, colorMode) { const context = painter.context; const gl = context.gl; const fbo = tile.fbo; if (!fbo) return; const program = painter.useProgram('hillshade'); - const posMatrix = painter.transform.calculatePosMatrix(tile.tileID.toUnwrapped(), true); - setLight(program, painter, layer); - // for scaling the magnitude of a points slope by its latitude - const latRange = getTileLatRange(painter, tile.tileID); - context.activeTexture.set(gl.TEXTURE0); + context.activeTexture.set(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, fbo.colorAttachment.get()); - gl.uniformMatrix4fv(program.uniforms.u_matrix, false, posMatrix); - gl.uniform2fv(program.uniforms.u_latrange, (latRange: Array)); - gl.uniform1i(program.uniforms.u_image, 0); - - const shadowColor = layer.paint.get("hillshade-shadow-color"); - gl.uniform4f(program.uniforms.u_shadow, shadowColor.r, shadowColor.g, shadowColor.b, shadowColor.a); - const highlightColor = layer.paint.get("hillshade-highlight-color"); - gl.uniform4f(program.uniforms.u_highlight, highlightColor.r, highlightColor.g, highlightColor.b, highlightColor.a); - const accentColor = layer.paint.get("hillshade-accent-color"); - gl.uniform4f(program.uniforms.u_accent, accentColor.r, accentColor.g, accentColor.b, accentColor.a); + const uniformValues = hillshadeUniformValues(painter, tile, layer); if (tile.maskedBoundsBuffer && tile.maskedIndexBuffer && tile.segments) { - program.draw( - context, - gl.TRIANGLES, - layer.id, - tile.maskedBoundsBuffer, - tile.maskedIndexBuffer, - tile.segments - ); + program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, + uniformValues, layer.id, tile.maskedBoundsBuffer, + tile.maskedIndexBuffer, tile.segments); } else { - const buffer = painter.rasterBoundsBuffer; - const vao = painter.rasterBoundsVAO; - vao.bind(context, program, buffer, []); - gl.drawArrays(gl.TRIANGLE_STRIP, 0, buffer.length); + program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, + uniformValues, layer.id, painter.rasterBoundsBuffer, + painter.quadTriangleIndexBuffer, painter.rasterBoundsSegments); } } - // hillshade rendering is done in two steps. the prepare step first calculates the slope of the terrain in the x and y // directions for each pixel, and saves those values to a framebuffer texture in the r and g channels. -function prepareHillshade(painter, tile, sourceMaxZoom) { +function prepareHillshade(painter, tile, layer, sourceMaxZoom, depthMode, stencilMode, colorMode) { const context = painter.context; const gl = context.gl; // decode rgba levels by using integer overflow to convert each Uint32Array element -> 4 Uint8Array elements. @@ -145,24 +112,11 @@ function prepareHillshade(painter, tile, sourceMaxZoom) { context.bindFramebuffer.set(fbo.framebuffer); context.viewport.set([0, 0, tileSize, tileSize]); - const matrix = mat4.create(); - // Flip rendering at y axis. - mat4.ortho(matrix, 0, EXTENT, -EXTENT, 0, 0, 1); - mat4.translate(matrix, matrix, [0, -EXTENT, 0]); - - const program = painter.useProgram('hillshadePrepare'); - - gl.uniformMatrix4fv(program.uniforms.u_matrix, false, matrix); - gl.uniform1f(program.uniforms.u_zoom, tile.tileID.overscaledZ); - gl.uniform2fv(program.uniforms.u_dimension, ([tileSize * 2, tileSize * 2]: Array)); - gl.uniform1i(program.uniforms.u_image, 1); - gl.uniform1f(program.uniforms.u_maxzoom, sourceMaxZoom); - - const buffer = painter.rasterBoundsBuffer; - const vao = painter.rasterBoundsVAO; - - vao.bind(context, program, buffer, []); - gl.drawArrays(gl.TRIANGLE_STRIP, 0, buffer.length); + painter.useProgram('hillshadePrepare').draw(context, gl.TRIANGLES, + depthMode, stencilMode, colorMode, + hillshadeUniformPrepareValues(tile, sourceMaxZoom), + layer.id, painter.rasterBoundsBuffer, + painter.quadTriangleIndexBuffer, painter.rasterBoundsSegments); tile.needsHillshadePrepare = false; } diff --git a/src/render/draw_line.js b/src/render/draw_line.js index 5efb4d7e89d..a544939dac0 100644 --- a/src/render/draw_line.js +++ b/src/render/draw_line.js @@ -1,10 +1,13 @@ // @flow -import browser from '../util/browser'; - -import pixelsToTileUnits from '../source/pixels_to_tile_units'; import DepthMode from '../gl/depth_mode'; import Texture from './texture'; +import { + lineUniformValues, + linePatternUniformValues, + lineSDFUniformValues, + lineGradientUniformValues +} from './program/line_program'; import type Painter from './painter'; import type SourceCache from '../source/source_cache'; @@ -19,17 +22,14 @@ export default function drawLine(painter: Painter, sourceCache: SourceCache, lay const width = layer.paint.get('line-width'); if (opacity.constantOr(1) === 0 || width.constantOr(1) === 0) return; - const context = painter.context; - - context.setDepthMode(painter.depthModeForSublayer(0, DepthMode.ReadOnly)); - context.setColorMode(painter.colorModeForRenderPass()); + const depthMode = painter.depthModeForSublayer(0, DepthMode.ReadOnly); + const colorMode = painter.colorModeForRenderPass(); const programId = layer.paint.get('line-dasharray') ? 'lineSDF' : layer.paint.get('line-pattern') ? 'linePattern' : layer.paint.get('line-gradient') ? 'lineGradient' : 'line'; - let prevTileZoom; let firstTile = true; for (const coord of coords) { @@ -41,102 +41,48 @@ export default function drawLine(painter: Painter, sourceCache: SourceCache, lay const prevProgram = painter.context.program.get(); const program = painter.useProgram(programId, programConfiguration); const programChanged = firstTile || program.program !== prevProgram; - const tileRatioChanged = prevTileZoom !== tile.tileID.overscaledZ; - if (programChanged) { - programConfiguration.setUniforms(painter.context, program, layer.paint, {zoom: painter.transform.zoom}); - } - drawLineTile(program, painter, tile, bucket, layer, coord, programConfiguration, programChanged, tileRatioChanged); - prevTileZoom = tile.tileID.overscaledZ; + drawLineTile(program, painter, tile, bucket, layer, coord, depthMode, colorMode, programConfiguration, programChanged); firstTile = false; + // once refactored so that bound texture state is managed, we'll also be able to remove this firstTile/programChanged logic } } -function drawLineTile(program, painter, tile, bucket, layer, coord, programConfiguration, programChanged, tileRatioChanged) { +function drawLineTile(program, painter, tile, bucket, layer, coord, depthMode, colorMode, programConfiguration, programChanged) { const context = painter.context; const gl = context.gl; const dasharray = layer.paint.get('line-dasharray'); const image = layer.paint.get('line-pattern'); + const gradient = layer.paint.get('line-gradient'); - let posA, posB, imagePosA, imagePosB; - - if (programChanged || tileRatioChanged) { - const tileRatio = 1 / pixelsToTileUnits(tile, 1, painter.transform.tileZoom); - - if (dasharray) { - posA = painter.lineAtlas.getDash(dasharray.from, layer.layout.get('line-cap') === 'round'); - posB = painter.lineAtlas.getDash(dasharray.to, layer.layout.get('line-cap') === 'round'); - - const widthA = posA.width * dasharray.fromScale; - const widthB = posB.width * dasharray.toScale; - - gl.uniform2f(program.uniforms.u_patternscale_a, tileRatio / widthA, -posA.height / 2); - gl.uniform2f(program.uniforms.u_patternscale_b, tileRatio / widthB, -posB.height / 2); - gl.uniform1f(program.uniforms.u_sdfgamma, painter.lineAtlas.width / (Math.min(widthA, widthB) * 256 * browser.devicePixelRatio) / 2); + if (painter.isPatternMissing(image)) return; - } else if (image) { - imagePosA = painter.imageManager.getPattern(image.from); - imagePosB = painter.imageManager.getPattern(image.to); - if (!imagePosA || !imagePosB) return; - - gl.uniform2f(program.uniforms.u_pattern_size_a, imagePosA.displaySize[0] * image.fromScale / tileRatio, imagePosA.displaySize[1]); - gl.uniform2f(program.uniforms.u_pattern_size_b, imagePosB.displaySize[0] * image.toScale / tileRatio, imagePosB.displaySize[1]); - - const {width, height} = painter.imageManager.getPixelSize(); - gl.uniform2fv(program.uniforms.u_texsize, ([width, height]: Array)); - } - - gl.uniform2f(program.uniforms.u_gl_units_to_pixels, 1 / painter.transform.pixelsToGLUnits[0], 1 / painter.transform.pixelsToGLUnits[1]); - } + const uniformValues = dasharray ? lineSDFUniformValues(painter, tile, layer, dasharray) : + image ? linePatternUniformValues(painter, tile, layer, image) : + gradient ? lineGradientUniformValues(painter, tile, layer) : + lineUniformValues(painter, tile, layer); if (programChanged) { - if (dasharray) { - gl.uniform1i(program.uniforms.u_image, 0); context.activeTexture.set(gl.TEXTURE0); painter.lineAtlas.bind(context); - - gl.uniform1f(program.uniforms.u_tex_y_a, (posA: any).y); - gl.uniform1f(program.uniforms.u_tex_y_b, (posB: any).y); - gl.uniform1f(program.uniforms.u_mix, dasharray.t); - } else if (image) { - gl.uniform1i(program.uniforms.u_image, 0); context.activeTexture.set(gl.TEXTURE0); painter.imageManager.bind(context); - - gl.uniform2fv(program.uniforms.u_pattern_tl_a, (imagePosA: any).tl); - gl.uniform2fv(program.uniforms.u_pattern_br_a, (imagePosA: any).br); - gl.uniform2fv(program.uniforms.u_pattern_tl_b, (imagePosB: any).tl); - gl.uniform2fv(program.uniforms.u_pattern_br_b, (imagePosB: any).br); - gl.uniform1f(program.uniforms.u_fade, image.t); } } - context.setStencilMode(painter.stencilModeForClipping(coord)); - - const posMatrix = painter.translatePosMatrix(coord.posMatrix, tile, layer.paint.get('line-translate'), layer.paint.get('line-translate-anchor')); - gl.uniformMatrix4fv(program.uniforms.u_matrix, false, posMatrix); - - gl.uniform1f(program.uniforms.u_ratio, 1 / pixelsToTileUnits(tile, 1, painter.transform.zoom)); - - if (layer.paint.get('line-gradient')) { + if (gradient) { context.activeTexture.set(gl.TEXTURE0); let gradientTexture = layer.gradientTexture; if (!layer.gradient) return; if (!gradientTexture) gradientTexture = layer.gradientTexture = new Texture(context, layer.gradient, gl.RGBA); gradientTexture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE); - - gl.uniform1i(program.uniforms.u_image, 0); } - program.draw( - context, - gl.TRIANGLES, - layer.id, - bucket.layoutVertexBuffer, - bucket.indexBuffer, - bucket.segments, - programConfiguration); + program.draw(context, gl.TRIANGLES, depthMode, + painter.stencilModeForClipping(coord), colorMode, uniformValues, + layer.id, bucket.layoutVertexBuffer, bucket.indexBuffer, bucket.segments, + layer.paint, painter.transform.zoom, programConfiguration); } diff --git a/src/render/draw_raster.js b/src/render/draw_raster.js index 2829a7bca82..481971710be 100644 --- a/src/render/draw_raster.js +++ b/src/render/draw_raster.js @@ -6,6 +6,7 @@ import ImageSource from '../source/image_source'; import browser from '../util/browser'; import StencilMode from '../gl/stencil_mode'; import DepthMode from '../gl/depth_mode'; +import { rasterUniformValues } from './program/raster_program'; import type Painter from './painter'; import type SourceCache from '../source/source_cache'; @@ -23,34 +24,21 @@ function drawRaster(painter: Painter, sourceCache: SourceCache, layer: RasterSty const source = sourceCache.getSource(); const program = painter.useProgram('raster'); - context.setStencilMode(StencilMode.disabled); - context.setColorMode(painter.colorModeForRenderPass()); - - // Constant parameters. - gl.uniform1f(program.uniforms.u_brightness_low, layer.paint.get('raster-brightness-min')); - gl.uniform1f(program.uniforms.u_brightness_high, layer.paint.get('raster-brightness-max')); - gl.uniform1f(program.uniforms.u_saturation_factor, saturationFactor(layer.paint.get('raster-saturation'))); - gl.uniform1f(program.uniforms.u_contrast_factor, contrastFactor(layer.paint.get('raster-contrast'))); - gl.uniform3fv(program.uniforms.u_spin_weights, (spinWeights(layer.paint.get('raster-hue-rotate')): Array)); - gl.uniform1f(program.uniforms.u_buffer_scale, 1); - gl.uniform1i(program.uniforms.u_image0, 0); - gl.uniform1i(program.uniforms.u_image1, 1); - + const stencilMode = StencilMode.disabled; + const colorMode = painter.colorModeForRenderPass(); const minTileZ = coords.length && coords[0].overscaledZ; for (const coord of coords) { // Set the lower zoom level to sublayer 0, and higher zoom levels to higher sublayers // Use gl.LESS to prevent double drawing in areas where tiles overlap. - context.setDepthMode(painter.depthModeForSublayer(coord.overscaledZ - minTileZ, - layer.paint.get('raster-opacity') === 1 ? DepthMode.ReadWrite : DepthMode.ReadOnly, gl.LESS)); + const depthMode = painter.depthModeForSublayer(coord.overscaledZ - minTileZ, + layer.paint.get('raster-opacity') === 1 ? DepthMode.ReadWrite : DepthMode.ReadOnly, gl.LESS); const tile = sourceCache.getTile(coord); const posMatrix = painter.transform.calculatePosMatrix(coord.toUnwrapped(), true); tile.registerFadeDuration(layer.paint.get('raster-fade-duration')); - gl.uniformMatrix4fv(program.uniforms.u_matrix, false, posMatrix); - const parentTile = sourceCache.findLoadedParent(coord, 0), fade = getFadeValues(tile, parentTile, sourceCache, layer, painter.transform); @@ -72,59 +60,25 @@ function drawRaster(painter: Painter, sourceCache: SourceCache, layer: RasterSty tile.texture.bind(textureFilter, gl.CLAMP_TO_EDGE, gl.LINEAR_MIPMAP_NEAREST); } - // cross-fade parameters - gl.uniform2fv(program.uniforms.u_tl_parent, ((parentTL || [0, 0]): Array)); - gl.uniform1f(program.uniforms.u_scale_parent, parentScaleBy || 1); - gl.uniform1f(program.uniforms.u_fade_t, fade.mix); - gl.uniform1f(program.uniforms.u_opacity, fade.opacity * layer.paint.get('raster-opacity')); - + const uniformValues = rasterUniformValues(posMatrix, parentTL || [0, 0], parentScaleBy || 1, fade, layer); if (source instanceof ImageSource) { - const buffer = source.boundsBuffer; - const vao = source.boundsVAO; - vao.bind(context, program, buffer, []); - gl.drawArrays(gl.TRIANGLE_STRIP, 0, buffer.length); + program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, + uniformValues, layer.id, source.boundsBuffer, + painter.quadTriangleIndexBuffer, source.boundsSegments); } else if (tile.maskedBoundsBuffer && tile.maskedIndexBuffer && tile.segments) { - program.draw( - context, - gl.TRIANGLES, - layer.id, - tile.maskedBoundsBuffer, - tile.maskedIndexBuffer, - tile.segments - ); + program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, + uniformValues, layer.id, tile.maskedBoundsBuffer, + tile.maskedIndexBuffer, tile.segments, layer.paint, + painter.transform.zoom); } else { - const buffer = painter.rasterBoundsBuffer; - const vao = painter.rasterBoundsVAO; - vao.bind(context, program, buffer, []); - gl.drawArrays(gl.TRIANGLE_STRIP, 0, buffer.length); + program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, + uniformValues, layer.id, painter.rasterBoundsBuffer, + painter.quadTriangleIndexBuffer, painter.rasterBoundsSegments); } } } -function spinWeights(angle) { - angle *= Math.PI / 180; - const s = Math.sin(angle); - const c = Math.cos(angle); - return [ - (2 * c + 1) / 3, - (-Math.sqrt(3) * s - c + 1) / 3, - (Math.sqrt(3) * s - c + 1) / 3 - ]; -} - -function contrastFactor(contrast) { - return contrast > 0 ? - 1 / (1 - contrast) : - 1 + contrast; -} - -function saturationFactor(saturation) { - return saturation > 0 ? - 1 - 1 / (1.001 - saturation) : - -saturation; -} - function getFadeValues(tile, parentTile, sourceCache, layer, transform) { const fadeDuration = layer.paint.get('raster-fade-duration'); diff --git a/src/render/draw_symbol.js b/src/render/draw_symbol.js index 28193f0f67c..c468df28e27 100644 --- a/src/render/draw_symbol.js +++ b/src/render/draw_symbol.js @@ -11,6 +11,10 @@ import properties from '../style/style_layer/symbol_style_layer_properties'; const symbolLayoutProperties = properties.layout; import StencilMode from '../gl/stencil_mode'; import DepthMode from '../gl/depth_mode'; +import { + symbolIconUniformValues, + symbolSDFUniformValues +} from './program/symbol_program'; import type Painter from './painter'; import type SourceCache from '../source/source_cache'; @@ -23,11 +27,9 @@ export default drawSymbols; function drawSymbols(painter: Painter, sourceCache: SourceCache, layer: SymbolStyleLayer, coords: Array) { if (painter.renderPass !== 'translucent') return; - const context = painter.context; - // Disable the stencil test so that labels aren't clipped to tile boundaries. - context.setStencilMode(StencilMode.disabled); - context.setColorMode(painter.colorModeForRenderPass()); + const stencilMode = StencilMode.disabled; + const colorMode = painter.colorModeForRenderPass(); if (layer.paint.get('icon-opacity').constantOr(1) !== 0) { drawLayerSymbols(painter, sourceCache, layer, coords, false, @@ -35,7 +37,8 @@ function drawSymbols(painter: Painter, sourceCache: SourceCache, layer: SymbolSt layer.paint.get('icon-translate-anchor'), layer.layout.get('icon-rotation-alignment'), layer.layout.get('icon-pitch-alignment'), - layer.layout.get('icon-keep-upright') + layer.layout.get('icon-keep-upright'), + stencilMode, colorMode ); } @@ -45,7 +48,8 @@ function drawSymbols(painter: Painter, sourceCache: SourceCache, layer: SymbolSt layer.paint.get('text-translate-anchor'), layer.layout.get('text-rotation-alignment'), layer.layout.get('text-pitch-alignment'), - layer.layout.get('text-keep-upright') + layer.layout.get('text-keep-upright'), + stencilMode, colorMode ); } @@ -55,7 +59,7 @@ function drawSymbols(painter: Painter, sourceCache: SourceCache, layer: SymbolSt } function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate, translateAnchor, - rotationAlignment, pitchAlignment, keepUpright) { + rotationAlignment, pitchAlignment, keepUpright, stencilMode, colorMode) { const context = painter.context; const gl = context.gl; @@ -71,9 +75,10 @@ function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate const depthOn = pitchWithMap; - context.setDepthMode(depthOn ? painter.depthModeForSublayer(0, DepthMode.ReadOnly) : DepthMode.disabled); + const depthMode = depthOn ? painter.depthModeForSublayer(0, DepthMode.ReadOnly) : DepthMode.disabled; let program; + let size; for (const coord of coords) { const tile = sourceCache.getTile(coord); @@ -89,103 +94,67 @@ function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate if (!program) { program = painter.useProgram(isSDF ? 'symbolSDF' : 'symbolIcon', programConfiguration); - programConfiguration.setUniforms(painter.context, program, layer.paint, {zoom: painter.transform.zoom}); - - setSymbolDrawState(program, painter, layer, isText, rotateInShader, pitchWithMap, sizeData); + size = symbolSize.evaluateSizeForZoom(sizeData, tr.zoom, symbolLayoutProperties.properties[isText ? 'text-size' : 'icon-size']); } context.activeTexture.set(gl.TEXTURE0); - gl.uniform1i(program.uniforms.u_texture, 0); + let texSize: [number, number]; if (isText) { tile.glyphAtlasTexture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE); - gl.uniform2fv(program.uniforms.u_texsize, tile.glyphAtlasTexture.size); + texSize = tile.glyphAtlasTexture.size; } else { const iconScaled = layer.layout.get('icon-size').constantOr(0) !== 1 || bucket.iconsNeedLinear; const iconTransformed = pitchWithMap || tr.pitch !== 0; tile.iconAtlasTexture.bind(isSDF || painter.options.rotating || painter.options.zooming || iconScaled || iconTransformed ? gl.LINEAR : gl.NEAREST, gl.CLAMP_TO_EDGE); - gl.uniform2fv(program.uniforms.u_texsize, tile.iconAtlasTexture.size); - } - gl.uniformMatrix4fv(program.uniforms.u_matrix, false, painter.translatePosMatrix(coord.posMatrix, tile, translate, translateAnchor)); + texSize = tile.iconAtlasTexture.size; + } const s = pixelsToTileUnits(tile, 1, painter.transform.zoom); const labelPlaneMatrix = symbolProjection.getLabelPlaneMatrix(coord.posMatrix, pitchWithMap, rotateWithMap, painter.transform, s); const glCoordMatrix = symbolProjection.getGlCoordMatrix(coord.posMatrix, pitchWithMap, rotateWithMap, painter.transform, s); - gl.uniformMatrix4fv(program.uniforms.u_gl_coord_matrix, false, painter.translatePosMatrix(glCoordMatrix, tile, translate, translateAnchor, true)); if (alongLine) { - gl.uniformMatrix4fv(program.uniforms.u_label_plane_matrix, false, identityMat4); symbolProjection.updateLineLabels(bucket, coord.posMatrix, painter, isText, labelPlaneMatrix, glCoordMatrix, pitchWithMap, keepUpright); - } else { - gl.uniformMatrix4fv(program.uniforms.u_label_plane_matrix, false, labelPlaneMatrix); } - gl.uniform1f(program.uniforms.u_fade_change, painter.options.fadeDuration ? painter.symbolFadeChange : 1); - - drawTileSymbols(program, programConfiguration, painter, layer, tile, buffers, isText, isSDF, pitchWithMap); - } -} - -function setSymbolDrawState(program, painter, layer, isText, rotateInShader, pitchWithMap, sizeData) { - - const gl = painter.context.gl; - const tr = painter.transform; - - gl.uniform1i(program.uniforms.u_pitch_with_map, pitchWithMap ? 1 : 0); + const matrix = painter.translatePosMatrix(coord.posMatrix, tile, translate, translateAnchor), + uLabelPlaneMatrix = alongLine ? identityMat4 : labelPlaneMatrix, + uglCoordMatrix = painter.translatePosMatrix(glCoordMatrix, tile, translate, translateAnchor, true); - gl.uniform1f(program.uniforms.u_is_text, isText ? 1 : 0); + let uniformValues; + if (isSDF) { + const hasHalo = layer.paint.get(isText ? 'text-halo-width' : 'icon-halo-width').constantOr(1) !== 0; - gl.uniform1f(program.uniforms.u_pitch, tr.pitch / 360 * 2 * Math.PI); + uniformValues = symbolSDFUniformValues(sizeData.functionType, + size, rotateInShader, pitchWithMap, painter, matrix, + uLabelPlaneMatrix, uglCoordMatrix, isText, texSize, true); - const isZoomConstant = sizeData.functionType === 'constant' || sizeData.functionType === 'source'; - const isFeatureConstant = sizeData.functionType === 'constant' || sizeData.functionType === 'camera'; - gl.uniform1i(program.uniforms.u_is_size_zoom_constant, isZoomConstant ? 1 : 0); - gl.uniform1i(program.uniforms.u_is_size_feature_constant, isFeatureConstant ? 1 : 0); + if (hasHalo) { + drawSymbolElements(buffers, layer, painter, program, depthMode, stencilMode, colorMode, uniformValues); + } - gl.uniform1f(program.uniforms.u_camera_to_center_distance, tr.cameraToCenterDistance); + uniformValues['u_is_halo'] = 0; - const size = symbolSize.evaluateSizeForZoom(sizeData, tr.zoom, symbolLayoutProperties.properties[isText ? 'text-size' : 'icon-size']); - if (size.uSizeT !== undefined) gl.uniform1f(program.uniforms.u_size_t, size.uSizeT); - if (size.uSize !== undefined) gl.uniform1f(program.uniforms.u_size, size.uSize); - - gl.uniform1f(program.uniforms.u_aspect_ratio, tr.width / tr.height); - gl.uniform1i(program.uniforms.u_rotate_symbol, rotateInShader ? 1 : 0); -} - -function drawTileSymbols(program, programConfiguration, painter, layer, tile, buffers, isText, isSDF, pitchWithMap) { - - const context = painter.context; - const gl = context.gl; - const tr = painter.transform; - - if (isSDF) { - const hasHalo = layer.paint.get(isText ? 'text-halo-width' : 'icon-halo-width').constantOr(1) !== 0; - const gammaScale = (pitchWithMap ? Math.cos(tr._pitch) * tr.cameraToCenterDistance : 1); - gl.uniform1f(program.uniforms.u_gamma_scale, gammaScale); - - if (hasHalo) { // Draw halo underneath the text. - gl.uniform1f(program.uniforms.u_is_halo, 1); - drawSymbolElements(buffers, layer, context, program); + } else { + uniformValues = symbolIconUniformValues(sizeData.functionType, + size, rotateInShader, pitchWithMap, painter, matrix, + uLabelPlaneMatrix, uglCoordMatrix, isText, texSize); } - gl.uniform1f(program.uniforms.u_is_halo, 0); + drawSymbolElements(buffers, layer, painter, program, depthMode, stencilMode, colorMode, uniformValues); } - - drawSymbolElements(buffers, layer, context, program); } -function drawSymbolElements(buffers, layer, context, program) { - program.draw( - context, - context.gl.TRIANGLES, - layer.id, - buffers.layoutVertexBuffer, - buffers.indexBuffer, - buffers.segments, - buffers.programConfigurations.get(layer.id), - buffers.dynamicLayoutVertexBuffer, - buffers.opacityVertexBuffer); +function drawSymbolElements(buffers, layer, painter, program, depthMode, stencilMode, colorMode, uniformValues) { + const context = painter.context; + const gl = context.gl; + program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, + uniformValues, layer.id, buffers.layoutVertexBuffer, + buffers.indexBuffer, buffers.segments, layer.paint, + painter.transform.zoom, buffers.programConfigurations.get(layer.id), + buffers.dynamicLayoutVertexBuffer, buffers.opacityVertexBuffer); } diff --git a/src/render/painter.js b/src/render/painter.js index 078d16a9493..762ef404b02 100644 --- a/src/render/painter.js +++ b/src/render/painter.js @@ -6,20 +6,22 @@ import { mat4 } from 'gl-matrix'; import SourceCache from '../source/source_cache'; import EXTENT from '../data/extent'; import pixelsToTileUnits from '../source/pixels_to_tile_units'; -import VertexArrayObject from './vertex_array_object'; -import { RasterBoundsArray, PosArray } from '../data/array_types'; +import SegmentVector from '../data/segment'; +import { RasterBoundsArray, PosArray, TriangleIndexArray, LineStripIndexArray } from '../data/array_types'; import rasterBoundsAttributes from '../data/raster_bounds_attributes'; import posAttributes from '../data/pos_attributes'; import ProgramConfiguration from '../data/program_configuration'; import CrossTileSymbolIndex from '../symbol/cross_tile_symbol_index'; import shaders from '../shaders'; import Program from './program'; +import { programUniforms } from './program/program_uniforms'; import Context from '../gl/context'; import DepthMode from '../gl/depth_mode'; import StencilMode from '../gl/stencil_mode'; import ColorMode from '../gl/color_mode'; import Texture from './texture'; import updateTileMasks from './tile_mask'; +import { clippingMaskUniformValues } from './program/clipping_mask_program'; import Color from '../style-spec/util/color'; import symbol from './draw_symbol'; import circle from './draw_circle'; @@ -50,10 +52,12 @@ import type Tile from '../source/tile'; import type {OverscaledTileID} from '../source/tile_id'; import type Style from '../style/style'; import type StyleLayer from '../style/style_layer'; +import type {CrossFaded} from '../style/cross_faded'; import type LineAtlas from './line_atlas'; import type ImageManager from './image_manager'; import type GlyphManager from './glyph_manager'; import type VertexBuffer from '../gl/vertex_buffer'; +import type IndexBuffer from '../gl/index_buffer'; import type {DepthMaskType, DepthFuncType} from '../gl/types'; export type RenderPass = 'offscreen' | 'opaque' | 'translucent'; @@ -84,15 +88,17 @@ class Painter { depthRbo: WebGLRenderbuffer; depthRboNeedsClear: boolean; tileExtentBuffer: VertexBuffer; - tileExtentVAO: VertexArrayObject; - tileExtentPatternVAO: VertexArrayObject; + tileExtentSegments: SegmentVector; debugBuffer: VertexBuffer; - debugVAO: VertexArrayObject; + debugSegments: SegmentVector; rasterBoundsBuffer: VertexBuffer; - rasterBoundsVAO: VertexArrayObject; + rasterBoundsSegments: SegmentVector; viewportBuffer: VertexBuffer; - viewportVAO: VertexArrayObject; + viewportSegments: SegmentVector; + quadTriangleIndexBuffer: IndexBuffer; + tileBorderIndexBuffer: IndexBuffer; _tileClippingMaskIDs: { [number]: number }; + stencilClearMode: StencilMode; style: Style; options: PainterOptions; lineAtlas: LineAtlas; @@ -103,7 +109,7 @@ class Painter { currentLayer: number; id: string; _showOverdrawInspector: boolean; - cache: { [string]: Program }; + cache: { [string]: Program<*> }; crossTileSymbolIndex: CrossTileSymbolIndex; symbolFadeChange: number; @@ -158,17 +164,15 @@ class Painter { tileExtentArray.emplaceBack(0, EXTENT); tileExtentArray.emplaceBack(EXTENT, EXTENT); this.tileExtentBuffer = context.createVertexBuffer(tileExtentArray, posAttributes.members); - this.tileExtentVAO = new VertexArrayObject(); - this.tileExtentPatternVAO = new VertexArrayObject(); + this.tileExtentSegments = SegmentVector.simpleSegment(0, 0, 4, 2); const debugArray = new PosArray(); debugArray.emplaceBack(0, 0); debugArray.emplaceBack(EXTENT, 0); - debugArray.emplaceBack(EXTENT, EXTENT); debugArray.emplaceBack(0, EXTENT); - debugArray.emplaceBack(0, 0); + debugArray.emplaceBack(EXTENT, EXTENT); this.debugBuffer = context.createVertexBuffer(debugArray, posAttributes.members); - this.debugVAO = new VertexArrayObject(); + this.debugSegments = SegmentVector.simpleSegment(0, 0, 4, 5); const rasterBoundsArray = new RasterBoundsArray(); rasterBoundsArray.emplaceBack(0, 0, 0, 0); @@ -176,7 +180,7 @@ class Painter { rasterBoundsArray.emplaceBack(0, EXTENT, 0, EXTENT); rasterBoundsArray.emplaceBack(EXTENT, EXTENT, EXTENT, EXTENT); this.rasterBoundsBuffer = context.createVertexBuffer(rasterBoundsArray, rasterBoundsAttributes.members); - this.rasterBoundsVAO = new VertexArrayObject(); + this.rasterBoundsSegments = SegmentVector.simpleSegment(0, 0, 4, 2); const viewportArray = new PosArray(); viewportArray.emplaceBack(0, 0); @@ -184,7 +188,23 @@ class Painter { viewportArray.emplaceBack(0, 1); viewportArray.emplaceBack(1, 1); this.viewportBuffer = context.createVertexBuffer(viewportArray, posAttributes.members); - this.viewportVAO = new VertexArrayObject(); + this.viewportSegments = SegmentVector.simpleSegment(0, 0, 4, 2); + + const tileLineStripIndices = new LineStripIndexArray(); + tileLineStripIndices.emplaceBack(0); + tileLineStripIndices.emplaceBack(1); + tileLineStripIndices.emplaceBack(3); + tileLineStripIndices.emplaceBack(2); + tileLineStripIndices.emplaceBack(0); + this.tileBorderIndexBuffer = context.createIndexBuffer(tileLineStripIndices); + + const quadTriangleIndices = new TriangleIndexArray(); + quadTriangleIndices.emplaceBack(0, 1, 2); + quadTriangleIndices.emplaceBack(2, 1, 3); + this.quadTriangleIndexBuffer = context.createIndexBuffer(quadTriangleIndices); + + const gl = this.context.gl; + this.stencilClearMode = new StencilMode({ func: gl.ALWAYS, mask: 0 }, 0x0, 0xFF, gl.ZERO, gl.ZERO, gl.ZERO); } /* @@ -200,19 +220,15 @@ class Painter { // effectively clearing the stencil buffer: once an upstream patch lands, remove // this function in favor of context.clear({ stencil: 0x0 }) - context.setColorMode(ColorMode.disabled); - context.setDepthMode(DepthMode.disabled); - context.setStencilMode(new StencilMode({ func: gl.ALWAYS, mask: 0 }, 0x0, 0xFF, gl.ZERO, gl.ZERO, gl.ZERO)); - const matrix = mat4.create(); mat4.ortho(matrix, 0, this.width, this.height, 0, 0, 1); mat4.scale(matrix, matrix, [gl.drawingBufferWidth, gl.drawingBufferHeight, 0]); - const program = this.useProgram('clippingMask'); - gl.uniformMatrix4fv(program.uniforms.u_matrix, false, matrix); - - this.viewportVAO.bind(context, program, this.viewportBuffer, []); - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + this.useProgram('clippingMask').draw(context, gl.TRIANGLES, + DepthMode.disabled, this.stencilClearMode, ColorMode.disabled, + clippingMaskUniformValues(matrix), + '$clipping', this.viewportBuffer, + this.quadTriangleIndexBuffer, this.viewportSegments); } _renderTileClippingMasks(tileIDs: Array) { @@ -222,21 +238,20 @@ class Painter { context.setColorMode(ColorMode.disabled); context.setDepthMode(DepthMode.disabled); + const program = this.useProgram('clippingMask'); + let idNext = 1; this._tileClippingMaskIDs = {}; for (const tileID of tileIDs) { const id = this._tileClippingMaskIDs[tileID.key] = idNext++; - // Tests will always pass, and ref value will be written to stencil buffer. - context.setStencilMode(new StencilMode({ func: gl.ALWAYS, mask: 0 }, id, 0xFF, gl.KEEP, gl.KEEP, gl.REPLACE)); - - const program = this.useProgram('clippingMask'); - gl.uniformMatrix4fv(program.uniforms.u_matrix, false, tileID.posMatrix); - - // Draw the clipping mask - this.tileExtentVAO.bind(this.context, program, this.tileExtentBuffer, []); - gl.drawArrays(gl.TRIANGLE_STRIP, 0, this.tileExtentBuffer.length); + program.draw(context, gl.TRIANGLES, DepthMode.disabled, + // Tests will always pass, and ref value will be written to stencil buffer. + new StencilMode({ func: gl.ALWAYS, mask: 0 }, id, 0xFF, gl.KEEP, gl.KEEP, gl.REPLACE), + ColorMode.disabled, clippingMaskUniformValues(tileID.posMatrix), + '$clipping', this.tileExtentBuffer, + this.quadTriangleIndexBuffer, this.tileExtentSegments); } } @@ -446,16 +461,28 @@ class Painter { return textures && textures.length > 0 ? textures.pop() : null; } - _createProgramCached(name: string, programConfiguration: ProgramConfiguration): Program { + /** + * Checks whether a pattern image is needed, and if it is, whether it is not loaded. + * + * @returns true if a needed image is missing and rendering needs to be skipped. + */ + isPatternMissing(image: ?CrossFaded): boolean { + if (!image) return false; + const imagePosA = this.imageManager.getPattern(image.from); + const imagePosB = this.imageManager.getPattern(image.to); + return !imagePosA || !imagePosB; + } + + _createProgramCached(name: string, programConfiguration: ProgramConfiguration): Program { this.cache = this.cache || {}; const key = `${name}${programConfiguration.cacheKey || ''}${this._showOverdrawInspector ? '/overdraw' : ''}`; if (!this.cache[key]) { - this.cache[key] = new Program(this.context, shaders[name], programConfiguration, this._showOverdrawInspector); + this.cache[key] = new Program(this.context, shaders[name], programConfiguration, programUniforms[name], this._showOverdrawInspector); } return this.cache[key]; } - useProgram(name: string, programConfiguration?: ProgramConfiguration): Program { + useProgram(name: string, programConfiguration?: ProgramConfiguration): Program { const nextProgram = this._createProgramCached(name, programConfiguration || this.emptyProgramConfiguration); this.context.program.set(nextProgram.program); diff --git a/src/render/pattern.js b/src/render/pattern.js deleted file mode 100644 index f5b60d7abe1..00000000000 --- a/src/render/pattern.js +++ /dev/null @@ -1,63 +0,0 @@ -// @flow - -import assert from 'assert'; - -import pixelsToTileUnits from '../source/pixels_to_tile_units'; - -import type Painter from './painter'; -import type Program from './program'; -import type {OverscaledTileID} from '../source/tile_id'; -import type {CrossFaded} from '../style/cross_faded'; - -/** - * Checks whether a pattern image is needed, and if it is, whether it is not loaded. - * @private - * @returns true if a needed image is missing and rendering needs to be skipped. - */ -export const isPatternMissing = function(image: ?CrossFaded, painter: Painter): boolean { - if (!image) return false; - const imagePosA = painter.imageManager.getPattern(image.from); - const imagePosB = painter.imageManager.getPattern(image.to); - return !imagePosA || !imagePosB; -}; - -export const prepare = function (image: CrossFaded, painter: Painter, program: Program) { - const context = painter.context; - const gl = context.gl; - - const imagePosA = painter.imageManager.getPattern(image.from); - const imagePosB = painter.imageManager.getPattern(image.to); - assert(imagePosA && imagePosB); - - gl.uniform1i(program.uniforms.u_image, 0); - gl.uniform2fv(program.uniforms.u_pattern_tl_a, (imagePosA: any).tl); - gl.uniform2fv(program.uniforms.u_pattern_br_a, (imagePosA: any).br); - gl.uniform2fv(program.uniforms.u_pattern_tl_b, (imagePosB: any).tl); - gl.uniform2fv(program.uniforms.u_pattern_br_b, (imagePosB: any).br); - const {width, height} = painter.imageManager.getPixelSize(); - gl.uniform2fv(program.uniforms.u_texsize, ([width, height]: Array)); - gl.uniform1f(program.uniforms.u_mix, image.t); - gl.uniform2fv(program.uniforms.u_pattern_size_a, (imagePosA: any).displaySize); - gl.uniform2fv(program.uniforms.u_pattern_size_b, (imagePosB: any).displaySize); - gl.uniform1f(program.uniforms.u_scale_a, image.fromScale); - gl.uniform1f(program.uniforms.u_scale_b, image.toScale); - - context.activeTexture.set(gl.TEXTURE0); - painter.imageManager.bind(painter.context); -}; - -export const setPatternUniforms = function (tile: {tileID: OverscaledTileID, tileSize: number}, painter: Painter, program: Program) { - const gl = painter.context.gl; - - gl.uniform1f(program.uniforms.u_tile_units_to_pixels, 1 / pixelsToTileUnits(tile, 1, painter.transform.tileZoom)); - - const numTiles = Math.pow(2, tile.tileID.overscaledZ); - const tileSizeAtNearestZoom = tile.tileSize * Math.pow(2, painter.transform.tileZoom) / numTiles; - - const pixelX = tileSizeAtNearestZoom * (tile.tileID.canonical.x + tile.tileID.wrap * numTiles); - const pixelY = tileSizeAtNearestZoom * tile.tileID.canonical.y; - - // split the pixel coord into two pairs of 16 bit numbers. The glsl spec only guarantees 16 bits of precision. - gl.uniform2f(program.uniforms.u_pixel_coord_upper, pixelX >> 16, pixelY >> 16); - gl.uniform2f(program.uniforms.u_pixel_coord_lower, pixelX & 0xFFFF, pixelY & 0xFFFF); -}; diff --git a/src/render/program.js b/src/render/program.js index bf4dbbcf944..fbfd11ca83f 100644 --- a/src/render/program.js +++ b/src/render/program.js @@ -11,20 +11,29 @@ import Context from '../gl/context'; import type SegmentVector from '../data/segment'; import type VertexBuffer from '../gl/vertex_buffer'; import type IndexBuffer from '../gl/index_buffer'; +import type DepthMode from '../gl/depth_mode'; +import type StencilMode from '../gl/stencil_mode'; +import type ColorMode from '../gl/color_mode'; +import type {Uniforms, UniformBindings, UniformValues, UniformLocations, BinderUniformTypes} from './uniform_binding'; export type DrawMode = | $PropertyType - | $PropertyType; + | $PropertyType + | $PropertyType; -class Program { +class Program { program: WebGLProgram; - uniforms: {[string]: WebGLUniformLocation}; + uniforms: UniformLocations; attributes: {[string]: number}; numAttributes: number; + fixedUniforms: Uniforms; + binderUniforms: Uniforms; + configuration: ProgramConfiguration; constructor(context: Context, source: {fragmentSource: string, vertexSource: string}, configuration: ProgramConfiguration, + fixedUniforms: (Context) => Uniforms, showOverdrawInspector: boolean) { const gl = context.gl; this.program = gl.createProgram(); @@ -81,23 +90,43 @@ class Program { this.uniforms[uniform.name] = gl.getUniformLocation(this.program, uniform.name); } } + + this.fixedUniforms = fixedUniforms(context); } draw(context: Context, drawMode: DrawMode, + depthMode: $ReadOnly, + stencilMode: $ReadOnly, + colorMode: $ReadOnly, + uniformValues: UniformValues, layerID: string, layoutVertexBuffer: VertexBuffer, indexBuffer: IndexBuffer, segments: SegmentVector, + currentProperties: any, + zoom: ?number, configuration: ?ProgramConfiguration, dynamicLayoutBuffer: ?VertexBuffer, dynamicLayoutBuffer2: ?VertexBuffer) { const gl = context.gl; + context.setDepthMode(depthMode); + context.setStencilMode(stencilMode); + context.setColorMode(colorMode); + + this.fixedUniforms.set(this.uniforms, uniformValues); + if (configuration) { + const invalidate = this.configuration && this.configuration !== configuration; + configuration.setUniforms(context, this, currentProperties, {zoom: (zoom: any)}, invalidate); + this.configuration = configuration; + } + const primitiveSize = { [gl.LINES]: 2, - [gl.TRIANGLES]: 3 + [gl.TRIANGLES]: 3, + [gl.LINE_STRIP]: 1 }[drawMode]; for (const segment of segments.get()) { diff --git a/src/render/program/background_program.js b/src/render/program/background_program.js new file mode 100644 index 00000000000..946a346f2c8 --- /dev/null +++ b/src/render/program/background_program.js @@ -0,0 +1,101 @@ +// @flow + +import { patternUniformValues } from './pattern'; +import { + Uniform1i, + Uniform1f, + Uniform2fv, + Uniform4fv, + UniformMatrix4fv, + Uniforms +} from '../uniform_binding'; +import { extend } from '../../util/util'; + +import type Painter from '../painter'; +import type {UniformValues} from '../uniform_binding'; +import type Context from '../../gl/context'; +import type Color from '../../style-spec/util/color'; +import type {CrossFaded} from '../../style/cross_faded'; +import type {OverscaledTileID} from '../../source/tile_id'; + +export type BackgroundUniformsType = {| + 'u_matrix': UniformMatrix4fv, + 'u_opacity': Uniform1f, + 'u_color': Uniform4fv +|}; + +export type BackgroundPatternUniformsType = {| + 'u_matrix': UniformMatrix4fv, + 'u_opacity': Uniform1f, + // pattern uniforms: + 'u_image': Uniform1i, + 'u_pattern_tl_a': Uniform2fv, + 'u_pattern_br_a': Uniform2fv, + 'u_pattern_tl_b': Uniform2fv, + 'u_pattern_br_b': Uniform2fv, + 'u_texsize': Uniform2fv, + 'u_mix': Uniform1f, + 'u_pattern_size_a': Uniform2fv, + 'u_pattern_size_b': Uniform2fv, + 'u_scale_a': Uniform1f, + 'u_scale_b': Uniform1f, + 'u_pixel_coord_upper': Uniform2fv, + 'u_pixel_coord_lower': Uniform2fv, + 'u_tile_units_to_pixels': Uniform1f +|}; + +const backgroundUniforms = (context: Context): Uniforms => new Uniforms({ + 'u_matrix': new UniformMatrix4fv(context), + 'u_opacity': new Uniform1f(context), + 'u_color': new Uniform4fv(context) +}); + +const backgroundPatternUniforms = (context: Context): Uniforms => new Uniforms({ + 'u_matrix': new UniformMatrix4fv(context), + 'u_opacity': new Uniform1f(context), + 'u_image': new Uniform1i(context), + 'u_pattern_tl_a': new Uniform2fv(context), + 'u_pattern_br_a': new Uniform2fv(context), + 'u_pattern_tl_b': new Uniform2fv(context), + 'u_pattern_br_b': new Uniform2fv(context), + 'u_texsize': new Uniform2fv(context), + 'u_mix': new Uniform1f(context), + 'u_pattern_size_a': new Uniform2fv(context), + 'u_pattern_size_b': new Uniform2fv(context), + 'u_scale_a': new Uniform1f(context), + 'u_scale_b': new Uniform1f(context), + 'u_pixel_coord_upper': new Uniform2fv(context), + 'u_pixel_coord_lower': new Uniform2fv(context), + 'u_tile_units_to_pixels': new Uniform1f(context) +}); + +const backgroundUniformValues = ( + matrix: Float32Array, + opacity: number, + color: Color +): UniformValues => ({ + 'u_matrix': matrix, + 'u_opacity': opacity, + 'u_color': [color.r, color.g, color.b, color.a] +}); + +const backgroundPatternUniformValues = ( + matrix: Float32Array, + opacity: number, + painter: Painter, + image: CrossFaded, + tile: {tileID: OverscaledTileID, tileSize: number} +): UniformValues => extend( + patternUniformValues(image, painter, tile), + { + 'u_matrix': matrix, + 'u_opacity': opacity + } +); + +export { + backgroundUniforms, + backgroundPatternUniforms, + backgroundUniformValues, + backgroundPatternUniformValues +}; diff --git a/src/render/program/circle_program.js b/src/render/program/circle_program.js new file mode 100644 index 00000000000..0bd43ca8e2d --- /dev/null +++ b/src/render/program/circle_program.js @@ -0,0 +1,66 @@ +// @flow + +import { + Uniform1i, + Uniform1f, + Uniform2fv, + UniformMatrix4fv, + Uniforms +} from '../uniform_binding'; +import pixelsToTileUnits from '../../source/pixels_to_tile_units'; + +import type Context from '../../gl/context'; +import type {UniformValues} from '../uniform_binding'; +import type {OverscaledTileID} from '../../source/tile_id'; +import type Tile from '../../source/tile'; +import type CircleStyleLayer from '../../style/style_layer/circle_style_layer'; +import type Painter from '../painter'; + +export type CircleUniformsType = {| + 'u_camera_to_center_distance': Uniform1f, + 'u_scale_with_map': Uniform1i, + 'u_pitch_with_map': Uniform1i, + 'u_extrude_scale': Uniform2fv, + 'u_matrix': UniformMatrix4fv +|}; + +const circleUniforms = (context: Context): Uniforms => new Uniforms({ + 'u_camera_to_center_distance': new Uniform1f(context), + 'u_scale_with_map': new Uniform1i(context), + 'u_pitch_with_map': new Uniform1i(context), + 'u_extrude_scale': new Uniform2fv(context), + 'u_matrix': new UniformMatrix4fv(context) +}); + +const circleUniformValues = ( + painter: Painter, + coord: OverscaledTileID, + tile: Tile, + layer: CircleStyleLayer +): UniformValues => { + const transform = painter.transform; + + let pitchWithMap: boolean, extrudeScale: [number, number]; + if (layer.paint.get('circle-pitch-alignment') === 'map') { + const pixelRatio = pixelsToTileUnits(tile, 1, transform.zoom); + pitchWithMap = true; + extrudeScale = [pixelRatio, pixelRatio]; + } else { + pitchWithMap = false; + extrudeScale = transform.pixelsToGLUnits; + } + + return { + 'u_camera_to_center_distance': transform.cameraToCenterDistance, + 'u_scale_with_map': +(layer.paint.get('circle-pitch-scale') === 'map'), + 'u_matrix': painter.translatePosMatrix( + coord.posMatrix, + tile, + layer.paint.get('circle-translate'), + layer.paint.get('circle-translate-anchor')), + 'u_pitch_with_map': +(pitchWithMap), + 'u_extrude_scale': extrudeScale + }; +}; + +export { circleUniforms, circleUniformValues }; diff --git a/src/render/program/clipping_mask_program.js b/src/render/program/clipping_mask_program.js new file mode 100644 index 00000000000..58f5b500797 --- /dev/null +++ b/src/render/program/clipping_mask_program.js @@ -0,0 +1,20 @@ +// @flow + +import { UniformMatrix4fv, Uniforms } from '../uniform_binding'; + +import type Context from '../../gl/context'; +import type {UniformValues} from '../uniform_binding'; + +export type ClippingMaskUniformsType = {| + 'u_matrix': UniformMatrix4fv +|}; + +const clippingMaskUniforms = (context: Context): Uniforms => new Uniforms({ + 'u_matrix': new UniformMatrix4fv(context) +}); + +const clippingMaskUniformValues = (matrix: Float32Array): UniformValues => ({ + 'u_matrix': matrix +}); + +export { clippingMaskUniforms, clippingMaskUniformValues }; diff --git a/src/render/program/collision_program.js b/src/render/program/collision_program.js new file mode 100644 index 00000000000..0f0a4b2232b --- /dev/null +++ b/src/render/program/collision_program.js @@ -0,0 +1,50 @@ +// @flow + +import { + Uniform1f, + Uniform2fv, + UniformMatrix4fv, + Uniforms +} from '../uniform_binding'; +import pixelsToTileUnits from '../../source/pixels_to_tile_units'; + +import type Context from '../../gl/context'; +import type {UniformValues} from '../uniform_binding'; +import type Transform from '../../geo/transform'; +import type Tile from '../../source/tile'; + +export type CollisionUniformsType = {| + 'u_matrix': UniformMatrix4fv, + 'u_camera_to_center_distance': Uniform1f, + 'u_pixels_to_tile_units': Uniform1f, + 'u_extrude_scale': Uniform2fv, + 'u_overscale_factor': Uniform1f +|}; + +const collisionUniforms = (context: Context): Uniforms => new Uniforms({ + 'u_matrix': new UniformMatrix4fv(context), + 'u_camera_to_center_distance': new Uniform1f(context), + 'u_pixels_to_tile_units': new Uniform1f(context), + 'u_extrude_scale': new Uniform2fv(context), + 'u_overscale_factor': new Uniform1f(context) +}); + +const collisionUniformValues = ( + matrix: Float32Array, + transform: Transform, + tile: Tile +): UniformValues => { + const pixelRatio = pixelsToTileUnits(tile, 1, transform.zoom); + const scale = Math.pow(2, transform.zoom - tile.tileID.overscaledZ); + const overscaleFactor = tile.tileID.overscaleFactor(); + return { + 'u_matrix': matrix, + 'u_camera_to_center_distance': transform.cameraToCenterDistance, + 'u_pixels_to_tile_units': pixelRatio, + 'u_extrude_scale': [transform.pixelsToGLUnits[0] / (pixelRatio * scale), + transform.pixelsToGLUnits[1] / (pixelRatio * scale)], + 'u_overscale_factor': overscaleFactor + }; +}; + +export { collisionUniforms, collisionUniformValues }; diff --git a/src/render/program/debug_program.js b/src/render/program/debug_program.js new file mode 100644 index 00000000000..cd1d7d8651c --- /dev/null +++ b/src/render/program/debug_program.js @@ -0,0 +1,28 @@ +// @flow + +import { + Uniform4fv, + UniformMatrix4fv, + Uniforms +} from '../uniform_binding'; + +import type Context from '../../gl/context'; +import type {UniformValues} from '../uniform_binding'; +import type Color from '../../style-spec/util/color'; + +export type DebugUniformsType = {| + 'u_color': Uniform4fv, + 'u_matrix': UniformMatrix4fv +|}; + +const debugUniforms = (context: Context): Uniforms => new Uniforms({ + 'u_color': new Uniform4fv(context), + 'u_matrix': new UniformMatrix4fv(context) +}); + +const debugUniformValues = (matrix: Float32Array, color: Color): UniformValues => ({ + 'u_matrix': matrix, + 'u_color': [color.r, color.g, color.b, color.a] +}); + +export { debugUniforms, debugUniformValues }; diff --git a/src/render/program/fill_extrusion_program.js b/src/render/program/fill_extrusion_program.js new file mode 100644 index 00000000000..ec1317e198a --- /dev/null +++ b/src/render/program/fill_extrusion_program.js @@ -0,0 +1,158 @@ +// @flow + +import { patternUniformValues } from './pattern'; +import { + Uniform1i, + Uniform1f, + Uniform2fv, + Uniform3fv, + UniformMatrix4fv, + Uniforms +} from '../uniform_binding'; + +import {mat3, vec3, mat4} from 'gl-matrix'; +import { extend } from '../../util/util'; + +import type Context from '../../gl/context'; +import type Painter from '../painter'; +import type {OverscaledTileID} from '../../source/tile_id'; +import type {CrossFaded} from '../../style/cross_faded'; +import type {UniformValues} from '../uniform_binding'; +import type FillExtrusionStyleLayer from '../../style/style_layer/fill_extrusion_style_layer'; + +export type FillExtrusionUniformsType = {| + 'u_matrix': UniformMatrix4fv, + 'u_lightpos': Uniform3fv, + 'u_lightintensity': Uniform1f, + 'u_lightcolor': Uniform3fv +|}; + +export type FillExtrusionPatternUniformsType = {| + 'u_matrix': UniformMatrix4fv, + 'u_lightpos': Uniform3fv, + 'u_lightintensity': Uniform1f, + 'u_lightcolor': Uniform3fv, + 'u_height_factor': Uniform1f, + // pattern uniforms: + 'u_image': Uniform1i, + 'u_pattern_tl_a': Uniform2fv, + 'u_pattern_br_a': Uniform2fv, + 'u_pattern_tl_b': Uniform2fv, + 'u_pattern_br_b': Uniform2fv, + 'u_texsize': Uniform2fv, + 'u_mix': Uniform1f, + 'u_pattern_size_a': Uniform2fv, + 'u_pattern_size_b': Uniform2fv, + 'u_scale_a': Uniform1f, + 'u_scale_b': Uniform1f, + 'u_pixel_coord_upper': Uniform2fv, + 'u_pixel_coord_lower': Uniform2fv, + 'u_tile_units_to_pixels': Uniform1f +|}; + +export type ExtrusionTextureUniformsType = {| + 'u_matrix': UniformMatrix4fv, + 'u_world': Uniform2fv, + 'u_image': Uniform1i, + 'u_opacity': Uniform1f +|}; + +const fillExtrusionUniforms = (context: Context): Uniforms => new Uniforms({ + 'u_matrix': new UniformMatrix4fv(context), + 'u_lightpos': new Uniform3fv(context), + 'u_lightintensity': new Uniform1f(context), + 'u_lightcolor': new Uniform3fv(context) +}); + +const fillExtrusionPatternUniforms = (context: Context): Uniforms => new Uniforms({ + 'u_matrix': new UniformMatrix4fv(context), + 'u_lightpos': new Uniform3fv(context), + 'u_lightintensity': new Uniform1f(context), + 'u_lightcolor': new Uniform3fv(context), + 'u_height_factor': new Uniform1f(context), + 'u_image': new Uniform1i(context), + 'u_pattern_tl_a': new Uniform2fv(context), + 'u_pattern_br_a': new Uniform2fv(context), + 'u_pattern_tl_b': new Uniform2fv(context), + 'u_pattern_br_b': new Uniform2fv(context), + 'u_texsize': new Uniform2fv(context), + 'u_mix': new Uniform1f(context), + 'u_pattern_size_a': new Uniform2fv(context), + 'u_pattern_size_b': new Uniform2fv(context), + 'u_scale_a': new Uniform1f(context), + 'u_scale_b': new Uniform1f(context), + 'u_pixel_coord_upper': new Uniform2fv(context), + 'u_pixel_coord_lower': new Uniform2fv(context), + 'u_tile_units_to_pixels': new Uniform1f(context) +}); + +const extrusionTextureUniforms = (context: Context): Uniforms => new Uniforms({ + 'u_matrix': new UniformMatrix4fv(context), + 'u_world': new Uniform2fv(context), + 'u_image': new Uniform1i(context), + 'u_opacity': new Uniform1f(context) +}); + +const fillExtrusionUniformValues = ( + matrix: Float32Array, + painter: Painter +): UniformValues => { + const light = painter.style.light; + const _lp = light.properties.get('position'); + const lightPos = [_lp.x, _lp.y, _lp.z]; + const lightMat = mat3.create(); + if (light.properties.get('anchor') === 'viewport') { + mat3.fromRotation(lightMat, -painter.transform.angle); + } + vec3.transformMat3(lightPos, lightPos, lightMat); + + const lightColor = light.properties.get('color'); + + return { + 'u_matrix': matrix, + 'u_lightpos': lightPos, + 'u_lightintensity': light.properties.get('intensity'), + 'u_lightcolor': [lightColor.r, lightColor.g, lightColor.b] + }; +}; + +const fillExtrusionPatternUniformValues = ( + matrix: Float32Array, + painter: Painter, + coord: OverscaledTileID, + image: CrossFaded, + tile: {tileID: OverscaledTileID, tileSize: number} +): UniformValues => { + return extend(fillExtrusionUniformValues(matrix, painter), + patternUniformValues(image, painter, tile), + { + 'u_height_factor': -Math.pow(2, coord.overscaledZ) / tile.tileSize / 8 + }); +}; + +const extrusionTextureUniformValues = ( + painter: Painter, + layer: FillExtrusionStyleLayer, + textureUnit: number +): UniformValues => { + const matrix = mat4.create(); + mat4.ortho(matrix, 0, painter.width, painter.height, 0, 0, 1); + + const gl = painter.context.gl; + + return { + 'u_matrix': matrix, + 'u_world': [gl.drawingBufferWidth, gl.drawingBufferHeight], + 'u_image': textureUnit, + 'u_opacity': layer.paint.get('fill-extrusion-opacity') + }; +}; + +export { + fillExtrusionUniforms, + fillExtrusionPatternUniforms, + extrusionTextureUniforms, + fillExtrusionUniformValues, + fillExtrusionPatternUniformValues, + extrusionTextureUniformValues +}; diff --git a/src/render/program/fill_program.js b/src/render/program/fill_program.js new file mode 100644 index 00000000000..98fa19a8806 --- /dev/null +++ b/src/render/program/fill_program.js @@ -0,0 +1,157 @@ +// @flow + +import {patternUniformValues} from './pattern'; +import { + Uniform1i, + Uniform1f, + Uniform2fv, + UniformMatrix4fv, + Uniforms +} from '../uniform_binding'; +import { extend } from '../../util/util'; + +import type Painter from '../painter'; +import type {UniformValues} from '../uniform_binding'; +import type Context from '../../gl/context'; +import type {CrossFaded} from '../../style/cross_faded'; +import type {OverscaledTileID} from '../../source/tile_id'; + +export type FillUniformsType = {| + 'u_matrix': UniformMatrix4fv +|}; + +export type FillOutlineUniformsType = {| + 'u_matrix': UniformMatrix4fv, + 'u_world': Uniform2fv +|}; + +export type FillPatternUniformsType = {| + 'u_matrix': UniformMatrix4fv, + // pattern uniforms: + 'u_image': Uniform1i, + 'u_pattern_tl_a': Uniform2fv, + 'u_pattern_br_a': Uniform2fv, + 'u_pattern_tl_b': Uniform2fv, + 'u_pattern_br_b': Uniform2fv, + 'u_texsize': Uniform2fv, + 'u_mix': Uniform1f, + 'u_pattern_size_a': Uniform2fv, + 'u_pattern_size_b': Uniform2fv, + 'u_scale_a': Uniform1f, + 'u_scale_b': Uniform1f, + 'u_pixel_coord_upper': Uniform2fv, + 'u_pixel_coord_lower': Uniform2fv, + 'u_tile_units_to_pixels': Uniform1f +|}; + +export type FillOutlinePatternUniformsType = {| + 'u_matrix': UniformMatrix4fv, + 'u_world': Uniform2fv, + // pattern uniforms: + 'u_image': Uniform1i, + 'u_pattern_tl_a': Uniform2fv, + 'u_pattern_br_a': Uniform2fv, + 'u_pattern_tl_b': Uniform2fv, + 'u_pattern_br_b': Uniform2fv, + 'u_texsize': Uniform2fv, + 'u_mix': Uniform1f, + 'u_pattern_size_a': Uniform2fv, + 'u_pattern_size_b': Uniform2fv, + 'u_scale_a': Uniform1f, + 'u_scale_b': Uniform1f, + 'u_pixel_coord_upper': Uniform2fv, + 'u_pixel_coord_lower': Uniform2fv, + 'u_tile_units_to_pixels': Uniform1f +|}; + +const fillUniforms = (context: Context): Uniforms => new Uniforms({ + 'u_matrix': new UniformMatrix4fv(context) +}); + +const fillPatternUniforms = (context: Context): Uniforms => new Uniforms({ + 'u_matrix': new UniformMatrix4fv(context), + 'u_image': new Uniform1i(context), + 'u_pattern_tl_a': new Uniform2fv(context), + 'u_pattern_br_a': new Uniform2fv(context), + 'u_pattern_tl_b': new Uniform2fv(context), + 'u_pattern_br_b': new Uniform2fv(context), + 'u_texsize': new Uniform2fv(context), + 'u_mix': new Uniform1f(context), + 'u_pattern_size_a': new Uniform2fv(context), + 'u_pattern_size_b': new Uniform2fv(context), + 'u_scale_a': new Uniform1f(context), + 'u_scale_b': new Uniform1f(context), + 'u_pixel_coord_upper': new Uniform2fv(context), + 'u_pixel_coord_lower': new Uniform2fv(context), + 'u_tile_units_to_pixels': new Uniform1f(context) +}); + +const fillOutlineUniforms = (context: Context): Uniforms => new Uniforms({ + 'u_matrix': new UniformMatrix4fv(context), + 'u_world': new Uniform2fv(context) +}); + +const fillOutlinePatternUniforms = (context: Context): Uniforms => new Uniforms({ + 'u_matrix': new UniformMatrix4fv(context), + 'u_world': new Uniform2fv(context), + 'u_image': new Uniform1i(context), + 'u_pattern_tl_a': new Uniform2fv(context), + 'u_pattern_br_a': new Uniform2fv(context), + 'u_pattern_tl_b': new Uniform2fv(context), + 'u_pattern_br_b': new Uniform2fv(context), + 'u_texsize': new Uniform2fv(context), + 'u_mix': new Uniform1f(context), + 'u_pattern_size_a': new Uniform2fv(context), + 'u_pattern_size_b': new Uniform2fv(context), + 'u_scale_a': new Uniform1f(context), + 'u_scale_b': new Uniform1f(context), + 'u_pixel_coord_upper': new Uniform2fv(context), + 'u_pixel_coord_lower': new Uniform2fv(context), + 'u_tile_units_to_pixels': new Uniform1f(context) +}); + +const fillUniformValues = (matrix: Float32Array): UniformValues => ({ + 'u_matrix': matrix +}); + +const fillPatternUniformValues = ( + matrix: Float32Array, + painter: Painter, + image: CrossFaded, + tile: {tileID: OverscaledTileID, tileSize: number} +): UniformValues => extend( + fillUniformValues(matrix), + patternUniformValues(image, painter, tile) +); + +const fillOutlineUniformValues = ( + matrix: Float32Array, + drawingBufferSize: [number, number] +): UniformValues => ({ + 'u_matrix': matrix, + 'u_world': drawingBufferSize +}); + +const fillOutlinePatternUniformValues = ( + matrix: Float32Array, + painter: Painter, + image: CrossFaded, + tile: {tileID: OverscaledTileID, tileSize: number}, + drawingBufferSize: [number, number] +): UniformValues => extend( + fillPatternUniformValues(matrix, painter, image, tile), + { + 'u_world': drawingBufferSize + } +); + +export { + fillUniforms, + fillPatternUniforms, + fillOutlineUniforms, + fillOutlinePatternUniforms, + fillUniformValues, + fillPatternUniformValues, + fillOutlineUniformValues, + fillOutlinePatternUniformValues +}; diff --git a/src/render/program/heatmap_program.js b/src/render/program/heatmap_program.js new file mode 100644 index 00000000000..956293d6486 --- /dev/null +++ b/src/render/program/heatmap_program.js @@ -0,0 +1,84 @@ +// @flow + +import { mat4 } from 'gl-matrix'; + +import { + Uniform1i, + Uniform1f, + Uniform2fv, + UniformMatrix4fv, + Uniforms +} from '../uniform_binding'; +import pixelsToTileUnits from '../../source/pixels_to_tile_units'; + +import type Context from '../../gl/context'; +import type Tile from '../../source/tile'; +import type {UniformValues} from '../uniform_binding'; +import type Painter from '../painter'; +import type HeatmapStyleLayer from '../../style/style_layer/heatmap_style_layer'; + +export type HeatmapUniformsType = {| + 'u_extrude_scale': Uniform1f, + 'u_intensity': Uniform1f, + 'u_matrix': UniformMatrix4fv +|}; + +export type HeatmapTextureUniformsType = {| + 'u_matrix': UniformMatrix4fv, + 'u_world': Uniform2fv, + 'u_image': Uniform1i, + 'u_color_ramp': Uniform1i, + 'u_opacity': Uniform1f +|}; + +const heatmapUniforms = (context: Context): Uniforms => new Uniforms({ + 'u_extrude_scale': new Uniform1f(context), + 'u_intensity': new Uniform1f(context), + 'u_matrix': new UniformMatrix4fv(context) +}); + +const heatmapTextureUniforms = (context: Context): Uniforms => new Uniforms({ + 'u_matrix': new UniformMatrix4fv(context), + 'u_world': new Uniform2fv(context), + 'u_image': new Uniform1i(context), + 'u_color_ramp': new Uniform1i(context), + 'u_opacity': new Uniform1f(context) +}); + +const heatmapUniformValues = ( + matrix: Float32Array, + tile: Tile, + zoom: number, + intensity: number +): UniformValues => ({ + 'u_matrix': matrix, + 'u_extrude_scale': pixelsToTileUnits(tile, 1, zoom), + 'u_intensity': intensity +}); + +const heatmapTextureUniformValues = ( + painter: Painter, + layer: HeatmapStyleLayer, + textureUnit: number, + colorRampUnit: number +): UniformValues => { + const matrix = mat4.create(); + mat4.ortho(matrix, 0, painter.width, painter.height, 0, 0, 1); + + const gl = painter.context.gl; + + return { + 'u_matrix': matrix, + 'u_world': [gl.drawingBufferWidth, gl.drawingBufferHeight], + 'u_image': textureUnit, + 'u_color_ramp': colorRampUnit, + 'u_opacity': layer.paint.get('heatmap-opacity') + }; +}; + +export { + heatmapUniforms, + heatmapTextureUniforms, + heatmapUniformValues, + heatmapTextureUniformValues +}; diff --git a/src/render/program/hillshade_program.js b/src/render/program/hillshade_program.js new file mode 100644 index 00000000000..4dd02140c18 --- /dev/null +++ b/src/render/program/hillshade_program.js @@ -0,0 +1,122 @@ +// @flow + +import assert from 'assert'; +import { mat4 } from 'gl-matrix'; + +import { + Uniform1i, + Uniform1f, + Uniform2fv, + Uniform4fv, + UniformMatrix4fv, + Uniforms +} from '../uniform_binding'; +import EXTENT from '../../data/extent'; +import Coordinate from '../../geo/coordinate'; + +import type Context from '../../gl/context'; +import type {UniformValues} from '../uniform_binding'; +import type Tile from '../../source/tile'; +import type Painter from '../painter'; +import type HillshadeStyleLayer from '../../style/style_layer/hillshade_style_layer'; +import type DEMData from '../../data/dem_data'; +import type {OverscaledTileID} from '../../source/tile_id'; + +export type HillshadeUniformsType = {| + 'u_matrix': UniformMatrix4fv, + 'u_image': Uniform1i, + 'u_latrange': Uniform2fv, + 'u_light': Uniform2fv, + 'u_shadow': Uniform4fv, + 'u_highlight': Uniform4fv, + 'u_accent': Uniform4fv +|}; + +export type HillshadePrepareUniformsType = {| + 'u_matrix': UniformMatrix4fv, + 'u_image': Uniform1i, + 'u_dimension': Uniform2fv, + 'u_zoom': Uniform1f, + 'u_maxzoom': Uniform1f +|}; + +const hillshadeUniforms = (context: Context): Uniforms => new Uniforms({ + 'u_matrix': new UniformMatrix4fv(context), + 'u_image': new Uniform1i(context), + 'u_latrange': new Uniform2fv(context), + 'u_light': new Uniform2fv(context), + 'u_shadow': new Uniform4fv(context), + 'u_highlight': new Uniform4fv(context), + 'u_accent': new Uniform4fv(context) +}); + +const hillshadePrepareUniforms = (context: Context): Uniforms => new Uniforms({ + 'u_matrix': new UniformMatrix4fv(context), + 'u_image': new Uniform1i(context), + 'u_dimension': new Uniform2fv(context), + 'u_zoom': new Uniform1f(context), + 'u_maxzoom': new Uniform1f(context) +}); + +const hillshadeUniformValues = ( + painter: Painter, + tile: Tile, + layer: HillshadeStyleLayer +): UniformValues => { + const shadow = layer.paint.get("hillshade-shadow-color"); + const highlight = layer.paint.get("hillshade-highlight-color"); + const accent = layer.paint.get("hillshade-accent-color"); + + let azimuthal = layer.paint.get('hillshade-illumination-direction') * (Math.PI / 180); + // modify azimuthal angle by map rotation if light is anchored at the viewport + if (layer.paint.get('hillshade-illumination-anchor') === 'viewport') { + azimuthal -= painter.transform.angle; + } + + return { + 'u_matrix': painter.transform.calculatePosMatrix(tile.tileID.toUnwrapped(), true), + 'u_image': 0, + 'u_latrange': getTileLatRange(painter, tile.tileID), + 'u_light': [layer.paint.get('hillshade-exaggeration'), azimuthal], + 'u_shadow': [shadow.r, shadow.g, shadow.b, shadow.a], + 'u_highlight': [highlight.r, highlight.g, highlight.b, highlight.a], + 'u_accent': [accent.r, accent.g, accent.b, accent.a] + }; +}; + +const hillshadeUniformPrepareValues = ( + tile: {dem: ?DEMData, tileID: OverscaledTileID}, maxzoom: number +): UniformValues => { + assert(tile.dem); + const tileSize = ((tile.dem: any): DEMData).dim; + const matrix = mat4.create(); + // Flip rendering at y axis. + mat4.ortho(matrix, 0, EXTENT, -EXTENT, 0, 0, 1); + mat4.translate(matrix, matrix, [0, -EXTENT, 0]); + + return { + 'u_matrix': matrix, + 'u_image': 1, + 'u_dimension': [tileSize * 2, tileSize * 2], + 'u_zoom': tile.tileID.overscaledZ, + 'u_maxzoom': maxzoom + }; +}; + +function getTileLatRange(painter: Painter, tileID: OverscaledTileID) { + // for scaling the magnitude of a points slope by its latitude + const coordinate0 = tileID.toCoordinate(); + const coordinate1 = new Coordinate( + coordinate0.column, coordinate0.row + 1, coordinate0.zoom); + return [ + painter.transform.coordinateLocation(coordinate0).lat, + painter.transform.coordinateLocation(coordinate1).lat + ]; +} + +export { + hillshadeUniforms, + hillshadePrepareUniforms, + hillshadeUniformValues, + hillshadeUniformPrepareValues +}; diff --git a/src/render/program/line_program.js b/src/render/program/line_program.js new file mode 100644 index 00000000000..d5c739a6bef --- /dev/null +++ b/src/render/program/line_program.js @@ -0,0 +1,213 @@ +// @flow + +import { + Uniform1i, + Uniform1f, + Uniform2fv, + UniformMatrix4fv, + Uniforms +} from '../uniform_binding'; +import pixelsToTileUnits from '../../source/pixels_to_tile_units'; +import { extend } from '../../util/util'; +import browser from '../../util/browser'; + +import type Context from '../../gl/context'; +import type {UniformValues} from '../uniform_binding'; +import type Transform from '../../geo/transform'; +import type Tile from '../../source/tile'; +import type {CrossFaded} from '../../style/cross_faded'; +import type LineStyleLayer from '../../style/style_layer/line_style_layer'; +import type Painter from '../painter'; + +export type LineUniformsType = {| + 'u_matrix': UniformMatrix4fv, + 'u_ratio': Uniform1f, + 'u_gl_units_to_pixels': Uniform2fv +|}; + +export type LineGradientUniformsType = {| + 'u_matrix': UniformMatrix4fv, + 'u_ratio': Uniform1f, + 'u_gl_units_to_pixels': Uniform2fv, + 'u_image': Uniform1i +|}; + +export type LinePatternUniformsType = {| + 'u_matrix': UniformMatrix4fv, + 'u_ratio': Uniform1f, + 'u_gl_units_to_pixels': Uniform2fv, + 'u_pattern_size_a': Uniform2fv, + 'u_pattern_size_b': Uniform2fv, + 'u_texsize': Uniform2fv, + 'u_image': Uniform1i, + 'u_pattern_tl_a': Uniform2fv, + 'u_pattern_br_a': Uniform2fv, + 'u_pattern_tl_b': Uniform2fv, + 'u_pattern_br_b': Uniform2fv, + 'u_fade': Uniform1f +|}; + +export type LineSDFUniformsType = {| + 'u_matrix': UniformMatrix4fv, + 'u_ratio': Uniform1f, + 'u_gl_units_to_pixels': Uniform2fv, + 'u_patternscale_a': Uniform2fv, + 'u_patternscale_b': Uniform2fv, + 'u_sdfgamma': Uniform1f, + 'u_image': Uniform1i, + 'u_tex_y_a': Uniform1f, + 'u_tex_y_b': Uniform1f, + 'u_mix': Uniform1f +|}; + +const lineUniforms = (context: Context): Uniforms => new Uniforms({ + 'u_matrix': new UniformMatrix4fv(context), + 'u_ratio': new Uniform1f(context), + 'u_gl_units_to_pixels': new Uniform2fv(context) +}); + +const lineGradientUniforms = (context: Context): Uniforms => new Uniforms({ + 'u_matrix': new UniformMatrix4fv(context), + 'u_ratio': new Uniform1f(context), + 'u_gl_units_to_pixels': new Uniform2fv(context), + 'u_image': new Uniform1i(context) +}); + +const linePatternUniforms = (context: Context): Uniforms => new Uniforms({ + 'u_matrix': new UniformMatrix4fv(context), + 'u_ratio': new Uniform1f(context), + 'u_gl_units_to_pixels': new Uniform2fv(context), + 'u_pattern_size_a': new Uniform2fv(context), + 'u_pattern_size_b': new Uniform2fv(context), + 'u_texsize': new Uniform2fv(context), + 'u_image': new Uniform1i(context), + 'u_pattern_tl_a': new Uniform2fv(context), + 'u_pattern_br_a': new Uniform2fv(context), + 'u_pattern_tl_b': new Uniform2fv(context), + 'u_pattern_br_b': new Uniform2fv(context), + 'u_fade': new Uniform1f(context) +}); + +const lineSDFUniforms = (context: Context): Uniforms => new Uniforms({ + 'u_matrix': new UniformMatrix4fv(context), + 'u_ratio': new Uniform1f(context), + 'u_gl_units_to_pixels': new Uniform2fv(context), + 'u_patternscale_a': new Uniform2fv(context), + 'u_patternscale_b': new Uniform2fv(context), + 'u_sdfgamma': new Uniform1f(context), + 'u_image': new Uniform1i(context), + 'u_tex_y_a': new Uniform1f(context), + 'u_tex_y_b': new Uniform1f(context), + 'u_mix': new Uniform1f(context) +}); + +const lineUniformValues = ( + painter: Painter, + tile: Tile, + layer: LineStyleLayer +): UniformValues => { + const transform = painter.transform; + + return { + 'u_matrix': calculateMatrix(painter, tile, layer), + 'u_ratio': 1 / pixelsToTileUnits(tile, 1, transform.zoom), + 'u_gl_units_to_pixels': [ + 1 / transform.pixelsToGLUnits[0], + 1 / transform.pixelsToGLUnits[1] + ] + }; +}; + +const lineGradientUniformValues = ( + painter: Painter, + tile: Tile, + layer: LineStyleLayer +): UniformValues => { + return extend(lineUniformValues(painter, tile, layer), { + 'u_image': 0 + }); +}; + +const linePatternUniformValues = ( + painter: Painter, + tile: Tile, + layer: LineStyleLayer, + image: CrossFaded +): UniformValues => { + const pixelSize = painter.imageManager.getPixelSize(); + const tileRatio = calculateTileRatio(tile, painter.transform); + + const imagePosA: any = painter.imageManager.getPattern(image.from); + const imagePosB: any = painter.imageManager.getPattern(image.to); + + return extend(lineUniformValues(painter, tile, layer), { + 'u_pattern_size_a': [ + imagePosA.displaySize[0] * image.fromScale / tileRatio, + imagePosA.displaySize[1] + ], + 'u_pattern_size_b': [ + imagePosB.displaySize[0] * image.toScale / tileRatio, + imagePosB.displaySize[1] + ], + 'u_texsize': [pixelSize.width, pixelSize.height], + 'u_image': 0, + 'u_pattern_tl_a': imagePosA.tl, + 'u_pattern_br_a': imagePosA.br, + 'u_pattern_tl_b': imagePosB.tl, + 'u_pattern_br_b': imagePosB.br, + 'u_fade': image.t + }); +}; + +const lineSDFUniformValues = ( + painter: Painter, + tile: Tile, + layer: LineStyleLayer, + dasharray: CrossFaded> +): UniformValues => { + const transform = painter.transform; + const lineAtlas = painter.lineAtlas; + const tileRatio = calculateTileRatio(tile, transform); + + const round = layer.layout.get('line-cap') === 'round'; + + const posA = lineAtlas.getDash(dasharray.from, round); + const posB = lineAtlas.getDash(dasharray.to, round); + + const widthA = posA.width * dasharray.fromScale; + const widthB = posB.width * dasharray.toScale; + + return extend(lineUniformValues(painter, tile, layer), { + 'u_patternscale_a': [tileRatio / widthA, -posA.height / 2], + 'u_patternscale_b': [tileRatio / widthB, -posB.height / 2], + 'u_sdfgamma': lineAtlas.width / (Math.min(widthA, widthB) * 256 * browser.devicePixelRatio) / 2, + 'u_image': 0, + 'u_tex_y_a': posA.y, + 'u_tex_y_b': posB.y, + 'u_mix': dasharray.t + }); +}; + +function calculateTileRatio(tile: Tile, transform: Transform) { + return 1 / pixelsToTileUnits(tile, 1, transform.tileZoom); +} + +function calculateMatrix(painter, tile, layer) { + return painter.translatePosMatrix( + tile.tileID.posMatrix, + tile, + layer.paint.get('line-translate'), + layer.paint.get('line-translate-anchor') + ); +} + +export { + lineUniforms, + lineGradientUniforms, + linePatternUniforms, + lineSDFUniforms, + lineUniformValues, + lineGradientUniformValues, + linePatternUniformValues, + lineSDFUniformValues +}; diff --git a/src/render/program/pattern.js b/src/render/program/pattern.js new file mode 100644 index 00000000000..15f54c289c6 --- /dev/null +++ b/src/render/program/pattern.js @@ -0,0 +1,66 @@ +// @flow + +import assert from 'assert'; +import { + Uniform1i, + Uniform1f, + Uniform2fv, +} from '../uniform_binding'; +import pixelsToTileUnits from '../../source/pixels_to_tile_units'; + +import type Painter from '../painter'; +import type {OverscaledTileID} from '../../source/tile_id'; +import type {CrossFaded} from '../../style/cross_faded'; +import type {UniformValues} from '../uniform_binding'; + +type PatternUniformsType = {| + 'u_image': Uniform1i, + 'u_pattern_tl_a': Uniform2fv, + 'u_pattern_br_a': Uniform2fv, + 'u_pattern_tl_b': Uniform2fv, + 'u_pattern_br_b': Uniform2fv, + 'u_texsize': Uniform2fv, + 'u_mix': Uniform1f, + 'u_pattern_size_a': Uniform2fv, + 'u_pattern_size_b': Uniform2fv, + 'u_scale_a': Uniform1f, + 'u_scale_b': Uniform1f, + 'u_pixel_coord_upper': Uniform2fv, + 'u_pixel_coord_lower': Uniform2fv, + 'u_tile_units_to_pixels': Uniform1f +|}; + +function patternUniformValues(image: CrossFaded, painter: Painter, + tile: {tileID: OverscaledTileID, tileSize: number} +): UniformValues { + const imagePosA = painter.imageManager.getPattern(image.from); + const imagePosB = painter.imageManager.getPattern(image.to); + assert(imagePosA && imagePosB); + const {width, height} = painter.imageManager.getPixelSize(); + + const numTiles = Math.pow(2, tile.tileID.overscaledZ); + const tileSizeAtNearestZoom = tile.tileSize * Math.pow(2, painter.transform.tileZoom) / numTiles; + + const pixelX = tileSizeAtNearestZoom * (tile.tileID.canonical.x + tile.tileID.wrap * numTiles); + const pixelY = tileSizeAtNearestZoom * tile.tileID.canonical.y; + + return { + 'u_image': 0, + 'u_pattern_tl_a': (imagePosA: any).tl, + 'u_pattern_br_a': (imagePosA: any).br, + 'u_pattern_tl_b': (imagePosB: any).tl, + 'u_pattern_br_b': (imagePosB: any).br, + 'u_texsize': [width, height], + 'u_mix': image.t, + 'u_pattern_size_a': (imagePosA: any).displaySize, + 'u_pattern_size_b': (imagePosB: any).displaySize, + 'u_scale_a': image.fromScale, + 'u_scale_b': image.toScale, + 'u_tile_units_to_pixels': 1 / pixelsToTileUnits(tile, 1, painter.transform.tileZoom), + // split the pixel coord into two pairs of 16 bit numbers. The glsl spec only guarantees 16 bits of precision. + 'u_pixel_coord_upper': [pixelX >> 16, pixelY >> 16], + 'u_pixel_coord_lower': [pixelX & 0xFFFF, pixelY & 0xFFFF] + }; +} + +export { patternUniformValues }; diff --git a/src/render/program/program_uniforms.js b/src/render/program/program_uniforms.js new file mode 100644 index 00000000000..5dbf64cef07 --- /dev/null +++ b/src/render/program/program_uniforms.js @@ -0,0 +1,42 @@ +// @flow + +import { fillExtrusionUniforms, fillExtrusionPatternUniforms, extrusionTextureUniforms } from './fill_extrusion_program'; +import { fillUniforms, fillPatternUniforms, fillOutlineUniforms, fillOutlinePatternUniforms } from './fill_program'; +import { circleUniforms } from './circle_program'; +import { collisionUniforms } from './collision_program'; +import { debugUniforms } from './debug_program'; +import { clippingMaskUniforms } from './clipping_mask_program'; +import { heatmapUniforms, heatmapTextureUniforms } from './heatmap_program'; +import { hillshadeUniforms, hillshadePrepareUniforms } from './hillshade_program'; +import { lineUniforms, lineGradientUniforms, linePatternUniforms, lineSDFUniforms } from './line_program'; +import { rasterUniforms } from './raster_program'; +import { symbolIconUniforms, symbolSDFUniforms } from './symbol_program'; +import { backgroundUniforms, backgroundPatternUniforms } from './background_program'; + +export const programUniforms = { + fillExtrusion: fillExtrusionUniforms, + fillExtrusionPattern: fillExtrusionPatternUniforms, + extrusionTexture: extrusionTextureUniforms, + fill: fillUniforms, + fillPattern: fillPatternUniforms, + fillOutline: fillOutlineUniforms, + fillOutlinePattern: fillOutlinePatternUniforms, + circle: circleUniforms, + collisionBox: collisionUniforms, + collisionCircle: collisionUniforms, + debug: debugUniforms, + clippingMask: clippingMaskUniforms, + heatmap: heatmapUniforms, + heatmapTexture: heatmapTextureUniforms, + hillshade: hillshadeUniforms, + hillshadePrepare: hillshadePrepareUniforms, + line: lineUniforms, + lineGradient: lineGradientUniforms, + linePattern: linePatternUniforms, + lineSDF: lineSDFUniforms, + raster: rasterUniforms, + symbolIcon: symbolIconUniforms, + symbolSDF: symbolSDFUniforms, + background: backgroundUniforms, + backgroundPattern: backgroundPatternUniforms +}; diff --git a/src/render/program/raster_program.js b/src/render/program/raster_program.js new file mode 100644 index 00000000000..cd8becaaf1a --- /dev/null +++ b/src/render/program/raster_program.js @@ -0,0 +1,93 @@ +// @flow + +import { + Uniform1i, + Uniform1f, + Uniform2fv, + Uniform3fv, + UniformMatrix4fv, + Uniforms +} from '../uniform_binding'; + +import type Context from '../../gl/context'; +import type {UniformValues} from '../uniform_binding'; +import type RasterStyleLayer from '../../style/style_layer/raster_style_layer'; + +export type RasterUniformsType = {| + 'u_matrix': UniformMatrix4fv, + 'u_tl_parent': Uniform2fv, + 'u_scale_parent': Uniform1f, + 'u_buffer_scale': Uniform1f, + 'u_fade_t': Uniform1f, + 'u_opacity': Uniform1f, + 'u_image0': Uniform1i, + 'u_image1': Uniform1i, + 'u_brightness_low': Uniform1f, + 'u_brightness_high': Uniform1f, + 'u_saturation_factor': Uniform1f, + 'u_contrast_factor': Uniform1f, + 'u_spin_weights': Uniform3fv +|}; + +const rasterUniforms = (context: Context): Uniforms => new Uniforms({ + 'u_matrix': new UniformMatrix4fv(context), + 'u_tl_parent': new Uniform2fv(context), + 'u_scale_parent': new Uniform1f(context), + 'u_buffer_scale': new Uniform1f(context), + 'u_fade_t': new Uniform1f(context), + 'u_opacity': new Uniform1f(context), + 'u_image0': new Uniform1i(context), + 'u_image1': new Uniform1i(context), + 'u_brightness_low': new Uniform1f(context), + 'u_brightness_high': new Uniform1f(context), + 'u_saturation_factor': new Uniform1f(context), + 'u_contrast_factor': new Uniform1f(context), + 'u_spin_weights': new Uniform3fv(context) +}); + +const rasterUniformValues = ( + matrix: Float32Array, + parentTL: [number, number], + parentScaleBy: number, + fade: {mix: number, opacity: number}, + layer: RasterStyleLayer +): UniformValues => ({ + 'u_matrix': matrix, + 'u_tl_parent': parentTL, + 'u_scale_parent': parentScaleBy, + 'u_buffer_scale': 1, + 'u_fade_t': fade.mix, + 'u_opacity': fade.opacity * layer.paint.get('raster-opacity'), + 'u_image0': 0, + 'u_image1': 1, + 'u_brightness_low': layer.paint.get('raster-brightness-min'), + 'u_brightness_high': layer.paint.get('raster-brightness-max'), + 'u_saturation_factor': saturationFactor(layer.paint.get('raster-saturation')), + 'u_contrast_factor': contrastFactor(layer.paint.get('raster-contrast')), + 'u_spin_weights': spinWeights(layer.paint.get('raster-hue-rotate')) +}); + +function spinWeights(angle) { + angle *= Math.PI / 180; + const s = Math.sin(angle); + const c = Math.cos(angle); + return [ + (2 * c + 1) / 3, + (-Math.sqrt(3) * s - c + 1) / 3, + (Math.sqrt(3) * s - c + 1) / 3 + ]; +} + +function contrastFactor(contrast) { + return contrast > 0 ? + 1 / (1 - contrast) : + 1 + contrast; +} + +function saturationFactor(saturation) { + return saturation > 0 ? + 1 - 1 / (1.001 - saturation) : + -saturation; +} + +export { rasterUniforms, rasterUniformValues }; diff --git a/src/render/program/symbol_program.js b/src/render/program/symbol_program.js new file mode 100644 index 00000000000..6d52d58f6c5 --- /dev/null +++ b/src/render/program/symbol_program.js @@ -0,0 +1,153 @@ +// @flow + +import { + Uniform1i, + Uniform1f, + Uniform2fv, + UniformMatrix4fv, + Uniforms +} from '../uniform_binding'; +import { extend } from '../../util/util'; + +import type Context from '../../gl/context'; +import type Painter from '../painter'; +import type {UniformValues} from '../uniform_binding'; + +export type SymbolIconUniformsType = {| + 'u_is_size_zoom_constant': Uniform1i, + 'u_is_size_feature_constant': Uniform1i, + 'u_size_t': Uniform1f, + 'u_size': Uniform1f, + 'u_camera_to_center_distance': Uniform1f, + 'u_pitch': Uniform1f, + 'u_rotate_symbol': Uniform1i, + 'u_aspect_ratio': Uniform1f, + 'u_fade_change': Uniform1f, + 'u_matrix': UniformMatrix4fv, + 'u_label_plane_matrix': UniformMatrix4fv, + 'u_gl_coord_matrix': UniformMatrix4fv, + 'u_is_text': Uniform1f, + 'u_pitch_with_map': Uniform1i, + 'u_texsize': Uniform2fv, + 'u_texture': Uniform1i +|}; + +export type SymbolSDFUniformsType = {| + 'u_is_size_zoom_constant': Uniform1i, + 'u_is_size_feature_constant': Uniform1i, + 'u_size_t': Uniform1f, + 'u_size': Uniform1f, + 'u_camera_to_center_distance': Uniform1f, + 'u_pitch': Uniform1f, + 'u_rotate_symbol': Uniform1i, + 'u_aspect_ratio': Uniform1f, + 'u_fade_change': Uniform1f, + 'u_matrix': UniformMatrix4fv, + 'u_label_plane_matrix': UniformMatrix4fv, + 'u_gl_coord_matrix': UniformMatrix4fv, + 'u_is_text': Uniform1f, + 'u_pitch_with_map': Uniform1i, + 'u_texsize': Uniform2fv, + 'u_texture': Uniform1i, + 'u_gamma_scale': Uniform1f, + 'u_is_halo': Uniform1f +|}; + +const symbolIconUniforms = (context: Context): Uniforms => new Uniforms({ + 'u_is_size_zoom_constant': new Uniform1i(context), + 'u_is_size_feature_constant': new Uniform1i(context), + 'u_size_t': new Uniform1f(context), + 'u_size': new Uniform1f(context), + 'u_camera_to_center_distance': new Uniform1f(context), + 'u_pitch': new Uniform1f(context), + 'u_rotate_symbol': new Uniform1i(context), + 'u_aspect_ratio': new Uniform1f(context), + 'u_fade_change': new Uniform1f(context), + 'u_matrix': new UniformMatrix4fv(context), + 'u_label_plane_matrix': new UniformMatrix4fv(context), + 'u_gl_coord_matrix': new UniformMatrix4fv(context), + 'u_is_text': new Uniform1f(context), + 'u_pitch_with_map': new Uniform1i(context), + 'u_texsize': new Uniform2fv(context), + 'u_texture': new Uniform1i(context) +}); + +const symbolSDFUniforms = (context: Context): Uniforms => new Uniforms({ + 'u_is_size_zoom_constant': new Uniform1i(context), + 'u_is_size_feature_constant': new Uniform1i(context), + 'u_size_t': new Uniform1f(context), + 'u_size': new Uniform1f(context), + 'u_camera_to_center_distance': new Uniform1f(context), + 'u_pitch': new Uniform1f(context), + 'u_rotate_symbol': new Uniform1i(context), + 'u_aspect_ratio': new Uniform1f(context), + 'u_fade_change': new Uniform1f(context), + 'u_matrix': new UniformMatrix4fv(context), + 'u_label_plane_matrix': new UniformMatrix4fv(context), + 'u_gl_coord_matrix': new UniformMatrix4fv(context), + 'u_is_text': new Uniform1f(context), + 'u_pitch_with_map': new Uniform1i(context), + 'u_texsize': new Uniform2fv(context), + 'u_texture': new Uniform1i(context), + 'u_gamma_scale': new Uniform1f(context), + 'u_is_halo': new Uniform1f(context) +}); + +const symbolIconUniformValues = ( + functionType: string, + size: ?{uSizeT: number, uSize: number}, + rotateInShader: boolean, + pitchWithMap: boolean, + painter: Painter, + matrix: Float32Array, + labelPlaneMatrix: Float32Array, + glCoordMatrix: Float32Array, + isText: boolean, + texSize: [number, number] +): UniformValues => { + const transform = painter.transform; + + return { + 'u_is_size_zoom_constant': +(functionType === 'constant' || functionType === 'source'), + 'u_is_size_feature_constant': +(functionType === 'constant' || functionType === 'camera'), + 'u_size_t': size ? size.uSizeT : 0, + 'u_size': size ? size.uSize : 0, + 'u_camera_to_center_distance': transform.cameraToCenterDistance, + 'u_pitch': transform.pitch / 360 * 2 * Math.PI, + 'u_rotate_symbol': +rotateInShader, + 'u_aspect_ratio': transform.width / transform.height, + 'u_fade_change': painter.options.fadeDuration ? painter.symbolFadeChange : 1, + 'u_matrix': matrix, + 'u_label_plane_matrix': labelPlaneMatrix, + 'u_gl_coord_matrix': glCoordMatrix, + 'u_is_text': +isText, + 'u_pitch_with_map': +pitchWithMap, + 'u_texsize': texSize, + 'u_texture': 0 + }; +}; + +const symbolSDFUniformValues = ( + functionType: string, + size: ?{uSizeT: number, uSize: number}, + rotateInShader: boolean, + pitchWithMap: boolean, + painter: Painter, + matrix: Float32Array, + labelPlaneMatrix: Float32Array, + glCoordMatrix: Float32Array, + isText: boolean, + texSize: [number, number], + isHalo: boolean +): UniformValues => { + const transform = painter.transform; + + return extend(symbolIconUniformValues(functionType, size, + rotateInShader, pitchWithMap, painter, matrix, labelPlaneMatrix, + glCoordMatrix, isText, texSize), { + 'u_gamma_scale': (pitchWithMap ? Math.cos(transform._pitch) * transform.cameraToCenterDistance : 1), + 'u_is_halo': +isHalo + }); +}; + +export { symbolIconUniforms, symbolSDFUniforms, symbolIconUniformValues, symbolSDFUniformValues }; diff --git a/src/render/texture.js b/src/render/texture.js index ac0bf6785ee..bdc736b3c7a 100644 --- a/src/render/texture.js +++ b/src/render/texture.js @@ -35,7 +35,7 @@ export type TextureImage = class Texture { context: Context; - size: Array; + size: [number, number]; texture: WebGLTexture; format: TextureFormat; filter: ?TextureFilter; diff --git a/src/render/uniform_binding.js b/src/render/uniform_binding.js new file mode 100644 index 00000000000..87ce8d8e36c --- /dev/null +++ b/src/render/uniform_binding.js @@ -0,0 +1,123 @@ +// @flow + +import assert from 'assert'; +import Color from '../style-spec/util/color'; + +import type Context from '../gl/context'; + +export type UniformValues + = $Exact<$ObjMap(u: Uniform) => V>>; +export type UniformLocations = {[string]: WebGLUniformLocation}; +export type UniformBindings = {[string]: any}; +// binder uniforms are dynamically created: +export type BinderUniformTypes = any; + +class Uniform { + context: Context; + current: ?T; + + constructor(context: Context) { + this.context = context; + } +} + +class Uniform1i extends Uniform { + set(location: WebGLUniformLocation, v: number, invalidate: boolean = false): void { + if (invalidate || this.current !== v) { + this.current = v; + this.context.gl.uniform1i(location, v); + } + } +} + +class Uniform1f extends Uniform { + set(location: WebGLUniformLocation, v: number, invalidate: boolean = false): void { + if (invalidate || this.current !== v) { + this.current = v; + this.context.gl.uniform1f(location, v); + } + } +} + +class Uniform2fv extends Uniform<[number, number]> { + set(location: WebGLUniformLocation, v: [number, number], invalidate: boolean = false): void { + const c = this.current; + if (invalidate || !c || v[0] !== c[0] || v[1] !== c[1]) { + this.current = v; + this.context.gl.uniform2f(location, v[0], v[1]); + } + } +} + +class Uniform3fv extends Uniform<[number, number, number]> { + set(location: WebGLUniformLocation, v: [number, number, number], invalidate: boolean = false): void { + const c = this.current; + if (invalidate || !c || v[0] !== c[0] || v[1] !== c[1] || v[2] !== c[2]) { + this.current = v; + this.context.gl.uniform3f(location, v[0], v[1], v[2]); + } + } +} + +class Uniform4fv extends Uniform<[number, number, number, number] | Color> { + set(location: WebGLUniformLocation, v: [number, number, number, number] | Color, invalidate: boolean = false): void { + const c = this.current; + if (v instanceof Color && (!c || c instanceof Color)) { + if (invalidate || !c || v.r !== c.r || v.g !== c.g || v.b !== c.b || v.a !== c.a) { + this.current = v; + this.context.gl.uniform4f(location, v.r, v.g, v.b, v.a); + } + } else if (Array.isArray(v) && (!c || Array.isArray(c))) { + if (invalidate || !c || v[0] !== c[0] || v[1] !== c[1] || v[2] !== c[2] || v[3] !== c[3]) { + this.current = v; + this.context.gl.uniform4f(location, v[0], v[1], v[2], v[3]); + } + } + } +} + +class UniformMatrix4fv extends Uniform { + set(location: WebGLUniformLocation, v: Float32Array, invalidate: boolean = false): void { + let diff = !this.current || invalidate; + + if (!invalidate && this.current) { + for (let i = 0; i < 16; i++) { + if (v[i] !== this.current[i]) { + diff = true; + break; + } + } + } + + if (diff) { + this.current = v; + this.context.gl.uniformMatrix4fv(location, false, v); + } + } +} + +class Uniforms { + bindings: Us; + + constructor(bindings: Us) { + this.bindings = bindings; + } + + set(uniformLocations: UniformLocations, uniformValues: UniformValues) { + for (const name in uniformValues) { + assert(this.bindings[name], `No binding with name ${name}`); + this.bindings[name].set(uniformLocations[name], uniformValues[name]); + } + } +} + +export { + Uniform, + Uniform1i, + Uniform1f, + Uniform2fv, + Uniform3fv, + Uniform4fv, + UniformMatrix4fv, + Uniforms +}; diff --git a/src/render/vertex_array_object.js b/src/render/vertex_array_object.js index e5250092164..fab9aee0a1b 100644 --- a/src/render/vertex_array_object.js +++ b/src/render/vertex_array_object.js @@ -9,7 +9,7 @@ import type Context from '../gl/context'; class VertexArrayObject { context: Context; - boundProgram: ?Program; + boundProgram: ?Program<*>; boundLayoutVertexBuffer: ?VertexBuffer; boundPaintVertexBuffers: Array; boundIndexBuffer: ?IndexBuffer; @@ -29,7 +29,7 @@ class VertexArrayObject { } bind(context: Context, - program: Program, + program: Program<*>, layoutVertexBuffer: VertexBuffer, paintVertexBuffers: Array, indexBuffer: ?IndexBuffer, @@ -77,7 +77,7 @@ class VertexArrayObject { } } - freshBind(program: Program, + freshBind(program: Program<*>, layoutVertexBuffer: VertexBuffer, paintVertexBuffers: Array, indexBuffer: ?IndexBuffer, diff --git a/src/source/canvas_source.js b/src/source/canvas_source.js index e9d51ed5a83..5b8a19563bc 100644 --- a/src/source/canvas_source.js +++ b/src/source/canvas_source.js @@ -4,7 +4,7 @@ import ImageSource from './image_source'; import window from '../util/window'; import rasterBoundsAttributes from '../data/raster_bounds_attributes'; -import VertexArrayObject from '../render/vertex_array_object'; +import SegmentVector from '../data/segment'; import Texture from '../render/texture'; import { ErrorEvent } from '../util/evented'; import ValidationError from '../style-spec/error/validation_error'; @@ -193,8 +193,8 @@ class CanvasSource extends ImageSource { this.boundsBuffer = context.createVertexBuffer(this._boundsArray, rasterBoundsAttributes.members); } - if (!this.boundsVAO) { - this.boundsVAO = new VertexArrayObject(); + if (!this.boundsSegments) { + this.boundsSegments = SegmentVector.simpleSegment(0, 0, 4, 2); } if (!this.texture) { diff --git a/src/source/image_source.js b/src/source/image_source.js index cc414b73587..0306b98ba01 100644 --- a/src/source/image_source.js +++ b/src/source/image_source.js @@ -11,7 +11,7 @@ import browser from '../util/browser'; import EXTENT from '../data/extent'; import { RasterBoundsArray } from '../data/array_types'; import rasterBoundsAttributes from '../data/raster_bounds_attributes'; -import VertexArrayObject from '../render/vertex_array_object'; +import SegmentVector from '../data/segment'; import Texture from '../render/texture'; import type {Source} from './source'; @@ -75,7 +75,7 @@ class ImageSource extends Evented implements Source { tileID: CanonicalTileID; _boundsArray: RasterBoundsArray; boundsBuffer: VertexBuffer; - boundsVAO: VertexArrayObject; + boundsSegments: SegmentVector; /** * @private @@ -197,8 +197,8 @@ class ImageSource extends Evented implements Source { this.boundsBuffer = context.createVertexBuffer(this._boundsArray, rasterBoundsAttributes.members); } - if (!this.boundsVAO) { - this.boundsVAO = new VertexArrayObject(); + if (!this.boundsSegments) { + this.boundsSegments = SegmentVector.simpleSegment(0, 0, 4, 2); } if (!this.texture) { diff --git a/src/source/source_cache.js b/src/source/source_cache.js index 57affd30b6d..17e8926de53 100644 --- a/src/source/source_cache.js +++ b/src/source/source_cache.js @@ -261,9 +261,6 @@ class SourceCache extends Evented { this._state.initializeTileState(tile, this.map ? this.map.painter : null); this._source.fire(new Event('data', {dataType: 'source', tile: tile, coord: tile.tileID})); - - // HACK this is necessary to fix https://github.com/mapbox/mapbox-gl-js/issues/2986 - if (this.map) this.map.painter.tileExtentVAO.vao = null; } /** diff --git a/src/source/video_source.js b/src/source/video_source.js index 3b89ddb7a90..9b38761f42c 100644 --- a/src/source/video_source.js +++ b/src/source/video_source.js @@ -4,7 +4,7 @@ import { getVideo, ResourceType } from '../util/ajax'; import ImageSource from './image_source'; import rasterBoundsAttributes from '../data/raster_bounds_attributes'; -import VertexArrayObject from '../render/vertex_array_object'; +import SegmentVector from '../data/segment'; import Texture from '../render/texture'; import { ErrorEvent } from '../util/evented'; @@ -136,8 +136,8 @@ class VideoSource extends ImageSource { this.boundsBuffer = context.createVertexBuffer(this._boundsArray, rasterBoundsAttributes.members); } - if (!this.boundsVAO) { - this.boundsVAO = new VertexArrayObject(); + if (!this.boundsSegments) { + this.boundsSegments = SegmentVector.simpleSegment(0, 0, 4, 2); } if (!this.texture) { diff --git a/src/style-spec/util/color.js b/src/style-spec/util/color.js index 8c95f60fdd1..6b1f88fed36 100644 --- a/src/style-spec/util/color.js +++ b/src/style-spec/util/color.js @@ -29,6 +29,7 @@ class Color { static black: Color; static white: Color; static transparent: Color; + static red: Color; /** * Parses valid CSS color strings and returns a `Color` instance. @@ -89,5 +90,6 @@ class Color { Color.black = new Color(0, 0, 0, 1); Color.white = new Color(1, 1, 1, 1); Color.transparent = new Color(0, 0, 0, 0); +Color.red = new Color(1, 0, 0, 1); export default Color; diff --git a/test/unit/render/uniform_binding.test.js b/test/unit/render/uniform_binding.test.js new file mode 100644 index 00000000000..20e2de43a4b --- /dev/null +++ b/test/unit/render/uniform_binding.test.js @@ -0,0 +1,125 @@ +import { test } from 'mapbox-gl-js-test'; +import { + Uniform1i, + Uniform1f, + Uniform2fv, + Uniform3fv, + Uniform4fv +} from '../../../src/render/uniform_binding'; + +function arrEq(a, b) { + return a.every((el, i) => el === b[i]); +} + +test('Uniform1i', (t) => { + // test counts ensure we don't call the gl.uniform* setters more than expected + t.plan(4); + + const context = { + gl: { + uniform1i: () => { t.ok(true, 'sets value when unique'); } + } + }; + + const u = new Uniform1i(context); + + t.notOk(u.current, 'not set upon initialization'); + u.set(0, 1); + t.equal(u.current, 1, 'correctly set value'); + u.set(0, 1); + u.set(0, 2); + t.end(); +}); + +test('Uniform1f', (t) => { + t.plan(4); + + const context = { + gl: { + uniform1f: () => { t.ok(true, 'sets value when unique'); } + } + }; + + const u = new Uniform1f(context); + + t.notOk(u.current, 'not set upon initialization'); + u.set(0, 1); + t.equal(u.current, 1, 'correctly set value'); + u.set(0, 1); + u.set(0, 2); + t.end(); +}); + +test('Uniform1f: force set', (t) => { + t.plan(3); + + const context = { + gl: { + uniform1f: () => { t.ok(true, 'sets value when unique'); } + } + }; + + const u = new Uniform1f(context); + + u.set(0, 1); + t.equal(u.current, 1, 'correctly set value'); + u.set(0, 1, true); + t.end(); +}); + +test('Uniform2fv', (t) => { + t.plan(4); + + const context = { + gl: { + uniform2f: () => { t.ok(true, 'sets value when unique'); } + } + }; + + const u = new Uniform2fv(context); + + t.notOk(u.current, 'not set upon initialization'); + u.set(0, [1, 1]); + t.ok(arrEq(u.current, [1, 1]), 'correctly set value'); + u.set(0, [1, 1]); + u.set(0, [1, 2]); + t.end(); +}); + +test('Uniform3fv', (t) => { + t.plan(4); + + const context = { + gl: { + uniform3f: () => { t.ok(true, 'sets value when unique'); } + } + }; + + const u = new Uniform3fv(context); + + t.notOk(u.current, 'not set upon initialization'); + u.set(0, [1, 1, 1]); + t.ok(arrEq(u.current, [1, 1, 1]), 'correctly set value'); + u.set(0, [1, 1, 1]); + u.set(0, [1, 1, 2]); + t.end(); +}); + +test('Uniform4fv', (t) => { + t.plan(4); + + const context = { + gl: { + uniform4f: () => { t.ok(true, 'sets value when unique'); } + } + }; + + const u = new Uniform4fv(context); + + t.notOk(u.current, 'not set upon initialization'); + u.set(0, [1, 1, 1, 1]); + t.ok(arrEq(u.current, [1, 1, 1, 1]), 'correctly set value'); + u.set(0, [1, 1, 1, 1]); + u.set(0, [2, 1, 1, 1]); + t.end(); +}); From dba3231e7cce33d9f79f5f8b2c1569e30a1b5e28 Mon Sep 17 00:00:00 2001 From: Lauren Budorick Date: Thu, 15 Mar 2018 16:44:54 -0700 Subject: [PATCH 02/11] Maintain ownership of binder uniforms on Programs --- src/data/program_configuration.js | 48 +++++++++++------------- src/render/program.js | 8 ++-- src/render/uniform_binding.js | 36 +++++++++++------- test/unit/render/uniform_binding.test.js | 17 --------- 4 files changed, 47 insertions(+), 62 deletions(-) diff --git a/src/data/program_configuration.js b/src/data/program_configuration.js index ffc5d64f68c..3f1ebc7ae6d 100644 --- a/src/data/program_configuration.js +++ b/src/data/program_configuration.js @@ -76,8 +76,8 @@ interface Binder { defines(): Array; - setUniforms(context: Context, program: Program<*>, invalidate: boolean, - globals: GlobalProperties, currentValue: PossiblyEvaluatedPropertyValue): void; + setUniforms(context: Context, program: Program<*>, globals: GlobalProperties, + currentValue: PossiblyEvaluatedPropertyValue): void; } class ConstantBinder implements Binder { @@ -105,15 +105,16 @@ class ConstantBinder implements Binder { upload() {} destroy() {} - setUniforms(context: Context, program: Program<*>, invalidate: boolean, - globals: GlobalProperties, currentValue: PossiblyEvaluatedPropertyValue): void { + setUniforms(context: Context, program: Program<*>, globals: GlobalProperties, + currentValue: PossiblyEvaluatedPropertyValue): void { const value = currentValue.constantOr(this.value); - if (!this.uniformBinding) { - this.uniformBinding = this.type === 'color' ? new Uniform4fv(context) : new Uniform1f(context); + if (!program.binderUniforms.bindings[this.uniformName]) { + program.binderUniforms.bindings[this.uniformName] = this.type === 'color' ? + new Uniform4fv(context) : new Uniform1f(context); } - this.uniformBinding.set(program.uniforms[this.uniformName], (value: any), invalidate); + program.binderUniforms.bindings[this.uniformName].set(program.uniforms[this.uniformName], value); } } @@ -205,13 +206,12 @@ class SourceExpressionBinder implements Binder { } } - setUniforms(context: Context, program: Program<*>, invalidate: boolean): void { - if (!this.uniformBinding) { - this.uniformBinding = new Uniform1f(context); - this.uniformBinding.set(program.uniforms[this.uniformName], 0); - } else if (invalidate) { - this.uniformBinding.set(program.uniforms[this.uniformName], 0, invalidate); + setUniforms(context: Context, program: Program<*>): void { + if (!program.binderUniforms.bindings[this.uniformName]) { + program.binderUniforms.bindings[this.uniformName] = new Uniform1f(context); } + + program.binderUniforms.bindings[this.uniformName].set(program.uniforms[this.uniformName], 0); } } @@ -320,13 +320,13 @@ class CompositeExpressionBinder implements Binder { } } - setUniforms(context: Context, program: Program<*>, invalidate: boolean, + setUniforms(context: Context, program: Program<*>, globals: GlobalProperties): void { - if (!this.uniformBinding) { - this.uniformBinding = new Uniform1f(context); + if (!program.binderUniforms.bindings[this.uniformName]) { + program.binderUniforms.bindings[this.uniformName] = new Uniform1f(context); } - this.uniformBinding.set(program.uniforms[this.uniformName], this.interpolationFactor(globals.zoom), invalidate); + program.binderUniforms.bindings[this.uniformName].set(program.uniforms[this.uniformName], this.interpolationFactor(globals.zoom)); } } @@ -456,18 +456,12 @@ export default class ProgramConfiguration { return this._buffers; } - setUniforms(context: Context, program: Program<*>, properties: PossiblyEvaluated, globals: GlobalProperties, invalidate: boolean) { - // We maintain a reference here to the last Program used, and a reference - // on each Program to the last ProgramConfiguration used: if these match, - // we can assume the uniform bindings haven't changed, but if we're using - // a different ProgramConfiguration for the same Program or a different - // Program with the same ProgramConfiguration, our tracked uniform state - // won't be right, so we invalidate the old bindings here. - invalidate = invalidate || this.program !== program; + setUniforms(context: Context, program: Program<*>, properties: PossiblyEvaluated, globals: GlobalProperties) { + // Uniform state bindings are owned by the Program, but we set them + // from within the ProgramConfiguraton's binder members. for (const property in this.binders) { - const binder = this.binders[property]; - binder.setUniforms(context, program, invalidate, globals, properties.get(property)); + this.binders[property].setUniforms(context, program, globals, properties.get(property)); } } diff --git a/src/render/program.js b/src/render/program.js index fbfd11ca83f..35349eb05bc 100644 --- a/src/render/program.js +++ b/src/render/program.js @@ -7,6 +7,7 @@ import assert from 'assert'; import ProgramConfiguration from '../data/program_configuration'; import VertexArrayObject from './vertex_array_object'; import Context from '../gl/context'; +import { Uniforms } from './uniform_binding'; import type SegmentVector from '../data/segment'; import type VertexBuffer from '../gl/vertex_buffer'; @@ -14,7 +15,7 @@ import type IndexBuffer from '../gl/index_buffer'; import type DepthMode from '../gl/depth_mode'; import type StencilMode from '../gl/stencil_mode'; import type ColorMode from '../gl/color_mode'; -import type {Uniforms, UniformBindings, UniformValues, UniformLocations, BinderUniformTypes} from './uniform_binding'; +import type {UniformBindings, UniformValues, UniformLocations, BinderUniformTypes} from './uniform_binding'; export type DrawMode = | $PropertyType @@ -92,6 +93,7 @@ class Program { } this.fixedUniforms = fixedUniforms(context); + this.binderUniforms = new Uniforms({}); } draw(context: Context, @@ -118,9 +120,7 @@ class Program { this.fixedUniforms.set(this.uniforms, uniformValues); if (configuration) { - const invalidate = this.configuration && this.configuration !== configuration; - configuration.setUniforms(context, this, currentProperties, {zoom: (zoom: any)}, invalidate); - this.configuration = configuration; + configuration.setUniforms(context, this, currentProperties, {zoom: (zoom: any)}); } const primitiveSize = { diff --git a/src/render/uniform_binding.js b/src/render/uniform_binding.js index 87ce8d8e36c..f329c2d42ee 100644 --- a/src/render/uniform_binding.js +++ b/src/render/uniform_binding.js @@ -14,6 +14,7 @@ export type BinderUniformTypes = any; class Uniform { context: Context; + location: ?WebGLUniformLocation; current: ?T; constructor(context: Context) { @@ -22,54 +23,60 @@ class Uniform { } class Uniform1i extends Uniform { - set(location: WebGLUniformLocation, v: number, invalidate: boolean = false): void { - if (invalidate || this.current !== v) { + set(location: WebGLUniformLocation, v: number): void { + if (this.current !== v || this.location !== location) { this.current = v; + this.location = location; this.context.gl.uniform1i(location, v); } } } class Uniform1f extends Uniform { - set(location: WebGLUniformLocation, v: number, invalidate: boolean = false): void { - if (invalidate || this.current !== v) { + set(location: WebGLUniformLocation, v: number): void { + if (this.current !== v || this.location !== location) { this.current = v; + this.location = location; this.context.gl.uniform1f(location, v); } } } class Uniform2fv extends Uniform<[number, number]> { - set(location: WebGLUniformLocation, v: [number, number], invalidate: boolean = false): void { + set(location: WebGLUniformLocation, v: [number, number]): void { const c = this.current; - if (invalidate || !c || v[0] !== c[0] || v[1] !== c[1]) { + if (!c || v[0] !== c[0] || v[1] !== c[1] || this.location !== location) { this.current = v; + this.location = location; this.context.gl.uniform2f(location, v[0], v[1]); } } } class Uniform3fv extends Uniform<[number, number, number]> { - set(location: WebGLUniformLocation, v: [number, number, number], invalidate: boolean = false): void { + set(location: WebGLUniformLocation, v: [number, number, number]): void { const c = this.current; - if (invalidate || !c || v[0] !== c[0] || v[1] !== c[1] || v[2] !== c[2]) { + if (!c || v[0] !== c[0] || v[1] !== c[1] || v[2] !== c[2] || this.location !== location) { this.current = v; + this.location = location; this.context.gl.uniform3f(location, v[0], v[1], v[2]); } } } class Uniform4fv extends Uniform<[number, number, number, number] | Color> { - set(location: WebGLUniformLocation, v: [number, number, number, number] | Color, invalidate: boolean = false): void { + set(location: WebGLUniformLocation, v: [number, number, number, number] | Color): void { const c = this.current; if (v instanceof Color && (!c || c instanceof Color)) { - if (invalidate || !c || v.r !== c.r || v.g !== c.g || v.b !== c.b || v.a !== c.a) { + if (!c || v.r !== c.r || v.g !== c.g || v.b !== c.b || v.a !== c.a || this.location !== location) { this.current = v; + this.location = location; this.context.gl.uniform4f(location, v.r, v.g, v.b, v.a); } } else if (Array.isArray(v) && (!c || Array.isArray(c))) { - if (invalidate || !c || v[0] !== c[0] || v[1] !== c[1] || v[2] !== c[2] || v[3] !== c[3]) { + if (!c || v[0] !== c[0] || v[1] !== c[1] || v[2] !== c[2] || v[3] !== c[3] || this.location !== location) { this.current = v; + this.location = location; this.context.gl.uniform4f(location, v[0], v[1], v[2], v[3]); } } @@ -77,10 +84,10 @@ class Uniform4fv extends Uniform<[number, number, number, number] | Color> { } class UniformMatrix4fv extends Uniform { - set(location: WebGLUniformLocation, v: Float32Array, invalidate: boolean = false): void { - let diff = !this.current || invalidate; + set(location: WebGLUniformLocation, v: Float32Array): void { + let diff = !this.current || this.location !== location; - if (!invalidate && this.current) { + if (!diff && this.current) { for (let i = 0; i < 16; i++) { if (v[i] !== this.current[i]) { diff = true; @@ -91,6 +98,7 @@ class UniformMatrix4fv extends Uniform { if (diff) { this.current = v; + this.location = location; this.context.gl.uniformMatrix4fv(location, false, v); } } diff --git a/test/unit/render/uniform_binding.test.js b/test/unit/render/uniform_binding.test.js index 20e2de43a4b..02b93511c76 100644 --- a/test/unit/render/uniform_binding.test.js +++ b/test/unit/render/uniform_binding.test.js @@ -50,23 +50,6 @@ test('Uniform1f', (t) => { t.end(); }); -test('Uniform1f: force set', (t) => { - t.plan(3); - - const context = { - gl: { - uniform1f: () => { t.ok(true, 'sets value when unique'); } - } - }; - - const u = new Uniform1f(context); - - u.set(0, 1); - t.equal(u.current, 1, 'correctly set value'); - u.set(0, 1, true); - t.end(); -}); - test('Uniform2fv', (t) => { t.plan(4); From 3a6a2f34f05e0e1e2fa17cbd7d9d28a4521acd3f Mon Sep 17 00:00:00 2001 From: Lauren Budorick Date: Fri, 16 Mar 2018 17:17:03 -0700 Subject: [PATCH 03/11] Perf improvements: initalize location in uniform binding constructor, initialize bindings in program constructor --- src/data/program_configuration.js | 45 ++++--- src/render/draw_line.js | 14 +- src/render/program.js | 8 +- src/render/program/background_program.js | 50 ++++---- src/render/program/circle_program.js | 14 +- src/render/program/clipping_mask_program.js | 6 +- src/render/program/collision_program.js | 14 +- src/render/program/debug_program.js | 14 +- src/render/program/fill_extrusion_program.js | 62 ++++----- src/render/program/fill_program.js | 78 ++++++------ src/render/program/heatmap_program.js | 22 ++-- src/render/program/hillshade_program.js | 44 +++---- src/render/program/line_program.js | 68 +++++----- src/render/program/raster_program.js | 30 ++--- src/render/program/symbol_program.js | 74 +++++------ src/render/uniform_binding.js | 127 +++++++++++-------- test/unit/render/uniform_binding.test.js | 60 ++++----- 17 files changed, 377 insertions(+), 353 deletions(-) diff --git a/src/data/program_configuration.js b/src/data/program_configuration.js index 3f1ebc7ae6d..835481800a5 100644 --- a/src/data/program_configuration.js +++ b/src/data/program_configuration.js @@ -7,7 +7,7 @@ import { register } from '../util/web_worker_transfer'; import { PossiblyEvaluatedPropertyValue } from '../style/properties'; import { StructArrayLayout1f4, StructArrayLayout2f8, StructArrayLayout4f16 } from './array_types'; import EvaluationParameters from '../style/evaluation_parameters'; -import { Uniform, Uniform1f, Uniform4fv } from '../render/uniform_binding'; +import { Uniform, Uniform1f, UniformColor, Uniforms } from '../render/uniform_binding'; import type Context from '../gl/context'; import type {TypedStyleLayer} from '../style/style_layer/typed_style_layer'; @@ -67,7 +67,6 @@ function packColor(color: Color): [number, number] { interface Binder { statistics: { max: number }; uniformName: string; - uniformBinding: ?$Subtype>; populatePaintArray(length: number, feature: Feature): void; updatePaintArray(start: number, length: number, feature: Feature, featureState: FeatureState): void; @@ -78,6 +77,8 @@ interface Binder { setUniforms(context: Context, program: Program<*>, globals: GlobalProperties, currentValue: PossiblyEvaluatedPropertyValue): void; + + getBinding(context: Context, location: WebGLUniformLocation): $Subtype>; } class ConstantBinder implements Binder { @@ -86,7 +87,6 @@ class ConstantBinder implements Binder { statistics: { max: number }; type: string; uniformName: string; - uniformBinding: ?$Subtype>; constructor(value: T, name: string, type: string) { this.value = value; @@ -108,13 +108,13 @@ class ConstantBinder implements Binder { setUniforms(context: Context, program: Program<*>, globals: GlobalProperties, currentValue: PossiblyEvaluatedPropertyValue): void { const value = currentValue.constantOr(this.value); + program.binderUniforms.bindings[this.uniformName].set(value); + } - if (!program.binderUniforms.bindings[this.uniformName]) { - program.binderUniforms.bindings[this.uniformName] = this.type === 'color' ? - new Uniform4fv(context) : new Uniform1f(context); - } - - program.binderUniforms.bindings[this.uniformName].set(program.uniforms[this.uniformName], value); + getBinding(context: Context, location: WebGLUniformLocation): $Subtype> { + return (this.type === 'color') ? + new UniformColor(context, location) : + new Uniform1f(context, location); } } @@ -124,7 +124,6 @@ class SourceExpressionBinder implements Binder { uniformName: string; type: string; statistics: { max: number }; - uniformBinding: ?Uniform1f; paintVertexArray: StructArray; paintVertexAttributes: Array; @@ -207,11 +206,11 @@ class SourceExpressionBinder implements Binder { } setUniforms(context: Context, program: Program<*>): void { - if (!program.binderUniforms.bindings[this.uniformName]) { - program.binderUniforms.bindings[this.uniformName] = new Uniform1f(context); - } + program.binderUniforms.bindings[this.uniformName].set(0); + } - program.binderUniforms.bindings[this.uniformName].set(program.uniforms[this.uniformName], 0); + getBinding(context: Context, location: WebGLUniformLocation): Uniform1f { + return new Uniform1f(context, location); } } @@ -223,7 +222,6 @@ class CompositeExpressionBinder implements Binder { useIntegerZoom: boolean; zoom: number; statistics: { max: number }; - uniformBinding: ?Uniform1f; paintVertexArray: StructArray; paintVertexAttributes: Array; @@ -322,11 +320,11 @@ class CompositeExpressionBinder implements Binder { setUniforms(context: Context, program: Program<*>, globals: GlobalProperties): void { - if (!program.binderUniforms.bindings[this.uniformName]) { - program.binderUniforms.bindings[this.uniformName] = new Uniform1f(context); - } + program.binderUniforms.bindings[this.uniformName].set(this.interpolationFactor(globals.zoom)); + } - program.binderUniforms.bindings[this.uniformName].set(program.uniforms[this.uniformName], this.interpolationFactor(globals.zoom)); + getBinding(context: Context, location: WebGLUniformLocation): Uniform1f { + return new Uniform1f(context, location); } } @@ -456,6 +454,15 @@ export default class ProgramConfiguration { return this._buffers; } + getUniforms(context: Context, program: Program<*>): void { + program.binderUniforms = new Uniforms({}); + for (const property in this.binders) { + const binder = this.binders[property]; + program.binderUniforms.bindings[binder.uniformName] = + binder.getBinding(context, program.uniforms[binder.uniformName]); + } + } + setUniforms(context: Context, program: Program<*>, properties: PossiblyEvaluated, globals: GlobalProperties) { // Uniform state bindings are owned by the Program, but we set them // from within the ProgramConfiguraton's binder members. diff --git a/src/render/draw_line.js b/src/render/draw_line.js index a544939dac0..1abbbf43248 100644 --- a/src/render/draw_line.js +++ b/src/render/draw_line.js @@ -62,14 +62,12 @@ function drawLineTile(program, painter, tile, bucket, layer, coord, depthMode, c gradient ? lineGradientUniformValues(painter, tile, layer) : lineUniformValues(painter, tile, layer); - if (programChanged) { - if (dasharray) { - context.activeTexture.set(gl.TEXTURE0); - painter.lineAtlas.bind(context); - } else if (image) { - context.activeTexture.set(gl.TEXTURE0); - painter.imageManager.bind(context); - } + if (dasharray && (programChanged || painter.lineAtlas.dirty)) { + context.activeTexture.set(gl.TEXTURE0); + painter.lineAtlas.bind(context); + } else if (image && (programChanged || painter.imageManager.dirty)) { + context.activeTexture.set(gl.TEXTURE0); + painter.imageManager.bind(context); } if (gradient) { diff --git a/src/render/program.js b/src/render/program.js index 35349eb05bc..0f380f2654d 100644 --- a/src/render/program.js +++ b/src/render/program.js @@ -34,7 +34,7 @@ class Program { constructor(context: Context, source: {fragmentSource: string, vertexSource: string}, configuration: ProgramConfiguration, - fixedUniforms: (Context) => Uniforms, + fixedUniforms: (Context, UniformLocations) => Uniforms, showOverdrawInspector: boolean) { const gl = context.gl; this.program = gl.createProgram(); @@ -92,8 +92,8 @@ class Program { } } - this.fixedUniforms = fixedUniforms(context); - this.binderUniforms = new Uniforms({}); + this.fixedUniforms = fixedUniforms(context, this.uniforms); + configuration.getUniforms(context, (this: any)); } draw(context: Context, @@ -118,7 +118,7 @@ class Program { context.setStencilMode(stencilMode); context.setColorMode(colorMode); - this.fixedUniforms.set(this.uniforms, uniformValues); + this.fixedUniforms.set(uniformValues); if (configuration) { configuration.setUniforms(context, this, currentProperties, {zoom: (zoom: any)}); } diff --git a/src/render/program/background_program.js b/src/render/program/background_program.js index 946a346f2c8..69c7b05ad28 100644 --- a/src/render/program/background_program.js +++ b/src/render/program/background_program.js @@ -5,14 +5,14 @@ import { Uniform1i, Uniform1f, Uniform2fv, - Uniform4fv, + UniformColor, UniformMatrix4fv, Uniforms } from '../uniform_binding'; import { extend } from '../../util/util'; import type Painter from '../painter'; -import type {UniformValues} from '../uniform_binding'; +import type {UniformValues, UniformLocations} from '../uniform_binding'; import type Context from '../../gl/context'; import type Color from '../../style-spec/util/color'; import type {CrossFaded} from '../../style/cross_faded'; @@ -21,7 +21,7 @@ import type {OverscaledTileID} from '../../source/tile_id'; export type BackgroundUniformsType = {| 'u_matrix': UniformMatrix4fv, 'u_opacity': Uniform1f, - 'u_color': Uniform4fv + 'u_color': UniformColor |}; export type BackgroundPatternUniformsType = {| @@ -44,29 +44,29 @@ export type BackgroundPatternUniformsType = {| 'u_tile_units_to_pixels': Uniform1f |}; -const backgroundUniforms = (context: Context): Uniforms => new Uniforms({ - 'u_matrix': new UniformMatrix4fv(context), - 'u_opacity': new Uniform1f(context), - 'u_color': new Uniform4fv(context) +const backgroundUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ + 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), + 'u_opacity': new Uniform1f(context, locations.u_opacity), + 'u_color': new UniformColor(context, locations.u_color) }); -const backgroundPatternUniforms = (context: Context): Uniforms => new Uniforms({ - 'u_matrix': new UniformMatrix4fv(context), - 'u_opacity': new Uniform1f(context), - 'u_image': new Uniform1i(context), - 'u_pattern_tl_a': new Uniform2fv(context), - 'u_pattern_br_a': new Uniform2fv(context), - 'u_pattern_tl_b': new Uniform2fv(context), - 'u_pattern_br_b': new Uniform2fv(context), - 'u_texsize': new Uniform2fv(context), - 'u_mix': new Uniform1f(context), - 'u_pattern_size_a': new Uniform2fv(context), - 'u_pattern_size_b': new Uniform2fv(context), - 'u_scale_a': new Uniform1f(context), - 'u_scale_b': new Uniform1f(context), - 'u_pixel_coord_upper': new Uniform2fv(context), - 'u_pixel_coord_lower': new Uniform2fv(context), - 'u_tile_units_to_pixels': new Uniform1f(context) +const backgroundPatternUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ + 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), + 'u_opacity': new Uniform1f(context, locations.u_opacity), + 'u_image': new Uniform1i(context, locations.u_image), + 'u_pattern_tl_a': new Uniform2fv(context, locations.u_pattern_tl_a), + 'u_pattern_br_a': new Uniform2fv(context, locations.u_pattern_br_a), + 'u_pattern_tl_b': new Uniform2fv(context, locations.u_pattern_tl_b), + 'u_pattern_br_b': new Uniform2fv(context, locations.u_pattern_br_b), + 'u_texsize': new Uniform2fv(context, locations.u_texsize), + 'u_mix': new Uniform1f(context, locations.u_mix), + 'u_pattern_size_a': new Uniform2fv(context, locations.u_pattern_size_a), + 'u_pattern_size_b': new Uniform2fv(context, locations.u_pattern_size_b), + 'u_scale_a': new Uniform1f(context, locations.u_scale_a), + 'u_scale_b': new Uniform1f(context, locations.u_scale_b), + 'u_pixel_coord_upper': new Uniform2fv(context, locations.u_pixel_coord_upper), + 'u_pixel_coord_lower': new Uniform2fv(context, locations.u_pixel_coord_lower), + 'u_tile_units_to_pixels': new Uniform1f(context, locations.u_tile_units_to_pixels) }); const backgroundUniformValues = ( @@ -76,7 +76,7 @@ const backgroundUniformValues = ( ): UniformValues => ({ 'u_matrix': matrix, 'u_opacity': opacity, - 'u_color': [color.r, color.g, color.b, color.a] + 'u_color': color }); const backgroundPatternUniformValues = ( diff --git a/src/render/program/circle_program.js b/src/render/program/circle_program.js index 0bd43ca8e2d..94795ecc452 100644 --- a/src/render/program/circle_program.js +++ b/src/render/program/circle_program.js @@ -10,7 +10,7 @@ import { import pixelsToTileUnits from '../../source/pixels_to_tile_units'; import type Context from '../../gl/context'; -import type {UniformValues} from '../uniform_binding'; +import type {UniformValues, UniformLocations} from '../uniform_binding'; import type {OverscaledTileID} from '../../source/tile_id'; import type Tile from '../../source/tile'; import type CircleStyleLayer from '../../style/style_layer/circle_style_layer'; @@ -24,12 +24,12 @@ export type CircleUniformsType = {| 'u_matrix': UniformMatrix4fv |}; -const circleUniforms = (context: Context): Uniforms => new Uniforms({ - 'u_camera_to_center_distance': new Uniform1f(context), - 'u_scale_with_map': new Uniform1i(context), - 'u_pitch_with_map': new Uniform1i(context), - 'u_extrude_scale': new Uniform2fv(context), - 'u_matrix': new UniformMatrix4fv(context) +const circleUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ + 'u_camera_to_center_distance': new Uniform1f(context, locations.u_camera_to_center_distance), + 'u_scale_with_map': new Uniform1i(context, locations.u_scale_with_map), + 'u_pitch_with_map': new Uniform1i(context, locations.u_pitch_with_map), + 'u_extrude_scale': new Uniform2fv(context, locations.u_extrude_scale), + 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix) }); const circleUniformValues = ( diff --git a/src/render/program/clipping_mask_program.js b/src/render/program/clipping_mask_program.js index 58f5b500797..f2b9daca6fd 100644 --- a/src/render/program/clipping_mask_program.js +++ b/src/render/program/clipping_mask_program.js @@ -3,14 +3,14 @@ import { UniformMatrix4fv, Uniforms } from '../uniform_binding'; import type Context from '../../gl/context'; -import type {UniformValues} from '../uniform_binding'; +import type {UniformValues, UniformLocations} from '../uniform_binding'; export type ClippingMaskUniformsType = {| 'u_matrix': UniformMatrix4fv |}; -const clippingMaskUniforms = (context: Context): Uniforms => new Uniforms({ - 'u_matrix': new UniformMatrix4fv(context) +const clippingMaskUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ + 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix) }); const clippingMaskUniformValues = (matrix: Float32Array): UniformValues => ({ diff --git a/src/render/program/collision_program.js b/src/render/program/collision_program.js index 0f0a4b2232b..f9ac480d4f0 100644 --- a/src/render/program/collision_program.js +++ b/src/render/program/collision_program.js @@ -9,7 +9,7 @@ import { import pixelsToTileUnits from '../../source/pixels_to_tile_units'; import type Context from '../../gl/context'; -import type {UniformValues} from '../uniform_binding'; +import type {UniformValues, UniformLocations} from '../uniform_binding'; import type Transform from '../../geo/transform'; import type Tile from '../../source/tile'; @@ -21,12 +21,12 @@ export type CollisionUniformsType = {| 'u_overscale_factor': Uniform1f |}; -const collisionUniforms = (context: Context): Uniforms => new Uniforms({ - 'u_matrix': new UniformMatrix4fv(context), - 'u_camera_to_center_distance': new Uniform1f(context), - 'u_pixels_to_tile_units': new Uniform1f(context), - 'u_extrude_scale': new Uniform2fv(context), - 'u_overscale_factor': new Uniform1f(context) +const collisionUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ + 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), + 'u_camera_to_center_distance': new Uniform1f(context, locations.u_camera_to_center_distance), + 'u_pixels_to_tile_units': new Uniform1f(context, locations.u_pixels_to_tile_units), + 'u_extrude_scale': new Uniform2fv(context, locations.u_extrude_scale), + 'u_overscale_factor': new Uniform1f(context, locations.u_overscale_factor) }); const collisionUniformValues = ( diff --git a/src/render/program/debug_program.js b/src/render/program/debug_program.js index cd1d7d8651c..3629b126ca0 100644 --- a/src/render/program/debug_program.js +++ b/src/render/program/debug_program.js @@ -1,28 +1,28 @@ // @flow import { - Uniform4fv, + UniformColor, UniformMatrix4fv, Uniforms } from '../uniform_binding'; import type Context from '../../gl/context'; -import type {UniformValues} from '../uniform_binding'; +import type {UniformValues, UniformLocations} from '../uniform_binding'; import type Color from '../../style-spec/util/color'; export type DebugUniformsType = {| - 'u_color': Uniform4fv, + 'u_color': UniformColor, 'u_matrix': UniformMatrix4fv |}; -const debugUniforms = (context: Context): Uniforms => new Uniforms({ - 'u_color': new Uniform4fv(context), - 'u_matrix': new UniformMatrix4fv(context) +const debugUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ + 'u_color': new UniformColor(context, locations.u_color), + 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix) }); const debugUniformValues = (matrix: Float32Array, color: Color): UniformValues => ({ 'u_matrix': matrix, - 'u_color': [color.r, color.g, color.b, color.a] + 'u_color': color }); export { debugUniforms, debugUniformValues }; diff --git a/src/render/program/fill_extrusion_program.js b/src/render/program/fill_extrusion_program.js index ec1317e198a..de3bf0ab181 100644 --- a/src/render/program/fill_extrusion_program.js +++ b/src/render/program/fill_extrusion_program.js @@ -17,7 +17,7 @@ import type Context from '../../gl/context'; import type Painter from '../painter'; import type {OverscaledTileID} from '../../source/tile_id'; import type {CrossFaded} from '../../style/cross_faded'; -import type {UniformValues} from '../uniform_binding'; +import type {UniformValues, UniformLocations} from '../uniform_binding'; import type FillExtrusionStyleLayer from '../../style/style_layer/fill_extrusion_style_layer'; export type FillExtrusionUniformsType = {| @@ -57,40 +57,40 @@ export type ExtrusionTextureUniformsType = {| 'u_opacity': Uniform1f |}; -const fillExtrusionUniforms = (context: Context): Uniforms => new Uniforms({ - 'u_matrix': new UniformMatrix4fv(context), - 'u_lightpos': new Uniform3fv(context), - 'u_lightintensity': new Uniform1f(context), - 'u_lightcolor': new Uniform3fv(context) +const fillExtrusionUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ + 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), + 'u_lightpos': new Uniform3fv(context, locations.u_lightpos), + 'u_lightintensity': new Uniform1f(context, locations.u_lightintensity), + 'u_lightcolor': new Uniform3fv(context, locations.u_lightcolor) }); -const fillExtrusionPatternUniforms = (context: Context): Uniforms => new Uniforms({ - 'u_matrix': new UniformMatrix4fv(context), - 'u_lightpos': new Uniform3fv(context), - 'u_lightintensity': new Uniform1f(context), - 'u_lightcolor': new Uniform3fv(context), - 'u_height_factor': new Uniform1f(context), - 'u_image': new Uniform1i(context), - 'u_pattern_tl_a': new Uniform2fv(context), - 'u_pattern_br_a': new Uniform2fv(context), - 'u_pattern_tl_b': new Uniform2fv(context), - 'u_pattern_br_b': new Uniform2fv(context), - 'u_texsize': new Uniform2fv(context), - 'u_mix': new Uniform1f(context), - 'u_pattern_size_a': new Uniform2fv(context), - 'u_pattern_size_b': new Uniform2fv(context), - 'u_scale_a': new Uniform1f(context), - 'u_scale_b': new Uniform1f(context), - 'u_pixel_coord_upper': new Uniform2fv(context), - 'u_pixel_coord_lower': new Uniform2fv(context), - 'u_tile_units_to_pixels': new Uniform1f(context) +const fillExtrusionPatternUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ + 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), + 'u_lightpos': new Uniform3fv(context, locations.u_lightpos), + 'u_lightintensity': new Uniform1f(context, locations.u_lightintensity), + 'u_lightcolor': new Uniform3fv(context, locations.u_lightcolor), + 'u_height_factor': new Uniform1f(context, locations.u_height_factor), + 'u_image': new Uniform1i(context, locations.u_image), + 'u_pattern_tl_a': new Uniform2fv(context, locations.u_pattern_tl_a), + 'u_pattern_br_a': new Uniform2fv(context, locations.u_pattern_br_a), + 'u_pattern_tl_b': new Uniform2fv(context, locations.u_pattern_tl_b), + 'u_pattern_br_b': new Uniform2fv(context, locations.u_pattern_br_b), + 'u_texsize': new Uniform2fv(context, locations.u_texsize), + 'u_mix': new Uniform1f(context, locations.u_mix), + 'u_pattern_size_a': new Uniform2fv(context, locations.u_pattern_size_a), + 'u_pattern_size_b': new Uniform2fv(context, locations.u_pattern_size_b), + 'u_scale_a': new Uniform1f(context, locations.u_scale_a), + 'u_scale_b': new Uniform1f(context, locations.u_scale_b), + 'u_pixel_coord_upper': new Uniform2fv(context, locations.u_pixel_coord_upper), + 'u_pixel_coord_lower': new Uniform2fv(context, locations.u_pixel_coord_lower), + 'u_tile_units_to_pixels': new Uniform1f(context, locations.u_tile_units_to_pixels) }); -const extrusionTextureUniforms = (context: Context): Uniforms => new Uniforms({ - 'u_matrix': new UniformMatrix4fv(context), - 'u_world': new Uniform2fv(context), - 'u_image': new Uniform1i(context), - 'u_opacity': new Uniform1f(context) +const extrusionTextureUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ + 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), + 'u_world': new Uniform2fv(context, locations.u_world), + 'u_image': new Uniform1i(context, locations.u_image), + 'u_opacity': new Uniform1f(context, locations.u_opacity) }); const fillExtrusionUniformValues = ( diff --git a/src/render/program/fill_program.js b/src/render/program/fill_program.js index 98fa19a8806..f3027346be6 100644 --- a/src/render/program/fill_program.js +++ b/src/render/program/fill_program.js @@ -11,7 +11,7 @@ import { import { extend } from '../../util/util'; import type Painter from '../painter'; -import type {UniformValues} from '../uniform_binding'; +import type {UniformValues, UniformLocations} from '../uniform_binding'; import type Context from '../../gl/context'; import type {CrossFaded} from '../../style/cross_faded'; import type {OverscaledTileID} from '../../source/tile_id'; @@ -64,50 +64,50 @@ export type FillOutlinePatternUniformsType = {| 'u_tile_units_to_pixels': Uniform1f |}; -const fillUniforms = (context: Context): Uniforms => new Uniforms({ - 'u_matrix': new UniformMatrix4fv(context) +const fillUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ + 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix) }); -const fillPatternUniforms = (context: Context): Uniforms => new Uniforms({ - 'u_matrix': new UniformMatrix4fv(context), - 'u_image': new Uniform1i(context), - 'u_pattern_tl_a': new Uniform2fv(context), - 'u_pattern_br_a': new Uniform2fv(context), - 'u_pattern_tl_b': new Uniform2fv(context), - 'u_pattern_br_b': new Uniform2fv(context), - 'u_texsize': new Uniform2fv(context), - 'u_mix': new Uniform1f(context), - 'u_pattern_size_a': new Uniform2fv(context), - 'u_pattern_size_b': new Uniform2fv(context), - 'u_scale_a': new Uniform1f(context), - 'u_scale_b': new Uniform1f(context), - 'u_pixel_coord_upper': new Uniform2fv(context), - 'u_pixel_coord_lower': new Uniform2fv(context), - 'u_tile_units_to_pixels': new Uniform1f(context) +const fillPatternUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ + 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), + 'u_image': new Uniform1i(context, locations.u_image), + 'u_pattern_tl_a': new Uniform2fv(context, locations.u_pattern_tl_a), + 'u_pattern_br_a': new Uniform2fv(context, locations.u_pattern_br_a), + 'u_pattern_tl_b': new Uniform2fv(context, locations.u_pattern_tl_b), + 'u_pattern_br_b': new Uniform2fv(context, locations.u_pattern_br_b), + 'u_texsize': new Uniform2fv(context, locations.u_texsize), + 'u_mix': new Uniform1f(context, locations.u_mix), + 'u_pattern_size_a': new Uniform2fv(context, locations.u_pattern_size_a), + 'u_pattern_size_b': new Uniform2fv(context, locations.u_pattern_size_b), + 'u_scale_a': new Uniform1f(context, locations.u_scale_a), + 'u_scale_b': new Uniform1f(context, locations.u_scale_b), + 'u_pixel_coord_upper': new Uniform2fv(context, locations.u_pixel_coord_upper), + 'u_pixel_coord_lower': new Uniform2fv(context, locations.u_pixel_coord_lower), + 'u_tile_units_to_pixels': new Uniform1f(context, locations.u_tile_units_to_pixels) }); -const fillOutlineUniforms = (context: Context): Uniforms => new Uniforms({ - 'u_matrix': new UniformMatrix4fv(context), - 'u_world': new Uniform2fv(context) +const fillOutlineUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ + 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), + 'u_world': new Uniform2fv(context, locations.u_world) }); -const fillOutlinePatternUniforms = (context: Context): Uniforms => new Uniforms({ - 'u_matrix': new UniformMatrix4fv(context), - 'u_world': new Uniform2fv(context), - 'u_image': new Uniform1i(context), - 'u_pattern_tl_a': new Uniform2fv(context), - 'u_pattern_br_a': new Uniform2fv(context), - 'u_pattern_tl_b': new Uniform2fv(context), - 'u_pattern_br_b': new Uniform2fv(context), - 'u_texsize': new Uniform2fv(context), - 'u_mix': new Uniform1f(context), - 'u_pattern_size_a': new Uniform2fv(context), - 'u_pattern_size_b': new Uniform2fv(context), - 'u_scale_a': new Uniform1f(context), - 'u_scale_b': new Uniform1f(context), - 'u_pixel_coord_upper': new Uniform2fv(context), - 'u_pixel_coord_lower': new Uniform2fv(context), - 'u_tile_units_to_pixels': new Uniform1f(context) +const fillOutlinePatternUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ + 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), + 'u_world': new Uniform2fv(context, locations.u_world), + 'u_image': new Uniform1i(context, locations.u_image), + 'u_pattern_tl_a': new Uniform2fv(context, locations.u_pattern_tl_a), + 'u_pattern_br_a': new Uniform2fv(context, locations.u_pattern_br_a), + 'u_pattern_tl_b': new Uniform2fv(context, locations.u_pattern_tl_b), + 'u_pattern_br_b': new Uniform2fv(context, locations.u_pattern_br_b), + 'u_texsize': new Uniform2fv(context, locations.u_texsize), + 'u_mix': new Uniform1f(context, locations.u_mix), + 'u_pattern_size_a': new Uniform2fv(context, locations.u_pattern_size_a), + 'u_pattern_size_b': new Uniform2fv(context, locations.u_pattern_size_b), + 'u_scale_a': new Uniform1f(context, locations.u_scale_a), + 'u_scale_b': new Uniform1f(context, locations.u_scale_b), + 'u_pixel_coord_upper': new Uniform2fv(context, locations.u_pixel_coord_upper), + 'u_pixel_coord_lower': new Uniform2fv(context, locations.u_pixel_coord_lower), + 'u_tile_units_to_pixels': new Uniform1f(context, locations.u_tile_units_to_pixels) }); const fillUniformValues = (matrix: Float32Array): UniformValues => ({ diff --git a/src/render/program/heatmap_program.js b/src/render/program/heatmap_program.js index 956293d6486..6024b98643e 100644 --- a/src/render/program/heatmap_program.js +++ b/src/render/program/heatmap_program.js @@ -13,7 +13,7 @@ import pixelsToTileUnits from '../../source/pixels_to_tile_units'; import type Context from '../../gl/context'; import type Tile from '../../source/tile'; -import type {UniformValues} from '../uniform_binding'; +import type {UniformValues, UniformLocations} from '../uniform_binding'; import type Painter from '../painter'; import type HeatmapStyleLayer from '../../style/style_layer/heatmap_style_layer'; @@ -31,18 +31,18 @@ export type HeatmapTextureUniformsType = {| 'u_opacity': Uniform1f |}; -const heatmapUniforms = (context: Context): Uniforms => new Uniforms({ - 'u_extrude_scale': new Uniform1f(context), - 'u_intensity': new Uniform1f(context), - 'u_matrix': new UniformMatrix4fv(context) +const heatmapUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ + 'u_extrude_scale': new Uniform1f(context, locations.u_extrude_scale), + 'u_intensity': new Uniform1f(context, locations.u_intensity), + 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix) }); -const heatmapTextureUniforms = (context: Context): Uniforms => new Uniforms({ - 'u_matrix': new UniformMatrix4fv(context), - 'u_world': new Uniform2fv(context), - 'u_image': new Uniform1i(context), - 'u_color_ramp': new Uniform1i(context), - 'u_opacity': new Uniform1f(context) +const heatmapTextureUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ + 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), + 'u_world': new Uniform2fv(context, locations.u_world), + 'u_image': new Uniform1i(context, locations.u_image), + 'u_color_ramp': new Uniform1i(context, locations.u_color_ramp), + 'u_opacity': new Uniform1f(context, locations.u_opacity) }); const heatmapUniformValues = ( diff --git a/src/render/program/hillshade_program.js b/src/render/program/hillshade_program.js index 4dd02140c18..0450f7e08ce 100644 --- a/src/render/program/hillshade_program.js +++ b/src/render/program/hillshade_program.js @@ -7,7 +7,7 @@ import { Uniform1i, Uniform1f, Uniform2fv, - Uniform4fv, + UniformColor, UniformMatrix4fv, Uniforms } from '../uniform_binding'; @@ -15,7 +15,7 @@ import EXTENT from '../../data/extent'; import Coordinate from '../../geo/coordinate'; import type Context from '../../gl/context'; -import type {UniformValues} from '../uniform_binding'; +import type {UniformValues, UniformLocations} from '../uniform_binding'; import type Tile from '../../source/tile'; import type Painter from '../painter'; import type HillshadeStyleLayer from '../../style/style_layer/hillshade_style_layer'; @@ -27,9 +27,9 @@ export type HillshadeUniformsType = {| 'u_image': Uniform1i, 'u_latrange': Uniform2fv, 'u_light': Uniform2fv, - 'u_shadow': Uniform4fv, - 'u_highlight': Uniform4fv, - 'u_accent': Uniform4fv + 'u_shadow': UniformColor, + 'u_highlight': UniformColor, + 'u_accent': UniformColor |}; export type HillshadePrepareUniformsType = {| @@ -40,22 +40,22 @@ export type HillshadePrepareUniformsType = {| 'u_maxzoom': Uniform1f |}; -const hillshadeUniforms = (context: Context): Uniforms => new Uniforms({ - 'u_matrix': new UniformMatrix4fv(context), - 'u_image': new Uniform1i(context), - 'u_latrange': new Uniform2fv(context), - 'u_light': new Uniform2fv(context), - 'u_shadow': new Uniform4fv(context), - 'u_highlight': new Uniform4fv(context), - 'u_accent': new Uniform4fv(context) +const hillshadeUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ + 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), + 'u_image': new Uniform1i(context, locations.u_image), + 'u_latrange': new Uniform2fv(context, locations.u_latrange), + 'u_light': new Uniform2fv(context, locations.u_light), + 'u_shadow': new UniformColor(context, locations.u_shadow), + 'u_highlight': new UniformColor(context, locations.u_highlight), + 'u_accent': new UniformColor(context, locations.u_accent) }); -const hillshadePrepareUniforms = (context: Context): Uniforms => new Uniforms({ - 'u_matrix': new UniformMatrix4fv(context), - 'u_image': new Uniform1i(context), - 'u_dimension': new Uniform2fv(context), - 'u_zoom': new Uniform1f(context), - 'u_maxzoom': new Uniform1f(context) +const hillshadePrepareUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ + 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), + 'u_image': new Uniform1i(context, locations.u_image), + 'u_dimension': new Uniform2fv(context, locations.u_dimension), + 'u_zoom': new Uniform1f(context, locations.u_zoom), + 'u_maxzoom': new Uniform1f(context, locations.u_maxzoom) }); const hillshadeUniformValues = ( @@ -78,9 +78,9 @@ const hillshadeUniformValues = ( 'u_image': 0, 'u_latrange': getTileLatRange(painter, tile.tileID), 'u_light': [layer.paint.get('hillshade-exaggeration'), azimuthal], - 'u_shadow': [shadow.r, shadow.g, shadow.b, shadow.a], - 'u_highlight': [highlight.r, highlight.g, highlight.b, highlight.a], - 'u_accent': [accent.r, accent.g, accent.b, accent.a] + 'u_shadow': shadow, + 'u_highlight': highlight, + 'u_accent': accent }; }; diff --git a/src/render/program/line_program.js b/src/render/program/line_program.js index d5c739a6bef..66a230aaccd 100644 --- a/src/render/program/line_program.js +++ b/src/render/program/line_program.js @@ -12,7 +12,7 @@ import { extend } from '../../util/util'; import browser from '../../util/browser'; import type Context from '../../gl/context'; -import type {UniformValues} from '../uniform_binding'; +import type {UniformValues, UniformLocations} from '../uniform_binding'; import type Transform from '../../geo/transform'; import type Tile from '../../source/tile'; import type {CrossFaded} from '../../style/cross_faded'; @@ -60,45 +60,45 @@ export type LineSDFUniformsType = {| 'u_mix': Uniform1f |}; -const lineUniforms = (context: Context): Uniforms => new Uniforms({ - 'u_matrix': new UniformMatrix4fv(context), - 'u_ratio': new Uniform1f(context), - 'u_gl_units_to_pixels': new Uniform2fv(context) +const lineUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ + 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), + 'u_ratio': new Uniform1f(context, locations.u_ratio), + 'u_gl_units_to_pixels': new Uniform2fv(context, locations.u_gl_units_to_pixels) }); -const lineGradientUniforms = (context: Context): Uniforms => new Uniforms({ - 'u_matrix': new UniformMatrix4fv(context), - 'u_ratio': new Uniform1f(context), - 'u_gl_units_to_pixels': new Uniform2fv(context), - 'u_image': new Uniform1i(context) +const lineGradientUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ + 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), + 'u_ratio': new Uniform1f(context, locations.u_ratio), + 'u_gl_units_to_pixels': new Uniform2fv(context, locations.u_gl_units_to_pixels), + 'u_image': new Uniform1i(context, locations.u_image) }); -const linePatternUniforms = (context: Context): Uniforms => new Uniforms({ - 'u_matrix': new UniformMatrix4fv(context), - 'u_ratio': new Uniform1f(context), - 'u_gl_units_to_pixels': new Uniform2fv(context), - 'u_pattern_size_a': new Uniform2fv(context), - 'u_pattern_size_b': new Uniform2fv(context), - 'u_texsize': new Uniform2fv(context), - 'u_image': new Uniform1i(context), - 'u_pattern_tl_a': new Uniform2fv(context), - 'u_pattern_br_a': new Uniform2fv(context), - 'u_pattern_tl_b': new Uniform2fv(context), - 'u_pattern_br_b': new Uniform2fv(context), - 'u_fade': new Uniform1f(context) +const linePatternUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ + 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), + 'u_ratio': new Uniform1f(context, locations.u_ratio), + 'u_gl_units_to_pixels': new Uniform2fv(context, locations.u_gl_units_to_pixels), + 'u_pattern_size_a': new Uniform2fv(context, locations.u_pattern_size_a), + 'u_pattern_size_b': new Uniform2fv(context, locations.u_pattern_size_b), + 'u_texsize': new Uniform2fv(context, locations.u_texsize), + 'u_image': new Uniform1i(context, locations.u_image), + 'u_pattern_tl_a': new Uniform2fv(context, locations.u_pattern_tl_a), + 'u_pattern_br_a': new Uniform2fv(context, locations.u_pattern_br_a), + 'u_pattern_tl_b': new Uniform2fv(context, locations.u_pattern_tl_b), + 'u_pattern_br_b': new Uniform2fv(context, locations.u_pattern_br_b), + 'u_fade': new Uniform1f(context, locations.u_fade) }); -const lineSDFUniforms = (context: Context): Uniforms => new Uniforms({ - 'u_matrix': new UniformMatrix4fv(context), - 'u_ratio': new Uniform1f(context), - 'u_gl_units_to_pixels': new Uniform2fv(context), - 'u_patternscale_a': new Uniform2fv(context), - 'u_patternscale_b': new Uniform2fv(context), - 'u_sdfgamma': new Uniform1f(context), - 'u_image': new Uniform1i(context), - 'u_tex_y_a': new Uniform1f(context), - 'u_tex_y_b': new Uniform1f(context), - 'u_mix': new Uniform1f(context) +const lineSDFUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ + 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), + 'u_ratio': new Uniform1f(context, locations.u_ratio), + 'u_gl_units_to_pixels': new Uniform2fv(context, locations.u_gl_units_to_pixels), + 'u_patternscale_a': new Uniform2fv(context, locations.u_patternscale_a), + 'u_patternscale_b': new Uniform2fv(context, locations.u_patternscale_b), + 'u_sdfgamma': new Uniform1f(context, locations.u_sdfgamma), + 'u_image': new Uniform1i(context, locations.u_image), + 'u_tex_y_a': new Uniform1f(context, locations.u_tex_y_a), + 'u_tex_y_b': new Uniform1f(context, locations.u_tex_y_b), + 'u_mix': new Uniform1f(context, locations.u_mix) }); const lineUniformValues = ( diff --git a/src/render/program/raster_program.js b/src/render/program/raster_program.js index cd8becaaf1a..ef99cdae876 100644 --- a/src/render/program/raster_program.js +++ b/src/render/program/raster_program.js @@ -10,7 +10,7 @@ import { } from '../uniform_binding'; import type Context from '../../gl/context'; -import type {UniformValues} from '../uniform_binding'; +import type {UniformValues, UniformLocations} from '../uniform_binding'; import type RasterStyleLayer from '../../style/style_layer/raster_style_layer'; export type RasterUniformsType = {| @@ -29,20 +29,20 @@ export type RasterUniformsType = {| 'u_spin_weights': Uniform3fv |}; -const rasterUniforms = (context: Context): Uniforms => new Uniforms({ - 'u_matrix': new UniformMatrix4fv(context), - 'u_tl_parent': new Uniform2fv(context), - 'u_scale_parent': new Uniform1f(context), - 'u_buffer_scale': new Uniform1f(context), - 'u_fade_t': new Uniform1f(context), - 'u_opacity': new Uniform1f(context), - 'u_image0': new Uniform1i(context), - 'u_image1': new Uniform1i(context), - 'u_brightness_low': new Uniform1f(context), - 'u_brightness_high': new Uniform1f(context), - 'u_saturation_factor': new Uniform1f(context), - 'u_contrast_factor': new Uniform1f(context), - 'u_spin_weights': new Uniform3fv(context) +const rasterUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ + 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), + 'u_tl_parent': new Uniform2fv(context, locations.u_tl_parent), + 'u_scale_parent': new Uniform1f(context, locations.u_scale_parent), + 'u_buffer_scale': new Uniform1f(context, locations.u_buffer_scale), + 'u_fade_t': new Uniform1f(context, locations.u_fade_t), + 'u_opacity': new Uniform1f(context, locations.u_opacity), + 'u_image0': new Uniform1i(context, locations.u_image0), + 'u_image1': new Uniform1i(context, locations.u_image1), + 'u_brightness_low': new Uniform1f(context, locations.u_brightness_low), + 'u_brightness_high': new Uniform1f(context, locations.u_brightness_high), + 'u_saturation_factor': new Uniform1f(context, locations.u_saturation_factor), + 'u_contrast_factor': new Uniform1f(context, locations.u_contrast_factor), + 'u_spin_weights': new Uniform3fv(context, locations.u_spin_weights) }); const rasterUniformValues = ( diff --git a/src/render/program/symbol_program.js b/src/render/program/symbol_program.js index 6d52d58f6c5..8119291fbe0 100644 --- a/src/render/program/symbol_program.js +++ b/src/render/program/symbol_program.js @@ -11,7 +11,7 @@ import { extend } from '../../util/util'; import type Context from '../../gl/context'; import type Painter from '../painter'; -import type {UniformValues} from '../uniform_binding'; +import type {UniformValues, UniformLocations} from '../uniform_binding'; export type SymbolIconUniformsType = {| 'u_is_size_zoom_constant': Uniform1i, @@ -53,44 +53,44 @@ export type SymbolSDFUniformsType = {| 'u_is_halo': Uniform1f |}; -const symbolIconUniforms = (context: Context): Uniforms => new Uniforms({ - 'u_is_size_zoom_constant': new Uniform1i(context), - 'u_is_size_feature_constant': new Uniform1i(context), - 'u_size_t': new Uniform1f(context), - 'u_size': new Uniform1f(context), - 'u_camera_to_center_distance': new Uniform1f(context), - 'u_pitch': new Uniform1f(context), - 'u_rotate_symbol': new Uniform1i(context), - 'u_aspect_ratio': new Uniform1f(context), - 'u_fade_change': new Uniform1f(context), - 'u_matrix': new UniformMatrix4fv(context), - 'u_label_plane_matrix': new UniformMatrix4fv(context), - 'u_gl_coord_matrix': new UniformMatrix4fv(context), - 'u_is_text': new Uniform1f(context), - 'u_pitch_with_map': new Uniform1i(context), - 'u_texsize': new Uniform2fv(context), - 'u_texture': new Uniform1i(context) +const symbolIconUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ + 'u_is_size_zoom_constant': new Uniform1i(context, locations.u_is_size_zoom_constant), + 'u_is_size_feature_constant': new Uniform1i(context, locations.u_is_size_feature_constant), + 'u_size_t': new Uniform1f(context, locations.u_size_t), + 'u_size': new Uniform1f(context, locations.u_size), + 'u_camera_to_center_distance': new Uniform1f(context, locations.u_camera_to_center_distance), + 'u_pitch': new Uniform1f(context, locations.u_pitch), + 'u_rotate_symbol': new Uniform1i(context, locations.u_rotate_symbol), + 'u_aspect_ratio': new Uniform1f(context, locations.u_aspect_ratio), + 'u_fade_change': new Uniform1f(context, locations.u_fade_change), + 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), + 'u_label_plane_matrix': new UniformMatrix4fv(context, locations.u_label_plane_matrix), + 'u_gl_coord_matrix': new UniformMatrix4fv(context, locations.u_gl_coord_matrix), + 'u_is_text': new Uniform1f(context, locations.u_is_text), + 'u_pitch_with_map': new Uniform1i(context, locations.u_pitch_with_map), + 'u_texsize': new Uniform2fv(context, locations.u_texsize), + 'u_texture': new Uniform1i(context, locations.u_texture) }); -const symbolSDFUniforms = (context: Context): Uniforms => new Uniforms({ - 'u_is_size_zoom_constant': new Uniform1i(context), - 'u_is_size_feature_constant': new Uniform1i(context), - 'u_size_t': new Uniform1f(context), - 'u_size': new Uniform1f(context), - 'u_camera_to_center_distance': new Uniform1f(context), - 'u_pitch': new Uniform1f(context), - 'u_rotate_symbol': new Uniform1i(context), - 'u_aspect_ratio': new Uniform1f(context), - 'u_fade_change': new Uniform1f(context), - 'u_matrix': new UniformMatrix4fv(context), - 'u_label_plane_matrix': new UniformMatrix4fv(context), - 'u_gl_coord_matrix': new UniformMatrix4fv(context), - 'u_is_text': new Uniform1f(context), - 'u_pitch_with_map': new Uniform1i(context), - 'u_texsize': new Uniform2fv(context), - 'u_texture': new Uniform1i(context), - 'u_gamma_scale': new Uniform1f(context), - 'u_is_halo': new Uniform1f(context) +const symbolSDFUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ + 'u_is_size_zoom_constant': new Uniform1i(context, locations.u_is_size_zoom_constant), + 'u_is_size_feature_constant': new Uniform1i(context, locations.u_is_size_feature_constant), + 'u_size_t': new Uniform1f(context, locations.u_size_t), + 'u_size': new Uniform1f(context, locations.u_size), + 'u_camera_to_center_distance': new Uniform1f(context, locations.u_camera_to_center_distance), + 'u_pitch': new Uniform1f(context, locations.u_pitch), + 'u_rotate_symbol': new Uniform1i(context, locations.u_rotate_symbol), + 'u_aspect_ratio': new Uniform1f(context, locations.u_aspect_ratio), + 'u_fade_change': new Uniform1f(context, locations.u_fade_change), + 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), + 'u_label_plane_matrix': new UniformMatrix4fv(context, locations.u_label_plane_matrix), + 'u_gl_coord_matrix': new UniformMatrix4fv(context, locations.u_gl_coord_matrix), + 'u_is_text': new Uniform1f(context, locations.u_is_text), + 'u_pitch_with_map': new Uniform1i(context, locations.u_pitch_with_map), + 'u_texsize': new Uniform2fv(context, locations.u_texsize), + 'u_texture': new Uniform1i(context, locations.u_texture), + 'u_gamma_scale': new Uniform1f(context, locations.u_gamma_scale), + 'u_is_halo': new Uniform1f(context, locations.u_is_halo) }); const symbolIconUniformValues = ( diff --git a/src/render/uniform_binding.js b/src/render/uniform_binding.js index f329c2d42ee..044250105bc 100644 --- a/src/render/uniform_binding.js +++ b/src/render/uniform_binding.js @@ -15,91 +15,113 @@ export type BinderUniformTypes = any; class Uniform { context: Context; location: ?WebGLUniformLocation; - current: ?T; + current: T; - constructor(context: Context) { + constructor(context: Context, location: WebGLUniformLocation) { this.context = context; + this.location = location; } } class Uniform1i extends Uniform { - set(location: WebGLUniformLocation, v: number): void { - if (this.current !== v || this.location !== location) { + constructor(context: Context, location: WebGLUniformLocation) { + super(context, location); + this.current = 0; + } + + set(v: number): void { + if (this.current !== v) { this.current = v; - this.location = location; - this.context.gl.uniform1i(location, v); + this.context.gl.uniform1i(this.location, v); } } } class Uniform1f extends Uniform { - set(location: WebGLUniformLocation, v: number): void { - if (this.current !== v || this.location !== location) { + constructor(context: Context, location: WebGLUniformLocation) { + super(context, location); + this.current = 0; + } + + set(v: number): void { + if (this.current !== v) { this.current = v; - this.location = location; - this.context.gl.uniform1f(location, v); + this.context.gl.uniform1f(this.location, v); } } } class Uniform2fv extends Uniform<[number, number]> { - set(location: WebGLUniformLocation, v: [number, number]): void { - const c = this.current; - if (!c || v[0] !== c[0] || v[1] !== c[1] || this.location !== location) { + constructor(context: Context, location: WebGLUniformLocation) { + super(context, location); + this.current = [0, 0]; + } + + set(v: [number, number]): void { + if (v[0] !== this.current[0] || v[1] !== this.current[1]) { this.current = v; - this.location = location; - this.context.gl.uniform2f(location, v[0], v[1]); + this.context.gl.uniform2f(this.location, v[0], v[1]); } } } class Uniform3fv extends Uniform<[number, number, number]> { - set(location: WebGLUniformLocation, v: [number, number, number]): void { - const c = this.current; - if (!c || v[0] !== c[0] || v[1] !== c[1] || v[2] !== c[2] || this.location !== location) { + constructor(context: Context, location: WebGLUniformLocation) { + super(context, location); + this.current = [0, 0, 0]; + } + + set(v: [number, number, number]): void { + if (v[0] !== this.current[0] || v[1] !== this.current[1] || v[2] !== this.current[2]) { this.current = v; - this.location = location; - this.context.gl.uniform3f(location, v[0], v[1], v[2]); + this.context.gl.uniform3f(this.location, v[0], v[1], v[2]); } } } -class Uniform4fv extends Uniform<[number, number, number, number] | Color> { - set(location: WebGLUniformLocation, v: [number, number, number, number] | Color): void { - const c = this.current; - if (v instanceof Color && (!c || c instanceof Color)) { - if (!c || v.r !== c.r || v.g !== c.g || v.b !== c.b || v.a !== c.a || this.location !== location) { - this.current = v; - this.location = location; - this.context.gl.uniform4f(location, v.r, v.g, v.b, v.a); - } - } else if (Array.isArray(v) && (!c || Array.isArray(c))) { - if (!c || v[0] !== c[0] || v[1] !== c[1] || v[2] !== c[2] || v[3] !== c[3] || this.location !== location) { - this.current = v; - this.location = location; - this.context.gl.uniform4f(location, v[0], v[1], v[2], v[3]); - } +class Uniform4fv extends Uniform<[number, number, number, number]> { + constructor(context: Context, location: WebGLUniformLocation) { + super(context, location); + this.current = [0, 0, 0, 0]; + } + + set(v: [number, number, number, number]): void { + if (v[0] !== this.current[0] || v[1] !== this.current[1] || + v[2] !== this.current[2] || v[3] !== this.current[3]) { + this.current = v; + this.context.gl.uniform4f(this.location, v[0], v[1], v[2], v[3]); } } } -class UniformMatrix4fv extends Uniform { - set(location: WebGLUniformLocation, v: Float32Array): void { - let diff = !this.current || this.location !== location; - - if (!diff && this.current) { - for (let i = 0; i < 16; i++) { - if (v[i] !== this.current[i]) { - diff = true; - break; - } - } - } +class UniformColor extends Uniform { + constructor(context: Context, location: WebGLUniformLocation) { + super(context, location); + this.current = new Color(0, 0, 0, 0); + } - if (diff) { + set(v: Color): void { + if (v.r !== this.current.r || v.g !== this.current.g || + v.b !== this.current.b || v.a !== this.current.a) { this.current = v; - this.location = location; - this.context.gl.uniformMatrix4fv(location, false, v); + this.context.gl.uniform4f(this.location, v.r, v.g, v.b, v.a); + } + } +} + +class UniformMatrix4fv extends Uniform { + constructor(context: Context, location: WebGLUniformLocation) { + super(context, location); + this.current = new Float32Array(16); + } + + set(v: Float32Array): void { + for (let i = 0; i < 16; i++) { + if (v[i] !== this.current[i]) { + this.current = v; + this.context.gl.uniformMatrix4fv(this.location, false, v); + break; + } } } } @@ -111,10 +133,10 @@ class Uniforms { this.bindings = bindings; } - set(uniformLocations: UniformLocations, uniformValues: UniformValues) { + set(uniformValues: UniformValues) { for (const name in uniformValues) { assert(this.bindings[name], `No binding with name ${name}`); - this.bindings[name].set(uniformLocations[name], uniformValues[name]); + this.bindings[name].set(uniformValues[name]); } } } @@ -126,6 +148,7 @@ export { Uniform2fv, Uniform3fv, Uniform4fv, + UniformColor, UniformMatrix4fv, Uniforms }; diff --git a/test/unit/render/uniform_binding.test.js b/test/unit/render/uniform_binding.test.js index 02b93511c76..f8f16ec04be 100644 --- a/test/unit/render/uniform_binding.test.js +++ b/test/unit/render/uniform_binding.test.js @@ -7,10 +7,6 @@ import { Uniform4fv } from '../../../src/render/uniform_binding'; -function arrEq(a, b) { - return a.every((el, i) => el === b[i]); -} - test('Uniform1i', (t) => { // test counts ensure we don't call the gl.uniform* setters more than expected t.plan(4); @@ -21,13 +17,13 @@ test('Uniform1i', (t) => { } }; - const u = new Uniform1i(context); + const u = new Uniform1i(context, 0); - t.notOk(u.current, 'not set upon initialization'); - u.set(0, 1); + t.equal(u.current, 0, 'not set upon initialization'); + u.set(1); t.equal(u.current, 1, 'correctly set value'); - u.set(0, 1); - u.set(0, 2); + u.set(1); + u.set(2); t.end(); }); @@ -40,13 +36,13 @@ test('Uniform1f', (t) => { } }; - const u = new Uniform1f(context); + const u = new Uniform1f(context, 0); - t.notOk(u.current, 'not set upon initialization'); - u.set(0, 1); + t.equal(u.current, 0, 'not set upon initialization'); + u.set(1); t.equal(u.current, 1, 'correctly set value'); - u.set(0, 1); - u.set(0, 2); + u.set(1); + u.set(2); t.end(); }); @@ -59,13 +55,13 @@ test('Uniform2fv', (t) => { } }; - const u = new Uniform2fv(context); + const u = new Uniform2fv(context, 0); - t.notOk(u.current, 'not set upon initialization'); - u.set(0, [1, 1]); - t.ok(arrEq(u.current, [1, 1]), 'correctly set value'); - u.set(0, [1, 1]); - u.set(0, [1, 2]); + t.deepEqual(u.current, [0, 0], 'not set upon initialization'); + u.set([1, 1]); + t.deepEqual(u.current, [1, 1], 'correctly set value'); + u.set([1, 1]); + u.set([1, 2]); t.end(); }); @@ -78,13 +74,13 @@ test('Uniform3fv', (t) => { } }; - const u = new Uniform3fv(context); + const u = new Uniform3fv(context, 0); - t.notOk(u.current, 'not set upon initialization'); - u.set(0, [1, 1, 1]); - t.ok(arrEq(u.current, [1, 1, 1]), 'correctly set value'); - u.set(0, [1, 1, 1]); - u.set(0, [1, 1, 2]); + t.deepEqual(u.current, [0, 0, 0], 'not set upon initialization'); + u.set([1, 1, 1]); + t.deepEqual(u.current, [1, 1, 1], 'correctly set value'); + u.set([1, 1, 1]); + u.set([1, 1, 2]); t.end(); }); @@ -97,12 +93,12 @@ test('Uniform4fv', (t) => { } }; - const u = new Uniform4fv(context); + const u = new Uniform4fv(context, 0); - t.notOk(u.current, 'not set upon initialization'); - u.set(0, [1, 1, 1, 1]); - t.ok(arrEq(u.current, [1, 1, 1, 1]), 'correctly set value'); - u.set(0, [1, 1, 1, 1]); - u.set(0, [2, 1, 1, 1]); + t.deepEqual(u.current, [0, 0, 0, 0], 'not set upon initialization'); + u.set([1, 1, 1, 1]); + t.deepEqual(u.current, [1, 1, 1, 1], 'correctly set value'); + u.set([1, 1, 1, 1]); + u.set([2, 1, 1, 1]); t.end(); }); From ebb55762368601e8f1f5f331af84860334095cc3 Mon Sep 17 00:00:00 2001 From: Lauren Budorick Date: Mon, 19 Mar 2018 13:53:02 -0700 Subject: [PATCH 04/11] Check for most commonly divergent matrix indices first --- src/render/uniform_binding.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/render/uniform_binding.js b/src/render/uniform_binding.js index 044250105bc..c1d2666377f 100644 --- a/src/render/uniform_binding.js +++ b/src/render/uniform_binding.js @@ -97,7 +97,7 @@ class Uniform4fv extends Uniform<[number, number, number, number]> { class UniformColor extends Uniform { constructor(context: Context, location: WebGLUniformLocation) { super(context, location); - this.current = new Color(0, 0, 0, 0); + this.current = Color.transparent; } set(v: Color): void { @@ -109,14 +109,23 @@ class UniformColor extends Uniform { } } +const emptyMat4 = new Float32Array(16); class UniformMatrix4fv extends Uniform { constructor(context: Context, location: WebGLUniformLocation) { super(context, location); - this.current = new Float32Array(16); + this.current = emptyMat4; } set(v: Float32Array): void { - for (let i = 0; i < 16; i++) { + // The vast majority of matrix comparisons that will trip this set + // happen at i=12 or i=0, so we check those first to avoid lots of + // unnecessary iteration: + if (v[12] !== this.current[12] || v[0] !== this.current[0]) { + this.current = v; + this.context.gl.uniformMatrix4fv(this.location, false, v); + return; + } + for (let i = 1; i < 16; i++) { if (v[i] !== this.current[i]) { this.current = v; this.context.gl.uniformMatrix4fv(this.location, false, v); From dd5d5c8a791bf6e131f6b947444275f247395c19 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 19 Mar 2018 13:36:49 -0700 Subject: [PATCH 05/11] Inline Uniforms class --- src/data/program_configuration.js | 12 ++++----- src/render/program.js | 15 +++++------ src/render/program/background_program.js | 7 +++--- src/render/program/circle_program.js | 5 ++-- src/render/program/clipping_mask_program.js | 4 +-- src/render/program/collision_program.js | 5 ++-- src/render/program/debug_program.js | 5 ++-- src/render/program/fill_extrusion_program.js | 9 +++---- src/render/program/fill_program.js | 11 ++++----- src/render/program/heatmap_program.js | 7 +++--- src/render/program/hillshade_program.js | 7 +++--- src/render/program/line_program.js | 11 ++++----- src/render/program/raster_program.js | 5 ++-- src/render/program/symbol_program.js | 7 +++--- src/render/uniform_binding.js | 26 ++++---------------- 15 files changed, 55 insertions(+), 81 deletions(-) diff --git a/src/data/program_configuration.js b/src/data/program_configuration.js index 835481800a5..0fe8a781be4 100644 --- a/src/data/program_configuration.js +++ b/src/data/program_configuration.js @@ -7,7 +7,7 @@ import { register } from '../util/web_worker_transfer'; import { PossiblyEvaluatedPropertyValue } from '../style/properties'; import { StructArrayLayout1f4, StructArrayLayout2f8, StructArrayLayout4f16 } from './array_types'; import EvaluationParameters from '../style/evaluation_parameters'; -import { Uniform, Uniform1f, UniformColor, Uniforms } from '../render/uniform_binding'; +import { Uniform, Uniform1f, UniformColor } from '../render/uniform_binding'; import type Context from '../gl/context'; import type {TypedStyleLayer} from '../style/style_layer/typed_style_layer'; @@ -108,7 +108,7 @@ class ConstantBinder implements Binder { setUniforms(context: Context, program: Program<*>, globals: GlobalProperties, currentValue: PossiblyEvaluatedPropertyValue): void { const value = currentValue.constantOr(this.value); - program.binderUniforms.bindings[this.uniformName].set(value); + program.binderUniforms[this.uniformName].set(value); } getBinding(context: Context, location: WebGLUniformLocation): $Subtype> { @@ -206,7 +206,7 @@ class SourceExpressionBinder implements Binder { } setUniforms(context: Context, program: Program<*>): void { - program.binderUniforms.bindings[this.uniformName].set(0); + program.binderUniforms[this.uniformName].set(0); } getBinding(context: Context, location: WebGLUniformLocation): Uniform1f { @@ -320,7 +320,7 @@ class CompositeExpressionBinder implements Binder { setUniforms(context: Context, program: Program<*>, globals: GlobalProperties): void { - program.binderUniforms.bindings[this.uniformName].set(this.interpolationFactor(globals.zoom)); + program.binderUniforms[this.uniformName].set(this.interpolationFactor(globals.zoom)); } getBinding(context: Context, location: WebGLUniformLocation): Uniform1f { @@ -455,10 +455,10 @@ export default class ProgramConfiguration { } getUniforms(context: Context, program: Program<*>): void { - program.binderUniforms = new Uniforms({}); + program.binderUniforms = {}; for (const property in this.binders) { const binder = this.binders[property]; - program.binderUniforms.bindings[binder.uniformName] = + program.binderUniforms[binder.uniformName] = binder.getBinding(context, program.uniforms[binder.uniformName]); } } diff --git a/src/render/program.js b/src/render/program.js index 0f380f2654d..1d9f0dfbde9 100644 --- a/src/render/program.js +++ b/src/render/program.js @@ -7,7 +7,6 @@ import assert from 'assert'; import ProgramConfiguration from '../data/program_configuration'; import VertexArrayObject from './vertex_array_object'; import Context from '../gl/context'; -import { Uniforms } from './uniform_binding'; import type SegmentVector from '../data/segment'; import type VertexBuffer from '../gl/vertex_buffer'; @@ -15,7 +14,7 @@ import type IndexBuffer from '../gl/index_buffer'; import type DepthMode from '../gl/depth_mode'; import type StencilMode from '../gl/stencil_mode'; import type ColorMode from '../gl/color_mode'; -import type {UniformBindings, UniformValues, UniformLocations, BinderUniformTypes} from './uniform_binding'; +import type {UniformBindings, UniformValues, UniformLocations} from './uniform_binding'; export type DrawMode = | $PropertyType @@ -27,14 +26,13 @@ class Program { uniforms: UniformLocations; attributes: {[string]: number}; numAttributes: number; - fixedUniforms: Uniforms; - binderUniforms: Uniforms; - configuration: ProgramConfiguration; + fixedUniforms: Us; + binderUniforms: UniformBindings; constructor(context: Context, source: {fragmentSource: string, vertexSource: string}, configuration: ProgramConfiguration, - fixedUniforms: (Context, UniformLocations) => Uniforms, + fixedUniforms: (Context, UniformLocations) => Us, showOverdrawInspector: boolean) { const gl = context.gl; this.program = gl.createProgram(); @@ -118,7 +116,10 @@ class Program { context.setStencilMode(stencilMode); context.setColorMode(colorMode); - this.fixedUniforms.set(uniformValues); + for (const name in this.fixedUniforms) { + this.fixedUniforms[name].set(uniformValues[name]); + } + if (configuration) { configuration.setUniforms(context, this, currentProperties, {zoom: (zoom: any)}); } diff --git a/src/render/program/background_program.js b/src/render/program/background_program.js index 69c7b05ad28..fbcc6d70de6 100644 --- a/src/render/program/background_program.js +++ b/src/render/program/background_program.js @@ -6,8 +6,7 @@ import { Uniform1f, Uniform2fv, UniformColor, - UniformMatrix4fv, - Uniforms + UniformMatrix4fv } from '../uniform_binding'; import { extend } from '../../util/util'; @@ -44,13 +43,13 @@ export type BackgroundPatternUniformsType = {| 'u_tile_units_to_pixels': Uniform1f |}; -const backgroundUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ +const backgroundUniforms = (context: Context, locations: UniformLocations): BackgroundUniformsType => ({ 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), 'u_opacity': new Uniform1f(context, locations.u_opacity), 'u_color': new UniformColor(context, locations.u_color) }); -const backgroundPatternUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ +const backgroundPatternUniforms = (context: Context, locations: UniformLocations): BackgroundPatternUniformsType => ({ 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), 'u_opacity': new Uniform1f(context, locations.u_opacity), 'u_image': new Uniform1i(context, locations.u_image), diff --git a/src/render/program/circle_program.js b/src/render/program/circle_program.js index 94795ecc452..30a4c2bce1b 100644 --- a/src/render/program/circle_program.js +++ b/src/render/program/circle_program.js @@ -4,8 +4,7 @@ import { Uniform1i, Uniform1f, Uniform2fv, - UniformMatrix4fv, - Uniforms + UniformMatrix4fv } from '../uniform_binding'; import pixelsToTileUnits from '../../source/pixels_to_tile_units'; @@ -24,7 +23,7 @@ export type CircleUniformsType = {| 'u_matrix': UniformMatrix4fv |}; -const circleUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ +const circleUniforms = (context: Context, locations: UniformLocations): CircleUniformsType => ({ 'u_camera_to_center_distance': new Uniform1f(context, locations.u_camera_to_center_distance), 'u_scale_with_map': new Uniform1i(context, locations.u_scale_with_map), 'u_pitch_with_map': new Uniform1i(context, locations.u_pitch_with_map), diff --git a/src/render/program/clipping_mask_program.js b/src/render/program/clipping_mask_program.js index f2b9daca6fd..e8e2d9708b8 100644 --- a/src/render/program/clipping_mask_program.js +++ b/src/render/program/clipping_mask_program.js @@ -1,6 +1,6 @@ // @flow -import { UniformMatrix4fv, Uniforms } from '../uniform_binding'; +import { UniformMatrix4fv } from '../uniform_binding'; import type Context from '../../gl/context'; import type {UniformValues, UniformLocations} from '../uniform_binding'; @@ -9,7 +9,7 @@ export type ClippingMaskUniformsType = {| 'u_matrix': UniformMatrix4fv |}; -const clippingMaskUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ +const clippingMaskUniforms = (context: Context, locations: UniformLocations): ClippingMaskUniformsType => ({ 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix) }); diff --git a/src/render/program/collision_program.js b/src/render/program/collision_program.js index f9ac480d4f0..5dec2e8fac8 100644 --- a/src/render/program/collision_program.js +++ b/src/render/program/collision_program.js @@ -3,8 +3,7 @@ import { Uniform1f, Uniform2fv, - UniformMatrix4fv, - Uniforms + UniformMatrix4fv } from '../uniform_binding'; import pixelsToTileUnits from '../../source/pixels_to_tile_units'; @@ -21,7 +20,7 @@ export type CollisionUniformsType = {| 'u_overscale_factor': Uniform1f |}; -const collisionUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ +const collisionUniforms = (context: Context, locations: UniformLocations): CollisionUniformsType => ({ 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), 'u_camera_to_center_distance': new Uniform1f(context, locations.u_camera_to_center_distance), 'u_pixels_to_tile_units': new Uniform1f(context, locations.u_pixels_to_tile_units), diff --git a/src/render/program/debug_program.js b/src/render/program/debug_program.js index 3629b126ca0..9a023c1d86a 100644 --- a/src/render/program/debug_program.js +++ b/src/render/program/debug_program.js @@ -2,8 +2,7 @@ import { UniformColor, - UniformMatrix4fv, - Uniforms + UniformMatrix4fv } from '../uniform_binding'; import type Context from '../../gl/context'; @@ -15,7 +14,7 @@ export type DebugUniformsType = {| 'u_matrix': UniformMatrix4fv |}; -const debugUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ +const debugUniforms = (context: Context, locations: UniformLocations): DebugUniformsType => ({ 'u_color': new UniformColor(context, locations.u_color), 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix) }); diff --git a/src/render/program/fill_extrusion_program.js b/src/render/program/fill_extrusion_program.js index de3bf0ab181..3df9953ed53 100644 --- a/src/render/program/fill_extrusion_program.js +++ b/src/render/program/fill_extrusion_program.js @@ -6,8 +6,7 @@ import { Uniform1f, Uniform2fv, Uniform3fv, - UniformMatrix4fv, - Uniforms + UniformMatrix4fv } from '../uniform_binding'; import {mat3, vec3, mat4} from 'gl-matrix'; @@ -57,14 +56,14 @@ export type ExtrusionTextureUniformsType = {| 'u_opacity': Uniform1f |}; -const fillExtrusionUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ +const fillExtrusionUniforms = (context: Context, locations: UniformLocations): FillExtrusionUniformsType => ({ 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), 'u_lightpos': new Uniform3fv(context, locations.u_lightpos), 'u_lightintensity': new Uniform1f(context, locations.u_lightintensity), 'u_lightcolor': new Uniform3fv(context, locations.u_lightcolor) }); -const fillExtrusionPatternUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ +const fillExtrusionPatternUniforms = (context: Context, locations: UniformLocations): FillExtrusionPatternUniformsType => ({ 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), 'u_lightpos': new Uniform3fv(context, locations.u_lightpos), 'u_lightintensity': new Uniform1f(context, locations.u_lightintensity), @@ -86,7 +85,7 @@ const fillExtrusionPatternUniforms = (context: Context, locations: UniformLocati 'u_tile_units_to_pixels': new Uniform1f(context, locations.u_tile_units_to_pixels) }); -const extrusionTextureUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ +const extrusionTextureUniforms = (context: Context, locations: UniformLocations): ExtrusionTextureUniformsType => ({ 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), 'u_world': new Uniform2fv(context, locations.u_world), 'u_image': new Uniform1i(context, locations.u_image), diff --git a/src/render/program/fill_program.js b/src/render/program/fill_program.js index f3027346be6..3e7a225d890 100644 --- a/src/render/program/fill_program.js +++ b/src/render/program/fill_program.js @@ -5,8 +5,7 @@ import { Uniform1i, Uniform1f, Uniform2fv, - UniformMatrix4fv, - Uniforms + UniformMatrix4fv } from '../uniform_binding'; import { extend } from '../../util/util'; @@ -64,11 +63,11 @@ export type FillOutlinePatternUniformsType = {| 'u_tile_units_to_pixels': Uniform1f |}; -const fillUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ +const fillUniforms = (context: Context, locations: UniformLocations): FillUniformsType => ({ 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix) }); -const fillPatternUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ +const fillPatternUniforms = (context: Context, locations: UniformLocations): FillPatternUniformsType => ({ 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), 'u_image': new Uniform1i(context, locations.u_image), 'u_pattern_tl_a': new Uniform2fv(context, locations.u_pattern_tl_a), @@ -86,12 +85,12 @@ const fillPatternUniforms = (context: Context, locations: UniformLocations): Uni 'u_tile_units_to_pixels': new Uniform1f(context, locations.u_tile_units_to_pixels) }); -const fillOutlineUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ +const fillOutlineUniforms = (context: Context, locations: UniformLocations): FillOutlineUniformsType => ({ 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), 'u_world': new Uniform2fv(context, locations.u_world) }); -const fillOutlinePatternUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ +const fillOutlinePatternUniforms = (context: Context, locations: UniformLocations): FillOutlinePatternUniformsType => ({ 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), 'u_world': new Uniform2fv(context, locations.u_world), 'u_image': new Uniform1i(context, locations.u_image), diff --git a/src/render/program/heatmap_program.js b/src/render/program/heatmap_program.js index 6024b98643e..b93cccbd29c 100644 --- a/src/render/program/heatmap_program.js +++ b/src/render/program/heatmap_program.js @@ -6,8 +6,7 @@ import { Uniform1i, Uniform1f, Uniform2fv, - UniformMatrix4fv, - Uniforms + UniformMatrix4fv } from '../uniform_binding'; import pixelsToTileUnits from '../../source/pixels_to_tile_units'; @@ -31,13 +30,13 @@ export type HeatmapTextureUniformsType = {| 'u_opacity': Uniform1f |}; -const heatmapUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ +const heatmapUniforms = (context: Context, locations: UniformLocations): HeatmapUniformsType => ({ 'u_extrude_scale': new Uniform1f(context, locations.u_extrude_scale), 'u_intensity': new Uniform1f(context, locations.u_intensity), 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix) }); -const heatmapTextureUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ +const heatmapTextureUniforms = (context: Context, locations: UniformLocations): HeatmapTextureUniformsType => ({ 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), 'u_world': new Uniform2fv(context, locations.u_world), 'u_image': new Uniform1i(context, locations.u_image), diff --git a/src/render/program/hillshade_program.js b/src/render/program/hillshade_program.js index 0450f7e08ce..12cdd9802b0 100644 --- a/src/render/program/hillshade_program.js +++ b/src/render/program/hillshade_program.js @@ -8,8 +8,7 @@ import { Uniform1f, Uniform2fv, UniformColor, - UniformMatrix4fv, - Uniforms + UniformMatrix4fv } from '../uniform_binding'; import EXTENT from '../../data/extent'; import Coordinate from '../../geo/coordinate'; @@ -40,7 +39,7 @@ export type HillshadePrepareUniformsType = {| 'u_maxzoom': Uniform1f |}; -const hillshadeUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ +const hillshadeUniforms = (context: Context, locations: UniformLocations): HillshadeUniformsType => ({ 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), 'u_image': new Uniform1i(context, locations.u_image), 'u_latrange': new Uniform2fv(context, locations.u_latrange), @@ -50,7 +49,7 @@ const hillshadeUniforms = (context: Context, locations: UniformLocations): Unifo 'u_accent': new UniformColor(context, locations.u_accent) }); -const hillshadePrepareUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ +const hillshadePrepareUniforms = (context: Context, locations: UniformLocations): HillshadePrepareUniformsType => ({ 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), 'u_image': new Uniform1i(context, locations.u_image), 'u_dimension': new Uniform2fv(context, locations.u_dimension), diff --git a/src/render/program/line_program.js b/src/render/program/line_program.js index 66a230aaccd..cf278a7cf7c 100644 --- a/src/render/program/line_program.js +++ b/src/render/program/line_program.js @@ -4,8 +4,7 @@ import { Uniform1i, Uniform1f, Uniform2fv, - UniformMatrix4fv, - Uniforms + UniformMatrix4fv } from '../uniform_binding'; import pixelsToTileUnits from '../../source/pixels_to_tile_units'; import { extend } from '../../util/util'; @@ -60,20 +59,20 @@ export type LineSDFUniformsType = {| 'u_mix': Uniform1f |}; -const lineUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ +const lineUniforms = (context: Context, locations: UniformLocations): LineUniformsType => ({ 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), 'u_ratio': new Uniform1f(context, locations.u_ratio), 'u_gl_units_to_pixels': new Uniform2fv(context, locations.u_gl_units_to_pixels) }); -const lineGradientUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ +const lineGradientUniforms = (context: Context, locations: UniformLocations): LineGradientUniformsType => ({ 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), 'u_ratio': new Uniform1f(context, locations.u_ratio), 'u_gl_units_to_pixels': new Uniform2fv(context, locations.u_gl_units_to_pixels), 'u_image': new Uniform1i(context, locations.u_image) }); -const linePatternUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ +const linePatternUniforms = (context: Context, locations: UniformLocations): LinePatternUniformsType => ({ 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), 'u_ratio': new Uniform1f(context, locations.u_ratio), 'u_gl_units_to_pixels': new Uniform2fv(context, locations.u_gl_units_to_pixels), @@ -88,7 +87,7 @@ const linePatternUniforms = (context: Context, locations: UniformLocations): Uni 'u_fade': new Uniform1f(context, locations.u_fade) }); -const lineSDFUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ +const lineSDFUniforms = (context: Context, locations: UniformLocations): LineSDFUniformsType => ({ 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), 'u_ratio': new Uniform1f(context, locations.u_ratio), 'u_gl_units_to_pixels': new Uniform2fv(context, locations.u_gl_units_to_pixels), diff --git a/src/render/program/raster_program.js b/src/render/program/raster_program.js index ef99cdae876..48ebb145553 100644 --- a/src/render/program/raster_program.js +++ b/src/render/program/raster_program.js @@ -5,8 +5,7 @@ import { Uniform1f, Uniform2fv, Uniform3fv, - UniformMatrix4fv, - Uniforms + UniformMatrix4fv } from '../uniform_binding'; import type Context from '../../gl/context'; @@ -29,7 +28,7 @@ export type RasterUniformsType = {| 'u_spin_weights': Uniform3fv |}; -const rasterUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ +const rasterUniforms = (context: Context, locations: UniformLocations): RasterUniformsType => ({ 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), 'u_tl_parent': new Uniform2fv(context, locations.u_tl_parent), 'u_scale_parent': new Uniform1f(context, locations.u_scale_parent), diff --git a/src/render/program/symbol_program.js b/src/render/program/symbol_program.js index 8119291fbe0..97d7f6ea4b0 100644 --- a/src/render/program/symbol_program.js +++ b/src/render/program/symbol_program.js @@ -4,8 +4,7 @@ import { Uniform1i, Uniform1f, Uniform2fv, - UniformMatrix4fv, - Uniforms + UniformMatrix4fv } from '../uniform_binding'; import { extend } from '../../util/util'; @@ -53,7 +52,7 @@ export type SymbolSDFUniformsType = {| 'u_is_halo': Uniform1f |}; -const symbolIconUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ +const symbolIconUniforms = (context: Context, locations: UniformLocations): SymbolIconUniformsType => ({ 'u_is_size_zoom_constant': new Uniform1i(context, locations.u_is_size_zoom_constant), 'u_is_size_feature_constant': new Uniform1i(context, locations.u_is_size_feature_constant), 'u_size_t': new Uniform1f(context, locations.u_size_t), @@ -72,7 +71,7 @@ const symbolIconUniforms = (context: Context, locations: UniformLocations): Unif 'u_texture': new Uniform1i(context, locations.u_texture) }); -const symbolSDFUniforms = (context: Context, locations: UniformLocations): Uniforms => new Uniforms({ +const symbolSDFUniforms = (context: Context, locations: UniformLocations): SymbolSDFUniformsType => ({ 'u_is_size_zoom_constant': new Uniform1i(context, locations.u_is_size_zoom_constant), 'u_is_size_feature_constant': new Uniform1i(context, locations.u_is_size_feature_constant), 'u_size_t': new Uniform1f(context, locations.u_size_t), diff --git a/src/render/uniform_binding.js b/src/render/uniform_binding.js index c1d2666377f..0840a8fe588 100644 --- a/src/render/uniform_binding.js +++ b/src/render/uniform_binding.js @@ -1,6 +1,5 @@ // @flow -import assert from 'assert'; import Color from '../style-spec/util/color'; import type Context from '../gl/context'; @@ -8,9 +7,6 @@ import type Context from '../gl/context'; export type UniformValues = $Exact<$ObjMap(u: Uniform) => V>>; export type UniformLocations = {[string]: WebGLUniformLocation}; -export type UniformBindings = {[string]: any}; -// binder uniforms are dynamically created: -export type BinderUniformTypes = any; class Uniform { context: Context; @@ -21,6 +17,8 @@ class Uniform { this.context = context; this.location = location; } + + +set: (v: T) => void; } class Uniform1i extends Uniform { @@ -135,21 +133,6 @@ class UniformMatrix4fv extends Uniform { } } -class Uniforms { - bindings: Us; - - constructor(bindings: Us) { - this.bindings = bindings; - } - - set(uniformValues: UniformValues) { - for (const name in uniformValues) { - assert(this.bindings[name], `No binding with name ${name}`); - this.bindings[name].set(uniformValues[name]); - } - } -} - export { Uniform, Uniform1i, @@ -158,6 +141,7 @@ export { Uniform3fv, Uniform4fv, UniformColor, - UniformMatrix4fv, - Uniforms + UniformMatrix4fv }; + +export type UniformBindings = {[string]: Uniform}; From 8c8f9f8bc7c4d891df12c7e8ba47d044d82002c3 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 19 Mar 2018 13:39:11 -0700 Subject: [PATCH 06/11] Inline drawLineTile and hoist loop invariant code --- src/render/draw_line.js | 78 ++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 40 deletions(-) diff --git a/src/render/draw_line.js b/src/render/draw_line.js index 1abbbf43248..057f792164f 100644 --- a/src/render/draw_line.js +++ b/src/render/draw_line.js @@ -25,13 +25,31 @@ export default function drawLine(painter: Painter, sourceCache: SourceCache, lay const depthMode = painter.depthModeForSublayer(0, DepthMode.ReadOnly); const colorMode = painter.colorModeForRenderPass(); + const dasharray = layer.paint.get('line-dasharray'); + const image = layer.paint.get('line-pattern'); + const gradient = layer.paint.get('line-gradient'); + + if (painter.isPatternMissing(image)) return; + const programId = - layer.paint.get('line-dasharray') ? 'lineSDF' : - layer.paint.get('line-pattern') ? 'linePattern' : - layer.paint.get('line-gradient') ? 'lineGradient' : 'line'; + dasharray ? 'lineSDF' : + image ? 'linePattern' : + gradient ? 'lineGradient' : 'line'; + + const context = painter.context; + const gl = context.gl; let firstTile = true; + if (gradient) { + context.activeTexture.set(gl.TEXTURE0); + + let gradientTexture = layer.gradientTexture; + if (!layer.gradient) return; + if (!gradientTexture) gradientTexture = layer.gradientTexture = new Texture(context, layer.gradient, gl.RGBA); + gradientTexture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE); + } + for (const coord of coords) { const tile = sourceCache.getTile(coord); const bucket: ?LineBucket = (tile.getBucket(layer): any); @@ -42,45 +60,25 @@ export default function drawLine(painter: Painter, sourceCache: SourceCache, lay const program = painter.useProgram(programId, programConfiguration); const programChanged = firstTile || program.program !== prevProgram; - drawLineTile(program, painter, tile, bucket, layer, coord, depthMode, colorMode, programConfiguration, programChanged); - firstTile = false; - // once refactored so that bound texture state is managed, we'll also be able to remove this firstTile/programChanged logic - } -} + if (dasharray && (programChanged || painter.lineAtlas.dirty)) { + context.activeTexture.set(gl.TEXTURE0); + painter.lineAtlas.bind(context); + } else if (image && (programChanged || painter.imageManager.dirty)) { + context.activeTexture.set(gl.TEXTURE0); + painter.imageManager.bind(context); + } -function drawLineTile(program, painter, tile, bucket, layer, coord, depthMode, colorMode, programConfiguration, programChanged) { - const context = painter.context; - const gl = context.gl; - const dasharray = layer.paint.get('line-dasharray'); - const image = layer.paint.get('line-pattern'); - const gradient = layer.paint.get('line-gradient'); + const uniformValues = dasharray ? lineSDFUniformValues(painter, tile, layer, dasharray) : + image ? linePatternUniformValues(painter, tile, layer, image) : + gradient ? lineGradientUniformValues(painter, tile, layer) : + lineUniformValues(painter, tile, layer); - if (painter.isPatternMissing(image)) return; - - const uniformValues = dasharray ? lineSDFUniformValues(painter, tile, layer, dasharray) : - image ? linePatternUniformValues(painter, tile, layer, image) : - gradient ? lineGradientUniformValues(painter, tile, layer) : - lineUniformValues(painter, tile, layer); - - if (dasharray && (programChanged || painter.lineAtlas.dirty)) { - context.activeTexture.set(gl.TEXTURE0); - painter.lineAtlas.bind(context); - } else if (image && (programChanged || painter.imageManager.dirty)) { - context.activeTexture.set(gl.TEXTURE0); - painter.imageManager.bind(context); - } + program.draw(context, gl.TRIANGLES, depthMode, + painter.stencilModeForClipping(coord), colorMode, uniformValues, + layer.id, bucket.layoutVertexBuffer, bucket.indexBuffer, bucket.segments, + layer.paint, painter.transform.zoom, programConfiguration); - if (gradient) { - context.activeTexture.set(gl.TEXTURE0); - - let gradientTexture = layer.gradientTexture; - if (!layer.gradient) return; - if (!gradientTexture) gradientTexture = layer.gradientTexture = new Texture(context, layer.gradient, gl.RGBA); - gradientTexture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE); + firstTile = false; + // once refactored so that bound texture state is managed, we'll also be able to remove this firstTile/programChanged logic } - - program.draw(context, gl.TRIANGLES, depthMode, - painter.stencilModeForClipping(coord), colorMode, uniformValues, - layer.id, bucket.layoutVertexBuffer, bucket.indexBuffer, bucket.segments, - layer.paint, painter.transform.zoom, programConfiguration); } From 4541c227a99a0f5c15d7feccde607079882f2fa9 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 19 Mar 2018 13:40:23 -0700 Subject: [PATCH 07/11] Set GL program state inside Program#draw --- src/render/painter.js | 10 +--------- src/render/program.js | 1 + 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/render/painter.js b/src/render/painter.js index 762ef404b02..cae8202c160 100644 --- a/src/render/painter.js +++ b/src/render/painter.js @@ -473,7 +473,7 @@ class Painter { return !imagePosA || !imagePosB; } - _createProgramCached(name: string, programConfiguration: ProgramConfiguration): Program { + useProgram(name: string, programConfiguration: ProgramConfiguration = this.emptyProgramConfiguration): Program { this.cache = this.cache || {}; const key = `${name}${programConfiguration.cacheKey || ''}${this._showOverdrawInspector ? '/overdraw' : ''}`; if (!this.cache[key]) { @@ -481,14 +481,6 @@ class Painter { } return this.cache[key]; } - - useProgram(name: string, programConfiguration?: ProgramConfiguration): Program { - const nextProgram = this._createProgramCached(name, programConfiguration || this.emptyProgramConfiguration); - - this.context.program.set(nextProgram.program); - - return nextProgram; - } } export default Painter; diff --git a/src/render/program.js b/src/render/program.js index 1d9f0dfbde9..5576d59f631 100644 --- a/src/render/program.js +++ b/src/render/program.js @@ -112,6 +112,7 @@ class Program { const gl = context.gl; + context.program.set(this.program); context.setDepthMode(depthMode); context.setStencilMode(stencilMode); context.setColorMode(colorMode); From 0791813fc83e98520b14cb2374bff0685930ef29 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 19 Mar 2018 14:01:17 -0700 Subject: [PATCH 08/11] Break cyclic dependency between Program and ProgramConfiguration --- src/data/program_configuration.js | 38 +++++++++++++++++-------------- src/render/program.js | 11 ++++----- 2 files changed, 26 insertions(+), 23 deletions(-) diff --git a/src/data/program_configuration.js b/src/data/program_configuration.js index 0fe8a781be4..91251d04bf2 100644 --- a/src/data/program_configuration.js +++ b/src/data/program_configuration.js @@ -7,13 +7,18 @@ import { register } from '../util/web_worker_transfer'; import { PossiblyEvaluatedPropertyValue } from '../style/properties'; import { StructArrayLayout1f4, StructArrayLayout2f8, StructArrayLayout4f16 } from './array_types'; import EvaluationParameters from '../style/evaluation_parameters'; -import { Uniform, Uniform1f, UniformColor } from '../render/uniform_binding'; +import { + Uniform, + Uniform1f, + UniformColor, + type UniformBindings, + type UniformLocations +} from '../render/uniform_binding'; import type Context from '../gl/context'; import type {TypedStyleLayer} from '../style/style_layer/typed_style_layer'; import type {StructArray, StructArrayMember} from '../util/struct_array'; import type VertexBuffer from '../gl/vertex_buffer'; -import type Program from '../render/program'; import type { Feature, FeatureState, @@ -75,7 +80,7 @@ interface Binder { defines(): Array; - setUniforms(context: Context, program: Program<*>, globals: GlobalProperties, + setUniforms(context: Context, uniform: Uniform<*>, globals: GlobalProperties, currentValue: PossiblyEvaluatedPropertyValue): void; getBinding(context: Context, location: WebGLUniformLocation): $Subtype>; @@ -105,10 +110,9 @@ class ConstantBinder implements Binder { upload() {} destroy() {} - setUniforms(context: Context, program: Program<*>, globals: GlobalProperties, + setUniforms(context: Context, uniform: Uniform<*>, globals: GlobalProperties, currentValue: PossiblyEvaluatedPropertyValue): void { - const value = currentValue.constantOr(this.value); - program.binderUniforms[this.uniformName].set(value); + uniform.set(currentValue.constantOr(this.value)); } getBinding(context: Context, location: WebGLUniformLocation): $Subtype> { @@ -205,8 +209,8 @@ class SourceExpressionBinder implements Binder { } } - setUniforms(context: Context, program: Program<*>): void { - program.binderUniforms[this.uniformName].set(0); + setUniforms(context: Context, uniform: Uniform<*>): void { + uniform.set(0); } getBinding(context: Context, location: WebGLUniformLocation): Uniform1f { @@ -318,9 +322,9 @@ class CompositeExpressionBinder implements Binder { } } - setUniforms(context: Context, program: Program<*>, + setUniforms(context: Context, uniform: Uniform<*>, globals: GlobalProperties): void { - program.binderUniforms[this.uniformName].set(this.interpolationFactor(globals.zoom)); + uniform.set(this.interpolationFactor(globals.zoom)); } getBinding(context: Context, location: WebGLUniformLocation): Uniform1f { @@ -352,7 +356,6 @@ export default class ProgramConfiguration { binders: { [string]: Binder }; cacheKey: string; layoutAttributes: Array; - program: ?Program<*>; _buffers: Array; @@ -454,21 +457,22 @@ export default class ProgramConfiguration { return this._buffers; } - getUniforms(context: Context, program: Program<*>): void { - program.binderUniforms = {}; + getUniforms(context: Context, locations: UniformLocations): UniformBindings { + const result = {}; for (const property in this.binders) { const binder = this.binders[property]; - program.binderUniforms[binder.uniformName] = - binder.getBinding(context, program.uniforms[binder.uniformName]); + result[binder.uniformName] = binder.getBinding(context, locations[binder.uniformName]); } + return result; } - setUniforms(context: Context, program: Program<*>, properties: PossiblyEvaluated, globals: GlobalProperties) { + setUniforms(context: Context, uniformBindings: UniformBindings, properties: PossiblyEvaluated, globals: GlobalProperties) { // Uniform state bindings are owned by the Program, but we set them // from within the ProgramConfiguraton's binder members. for (const property in this.binders) { - this.binders[property].setUniforms(context, program, globals, properties.get(property)); + const binder = this.binders[property]; + binder.setUniforms(context, uniformBindings[binder.uniformName], globals, properties.get(property)); } } diff --git a/src/render/program.js b/src/render/program.js index 5576d59f631..44ec70c9331 100644 --- a/src/render/program.js +++ b/src/render/program.js @@ -23,7 +23,6 @@ export type DrawMode = class Program { program: WebGLProgram; - uniforms: UniformLocations; attributes: {[string]: number}; numAttributes: number; fixedUniforms: Us; @@ -73,7 +72,7 @@ class Program { this.numAttributes = gl.getProgramParameter(this.program, gl.ACTIVE_ATTRIBUTES); this.attributes = {}; - this.uniforms = {}; + const uniformLocations = {}; for (let i = 0; i < this.numAttributes; i++) { const attribute = gl.getActiveAttrib(this.program, i); @@ -86,12 +85,12 @@ class Program { for (let i = 0; i < numUniforms; i++) { const uniform = gl.getActiveUniform(this.program, i); if (uniform) { - this.uniforms[uniform.name] = gl.getUniformLocation(this.program, uniform.name); + uniformLocations[uniform.name] = gl.getUniformLocation(this.program, uniform.name); } } - this.fixedUniforms = fixedUniforms(context, this.uniforms); - configuration.getUniforms(context, (this: any)); + this.fixedUniforms = fixedUniforms(context, uniformLocations); + this.binderUniforms = configuration.getUniforms(context, uniformLocations); } draw(context: Context, @@ -122,7 +121,7 @@ class Program { } if (configuration) { - configuration.setUniforms(context, this, currentProperties, {zoom: (zoom: any)}); + configuration.setUniforms(context, this.binderUniforms, currentProperties, {zoom: (zoom: any)}); } const primitiveSize = { From ae87c35f4d8f465ac3fb310382f87c957280bf72 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 19 Mar 2018 14:13:47 -0700 Subject: [PATCH 09/11] Cache gl property --- src/render/uniform_binding.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/render/uniform_binding.js b/src/render/uniform_binding.js index 0840a8fe588..31960458b28 100644 --- a/src/render/uniform_binding.js +++ b/src/render/uniform_binding.js @@ -9,12 +9,12 @@ export type UniformValues export type UniformLocations = {[string]: WebGLUniformLocation}; class Uniform { - context: Context; + gl: WebGLRenderingContext; location: ?WebGLUniformLocation; current: T; constructor(context: Context, location: WebGLUniformLocation) { - this.context = context; + this.gl = context.gl; this.location = location; } @@ -30,7 +30,7 @@ class Uniform1i extends Uniform { set(v: number): void { if (this.current !== v) { this.current = v; - this.context.gl.uniform1i(this.location, v); + this.gl.uniform1i(this.location, v); } } } @@ -44,7 +44,7 @@ class Uniform1f extends Uniform { set(v: number): void { if (this.current !== v) { this.current = v; - this.context.gl.uniform1f(this.location, v); + this.gl.uniform1f(this.location, v); } } } @@ -58,7 +58,7 @@ class Uniform2fv extends Uniform<[number, number]> { set(v: [number, number]): void { if (v[0] !== this.current[0] || v[1] !== this.current[1]) { this.current = v; - this.context.gl.uniform2f(this.location, v[0], v[1]); + this.gl.uniform2f(this.location, v[0], v[1]); } } } @@ -72,7 +72,7 @@ class Uniform3fv extends Uniform<[number, number, number]> { set(v: [number, number, number]): void { if (v[0] !== this.current[0] || v[1] !== this.current[1] || v[2] !== this.current[2]) { this.current = v; - this.context.gl.uniform3f(this.location, v[0], v[1], v[2]); + this.gl.uniform3f(this.location, v[0], v[1], v[2]); } } } @@ -87,7 +87,7 @@ class Uniform4fv extends Uniform<[number, number, number, number]> { if (v[0] !== this.current[0] || v[1] !== this.current[1] || v[2] !== this.current[2] || v[3] !== this.current[3]) { this.current = v; - this.context.gl.uniform4f(this.location, v[0], v[1], v[2], v[3]); + this.gl.uniform4f(this.location, v[0], v[1], v[2], v[3]); } } } @@ -102,7 +102,7 @@ class UniformColor extends Uniform { if (v.r !== this.current.r || v.g !== this.current.g || v.b !== this.current.b || v.a !== this.current.a) { this.current = v; - this.context.gl.uniform4f(this.location, v.r, v.g, v.b, v.a); + this.gl.uniform4f(this.location, v.r, v.g, v.b, v.a); } } } @@ -120,13 +120,13 @@ class UniformMatrix4fv extends Uniform { // unnecessary iteration: if (v[12] !== this.current[12] || v[0] !== this.current[0]) { this.current = v; - this.context.gl.uniformMatrix4fv(this.location, false, v); + this.gl.uniformMatrix4fv(this.location, false, v); return; } for (let i = 1; i < 16; i++) { if (v[i] !== this.current[i]) { this.current = v; - this.context.gl.uniformMatrix4fv(this.location, false, v); + this.gl.uniformMatrix4fv(this.location, false, v); break; } } From 1a9cfd7d7fb418c78d3994b1d45230dad1cb1f4a Mon Sep 17 00:00:00 2001 From: Lauren Budorick Date: Mon, 19 Mar 2018 16:00:33 -0700 Subject: [PATCH 10/11] Fix line drawing --- src/render/draw_line.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/render/draw_line.js b/src/render/draw_line.js index 057f792164f..3bad679980e 100644 --- a/src/render/draw_line.js +++ b/src/render/draw_line.js @@ -60,6 +60,11 @@ export default function drawLine(painter: Painter, sourceCache: SourceCache, lay const program = painter.useProgram(programId, programConfiguration); const programChanged = firstTile || program.program !== prevProgram; + const uniformValues = dasharray ? lineSDFUniformValues(painter, tile, layer, dasharray) : + image ? linePatternUniformValues(painter, tile, layer, image) : + gradient ? lineGradientUniformValues(painter, tile, layer) : + lineUniformValues(painter, tile, layer); + if (dasharray && (programChanged || painter.lineAtlas.dirty)) { context.activeTexture.set(gl.TEXTURE0); painter.lineAtlas.bind(context); @@ -68,11 +73,6 @@ export default function drawLine(painter: Painter, sourceCache: SourceCache, lay painter.imageManager.bind(context); } - const uniformValues = dasharray ? lineSDFUniformValues(painter, tile, layer, dasharray) : - image ? linePatternUniformValues(painter, tile, layer, image) : - gradient ? lineGradientUniformValues(painter, tile, layer) : - lineUniformValues(painter, tile, layer); - program.draw(context, gl.TRIANGLES, depthMode, painter.stencilModeForClipping(coord), colorMode, uniformValues, layer.id, bucket.layoutVertexBuffer, bucket.indexBuffer, bucket.segments, From 4c843a76941baac7c35427ca800ebfb24b704589 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 6 Aug 2018 15:48:18 -0700 Subject: [PATCH 11/11] Drop v suffix from Uniform* names --- src/render/program/background_program.js | 48 ++++----- src/render/program/circle_program.js | 12 +-- src/render/program/clipping_mask_program.js | 6 +- src/render/program/collision_program.js | 12 +-- src/render/program/debug_program.js | 6 +- src/render/program/fill_extrusion_program.js | 74 +++++++------- src/render/program/fill_program.js | 100 +++++++++---------- src/render/program/heatmap_program.js | 16 +-- src/render/program/hillshade_program.js | 24 ++--- src/render/program/line_program.js | 72 ++++++------- src/render/program/pattern.js | 20 ++-- src/render/program/raster_program.js | 18 ++-- src/render/program/symbol_program.js | 36 +++---- src/render/uniform_binding.js | 16 +-- test/unit/render/uniform_binding.test.js | 18 ++-- 15 files changed, 239 insertions(+), 239 deletions(-) diff --git a/src/render/program/background_program.js b/src/render/program/background_program.js index fbcc6d70de6..6847fa3140e 100644 --- a/src/render/program/background_program.js +++ b/src/render/program/background_program.js @@ -4,9 +4,9 @@ import { patternUniformValues } from './pattern'; import { Uniform1i, Uniform1f, - Uniform2fv, + Uniform2f, UniformColor, - UniformMatrix4fv + UniformMatrix4f } from '../uniform_binding'; import { extend } from '../../util/util'; @@ -18,53 +18,53 @@ import type {CrossFaded} from '../../style/cross_faded'; import type {OverscaledTileID} from '../../source/tile_id'; export type BackgroundUniformsType = {| - 'u_matrix': UniformMatrix4fv, + 'u_matrix': UniformMatrix4f, 'u_opacity': Uniform1f, 'u_color': UniformColor |}; export type BackgroundPatternUniformsType = {| - 'u_matrix': UniformMatrix4fv, + 'u_matrix': UniformMatrix4f, 'u_opacity': Uniform1f, // pattern uniforms: 'u_image': Uniform1i, - 'u_pattern_tl_a': Uniform2fv, - 'u_pattern_br_a': Uniform2fv, - 'u_pattern_tl_b': Uniform2fv, - 'u_pattern_br_b': Uniform2fv, - 'u_texsize': Uniform2fv, + 'u_pattern_tl_a': Uniform2f, + 'u_pattern_br_a': Uniform2f, + 'u_pattern_tl_b': Uniform2f, + 'u_pattern_br_b': Uniform2f, + 'u_texsize': Uniform2f, 'u_mix': Uniform1f, - 'u_pattern_size_a': Uniform2fv, - 'u_pattern_size_b': Uniform2fv, + 'u_pattern_size_a': Uniform2f, + 'u_pattern_size_b': Uniform2f, 'u_scale_a': Uniform1f, 'u_scale_b': Uniform1f, - 'u_pixel_coord_upper': Uniform2fv, - 'u_pixel_coord_lower': Uniform2fv, + 'u_pixel_coord_upper': Uniform2f, + 'u_pixel_coord_lower': Uniform2f, 'u_tile_units_to_pixels': Uniform1f |}; const backgroundUniforms = (context: Context, locations: UniformLocations): BackgroundUniformsType => ({ - 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), + 'u_matrix': new UniformMatrix4f(context, locations.u_matrix), 'u_opacity': new Uniform1f(context, locations.u_opacity), 'u_color': new UniformColor(context, locations.u_color) }); const backgroundPatternUniforms = (context: Context, locations: UniformLocations): BackgroundPatternUniformsType => ({ - 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), + 'u_matrix': new UniformMatrix4f(context, locations.u_matrix), 'u_opacity': new Uniform1f(context, locations.u_opacity), 'u_image': new Uniform1i(context, locations.u_image), - 'u_pattern_tl_a': new Uniform2fv(context, locations.u_pattern_tl_a), - 'u_pattern_br_a': new Uniform2fv(context, locations.u_pattern_br_a), - 'u_pattern_tl_b': new Uniform2fv(context, locations.u_pattern_tl_b), - 'u_pattern_br_b': new Uniform2fv(context, locations.u_pattern_br_b), - 'u_texsize': new Uniform2fv(context, locations.u_texsize), + 'u_pattern_tl_a': new Uniform2f(context, locations.u_pattern_tl_a), + 'u_pattern_br_a': new Uniform2f(context, locations.u_pattern_br_a), + 'u_pattern_tl_b': new Uniform2f(context, locations.u_pattern_tl_b), + 'u_pattern_br_b': new Uniform2f(context, locations.u_pattern_br_b), + 'u_texsize': new Uniform2f(context, locations.u_texsize), 'u_mix': new Uniform1f(context, locations.u_mix), - 'u_pattern_size_a': new Uniform2fv(context, locations.u_pattern_size_a), - 'u_pattern_size_b': new Uniform2fv(context, locations.u_pattern_size_b), + 'u_pattern_size_a': new Uniform2f(context, locations.u_pattern_size_a), + 'u_pattern_size_b': new Uniform2f(context, locations.u_pattern_size_b), 'u_scale_a': new Uniform1f(context, locations.u_scale_a), 'u_scale_b': new Uniform1f(context, locations.u_scale_b), - 'u_pixel_coord_upper': new Uniform2fv(context, locations.u_pixel_coord_upper), - 'u_pixel_coord_lower': new Uniform2fv(context, locations.u_pixel_coord_lower), + 'u_pixel_coord_upper': new Uniform2f(context, locations.u_pixel_coord_upper), + 'u_pixel_coord_lower': new Uniform2f(context, locations.u_pixel_coord_lower), 'u_tile_units_to_pixels': new Uniform1f(context, locations.u_tile_units_to_pixels) }); diff --git a/src/render/program/circle_program.js b/src/render/program/circle_program.js index 30a4c2bce1b..17732373106 100644 --- a/src/render/program/circle_program.js +++ b/src/render/program/circle_program.js @@ -3,8 +3,8 @@ import { Uniform1i, Uniform1f, - Uniform2fv, - UniformMatrix4fv + Uniform2f, + UniformMatrix4f } from '../uniform_binding'; import pixelsToTileUnits from '../../source/pixels_to_tile_units'; @@ -19,16 +19,16 @@ export type CircleUniformsType = {| 'u_camera_to_center_distance': Uniform1f, 'u_scale_with_map': Uniform1i, 'u_pitch_with_map': Uniform1i, - 'u_extrude_scale': Uniform2fv, - 'u_matrix': UniformMatrix4fv + 'u_extrude_scale': Uniform2f, + 'u_matrix': UniformMatrix4f |}; const circleUniforms = (context: Context, locations: UniformLocations): CircleUniformsType => ({ 'u_camera_to_center_distance': new Uniform1f(context, locations.u_camera_to_center_distance), 'u_scale_with_map': new Uniform1i(context, locations.u_scale_with_map), 'u_pitch_with_map': new Uniform1i(context, locations.u_pitch_with_map), - 'u_extrude_scale': new Uniform2fv(context, locations.u_extrude_scale), - 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix) + 'u_extrude_scale': new Uniform2f(context, locations.u_extrude_scale), + 'u_matrix': new UniformMatrix4f(context, locations.u_matrix) }); const circleUniformValues = ( diff --git a/src/render/program/clipping_mask_program.js b/src/render/program/clipping_mask_program.js index e8e2d9708b8..f1cbea38b26 100644 --- a/src/render/program/clipping_mask_program.js +++ b/src/render/program/clipping_mask_program.js @@ -1,16 +1,16 @@ // @flow -import { UniformMatrix4fv } from '../uniform_binding'; +import { UniformMatrix4f } from '../uniform_binding'; import type Context from '../../gl/context'; import type {UniformValues, UniformLocations} from '../uniform_binding'; export type ClippingMaskUniformsType = {| - 'u_matrix': UniformMatrix4fv + 'u_matrix': UniformMatrix4f |}; const clippingMaskUniforms = (context: Context, locations: UniformLocations): ClippingMaskUniformsType => ({ - 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix) + 'u_matrix': new UniformMatrix4f(context, locations.u_matrix) }); const clippingMaskUniformValues = (matrix: Float32Array): UniformValues => ({ diff --git a/src/render/program/collision_program.js b/src/render/program/collision_program.js index 5dec2e8fac8..157e2317a3f 100644 --- a/src/render/program/collision_program.js +++ b/src/render/program/collision_program.js @@ -2,8 +2,8 @@ import { Uniform1f, - Uniform2fv, - UniformMatrix4fv + Uniform2f, + UniformMatrix4f } from '../uniform_binding'; import pixelsToTileUnits from '../../source/pixels_to_tile_units'; @@ -13,18 +13,18 @@ import type Transform from '../../geo/transform'; import type Tile from '../../source/tile'; export type CollisionUniformsType = {| - 'u_matrix': UniformMatrix4fv, + 'u_matrix': UniformMatrix4f, 'u_camera_to_center_distance': Uniform1f, 'u_pixels_to_tile_units': Uniform1f, - 'u_extrude_scale': Uniform2fv, + 'u_extrude_scale': Uniform2f, 'u_overscale_factor': Uniform1f |}; const collisionUniforms = (context: Context, locations: UniformLocations): CollisionUniformsType => ({ - 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), + 'u_matrix': new UniformMatrix4f(context, locations.u_matrix), 'u_camera_to_center_distance': new Uniform1f(context, locations.u_camera_to_center_distance), 'u_pixels_to_tile_units': new Uniform1f(context, locations.u_pixels_to_tile_units), - 'u_extrude_scale': new Uniform2fv(context, locations.u_extrude_scale), + 'u_extrude_scale': new Uniform2f(context, locations.u_extrude_scale), 'u_overscale_factor': new Uniform1f(context, locations.u_overscale_factor) }); diff --git a/src/render/program/debug_program.js b/src/render/program/debug_program.js index 9a023c1d86a..14ad091a2a5 100644 --- a/src/render/program/debug_program.js +++ b/src/render/program/debug_program.js @@ -2,7 +2,7 @@ import { UniformColor, - UniformMatrix4fv + UniformMatrix4f } from '../uniform_binding'; import type Context from '../../gl/context'; @@ -11,12 +11,12 @@ import type Color from '../../style-spec/util/color'; export type DebugUniformsType = {| 'u_color': UniformColor, - 'u_matrix': UniformMatrix4fv + 'u_matrix': UniformMatrix4f |}; const debugUniforms = (context: Context, locations: UniformLocations): DebugUniformsType => ({ 'u_color': new UniformColor(context, locations.u_color), - 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix) + 'u_matrix': new UniformMatrix4f(context, locations.u_matrix) }); const debugUniformValues = (matrix: Float32Array, color: Color): UniformValues => ({ diff --git a/src/render/program/fill_extrusion_program.js b/src/render/program/fill_extrusion_program.js index 3df9953ed53..52ed0d0a33b 100644 --- a/src/render/program/fill_extrusion_program.js +++ b/src/render/program/fill_extrusion_program.js @@ -4,9 +4,9 @@ import { patternUniformValues } from './pattern'; import { Uniform1i, Uniform1f, - Uniform2fv, - Uniform3fv, - UniformMatrix4fv + Uniform2f, + Uniform3f, + UniformMatrix4f } from '../uniform_binding'; import {mat3, vec3, mat4} from 'gl-matrix'; @@ -20,74 +20,74 @@ import type {UniformValues, UniformLocations} from '../uniform_binding'; import type FillExtrusionStyleLayer from '../../style/style_layer/fill_extrusion_style_layer'; export type FillExtrusionUniformsType = {| - 'u_matrix': UniformMatrix4fv, - 'u_lightpos': Uniform3fv, + 'u_matrix': UniformMatrix4f, + 'u_lightpos': Uniform3f, 'u_lightintensity': Uniform1f, - 'u_lightcolor': Uniform3fv + 'u_lightcolor': Uniform3f |}; export type FillExtrusionPatternUniformsType = {| - 'u_matrix': UniformMatrix4fv, - 'u_lightpos': Uniform3fv, + 'u_matrix': UniformMatrix4f, + 'u_lightpos': Uniform3f, 'u_lightintensity': Uniform1f, - 'u_lightcolor': Uniform3fv, + 'u_lightcolor': Uniform3f, 'u_height_factor': Uniform1f, // pattern uniforms: 'u_image': Uniform1i, - 'u_pattern_tl_a': Uniform2fv, - 'u_pattern_br_a': Uniform2fv, - 'u_pattern_tl_b': Uniform2fv, - 'u_pattern_br_b': Uniform2fv, - 'u_texsize': Uniform2fv, + 'u_pattern_tl_a': Uniform2f, + 'u_pattern_br_a': Uniform2f, + 'u_pattern_tl_b': Uniform2f, + 'u_pattern_br_b': Uniform2f, + 'u_texsize': Uniform2f, 'u_mix': Uniform1f, - 'u_pattern_size_a': Uniform2fv, - 'u_pattern_size_b': Uniform2fv, + 'u_pattern_size_a': Uniform2f, + 'u_pattern_size_b': Uniform2f, 'u_scale_a': Uniform1f, 'u_scale_b': Uniform1f, - 'u_pixel_coord_upper': Uniform2fv, - 'u_pixel_coord_lower': Uniform2fv, + 'u_pixel_coord_upper': Uniform2f, + 'u_pixel_coord_lower': Uniform2f, 'u_tile_units_to_pixels': Uniform1f |}; export type ExtrusionTextureUniformsType = {| - 'u_matrix': UniformMatrix4fv, - 'u_world': Uniform2fv, + 'u_matrix': UniformMatrix4f, + 'u_world': Uniform2f, 'u_image': Uniform1i, 'u_opacity': Uniform1f |}; const fillExtrusionUniforms = (context: Context, locations: UniformLocations): FillExtrusionUniformsType => ({ - 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), - 'u_lightpos': new Uniform3fv(context, locations.u_lightpos), + 'u_matrix': new UniformMatrix4f(context, locations.u_matrix), + 'u_lightpos': new Uniform3f(context, locations.u_lightpos), 'u_lightintensity': new Uniform1f(context, locations.u_lightintensity), - 'u_lightcolor': new Uniform3fv(context, locations.u_lightcolor) + 'u_lightcolor': new Uniform3f(context, locations.u_lightcolor) }); const fillExtrusionPatternUniforms = (context: Context, locations: UniformLocations): FillExtrusionPatternUniformsType => ({ - 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), - 'u_lightpos': new Uniform3fv(context, locations.u_lightpos), + 'u_matrix': new UniformMatrix4f(context, locations.u_matrix), + 'u_lightpos': new Uniform3f(context, locations.u_lightpos), 'u_lightintensity': new Uniform1f(context, locations.u_lightintensity), - 'u_lightcolor': new Uniform3fv(context, locations.u_lightcolor), + 'u_lightcolor': new Uniform3f(context, locations.u_lightcolor), 'u_height_factor': new Uniform1f(context, locations.u_height_factor), 'u_image': new Uniform1i(context, locations.u_image), - 'u_pattern_tl_a': new Uniform2fv(context, locations.u_pattern_tl_a), - 'u_pattern_br_a': new Uniform2fv(context, locations.u_pattern_br_a), - 'u_pattern_tl_b': new Uniform2fv(context, locations.u_pattern_tl_b), - 'u_pattern_br_b': new Uniform2fv(context, locations.u_pattern_br_b), - 'u_texsize': new Uniform2fv(context, locations.u_texsize), + 'u_pattern_tl_a': new Uniform2f(context, locations.u_pattern_tl_a), + 'u_pattern_br_a': new Uniform2f(context, locations.u_pattern_br_a), + 'u_pattern_tl_b': new Uniform2f(context, locations.u_pattern_tl_b), + 'u_pattern_br_b': new Uniform2f(context, locations.u_pattern_br_b), + 'u_texsize': new Uniform2f(context, locations.u_texsize), 'u_mix': new Uniform1f(context, locations.u_mix), - 'u_pattern_size_a': new Uniform2fv(context, locations.u_pattern_size_a), - 'u_pattern_size_b': new Uniform2fv(context, locations.u_pattern_size_b), + 'u_pattern_size_a': new Uniform2f(context, locations.u_pattern_size_a), + 'u_pattern_size_b': new Uniform2f(context, locations.u_pattern_size_b), 'u_scale_a': new Uniform1f(context, locations.u_scale_a), 'u_scale_b': new Uniform1f(context, locations.u_scale_b), - 'u_pixel_coord_upper': new Uniform2fv(context, locations.u_pixel_coord_upper), - 'u_pixel_coord_lower': new Uniform2fv(context, locations.u_pixel_coord_lower), + 'u_pixel_coord_upper': new Uniform2f(context, locations.u_pixel_coord_upper), + 'u_pixel_coord_lower': new Uniform2f(context, locations.u_pixel_coord_lower), 'u_tile_units_to_pixels': new Uniform1f(context, locations.u_tile_units_to_pixels) }); const extrusionTextureUniforms = (context: Context, locations: UniformLocations): ExtrusionTextureUniformsType => ({ - 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), - 'u_world': new Uniform2fv(context, locations.u_world), + 'u_matrix': new UniformMatrix4f(context, locations.u_matrix), + 'u_world': new Uniform2f(context, locations.u_world), 'u_image': new Uniform1i(context, locations.u_image), 'u_opacity': new Uniform1f(context, locations.u_opacity) }); diff --git a/src/render/program/fill_program.js b/src/render/program/fill_program.js index 3e7a225d890..f5c213c9fd5 100644 --- a/src/render/program/fill_program.js +++ b/src/render/program/fill_program.js @@ -4,8 +4,8 @@ import {patternUniformValues} from './pattern'; import { Uniform1i, Uniform1f, - Uniform2fv, - UniformMatrix4fv + Uniform2f, + UniformMatrix4f } from '../uniform_binding'; import { extend } from '../../util/util'; @@ -16,96 +16,96 @@ import type {CrossFaded} from '../../style/cross_faded'; import type {OverscaledTileID} from '../../source/tile_id'; export type FillUniformsType = {| - 'u_matrix': UniformMatrix4fv + 'u_matrix': UniformMatrix4f |}; export type FillOutlineUniformsType = {| - 'u_matrix': UniformMatrix4fv, - 'u_world': Uniform2fv + 'u_matrix': UniformMatrix4f, + 'u_world': Uniform2f |}; export type FillPatternUniformsType = {| - 'u_matrix': UniformMatrix4fv, + 'u_matrix': UniformMatrix4f, // pattern uniforms: 'u_image': Uniform1i, - 'u_pattern_tl_a': Uniform2fv, - 'u_pattern_br_a': Uniform2fv, - 'u_pattern_tl_b': Uniform2fv, - 'u_pattern_br_b': Uniform2fv, - 'u_texsize': Uniform2fv, + 'u_pattern_tl_a': Uniform2f, + 'u_pattern_br_a': Uniform2f, + 'u_pattern_tl_b': Uniform2f, + 'u_pattern_br_b': Uniform2f, + 'u_texsize': Uniform2f, 'u_mix': Uniform1f, - 'u_pattern_size_a': Uniform2fv, - 'u_pattern_size_b': Uniform2fv, + 'u_pattern_size_a': Uniform2f, + 'u_pattern_size_b': Uniform2f, 'u_scale_a': Uniform1f, 'u_scale_b': Uniform1f, - 'u_pixel_coord_upper': Uniform2fv, - 'u_pixel_coord_lower': Uniform2fv, + 'u_pixel_coord_upper': Uniform2f, + 'u_pixel_coord_lower': Uniform2f, 'u_tile_units_to_pixels': Uniform1f |}; export type FillOutlinePatternUniformsType = {| - 'u_matrix': UniformMatrix4fv, - 'u_world': Uniform2fv, + 'u_matrix': UniformMatrix4f, + 'u_world': Uniform2f, // pattern uniforms: 'u_image': Uniform1i, - 'u_pattern_tl_a': Uniform2fv, - 'u_pattern_br_a': Uniform2fv, - 'u_pattern_tl_b': Uniform2fv, - 'u_pattern_br_b': Uniform2fv, - 'u_texsize': Uniform2fv, + 'u_pattern_tl_a': Uniform2f, + 'u_pattern_br_a': Uniform2f, + 'u_pattern_tl_b': Uniform2f, + 'u_pattern_br_b': Uniform2f, + 'u_texsize': Uniform2f, 'u_mix': Uniform1f, - 'u_pattern_size_a': Uniform2fv, - 'u_pattern_size_b': Uniform2fv, + 'u_pattern_size_a': Uniform2f, + 'u_pattern_size_b': Uniform2f, 'u_scale_a': Uniform1f, 'u_scale_b': Uniform1f, - 'u_pixel_coord_upper': Uniform2fv, - 'u_pixel_coord_lower': Uniform2fv, + 'u_pixel_coord_upper': Uniform2f, + 'u_pixel_coord_lower': Uniform2f, 'u_tile_units_to_pixels': Uniform1f |}; const fillUniforms = (context: Context, locations: UniformLocations): FillUniformsType => ({ - 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix) + 'u_matrix': new UniformMatrix4f(context, locations.u_matrix) }); const fillPatternUniforms = (context: Context, locations: UniformLocations): FillPatternUniformsType => ({ - 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), + 'u_matrix': new UniformMatrix4f(context, locations.u_matrix), 'u_image': new Uniform1i(context, locations.u_image), - 'u_pattern_tl_a': new Uniform2fv(context, locations.u_pattern_tl_a), - 'u_pattern_br_a': new Uniform2fv(context, locations.u_pattern_br_a), - 'u_pattern_tl_b': new Uniform2fv(context, locations.u_pattern_tl_b), - 'u_pattern_br_b': new Uniform2fv(context, locations.u_pattern_br_b), - 'u_texsize': new Uniform2fv(context, locations.u_texsize), + 'u_pattern_tl_a': new Uniform2f(context, locations.u_pattern_tl_a), + 'u_pattern_br_a': new Uniform2f(context, locations.u_pattern_br_a), + 'u_pattern_tl_b': new Uniform2f(context, locations.u_pattern_tl_b), + 'u_pattern_br_b': new Uniform2f(context, locations.u_pattern_br_b), + 'u_texsize': new Uniform2f(context, locations.u_texsize), 'u_mix': new Uniform1f(context, locations.u_mix), - 'u_pattern_size_a': new Uniform2fv(context, locations.u_pattern_size_a), - 'u_pattern_size_b': new Uniform2fv(context, locations.u_pattern_size_b), + 'u_pattern_size_a': new Uniform2f(context, locations.u_pattern_size_a), + 'u_pattern_size_b': new Uniform2f(context, locations.u_pattern_size_b), 'u_scale_a': new Uniform1f(context, locations.u_scale_a), 'u_scale_b': new Uniform1f(context, locations.u_scale_b), - 'u_pixel_coord_upper': new Uniform2fv(context, locations.u_pixel_coord_upper), - 'u_pixel_coord_lower': new Uniform2fv(context, locations.u_pixel_coord_lower), + 'u_pixel_coord_upper': new Uniform2f(context, locations.u_pixel_coord_upper), + 'u_pixel_coord_lower': new Uniform2f(context, locations.u_pixel_coord_lower), 'u_tile_units_to_pixels': new Uniform1f(context, locations.u_tile_units_to_pixels) }); const fillOutlineUniforms = (context: Context, locations: UniformLocations): FillOutlineUniformsType => ({ - 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), - 'u_world': new Uniform2fv(context, locations.u_world) + 'u_matrix': new UniformMatrix4f(context, locations.u_matrix), + 'u_world': new Uniform2f(context, locations.u_world) }); const fillOutlinePatternUniforms = (context: Context, locations: UniformLocations): FillOutlinePatternUniformsType => ({ - 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), - 'u_world': new Uniform2fv(context, locations.u_world), + 'u_matrix': new UniformMatrix4f(context, locations.u_matrix), + 'u_world': new Uniform2f(context, locations.u_world), 'u_image': new Uniform1i(context, locations.u_image), - 'u_pattern_tl_a': new Uniform2fv(context, locations.u_pattern_tl_a), - 'u_pattern_br_a': new Uniform2fv(context, locations.u_pattern_br_a), - 'u_pattern_tl_b': new Uniform2fv(context, locations.u_pattern_tl_b), - 'u_pattern_br_b': new Uniform2fv(context, locations.u_pattern_br_b), - 'u_texsize': new Uniform2fv(context, locations.u_texsize), + 'u_pattern_tl_a': new Uniform2f(context, locations.u_pattern_tl_a), + 'u_pattern_br_a': new Uniform2f(context, locations.u_pattern_br_a), + 'u_pattern_tl_b': new Uniform2f(context, locations.u_pattern_tl_b), + 'u_pattern_br_b': new Uniform2f(context, locations.u_pattern_br_b), + 'u_texsize': new Uniform2f(context, locations.u_texsize), 'u_mix': new Uniform1f(context, locations.u_mix), - 'u_pattern_size_a': new Uniform2fv(context, locations.u_pattern_size_a), - 'u_pattern_size_b': new Uniform2fv(context, locations.u_pattern_size_b), + 'u_pattern_size_a': new Uniform2f(context, locations.u_pattern_size_a), + 'u_pattern_size_b': new Uniform2f(context, locations.u_pattern_size_b), 'u_scale_a': new Uniform1f(context, locations.u_scale_a), 'u_scale_b': new Uniform1f(context, locations.u_scale_b), - 'u_pixel_coord_upper': new Uniform2fv(context, locations.u_pixel_coord_upper), - 'u_pixel_coord_lower': new Uniform2fv(context, locations.u_pixel_coord_lower), + 'u_pixel_coord_upper': new Uniform2f(context, locations.u_pixel_coord_upper), + 'u_pixel_coord_lower': new Uniform2f(context, locations.u_pixel_coord_lower), 'u_tile_units_to_pixels': new Uniform1f(context, locations.u_tile_units_to_pixels) }); diff --git a/src/render/program/heatmap_program.js b/src/render/program/heatmap_program.js index b93cccbd29c..031f37a750c 100644 --- a/src/render/program/heatmap_program.js +++ b/src/render/program/heatmap_program.js @@ -5,8 +5,8 @@ import { mat4 } from 'gl-matrix'; import { Uniform1i, Uniform1f, - Uniform2fv, - UniformMatrix4fv + Uniform2f, + UniformMatrix4f } from '../uniform_binding'; import pixelsToTileUnits from '../../source/pixels_to_tile_units'; @@ -19,12 +19,12 @@ import type HeatmapStyleLayer from '../../style/style_layer/heatmap_style_layer' export type HeatmapUniformsType = {| 'u_extrude_scale': Uniform1f, 'u_intensity': Uniform1f, - 'u_matrix': UniformMatrix4fv + 'u_matrix': UniformMatrix4f |}; export type HeatmapTextureUniformsType = {| - 'u_matrix': UniformMatrix4fv, - 'u_world': Uniform2fv, + 'u_matrix': UniformMatrix4f, + 'u_world': Uniform2f, 'u_image': Uniform1i, 'u_color_ramp': Uniform1i, 'u_opacity': Uniform1f @@ -33,12 +33,12 @@ export type HeatmapTextureUniformsType = {| const heatmapUniforms = (context: Context, locations: UniformLocations): HeatmapUniformsType => ({ 'u_extrude_scale': new Uniform1f(context, locations.u_extrude_scale), 'u_intensity': new Uniform1f(context, locations.u_intensity), - 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix) + 'u_matrix': new UniformMatrix4f(context, locations.u_matrix) }); const heatmapTextureUniforms = (context: Context, locations: UniformLocations): HeatmapTextureUniformsType => ({ - 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), - 'u_world': new Uniform2fv(context, locations.u_world), + 'u_matrix': new UniformMatrix4f(context, locations.u_matrix), + 'u_world': new Uniform2f(context, locations.u_world), 'u_image': new Uniform1i(context, locations.u_image), 'u_color_ramp': new Uniform1i(context, locations.u_color_ramp), 'u_opacity': new Uniform1f(context, locations.u_opacity) diff --git a/src/render/program/hillshade_program.js b/src/render/program/hillshade_program.js index 12cdd9802b0..e84c9626427 100644 --- a/src/render/program/hillshade_program.js +++ b/src/render/program/hillshade_program.js @@ -6,9 +6,9 @@ import { mat4 } from 'gl-matrix'; import { Uniform1i, Uniform1f, - Uniform2fv, + Uniform2f, UniformColor, - UniformMatrix4fv + UniformMatrix4f } from '../uniform_binding'; import EXTENT from '../../data/extent'; import Coordinate from '../../geo/coordinate'; @@ -22,37 +22,37 @@ import type DEMData from '../../data/dem_data'; import type {OverscaledTileID} from '../../source/tile_id'; export type HillshadeUniformsType = {| - 'u_matrix': UniformMatrix4fv, + 'u_matrix': UniformMatrix4f, 'u_image': Uniform1i, - 'u_latrange': Uniform2fv, - 'u_light': Uniform2fv, + 'u_latrange': Uniform2f, + 'u_light': Uniform2f, 'u_shadow': UniformColor, 'u_highlight': UniformColor, 'u_accent': UniformColor |}; export type HillshadePrepareUniformsType = {| - 'u_matrix': UniformMatrix4fv, + 'u_matrix': UniformMatrix4f, 'u_image': Uniform1i, - 'u_dimension': Uniform2fv, + 'u_dimension': Uniform2f, 'u_zoom': Uniform1f, 'u_maxzoom': Uniform1f |}; const hillshadeUniforms = (context: Context, locations: UniformLocations): HillshadeUniformsType => ({ - 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), + 'u_matrix': new UniformMatrix4f(context, locations.u_matrix), 'u_image': new Uniform1i(context, locations.u_image), - 'u_latrange': new Uniform2fv(context, locations.u_latrange), - 'u_light': new Uniform2fv(context, locations.u_light), + 'u_latrange': new Uniform2f(context, locations.u_latrange), + 'u_light': new Uniform2f(context, locations.u_light), 'u_shadow': new UniformColor(context, locations.u_shadow), 'u_highlight': new UniformColor(context, locations.u_highlight), 'u_accent': new UniformColor(context, locations.u_accent) }); const hillshadePrepareUniforms = (context: Context, locations: UniformLocations): HillshadePrepareUniformsType => ({ - 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), + 'u_matrix': new UniformMatrix4f(context, locations.u_matrix), 'u_image': new Uniform1i(context, locations.u_image), - 'u_dimension': new Uniform2fv(context, locations.u_dimension), + 'u_dimension': new Uniform2f(context, locations.u_dimension), 'u_zoom': new Uniform1f(context, locations.u_zoom), 'u_maxzoom': new Uniform1f(context, locations.u_maxzoom) }); diff --git a/src/render/program/line_program.js b/src/render/program/line_program.js index cf278a7cf7c..c1472fa9ccf 100644 --- a/src/render/program/line_program.js +++ b/src/render/program/line_program.js @@ -3,8 +3,8 @@ import { Uniform1i, Uniform1f, - Uniform2fv, - UniformMatrix4fv + Uniform2f, + UniformMatrix4f } from '../uniform_binding'; import pixelsToTileUnits from '../../source/pixels_to_tile_units'; import { extend } from '../../util/util'; @@ -19,39 +19,39 @@ import type LineStyleLayer from '../../style/style_layer/line_style_layer'; import type Painter from '../painter'; export type LineUniformsType = {| - 'u_matrix': UniformMatrix4fv, + 'u_matrix': UniformMatrix4f, 'u_ratio': Uniform1f, - 'u_gl_units_to_pixels': Uniform2fv + 'u_gl_units_to_pixels': Uniform2f |}; export type LineGradientUniformsType = {| - 'u_matrix': UniformMatrix4fv, + 'u_matrix': UniformMatrix4f, 'u_ratio': Uniform1f, - 'u_gl_units_to_pixels': Uniform2fv, + 'u_gl_units_to_pixels': Uniform2f, 'u_image': Uniform1i |}; export type LinePatternUniformsType = {| - 'u_matrix': UniformMatrix4fv, + 'u_matrix': UniformMatrix4f, 'u_ratio': Uniform1f, - 'u_gl_units_to_pixels': Uniform2fv, - 'u_pattern_size_a': Uniform2fv, - 'u_pattern_size_b': Uniform2fv, - 'u_texsize': Uniform2fv, + 'u_gl_units_to_pixels': Uniform2f, + 'u_pattern_size_a': Uniform2f, + 'u_pattern_size_b': Uniform2f, + 'u_texsize': Uniform2f, 'u_image': Uniform1i, - 'u_pattern_tl_a': Uniform2fv, - 'u_pattern_br_a': Uniform2fv, - 'u_pattern_tl_b': Uniform2fv, - 'u_pattern_br_b': Uniform2fv, + 'u_pattern_tl_a': Uniform2f, + 'u_pattern_br_a': Uniform2f, + 'u_pattern_tl_b': Uniform2f, + 'u_pattern_br_b': Uniform2f, 'u_fade': Uniform1f |}; export type LineSDFUniformsType = {| - 'u_matrix': UniformMatrix4fv, + 'u_matrix': UniformMatrix4f, 'u_ratio': Uniform1f, - 'u_gl_units_to_pixels': Uniform2fv, - 'u_patternscale_a': Uniform2fv, - 'u_patternscale_b': Uniform2fv, + 'u_gl_units_to_pixels': Uniform2f, + 'u_patternscale_a': Uniform2f, + 'u_patternscale_b': Uniform2f, 'u_sdfgamma': Uniform1f, 'u_image': Uniform1i, 'u_tex_y_a': Uniform1f, @@ -60,39 +60,39 @@ export type LineSDFUniformsType = {| |}; const lineUniforms = (context: Context, locations: UniformLocations): LineUniformsType => ({ - 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), + 'u_matrix': new UniformMatrix4f(context, locations.u_matrix), 'u_ratio': new Uniform1f(context, locations.u_ratio), - 'u_gl_units_to_pixels': new Uniform2fv(context, locations.u_gl_units_to_pixels) + 'u_gl_units_to_pixels': new Uniform2f(context, locations.u_gl_units_to_pixels) }); const lineGradientUniforms = (context: Context, locations: UniformLocations): LineGradientUniformsType => ({ - 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), + 'u_matrix': new UniformMatrix4f(context, locations.u_matrix), 'u_ratio': new Uniform1f(context, locations.u_ratio), - 'u_gl_units_to_pixels': new Uniform2fv(context, locations.u_gl_units_to_pixels), + 'u_gl_units_to_pixels': new Uniform2f(context, locations.u_gl_units_to_pixels), 'u_image': new Uniform1i(context, locations.u_image) }); const linePatternUniforms = (context: Context, locations: UniformLocations): LinePatternUniformsType => ({ - 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), + 'u_matrix': new UniformMatrix4f(context, locations.u_matrix), 'u_ratio': new Uniform1f(context, locations.u_ratio), - 'u_gl_units_to_pixels': new Uniform2fv(context, locations.u_gl_units_to_pixels), - 'u_pattern_size_a': new Uniform2fv(context, locations.u_pattern_size_a), - 'u_pattern_size_b': new Uniform2fv(context, locations.u_pattern_size_b), - 'u_texsize': new Uniform2fv(context, locations.u_texsize), + 'u_gl_units_to_pixels': new Uniform2f(context, locations.u_gl_units_to_pixels), + 'u_pattern_size_a': new Uniform2f(context, locations.u_pattern_size_a), + 'u_pattern_size_b': new Uniform2f(context, locations.u_pattern_size_b), + 'u_texsize': new Uniform2f(context, locations.u_texsize), 'u_image': new Uniform1i(context, locations.u_image), - 'u_pattern_tl_a': new Uniform2fv(context, locations.u_pattern_tl_a), - 'u_pattern_br_a': new Uniform2fv(context, locations.u_pattern_br_a), - 'u_pattern_tl_b': new Uniform2fv(context, locations.u_pattern_tl_b), - 'u_pattern_br_b': new Uniform2fv(context, locations.u_pattern_br_b), + 'u_pattern_tl_a': new Uniform2f(context, locations.u_pattern_tl_a), + 'u_pattern_br_a': new Uniform2f(context, locations.u_pattern_br_a), + 'u_pattern_tl_b': new Uniform2f(context, locations.u_pattern_tl_b), + 'u_pattern_br_b': new Uniform2f(context, locations.u_pattern_br_b), 'u_fade': new Uniform1f(context, locations.u_fade) }); const lineSDFUniforms = (context: Context, locations: UniformLocations): LineSDFUniformsType => ({ - 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), + 'u_matrix': new UniformMatrix4f(context, locations.u_matrix), 'u_ratio': new Uniform1f(context, locations.u_ratio), - 'u_gl_units_to_pixels': new Uniform2fv(context, locations.u_gl_units_to_pixels), - 'u_patternscale_a': new Uniform2fv(context, locations.u_patternscale_a), - 'u_patternscale_b': new Uniform2fv(context, locations.u_patternscale_b), + 'u_gl_units_to_pixels': new Uniform2f(context, locations.u_gl_units_to_pixels), + 'u_patternscale_a': new Uniform2f(context, locations.u_patternscale_a), + 'u_patternscale_b': new Uniform2f(context, locations.u_patternscale_b), 'u_sdfgamma': new Uniform1f(context, locations.u_sdfgamma), 'u_image': new Uniform1i(context, locations.u_image), 'u_tex_y_a': new Uniform1f(context, locations.u_tex_y_a), diff --git a/src/render/program/pattern.js b/src/render/program/pattern.js index 15f54c289c6..4e1ff4af69e 100644 --- a/src/render/program/pattern.js +++ b/src/render/program/pattern.js @@ -4,7 +4,7 @@ import assert from 'assert'; import { Uniform1i, Uniform1f, - Uniform2fv, + Uniform2f, } from '../uniform_binding'; import pixelsToTileUnits from '../../source/pixels_to_tile_units'; @@ -15,18 +15,18 @@ import type {UniformValues} from '../uniform_binding'; type PatternUniformsType = {| 'u_image': Uniform1i, - 'u_pattern_tl_a': Uniform2fv, - 'u_pattern_br_a': Uniform2fv, - 'u_pattern_tl_b': Uniform2fv, - 'u_pattern_br_b': Uniform2fv, - 'u_texsize': Uniform2fv, + 'u_pattern_tl_a': Uniform2f, + 'u_pattern_br_a': Uniform2f, + 'u_pattern_tl_b': Uniform2f, + 'u_pattern_br_b': Uniform2f, + 'u_texsize': Uniform2f, 'u_mix': Uniform1f, - 'u_pattern_size_a': Uniform2fv, - 'u_pattern_size_b': Uniform2fv, + 'u_pattern_size_a': Uniform2f, + 'u_pattern_size_b': Uniform2f, 'u_scale_a': Uniform1f, 'u_scale_b': Uniform1f, - 'u_pixel_coord_upper': Uniform2fv, - 'u_pixel_coord_lower': Uniform2fv, + 'u_pixel_coord_upper': Uniform2f, + 'u_pixel_coord_lower': Uniform2f, 'u_tile_units_to_pixels': Uniform1f |}; diff --git a/src/render/program/raster_program.js b/src/render/program/raster_program.js index 48ebb145553..857651f9d6d 100644 --- a/src/render/program/raster_program.js +++ b/src/render/program/raster_program.js @@ -3,9 +3,9 @@ import { Uniform1i, Uniform1f, - Uniform2fv, - Uniform3fv, - UniformMatrix4fv + Uniform2f, + Uniform3f, + UniformMatrix4f } from '../uniform_binding'; import type Context from '../../gl/context'; @@ -13,8 +13,8 @@ import type {UniformValues, UniformLocations} from '../uniform_binding'; import type RasterStyleLayer from '../../style/style_layer/raster_style_layer'; export type RasterUniformsType = {| - 'u_matrix': UniformMatrix4fv, - 'u_tl_parent': Uniform2fv, + 'u_matrix': UniformMatrix4f, + 'u_tl_parent': Uniform2f, 'u_scale_parent': Uniform1f, 'u_buffer_scale': Uniform1f, 'u_fade_t': Uniform1f, @@ -25,12 +25,12 @@ export type RasterUniformsType = {| 'u_brightness_high': Uniform1f, 'u_saturation_factor': Uniform1f, 'u_contrast_factor': Uniform1f, - 'u_spin_weights': Uniform3fv + 'u_spin_weights': Uniform3f |}; const rasterUniforms = (context: Context, locations: UniformLocations): RasterUniformsType => ({ - 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), - 'u_tl_parent': new Uniform2fv(context, locations.u_tl_parent), + 'u_matrix': new UniformMatrix4f(context, locations.u_matrix), + 'u_tl_parent': new Uniform2f(context, locations.u_tl_parent), 'u_scale_parent': new Uniform1f(context, locations.u_scale_parent), 'u_buffer_scale': new Uniform1f(context, locations.u_buffer_scale), 'u_fade_t': new Uniform1f(context, locations.u_fade_t), @@ -41,7 +41,7 @@ const rasterUniforms = (context: Context, locations: UniformLocations): RasterUn 'u_brightness_high': new Uniform1f(context, locations.u_brightness_high), 'u_saturation_factor': new Uniform1f(context, locations.u_saturation_factor), 'u_contrast_factor': new Uniform1f(context, locations.u_contrast_factor), - 'u_spin_weights': new Uniform3fv(context, locations.u_spin_weights) + 'u_spin_weights': new Uniform3f(context, locations.u_spin_weights) }); const rasterUniformValues = ( diff --git a/src/render/program/symbol_program.js b/src/render/program/symbol_program.js index 97d7f6ea4b0..87e299bba47 100644 --- a/src/render/program/symbol_program.js +++ b/src/render/program/symbol_program.js @@ -3,8 +3,8 @@ import { Uniform1i, Uniform1f, - Uniform2fv, - UniformMatrix4fv + Uniform2f, + UniformMatrix4f } from '../uniform_binding'; import { extend } from '../../util/util'; @@ -22,12 +22,12 @@ export type SymbolIconUniformsType = {| 'u_rotate_symbol': Uniform1i, 'u_aspect_ratio': Uniform1f, 'u_fade_change': Uniform1f, - 'u_matrix': UniformMatrix4fv, - 'u_label_plane_matrix': UniformMatrix4fv, - 'u_gl_coord_matrix': UniformMatrix4fv, + 'u_matrix': UniformMatrix4f, + 'u_label_plane_matrix': UniformMatrix4f, + 'u_gl_coord_matrix': UniformMatrix4f, 'u_is_text': Uniform1f, 'u_pitch_with_map': Uniform1i, - 'u_texsize': Uniform2fv, + 'u_texsize': Uniform2f, 'u_texture': Uniform1i |}; @@ -41,12 +41,12 @@ export type SymbolSDFUniformsType = {| 'u_rotate_symbol': Uniform1i, 'u_aspect_ratio': Uniform1f, 'u_fade_change': Uniform1f, - 'u_matrix': UniformMatrix4fv, - 'u_label_plane_matrix': UniformMatrix4fv, - 'u_gl_coord_matrix': UniformMatrix4fv, + 'u_matrix': UniformMatrix4f, + 'u_label_plane_matrix': UniformMatrix4f, + 'u_gl_coord_matrix': UniformMatrix4f, 'u_is_text': Uniform1f, 'u_pitch_with_map': Uniform1i, - 'u_texsize': Uniform2fv, + 'u_texsize': Uniform2f, 'u_texture': Uniform1i, 'u_gamma_scale': Uniform1f, 'u_is_halo': Uniform1f @@ -62,12 +62,12 @@ const symbolIconUniforms = (context: Context, locations: UniformLocations): Symb 'u_rotate_symbol': new Uniform1i(context, locations.u_rotate_symbol), 'u_aspect_ratio': new Uniform1f(context, locations.u_aspect_ratio), 'u_fade_change': new Uniform1f(context, locations.u_fade_change), - 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), - 'u_label_plane_matrix': new UniformMatrix4fv(context, locations.u_label_plane_matrix), - 'u_gl_coord_matrix': new UniformMatrix4fv(context, locations.u_gl_coord_matrix), + 'u_matrix': new UniformMatrix4f(context, locations.u_matrix), + 'u_label_plane_matrix': new UniformMatrix4f(context, locations.u_label_plane_matrix), + 'u_gl_coord_matrix': new UniformMatrix4f(context, locations.u_gl_coord_matrix), 'u_is_text': new Uniform1f(context, locations.u_is_text), 'u_pitch_with_map': new Uniform1i(context, locations.u_pitch_with_map), - 'u_texsize': new Uniform2fv(context, locations.u_texsize), + 'u_texsize': new Uniform2f(context, locations.u_texsize), 'u_texture': new Uniform1i(context, locations.u_texture) }); @@ -81,12 +81,12 @@ const symbolSDFUniforms = (context: Context, locations: UniformLocations): Symbo 'u_rotate_symbol': new Uniform1i(context, locations.u_rotate_symbol), 'u_aspect_ratio': new Uniform1f(context, locations.u_aspect_ratio), 'u_fade_change': new Uniform1f(context, locations.u_fade_change), - 'u_matrix': new UniformMatrix4fv(context, locations.u_matrix), - 'u_label_plane_matrix': new UniformMatrix4fv(context, locations.u_label_plane_matrix), - 'u_gl_coord_matrix': new UniformMatrix4fv(context, locations.u_gl_coord_matrix), + 'u_matrix': new UniformMatrix4f(context, locations.u_matrix), + 'u_label_plane_matrix': new UniformMatrix4f(context, locations.u_label_plane_matrix), + 'u_gl_coord_matrix': new UniformMatrix4f(context, locations.u_gl_coord_matrix), 'u_is_text': new Uniform1f(context, locations.u_is_text), 'u_pitch_with_map': new Uniform1i(context, locations.u_pitch_with_map), - 'u_texsize': new Uniform2fv(context, locations.u_texsize), + 'u_texsize': new Uniform2f(context, locations.u_texsize), 'u_texture': new Uniform1i(context, locations.u_texture), 'u_gamma_scale': new Uniform1f(context, locations.u_gamma_scale), 'u_is_halo': new Uniform1f(context, locations.u_is_halo) diff --git a/src/render/uniform_binding.js b/src/render/uniform_binding.js index 31960458b28..38fcfeebd88 100644 --- a/src/render/uniform_binding.js +++ b/src/render/uniform_binding.js @@ -49,7 +49,7 @@ class Uniform1f extends Uniform { } } -class Uniform2fv extends Uniform<[number, number]> { +class Uniform2f extends Uniform<[number, number]> { constructor(context: Context, location: WebGLUniformLocation) { super(context, location); this.current = [0, 0]; @@ -63,7 +63,7 @@ class Uniform2fv extends Uniform<[number, number]> { } } -class Uniform3fv extends Uniform<[number, number, number]> { +class Uniform3f extends Uniform<[number, number, number]> { constructor(context: Context, location: WebGLUniformLocation) { super(context, location); this.current = [0, 0, 0]; @@ -77,7 +77,7 @@ class Uniform3fv extends Uniform<[number, number, number]> { } } -class Uniform4fv extends Uniform<[number, number, number, number]> { +class Uniform4f extends Uniform<[number, number, number, number]> { constructor(context: Context, location: WebGLUniformLocation) { super(context, location); this.current = [0, 0, 0, 0]; @@ -108,7 +108,7 @@ class UniformColor extends Uniform { } const emptyMat4 = new Float32Array(16); -class UniformMatrix4fv extends Uniform { +class UniformMatrix4f extends Uniform { constructor(context: Context, location: WebGLUniformLocation) { super(context, location); this.current = emptyMat4; @@ -137,11 +137,11 @@ export { Uniform, Uniform1i, Uniform1f, - Uniform2fv, - Uniform3fv, - Uniform4fv, + Uniform2f, + Uniform3f, + Uniform4f, UniformColor, - UniformMatrix4fv + UniformMatrix4f }; export type UniformBindings = {[string]: Uniform}; diff --git a/test/unit/render/uniform_binding.test.js b/test/unit/render/uniform_binding.test.js index f8f16ec04be..dc4775574c2 100644 --- a/test/unit/render/uniform_binding.test.js +++ b/test/unit/render/uniform_binding.test.js @@ -2,9 +2,9 @@ import { test } from 'mapbox-gl-js-test'; import { Uniform1i, Uniform1f, - Uniform2fv, - Uniform3fv, - Uniform4fv + Uniform2f, + Uniform3f, + Uniform4f } from '../../../src/render/uniform_binding'; test('Uniform1i', (t) => { @@ -46,7 +46,7 @@ test('Uniform1f', (t) => { t.end(); }); -test('Uniform2fv', (t) => { +test('Uniform2f', (t) => { t.plan(4); const context = { @@ -55,7 +55,7 @@ test('Uniform2fv', (t) => { } }; - const u = new Uniform2fv(context, 0); + const u = new Uniform2f(context, 0); t.deepEqual(u.current, [0, 0], 'not set upon initialization'); u.set([1, 1]); @@ -65,7 +65,7 @@ test('Uniform2fv', (t) => { t.end(); }); -test('Uniform3fv', (t) => { +test('Uniform3f', (t) => { t.plan(4); const context = { @@ -74,7 +74,7 @@ test('Uniform3fv', (t) => { } }; - const u = new Uniform3fv(context, 0); + const u = new Uniform3f(context, 0); t.deepEqual(u.current, [0, 0, 0], 'not set upon initialization'); u.set([1, 1, 1]); @@ -84,7 +84,7 @@ test('Uniform3fv', (t) => { t.end(); }); -test('Uniform4fv', (t) => { +test('Uniform4f', (t) => { t.plan(4); const context = { @@ -93,7 +93,7 @@ test('Uniform4fv', (t) => { } }; - const u = new Uniform4fv(context, 0); + const u = new Uniform4f(context, 0); t.deepEqual(u.current, [0, 0, 0, 0], 'not set upon initialization'); u.set([1, 1, 1, 1]);