From e10bc8af13c11d4b95ba1e8967df222da456bdea Mon Sep 17 00:00:00 2001 From: Lauren Budorick Date: Tue, 24 Oct 2017 12:59:45 -0700 Subject: [PATCH 1/9] Introduce WebGL context state tracking classes --- src/data/bucket.js | 3 +- src/data/bucket/circle_bucket.js | 13 +- src/data/bucket/fill_bucket.js | 15 +- src/data/bucket/fill_extrusion_bucket.js | 13 +- src/data/bucket/line_bucket.js | 13 +- src/data/bucket/symbol_bucket.js | 29 +- src/data/program_configuration.js | 28 +- src/gl/context.js | 163 +++++++ src/gl/index_buffer.js | 31 +- src/gl/state.js | 35 ++ src/gl/types.js | 60 +++ src/gl/value.js | 320 +++++++++++++ src/gl/vertex_buffer.js | 20 +- src/render/draw_background.js | 11 +- src/render/draw_circle.js | 11 +- src/render/draw_collision_debug.js | 5 +- src/render/draw_debug.js | 12 +- src/render/draw_fill.js | 22 +- src/render/draw_fill_extrusion.js | 34 +- src/render/draw_heatmap.js | 65 +-- src/render/draw_line.js | 22 +- src/render/draw_raster.js | 21 +- src/render/draw_symbol.js | 34 +- src/render/image_manager.js | 6 +- src/render/line_atlas.js | 9 +- src/render/painnnter | 561 +++++++++++++++++++++++ src/render/painter.js | 172 +++---- src/render/pattern.js | 9 +- src/render/program.js | 12 +- src/render/render_texture.js | 20 +- src/render/texture.js | 25 +- src/render/tile_mask.js | 5 +- src/render/vertex_array_object.js | 34 +- src/source/canvas_source.js | 2 +- src/source/image_source.js | 12 +- src/source/raster_tile_source.js | 5 +- src/source/source_cache.js | 5 +- src/source/tile.js | 21 +- src/source/video_source.js | 2 +- src/ui/map.js | 2 +- yarn.lock | 436 ++++-------------- 41 files changed, 1625 insertions(+), 693 deletions(-) create mode 100644 src/gl/context.js create mode 100644 src/gl/state.js create mode 100644 src/gl/types.js create mode 100644 src/gl/value.js create mode 100644 src/render/painnnter diff --git a/src/data/bucket.js b/src/data/bucket.js index bb1e03005c7..e467442a1f6 100644 --- a/src/data/bucket.js +++ b/src/data/bucket.js @@ -7,6 +7,7 @@ import type Style from '../style/style'; import type StyleLayer from '../style/style_layer'; import type FeatureIndex from './feature_index'; import type {Serialized} from '../util/web_worker_transfer'; +import type Context from '../gl/context'; export type BucketParameters = { index: number, @@ -58,7 +59,7 @@ export interface Bucket { populate(features: Array, options: PopulateParameters): void; isEmpty(): boolean; - upload(gl: WebGLRenderingContext): void; + upload(context: Context): void; uploaded: boolean; /** diff --git a/src/data/bucket/circle_bucket.js b/src/data/bucket/circle_bucket.js index 764e54cf16d..71ad8f5fe01 100644 --- a/src/data/bucket/circle_bucket.js +++ b/src/data/bucket/circle_bucket.js @@ -1,8 +1,6 @@ // @flow const {SegmentVector} = require('../segment'); -const VertexBuffer = require('../../gl/vertex_buffer'); -const IndexBuffer = require('../../gl/index_buffer'); const {ProgramConfigurationSet} = require('../program_configuration'); const createVertexArrayType = require('../vertex_array_type'); const {TriangleIndexArray} = require('../index_array_type'); @@ -19,6 +17,9 @@ import type { import type {ProgramInterface} from '../program_configuration'; import type StyleLayer from '../../style/style_layer'; import type {StructArray} from '../../util/struct_array'; +import type Context from '../../gl/context'; +import type IndexBuffer from '../../gl/index_buffer'; +import type VertexBuffer from '../../gl/vertex_buffer'; import type Point from '@mapbox/point-geometry'; const circleInterface = { @@ -100,10 +101,10 @@ class CircleBucket implements Bucket { return this.layoutVertexArray.length === 0; } - upload(gl: WebGLRenderingContext) { - this.layoutVertexBuffer = new VertexBuffer(gl, this.layoutVertexArray); - this.indexBuffer = new IndexBuffer(gl, this.indexArray); - this.programConfigurations.upload(gl); + upload(context: Context) { + this.layoutVertexBuffer = context.createVertexBuffer(this.layoutVertexArray); + this.indexBuffer = context.createIndexBuffer(this.indexArray); + this.programConfigurations.upload(context); } destroy() { diff --git a/src/data/bucket/fill_bucket.js b/src/data/bucket/fill_bucket.js index 65bb461a631..d7352939807 100644 --- a/src/data/bucket/fill_bucket.js +++ b/src/data/bucket/fill_bucket.js @@ -1,8 +1,6 @@ // @flow const {SegmentVector} = require('../segment'); -const VertexBuffer = require('../../gl/vertex_buffer'); -const IndexBuffer = require('../../gl/index_buffer'); const {ProgramConfigurationSet} = require('../program_configuration'); const createVertexArrayType = require('../vertex_array_type'); const {LineIndexArray, TriangleIndexArray} = require('../index_array_type'); @@ -22,6 +20,9 @@ import type { import type {ProgramInterface} from '../program_configuration'; import type StyleLayer from '../../style/style_layer'; import type {StructArray} from '../../util/struct_array'; +import type Context from '../../gl/context'; +import type IndexBuffer from '../../gl/index_buffer'; +import type VertexBuffer from '../../gl/vertex_buffer'; import type Point from '@mapbox/point-geometry'; const fillInterface = { @@ -92,11 +93,11 @@ class FillBucket implements Bucket { return this.layoutVertexArray.length === 0; } - upload(gl: WebGLRenderingContext) { - this.layoutVertexBuffer = new VertexBuffer(gl, this.layoutVertexArray); - this.indexBuffer = new IndexBuffer(gl, this.indexArray); - this.indexBuffer2 = new IndexBuffer(gl, this.indexArray2); - this.programConfigurations.upload(gl); + upload(context: Context) { + this.layoutVertexBuffer = context.createVertexBuffer(this.layoutVertexArray); + this.indexBuffer = context.createIndexBuffer(this.indexArray); + this.indexBuffer2 = context.createIndexBuffer(this.indexArray2); + this.programConfigurations.upload(context); } destroy() { diff --git a/src/data/bucket/fill_extrusion_bucket.js b/src/data/bucket/fill_extrusion_bucket.js index f75a6373932..7483f26681f 100644 --- a/src/data/bucket/fill_extrusion_bucket.js +++ b/src/data/bucket/fill_extrusion_bucket.js @@ -1,8 +1,6 @@ // @flow const {SegmentVector, MAX_VERTEX_ARRAY_LENGTH} = require('../segment'); -const VertexBuffer = require('../../gl/vertex_buffer'); -const IndexBuffer = require('../../gl/index_buffer'); const {ProgramConfigurationSet} = require('../program_configuration'); const createVertexArrayType = require('../vertex_array_type'); const {TriangleIndexArray} = require('../index_array_type'); @@ -23,6 +21,9 @@ import type { import type {ProgramInterface} from '../program_configuration'; import type StyleLayer from '../../style/style_layer'; import type {StructArray} from '../../util/struct_array'; +import type Context from '../../gl/context'; +import type IndexBuffer from '../../gl/index_buffer'; +import type VertexBuffer from '../../gl/vertex_buffer'; import type Point from '@mapbox/point-geometry'; const fillExtrusionInterface = { @@ -105,10 +106,10 @@ class FillExtrusionBucket implements Bucket { return this.layoutVertexArray.length === 0; } - upload(gl: WebGLRenderingContext) { - this.layoutVertexBuffer = new VertexBuffer(gl, this.layoutVertexArray); - this.indexBuffer = new IndexBuffer(gl, this.indexArray); - this.programConfigurations.upload(gl); + upload(context: Context) { + this.layoutVertexBuffer = context.createVertexBuffer(this.layoutVertexArray); + this.indexBuffer = context.createIndexBuffer(this.indexArray); + this.programConfigurations.upload(context); } destroy() { diff --git a/src/data/bucket/line_bucket.js b/src/data/bucket/line_bucket.js index 80708b0ae55..7207834ea54 100644 --- a/src/data/bucket/line_bucket.js +++ b/src/data/bucket/line_bucket.js @@ -1,8 +1,6 @@ // @flow const {SegmentVector} = require('../segment'); -const VertexBuffer = require('../../gl/vertex_buffer'); -const IndexBuffer = require('../../gl/index_buffer'); const {ProgramConfigurationSet} = require('../program_configuration'); const createVertexArrayType = require('../vertex_array_type'); const {TriangleIndexArray} = require('../index_array_type'); @@ -21,6 +19,9 @@ import type {ProgramInterface} from '../program_configuration'; import type LineStyleLayer from '../../style/style_layer/line_style_layer'; import type Point from '@mapbox/point-geometry'; import type {Segment} from '../segment'; +import type Context from '../../gl/context'; +import type IndexBuffer from '../../gl/index_buffer'; +import type VertexBuffer from '../../gl/vertex_buffer'; import type {StructArray} from '../../util/struct_array'; // NOTE ON EXTRUDE SCALE: @@ -149,10 +150,10 @@ class LineBucket implements Bucket { return this.layoutVertexArray.length === 0; } - upload(gl: WebGLRenderingContext) { - this.layoutVertexBuffer = new VertexBuffer(gl, this.layoutVertexArray); - this.indexBuffer = new IndexBuffer(gl, this.indexArray); - this.programConfigurations.upload(gl); + upload(context: Context) { + this.layoutVertexBuffer = context.createVertexBuffer(this.layoutVertexArray); + this.indexBuffer = context.createIndexBuffer(this.indexArray); + this.programConfigurations.upload(context); } destroy() { diff --git a/src/data/bucket/symbol_bucket.js b/src/data/bucket/symbol_bucket.js index a1e1c516b06..1fdc6cb5d0d 100644 --- a/src/data/bucket/symbol_bucket.js +++ b/src/data/bucket/symbol_bucket.js @@ -2,8 +2,6 @@ const Point = require('@mapbox/point-geometry'); const {SegmentVector} = require('../segment'); -const VertexBuffer = require('../../gl/vertex_buffer'); -const IndexBuffer = require('../../gl/index_buffer'); const {ProgramConfigurationSet} = require('../program_configuration'); const createVertexArrayType = require('../vertex_array_type'); const {TriangleIndexArray, LineIndexArray} = require('../index_array_type'); @@ -30,6 +28,9 @@ import type {ProgramInterface, LayoutAttribute} from '../program_configuration'; import type CollisionBoxArray, {CollisionBox} from '../../symbol/collision_box'; import type { StructArray } from '../../util/struct_array'; import type SymbolStyleLayer from '../../style/style_layer/symbol_style_layer'; +import type Context from '../../gl/context'; +import type IndexBuffer from '../../gl/index_buffer'; +import type VertexBuffer from '../../gl/vertex_buffer'; import type {SymbolQuad} from '../../symbol/quads'; import type {SizeData} from '../../symbol/symbol_size'; import type {PossiblyEvaluatedPropertyValue} from '../../style/properties'; @@ -266,23 +267,23 @@ class SymbolBuffers { } - upload(gl: WebGLRenderingContext, dynamicIndexBuffer) { - this.layoutVertexBuffer = new VertexBuffer(gl, this.layoutVertexArray); - this.indexBuffer = new IndexBuffer(gl, this.indexArray, dynamicIndexBuffer); - this.programConfigurations.upload(gl); + upload(context: Context, dynamicIndexBuffer) { + this.layoutVertexBuffer = context.createVertexBuffer(this.layoutVertexArray); + this.indexBuffer = context.createIndexBuffer(this.indexArray, dynamicIndexBuffer); + this.programConfigurations.upload(context); if (this.dynamicLayoutAttributes) { - this.dynamicLayoutVertexBuffer = new VertexBuffer(gl, this.dynamicLayoutVertexArray, true); + this.dynamicLayoutVertexBuffer = context.createVertexBuffer(this.dynamicLayoutVertexArray, true); } if (this.opacityAttributes) { - this.opacityVertexBuffer = new VertexBuffer(gl, this.opacityVertexArray, true); + this.opacityVertexBuffer = context.createVertexBuffer(this.opacityVertexArray, true); // This is a performance hack so that we can write to opacityVertexArray with uint32s // even though the shaders read uint8s this.opacityVertexBuffer.itemSize = 1; this.opacityVertexBuffer.attributes = shaderOpacityAttributes; } if (this.collisionAttributes) { - this.collisionVertexBuffer = new VertexBuffer(gl, this.collisionVertexArray, true); + this.collisionVertexBuffer = context.createVertexBuffer(this.collisionVertexArray, true); } } @@ -539,11 +540,11 @@ class SymbolBucket implements Bucket { return this.symbolInstances.length === 0; } - upload(gl: WebGLRenderingContext) { - this.text.upload(gl, this.sortFeaturesByY); - this.icon.upload(gl, this.sortFeaturesByY); - this.collisionBox.upload(gl); - this.collisionCircle.upload(gl); + upload(context: Context) { + this.text.upload(context, this.sortFeaturesByY); + this.icon.upload(context, this.sortFeaturesByY); + this.collisionBox.upload(context); + this.collisionCircle.upload(context); } destroy() { diff --git a/src/data/program_configuration.js b/src/data/program_configuration.js index 697e6bd6f3e..d83dc711a68 100644 --- a/src/data/program_configuration.js +++ b/src/data/program_configuration.js @@ -4,13 +4,14 @@ import type {GlobalProperties} from "../style-spec/expression/index"; const createVertexArrayType = require('./vertex_array_type'); const packUint8ToFloat = require('../shaders/encode_attribute').packUint8ToFloat; -const VertexBuffer = require('../gl/vertex_buffer'); const Color = require('../style-spec/util/color'); const {deserialize, serialize, register} = require('../util/web_worker_transfer'); +const Context = require('../gl/context'); import type StyleLayer from '../style/style_layer'; import type {Serialized} from '../util/web_worker_transfer'; import type {ViewType, StructArray} from '../util/struct_array'; +import type VertexBuffer from '../gl/vertex_buffer'; import type Program from '../render/program'; import type {Feature, SourceExpression, CompositeExpression} from '../style-spec/expression'; import type {PossiblyEvaluated, PossiblyEvaluatedPropertyValue} from '../style/properties'; @@ -84,7 +85,7 @@ interface Binder { defines(): Array; - setUniforms(gl: WebGLRenderingContext, + setUniforms(context: Context, program: Program, globals: GlobalProperties, currentValue: PossiblyEvaluatedPropertyValue): void; @@ -111,11 +112,12 @@ class ConstantBinder implements Binder { populatePaintArray() {} - setUniforms(gl: WebGLRenderingContext, + 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 { @@ -166,8 +168,8 @@ class SourceExpressionBinder implements Binder { } } - setUniforms(gl: WebGLRenderingContext, program: Program) { - gl.uniform1f(program.uniforms[`a_${this.name}_t`], 0); + setUniforms(context: Context, program: Program) { + context.gl.uniform1f(program.uniforms[`a_${this.name}_t`], 0); } } @@ -230,8 +232,8 @@ class CompositeExpressionBinder implements Binder { } } - setUniforms(gl: WebGLRenderingContext, program: Program, globals: GlobalProperties) { - gl.uniform1f(program.uniforms[`a_${this.name}_t`], this.interpolationFactor(globals.zoom)); + setUniforms(context: Context, program: Program, globals: GlobalProperties) { + context.gl.uniform1f(program.uniforms[`a_${this.name}_t`], this.interpolationFactor(globals.zoom)); } } @@ -362,16 +364,16 @@ class ProgramConfiguration { return result; } - setUniforms(gl: WebGLRenderingContext, program: Program, properties: PossiblyEvaluated, globals: GlobalProperties) { + setUniforms(context: Context, program: Program, properties: PossiblyEvaluated, globals: GlobalProperties) { for (const property in this.binders) { const binder = this.binders[property]; - binder.setUniforms(gl, program, globals, properties.get(binder.property)); + binder.setUniforms(context, program, globals, properties.get(binder.property)); } } - upload(gl: WebGLRenderingContext) { + upload(context: Context) { if (this.paintVertexArray) { - this.paintVertexBuffer = new VertexBuffer(gl, this.paintVertexArray); + this.paintVertexBuffer = context.createVertexBuffer(this.paintVertexArray); } } @@ -414,9 +416,9 @@ class ProgramConfigurationSet { return this.programConfigurations[layerId]; } - upload(gl: WebGLRenderingContext) { + upload(context: Context) { for (const layerId in this.programConfigurations) { - this.programConfigurations[layerId].upload(gl); + this.programConfigurations[layerId].upload(context); } } diff --git a/src/gl/context.js b/src/gl/context.js new file mode 100644 index 00000000000..d3024955491 --- /dev/null +++ b/src/gl/context.js @@ -0,0 +1,163 @@ +// @flow +const IndexBuffer = require('./index_buffer'); +const VertexBuffer = require('./vertex_buffer'); +const State = require('./state'); +const { + ClearColor, + ClearDepth, + ClearStencil, + ColorMask, + DepthMask, + StencilMask, + StencilFunc, + StencilOp, + StencilTest, + DepthRange, + DepthTest, + DepthFunc, + Blend, + BlendFunc, + BlendColor, + Program, + LineWidth, + ActiveTextureUnit, + Viewport, + BindFramebuffer, + BindRenderbuffer, + BindTexture, + BindVertexBuffer, + BindElementBuffer, + BindVertexArrayOES, + PixelStoreUnpack, + PixelStoreUnpackPremultiplyAlpha, +} = require('./value'); + + +import type {TriangleIndexArray, LineIndexArray} from '../data/index_array_type'; +import type {StructArray} from '../util/struct_array'; +import type { + BlendFuncType, + ColorType, + ColorMaskType, + DepthRangeType, + StencilFuncType, + DepthFuncType, + StencilOpType, + TextureUnitType, + ViewportType, +} from './types'; + +type ClearArgs = { + color?: ColorType, + depth?: number, + stencil?: number + // TODO previously painter had `clearDepth`, `clearColor`, `clearStencil` + // methods so that callers wouldn't need to know appropriate/default values + // for clearing...should we still provide some such help or no? painter now + // calls context.clear in several places and has to know appropriate values +}; + + +class Context { + gl: WebGLRenderingContext; + extVertexArrayObject: any; + currentNumAttributes: ?number; + + clearColor: State; + clearDepth: State; + clearStencil: State; + colorMask: State; + depthMask: State; + stencilMask: State; + stencilFunc: State; + stencilOp: State; + stencilTest: State; + depthRange: State; + depthTest: State; + depthFunc: State; + blend: State; + blendFunc: State; + blendColor: State; + program: State; + lineWidth: State; + activeTexture: State; + viewport: State; + bindFramebuffer: State; + bindRenderbuffer: State + bindTexture: State; + bindVertexBuffer: State; + bindElementBuffer: State; + bindVertexArrayOES: State; + pixelStoreUnpack: State; + pixelStoreUnpackPremultiplyAlpha: State; + + constructor(gl: WebGLRenderingContext) { + this.gl = gl; + this.extVertexArrayObject = this.gl.getExtension('OES_vertex_array_object'); + // TODO is there any reason to wait to try to initialize this? + + this.clearColor = new State(new ClearColor(this)); + this.clearDepth = new State(new ClearDepth(this)); + this.clearStencil = new State(new ClearStencil(this)); + this.colorMask = new State(new ColorMask(this)); + this.depthMask = new State(new DepthMask(this)); + this.stencilMask = new State(new StencilMask(this)); + this.stencilFunc = new State(new StencilFunc(this)); + this.stencilOp = new State(new StencilOp(this)); + this.stencilTest = new State(new StencilTest(this)); + this.depthRange = new State(new DepthRange(this)); + this.depthTest = new State(new DepthTest(this)); + this.depthFunc = new State(new DepthFunc(this)); + this.blend = new State(new Blend(this)); + this.blendFunc = new State(new BlendFunc(this)); + this.blendColor = new State(new BlendColor(this)); + this.program = new State(new Program(this)); + this.lineWidth = new State(new LineWidth(this)); + this.activeTexture = new State(new ActiveTextureUnit(this)); + this.viewport = new State(new Viewport(this)); + this.bindFramebuffer = new State(new BindFramebuffer(this)); + this.bindRenderbuffer = new State(new BindRenderbuffer(this)); + this.bindTexture = new State(new BindTexture(this)); + this.bindVertexBuffer = new State(new BindVertexBuffer(this)); + this.bindElementBuffer = new State(new BindElementBuffer(this)); + this.bindVertexArrayOES = this.extVertexArrayObject && new State(new BindVertexArrayOES(this)); + this.pixelStoreUnpack = new State(new PixelStoreUnpack(this)); + this.pixelStoreUnpackPremultiplyAlpha = new State(new PixelStoreUnpackPremultiplyAlpha(this)); + } + + createIndexBuffer(array: TriangleIndexArray | LineIndexArray, dynamicDraw?: boolean) { + return new IndexBuffer(this, array, dynamicDraw); + } + + createVertexBuffer(array: StructArray, dynamicDraw?: boolean) { + return new VertexBuffer(this, array, dynamicDraw); + } + + clear({color, depth, stencil}: ClearArgs) { + const gl = this.gl; + let mask = 0; + + if (color) { + mask |= gl.COLOR_BUFFER_BIT; + this.clearColor.set(color); + this.colorMask.set([true, true, true, true]); + } + + if (typeof depth !== 'undefined') { + mask |= gl.DEPTH_BUFFER_BIT; + this.clearDepth.set(depth); + this.depthMask.set(true); + } + + // See note in Painter#clearStencil: implement this the easy way once GPU bug/workaround is fixed upstream + // if (typeof stencil !== 'undefined') { + // mask |= gl.STENCIL_BUFFER_BIT; + // this.clearStencil.set(stencil); + // this.stencilMask.set(0xFF); + // } + + gl.clear(mask); + } +} + +module.exports = Context; diff --git a/src/gl/index_buffer.js b/src/gl/index_buffer.js index d81f53c1a32..f8ace9a20ee 100644 --- a/src/gl/index_buffer.js +++ b/src/gl/index_buffer.js @@ -3,21 +3,24 @@ const assert = require('assert'); import type {StructArray} from '../util/struct_array'; import type {TriangleIndexArray, LineIndexArray} from '../data/index_array_type'; +import type {SerializedStructArray} from '../util/struct_array'; +import type Context from '../gl/context'; class IndexBuffer { - gl: WebGLRenderingContext; + context: Context; buffer: WebGLBuffer; dynamicDraw: boolean; - constructor(gl: WebGLRenderingContext, array: TriangleIndexArray | LineIndexArray, dynamicDraw?: boolean) { - this.gl = gl; + constructor(context: Context, array: TriangleIndexArray | LineIndexArray, dynamicDraw?: boolean) { + this.context = context; + const gl = context.gl; this.buffer = gl.createBuffer(); this.dynamicDraw = Boolean(dynamicDraw); this.unbindVAO(); - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.buffer); + context.bindElementBuffer.set(this.buffer); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, array.arrayBuffer, this.dynamicDraw ? gl.DYNAMIC_DRAW : gl.STATIC_DRAW); if (!this.dynamicDraw) { @@ -29,30 +32,34 @@ class IndexBuffer { // The bound index buffer is part of vertex array object state. We don't want to // modify whatever VAO happens to be currently bound, so make sure the default // vertex array provided by the context is bound instead. - if (this.gl.extVertexArrayObject === undefined) { - (this.gl: any).extVertexArrayObject = this.gl.getExtension("OES_vertex_array_object"); - } - if (this.gl.extVertexArrayObject) { - (this.gl: any).extVertexArrayObject.bindVertexArrayOES(null); + if (this.context.extVertexArrayObject) { + this.context.bindVertexArrayOES.set(null); } } bind() { - this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.buffer); + const gl = this.context.gl; + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.buffer); + // this.context.bindElementBuffer.set(this.buffer); + // TODO not sure why this doesn't work, but using bindElementBuffer throws: + // [.Offscreen-For-WebGL-0x7fbaf382a800]GL ERROR :GL_INVALID_OPERATION : + // glDrawElements: bound to target 0x8893 : no buffer } updateData(array: StructArray) { + const gl = this.context.gl; assert(this.dynamicDraw); // The right VAO will get this buffer re-bound later in VertexArrayObject#bind // See https://github.com/mapbox/mapbox-gl-js/issues/5620 this.unbindVAO(); this.bind(); - this.gl.bufferSubData(this.gl.ELEMENT_ARRAY_BUFFER, 0, array.arrayBuffer); + gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER, 0, array.arrayBuffer); } destroy() { + const gl = this.context.gl; if (this.buffer) { - this.gl.deleteBuffer(this.buffer); + gl.deleteBuffer(this.buffer); delete this.buffer; } } diff --git a/src/gl/state.js b/src/gl/state.js new file mode 100644 index 00000000000..7cb7817cd25 --- /dev/null +++ b/src/gl/state.js @@ -0,0 +1,35 @@ +// @flow + +import type {Value} from './value'; + +class State { + value: Value; + current: T; + dirty: boolean; + + constructor(v: Value) { + this.value = v; + this.current = v.constructor.default(v.context); + } + + get(): T { + return this.current; + } + + set(t: T) { + if (this.current !== t) { + this.current = t; + this.value.set(t); + } + } + + setDirty(): void { + this.dirty = true; + } + + isDirty(): boolean { + return this.dirty; + } +} + +module.exports = State; diff --git a/src/gl/types.js b/src/gl/types.js new file mode 100644 index 00000000000..64c9179e376 --- /dev/null +++ b/src/gl/types.js @@ -0,0 +1,60 @@ +// @flow + +type BlendFuncConstant = + | $PropertyType + | $PropertyType + | $PropertyType + | $PropertyType + | $PropertyType + | $PropertyType + | $PropertyType + | $PropertyType + | $PropertyType + | $PropertyType + | $PropertyType + | $PropertyType + | $PropertyType + | $PropertyType + | $PropertyType; + +export type BlendFuncType = [BlendFuncConstant, BlendFuncConstant]; + +export type ColorType = [number, number, number, number]; + +export type ColorMaskType = [boolean, boolean, boolean, boolean]; + +export type DepthRangeType = [number, number]; + +export type CompareFuncType = + | $PropertyType + | $PropertyType + | $PropertyType + | $PropertyType + | $PropertyType + | $PropertyType + | $PropertyType + | $PropertyType; + +export type StencilFuncType = { + func: CompareFuncType, + ref: number, + mask: number +}; + +export type DepthFuncType = CompareFuncType; + +type StencilOpConstant = + | $PropertyType + | $PropertyType + | $PropertyType + | $PropertyType + | $PropertyType + | $PropertyType + | $PropertyType + | $PropertyType; + +export type StencilOpType = [StencilOpConstant, StencilOpConstant, StencilOpConstant]; + +export type TextureUnitType = number; + +export type ViewportType = [number, number, number, number]; diff --git a/src/gl/value.js b/src/gl/value.js new file mode 100644 index 00000000000..e8d672540b7 --- /dev/null +++ b/src/gl/value.js @@ -0,0 +1,320 @@ +// @flow + +import type Context from './context'; +import type { + BlendFuncType, + ColorType, + ColorMaskType, + DepthRangeType, + StencilFuncType, + StencilOpType, + DepthFuncType, + TextureUnitType, + ViewportType, +} from './types'; + +export interface Value { + context: Context; + static default(context?: Context): T; + set(value: T): void; +} + +class ContextValue { + context: Context; + + constructor(context: Context) { + this.context = context; + } +} + +class ClearColor extends ContextValue implements Value { + static default() { return [0, 0, 0, 0]; } + + set(v: ColorType): void { + this.context.gl.clearColor(v[0], v[1], v[2], v[3]); + } +} + +class ClearDepth extends ContextValue implements Value { + static default() { return 1; } + + set(v: number): void { + this.context.gl.clearDepth(v); + } +} + +class ClearStencil extends ContextValue implements Value { + static default() { return 0; } + + set(v: number): void { + this.context.gl.clearStencil(v); + } +} + +class ColorMask extends ContextValue implements Value { + static default() { return [true, true, true, true]; } + + set(v: ColorMaskType): void { + this.context.gl.colorMask(v[0], v[1], v[2], v[3]); + } +} + +class DepthMask extends ContextValue implements Value { + static default() { return true; } + + set(v: boolean): void { + this.context.gl.depthMask(v); + } +} + +class StencilMask extends ContextValue implements Value { + static default() { return 0xFF; } + + set(v: number): void { + this.context.gl.stencilMask(v); + } +} + +class StencilFunc extends ContextValue implements Value { + static default(context: Context) { + return { + func: context.gl.ALWAYS, + ref: 0, + mask: 0xFF + }; + } + + set(v: StencilFuncType): void { + this.context.gl.stencilFunc(v.func, v.ref, v.mask); + } +} + +class StencilOp extends ContextValue implements Value { + static default(context: Context) { + const gl = context.gl; + return [gl.KEEP, gl.KEEP, gl.KEEP]; + } + + set(v: StencilOpType): void { + this.context.gl.stencilOp(v[0], v[1], v[2]); + } +} + +class StencilTest extends ContextValue implements Value { + static default() { return false; } + + set(v: boolean): void { + const gl = this.context.gl; + if (v) { + gl.enable(gl.STENCIL_TEST); + } else { + gl.disable(gl.STENCIL_TEST); + } + } +} + +class DepthRange extends ContextValue implements Value { + static default() { return [0, 1]; } + + set(v: DepthRangeType): void { + this.context.gl.depthRange(v[0], v[1]); + } +} + +class DepthTest extends ContextValue implements Value { + static default() { return false; } + + set(v: boolean): void { + const gl = this.context.gl; + if (v) { + gl.enable(gl.DEPTH_TEST); + } else { + gl.disable(gl.DEPTH_TEST); + } + } +} + +class DepthFunc extends ContextValue implements Value { + static default(context: Context) { + return context.gl.LESS; + } + + set(v: DepthFuncType): void { + this.context.gl.depthFunc(v); + } +} + +class Blend extends ContextValue implements Value { + static default() { return true; } + + set(v: boolean): void { + const gl = this.context.gl; + if (v) { + gl.enable(gl.BLEND); + } else { + gl.disable(gl.BLEND); + } + } +} + +class BlendFunc extends ContextValue implements Value { + static default(context: Context) { + const gl = context.gl; + return [gl.ONE, gl.ZERO]; + } + + set(v: BlendFuncType): void { + this.context.gl.blendFunc(v[0], v[1]); + } +} + +class BlendColor extends ContextValue implements Value { + static default() { return [0, 0, 0, 0]; } + + set(v: ColorType): void { + this.context.gl.blendColor(v[0], v[1], v[2], v[3]); + } +} + +class Program extends ContextValue implements Value { + static default() { return null; } + + set(v: ?WebGLProgram): void { + this.context.gl.useProgram(v); + } +} + +class LineWidth extends ContextValue implements Value { + static default() { return 1; } + + set(v: number): void { + this.context.gl.lineWidth(v); + } +} + +class ActiveTextureUnit extends ContextValue implements Value { + static default(context: Context) { + return context.gl.TEXTURE0; + } + + set(v: TextureUnitType): void { + this.context.gl.activeTexture(v); + } +} + +class Viewport extends ContextValue implements Value { + static default(context: Context) { + const gl = context.gl; + return [0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight]; + } + + set(v: ViewportType): void { + this.context.gl.viewport(v[0], v[1], v[2], v[3]); + } +} + +class BindFramebuffer extends ContextValue implements Value { + static default() { return null; } + + set(v: ?WebGLFramebuffer): void { + const gl = this.context.gl; + gl.bindFramebuffer(gl.FRAMEBUFFER, v); + } +} + +class BindRenderbuffer extends ContextValue implements Value { + static default() { return null; } + + set(v: ?WebGLRenderbuffer): void { + const gl = this.context.gl; + gl.bindRenderbuffer(gl.RENDERBUFFER, v); + } +} + +class BindTexture extends ContextValue implements Value { + static default() { return null; } + + set(v: ?WebGLTexture): void { + const gl = this.context.gl; + gl.bindTexture(gl.TEXTURE_2D, v); + } +} + +class BindVertexBuffer extends ContextValue implements Value { + static default() { return null; } + + set(v: ?WebGLBuffer): void { + const gl = this.context.gl; + gl.bindBuffer(gl.ARRAY_BUFFER, v); + } +} + +class BindElementBuffer extends ContextValue implements Value { + static default() { return null; } + + set(v: ?WebGLBuffer): void { + const gl = this.context.gl; + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, v); + } +} + +class BindVertexArrayOES extends ContextValue implements Value { + static default() { return null; } + + set(v: ?any): void { + const context = this.context; + if (context.extVertexArrayObject) { + context.extVertexArrayObject.bindVertexArrayOES(v); + } + } +} + +class PixelStoreUnpack extends ContextValue implements Value { + static default() { return 4; } + + set(v: number): void { + const gl = this.context.gl; + gl.pixelStorei(gl.UNPACK_ALIGNMENT, v); + } +} + +class PixelStoreUnpackPremultiplyAlpha extends ContextValue implements Value { + static default() { return false; } + + set(v: boolean): void { + const gl = this.context.gl; + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, (v: any)); + } +} + +module.exports = { + ClearColor, + ClearDepth, + ClearStencil, + ColorMask, + DepthMask, + StencilMask, + StencilFunc, + StencilOp, + StencilTest, + DepthRange, + DepthTest, + DepthFunc, + Blend, + BlendFunc, + BlendColor, + + Program, + LineWidth, + ActiveTextureUnit, + Viewport, + BindFramebuffer, + BindRenderbuffer, + BindTexture, + BindVertexBuffer, + BindElementBuffer, + BindVertexArrayOES, + // VertexAttribute, + PixelStoreUnpack, + PixelStoreUnpackPremultiplyAlpha, +}; diff --git a/src/gl/vertex_buffer.js b/src/gl/vertex_buffer.js index 066a0819627..643ae932400 100644 --- a/src/gl/vertex_buffer.js +++ b/src/gl/vertex_buffer.js @@ -6,6 +6,7 @@ import type { } from '../util/struct_array'; import type Program from '../render/program'; +import type Context from '../gl/context'; /** * @enum {string} AttributeType @@ -32,22 +33,23 @@ class VertexBuffer { attributes: Array; itemSize: number; dynamicDraw: ?boolean; - gl: WebGLRenderingContext; + context: Context; buffer: WebGLBuffer; /** * @param dynamicDraw Whether this buffer will be repeatedly updated. */ - constructor(gl: WebGLRenderingContext, array: StructArray, dynamicDraw?: boolean) { + constructor(context: Context, array: StructArray, dynamicDraw?: boolean) { this.length = array.length; this.attributes = array.members; this.itemSize = array.bytesPerElement; this.dynamicDraw = dynamicDraw; - this.gl = gl; + this.context = context; + const gl = context.gl; this.buffer = gl.createBuffer(); - this.gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer); - this.gl.bufferData(gl.ARRAY_BUFFER, array.arrayBuffer, this.dynamicDraw ? gl.DYNAMIC_DRAW : gl.STATIC_DRAW); + context.bindVertexBuffer.set(this.buffer); + gl.bufferData(gl.ARRAY_BUFFER, array.arrayBuffer, this.dynamicDraw ? gl.DYNAMIC_DRAW : gl.STATIC_DRAW); if (!this.dynamicDraw) { delete array.arrayBuffer; @@ -55,12 +57,13 @@ class VertexBuffer { } bind() { - this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.buffer); + this.context.bindVertexBuffer.set(this.buffer); } updateData(array: StructArray) { + const gl = this.context.gl; this.bind(); - this.gl.bufferSubData(this.gl.ARRAY_BUFFER, 0, array.arrayBuffer); + gl.bufferSubData(gl.ARRAY_BUFFER, 0, array.arrayBuffer); } enableAttributes(gl: WebGLRenderingContext, program: Program) { @@ -101,8 +104,9 @@ class VertexBuffer { * Destroy the GL buffer bound to the given WebGL context */ destroy() { + const gl = this.context.gl; if (this.buffer) { - this.gl.deleteBuffer(this.buffer); + gl.deleteBuffer(this.buffer); delete this.buffer; } } diff --git a/src/render/draw_background.js b/src/render/draw_background.js index fbd06f4f076..74252357727 100644 --- a/src/render/draw_background.js +++ b/src/render/draw_background.js @@ -17,7 +17,8 @@ function drawBackground(painter: Painter, sourceCache: SourceCache, layer: Backg if (opacity === 0) return; - const gl = painter.gl; + const context = painter.context; + const gl = context.gl; const transform = painter.transform; const tileSize = transform.tileSize; const image = layer.paint.get('background-pattern'); @@ -26,7 +27,7 @@ function drawBackground(painter: Painter, sourceCache: SourceCache, layer: Backg const pass = (!image && color.a === 1 && opacity === 1) ? 'opaque' : 'translucent'; if (painter.renderPass !== pass) return; - gl.disable(gl.STENCIL_TEST); + context.stencilTest.set(false); painter.setDepthSublayer(0); @@ -44,12 +45,12 @@ function drawBackground(painter: Painter, sourceCache: SourceCache, layer: Backg program = painter.useProgram('fillPattern', configuration); configuration.setUniforms(gl, program, properties, globals); pattern.prepare(image, painter, program); - painter.tileExtentPatternVAO.bind(gl, program, painter.tileExtentBuffer); + painter.tileExtentPatternVAO.bind(context, program, painter.tileExtentBuffer); } else { const configuration = ProgramConfiguration.forBackgroundColor(color, opacity); program = painter.useProgram('fill', configuration); - configuration.setUniforms(gl, program, properties, globals); - painter.tileExtentVAO.bind(gl, program, painter.tileExtentBuffer); + configuration.setUniforms(context, program, properties, globals); + painter.tileExtentVAO.bind(context, program, painter.tileExtentBuffer); } const coords = transform.coveringTiles({tileSize}); diff --git a/src/render/draw_circle.js b/src/render/draw_circle.js index 28379470009..487bbd9822c 100644 --- a/src/render/draw_circle.js +++ b/src/render/draw_circle.js @@ -21,14 +21,15 @@ function drawCircles(painter: Painter, sourceCache: SourceCache, layer: CircleSt return; } - const gl = painter.gl; + const context = painter.context; + const gl = context.gl; painter.setDepthSublayer(0); - painter.depthMask(false); + context.depthMask.set(false); // Allow circles to be drawn across boundaries, so that // large circles are not clipped to tiles - gl.disable(gl.STENCIL_TEST); + context.stencilTest.set(false); for (let i = 0; i < coords.length; i++) { const coord = coords[i]; @@ -39,7 +40,7 @@ function drawCircles(painter: Painter, sourceCache: SourceCache, layer: CircleSt const programConfiguration = bucket.programConfigurations.get(layer.id); const program = painter.useProgram('circle', programConfiguration); - programConfiguration.setUniforms(gl, program, layer.paint, {zoom: painter.transform.zoom}); + programConfiguration.setUniforms(context, program, layer.paint, {zoom: painter.transform.zoom}); 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); @@ -60,7 +61,7 @@ function drawCircles(painter: Painter, sourceCache: SourceCache, layer: CircleSt )); program.draw( - gl, + context, gl.TRIANGLES, layer.id, bucket.layoutVertexBuffer, diff --git a/src/render/draw_collision_debug.js b/src/render/draw_collision_debug.js index fdf1903cc97..1cf8639908e 100644 --- a/src/render/draw_collision_debug.js +++ b/src/render/draw_collision_debug.js @@ -10,7 +10,8 @@ const pixelsToTileUnits = require('../source/pixels_to_tile_units'); module.exports = drawCollisionDebug; function drawCollisionDebugGeometry(painter: Painter, sourceCache: SourceCache, layer: StyleLayer, coords: Array, drawCircles: boolean) { - const gl = painter.gl; + const context = painter.context; + const gl = context.gl; const program = drawCircles ? painter.useProgram('collisionCircle') : painter.useProgram('collisionBox'); for (let i = 0; i < coords.length; i++) { const coord = coords[i]; @@ -35,7 +36,7 @@ function drawCollisionDebugGeometry(painter: Painter, sourceCache: SourceCache, painter.transform.pixelsToGLUnits[1] / (pixelRatio * scale)); program.draw( - gl, + context, drawCircles ? gl.TRIANGLES : gl.LINES, layer.id, buffers.layoutVertexBuffer, diff --git a/src/render/draw_debug.js b/src/render/draw_debug.js index 9b3b50ed183..1fb7bed27ac 100644 --- a/src/render/draw_debug.js +++ b/src/render/draw_debug.js @@ -3,7 +3,6 @@ const browser = require('../util/browser'); const mat4 = require('@mapbox/gl-matrix').mat4; const EXTENT = require('../data/extent'); -const VertexBuffer = require('../gl/vertex_buffer'); const VertexArrayObject = require('./vertex_array_object'); const PosArray = require('../data/pos_array'); @@ -20,9 +19,10 @@ function drawDebug(painter: Painter, sourceCache: SourceCache, coords: Array, painter, programCon if (!pat) { program = painter.useProgram(programId, programConfiguration); if (firstTile || program !== prevProgram) { - programConfiguration.setUniforms(painter.gl, program, layer.paint, {zoom: painter.transform.zoom}); + programConfiguration.setUniforms(painter.context, program, layer.paint, {zoom: painter.transform.zoom}); } } else { program = painter.useProgram(`${programId}Pattern`, programConfiguration); if (firstTile || program !== prevProgram) { - programConfiguration.setUniforms(painter.gl, program, layer.paint, {zoom: painter.transform.zoom}); + programConfiguration.setUniforms(painter.context, program, layer.paint, {zoom: painter.transform.zoom}); pattern.prepare(pat, painter, program); } pattern.setTile(tile, painter, program); } - painter.gl.uniformMatrix4fv(program.uniforms.u_matrix, false, painter.translatePosMatrix( + 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') diff --git a/src/render/draw_fill_extrusion.js b/src/render/draw_fill_extrusion.js index 2c763034ee6..32125a86406 100644 --- a/src/render/draw_fill_extrusion.js +++ b/src/render/draw_fill_extrusion.js @@ -20,13 +20,13 @@ function draw(painter: Painter, source: SourceCache, layer: FillExtrusionStyleLa } if (painter.renderPass === '3d') { - const gl = painter.gl; + const context = painter.context; - gl.disable(gl.STENCIL_TEST); - gl.enable(gl.DEPTH_TEST); + context.stencilTest.set(false); + context.depthTest.set(true); - painter.clearColor(); - painter.depthMask(true); + context.clear({ color: [0, 0, 0, 0] }); + context.depthMask.set(true); for (let i = 0; i < coords.length; i++) { drawExtrusion(painter, source, layer, coords[i]); @@ -40,14 +40,15 @@ function drawExtrusionTexture(painter, layer) { const renderedTexture = layer.viewportFrame; if (!renderedTexture) return; - const gl = painter.gl; + const context = painter.context; + const gl = context.gl; const program = painter.useProgram('extrusionTexture'); - gl.disable(gl.STENCIL_TEST); - gl.disable(gl.DEPTH_TEST); + context.stencilTest.set(false); + context.depthTest.set(false); - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, renderedTexture.texture); + context.activeTexture.set(gl.TEXTURE0); + context.bindTexture.set(renderedTexture.texture); gl.uniform1f(program.uniforms.u_opacity, layer.paint.get('fill-extrusion-opacity')); gl.uniform1i(program.uniforms.u_image, 0); @@ -58,7 +59,7 @@ function drawExtrusionTexture(painter, layer) { gl.uniform2f(program.uniforms.u_world, gl.drawingBufferWidth, gl.drawingBufferHeight); - painter.viewportVAO.bind(gl, program, painter.viewportBuffer); + painter.viewportVAO.bind(context, program, painter.viewportBuffer); gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); } @@ -67,13 +68,14 @@ function drawExtrusion(painter, source, layer, coord) { const bucket: ?FillExtrusionBucket = (tile.getBucket(layer): any); if (!bucket) return; - const gl = painter.gl; + const context = painter.context; + const gl = context.gl; const image = layer.paint.get('fill-extrusion-pattern'); const programConfiguration = bucket.programConfigurations.get(layer.id); const program = painter.useProgram(image ? 'fillExtrusionPattern' : 'fillExtrusion', programConfiguration); - programConfiguration.setUniforms(gl, program, layer.paint, {zoom: painter.transform.zoom}); + programConfiguration.setUniforms(context, program, layer.paint, {zoom: painter.transform.zoom}); if (image) { if (pattern.isPatternMissing(image, painter)) return; @@ -82,7 +84,7 @@ function drawExtrusion(painter, source, layer, coord) { gl.uniform1f(program.uniforms.u_height_factor, -Math.pow(2, coord.z) / tile.tileSize / 8); } - painter.gl.uniformMatrix4fv(program.uniforms.u_matrix, false, painter.translatePosMatrix( + painter.context.gl.uniformMatrix4fv(program.uniforms.u_matrix, false, painter.translatePosMatrix( coord.posMatrix, tile, layer.paint.get('fill-extrusion-translate'), @@ -92,7 +94,7 @@ function drawExtrusion(painter, source, layer, coord) { setLight(program, painter); program.draw( - gl, + context, gl.TRIANGLES, layer.id, bucket.layoutVertexBuffer, @@ -102,7 +104,7 @@ function drawExtrusion(painter, source, layer, coord) { } function setLight(program, painter) { - const gl = painter.gl; + const gl = painter.context.gl; const light = painter.style.light; const _lp = light.properties.get('position'); diff --git a/src/render/draw_heatmap.js b/src/render/draw_heatmap.js index aab25f197de..4f2c10d648e 100644 --- a/src/render/draw_heatmap.js +++ b/src/render/draw_heatmap.js @@ -18,22 +18,22 @@ function drawHeatmap(painter: Painter, sourceCache: SourceCache, layer: HeatmapS return; } - const gl = painter.gl; + const context = painter.context; + const gl = context.gl; painter.setDepthSublayer(0); - painter.depthMask(false); + context.depthMask.set(false); // Allow kernels to be drawn across boundaries, so that // large kernels are not clipped to tiles - gl.disable(gl.STENCIL_TEST); + context.stencilTest.set(false); - renderToTexture(gl, painter, layer); + renderToTexture(context, painter, layer); - gl.clearColor(0, 0, 0, 0); - gl.clear(gl.COLOR_BUFFER_BIT); + context.clear({ color: [0, 0, 0, 0] }); // Turn on additive blending for kernels, which is a key aspect of kernel density estimation formula - gl.blendFunc(gl.ONE, gl.ONE); + context.blendFunc.set([gl.ONE, gl.ONE]); for (let i = 0; i < coords.length; i++) { const coord = coords[i]; @@ -50,7 +50,7 @@ function drawHeatmap(painter: Painter, sourceCache: SourceCache, layer: HeatmapS const programConfiguration = bucket.programConfigurations.get(layer.id); const program = painter.useProgram('heatmap', programConfiguration); const {zoom} = painter.transform; - programConfiguration.setUniforms(gl, program, layer.paint, {zoom}); + programConfiguration.setUniforms(painter.context, program, layer.paint, {zoom}); gl.uniform1f(program.uniforms.u_radius, layer.paint.get('heatmap-radius')); gl.uniform1f(program.uniforms.u_extrude_scale, pixelsToTileUnits(tile, 1, zoom)); @@ -59,7 +59,7 @@ function drawHeatmap(painter: Painter, sourceCache: SourceCache, layer: HeatmapS gl.uniformMatrix4fv(program.uniforms.u_matrix, false, coord.posMatrix); program.draw( - gl, + context, gl.TRIANGLES, layer.id, bucket.layoutVertexBuffer, @@ -68,21 +68,22 @@ function drawHeatmap(painter: Painter, sourceCache: SourceCache, layer: HeatmapS programConfiguration); } - renderTextureToMap(gl, painter, layer); + renderTextureToMap(context, painter, layer); } -function renderToTexture(gl, painter, layer) { - gl.activeTexture(gl.TEXTURE1); +function renderToTexture(context, painter, layer) { + const gl = context.gl; + context.activeTexture.set(gl.TEXTURE1); // Use a 4x downscaled screen texture for better performance - gl.viewport(0, 0, painter.width / 4, painter.height / 4); + context.viewport.set([0, 0, painter.width / 4, painter.height / 4]); let texture = layer.heatmapTexture; let fbo = layer.heatmapFbo; if (!texture) { texture = layer.heatmapTexture = gl.createTexture(); - gl.bindTexture(gl.TEXTURE_2D, texture); + context.bindTexture.set(texture); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); @@ -90,47 +91,49 @@ function renderToTexture(gl, painter, layer) { fbo = layer.heatmapFbo = gl.createFramebuffer(); - bindTextureFramebuffer(gl, painter, texture, fbo); + bindTextureFramebuffer(context, painter, texture, fbo); } else { - gl.bindTexture(gl.TEXTURE_2D, texture); - gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); + context.bindTexture.set(texture); + context.bindFramebuffer.set(fbo); } } -function bindTextureFramebuffer(gl, painter, texture, fbo) { +function bindTextureFramebuffer(context, painter, texture, fbo) { + const gl = context.gl; // Use the higher precision half-float texture where available (producing much smoother looking heatmaps); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, painter.width / 4, painter.height / 4, 0, gl.RGBA, painter.extTextureHalfFloat ? painter.extTextureHalfFloat.HALF_FLOAT_OES : gl.UNSIGNED_BYTE, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); + context.bindFramebuffer.set(fbo); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); // If using half-float texture as a render target is not supported, fall back to a low precision texture if (painter.extTextureHalfFloat && gl.checkFramebufferStatus(gl.FRAMEBUFFER) !== gl.FRAMEBUFFER_COMPLETE) { painter.extTextureHalfFloat = null; - bindTextureFramebuffer(gl, painter, texture, fbo); + bindTextureFramebuffer(context, painter, texture, fbo); } } -function renderTextureToMap(gl, painter, layer) { - gl.bindFramebuffer(gl.FRAMEBUFFER, null); +function renderTextureToMap(context, painter, layer) { + const gl = context.gl; + context.bindFramebuffer.set(null); - gl.activeTexture(gl.TEXTURE2); + context.activeTexture.set(gl.TEXTURE2); let colorRampTexture = layer.colorRampTexture; if (!colorRampTexture) { - colorRampTexture = layer.colorRampTexture = new Texture(gl, layer.colorRamp, gl.RGBA); + colorRampTexture = layer.colorRampTexture = new Texture(context, layer.colorRamp, gl.RGBA); } colorRampTexture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + context.blendFunc.set([gl.ONE, gl.ONE_MINUS_SRC_ALPHA]); const program = painter.useProgram('heatmapTexture'); - gl.viewport(0, 0, painter.width, painter.height); + context.viewport.set([0, 0, painter.width, painter.height]); - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, layer.heatmapTexture); + context.activeTexture.set(gl.TEXTURE0); + context.bindTexture.set(layer.heatmapTexture); const opacity = layer.paint.get('heatmap-opacity'); gl.uniform1f(program.uniforms.u_opacity, opacity); @@ -141,12 +144,12 @@ function renderTextureToMap(gl, painter, layer) { mat4.ortho(matrix, 0, painter.width, painter.height, 0, 0, 1); gl.uniformMatrix4fv(program.uniforms.u_matrix, false, matrix); - gl.disable(gl.DEPTH_TEST); + context.depthTest.set(false); gl.uniform2f(program.uniforms.u_world, gl.drawingBufferWidth, gl.drawingBufferHeight); - painter.viewportVAO.bind(gl, program, painter.viewportBuffer); + painter.viewportVAO.bind(painter.context, program, painter.viewportBuffer); gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - gl.enable(gl.DEPTH_TEST); + context.depthTest.set(true); } diff --git a/src/render/draw_line.js b/src/render/draw_line.js index 0e066df3058..92d32cb955d 100644 --- a/src/render/draw_line.js +++ b/src/render/draw_line.js @@ -15,11 +15,12 @@ module.exports = function drawLine(painter: Painter, sourceCache: SourceCache, l const opacity = layer.paint.get('line-opacity'); if (opacity.constantOr(1) === 0) return; + const context = painter.context; + painter.setDepthSublayer(0); - painter.depthMask(false); + context.depthMask.set(false); - const gl = painter.gl; - gl.enable(gl.STENCIL_TEST); + context.stencilTest.set(true); const programId = layer.paint.get('line-dasharray') ? 'lineSDF' : @@ -40,7 +41,7 @@ module.exports = function drawLine(painter: Painter, sourceCache: SourceCache, l const tileRatioChanged = prevTileZoom !== tile.coord.z; if (programChanged) { - programConfiguration.setUniforms(painter.gl, program, layer.paint, {zoom: painter.transform.zoom}); + programConfiguration.setUniforms(painter.context, program, layer.paint, {zoom: painter.transform.zoom}); } drawLineTile(program, painter, tile, bucket, layer, coord, programConfiguration, programChanged, tileRatioChanged); prevTileZoom = tile.coord.z; @@ -49,7 +50,8 @@ module.exports = function drawLine(painter: Painter, sourceCache: SourceCache, l }; function drawLineTile(program, painter, tile, bucket, layer, coord, programConfiguration, programChanged, tileRatioChanged) { - const gl = painter.gl; + const context = painter.context; + const gl = context.gl; const dasharray = layer.paint.get('line-dasharray'); const image = layer.paint.get('line-pattern'); @@ -88,8 +90,8 @@ function drawLineTile(program, painter, tile, bucket, layer, coord, programConfi if (dasharray) { gl.uniform1i(program.uniforms.u_image, 0); - gl.activeTexture(gl.TEXTURE0); - painter.lineAtlas.bind(gl); + 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); @@ -97,8 +99,8 @@ function drawLineTile(program, painter, tile, bucket, layer, coord, programConfi } else if (image) { gl.uniform1i(program.uniforms.u_image, 0); - gl.activeTexture(gl.TEXTURE0); - painter.imageManager.bind(gl); + 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); @@ -116,7 +118,7 @@ function drawLineTile(program, painter, tile, bucket, layer, coord, programConfi gl.uniform1f(program.uniforms.u_ratio, 1 / pixelsToTileUnits(tile, 1, painter.transform.zoom)); program.draw( - gl, + context, gl.TRIANGLES, layer.id, bucket.layoutVertexBuffer, diff --git a/src/render/draw_raster.js b/src/render/draw_raster.js index bd7b5e31a82..e4eb164fac0 100644 --- a/src/render/draw_raster.js +++ b/src/render/draw_raster.js @@ -15,16 +15,17 @@ function drawRaster(painter: Painter, sourceCache: SourceCache, layer: RasterSty if (painter.renderPass !== 'translucent') return; if (layer.paint.get('raster-opacity') === 0) return; - const gl = painter.gl; + const context = painter.context; + const gl = context.gl; const source = sourceCache.getSource(); const program = painter.useProgram('raster'); - gl.enable(gl.DEPTH_TEST); - painter.depthMask(layer.paint.get('raster-opacity') === 1); + context.depthTest.set(true); + context.depthMask.set(layer.paint.get('raster-opacity') === 1); // Change depth function to prevent double drawing in areas where tiles overlap. gl.depthFunc(gl.LESS); - gl.disable(gl.STENCIL_TEST); + context.stencilTest.set(false); // Constant parameters. gl.uniform1f(program.uniforms.u_brightness_low, layer.paint.get('raster-brightness-min')); @@ -54,10 +55,10 @@ function drawRaster(painter: Painter, sourceCache: SourceCache, layer: RasterSty let parentScaleBy, parentTL; - gl.activeTexture(gl.TEXTURE0); + context.activeTexture.set(gl.TEXTURE0); tile.texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE, gl.LINEAR_MIPMAP_NEAREST); - gl.activeTexture(gl.TEXTURE1); + context.activeTexture.set(gl.TEXTURE1); if (parentTile) { parentTile.texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE, gl.LINEAR_MIPMAP_NEAREST); @@ -78,11 +79,11 @@ function drawRaster(painter: Painter, sourceCache: SourceCache, layer: RasterSty if (source instanceof ImageSource) { const buffer = source.boundsBuffer; const vao = source.boundsVAO; - vao.bind(gl, program, buffer); + vao.bind(context, program, buffer); gl.drawArrays(gl.TRIANGLE_STRIP, 0, buffer.length); } else if (tile.maskedBoundsBuffer && tile.maskedIndexBuffer && tile.segments) { program.draw( - gl, + context, gl.TRIANGLES, layer.id, tile.maskedBoundsBuffer, @@ -92,12 +93,12 @@ function drawRaster(painter: Painter, sourceCache: SourceCache, layer: RasterSty } else { const buffer = painter.rasterBoundsBuffer; const vao = painter.rasterBoundsVAO; - vao.bind(gl, program, buffer); + vao.bind(context, program, buffer); gl.drawArrays(gl.TRIANGLE_STRIP, 0, buffer.length); } } - gl.depthFunc(gl.LEQUAL); + context.depthFunc.set(gl.LEQUAL); } function spinWeights(angle) { diff --git a/src/render/draw_symbol.js b/src/render/draw_symbol.js index 92d8acab832..4e4899376d5 100644 --- a/src/render/draw_symbol.js +++ b/src/render/draw_symbol.js @@ -20,13 +20,13 @@ module.exports = drawSymbols; function drawSymbols(painter: Painter, sourceCache: SourceCache, layer: SymbolStyleLayer, coords: Array) { if (painter.renderPass !== 'translucent') return; - const gl = painter.gl; + const context = painter.context; // Disable the stencil test so that labels aren't clipped to tile boundaries. - gl.disable(gl.STENCIL_TEST); + context.stencilTest.set(false); painter.setDepthSublayer(0); - painter.depthMask(false); + context.depthMask.set(false); if (layer.paint.get('icon-opacity').constantOr(1) !== 0) { drawLayerSymbols(painter, sourceCache, layer, coords, false, @@ -56,7 +56,8 @@ function drawSymbols(painter: Painter, sourceCache: SourceCache, layer: SymbolSt function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate, translateAnchor, rotationAlignment, pitchAlignment, keepUpright) { - const gl = painter.gl; + const context = painter.context; + const gl = context.gl; const tr = painter.transform; const rotateWithMap = rotationAlignment === 'map'; @@ -70,9 +71,9 @@ function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate const depthOn = pitchWithMap; if (depthOn) { - gl.enable(gl.DEPTH_TEST); + context.depthTest.set(true); } else { - gl.disable(gl.DEPTH_TEST); + context.depthTest.set(false); } let program; @@ -91,12 +92,12 @@ function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate if (!program) { program = painter.useProgram(isSDF ? 'symbolSDF' : 'symbolIcon', programConfiguration); - programConfiguration.setUniforms(gl, program, layer.paint, {zoom: painter.transform.zoom}); + programConfiguration.setUniforms(painter.context, program, layer.paint, {zoom: painter.transform.zoom}); setSymbolDrawState(program, painter, layer, isText, rotateInShader, pitchWithMap, sizeData); } - gl.activeTexture(gl.TEXTURE0); + context.activeTexture.set(gl.TEXTURE0); gl.uniform1i(program.uniforms.u_texture, 0); if (isText) { @@ -132,12 +133,12 @@ function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate drawTileSymbols(program, programConfiguration, painter, layer, tile, buffers, isText, isSDF, pitchWithMap); } - if (!depthOn) gl.enable(gl.DEPTH_TEST); + if (!depthOn) context.depthTest.set(true); } function setSymbolDrawState(program, painter, layer, isText, rotateInShader, pitchWithMap, sizeData) { - const gl = painter.gl; + const gl = painter.context.gl; const tr = painter.transform; gl.uniform1i(program.uniforms.u_pitch_with_map, pitchWithMap ? 1 : 0); @@ -163,7 +164,8 @@ function setSymbolDrawState(program, painter, layer, isText, rotateInShader, pit function drawTileSymbols(program, programConfiguration, painter, layer, tile, buffers, isText, isSDF, pitchWithMap) { - const gl = painter.gl; + const context = painter.context; + const gl = context.gl; const tr = painter.transform; if (isSDF) { @@ -173,19 +175,19 @@ function drawTileSymbols(program, programConfiguration, painter, layer, tile, bu if (hasHalo) { // Draw halo underneath the text. gl.uniform1f(program.uniforms.u_is_halo, 1); - drawSymbolElements(buffers, layer, gl, program); + drawSymbolElements(buffers, layer, context, program); } gl.uniform1f(program.uniforms.u_is_halo, 0); } - drawSymbolElements(buffers, layer, gl, program); + drawSymbolElements(buffers, layer, context, program); } -function drawSymbolElements(buffers, layer, gl, program) { +function drawSymbolElements(buffers, layer, context, program) { program.draw( - gl, - gl.TRIANGLES, + context, + context.gl.TRIANGLES, layer.id, buffers.layoutVertexBuffer, buffers.indexBuffer, diff --git a/src/render/image_manager.js b/src/render/image_manager.js index c5fbd954ca8..d5e0c3ea728 100644 --- a/src/render/image_manager.js +++ b/src/render/image_manager.js @@ -7,6 +7,7 @@ const Texture = require('./texture'); const assert = require('assert'); import type {StyleImage} from '../style/style_image'; +import type Context from '../gl/context'; import type {ImagePosition} from './image_atlas'; import type {Bin} from '@mapbox/shelf-pack'; import type {Callback} from '../types/callback'; @@ -179,9 +180,10 @@ class ImageManager { return position; } - bind(gl: WebGLRenderingContext) { + bind(context: Context) { + const gl = context.gl; if (!this.atlasTexture) { - this.atlasTexture = new Texture(gl, this.atlasImage, gl.RGBA); + this.atlasTexture = new Texture(context, this.atlasImage, gl.RGBA); } else if (this.dirty) { this.atlasTexture.update(this.atlasImage); this.dirty = false; diff --git a/src/render/line_atlas.js b/src/render/line_atlas.js index f80d71b8b48..0feaa6bd88b 100644 --- a/src/render/line_atlas.js +++ b/src/render/line_atlas.js @@ -2,6 +2,8 @@ const util = require('../util/util'); +import type Context from '../gl/context'; + /** * A LineAtlas lets us reuse rendered dashed lines * by writing many of them to a texture and then fetching their positions @@ -128,10 +130,11 @@ class LineAtlas { return pos; } - bind(gl: WebGLRenderingContext) { + bind(context: Context) { + const gl = context.gl; if (!this.texture) { this.texture = gl.createTexture(); - gl.bindTexture(gl.TEXTURE_2D, this.texture); + context.bindTexture.set(this.texture); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); @@ -139,7 +142,7 @@ class LineAtlas { gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, this.data); } else { - gl.bindTexture(gl.TEXTURE_2D, this.texture); + context.bindTexture.set(this.texture); if (this.dirty) { this.dirty = false; diff --git a/src/render/painnnter b/src/render/painnnter new file mode 100644 index 00000000000..efe639da544 --- /dev/null +++ b/src/render/painnnter @@ -0,0 +1,561 @@ +// @flow + +const browser = require('../util/browser'); +const mat4 = require('@mapbox/gl-matrix').mat4; +const SourceCache = require('../source/source_cache'); +const EXTENT = require('../data/extent'); +const pixelsToTileUnits = require('../source/pixels_to_tile_units'); +const util = require('../util/util'); +const VertexArrayObject = require('./vertex_array_object'); +const RasterBoundsArray = require('../data/raster_bounds_array'); +const PosArray = require('../data/pos_array'); +const {ProgramConfiguration} = require('../data/program_configuration'); +const CrossTileSymbolIndex = require('../symbol/cross_tile_symbol_index'); +const shaders = require('../shaders'); +const Program = require('./program'); +const Context = require('../gl/context'); +const RenderTexture = require('./render_texture'); +const updateTileMasks = require('./tile_mask'); + +const draw = { + symbol: require('./draw_symbol'), + circle: require('./draw_circle'), + heatmap: require('./draw_heatmap'), + line: require('./draw_line'), + fill: require('./draw_fill'), + 'fill-extrusion': require('./draw_fill_extrusion'), + raster: require('./draw_raster'), + background: require('./draw_background'), + debug: require('./draw_debug') +}; + +import type Transform from '../geo/transform'; +import type Tile from '../source/tile'; +import type TileCoord from '../source/tile_coord'; +import type Style from '../style/style'; +import type StyleLayer from '../style/style_layer'; +import type LineAtlas from './line_atlas'; +import type Texture from './texture'; +import type ImageManager from './image_manager'; +import type GlyphManager from './glyph_manager'; +import type VertexBuffer from '../gl/vertex_buffer'; + +export type RenderPass = '3d' | 'opaque' | 'translucent'; + +type PainterOptions = { + showOverdrawInspector: boolean, + showTileBoundaries: boolean, + rotating: boolean, + zooming: boolean, + collisionFadeDuration: number +} + +/** + * Initialize a new painter object. + * + * @param {Canvas} gl an experimental-webgl drawing context + * @private + */ +class Painter { + context: Context; + transform: Transform; + _tileTextures: { [number]: Array }; + numSublayers: number; + depthEpsilon: number; + lineWidthRange: [number, number]; + emptyProgramConfiguration: ProgramConfiguration; + width: number; + height: number; + depthRbo: WebGLRenderbuffer; + depthRboAttached: boolean; + tileExtentBuffer: VertexBuffer; + tileExtentVAO: VertexArrayObject; + tileExtentPatternVAO: VertexArrayObject; + debugBuffer: VertexBuffer; + debugVAO: VertexArrayObject; + rasterBoundsBuffer: VertexBuffer; + rasterBoundsVAO: VertexArrayObject; + viewportBuffer: VertexBuffer; + viewportVAO: VertexArrayObject; + extTextureFilterAnisotropic: any; + extTextureFilterAnisotropicMax: any; + extTextureHalfFloat: any; + _tileClippingMaskIDs: { [number]: number }; + style: Style; + options: PainterOptions; + lineAtlas: LineAtlas; + imageManager: ImageManager; + glyphManager: GlyphManager; + depthRange: number; + renderPass: RenderPass; + currentLayer: number; + id: string; + _showOverdrawInspector: boolean; + cache: { [string]: Program }; + currentProgram: Program; + crossTileSymbolIndex: CrossTileSymbolIndex; + + constructor(gl: WebGLRenderingContext, transform: Transform) { + this.context = new Context(gl); + this.transform = transform; + this._tileTextures = {}; + + this.setup(); + + // Within each layer there are multiple distinct z-planes that can be drawn to. + // This is implemented using the WebGL depth buffer. + this.numSublayers = SourceCache.maxUnderzooming + SourceCache.maxOverzooming + 1; + this.depthEpsilon = 1 / Math.pow(2, 16); + + this.lineWidthRange = gl.getParameter(gl.ALIASED_LINE_WIDTH_RANGE); + + this.emptyProgramConfiguration = new ProgramConfiguration(); + + this.crossTileSymbolIndex = new CrossTileSymbolIndex(); + } + + /* + * Update the GL viewport, projection matrix, and transforms to compensate + * for a new width and height value. + */ + resize(width: number, height: number) { + const gl = this.context.gl; + + this.width = width * browser.devicePixelRatio; + this.height = height * browser.devicePixelRatio; + this.context.viewport.set([0, 0, this.width, this.height]); + + if (this.style) { + for (const layerId of this.style._order) { + this.style._layers[layerId].resize(gl); + } + } + + if (this.depthRbo) { + gl.deleteRenderbuffer(this.depthRbo); + this.depthRbo = null; + } + } + + setup() { + const context = this.context; + const gl = this.context.gl; + + // We are blending the new pixels *behind* the existing pixels. That way we can + // draw front-to-back and use then stencil buffer to cull opaque pixels early. + context.blend.set(true); + context.blendFunc.set([gl.LINES, gl.ONE_MINUS_SRC_ALPHA]); + + context.stencilTest.set(true); + + context.depthTest.set(true); + context.depthFunc.set(gl.LEQUAL); + + context.depthMask.set(false); + + const tileExtentArray = new PosArray(); + tileExtentArray.emplaceBack(0, 0); + tileExtentArray.emplaceBack(EXTENT, 0); + tileExtentArray.emplaceBack(0, EXTENT); + tileExtentArray.emplaceBack(EXTENT, EXTENT); + this.tileExtentBuffer = context.createVertexBuffer(tileExtentArray); + this.tileExtentVAO = new VertexArrayObject(); + this.tileExtentPatternVAO = new VertexArrayObject(); + + const debugArray = new PosArray(); + debugArray.emplaceBack(0, 0); + debugArray.emplaceBack(EXTENT, 0); + debugArray.emplaceBack(EXTENT, EXTENT); + debugArray.emplaceBack(0, EXTENT); + debugArray.emplaceBack(0, 0); + this.debugBuffer = context.createVertexBuffer(debugArray); + this.debugVAO = new VertexArrayObject(); + + const rasterBoundsArray = new RasterBoundsArray(); + rasterBoundsArray.emplaceBack(0, 0, 0, 0); + rasterBoundsArray.emplaceBack(EXTENT, 0, EXTENT, 0); + rasterBoundsArray.emplaceBack(0, EXTENT, 0, EXTENT); + rasterBoundsArray.emplaceBack(EXTENT, EXTENT, EXTENT, EXTENT); + this.rasterBoundsBuffer = context.createVertexBuffer(rasterBoundsArray); + this.rasterBoundsVAO = new VertexArrayObject(); + + const viewportArray = new PosArray(); + viewportArray.emplaceBack(0, 0); + viewportArray.emplaceBack(1, 0); + viewportArray.emplaceBack(0, 1); + viewportArray.emplaceBack(1, 1); + this.viewportBuffer = context.createVertexBuffer(viewportArray); + this.viewportVAO = new VertexArrayObject(); + + this.extTextureFilterAnisotropic = ( + gl.getExtension('EXT_texture_filter_anisotropic') || + gl.getExtension('MOZ_EXT_texture_filter_anisotropic') || + gl.getExtension('WEBKIT_EXT_texture_filter_anisotropic') + ); + if (this.extTextureFilterAnisotropic) { + this.extTextureFilterAnisotropicMax = gl.getParameter(this.extTextureFilterAnisotropic.MAX_TEXTURE_MAX_ANISOTROPY_EXT); + } + + this.extTextureHalfFloat = gl.getExtension('OES_texture_half_float'); + if (this.extTextureHalfFloat) { + gl.getExtension('OES_texture_half_float_linear'); + } + } + + /* + * Reset the drawing canvas by clearing the stencil buffer so that we can draw + * new tiles at the same location, while retaining previously drawn pixels. + */ + clearStencil() { + const context = this.context; + const gl = context.gl; + + // As a temporary workaround for https://github.com/mapbox/mapbox-gl-js/issues/5490, + // pending an upstream fix, we draw a fullscreen stencil=0 clipping mask here, + // effectively clearing the stencil buffer: once an upstream patch lands, remove + // this function in favor of context.clear({ stencil: 0x0 }) + + context.colorMask.set([false, false, false, false]); + context.depthMask.set(false); + context.depthTest.set(false); + context.stencilTest.set(true); + + context.stencilMask.set(0xFF); + context.stencilOp.set([gl.ZERO, gl.ZERO, gl.ZERO]); + + context.stencilFunc.set({ func: gl.ALWAYS, ref: 0x0, mask: 0xFF }); + + 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('fill', ProgramConfiguration.forTileClippingMask()); + gl.uniformMatrix4fv(program.uniforms.u_matrix, false, matrix); + + this.viewportVAO.bind(context, program, this.viewportBuffer); + gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); + + context.stencilMask.set(0x00); + context.colorMask.set([true, true, true, true]); + context.depthMask.set(true); + context.depthTest.set(true); + } + + _renderTileClippingMasks(coords: Array) { + const context = this.context; + const gl = context.gl; + context.colorMask.set([false, false, false, false]); + context.depthMask.set(false); + context.depthTest.set(false); + context.stencilTest.set(true); + + context.stencilMask.set(0xFF); + // Tests will always pass, and ref value will be written to stencil buffer. + context.stencilOp.set([gl.KEEP, gl.KEEP, gl.REPLACE]); + + let idNext = 1; + this._tileClippingMaskIDs = {}; + const programConfiguration = ProgramConfiguration.forTileClippingMask(); + + for (const coord of coords) { + const id = this._tileClippingMaskIDs[coord.id] = idNext++; + + gl.stencilFunc(gl.ALWAYS, id, 0xFF); + + const program = this.useProgram('fill', programConfiguration); + gl.uniformMatrix4fv(program.uniforms.u_matrix, false, coord.posMatrix); + + // Draw the clipping mask + this.tileExtentVAO.bind(this.context, program, this.tileExtentBuffer); + gl.drawArrays(gl.TRIANGLE_STRIP, 0, this.tileExtentBuffer.length); + } + + context.stencilMask.set(0x00); + context.colorMask.set([true, true, true, true]); + context.depthMask.set(true); + context.depthTest.set(true); + } + + enableTileClippingMask(coord: TileCoord) { + const gl = this.context.gl; + gl.stencilFunc(gl.EQUAL, this._tileClippingMaskIDs[coord.id], 0xFF); + } + + render(style: Style, options: PainterOptions) { + this.style = style; + this.options = options; + + this.lineAtlas = style.lineAtlas; + this.imageManager = style.imageManager; + this.glyphManager = style.glyphManager; + + const context = this.context; + + for (const id in style.sourceCaches) { + const sourceCache = this.style.sourceCaches[id]; + if (sourceCache.used) { + sourceCache.prepare(this.context); + } + } + + const layerIds = this.style._order; + + const rasterSources = util.filterObject(this.style.sourceCaches, (sc) => { return sc._source.type === 'raster'; }); + for (const key in rasterSources) { + const sourceCache = rasterSources[key]; + const coords = sourceCache.getVisibleCoordinates(); + const visibleTiles = coords.map((c)=>{ return sourceCache.getTile(c); }); + updateTileMasks(visibleTiles, this.context); + } + + // 3D pass + // We first create a renderbuffer that we'll use to preserve depth + // results across 3D layers, then render each 3D layer to its own + // framebuffer/texture, which we'll use later in the translucent pass + // to render to the main framebuffer. By doing this before we render to + // the main framebuffer we won't have to do an expensive framebuffer + // restore mid-render pass. + // The most important distinction of the 3D pass is that we use the + // depth buffer in an entirely different way (to represent 3D space) + // than we do in the 2D pass (to preserve layer order). + this.renderPass = '3d'; + { + // We'll wait and only attach the depth renderbuffer if we think we're + // rendering something. + let first = true; + + let sourceCache; + let coords = []; + + for (let i = 0; i < layerIds.length; i++) { + const layer = this.style._layers[layerIds[i]]; + + if (!layer.has3DPass() || layer.isHidden(this.transform.zoom)) continue; + + if (layer.source !== (sourceCache && sourceCache.id)) { + sourceCache = this.style.sourceCaches[layer.source]; + coords = []; + + if (sourceCache) { + this.clearStencil(); + coords = sourceCache.getVisibleCoordinates(); + } + + coords.reverse(); + } + + if (!coords.length) continue; + + this._setup3DRenderbuffer(); + + const renderTarget = layer.viewportFrame || new RenderTexture(this); + layer.viewportFrame = renderTarget; + renderTarget.bindWithDepth(this.depthRbo); + + if (first) { + context.clear({ depth: 1 }); + first = false; + } + + this.renderLayer(this, (sourceCache: any), layer, coords); + + renderTarget.unbind(); + } + } + + // Clear buffers in preparation for drawing to the main framebuffer + context.clear({ color: [0, 0, 0, 0], depth: 1 }); + + this.showOverdrawInspector(options.showOverdrawInspector); + + this.depthRange = (style._order.length + 2) * this.numSublayers * this.depthEpsilon; + + // Opaque pass + // Draw opaque layers top-to-bottom first. + this.renderPass = 'opaque'; + { + let sourceCache; + let coords = []; + + this.currentLayer = layerIds.length - 1; + + if (!this._showOverdrawInspector) { + this.context.blend.set(false); + } + + for (this.currentLayer; this.currentLayer >= 0; this.currentLayer--) { + const layer = this.style._layers[layerIds[this.currentLayer]]; + + if (layer.source !== (sourceCache && sourceCache.id)) { + sourceCache = this.style.sourceCaches[layer.source]; + coords = []; + + if (sourceCache) { + this.clearStencil(); + coords = sourceCache.getVisibleCoordinates(); + if (sourceCache.getSource().isTileClipped) { + this._renderTileClippingMasks(coords); + } + } + } + + this.renderLayer(this, (sourceCache: any), layer, coords); + } + } + + // Translucent pass + // Draw all other layers bottom-to-top. + this.renderPass = 'translucent'; + { + let sourceCache; + let coords = []; + + this.context.blend.set(true); + + this.currentLayer = 0; + + for (this.currentLayer; this.currentLayer < layerIds.length; this.currentLayer++) { + const layer = this.style._layers[layerIds[this.currentLayer]]; + + if (layer.source !== (sourceCache && sourceCache.id)) { + sourceCache = this.style.sourceCaches[layer.source]; + coords = []; + + if (sourceCache) { + this.clearStencil(); + coords = sourceCache.getVisibleCoordinates(); + if (sourceCache.getSource().isTileClipped) { + this._renderTileClippingMasks(coords); + } + } + + coords.reverse(); + } + + this.renderLayer(this, (sourceCache: any), layer, coords); + } + } + + if (this.options.showTileBoundaries) { + const sourceCache = this.style.sourceCaches[Object.keys(this.style.sourceCaches)[0]]; + if (sourceCache) { + draw.debug(this, sourceCache, sourceCache.getVisibleCoordinates()); + } + } + } + + _setup3DRenderbuffer() { + const context = this.context; + // All of the 3D textures will use the same depth renderbuffer. + if (!this.depthRbo) { + const gl = this.context.gl; + this.depthRbo = gl.createRenderbuffer(); + + context.bindRenderbuffer.set(this.depthRbo); + gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, this.width, this.height); + context.bindRenderbuffer.set(null); + } + + this.depthRboAttached = true; + } + + renderLayer(painter: Painter, sourceCache: SourceCache, layer: StyleLayer, coords: Array) { + if (layer.isHidden(this.transform.zoom)) return; + if (layer.type !== 'background' && !coords.length) return; + this.id = layer.id; + + draw[layer.type](painter, sourceCache, layer, coords); + } + + setDepthSublayer(n: number) { + const farDepth = 1 - ((1 + this.currentLayer) * this.numSublayers + n) * this.depthEpsilon; + const nearDepth = farDepth - 1 + this.depthRange; + this.context.depthRange.set([nearDepth, farDepth]); + } + + /** + * Transform a matrix to incorporate the *-translate and *-translate-anchor properties into it. + * @param inViewportPixelUnitsUnits True when the units accepted by the matrix are in viewport pixels instead of tile units. + * @returns {Float32Array} matrix + */ + translatePosMatrix(matrix: Float32Array, tile: Tile, translate: [number, number], translateAnchor: 'map' | 'viewport', inViewportPixelUnitsUnits?: boolean) { + if (!translate[0] && !translate[1]) return matrix; + + const angle = inViewportPixelUnitsUnits ? + (translateAnchor === 'map' ? this.transform.angle : 0) : + (translateAnchor === 'viewport' ? -this.transform.angle : 0); + + if (angle) { + const sinA = Math.sin(angle); + const cosA = Math.cos(angle); + translate = [ + translate[0] * cosA - translate[1] * sinA, + translate[0] * sinA + translate[1] * cosA + ]; + } + + const translation = [ + inViewportPixelUnitsUnits ? translate[0] : pixelsToTileUnits(tile, translate[0], this.transform.zoom), + inViewportPixelUnitsUnits ? translate[1] : pixelsToTileUnits(tile, translate[1], this.transform.zoom), + 0 + ]; + + const translatedMatrix = new Float32Array(16); + mat4.translate(translatedMatrix, matrix, translation); + return translatedMatrix; + } + + saveTileTexture(texture: Texture) { + const textures = this._tileTextures[texture.size[0]]; + if (!textures) { + this._tileTextures[texture.size[0]] = [texture]; + } else { + textures.push(texture); + } + } + + getTileTexture(size: number) { + const textures = this._tileTextures[size]; + return textures && textures.length > 0 ? textures.pop() : null; + } + + lineWidth(width: number) { + this.context.lineWidth.set(util.clamp(width, this.lineWidthRange[0], this.lineWidthRange[1])); + } + + showOverdrawInspector(enabled: boolean) { + if (!enabled && !this._showOverdrawInspector) return; + this._showOverdrawInspector = enabled; + + const context = this.context; + const gl = context.gl; + if (enabled) { + context.blendFunc.set([gl.CONSTANT_COLOR, gl.ONE]); + const numOverdrawSteps = 8; + const a = 1 / numOverdrawSteps; + context.blendColor.set([a, a, a, 0]); + context.clear({ color: [0, 0, 0, 1] }); + } else { + context.blendFunc.set([gl.ONE, gl.ONE_MINUS_SRC_ALPHA]); + } + } + + _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); + } + 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; + } +} + +module.exports = Painter; diff --git a/src/render/painter.js b/src/render/painter.js index afc350dc71f..987e5170dc5 100644 --- a/src/render/painter.js +++ b/src/render/painter.js @@ -6,7 +6,6 @@ const SourceCache = require('../source/source_cache'); const EXTENT = require('../data/extent'); const pixelsToTileUnits = require('../source/pixels_to_tile_units'); const util = require('../util/util'); -const VertexBuffer = require('../gl/vertex_buffer'); const VertexArrayObject = require('./vertex_array_object'); const RasterBoundsArray = require('../data/raster_bounds_array'); const PosArray = require('../data/pos_array'); @@ -14,6 +13,7 @@ const {ProgramConfiguration} = require('../data/program_configuration'); const CrossTileSymbolIndex = require('../symbol/cross_tile_symbol_index'); const shaders = require('../shaders'); const Program = require('./program'); +const Context = require('../gl/context'); const RenderTexture = require('./render_texture'); const updateTileMasks = require('./tile_mask'); @@ -38,6 +38,7 @@ import type LineAtlas from './line_atlas'; import type Texture from './texture'; import type ImageManager from './image_manager'; import type GlyphManager from './glyph_manager'; +import type VertexBuffer from '../gl/vertex_buffer'; export type RenderPass = '3d' | 'opaque' | 'translucent'; @@ -56,7 +57,7 @@ type PainterOptions = { * @private */ class Painter { - gl: WebGLRenderingContext; + context: Context; transform: Transform; _tileTextures: { [number]: Array }; numSublayers: number; @@ -67,7 +68,6 @@ class Painter { height: number; depthRbo: WebGLRenderbuffer; depthRboAttached: boolean; - _depthMask: boolean; tileExtentBuffer: VertexBuffer; tileExtentVAO: VertexArrayObject; tileExtentPatternVAO: VertexArrayObject; @@ -96,7 +96,7 @@ class Painter { crossTileSymbolIndex: CrossTileSymbolIndex; constructor(gl: WebGLRenderingContext, transform: Transform) { - this.gl = gl; + this.context = new Context(gl); this.transform = transform; this._tileTextures = {}; @@ -119,11 +119,11 @@ class Painter { * for a new width and height value. */ resize(width: number, height: number) { - const gl = this.gl; + const gl = this.context.gl; this.width = width * browser.devicePixelRatio; this.height = height * browser.devicePixelRatio; - gl.viewport(0, 0, this.width, this.height); + this.context.viewport.set([0, 0, this.width, this.height]); if (this.style) { for (const layerId of this.style._order) { @@ -132,33 +132,33 @@ class Painter { } if (this.depthRbo) { - this.gl.deleteRenderbuffer(this.depthRbo); + gl.deleteRenderbuffer(this.depthRbo); this.depthRbo = null; } } setup() { - const gl = this.gl; + const context = this.context; + const gl = this.context.gl; // We are blending the new pixels *behind* the existing pixels. That way we can // draw front-to-back and use then stencil buffer to cull opaque pixels early. - gl.enable(gl.BLEND); - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + context.blend.set(true); + context.blendFunc.set([gl.LINES, gl.ONE_MINUS_SRC_ALPHA]); - gl.enable(gl.STENCIL_TEST); + context.stencilTest.set(true); - gl.enable(gl.DEPTH_TEST); - gl.depthFunc(gl.LEQUAL); + context.depthTest.set(true); + context.depthFunc.set(gl.LEQUAL); - this._depthMask = false; - gl.depthMask(false); + context.depthMask.set(false); const tileExtentArray = new PosArray(); tileExtentArray.emplaceBack(0, 0); tileExtentArray.emplaceBack(EXTENT, 0); tileExtentArray.emplaceBack(0, EXTENT); tileExtentArray.emplaceBack(EXTENT, EXTENT); - this.tileExtentBuffer = new VertexBuffer(gl, tileExtentArray); + this.tileExtentBuffer = context.createVertexBuffer(tileExtentArray); this.tileExtentVAO = new VertexArrayObject(); this.tileExtentPatternVAO = new VertexArrayObject(); @@ -168,7 +168,7 @@ class Painter { debugArray.emplaceBack(EXTENT, EXTENT); debugArray.emplaceBack(0, EXTENT); debugArray.emplaceBack(0, 0); - this.debugBuffer = new VertexBuffer(gl, debugArray); + this.debugBuffer = context.createVertexBuffer(debugArray); this.debugVAO = new VertexArrayObject(); const rasterBoundsArray = new RasterBoundsArray(); @@ -176,7 +176,7 @@ class Painter { rasterBoundsArray.emplaceBack(EXTENT, 0, EXTENT, 0); rasterBoundsArray.emplaceBack(0, EXTENT, 0, EXTENT); rasterBoundsArray.emplaceBack(EXTENT, EXTENT, EXTENT, EXTENT); - this.rasterBoundsBuffer = new VertexBuffer(gl, rasterBoundsArray); + this.rasterBoundsBuffer = context.createVertexBuffer(rasterBoundsArray); this.rasterBoundsVAO = new VertexArrayObject(); const viewportArray = new PosArray(); @@ -184,7 +184,7 @@ class Painter { viewportArray.emplaceBack(1, 0); viewportArray.emplaceBack(0, 1); viewportArray.emplaceBack(1, 1); - this.viewportBuffer = new VertexBuffer(gl, viewportArray); + this.viewportBuffer = context.createVertexBuffer(viewportArray); this.viewportVAO = new VertexArrayObject(); this.extTextureFilterAnisotropic = ( @@ -202,40 +202,28 @@ class Painter { } } - /* - * Reset the color buffers of the drawing canvas. - */ - clearColor() { - const gl = this.gl; - gl.clearColor(0, 0, 0, 0); - gl.clear(gl.COLOR_BUFFER_BIT); - } - /* * Reset the drawing canvas by clearing the stencil buffer so that we can draw * new tiles at the same location, while retaining previously drawn pixels. */ clearStencil() { - const gl = this.gl; + const context = this.context; + const gl = context.gl; // As a temporary workaround for https://github.com/mapbox/mapbox-gl-js/issues/5490, // pending an upstream fix, we draw a fullscreen stencil=0 clipping mask here, - // effectively clearing the stencil buffer: restore this code for native - // performance and readability once an upstream patch lands. + // effectively clearing the stencil buffer: once an upstream patch lands, remove + // this function in favor of context.clear({ stencil: 0x0 }) - // gl.clearStencil(0x0); - // gl.stencilMask(0xFF); - // gl.clear(gl.STENCIL_BUFFER_BIT); + context.colorMask.set([false, false, false, false]); + context.depthMask.set(false); + context.depthTest.set(false); + context.stencilTest.set(true); - gl.colorMask(false, false, false, false); - this.depthMask(false); - gl.disable(gl.DEPTH_TEST); - gl.enable(gl.STENCIL_TEST); + context.stencilMask.set(0xFF); + context.stencilOp.set([gl.ZERO, gl.ZERO, gl.ZERO]); - gl.stencilMask(0xFF); - gl.stencilOp(gl.ZERO, gl.ZERO, gl.ZERO); - - gl.stencilFunc(gl.ALWAYS, 0x0, 0xFF); + context.stencilFunc.set({ func: gl.ALWAYS, ref: 0x0, mask: 0xFF }); const matrix = mat4.create(); mat4.ortho(matrix, 0, this.width, this.height, 0, 0, 1); @@ -244,32 +232,26 @@ class Painter { const program = this.useProgram('fill', ProgramConfiguration.forTileClippingMask()); gl.uniformMatrix4fv(program.uniforms.u_matrix, false, matrix); - this.viewportVAO.bind(gl, program, this.viewportBuffer); + this.viewportVAO.bind(context, program, this.viewportBuffer); gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - gl.stencilMask(0x00); - gl.colorMask(true, true, true, true); - this.depthMask(true); - gl.enable(gl.DEPTH_TEST); - } - - clearDepth() { - const gl = this.gl; - gl.clearDepth(1); - this.depthMask(true); - gl.clear(gl.DEPTH_BUFFER_BIT); + context.stencilMask.set(0x00); + context.colorMask.set([true, true, true, true]); + context.depthMask.set(true); + context.depthTest.set(true); } _renderTileClippingMasks(coords: Array) { - const gl = this.gl; - gl.colorMask(false, false, false, false); - this.depthMask(false); - gl.disable(gl.DEPTH_TEST); - gl.enable(gl.STENCIL_TEST); - - gl.stencilMask(0xFF); + const context = this.context; + const gl = context.gl; + context.colorMask.set([false, false, false, false]); + context.depthMask.set(false); + context.depthTest.set(false); + context.stencilTest.set(true); + + context.stencilMask.set(0xFF); // Tests will always pass, and ref value will be written to stencil buffer. - gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE); + context.stencilOp.set([gl.KEEP, gl.KEEP, gl.REPLACE]); let idNext = 1; this._tileClippingMaskIDs = {}; @@ -284,18 +266,18 @@ class Painter { gl.uniformMatrix4fv(program.uniforms.u_matrix, false, coord.posMatrix); // Draw the clipping mask - this.tileExtentVAO.bind(gl, program, this.tileExtentBuffer); + this.tileExtentVAO.bind(this.context, program, this.tileExtentBuffer); gl.drawArrays(gl.TRIANGLE_STRIP, 0, this.tileExtentBuffer.length); } - gl.stencilMask(0x00); - gl.colorMask(true, true, true, true); - this.depthMask(true); - gl.enable(gl.DEPTH_TEST); + context.stencilMask.set(0x00); + context.colorMask.set([true, true, true, true]); + context.depthMask.set(true); + context.depthTest.set(true); } enableTileClippingMask(coord: TileCoord) { - const gl = this.gl; + const gl = this.context.gl; gl.stencilFunc(gl.EQUAL, this._tileClippingMaskIDs[coord.id], 0xFF); } @@ -307,10 +289,12 @@ class Painter { this.imageManager = style.imageManager; this.glyphManager = style.glyphManager; + const context = this.context; + for (const id in style.sourceCaches) { const sourceCache = this.style.sourceCaches[id]; if (sourceCache.used) { - sourceCache.prepare(this.gl); + sourceCache.prepare(this.context); } } @@ -321,7 +305,7 @@ class Painter { const sourceCache = rasterSources[key]; const coords = sourceCache.getVisibleCoordinates(); const visibleTiles = coords.map((c)=>{ return sourceCache.getTile(c); }); - updateTileMasks(visibleTiles, this.gl); + updateTileMasks(visibleTiles, this.context); } // 3D pass @@ -369,7 +353,7 @@ class Painter { renderTarget.bindWithDepth(this.depthRbo); if (first) { - this.clearDepth(); + context.clear({ depth: 1 }); first = false; } @@ -380,8 +364,7 @@ class Painter { } // Clear buffers in preparation for drawing to the main framebuffer - this.clearColor(); - this.clearDepth(); + context.clear({ color: [0, 0, 0, 0], depth: 1 }); this.showOverdrawInspector(options.showOverdrawInspector); @@ -397,7 +380,7 @@ class Painter { this.currentLayer = layerIds.length - 1; if (!this._showOverdrawInspector) { - this.gl.disable(this.gl.BLEND); + this.context.blend.set(false); } for (this.currentLayer; this.currentLayer >= 0; this.currentLayer--) { @@ -427,7 +410,7 @@ class Painter { let sourceCache; let coords = []; - this.gl.enable(this.gl.BLEND); + this.context.blend.set(true); this.currentLayer = 0; @@ -462,25 +445,20 @@ class Painter { } _setup3DRenderbuffer() { + const context = this.context; // All of the 3D textures will use the same depth renderbuffer. if (!this.depthRbo) { - const gl = this.gl; + const gl = this.context.gl; this.depthRbo = gl.createRenderbuffer(); - gl.bindRenderbuffer(gl.RENDERBUFFER, this.depthRbo); + + context.bindRenderbuffer.set(this.depthRbo); gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, this.width, this.height); - gl.bindRenderbuffer(gl.RENDERBUFFER, null); + context.bindRenderbuffer.set(null); } this.depthRboAttached = true; } - depthMask(mask: boolean) { - if (mask !== this._depthMask) { - this._depthMask = mask; - this.gl.depthMask(mask); - } - } - renderLayer(painter: Painter, sourceCache: SourceCache, layer: StyleLayer, coords: Array) { if (layer.isHidden(this.transform.zoom)) return; if (layer.type !== 'background' && !coords.length) return; @@ -492,7 +470,7 @@ class Painter { setDepthSublayer(n: number) { const farDepth = 1 - ((1 + this.currentLayer) * this.numSublayers + n) * this.depthEpsilon; const nearDepth = farDepth - 1 + this.depthRange; - this.gl.depthRange(nearDepth, farDepth); + this.context.depthRange.set([nearDepth, farDepth]); } /** @@ -542,23 +520,23 @@ class Painter { } lineWidth(width: number) { - this.gl.lineWidth(util.clamp(width, this.lineWidthRange[0], this.lineWidthRange[1])); + this.context.lineWidth.set(util.clamp(width, this.lineWidthRange[0], this.lineWidthRange[1])); } showOverdrawInspector(enabled: boolean) { if (!enabled && !this._showOverdrawInspector) return; this._showOverdrawInspector = enabled; - const gl = this.gl; + const context = this.context; + const gl = context.gl; if (enabled) { - gl.blendFunc(gl.CONSTANT_COLOR, gl.ONE); + context.blendFunc.set([gl.CONSTANT_COLOR, gl.ONE]); const numOverdrawSteps = 8; const a = 1 / numOverdrawSteps; - gl.blendColor(a, a, a, 0); - gl.clearColor(0, 0, 0, 1); - gl.clear(gl.COLOR_BUFFER_BIT); + context.blendColor.set([a, a, a, 0]); + context.clear({ color: [0, 0, 0, 1] }); } else { - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + context.blendFunc.set([gl.ONE, gl.ONE_MINUS_SRC_ALPHA]); } } @@ -566,19 +544,15 @@ class Painter { this.cache = this.cache || {}; const key = `${name}${programConfiguration.cacheKey || ''}${this._showOverdrawInspector ? '/overdraw' : ''}`; if (!this.cache[key]) { - this.cache[key] = new Program(this.gl, shaders[name], programConfiguration, this._showOverdrawInspector); + this.cache[key] = new Program(this.context, shaders[name], programConfiguration, this._showOverdrawInspector); } return this.cache[key]; } useProgram(name: string, programConfiguration?: ProgramConfiguration): Program { - const gl = this.gl; const nextProgram = this._createProgramCached(name, programConfiguration || this.emptyProgramConfiguration); - if (this.currentProgram !== nextProgram) { - gl.useProgram(nextProgram.program); - this.currentProgram = nextProgram; - } + this.context.program.set(nextProgram.program); return nextProgram; } diff --git a/src/render/pattern.js b/src/render/pattern.js index 13a1a91cdbb..b5b4552a362 100644 --- a/src/render/pattern.js +++ b/src/render/pattern.js @@ -21,7 +21,8 @@ exports.isPatternMissing = function(image: ?CrossFaded, painter: Painter }; exports.prepare = function (image: CrossFaded, painter: Painter, program: Program) { - const gl = painter.gl; + const context = painter.context; + const gl = context.gl; const imagePosA = painter.imageManager.getPattern(image.from); const imagePosB = painter.imageManager.getPattern(image.to); @@ -40,12 +41,12 @@ exports.prepare = function (image: CrossFaded, painter: Painter, program gl.uniform1f(program.uniforms.u_scale_a, image.fromScale); gl.uniform1f(program.uniforms.u_scale_b, image.toScale); - gl.activeTexture(gl.TEXTURE0); - painter.imageManager.bind(gl); + context.activeTexture.set(gl.TEXTURE0); + painter.imageManager.bind(painter.context); }; exports.setTile = function (tile: {coord: TileCoord, tileSize: number}, painter: Painter, program: Program) { - const gl = painter.gl; + const gl = painter.context.gl; gl.uniform1f(program.uniforms.u_tile_units_to_pixels, 1 / pixelsToTileUnits(tile, 1, painter.transform.tileZoom)); diff --git a/src/render/program.js b/src/render/program.js index 176c614dcdb..f6dbfe5e023 100644 --- a/src/render/program.js +++ b/src/render/program.js @@ -5,6 +5,7 @@ const shaders = require('../shaders'); const assert = require('assert'); const {ProgramConfiguration} = require('../data/program_configuration'); const VertexArrayObject = require('./vertex_array_object'); +const Context = require('../gl/context'); import type {SegmentVector} from '../data/segment'; import type VertexBuffer from '../gl/vertex_buffer'; @@ -15,17 +16,16 @@ export type DrawMode = | $PropertyType; class Program { - gl: WebGLRenderingContext; program: WebGLProgram; uniforms: {[string]: WebGLUniformLocation}; attributes: {[string]: number}; numAttributes: number; - constructor(gl: WebGLRenderingContext, + constructor(context: Context, source: {fragmentSource: string, vertexSource: string}, configuration: ProgramConfiguration, showOverdrawInspector: boolean) { - this.gl = gl; + const gl = context.gl; this.program = gl.createProgram(); const defines = configuration.defines().concat( @@ -82,7 +82,7 @@ class Program { } } - draw(gl: WebGLRenderingContext, + draw(context: Context, drawMode: DrawMode, layerID: string, layoutVertexBuffer: VertexBuffer, @@ -92,6 +92,8 @@ class Program { dynamicLayoutBuffer: ?VertexBuffer, dynamicLayoutBuffer2: ?VertexBuffer) { + const gl = context.gl; + const primitiveSize = { [gl.LINES]: 2, [gl.TRIANGLES]: 3 @@ -102,7 +104,7 @@ class Program { const vao = vaos[layerID] || (vaos[layerID] = new VertexArrayObject()); vao.bind( - gl, + context, this, layoutVertexBuffer, indexBuffer, diff --git a/src/render/render_texture.js b/src/render/render_texture.js index bd2a8376a6a..552ab5c7e32 100644 --- a/src/render/render_texture.js +++ b/src/render/render_texture.js @@ -1,12 +1,13 @@ // @flow +import type Context from '../gl/context'; import type VertexBuffer from '../gl/vertex_buffer'; import type VertexArrayObject from './vertex_array_object'; import type Painter from './painter'; class RenderTexture { - gl: WebGLRenderingContext; + context: Context; texture: WebGLTexture; fbo: WebGLFramebuffer; buffer: VertexBuffer; @@ -14,26 +15,28 @@ class RenderTexture { attachedRbo: ?WebGLRenderbuffer; constructor(painter: Painter) { - const gl = this.gl = painter.gl; + const context = this.context = painter.context; + const gl = context.gl; const texture = this.texture = gl.createTexture(); - gl.bindTexture(gl.TEXTURE_2D, texture); + context.bindTexture.set(texture); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, painter.width, painter.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - gl.bindTexture(gl.TEXTURE_2D, null); + context.bindTexture.set(null); const fbo = this.fbo = gl.createFramebuffer(); - gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); + context.bindFramebuffer.set(fbo); gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); } bindWithDepth(depthRbo: WebGLRenderbuffer) { - const gl = this.gl; - gl.bindFramebuffer(gl.FRAMEBUFFER, this.fbo); + const context = this.context; + const gl = context.gl; + context.bindFramebuffer.set(this.fbo); if (this.attachedRbo !== depthRbo) { gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthRbo); this.attachedRbo = depthRbo; @@ -41,8 +44,7 @@ class RenderTexture { } unbind() { - const gl = this.gl; - gl.bindFramebuffer(gl.FRAMEBUFFER, null); + this.context.bindFramebuffer.set(null); } } diff --git a/src/render/texture.js b/src/render/texture.js index 390ff14c2c2..17b727be68e 100644 --- a/src/render/texture.js +++ b/src/render/texture.js @@ -2,6 +2,7 @@ const {HTMLImageElement, HTMLCanvasElement, HTMLVideoElement, ImageData} = require('../util/window'); +import type Context from '../gl/context'; import type {RGBAImage, AlphaImage} from '../util/image'; import type {ImageTextureSource} from '../source/image_source'; @@ -23,21 +24,21 @@ export type TextureImage = | ImageTextureSource; class Texture { - gl: WebGLRenderingContext; + context: Context; size: Array; texture: WebGLTexture; format: TextureFormat; filter: ?TextureFilter; wrap: ?TextureWrap; - constructor(gl: WebGLRenderingContext, image: TextureImage, format: TextureFormat) { - this.gl = gl; + constructor(context: Context, image: TextureImage, format: TextureFormat) { + this.context = context; const {width, height} = image; this.size = [width, height]; this.format = format; - this.texture = gl.createTexture(); + this.texture = context.gl.createTexture(); this.update(image); } @@ -45,12 +46,13 @@ class Texture { const {width, height} = image; this.size = [width, height]; - const {gl} = this; - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1); + const {context} = this; + const {gl} = context; + context.bindTexture.set(this.texture); + context.pixelStoreUnpack.set(1); if (this.format === gl.RGBA) { - gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, (true: any)); + context.pixelStoreUnpackPremultiplyAlpha.set(true); } if (image instanceof HTMLImageElement || image instanceof HTMLCanvasElement || image instanceof HTMLVideoElement || image instanceof ImageData) { @@ -61,8 +63,9 @@ class Texture { } bind(filter: TextureFilter, wrap: TextureWrap, minFilter: ?TextureFilter) { - const {gl} = this; - gl.bindTexture(gl.TEXTURE_2D, this.texture); + const {context} = this; + const {gl} = context; + context.bindTexture.set(this.texture); if (filter !== this.filter) { gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filter); @@ -78,7 +81,7 @@ class Texture { } destroy() { - const {gl} = this; + const {gl} = this.context; gl.deleteTexture(this.texture); this.texture = (null: any); } diff --git a/src/render/tile_mask.js b/src/render/tile_mask.js index be3c8381e37..62ddab6ad7d 100644 --- a/src/render/tile_mask.js +++ b/src/render/tile_mask.js @@ -3,6 +3,7 @@ const TileCoord = require('../source/tile_coord'); import type Tile from './../source/tile'; +import type Context from '../gl/context'; export type Mask = { [number]: boolean @@ -59,7 +60,7 @@ export type Mask = { // 2/1/3, since it is not a descendant of it. -module.exports = function(renderableTiles: Array, gl: WebGLRenderingContext) { +module.exports = function(renderableTiles: Array, context: Context) { const sortedRenderables = renderableTiles.sort((a, b) => { return a.coord.isLessThan(b.coord) ? -1 : b.coord.isLessThan(a.coord) ? 1 : 0; }); for (let i = 0; i < sortedRenderables.length; i++) { @@ -72,7 +73,7 @@ module.exports = function(renderableTiles: Array, gl: WebGLRenderingContex // can never be children of the current wrap. computeTileMasks(tile.coord.wrapped(), tile.coord, childArray, new TileCoord(0, 0, 0, tile.coord.w + 1), mask); - tile.setMask(mask, gl); + tile.setMask(mask, context); } }; diff --git a/src/render/vertex_array_object.js b/src/render/vertex_array_object.js index 89ec18eec50..8336bb61739 100644 --- a/src/render/vertex_array_object.js +++ b/src/render/vertex_array_object.js @@ -5,8 +5,10 @@ const assert = require('assert'); import type Program from './program'; import type VertexBuffer from '../gl/vertex_buffer'; import type IndexBuffer from '../gl/index_buffer'; +import type Context from '../gl/context'; class VertexArrayObject { + context: Context; boundProgram: ?Program; boundVertexBuffer: ?VertexBuffer; boundVertexBuffer2: ?VertexBuffer; @@ -15,7 +17,6 @@ class VertexArrayObject { boundDynamicVertexBuffer: ?VertexBuffer; boundDynamicVertexBuffer2: ?VertexBuffer; vao: any; - gl: WebGLRenderingContext; constructor() { this.boundProgram = null; @@ -27,7 +28,7 @@ class VertexArrayObject { this.vao = null; } - bind(gl: WebGLRenderingContext, + bind(context: Context, program: Program, layoutVertexBuffer: VertexBuffer, indexBuffer: ?IndexBuffer, @@ -36,9 +37,7 @@ class VertexArrayObject { dynamicVertexBuffer: ?VertexBuffer, dynamicVertexBuffer2: ?VertexBuffer) { - if (gl.extVertexArrayObject === undefined) { - (gl: any).extVertexArrayObject = gl.getExtension("OES_vertex_array_object"); - } + this.context = context; const isFreshBindRequired = ( !this.vao || @@ -51,11 +50,10 @@ class VertexArrayObject { this.boundDynamicVertexBuffer2 !== dynamicVertexBuffer2 ); - if (!gl.extVertexArrayObject || isFreshBindRequired) { - this.freshBind(gl, program, layoutVertexBuffer, indexBuffer, vertexBuffer2, vertexOffset, dynamicVertexBuffer, dynamicVertexBuffer2); - this.gl = gl; + if (!context.extVertexArrayObject || isFreshBindRequired) { + this.freshBind(program, layoutVertexBuffer, indexBuffer, vertexBuffer2, vertexOffset, dynamicVertexBuffer, dynamicVertexBuffer2); } else { - (gl: any).extVertexArrayObject.bindVertexArrayOES(this.vao); + context.bindVertexArrayOES.set(this.vao); if (dynamicVertexBuffer) { // The buffer may have been updated. Rebind to upload data. @@ -72,8 +70,7 @@ class VertexArrayObject { } } - freshBind(gl: WebGLRenderingContext, - program: Program, + freshBind(program: Program, layoutVertexBuffer: VertexBuffer, indexBuffer: ?IndexBuffer, vertexBuffer2: ?VertexBuffer, @@ -83,10 +80,13 @@ class VertexArrayObject { let numPrevAttributes; const numNextAttributes = program.numAttributes; - if (gl.extVertexArrayObject) { + const context = this.context; + const gl = context.gl; + + if (context.extVertexArrayObject) { if (this.vao) this.destroy(); - this.vao = (gl: any).extVertexArrayObject.createVertexArrayOES(); - (gl: any).extVertexArrayObject.bindVertexArrayOES(this.vao); + this.vao = context.extVertexArrayObject.createVertexArrayOES(); + context.bindVertexArrayOES.set(this.vao); numPrevAttributes = 0; // store the arguments so that we can verify them when the vao is bound again @@ -99,7 +99,7 @@ class VertexArrayObject { this.boundDynamicVertexBuffer2 = dynamicVertexBuffer2; } else { - numPrevAttributes = (gl: any).currentNumAttributes || 0; + numPrevAttributes = context.currentNumAttributes || 0; // Disable all attributes from the previous program that aren't used in // the new program. Note: attribute indices are *not* program specific! @@ -140,12 +140,12 @@ class VertexArrayObject { dynamicVertexBuffer2.setVertexAttribPointers(gl, program, vertexOffset); } - (gl: any).currentNumAttributes = numNextAttributes; + context.currentNumAttributes = numNextAttributes; } destroy() { if (this.vao) { - (this.gl: any).extVertexArrayObject.deleteVertexArrayOES(this.vao); + this.context.extVertexArrayObject.deleteVertexArrayOES(this.vao); this.vao = null; } } diff --git a/src/source/canvas_source.js b/src/source/canvas_source.js index da24acd55a7..794000414e7 100644 --- a/src/source/canvas_source.js +++ b/src/source/canvas_source.js @@ -135,7 +135,7 @@ class CanvasSource extends ImageSource { if (Object.keys(this.tiles).length === 0) return; // not enough data for current position - this._prepareImage(this.map.painter.gl, this.canvas, resize); + this._prepareImage(this.map.painter.context, this.canvas, resize); } serialize(): Object { diff --git a/src/source/image_source.js b/src/source/image_source.js index c1646e4eb1b..3d09b2cacfb 100644 --- a/src/source/image_source.js +++ b/src/source/image_source.js @@ -10,7 +10,6 @@ const ajax = require('../util/ajax'); const browser = require('../util/browser'); const EXTENT = require('../data/extent'); const RasterBoundsArray = require('../data/raster_bounds_array'); -const VertexBuffer = require('../gl/vertex_buffer'); const VertexArrayObject = require('../render/vertex_array_object'); const Texture = require('../render/texture'); @@ -20,6 +19,8 @@ import type Dispatcher from '../util/dispatcher'; import type Tile from './tile'; import type Coordinate from '../geo/coordinate'; import type {Callback} from '../types/callback'; +import type Context from '../gl/context'; +import type VertexBuffer from '../gl/vertex_buffer'; export type ImageTextureSource = ImageData | @@ -187,12 +188,13 @@ class ImageSource extends Evented implements Source { prepare() { if (Object.keys(this.tiles).length === 0 || !this.image) return; - this._prepareImage(this.map.painter.gl, this.image); + this._prepareImage(this.map.painter.context, this.image); } - _prepareImage(gl: WebGLRenderingContext, image: ImageTextureSource, resize?: boolean) { + _prepareImage(context: Context, image: ImageTextureSource, resize?: boolean) { + const gl = context.gl; if (!this.boundsBuffer) { - this.boundsBuffer = new VertexBuffer(gl, this._boundsArray); + this.boundsBuffer = context.createVertexBuffer(this._boundsArray); } if (!this.boundsVAO) { @@ -201,7 +203,7 @@ class ImageSource extends Evented implements Source { if (!this.textureLoaded) { this.textureLoaded = true; - this.texture = new Texture(gl, image, gl.RGBA); + this.texture = new Texture(context, image, gl.RGBA); this.texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE); } else if (resize) { this.texture.update(image); diff --git a/src/source/raster_tile_source.js b/src/source/raster_tile_source.js index a310f2ce9e4..215b5e296dc 100644 --- a/src/source/raster_tile_source.js +++ b/src/source/raster_tile_source.js @@ -99,13 +99,14 @@ class RasterTileSource extends Evented implements Source { delete (img: any).cacheControl; delete (img: any).expires; - const gl = this.map.painter.gl; + const context = this.map.painter.context; + const gl = context.gl; tile.texture = this.map.painter.getTileTexture(img.width); if (tile.texture) { tile.texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE, gl.LINEAR_MIPMAP_NEAREST); gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, img); } else { - tile.texture = new Texture(gl, img, gl.RGBA); + tile.texture = new Texture(context, img, gl.RGBA); tile.texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE, gl.LINEAR_MIPMAP_NEAREST); if (this.map.painter.extTextureFilterAnisotropic) { diff --git a/src/source/source_cache.js b/src/source/source_cache.js index 9e7b6a322b2..40170751063 100644 --- a/src/source/source_cache.js +++ b/src/source/source_cache.js @@ -8,6 +8,7 @@ const Cache = require('../util/lru_cache'); const Coordinate = require('../geo/coordinate'); const util = require('../util/util'); const EXTENT = require('../data/extent'); +const Context = require('../gl/context'); const Point = require('@mapbox/point-geometry'); const browser = require('../util/browser'); @@ -162,13 +163,13 @@ class SourceCache extends Evented { return this._source.serialize(); } - prepare(gl: WebGLRenderingContext) { + prepare(context: Context) { if (this._source.prepare) { this._source.prepare(); } for (const i in this._tiles) { - this._tiles[i].upload(gl); + this._tiles[i].upload(context); } } diff --git a/src/source/tile.js b/src/source/tile.js index 9badaaa10f9..4e4d69bc318 100644 --- a/src/source/tile.js +++ b/src/source/tile.js @@ -14,8 +14,6 @@ const RasterBoundsArray = require('../data/raster_bounds_array'); const TileCoord = require('./tile_coord'); const EXTENT = require('../data/extent'); const Point = require('@mapbox/point-geometry'); -const VertexBuffer = require('../gl/vertex_buffer'); -const IndexBuffer = require('../gl/index_buffer'); const Texture = require('../render/texture'); const {SegmentVector} = require('../data/segment'); const {TriangleIndexArray} = require('../data/index_array_type'); @@ -33,6 +31,9 @@ import type {WorkerTileResult} from './worker_source'; import type {RGBAImage, AlphaImage} from '../util/image'; import type Mask from '../render/tile_mask'; import type CrossTileSymbolIndex from '../symbol/cross_tile_symbol_index'; +import type Context from '../gl/context'; +import type IndexBuffer from '../gl/index_buffer'; +import type VertexBuffer from '../gl/vertex_buffer'; export type TileState = | 'loading' // Tile data is in the process of loading. @@ -251,22 +252,24 @@ class Tile { return this.buckets[layer.id]; } - upload(gl: WebGLRenderingContext) { + upload(context: Context) { for (const id in this.buckets) { const bucket = this.buckets[id]; if (!bucket.uploaded) { - bucket.upload(gl); + bucket.upload(context); bucket.uploaded = true; } } + const gl = context.gl; + if (this.iconAtlasImage) { - this.iconAtlasTexture = new Texture(gl, this.iconAtlasImage, gl.RGBA); + this.iconAtlasTexture = new Texture(context, this.iconAtlasImage, gl.RGBA); this.iconAtlasImage = null; } if (this.glyphAtlasImage) { - this.glyphAtlasTexture = new Texture(gl, this.glyphAtlasImage, gl.ALPHA); + this.glyphAtlasTexture = new Texture(context, this.glyphAtlasImage, gl.ALPHA); this.glyphAtlasImage = null; } } @@ -342,7 +345,7 @@ class Tile { } } - setMask(mask: Mask, gl: WebGLRenderingContext) { + setMask(mask: Mask, context: Context) { // don't redo buffer work if the mask is the same; if (util.deepEqual(this.mask, mask)) return; @@ -387,8 +390,8 @@ class Tile { segment.primitiveLength += 2; } - this.maskedBoundsBuffer = new VertexBuffer(gl, maskedBoundsArray); - this.maskedIndexBuffer = new IndexBuffer(gl, indexArray); + this.maskedBoundsBuffer = context.createVertexBuffer(maskedBoundsArray); + this.maskedIndexBuffer = context.createIndexBuffer(indexArray); } hasData() { diff --git a/src/source/video_source.js b/src/source/video_source.js index d046f5d099d..726070c2fae 100644 --- a/src/source/video_source.js +++ b/src/source/video_source.js @@ -113,7 +113,7 @@ class VideoSource extends ImageSource { prepare() { if (Object.keys(this.tiles).length === 0 || this.video.readyState < 2) return; // not enough data for current position - this._prepareImage(this.map.painter.gl, this.video); + this._prepareImage(this.map.painter.context, this.video); } serialize() { diff --git a/src/ui/map.js b/src/ui/map.js index a4fc68d0465..9e36fa15917 100755 --- a/src/ui/map.js +++ b/src/ui/map.js @@ -1512,7 +1512,7 @@ class Map extends Camera { window.removeEventListener('resize', this._onWindowResize, false); window.removeEventListener('online', this._onWindowOnline, false); } - const extension = this.painter.gl.getExtension('WEBGL_lose_context'); + const extension = this.painter.context.gl.getExtension('WEBGL_lose_context'); if (extension) extension.loseContext(); removeNode(this._canvasContainer); removeNode(this._controlContainer); diff --git a/yarn.lock b/yarn.lock index 112f8fe2cfb..2afc2196c93 100644 --- a/yarn.lock +++ b/yarn.lock @@ -194,11 +194,7 @@ version "3.0.0" resolved "https://registry.yarnpkg.com/@mapbox/whoots-js/-/whoots-js-3.0.0.tgz#c1de4293081424da3ac30c23afa850af1019bb54" -"@types/node@*": - version "8.0.34" - resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.34.tgz#55f801fa2ddb2a40dd6dfc15ecfe1dde9c129fe9" - -"@types/node@^6.0.46": +"@types/node@*", "@types/node@^6.0.46": version "6.0.88" resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.88.tgz#f618f11a944f6a18d92b5c472028728a3e3d4b66" @@ -300,14 +296,10 @@ acorn@^4.0.0, acorn@^4.0.3, acorn@^4.0.4: version "4.0.13" resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787" -acorn@^5.0.0: +acorn@^5.0.0, acorn@^5.0.1: version "5.1.2" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.1.2.tgz#911cb53e036807cf0fa778dc5d370fbd864246d7" -acorn@^5.0.1: - version "5.0.3" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.0.3.tgz#c460df08491463f028ccb82eab3730bf01087b3d" - add-stream@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/add-stream/-/add-stream-1.0.0.tgz#6a7990437ca736d5e1288db92bd3266d5f5cb2aa" @@ -447,11 +439,7 @@ arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" -arr-flatten@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.0.3.tgz#a274ed85ac08849b6bd7847c4580745dc51adfb1" - -arr-flatten@^1.1.0: +arr-flatten@^1.0.1, arr-flatten@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" @@ -670,31 +658,7 @@ babel-code-frame@^6.26.0: esutils "^2.0.2" js-tokens "^3.0.2" -babel-core@^6.0.14, babel-core@^6.17.0, babel-core@^6.24.1: - version "6.25.0" - resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.25.0.tgz#7dd42b0463c742e9d5296deb3ec67a9322dad729" - dependencies: - babel-code-frame "^6.22.0" - babel-generator "^6.25.0" - babel-helpers "^6.24.1" - babel-messages "^6.23.0" - babel-register "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.25.0" - babel-traverse "^6.25.0" - babel-types "^6.25.0" - babylon "^6.17.2" - convert-source-map "^1.1.0" - debug "^2.1.1" - json5 "^0.5.0" - lodash "^4.2.0" - minimatch "^3.0.2" - path-is-absolute "^1.0.0" - private "^0.1.6" - slash "^1.0.0" - source-map "^0.5.0" - -babel-core@^6.25.0, babel-core@^6.26.0: +babel-core@^6.0.14, babel-core@^6.25.0, babel-core@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.0.tgz#af32f78b31a6fcef119c87b0fd8d9753f03a0bb8" dependencies: @@ -718,6 +682,30 @@ babel-core@^6.25.0, babel-core@^6.26.0: slash "^1.0.0" source-map "^0.5.6" +babel-core@^6.17.0: + version "6.25.0" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.25.0.tgz#7dd42b0463c742e9d5296deb3ec67a9322dad729" + dependencies: + babel-code-frame "^6.22.0" + babel-generator "^6.25.0" + babel-helpers "^6.24.1" + babel-messages "^6.23.0" + babel-register "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.25.0" + babel-traverse "^6.25.0" + babel-types "^6.25.0" + babylon "^6.17.2" + convert-source-map "^1.1.0" + debug "^2.1.1" + json5 "^0.5.0" + lodash "^4.2.0" + minimatch "^3.0.2" + path-is-absolute "^1.0.0" + private "^0.1.6" + slash "^1.0.0" + source-map "^0.5.0" + babel-eslint@^7.0.0: version "7.2.3" resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-7.2.3.tgz#b2fe2d80126470f5c19442dc757253a897710827" @@ -1031,7 +1019,7 @@ babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: dependencies: babel-runtime "^6.22.0" -babel-plugin-transform-es2015-block-scoping@^6.23.0: +babel-plugin-transform-es2015-block-scoping@^6.23.0, babel-plugin-transform-es2015-block-scoping@^6.24.1: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" dependencies: @@ -1041,16 +1029,6 @@ babel-plugin-transform-es2015-block-scoping@^6.23.0: babel-types "^6.26.0" lodash "^4.17.4" -babel-plugin-transform-es2015-block-scoping@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.24.1.tgz#76c295dc3a4741b1665adfd3167215dcff32a576" - dependencies: - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - lodash "^4.2.0" - babel-plugin-transform-es2015-classes@^6.23.0, babel-plugin-transform-es2015-classes@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" @@ -1113,7 +1091,7 @@ babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015 babel-runtime "^6.22.0" babel-template "^6.24.1" -babel-plugin-transform-es2015-modules-commonjs@^6.23.0: +babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz#0d8394029b7dc6abe1a97ef181e00758dd2e5d8a" dependencies: @@ -1122,15 +1100,6 @@ babel-plugin-transform-es2015-modules-commonjs@^6.23.0: babel-template "^6.26.0" babel-types "^6.26.0" -babel-plugin-transform-es2015-modules-commonjs@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.24.1.tgz#d3e310b40ef664a36622200097c6d440298f2bfe" - dependencies: - babel-plugin-transform-strict-mode "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-types "^6.24.1" - babel-plugin-transform-es2015-modules-systemjs@^6.23.0, babel-plugin-transform-es2015-modules-systemjs@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" @@ -1274,18 +1243,12 @@ babel-plugin-transform-react-remove-prop-types@^0.4.9: version "0.4.9" resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.9.tgz#6805ef83d77bda94ded472ff2f2836bacd6ac44c" -babel-plugin-transform-regenerator@^6.22.0: +babel-plugin-transform-regenerator@^6.22.0, babel-plugin-transform-regenerator@^6.24.1: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" dependencies: regenerator-transform "^0.10.0" -babel-plugin-transform-regenerator@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.24.1.tgz#b8da305ad43c3c99b4848e4fe4037b770d23c418" - dependencies: - regenerator-transform "0.9.11" - babel-plugin-transform-runtime@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.23.0.tgz#88490d446502ea9b8e7efb0fe09ec4d99479b1ee" @@ -1415,19 +1378,7 @@ babel-preset-stage-3@^6.24.1: babel-plugin-transform-exponentiation-operator "^6.24.1" babel-plugin-transform-object-rest-spread "^6.22.0" -babel-register@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.24.1.tgz#7e10e13a2f71065bdfad5a1787ba45bca6ded75f" - dependencies: - babel-core "^6.24.1" - babel-runtime "^6.22.0" - core-js "^2.4.0" - home-or-tmp "^2.0.0" - lodash "^4.2.0" - mkdirp "^0.5.1" - source-map-support "^0.4.2" - -babel-register@^6.26.0: +babel-register@^6.24.1, babel-register@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" dependencies: @@ -1446,20 +1397,20 @@ babel-runtime@6.11.6: core-js "^2.4.0" regenerator-runtime "^0.9.5" -babel-runtime@^6.18.0, babel-runtime@^6.2.0, babel-runtime@^6.22.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.23.0.tgz#0a9489f144de70efb3ce4300accdb329e2fc543b" - dependencies: - core-js "^2.4.0" - regenerator-runtime "^0.10.0" - -babel-runtime@^6.26.0: +babel-runtime@^6.18.0, babel-runtime@^6.2.0, babel-runtime@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" dependencies: core-js "^2.4.0" regenerator-runtime "^0.11.0" +babel-runtime@^6.22.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.23.0.tgz#0a9489f144de70efb3ce4300accdb329e2fc543b" + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.10.0" + babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.25.0, babel-template@^6.3.0: version "6.25.0" resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.25.0.tgz#665241166b7c2aa4c619d71e192969552b10c071" @@ -1508,7 +1459,7 @@ babel-traverse@^6.26.0: invariant "^2.2.2" lodash "^4.17.4" -babel-types@^6.16.0, babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.23.0, babel-types@^6.24.1, babel-types@^6.25.0: +babel-types@^6.16.0, babel-types@^6.18.0, babel-types@^6.23.0, babel-types@^6.24.1, babel-types@^6.25.0: version "6.25.0" resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.25.0.tgz#70afb248d5660e5d18f811d91c8303b54134a18e" dependencies: @@ -1517,7 +1468,7 @@ babel-types@^6.16.0, babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.23 lodash "^4.2.0" to-fast-properties "^1.0.1" -babel-types@^6.26.0: +babel-types@^6.19.0, babel-types@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" dependencies: @@ -1654,14 +1605,10 @@ block-stream@*: dependencies: inherits "~2.0.0" -bluebird@^3.3.1: +bluebird@^3.3.1, bluebird@^3.4.7: version "3.5.0" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.0.tgz#791420d7f551eea2897453a8a77653f96606d67c" -bluebird@^3.4.7: - version "3.5.1" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" - bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: version "4.11.7" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.7.tgz#ddb048e50d9482790094c13eb3fcfc833ce7ab46" @@ -2125,15 +2072,7 @@ chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba" - dependencies: - ansi-styles "^3.1.0" - escape-string-regexp "^1.0.5" - supports-color "^4.0.0" - -chalk@^2.0.1, chalk@^2.1.0: +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.1.0.tgz#ac5becf14fa21b99c6c92ca7a7d7cfd5b17e743e" dependencies: @@ -2432,7 +2371,15 @@ concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" -concat-stream@^1.4.6, concat-stream@^1.4.7, concat-stream@^1.5.0, concat-stream@^1.6.0, concat-stream@~1.6.0: +concat-stream@^1.4.6, concat-stream@^1.5.0, concat-stream@~1.5.0, concat-stream@~1.5.1: + version "1.5.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.5.2.tgz#708978624d856af41a5a741defdd261da752c266" + dependencies: + inherits "~2.0.1" + readable-stream "~2.0.0" + typedarray "~0.0.5" + +concat-stream@^1.4.7, concat-stream@^1.6.0, concat-stream@~1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" dependencies: @@ -2584,11 +2531,7 @@ core-js@^1.0.0: version "1.2.7" resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" -core-js@^2.0.0, core-js@^2.4.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e" - -core-js@^2.5.0: +core-js@^2.0.0, core-js@^2.4.0, core-js@^2.5.0: version "2.5.1" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.1.tgz#ae6874dc66937789b80754ff5428df66819ca50b" @@ -2697,7 +2640,7 @@ cryptiles@3.x.x: dependencies: boom "5.x.x" -crypto-browserify@^3.0.0: +crypto-browserify@^3.0.0, crypto-browserify@^3.11.0: version "3.11.0" resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.11.0.tgz#3652a0906ab9b2a7e0c3ce66a408e957a2485522" dependencies: @@ -2712,21 +2655,6 @@ crypto-browserify@^3.0.0: public-encrypt "^4.0.0" randombytes "^2.0.0" -crypto-browserify@^3.11.0: - version "3.11.1" - resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.11.1.tgz#948945efc6757a400d6e5e5af47194d10064279f" - dependencies: - browserify-cipher "^1.0.0" - browserify-sign "^4.0.0" - create-ecdh "^4.0.0" - create-hash "^1.1.0" - create-hmac "^1.1.0" - diffie-hellman "^5.0.0" - inherits "^2.0.1" - pbkdf2 "^3.0.3" - public-encrypt "^4.0.0" - randombytes "^2.0.0" - crypto-random-string@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" @@ -2860,18 +2788,12 @@ debug@2.6.4: dependencies: ms "0.7.3" -debug@2.6.8, debug@^2.1.1, debug@^2.1.3, debug@^2.2.0, debug@^2.6.0, debug@^2.6.3, debug@^2.6.8: +debug@2.6.8, debug@^2.1.1, debug@^2.1.3, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.3, debug@^2.6.8, debug@~2.6.7: version "2.6.8" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" dependencies: ms "2.0.0" -debug@^2.3.3, debug@~2.6.7: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - dependencies: - ms "2.0.0" - decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -3283,11 +3205,7 @@ ejs@^2.5.7: version "2.5.7" resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.5.7.tgz#cc872c168880ae3c7189762fd5ffc00896c9518a" -electron-to-chromium@^1.2.7: - version "1.3.15" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.15.tgz#08397934891cbcfaebbd18b82a95b5a481138369" - -electron-to-chromium@^1.3.24: +electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.24: version "1.3.25" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.25.tgz#453b21009836d0997d86035601ff6cae4791c460" @@ -3422,16 +3340,7 @@ error@^7.0.0: string-template "~0.2.1" xtend "~4.0.0" -es-abstract@^1.4.3, es-abstract@^1.5.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.7.0.tgz#dfade774e01bfcd97f96180298c449c8623fb94c" - dependencies: - es-to-primitive "^1.1.1" - function-bind "^1.1.0" - is-callable "^1.1.3" - is-regex "^1.0.3" - -es-abstract@^1.6.1: +es-abstract@^1.4.3, es-abstract@^1.5.0, es-abstract@^1.6.1, es-abstract@^1.7.0: version "1.9.0" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.9.0.tgz#690829a07cae36b222e7fd9b75c0d0573eb25227" dependencies: @@ -3441,16 +3350,6 @@ es-abstract@^1.6.1: is-callable "^1.1.3" is-regex "^1.0.4" -es-abstract@^1.7.0: - version "1.8.2" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.8.2.tgz#25103263dc4decbda60e0c737ca32313518027ee" - dependencies: - es-to-primitive "^1.1.1" - function-bind "^1.1.1" - has "^1.0.1" - is-callable "^1.1.3" - is-regex "^1.0.4" - es-to-primitive@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d" @@ -3656,10 +3555,6 @@ esprima@^2.6.0, esprima@^2.7.1: version "2.7.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" -esprima@^3.1.1, esprima@~3.1.0: - version "3.1.3" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" - esprima@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" @@ -3672,6 +3567,10 @@ esprima@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.1.1.tgz#5b6f1547f4d102e670e140c509be6771d6aeb549" +esprima@~3.1.0: + version "3.1.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" + espurify@^1.3.0, espurify@^1.6.0: version "1.7.0" resolved "https://registry.yarnpkg.com/espurify/-/espurify-1.7.0.tgz#1c5cf6cbccc32e6f639380bd4f991fab9ba9d226" @@ -3915,7 +3814,7 @@ fbjs@^0.6.1: ua-parser-js "^0.7.9" whatwg-fetch "^0.9.0" -fbjs@^0.8.16: +fbjs@^0.8.16, fbjs@^0.8.4: version "0.8.16" resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db" dependencies: @@ -3927,30 +3826,6 @@ fbjs@^0.8.16: setimmediate "^1.0.5" ua-parser-js "^0.7.9" -fbjs@^0.8.4: - version "0.8.14" - resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.14.tgz#d1dbe2be254c35a91e09f31f9cd50a40b2a0ed1c" - dependencies: - core-js "^1.0.0" - isomorphic-fetch "^2.1.1" - loose-envify "^1.0.0" - object-assign "^4.1.0" - promise "^7.1.1" - setimmediate "^1.0.5" - ua-parser-js "^0.7.9" - -fbjs@^0.8.9: - version "0.8.15" - resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.15.tgz#4f0695fdfcc16c37c0b07facec8cb4c4091685b9" - dependencies: - core-js "^1.0.0" - isomorphic-fetch "^2.1.1" - loose-envify "^1.0.0" - object-assign "^4.1.0" - promise "^7.1.1" - setimmediate "^1.0.5" - ua-parser-js "^0.7.9" - fd@~0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/fd/-/fd-0.0.2.tgz#e0edb2bd7a88cc86dd9f16391cba832418fd87ee" @@ -4208,14 +4083,14 @@ fstream@^1.0.0, fstream@^1.0.10, fstream@^1.0.2: mkdirp ">=0.5 0" rimraf "2" -function-bind@^1.0.2, function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - -function-bind@^1.1.0: +function-bind@^1.0.2, function-bind@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.0.tgz#16176714c801798e4e8f2cf7f7529467bb4a5771" +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + function-loop@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/function-loop/-/function-loop-1.0.1.tgz#8076bb305e8e6a3cceee2920765f330d190f340c" @@ -4377,13 +4252,13 @@ github-from-package@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" -github-slugger@1.2.0: +github-slugger@1.2.0, github-slugger@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-1.2.0.tgz#8ada3286fd046d8951c3c952a8d7854cfd90fd9a" dependencies: emoji-regex ">=6.0.0 <=6.1.1" -github-slugger@^1.0.0, github-slugger@^1.1.1: +github-slugger@^1.1.1: version "1.1.3" resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-1.1.3.tgz#314a6e759a18c2b0cc5760d512ccbab549c549a7" dependencies: @@ -4578,17 +4453,7 @@ gulp-sourcemaps@1.6.0: through2 "^2.0.0" vinyl "^1.0.0" -handlebars@^4.0.2: - version "4.0.11" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.11.tgz#630a35dfe0294bc281edae6ffc5d329fc7982dcc" - dependencies: - async "^1.4.0" - optimist "^0.6.1" - source-map "^0.4.4" - optionalDependencies: - uglify-js "^2.6" - -handlebars@^4.0.3: +handlebars@^4.0.2, handlebars@^4.0.3: version "4.0.10" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.10.tgz#3d30c718b09a3d96f23ea4cc1f403c4d3ba9ff4f" dependencies: @@ -4998,14 +4863,10 @@ iconv-lite@0.4.13: version "0.4.13" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.13.tgz#1f88aba4ab0b1508e8312acc39345f36e992e2f2" -iconv-lite@^0.4.17, iconv-lite@~0.4.13: +iconv-lite@^0.4.17, iconv-lite@^0.4.5, iconv-lite@~0.4.13: version "0.4.18" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.18.tgz#23d8656b16aae6742ac29732ea8f0336a4789cf2" -iconv-lite@^0.4.5: - version "0.4.19" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" - ieee754@^1.1.4, ieee754@^1.1.6: version "1.1.8" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" @@ -5018,14 +4879,10 @@ ignore@^3.2.0, ignore@^3.3.3: version "3.3.3" resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.3.tgz#432352e57accd87ab3110e82d3fea0e47812156d" -immutable@3.8.1: +immutable@3.8.1, immutable@^3.7.6: version "3.8.1" resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.1.tgz#200807f11ab0f72710ea485542de088075f68cd2" -immutable@^3.7.6: - version "3.8.2" - resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.2.tgz#c2439951455bb39913daf281376f1530e104adf3" - import-lazy@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" @@ -5412,7 +5269,7 @@ is-redirect@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" -is-regex@^1.0.3, is-regex@^1.0.4: +is-regex@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" dependencies: @@ -5603,27 +5460,20 @@ js-tokens@^3.0.0, js-tokens@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" -js-yaml@3.6.1, js-yaml@^3.3.1: +js-yaml@3.6.1: version "3.6.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.6.1.tgz#6e5fe67d8b205ce4d22fad05b7781e8dadcc4b30" dependencies: argparse "^1.0.7" esprima "^2.6.0" -js-yaml@^3.10.0, js-yaml@^3.4.6: +js-yaml@^3.10.0, js-yaml@^3.2.7, js-yaml@^3.3.1, js-yaml@^3.4.3, js-yaml@^3.4.6, js-yaml@^3.8.4: version "3.10.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc" dependencies: argparse "^1.0.7" esprima "^4.0.0" -js-yaml@^3.2.7, js-yaml@^3.4.3, js-yaml@^3.8.4: - version "3.8.4" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.8.4.tgz#520b4564f86573ba96662af85a8cafa7b4b5a6f6" - dependencies: - argparse "^1.0.7" - esprima "^3.1.1" - jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" @@ -5812,11 +5662,7 @@ kind-of@^4.0.0: dependencies: is-buffer "^1.1.5" -kind-of@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" - -kind-of@^5.0.2: +kind-of@^5.0.0, kind-of@^5.0.2: version "5.0.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.0.2.tgz#f57bec933d9a2209ffa96c5c08343607b7035fda" @@ -6328,23 +6174,7 @@ mdast-util-inject@^1.1.0: dependencies: mdast-util-to-string "^1.0.0" -mdast-util-to-hast@^2.0.0, mdast-util-to-hast@^2.2.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-2.5.0.tgz#f087844d255c7540f36906da30ba106c0ee5ee2f" - dependencies: - collapse-white-space "^1.0.0" - detab "^2.0.0" - mdast-util-definitions "^1.2.0" - mdurl "^1.0.1" - trim "0.0.1" - trim-lines "^1.0.0" - unist-builder "^1.0.1" - unist-util-generated "^1.1.0" - unist-util-position "^3.0.0" - unist-util-visit "^1.1.0" - xtend "^4.0.1" - -mdast-util-to-hast@^2.1.1: +mdast-util-to-hast@^2.0.0, mdast-util-to-hast@^2.1.1, mdast-util-to-hast@^2.2.0: version "2.4.2" resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-2.4.2.tgz#f116e8bf3da772ba5a397a92dab090f5ba91caa0" dependencies: @@ -6376,10 +6206,6 @@ mdn-data@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-1.0.0.tgz#a69d9da76847b4d5834c1465ea25c0653a1fbf66" -mdurl@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" - mem@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" @@ -6475,13 +6301,13 @@ mime-db@~1.30.0: version "1.30.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01" -mime-types@^2.1.12, mime-types@~2.1.7: +mime-types@^2.1.12, mime-types@~2.1.11, mime-types@~2.1.7: version "2.1.15" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.15.tgz#a4ebf5064094569237b8cf70046776d09fc92aed" dependencies: mime-db "~1.27.0" -mime-types@~2.1.11, mime-types@~2.1.16, mime-types@~2.1.17: +mime-types@~2.1.16, mime-types@~2.1.17: version "2.1.17" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a" dependencies: @@ -6495,11 +6321,7 @@ mime@1.3.4: version "1.3.4" resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53" -"mime@>= 0.0.1": - version "2.0.3" - resolved "https://registry.yarnpkg.com/mime/-/mime-2.0.3.tgz#4353337854747c48ea498330dc034f9f4bbbcc0b" - -mime@^1.2.11, mime@^1.4.1: +"mime@>= 0.0.1", mime@^1.2.11, mime@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" @@ -7623,7 +7445,7 @@ postcss-values-parser@^1.3.1: indexes-of "^1.0.1" uniq "^1.0.1" -postcss@^5.0.0, postcss@^5.0.18, postcss@^5.0.20, postcss@^5.0.21, postcss@^5.0.4, postcss@^5.0.8, postcss@^5.2.13, postcss@^5.2.16, postcss@^5.2.4: +postcss@^5.0.0, postcss@^5.0.14, postcss@^5.0.18, postcss@^5.0.20, postcss@^5.0.21, postcss@^5.0.4, postcss@^5.0.8, postcss@^5.2.13, postcss@^5.2.16, postcss@^5.2.4: version "5.2.17" resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.17.tgz#cf4f597b864d65c8a492b2eabe9d706c879c388b" dependencies: @@ -7632,15 +7454,6 @@ postcss@^5.0.0, postcss@^5.0.18, postcss@^5.0.20, postcss@^5.0.21, postcss@^5.0. source-map "^0.5.6" supports-color "^3.2.3" -postcss@^5.0.14: - version "5.2.18" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.18.tgz#badfa1497d46244f6390f58b319830d9107853c5" - dependencies: - chalk "^1.1.3" - js-base64 "^2.1.9" - source-map "^0.5.6" - supports-color "^3.2.3" - postcss@^6.0.0, postcss@^6.0.1, postcss@^6.0.12, postcss@^6.0.13: version "6.0.13" resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.13.tgz#b9ecab4ee00c89db3ec931145bd9590bbf3f125f" @@ -7724,14 +7537,7 @@ promise@^7.0.3, promise@^7.1.1: dependencies: asap "~2.0.3" -prop-types@^15.5.10: - version "15.5.10" - resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.5.10.tgz#2797dfc3126182e3a95e3dfbb2e893ddd7456154" - dependencies: - fbjs "^0.8.9" - loose-envify "^1.3.1" - -prop-types@^15.5.4, prop-types@^15.6.0: +prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.6.0: version "15.6.0" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856" dependencies: @@ -7811,11 +7617,7 @@ punycode@^1.2.4, punycode@^1.3.2, punycode@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" -q@^1.1.2: - version "1.5.0" - resolved "https://registry.yarnpkg.com/q/-/q-1.5.0.tgz#dd01bac9d06d30e6f219aecb8253ee9ebdc308f1" - -q@^1.4.1: +q@^1.1.2, q@^1.4.1: version "1.5.1" resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" @@ -7827,18 +7629,18 @@ qs@6.2.1: version "6.2.1" resolved "https://registry.yarnpkg.com/qs/-/qs-6.2.1.tgz#ce03c5ff0935bc1d9d69a9f14cbd18e568d67625" -"qs@>= 0.4.0", qs@^6.4.0, qs@~6.5.1: +"qs@>= 0.4.0", qs@~6.5.1: version "6.5.1" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" +qs@^6.4.0, qs@~6.4.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" + qs@~6.3.0: version "6.3.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.3.2.tgz#e75bd5f6e268122a2a0e0bda630b2550c166502c" -qs@~6.4.0: - version "6.4.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" - querystring-es3@^0.2.0, querystring-es3@~0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" @@ -8098,14 +7900,6 @@ regenerator-runtime@^0.9.5: version "0.9.6" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.9.6.tgz#d33eb95d0d2001a4be39659707c51b0cb71ce029" -regenerator-transform@0.9.11: - version "0.9.11" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.9.11.tgz#3a7d067520cb7b7176769eb5ff868691befe1283" - dependencies: - babel-runtime "^6.18.0" - babel-types "^6.19.0" - private "^0.1.6" - regenerator-transform@^0.10.0: version "0.10.1" resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" @@ -8337,7 +8131,7 @@ request-promise-native@^1.0.3: stealthy-require "^1.1.0" tough-cookie ">=2.3.3" -request@2, request@2.81.0, request@^2.79.0, request@^2.81.0: +request@2, request@2.81.0, request@^2.79.0: version "2.81.0" resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" dependencies: @@ -8389,7 +8183,7 @@ request@2.79.0: tunnel-agent "~0.4.1" uuid "^3.0.0" -"request@>= 2.44.0 < 3.0.0", request@^2.83.0: +"request@>= 2.44.0 < 3.0.0", request@^2.81.0, request@^2.83.0: version "2.83.0" resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356" dependencies: @@ -8572,14 +8366,10 @@ semver-diff@^2.0.0: dependencies: semver "^5.0.3" -"semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", semver@5.3.0, semver@^5.3.0, semver@~5.3.0: +"semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", semver@5.3.0, semver@^5.0.1, semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@~5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" -semver@^5.0.1, semver@^5.0.3, semver@^5.1.0: - version "5.4.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" - send@0.15.2: version "0.15.2" resolved "https://registry.yarnpkg.com/send/-/send-0.15.2.tgz#f91fab4403bcf87e716f70ceb5db2f578bdc17d6" @@ -8893,13 +8683,7 @@ source-map-resolve@^0.5.0: source-map-url "^0.4.0" urix "^0.1.0" -source-map-support@^0.4.15: - version "0.4.18" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" - dependencies: - source-map "^0.5.6" - -source-map-support@^0.4.2, source-map-support@^0.4.3: +source-map-support@^0.4.15, source-map-support@^0.4.3: version "0.4.15" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.15.tgz#03202df65c06d2bd8c7ec2362a193056fef8d3b1" dependencies: @@ -8915,14 +8699,14 @@ source-map-url@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" -source-map@0.5.x, source-map@^0.5.1, source-map@~0.5.0: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - -"source-map@>= 0.1.2", source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1, source-map@~0.5.3: +source-map@0.5.x, source-map@^0.5.0, source-map@^0.5.1, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.0, source-map@~0.5.1, source-map@~0.5.3: version "0.5.6" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" +"source-map@>= 0.1.2", source-map@^0.6.0, source-map@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + source-map@^0.1.34, source-map@~0.1.33: version "0.1.43" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" @@ -8935,10 +8719,6 @@ source-map@^0.4.2, source-map@^0.4.4: dependencies: amdefine ">=0.0.4" -source-map@^0.6.0, source-map@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - source-map@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d" @@ -9369,18 +9149,12 @@ supports-color@^3.1.2, supports-color@^3.2.3: dependencies: has-flag "^1.0.0" -supports-color@^4.0.0, supports-color@^4.2.1, supports-color@^4.4.0: +supports-color@^4.0.0, supports-color@^4.1.0, supports-color@^4.2.1, supports-color@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.4.0.tgz#883f7ddabc165142b2a61427f3352ded195d1a3e" dependencies: has-flag "^2.0.0" -supports-color@^4.1.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b" - dependencies: - has-flag "^2.0.0" - svg-tags@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/svg-tags/-/svg-tags-1.0.0.tgz#58f71cee3bd519b59d4b2a843b6c7de64ac04764" @@ -9814,14 +9588,10 @@ typedarray@^0.0.6, typedarray@~0.0.5: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" -ua-parser-js@0.7.12: +ua-parser-js@0.7.12, ua-parser-js@^0.7.9: version "0.7.12" resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.12.tgz#04c81a99bdd5dc52263ea29d24c6bf8d4818a4bb" -ua-parser-js@^0.7.9: - version "0.7.14" - resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.14.tgz#110d53fa4c3f326c121292bbeac904d2e03387ca" - uglify-es@^3.0.26: version "3.1.3" resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.1.3.tgz#a21eeb149cb120a1f8302563689e19496550780b" @@ -10255,14 +10025,10 @@ web-namespaces@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-1.1.1.tgz#742d9fff61ff84f4164f677244f42d29c10c451d" -webidl-conversions@^4.0.0: +webidl-conversions@^4.0.0, webidl-conversions@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.1.tgz#8015a17ab83e7e1b311638486ace81da6ce206a0" -webidl-conversions@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" - webpack-chunk-hash@^0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/webpack-chunk-hash/-/webpack-chunk-hash-0.5.0.tgz#1dba38203d73c1e6ab069b6810a5a37402399dec" From debc2100b921eb981e05883c41ab336747dec8d0 Mon Sep 17 00:00:00 2001 From: Lauren Budorick Date: Wed, 22 Nov 2017 16:40:24 -0800 Subject: [PATCH 2/9] Use Color type, fix flow errors from rebase, reset yarn.lock --- src/data/program_configuration.js | 2 +- src/gl/context.js | 8 +- src/gl/types.js | 2 - src/gl/value.js | 18 +- src/render/draw_background.js | 2 +- src/render/draw_fill_extrusion.js | 3 +- src/render/draw_heatmap.js | 3 +- src/render/painnnter | 561 ------------------------------ src/render/painter.js | 7 +- yarn.lock | 444 +++++++++++++++++------ 10 files changed, 366 insertions(+), 684 deletions(-) delete mode 100644 src/render/painnnter diff --git a/src/data/program_configuration.js b/src/data/program_configuration.js index d83dc711a68..491633479f5 100644 --- a/src/data/program_configuration.js +++ b/src/data/program_configuration.js @@ -6,8 +6,8 @@ const createVertexArrayType = require('./vertex_array_type'); const packUint8ToFloat = require('../shaders/encode_attribute').packUint8ToFloat; const Color = require('../style-spec/util/color'); const {deserialize, serialize, register} = require('../util/web_worker_transfer'); -const Context = require('../gl/context'); +import type Context from '../gl/context'; import type StyleLayer from '../style/style_layer'; import type {Serialized} from '../util/web_worker_transfer'; import type {ViewType, StructArray} from '../util/struct_array'; diff --git a/src/gl/context.js b/src/gl/context.js index d3024955491..27940f14a5f 100644 --- a/src/gl/context.js +++ b/src/gl/context.js @@ -37,7 +37,6 @@ import type {TriangleIndexArray, LineIndexArray} from '../data/index_array_type' import type {StructArray} from '../util/struct_array'; import type { BlendFuncType, - ColorType, ColorMaskType, DepthRangeType, StencilFuncType, @@ -46,9 +45,10 @@ import type { TextureUnitType, ViewportType, } from './types'; +import type Color from '../style-spec/util/color'; type ClearArgs = { - color?: ColorType, + color?: Color, depth?: number, stencil?: number // TODO previously painter had `clearDepth`, `clearColor`, `clearStencil` @@ -63,7 +63,7 @@ class Context { extVertexArrayObject: any; currentNumAttributes: ?number; - clearColor: State; + clearColor: State; clearDepth: State; clearStencil: State; colorMask: State; @@ -77,7 +77,7 @@ class Context { depthFunc: State; blend: State; blendFunc: State; - blendColor: State; + blendColor: State; program: State; lineWidth: State; activeTexture: State; diff --git a/src/gl/types.js b/src/gl/types.js index 64c9179e376..b393825e9ee 100644 --- a/src/gl/types.js +++ b/src/gl/types.js @@ -19,8 +19,6 @@ type BlendFuncConstant = export type BlendFuncType = [BlendFuncConstant, BlendFuncConstant]; -export type ColorType = [number, number, number, number]; - export type ColorMaskType = [boolean, boolean, boolean, boolean]; export type DepthRangeType = [number, number]; diff --git a/src/gl/value.js b/src/gl/value.js index e8d672540b7..230b2831b09 100644 --- a/src/gl/value.js +++ b/src/gl/value.js @@ -3,7 +3,6 @@ import type Context from './context'; import type { BlendFuncType, - ColorType, ColorMaskType, DepthRangeType, StencilFuncType, @@ -12,6 +11,7 @@ import type { TextureUnitType, ViewportType, } from './types'; +const Color = require('../style-spec/util/color'); export interface Value { context: Context; @@ -27,11 +27,11 @@ class ContextValue { } } -class ClearColor extends ContextValue implements Value { - static default() { return [0, 0, 0, 0]; } +class ClearColor extends ContextValue implements Value { + static default() { return Color.transparent; } - set(v: ColorType): void { - this.context.gl.clearColor(v[0], v[1], v[2], v[3]); + set(v: Color): void { + this.context.gl.clearColor(v.r, v.g, v.b, v.a); } } @@ -168,11 +168,11 @@ class BlendFunc extends ContextValue implements Value { } } -class BlendColor extends ContextValue implements Value { - static default() { return [0, 0, 0, 0]; } +class BlendColor extends ContextValue implements Value { + static default() { return Color.transparent; } - set(v: ColorType): void { - this.context.gl.blendColor(v[0], v[1], v[2], v[3]); + set(v: Color): void { + this.context.gl.blendColor(v.r, v.g, v.b, v.a); } } diff --git a/src/render/draw_background.js b/src/render/draw_background.js index 74252357727..af2a4d3bb2d 100644 --- a/src/render/draw_background.js +++ b/src/render/draw_background.js @@ -43,7 +43,7 @@ function drawBackground(painter: Painter, sourceCache: SourceCache, layer: Backg if (pattern.isPatternMissing(image, painter)) return; const configuration = ProgramConfiguration.forBackgroundPattern(opacity); program = painter.useProgram('fillPattern', configuration); - configuration.setUniforms(gl, program, properties, globals); + configuration.setUniforms(context, program, properties, globals); pattern.prepare(image, painter, program); painter.tileExtentPatternVAO.bind(context, program, painter.tileExtentBuffer); } else { diff --git a/src/render/draw_fill_extrusion.js b/src/render/draw_fill_extrusion.js index 32125a86406..eb9e545bb62 100644 --- a/src/render/draw_fill_extrusion.js +++ b/src/render/draw_fill_extrusion.js @@ -2,6 +2,7 @@ const glMatrix = require('@mapbox/gl-matrix'); const pattern = require('./pattern'); +const Color = require('../style-spec/util/color'); const mat3 = glMatrix.mat3; const mat4 = glMatrix.mat4; const vec3 = glMatrix.vec3; @@ -25,7 +26,7 @@ function draw(painter: Painter, source: SourceCache, layer: FillExtrusionStyleLa context.stencilTest.set(false); context.depthTest.set(true); - context.clear({ color: [0, 0, 0, 0] }); + context.clear({ color: Color.transparent }); context.depthMask.set(true); for (let i = 0; i < coords.length; i++) { diff --git a/src/render/draw_heatmap.js b/src/render/draw_heatmap.js index 4f2c10d648e..e6c26336df7 100644 --- a/src/render/draw_heatmap.js +++ b/src/render/draw_heatmap.js @@ -3,6 +3,7 @@ const mat4 = require('@mapbox/gl-matrix').mat4; const Texture = require('./texture'); const pixelsToTileUnits = require('../source/pixels_to_tile_units'); +const Color = require('../style-spec/util/color'); import type Painter from './painter'; import type SourceCache from '../source/source_cache'; @@ -30,7 +31,7 @@ function drawHeatmap(painter: Painter, sourceCache: SourceCache, layer: HeatmapS renderToTexture(context, painter, layer); - context.clear({ color: [0, 0, 0, 0] }); + context.clear({ color: Color.transparent }); // Turn on additive blending for kernels, which is a key aspect of kernel density estimation formula context.blendFunc.set([gl.ONE, gl.ONE]); diff --git a/src/render/painnnter b/src/render/painnnter deleted file mode 100644 index efe639da544..00000000000 --- a/src/render/painnnter +++ /dev/null @@ -1,561 +0,0 @@ -// @flow - -const browser = require('../util/browser'); -const mat4 = require('@mapbox/gl-matrix').mat4; -const SourceCache = require('../source/source_cache'); -const EXTENT = require('../data/extent'); -const pixelsToTileUnits = require('../source/pixels_to_tile_units'); -const util = require('../util/util'); -const VertexArrayObject = require('./vertex_array_object'); -const RasterBoundsArray = require('../data/raster_bounds_array'); -const PosArray = require('../data/pos_array'); -const {ProgramConfiguration} = require('../data/program_configuration'); -const CrossTileSymbolIndex = require('../symbol/cross_tile_symbol_index'); -const shaders = require('../shaders'); -const Program = require('./program'); -const Context = require('../gl/context'); -const RenderTexture = require('./render_texture'); -const updateTileMasks = require('./tile_mask'); - -const draw = { - symbol: require('./draw_symbol'), - circle: require('./draw_circle'), - heatmap: require('./draw_heatmap'), - line: require('./draw_line'), - fill: require('./draw_fill'), - 'fill-extrusion': require('./draw_fill_extrusion'), - raster: require('./draw_raster'), - background: require('./draw_background'), - debug: require('./draw_debug') -}; - -import type Transform from '../geo/transform'; -import type Tile from '../source/tile'; -import type TileCoord from '../source/tile_coord'; -import type Style from '../style/style'; -import type StyleLayer from '../style/style_layer'; -import type LineAtlas from './line_atlas'; -import type Texture from './texture'; -import type ImageManager from './image_manager'; -import type GlyphManager from './glyph_manager'; -import type VertexBuffer from '../gl/vertex_buffer'; - -export type RenderPass = '3d' | 'opaque' | 'translucent'; - -type PainterOptions = { - showOverdrawInspector: boolean, - showTileBoundaries: boolean, - rotating: boolean, - zooming: boolean, - collisionFadeDuration: number -} - -/** - * Initialize a new painter object. - * - * @param {Canvas} gl an experimental-webgl drawing context - * @private - */ -class Painter { - context: Context; - transform: Transform; - _tileTextures: { [number]: Array }; - numSublayers: number; - depthEpsilon: number; - lineWidthRange: [number, number]; - emptyProgramConfiguration: ProgramConfiguration; - width: number; - height: number; - depthRbo: WebGLRenderbuffer; - depthRboAttached: boolean; - tileExtentBuffer: VertexBuffer; - tileExtentVAO: VertexArrayObject; - tileExtentPatternVAO: VertexArrayObject; - debugBuffer: VertexBuffer; - debugVAO: VertexArrayObject; - rasterBoundsBuffer: VertexBuffer; - rasterBoundsVAO: VertexArrayObject; - viewportBuffer: VertexBuffer; - viewportVAO: VertexArrayObject; - extTextureFilterAnisotropic: any; - extTextureFilterAnisotropicMax: any; - extTextureHalfFloat: any; - _tileClippingMaskIDs: { [number]: number }; - style: Style; - options: PainterOptions; - lineAtlas: LineAtlas; - imageManager: ImageManager; - glyphManager: GlyphManager; - depthRange: number; - renderPass: RenderPass; - currentLayer: number; - id: string; - _showOverdrawInspector: boolean; - cache: { [string]: Program }; - currentProgram: Program; - crossTileSymbolIndex: CrossTileSymbolIndex; - - constructor(gl: WebGLRenderingContext, transform: Transform) { - this.context = new Context(gl); - this.transform = transform; - this._tileTextures = {}; - - this.setup(); - - // Within each layer there are multiple distinct z-planes that can be drawn to. - // This is implemented using the WebGL depth buffer. - this.numSublayers = SourceCache.maxUnderzooming + SourceCache.maxOverzooming + 1; - this.depthEpsilon = 1 / Math.pow(2, 16); - - this.lineWidthRange = gl.getParameter(gl.ALIASED_LINE_WIDTH_RANGE); - - this.emptyProgramConfiguration = new ProgramConfiguration(); - - this.crossTileSymbolIndex = new CrossTileSymbolIndex(); - } - - /* - * Update the GL viewport, projection matrix, and transforms to compensate - * for a new width and height value. - */ - resize(width: number, height: number) { - const gl = this.context.gl; - - this.width = width * browser.devicePixelRatio; - this.height = height * browser.devicePixelRatio; - this.context.viewport.set([0, 0, this.width, this.height]); - - if (this.style) { - for (const layerId of this.style._order) { - this.style._layers[layerId].resize(gl); - } - } - - if (this.depthRbo) { - gl.deleteRenderbuffer(this.depthRbo); - this.depthRbo = null; - } - } - - setup() { - const context = this.context; - const gl = this.context.gl; - - // We are blending the new pixels *behind* the existing pixels. That way we can - // draw front-to-back and use then stencil buffer to cull opaque pixels early. - context.blend.set(true); - context.blendFunc.set([gl.LINES, gl.ONE_MINUS_SRC_ALPHA]); - - context.stencilTest.set(true); - - context.depthTest.set(true); - context.depthFunc.set(gl.LEQUAL); - - context.depthMask.set(false); - - const tileExtentArray = new PosArray(); - tileExtentArray.emplaceBack(0, 0); - tileExtentArray.emplaceBack(EXTENT, 0); - tileExtentArray.emplaceBack(0, EXTENT); - tileExtentArray.emplaceBack(EXTENT, EXTENT); - this.tileExtentBuffer = context.createVertexBuffer(tileExtentArray); - this.tileExtentVAO = new VertexArrayObject(); - this.tileExtentPatternVAO = new VertexArrayObject(); - - const debugArray = new PosArray(); - debugArray.emplaceBack(0, 0); - debugArray.emplaceBack(EXTENT, 0); - debugArray.emplaceBack(EXTENT, EXTENT); - debugArray.emplaceBack(0, EXTENT); - debugArray.emplaceBack(0, 0); - this.debugBuffer = context.createVertexBuffer(debugArray); - this.debugVAO = new VertexArrayObject(); - - const rasterBoundsArray = new RasterBoundsArray(); - rasterBoundsArray.emplaceBack(0, 0, 0, 0); - rasterBoundsArray.emplaceBack(EXTENT, 0, EXTENT, 0); - rasterBoundsArray.emplaceBack(0, EXTENT, 0, EXTENT); - rasterBoundsArray.emplaceBack(EXTENT, EXTENT, EXTENT, EXTENT); - this.rasterBoundsBuffer = context.createVertexBuffer(rasterBoundsArray); - this.rasterBoundsVAO = new VertexArrayObject(); - - const viewportArray = new PosArray(); - viewportArray.emplaceBack(0, 0); - viewportArray.emplaceBack(1, 0); - viewportArray.emplaceBack(0, 1); - viewportArray.emplaceBack(1, 1); - this.viewportBuffer = context.createVertexBuffer(viewportArray); - this.viewportVAO = new VertexArrayObject(); - - this.extTextureFilterAnisotropic = ( - gl.getExtension('EXT_texture_filter_anisotropic') || - gl.getExtension('MOZ_EXT_texture_filter_anisotropic') || - gl.getExtension('WEBKIT_EXT_texture_filter_anisotropic') - ); - if (this.extTextureFilterAnisotropic) { - this.extTextureFilterAnisotropicMax = gl.getParameter(this.extTextureFilterAnisotropic.MAX_TEXTURE_MAX_ANISOTROPY_EXT); - } - - this.extTextureHalfFloat = gl.getExtension('OES_texture_half_float'); - if (this.extTextureHalfFloat) { - gl.getExtension('OES_texture_half_float_linear'); - } - } - - /* - * Reset the drawing canvas by clearing the stencil buffer so that we can draw - * new tiles at the same location, while retaining previously drawn pixels. - */ - clearStencil() { - const context = this.context; - const gl = context.gl; - - // As a temporary workaround for https://github.com/mapbox/mapbox-gl-js/issues/5490, - // pending an upstream fix, we draw a fullscreen stencil=0 clipping mask here, - // effectively clearing the stencil buffer: once an upstream patch lands, remove - // this function in favor of context.clear({ stencil: 0x0 }) - - context.colorMask.set([false, false, false, false]); - context.depthMask.set(false); - context.depthTest.set(false); - context.stencilTest.set(true); - - context.stencilMask.set(0xFF); - context.stencilOp.set([gl.ZERO, gl.ZERO, gl.ZERO]); - - context.stencilFunc.set({ func: gl.ALWAYS, ref: 0x0, mask: 0xFF }); - - 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('fill', ProgramConfiguration.forTileClippingMask()); - gl.uniformMatrix4fv(program.uniforms.u_matrix, false, matrix); - - this.viewportVAO.bind(context, program, this.viewportBuffer); - gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4); - - context.stencilMask.set(0x00); - context.colorMask.set([true, true, true, true]); - context.depthMask.set(true); - context.depthTest.set(true); - } - - _renderTileClippingMasks(coords: Array) { - const context = this.context; - const gl = context.gl; - context.colorMask.set([false, false, false, false]); - context.depthMask.set(false); - context.depthTest.set(false); - context.stencilTest.set(true); - - context.stencilMask.set(0xFF); - // Tests will always pass, and ref value will be written to stencil buffer. - context.stencilOp.set([gl.KEEP, gl.KEEP, gl.REPLACE]); - - let idNext = 1; - this._tileClippingMaskIDs = {}; - const programConfiguration = ProgramConfiguration.forTileClippingMask(); - - for (const coord of coords) { - const id = this._tileClippingMaskIDs[coord.id] = idNext++; - - gl.stencilFunc(gl.ALWAYS, id, 0xFF); - - const program = this.useProgram('fill', programConfiguration); - gl.uniformMatrix4fv(program.uniforms.u_matrix, false, coord.posMatrix); - - // Draw the clipping mask - this.tileExtentVAO.bind(this.context, program, this.tileExtentBuffer); - gl.drawArrays(gl.TRIANGLE_STRIP, 0, this.tileExtentBuffer.length); - } - - context.stencilMask.set(0x00); - context.colorMask.set([true, true, true, true]); - context.depthMask.set(true); - context.depthTest.set(true); - } - - enableTileClippingMask(coord: TileCoord) { - const gl = this.context.gl; - gl.stencilFunc(gl.EQUAL, this._tileClippingMaskIDs[coord.id], 0xFF); - } - - render(style: Style, options: PainterOptions) { - this.style = style; - this.options = options; - - this.lineAtlas = style.lineAtlas; - this.imageManager = style.imageManager; - this.glyphManager = style.glyphManager; - - const context = this.context; - - for (const id in style.sourceCaches) { - const sourceCache = this.style.sourceCaches[id]; - if (sourceCache.used) { - sourceCache.prepare(this.context); - } - } - - const layerIds = this.style._order; - - const rasterSources = util.filterObject(this.style.sourceCaches, (sc) => { return sc._source.type === 'raster'; }); - for (const key in rasterSources) { - const sourceCache = rasterSources[key]; - const coords = sourceCache.getVisibleCoordinates(); - const visibleTiles = coords.map((c)=>{ return sourceCache.getTile(c); }); - updateTileMasks(visibleTiles, this.context); - } - - // 3D pass - // We first create a renderbuffer that we'll use to preserve depth - // results across 3D layers, then render each 3D layer to its own - // framebuffer/texture, which we'll use later in the translucent pass - // to render to the main framebuffer. By doing this before we render to - // the main framebuffer we won't have to do an expensive framebuffer - // restore mid-render pass. - // The most important distinction of the 3D pass is that we use the - // depth buffer in an entirely different way (to represent 3D space) - // than we do in the 2D pass (to preserve layer order). - this.renderPass = '3d'; - { - // We'll wait and only attach the depth renderbuffer if we think we're - // rendering something. - let first = true; - - let sourceCache; - let coords = []; - - for (let i = 0; i < layerIds.length; i++) { - const layer = this.style._layers[layerIds[i]]; - - if (!layer.has3DPass() || layer.isHidden(this.transform.zoom)) continue; - - if (layer.source !== (sourceCache && sourceCache.id)) { - sourceCache = this.style.sourceCaches[layer.source]; - coords = []; - - if (sourceCache) { - this.clearStencil(); - coords = sourceCache.getVisibleCoordinates(); - } - - coords.reverse(); - } - - if (!coords.length) continue; - - this._setup3DRenderbuffer(); - - const renderTarget = layer.viewportFrame || new RenderTexture(this); - layer.viewportFrame = renderTarget; - renderTarget.bindWithDepth(this.depthRbo); - - if (first) { - context.clear({ depth: 1 }); - first = false; - } - - this.renderLayer(this, (sourceCache: any), layer, coords); - - renderTarget.unbind(); - } - } - - // Clear buffers in preparation for drawing to the main framebuffer - context.clear({ color: [0, 0, 0, 0], depth: 1 }); - - this.showOverdrawInspector(options.showOverdrawInspector); - - this.depthRange = (style._order.length + 2) * this.numSublayers * this.depthEpsilon; - - // Opaque pass - // Draw opaque layers top-to-bottom first. - this.renderPass = 'opaque'; - { - let sourceCache; - let coords = []; - - this.currentLayer = layerIds.length - 1; - - if (!this._showOverdrawInspector) { - this.context.blend.set(false); - } - - for (this.currentLayer; this.currentLayer >= 0; this.currentLayer--) { - const layer = this.style._layers[layerIds[this.currentLayer]]; - - if (layer.source !== (sourceCache && sourceCache.id)) { - sourceCache = this.style.sourceCaches[layer.source]; - coords = []; - - if (sourceCache) { - this.clearStencil(); - coords = sourceCache.getVisibleCoordinates(); - if (sourceCache.getSource().isTileClipped) { - this._renderTileClippingMasks(coords); - } - } - } - - this.renderLayer(this, (sourceCache: any), layer, coords); - } - } - - // Translucent pass - // Draw all other layers bottom-to-top. - this.renderPass = 'translucent'; - { - let sourceCache; - let coords = []; - - this.context.blend.set(true); - - this.currentLayer = 0; - - for (this.currentLayer; this.currentLayer < layerIds.length; this.currentLayer++) { - const layer = this.style._layers[layerIds[this.currentLayer]]; - - if (layer.source !== (sourceCache && sourceCache.id)) { - sourceCache = this.style.sourceCaches[layer.source]; - coords = []; - - if (sourceCache) { - this.clearStencil(); - coords = sourceCache.getVisibleCoordinates(); - if (sourceCache.getSource().isTileClipped) { - this._renderTileClippingMasks(coords); - } - } - - coords.reverse(); - } - - this.renderLayer(this, (sourceCache: any), layer, coords); - } - } - - if (this.options.showTileBoundaries) { - const sourceCache = this.style.sourceCaches[Object.keys(this.style.sourceCaches)[0]]; - if (sourceCache) { - draw.debug(this, sourceCache, sourceCache.getVisibleCoordinates()); - } - } - } - - _setup3DRenderbuffer() { - const context = this.context; - // All of the 3D textures will use the same depth renderbuffer. - if (!this.depthRbo) { - const gl = this.context.gl; - this.depthRbo = gl.createRenderbuffer(); - - context.bindRenderbuffer.set(this.depthRbo); - gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, this.width, this.height); - context.bindRenderbuffer.set(null); - } - - this.depthRboAttached = true; - } - - renderLayer(painter: Painter, sourceCache: SourceCache, layer: StyleLayer, coords: Array) { - if (layer.isHidden(this.transform.zoom)) return; - if (layer.type !== 'background' && !coords.length) return; - this.id = layer.id; - - draw[layer.type](painter, sourceCache, layer, coords); - } - - setDepthSublayer(n: number) { - const farDepth = 1 - ((1 + this.currentLayer) * this.numSublayers + n) * this.depthEpsilon; - const nearDepth = farDepth - 1 + this.depthRange; - this.context.depthRange.set([nearDepth, farDepth]); - } - - /** - * Transform a matrix to incorporate the *-translate and *-translate-anchor properties into it. - * @param inViewportPixelUnitsUnits True when the units accepted by the matrix are in viewport pixels instead of tile units. - * @returns {Float32Array} matrix - */ - translatePosMatrix(matrix: Float32Array, tile: Tile, translate: [number, number], translateAnchor: 'map' | 'viewport', inViewportPixelUnitsUnits?: boolean) { - if (!translate[0] && !translate[1]) return matrix; - - const angle = inViewportPixelUnitsUnits ? - (translateAnchor === 'map' ? this.transform.angle : 0) : - (translateAnchor === 'viewport' ? -this.transform.angle : 0); - - if (angle) { - const sinA = Math.sin(angle); - const cosA = Math.cos(angle); - translate = [ - translate[0] * cosA - translate[1] * sinA, - translate[0] * sinA + translate[1] * cosA - ]; - } - - const translation = [ - inViewportPixelUnitsUnits ? translate[0] : pixelsToTileUnits(tile, translate[0], this.transform.zoom), - inViewportPixelUnitsUnits ? translate[1] : pixelsToTileUnits(tile, translate[1], this.transform.zoom), - 0 - ]; - - const translatedMatrix = new Float32Array(16); - mat4.translate(translatedMatrix, matrix, translation); - return translatedMatrix; - } - - saveTileTexture(texture: Texture) { - const textures = this._tileTextures[texture.size[0]]; - if (!textures) { - this._tileTextures[texture.size[0]] = [texture]; - } else { - textures.push(texture); - } - } - - getTileTexture(size: number) { - const textures = this._tileTextures[size]; - return textures && textures.length > 0 ? textures.pop() : null; - } - - lineWidth(width: number) { - this.context.lineWidth.set(util.clamp(width, this.lineWidthRange[0], this.lineWidthRange[1])); - } - - showOverdrawInspector(enabled: boolean) { - if (!enabled && !this._showOverdrawInspector) return; - this._showOverdrawInspector = enabled; - - const context = this.context; - const gl = context.gl; - if (enabled) { - context.blendFunc.set([gl.CONSTANT_COLOR, gl.ONE]); - const numOverdrawSteps = 8; - const a = 1 / numOverdrawSteps; - context.blendColor.set([a, a, a, 0]); - context.clear({ color: [0, 0, 0, 1] }); - } else { - context.blendFunc.set([gl.ONE, gl.ONE_MINUS_SRC_ALPHA]); - } - } - - _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); - } - 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; - } -} - -module.exports = Painter; diff --git a/src/render/painter.js b/src/render/painter.js index 987e5170dc5..6b73e6eb0c3 100644 --- a/src/render/painter.js +++ b/src/render/painter.js @@ -16,6 +16,7 @@ const Program = require('./program'); const Context = require('../gl/context'); const RenderTexture = require('./render_texture'); const updateTileMasks = require('./tile_mask'); +const Color = require('../style-spec/util/color'); const draw = { symbol: require('./draw_symbol'), @@ -364,7 +365,7 @@ class Painter { } // Clear buffers in preparation for drawing to the main framebuffer - context.clear({ color: [0, 0, 0, 0], depth: 1 }); + context.clear({ color: Color.transparent, depth: 1 }); this.showOverdrawInspector(options.showOverdrawInspector); @@ -533,8 +534,8 @@ class Painter { context.blendFunc.set([gl.CONSTANT_COLOR, gl.ONE]); const numOverdrawSteps = 8; const a = 1 / numOverdrawSteps; - context.blendColor.set([a, a, a, 0]); - context.clear({ color: [0, 0, 0, 1] }); + context.blendColor.set(new Color(a, a, a, 0)); + context.clear({ color: Color.black }); } else { context.blendFunc.set([gl.ONE, gl.ONE_MINUS_SRC_ALPHA]); } diff --git a/yarn.lock b/yarn.lock index 2afc2196c93..f37e9f45407 100644 --- a/yarn.lock +++ b/yarn.lock @@ -194,7 +194,11 @@ version "3.0.0" resolved "https://registry.yarnpkg.com/@mapbox/whoots-js/-/whoots-js-3.0.0.tgz#c1de4293081424da3ac30c23afa850af1019bb54" -"@types/node@*", "@types/node@^6.0.46": +"@types/node@*": + version "8.0.34" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.34.tgz#55f801fa2ddb2a40dd6dfc15ecfe1dde9c129fe9" + +"@types/node@^6.0.46": version "6.0.88" resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.88.tgz#f618f11a944f6a18d92b5c472028728a3e3d4b66" @@ -296,10 +300,14 @@ acorn@^4.0.0, acorn@^4.0.3, acorn@^4.0.4: version "4.0.13" resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787" -acorn@^5.0.0, acorn@^5.0.1: +acorn@^5.0.0: version "5.1.2" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.1.2.tgz#911cb53e036807cf0fa778dc5d370fbd864246d7" +acorn@^5.0.1: + version "5.0.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.0.3.tgz#c460df08491463f028ccb82eab3730bf01087b3d" + add-stream@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/add-stream/-/add-stream-1.0.0.tgz#6a7990437ca736d5e1288db92bd3266d5f5cb2aa" @@ -439,7 +447,11 @@ arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" -arr-flatten@^1.0.1, arr-flatten@^1.1.0: +arr-flatten@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.0.3.tgz#a274ed85ac08849b6bd7847c4580745dc51adfb1" + +arr-flatten@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" @@ -658,31 +670,7 @@ babel-code-frame@^6.26.0: esutils "^2.0.2" js-tokens "^3.0.2" -babel-core@^6.0.14, babel-core@^6.25.0, babel-core@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.0.tgz#af32f78b31a6fcef119c87b0fd8d9753f03a0bb8" - dependencies: - babel-code-frame "^6.26.0" - babel-generator "^6.26.0" - babel-helpers "^6.24.1" - babel-messages "^6.23.0" - babel-register "^6.26.0" - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - convert-source-map "^1.5.0" - debug "^2.6.8" - json5 "^0.5.1" - lodash "^4.17.4" - minimatch "^3.0.4" - path-is-absolute "^1.0.1" - private "^0.1.7" - slash "^1.0.0" - source-map "^0.5.6" - -babel-core@^6.17.0: +babel-core@^6.0.14, babel-core@^6.17.0, babel-core@^6.24.1: version "6.25.0" resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.25.0.tgz#7dd42b0463c742e9d5296deb3ec67a9322dad729" dependencies: @@ -706,6 +694,30 @@ babel-core@^6.17.0: slash "^1.0.0" source-map "^0.5.0" +babel-core@^6.25.0, babel-core@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.0.tgz#af32f78b31a6fcef119c87b0fd8d9753f03a0bb8" + dependencies: + babel-code-frame "^6.26.0" + babel-generator "^6.26.0" + babel-helpers "^6.24.1" + babel-messages "^6.23.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + convert-source-map "^1.5.0" + debug "^2.6.8" + json5 "^0.5.1" + lodash "^4.17.4" + minimatch "^3.0.4" + path-is-absolute "^1.0.1" + private "^0.1.7" + slash "^1.0.0" + source-map "^0.5.6" + babel-eslint@^7.0.0: version "7.2.3" resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-7.2.3.tgz#b2fe2d80126470f5c19442dc757253a897710827" @@ -1019,7 +1031,7 @@ babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: dependencies: babel-runtime "^6.22.0" -babel-plugin-transform-es2015-block-scoping@^6.23.0, babel-plugin-transform-es2015-block-scoping@^6.24.1: +babel-plugin-transform-es2015-block-scoping@^6.23.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" dependencies: @@ -1029,6 +1041,16 @@ babel-plugin-transform-es2015-block-scoping@^6.23.0, babel-plugin-transform-es20 babel-types "^6.26.0" lodash "^4.17.4" +babel-plugin-transform-es2015-block-scoping@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.24.1.tgz#76c295dc3a4741b1665adfd3167215dcff32a576" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + lodash "^4.2.0" + babel-plugin-transform-es2015-classes@^6.23.0, babel-plugin-transform-es2015-classes@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" @@ -1091,7 +1113,7 @@ babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015 babel-runtime "^6.22.0" babel-template "^6.24.1" -babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: +babel-plugin-transform-es2015-modules-commonjs@^6.23.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz#0d8394029b7dc6abe1a97ef181e00758dd2e5d8a" dependencies: @@ -1100,6 +1122,15 @@ babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-e babel-template "^6.26.0" babel-types "^6.26.0" +babel-plugin-transform-es2015-modules-commonjs@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.24.1.tgz#d3e310b40ef664a36622200097c6d440298f2bfe" + dependencies: + babel-plugin-transform-strict-mode "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-types "^6.24.1" + babel-plugin-transform-es2015-modules-systemjs@^6.23.0, babel-plugin-transform-es2015-modules-systemjs@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" @@ -1243,12 +1274,18 @@ babel-plugin-transform-react-remove-prop-types@^0.4.9: version "0.4.9" resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.9.tgz#6805ef83d77bda94ded472ff2f2836bacd6ac44c" -babel-plugin-transform-regenerator@^6.22.0, babel-plugin-transform-regenerator@^6.24.1: +babel-plugin-transform-regenerator@^6.22.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" dependencies: regenerator-transform "^0.10.0" +babel-plugin-transform-regenerator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.24.1.tgz#b8da305ad43c3c99b4848e4fe4037b770d23c418" + dependencies: + regenerator-transform "0.9.11" + babel-plugin-transform-runtime@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.23.0.tgz#88490d446502ea9b8e7efb0fe09ec4d99479b1ee" @@ -1378,7 +1415,19 @@ babel-preset-stage-3@^6.24.1: babel-plugin-transform-exponentiation-operator "^6.24.1" babel-plugin-transform-object-rest-spread "^6.22.0" -babel-register@^6.24.1, babel-register@^6.26.0: +babel-register@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.24.1.tgz#7e10e13a2f71065bdfad5a1787ba45bca6ded75f" + dependencies: + babel-core "^6.24.1" + babel-runtime "^6.22.0" + core-js "^2.4.0" + home-or-tmp "^2.0.0" + lodash "^4.2.0" + mkdirp "^0.5.1" + source-map-support "^0.4.2" + +babel-register@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" dependencies: @@ -1397,20 +1446,20 @@ babel-runtime@6.11.6: core-js "^2.4.0" regenerator-runtime "^0.9.5" -babel-runtime@^6.18.0, babel-runtime@^6.2.0, babel-runtime@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" - dependencies: - core-js "^2.4.0" - regenerator-runtime "^0.11.0" - -babel-runtime@^6.22.0: +babel-runtime@^6.18.0, babel-runtime@^6.2.0, babel-runtime@^6.22.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.23.0.tgz#0a9489f144de70efb3ce4300accdb329e2fc543b" dependencies: core-js "^2.4.0" regenerator-runtime "^0.10.0" +babel-runtime@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.25.0, babel-template@^6.3.0: version "6.25.0" resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.25.0.tgz#665241166b7c2aa4c619d71e192969552b10c071" @@ -1459,7 +1508,7 @@ babel-traverse@^6.26.0: invariant "^2.2.2" lodash "^4.17.4" -babel-types@^6.16.0, babel-types@^6.18.0, babel-types@^6.23.0, babel-types@^6.24.1, babel-types@^6.25.0: +babel-types@^6.16.0, babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.23.0, babel-types@^6.24.1, babel-types@^6.25.0: version "6.25.0" resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.25.0.tgz#70afb248d5660e5d18f811d91c8303b54134a18e" dependencies: @@ -1468,7 +1517,7 @@ babel-types@^6.16.0, babel-types@^6.18.0, babel-types@^6.23.0, babel-types@^6.24 lodash "^4.2.0" to-fast-properties "^1.0.1" -babel-types@^6.19.0, babel-types@^6.26.0: +babel-types@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" dependencies: @@ -1605,10 +1654,14 @@ block-stream@*: dependencies: inherits "~2.0.0" -bluebird@^3.3.1, bluebird@^3.4.7: +bluebird@^3.3.1: version "3.5.0" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.0.tgz#791420d7f551eea2897453a8a77653f96606d67c" +bluebird@^3.4.7: + version "3.5.1" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" + bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: version "4.11.7" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.7.tgz#ddb048e50d9482790094c13eb3fcfc833ce7ab46" @@ -2072,7 +2125,15 @@ chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0: +chalk@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba" + dependencies: + ansi-styles "^3.1.0" + escape-string-regexp "^1.0.5" + supports-color "^4.0.0" + +chalk@^2.0.1, chalk@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.1.0.tgz#ac5becf14fa21b99c6c92ca7a7d7cfd5b17e743e" dependencies: @@ -2371,15 +2432,7 @@ concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" -concat-stream@^1.4.6, concat-stream@^1.5.0, concat-stream@~1.5.0, concat-stream@~1.5.1: - version "1.5.2" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.5.2.tgz#708978624d856af41a5a741defdd261da752c266" - dependencies: - inherits "~2.0.1" - readable-stream "~2.0.0" - typedarray "~0.0.5" - -concat-stream@^1.4.7, concat-stream@^1.6.0, concat-stream@~1.6.0: +concat-stream@^1.4.6, concat-stream@^1.4.7, concat-stream@^1.5.0, concat-stream@^1.6.0, concat-stream@~1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" dependencies: @@ -2395,6 +2448,14 @@ concat-stream@~1.5.0, concat-stream@~1.5.1: readable-stream "~2.0.0" typedarray "~0.0.5" +concat-stream@~1.5.0, concat-stream@~1.5.1: + version "1.5.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.5.2.tgz#708978624d856af41a5a741defdd261da752c266" + dependencies: + inherits "~2.0.1" + readable-stream "~2.0.0" + typedarray "~0.0.5" + concat-with-sourcemaps@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/concat-with-sourcemaps/-/concat-with-sourcemaps-1.0.4.tgz#f55b3be2aeb47601b10a2d5259ccfb70fd2f1dd6" @@ -2531,7 +2592,11 @@ core-js@^1.0.0: version "1.2.7" resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" -core-js@^2.0.0, core-js@^2.4.0, core-js@^2.5.0: +core-js@^2.0.0, core-js@^2.4.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e" + +core-js@^2.5.0: version "2.5.1" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.1.tgz#ae6874dc66937789b80754ff5428df66819ca50b" @@ -2640,7 +2705,7 @@ cryptiles@3.x.x: dependencies: boom "5.x.x" -crypto-browserify@^3.0.0, crypto-browserify@^3.11.0: +crypto-browserify@^3.0.0: version "3.11.0" resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.11.0.tgz#3652a0906ab9b2a7e0c3ce66a408e957a2485522" dependencies: @@ -2655,6 +2720,21 @@ crypto-browserify@^3.0.0, crypto-browserify@^3.11.0: public-encrypt "^4.0.0" randombytes "^2.0.0" +crypto-browserify@^3.11.0: + version "3.11.1" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.11.1.tgz#948945efc6757a400d6e5e5af47194d10064279f" + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + crypto-random-string@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" @@ -2788,12 +2868,18 @@ debug@2.6.4: dependencies: ms "0.7.3" -debug@2.6.8, debug@^2.1.1, debug@^2.1.3, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.3, debug@^2.6.8, debug@~2.6.7: +debug@2.6.8, debug@^2.1.1, debug@^2.1.3, debug@^2.2.0, debug@^2.6.0, debug@^2.6.3, debug@^2.6.8: version "2.6.8" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" dependencies: ms "2.0.0" +debug@^2.3.3, debug@~2.6.7: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + dependencies: + ms "2.0.0" + decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -3205,7 +3291,11 @@ ejs@^2.5.7: version "2.5.7" resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.5.7.tgz#cc872c168880ae3c7189762fd5ffc00896c9518a" -electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.24: +electron-to-chromium@^1.2.7: + version "1.3.15" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.15.tgz#08397934891cbcfaebbd18b82a95b5a481138369" + +electron-to-chromium@^1.3.24: version "1.3.25" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.25.tgz#453b21009836d0997d86035601ff6cae4791c460" @@ -3340,7 +3430,16 @@ error@^7.0.0: string-template "~0.2.1" xtend "~4.0.0" -es-abstract@^1.4.3, es-abstract@^1.5.0, es-abstract@^1.6.1, es-abstract@^1.7.0: +es-abstract@^1.4.3, es-abstract@^1.5.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.7.0.tgz#dfade774e01bfcd97f96180298c449c8623fb94c" + dependencies: + es-to-primitive "^1.1.1" + function-bind "^1.1.0" + is-callable "^1.1.3" + is-regex "^1.0.3" + +es-abstract@^1.6.1: version "1.9.0" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.9.0.tgz#690829a07cae36b222e7fd9b75c0d0573eb25227" dependencies: @@ -3350,6 +3449,16 @@ es-abstract@^1.4.3, es-abstract@^1.5.0, es-abstract@^1.6.1, es-abstract@^1.7.0: is-callable "^1.1.3" is-regex "^1.0.4" +es-abstract@^1.7.0: + version "1.8.2" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.8.2.tgz#25103263dc4decbda60e0c737ca32313518027ee" + dependencies: + es-to-primitive "^1.1.1" + function-bind "^1.1.1" + has "^1.0.1" + is-callable "^1.1.3" + is-regex "^1.0.4" + es-to-primitive@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d" @@ -3555,6 +3664,10 @@ esprima@^2.6.0, esprima@^2.7.1: version "2.7.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" +esprima@^3.1.1, esprima@~3.1.0: + version "3.1.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" + esprima@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" @@ -3567,10 +3680,6 @@ esprima@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.1.1.tgz#5b6f1547f4d102e670e140c509be6771d6aeb549" -esprima@~3.1.0: - version "3.1.3" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" - espurify@^1.3.0, espurify@^1.6.0: version "1.7.0" resolved "https://registry.yarnpkg.com/espurify/-/espurify-1.7.0.tgz#1c5cf6cbccc32e6f639380bd4f991fab9ba9d226" @@ -3814,7 +3923,7 @@ fbjs@^0.6.1: ua-parser-js "^0.7.9" whatwg-fetch "^0.9.0" -fbjs@^0.8.16, fbjs@^0.8.4: +fbjs@^0.8.16: version "0.8.16" resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db" dependencies: @@ -3826,6 +3935,30 @@ fbjs@^0.8.16, fbjs@^0.8.4: setimmediate "^1.0.5" ua-parser-js "^0.7.9" +fbjs@^0.8.4: + version "0.8.14" + resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.14.tgz#d1dbe2be254c35a91e09f31f9cd50a40b2a0ed1c" + dependencies: + core-js "^1.0.0" + isomorphic-fetch "^2.1.1" + loose-envify "^1.0.0" + object-assign "^4.1.0" + promise "^7.1.1" + setimmediate "^1.0.5" + ua-parser-js "^0.7.9" + +fbjs@^0.8.9: + version "0.8.15" + resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.15.tgz#4f0695fdfcc16c37c0b07facec8cb4c4091685b9" + dependencies: + core-js "^1.0.0" + isomorphic-fetch "^2.1.1" + loose-envify "^1.0.0" + object-assign "^4.1.0" + promise "^7.1.1" + setimmediate "^1.0.5" + ua-parser-js "^0.7.9" + fd@~0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/fd/-/fd-0.0.2.tgz#e0edb2bd7a88cc86dd9f16391cba832418fd87ee" @@ -4083,14 +4216,14 @@ fstream@^1.0.0, fstream@^1.0.10, fstream@^1.0.2: mkdirp ">=0.5 0" rimraf "2" -function-bind@^1.0.2, function-bind@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.0.tgz#16176714c801798e4e8f2cf7f7529467bb4a5771" - -function-bind@^1.1.1: +function-bind@^1.0.2, function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" +function-bind@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.0.tgz#16176714c801798e4e8f2cf7f7529467bb4a5771" + function-loop@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/function-loop/-/function-loop-1.0.1.tgz#8076bb305e8e6a3cceee2920765f330d190f340c" @@ -4252,13 +4385,13 @@ github-from-package@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" -github-slugger@1.2.0, github-slugger@^1.0.0: +github-slugger@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-1.2.0.tgz#8ada3286fd046d8951c3c952a8d7854cfd90fd9a" dependencies: emoji-regex ">=6.0.0 <=6.1.1" -github-slugger@^1.1.1: +github-slugger@^1.0.0, github-slugger@^1.1.1: version "1.1.3" resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-1.1.3.tgz#314a6e759a18c2b0cc5760d512ccbab549c549a7" dependencies: @@ -4453,7 +4586,17 @@ gulp-sourcemaps@1.6.0: through2 "^2.0.0" vinyl "^1.0.0" -handlebars@^4.0.2, handlebars@^4.0.3: +handlebars@^4.0.2: + version "4.0.11" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.11.tgz#630a35dfe0294bc281edae6ffc5d329fc7982dcc" + dependencies: + async "^1.4.0" + optimist "^0.6.1" + source-map "^0.4.4" + optionalDependencies: + uglify-js "^2.6" + +handlebars@^4.0.3: version "4.0.10" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.10.tgz#3d30c718b09a3d96f23ea4cc1f403c4d3ba9ff4f" dependencies: @@ -4863,10 +5006,14 @@ iconv-lite@0.4.13: version "0.4.13" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.13.tgz#1f88aba4ab0b1508e8312acc39345f36e992e2f2" -iconv-lite@^0.4.17, iconv-lite@^0.4.5, iconv-lite@~0.4.13: +iconv-lite@^0.4.17, iconv-lite@~0.4.13: version "0.4.18" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.18.tgz#23d8656b16aae6742ac29732ea8f0336a4789cf2" +iconv-lite@^0.4.5: + version "0.4.19" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" + ieee754@^1.1.4, ieee754@^1.1.6: version "1.1.8" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" @@ -4879,10 +5026,14 @@ ignore@^3.2.0, ignore@^3.3.3: version "3.3.3" resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.3.tgz#432352e57accd87ab3110e82d3fea0e47812156d" -immutable@3.8.1, immutable@^3.7.6: +immutable@3.8.1: version "3.8.1" resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.1.tgz#200807f11ab0f72710ea485542de088075f68cd2" +immutable@^3.7.6: + version "3.8.2" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.2.tgz#c2439951455bb39913daf281376f1530e104adf3" + import-lazy@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" @@ -5269,7 +5420,7 @@ is-redirect@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" -is-regex@^1.0.4: +is-regex@^1.0.3, is-regex@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" dependencies: @@ -5460,20 +5611,27 @@ js-tokens@^3.0.0, js-tokens@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" -js-yaml@3.6.1: +js-yaml@3.6.1, js-yaml@^3.3.1: version "3.6.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.6.1.tgz#6e5fe67d8b205ce4d22fad05b7781e8dadcc4b30" dependencies: argparse "^1.0.7" esprima "^2.6.0" -js-yaml@^3.10.0, js-yaml@^3.2.7, js-yaml@^3.3.1, js-yaml@^3.4.3, js-yaml@^3.4.6, js-yaml@^3.8.4: +js-yaml@^3.10.0, js-yaml@^3.4.6: version "3.10.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.10.0.tgz#2e78441646bd4682e963f22b6e92823c309c62dc" dependencies: argparse "^1.0.7" esprima "^4.0.0" +js-yaml@^3.2.7, js-yaml@^3.4.3, js-yaml@^3.8.4: + version "3.8.4" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.8.4.tgz#520b4564f86573ba96662af85a8cafa7b4b5a6f6" + dependencies: + argparse "^1.0.7" + esprima "^3.1.1" + jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" @@ -5662,7 +5820,11 @@ kind-of@^4.0.0: dependencies: is-buffer "^1.1.5" -kind-of@^5.0.0, kind-of@^5.0.2: +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + +kind-of@^5.0.2: version "5.0.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.0.2.tgz#f57bec933d9a2209ffa96c5c08343607b7035fda" @@ -6174,7 +6336,23 @@ mdast-util-inject@^1.1.0: dependencies: mdast-util-to-string "^1.0.0" -mdast-util-to-hast@^2.0.0, mdast-util-to-hast@^2.1.1, mdast-util-to-hast@^2.2.0: +mdast-util-to-hast@^2.0.0, mdast-util-to-hast@^2.2.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-2.5.0.tgz#f087844d255c7540f36906da30ba106c0ee5ee2f" + dependencies: + collapse-white-space "^1.0.0" + detab "^2.0.0" + mdast-util-definitions "^1.2.0" + mdurl "^1.0.1" + trim "0.0.1" + trim-lines "^1.0.0" + unist-builder "^1.0.1" + unist-util-generated "^1.1.0" + unist-util-position "^3.0.0" + unist-util-visit "^1.1.0" + xtend "^4.0.1" + +mdast-util-to-hast@^2.1.1: version "2.4.2" resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-2.4.2.tgz#f116e8bf3da772ba5a397a92dab090f5ba91caa0" dependencies: @@ -6206,6 +6384,10 @@ mdn-data@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-1.0.0.tgz#a69d9da76847b4d5834c1465ea25c0653a1fbf66" +mdurl@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" + mem@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" @@ -6301,13 +6483,13 @@ mime-db@~1.30.0: version "1.30.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01" -mime-types@^2.1.12, mime-types@~2.1.11, mime-types@~2.1.7: +mime-types@^2.1.12, mime-types@~2.1.7: version "2.1.15" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.15.tgz#a4ebf5064094569237b8cf70046776d09fc92aed" dependencies: mime-db "~1.27.0" -mime-types@~2.1.16, mime-types@~2.1.17: +mime-types@~2.1.11, mime-types@~2.1.16, mime-types@~2.1.17: version "2.1.17" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a" dependencies: @@ -6321,7 +6503,11 @@ mime@1.3.4: version "1.3.4" resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53" -"mime@>= 0.0.1", mime@^1.2.11, mime@^1.4.1: +"mime@>= 0.0.1": + version "2.0.3" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.0.3.tgz#4353337854747c48ea498330dc034f9f4bbbcc0b" + +mime@^1.2.11, mime@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" @@ -7445,7 +7631,7 @@ postcss-values-parser@^1.3.1: indexes-of "^1.0.1" uniq "^1.0.1" -postcss@^5.0.0, postcss@^5.0.14, postcss@^5.0.18, postcss@^5.0.20, postcss@^5.0.21, postcss@^5.0.4, postcss@^5.0.8, postcss@^5.2.13, postcss@^5.2.16, postcss@^5.2.4: +postcss@^5.0.0, postcss@^5.0.18, postcss@^5.0.20, postcss@^5.0.21, postcss@^5.0.4, postcss@^5.0.8, postcss@^5.2.13, postcss@^5.2.16, postcss@^5.2.4: version "5.2.17" resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.17.tgz#cf4f597b864d65c8a492b2eabe9d706c879c388b" dependencies: @@ -7454,6 +7640,15 @@ postcss@^5.0.0, postcss@^5.0.14, postcss@^5.0.18, postcss@^5.0.20, postcss@^5.0. source-map "^0.5.6" supports-color "^3.2.3" +postcss@^5.0.14: + version "5.2.18" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.18.tgz#badfa1497d46244f6390f58b319830d9107853c5" + dependencies: + chalk "^1.1.3" + js-base64 "^2.1.9" + source-map "^0.5.6" + supports-color "^3.2.3" + postcss@^6.0.0, postcss@^6.0.1, postcss@^6.0.12, postcss@^6.0.13: version "6.0.13" resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.13.tgz#b9ecab4ee00c89db3ec931145bd9590bbf3f125f" @@ -7537,7 +7732,14 @@ promise@^7.0.3, promise@^7.1.1: dependencies: asap "~2.0.3" -prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.6.0: +prop-types@^15.5.10: + version "15.5.10" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.5.10.tgz#2797dfc3126182e3a95e3dfbb2e893ddd7456154" + dependencies: + fbjs "^0.8.9" + loose-envify "^1.3.1" + +prop-types@^15.5.4, prop-types@^15.6.0: version "15.6.0" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856" dependencies: @@ -7617,7 +7819,11 @@ punycode@^1.2.4, punycode@^1.3.2, punycode@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" -q@^1.1.2, q@^1.4.1: +q@^1.1.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/q/-/q-1.5.0.tgz#dd01bac9d06d30e6f219aecb8253ee9ebdc308f1" + +q@^1.4.1: version "1.5.1" resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" @@ -7629,18 +7835,18 @@ qs@6.2.1: version "6.2.1" resolved "https://registry.yarnpkg.com/qs/-/qs-6.2.1.tgz#ce03c5ff0935bc1d9d69a9f14cbd18e568d67625" -"qs@>= 0.4.0", qs@~6.5.1: +"qs@>= 0.4.0", qs@^6.4.0, qs@~6.5.1: version "6.5.1" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" -qs@^6.4.0, qs@~6.4.0: - version "6.4.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" - qs@~6.3.0: version "6.3.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.3.2.tgz#e75bd5f6e268122a2a0e0bda630b2550c166502c" +qs@~6.4.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" + querystring-es3@^0.2.0, querystring-es3@~0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" @@ -7900,6 +8106,14 @@ regenerator-runtime@^0.9.5: version "0.9.6" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.9.6.tgz#d33eb95d0d2001a4be39659707c51b0cb71ce029" +regenerator-transform@0.9.11: + version "0.9.11" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.9.11.tgz#3a7d067520cb7b7176769eb5ff868691befe1283" + dependencies: + babel-runtime "^6.18.0" + babel-types "^6.19.0" + private "^0.1.6" + regenerator-transform@^0.10.0: version "0.10.1" resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" @@ -8131,7 +8345,7 @@ request-promise-native@^1.0.3: stealthy-require "^1.1.0" tough-cookie ">=2.3.3" -request@2, request@2.81.0, request@^2.79.0: +request@2, request@2.81.0, request@^2.79.0, request@^2.81.0: version "2.81.0" resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" dependencies: @@ -8183,7 +8397,7 @@ request@2.79.0: tunnel-agent "~0.4.1" uuid "^3.0.0" -"request@>= 2.44.0 < 3.0.0", request@^2.81.0, request@^2.83.0: +"request@>= 2.44.0 < 3.0.0", request@^2.83.0: version "2.83.0" resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356" dependencies: @@ -8366,10 +8580,14 @@ semver-diff@^2.0.0: dependencies: semver "^5.0.3" -"semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", semver@5.3.0, semver@^5.0.1, semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@~5.3.0: +"semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", semver@5.3.0, semver@^5.3.0, semver@~5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" +semver@^5.0.1, semver@^5.0.3, semver@^5.1.0: + version "5.4.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" + send@0.15.2: version "0.15.2" resolved "https://registry.yarnpkg.com/send/-/send-0.15.2.tgz#f91fab4403bcf87e716f70ceb5db2f578bdc17d6" @@ -8683,7 +8901,13 @@ source-map-resolve@^0.5.0: source-map-url "^0.4.0" urix "^0.1.0" -source-map-support@^0.4.15, source-map-support@^0.4.3: +source-map-support@^0.4.15: + version "0.4.18" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" + dependencies: + source-map "^0.5.6" + +source-map-support@^0.4.2, source-map-support@^0.4.3: version "0.4.15" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.15.tgz#03202df65c06d2bd8c7ec2362a193056fef8d3b1" dependencies: @@ -8699,14 +8923,14 @@ source-map-url@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" -source-map@0.5.x, source-map@^0.5.0, source-map@^0.5.1, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.0, source-map@~0.5.1, source-map@~0.5.3: +source-map@0.5.x, source-map@^0.5.1, source-map@~0.5.0: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + +"source-map@>= 0.1.2", source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1, source-map@~0.5.3: version "0.5.6" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" -"source-map@>= 0.1.2", source-map@^0.6.0, source-map@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - source-map@^0.1.34, source-map@~0.1.33: version "0.1.43" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" @@ -8719,6 +8943,10 @@ source-map@^0.4.2, source-map@^0.4.4: dependencies: amdefine ">=0.0.4" +source-map@^0.6.0, source-map@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + source-map@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d" @@ -9149,12 +9377,18 @@ supports-color@^3.1.2, supports-color@^3.2.3: dependencies: has-flag "^1.0.0" -supports-color@^4.0.0, supports-color@^4.1.0, supports-color@^4.2.1, supports-color@^4.4.0: +supports-color@^4.0.0, supports-color@^4.2.1, supports-color@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.4.0.tgz#883f7ddabc165142b2a61427f3352ded195d1a3e" dependencies: has-flag "^2.0.0" +supports-color@^4.1.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b" + dependencies: + has-flag "^2.0.0" + svg-tags@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/svg-tags/-/svg-tags-1.0.0.tgz#58f71cee3bd519b59d4b2a843b6c7de64ac04764" @@ -9588,10 +9822,14 @@ typedarray@^0.0.6, typedarray@~0.0.5: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" -ua-parser-js@0.7.12, ua-parser-js@^0.7.9: +ua-parser-js@0.7.12: version "0.7.12" resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.12.tgz#04c81a99bdd5dc52263ea29d24c6bf8d4818a4bb" +ua-parser-js@^0.7.9: + version "0.7.14" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.14.tgz#110d53fa4c3f326c121292bbeac904d2e03387ca" + uglify-es@^3.0.26: version "3.1.3" resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.1.3.tgz#a21eeb149cb120a1f8302563689e19496550780b" @@ -10025,10 +10263,14 @@ web-namespaces@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-1.1.1.tgz#742d9fff61ff84f4164f677244f42d29c10c451d" -webidl-conversions@^4.0.0, webidl-conversions@^4.0.1: +webidl-conversions@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.1.tgz#8015a17ab83e7e1b311638486ace81da6ce206a0" +webidl-conversions@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + webpack-chunk-hash@^0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/webpack-chunk-hash/-/webpack-chunk-hash-0.5.0.tgz#1dba38203d73c1e6ab069b6810a5a37402399dec" From b15cd5f31443045b93da81ce890156269034710e Mon Sep 17 00:00:00 2001 From: Lauren Budorick Date: Tue, 28 Nov 2017 13:22:01 -0800 Subject: [PATCH 3/9] Add equal method to Value to choose between object/deep equality on a case by case basis --- src/gl/context.js | 7 +------ src/gl/index_buffer.js | 7 +------ src/gl/state.js | 2 +- src/gl/value.js | 39 ++++++++++++++++++++++++++++++++++++++- 4 files changed, 41 insertions(+), 14 deletions(-) diff --git a/src/gl/context.js b/src/gl/context.js index 27940f14a5f..2afe6605a2c 100644 --- a/src/gl/context.js +++ b/src/gl/context.js @@ -51,10 +51,6 @@ type ClearArgs = { color?: Color, depth?: number, stencil?: number - // TODO previously painter had `clearDepth`, `clearColor`, `clearStencil` - // methods so that callers wouldn't need to know appropriate/default values - // for clearing...should we still provide some such help or no? painter now - // calls context.clear in several places and has to know appropriate values }; @@ -94,7 +90,6 @@ class Context { constructor(gl: WebGLRenderingContext) { this.gl = gl; this.extVertexArrayObject = this.gl.getExtension('OES_vertex_array_object'); - // TODO is there any reason to wait to try to initialize this? this.clearColor = new State(new ClearColor(this)); this.clearDepth = new State(new ClearDepth(this)); @@ -133,7 +128,7 @@ class Context { return new VertexBuffer(this, array, dynamicDraw); } - clear({color, depth, stencil}: ClearArgs) { + clear({color, depth}: ClearArgs) { const gl = this.gl; let mask = 0; diff --git a/src/gl/index_buffer.js b/src/gl/index_buffer.js index f8ace9a20ee..76b3ec26e23 100644 --- a/src/gl/index_buffer.js +++ b/src/gl/index_buffer.js @@ -38,12 +38,7 @@ class IndexBuffer { } bind() { - const gl = this.context.gl; - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.buffer); - // this.context.bindElementBuffer.set(this.buffer); - // TODO not sure why this doesn't work, but using bindElementBuffer throws: - // [.Offscreen-For-WebGL-0x7fbaf382a800]GL ERROR :GL_INVALID_OPERATION : - // glDrawElements: bound to target 0x8893 : no buffer + this.context.bindElementBuffer.set(this.buffer); } updateData(array: StructArray) { diff --git a/src/gl/state.js b/src/gl/state.js index 7cb7817cd25..db998992bb8 100644 --- a/src/gl/state.js +++ b/src/gl/state.js @@ -17,7 +17,7 @@ class State { } set(t: T) { - if (this.current !== t) { + if (!this.value.constructor.equal(this.current, t)) { this.current = t; this.value.set(t); } diff --git a/src/gl/value.js b/src/gl/value.js index 230b2831b09..606c058a0e4 100644 --- a/src/gl/value.js +++ b/src/gl/value.js @@ -1,5 +1,8 @@ // @flow +const Color = require('../style-spec/util/color'); +const util = require('../util/util'); + import type Context from './context'; import type { BlendFuncType, @@ -11,12 +14,13 @@ import type { TextureUnitType, ViewportType, } from './types'; -const Color = require('../style-spec/util/color'); + export interface Value { context: Context; static default(context?: Context): T; set(value: T): void; + static equal(a: T, b: T): boolean; } class ContextValue { @@ -25,6 +29,10 @@ class ContextValue { constructor(context: Context) { this.context = context; } + + static equal(a, b): boolean { + return util.deepEqual(a, b); + } } class ClearColor extends ContextValue implements Value { @@ -182,6 +190,10 @@ class Program extends ContextValue implements Value { set(v: ?WebGLProgram): void { this.context.gl.useProgram(v); } + + static equal(a: ?WebGLProgram, b: ?WebGLProgram): boolean { + return a === b; + } } class LineWidth extends ContextValue implements Value { @@ -220,6 +232,10 @@ class BindFramebuffer extends ContextValue implements Value { const gl = this.context.gl; gl.bindFramebuffer(gl.FRAMEBUFFER, v); } + + static equal(a: ?WebGLFramebuffer, b: ?WebGLFramebuffer): boolean { + return a === b; + } } class BindRenderbuffer extends ContextValue implements Value { @@ -229,6 +245,10 @@ class BindRenderbuffer extends ContextValue implements Value const gl = this.context.gl; gl.bindRenderbuffer(gl.RENDERBUFFER, v); } + + static equal(a: ?WebGLRenderbuffer, b: ?WebGLRenderbuffer): boolean { + return a === b; + } } class BindTexture extends ContextValue implements Value { @@ -238,6 +258,10 @@ class BindTexture extends ContextValue implements Value { const gl = this.context.gl; gl.bindTexture(gl.TEXTURE_2D, v); } + + static equal(a: ?WebGLTexture, b: ?WebGLTexture): boolean { + return a === b; + } } class BindVertexBuffer extends ContextValue implements Value { @@ -247,6 +271,10 @@ class BindVertexBuffer extends ContextValue implements Value { const gl = this.context.gl; gl.bindBuffer(gl.ARRAY_BUFFER, v); } + + static equal(a: ?WebGLBuffer, b: ?WebGLBuffer): boolean { + return a === b; + } } class BindElementBuffer extends ContextValue implements Value { @@ -256,6 +284,11 @@ class BindElementBuffer extends ContextValue implements Value { const gl = this.context.gl; gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, v); } + + static equal(): boolean { + // Always rebind: + return false; + } } class BindVertexArrayOES extends ContextValue implements Value { @@ -267,6 +300,10 @@ class BindVertexArrayOES extends ContextValue implements Value { context.extVertexArrayObject.bindVertexArrayOES(v); } } + + static equal(a, b): boolean { + return a === b; + } } class PixelStoreUnpack extends ContextValue implements Value { From 8dfe08b8a816e93340f8b387bdb89b98869a8754 Mon Sep 17 00:00:00 2001 From: Lauren Budorick Date: Tue, 28 Nov 2017 14:40:05 -0800 Subject: [PATCH 4/9] Update unit tests to use Context class --- test/unit/data/vertex_buffer.test.js | 5 +++-- test/unit/source/tile.test.js | 9 +++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/test/unit/data/vertex_buffer.test.js b/test/unit/data/vertex_buffer.test.js index 3980970e34d..f4419f0ffbf 100644 --- a/test/unit/data/vertex_buffer.test.js +++ b/test/unit/data/vertex_buffer.test.js @@ -3,6 +3,7 @@ const test = require('mapbox-gl-js-test').test; const VertexBuffer = require('../../../src/gl/vertex_buffer'); const StructArrayType = require('../../../src/util/struct_array'); +const Context = require('../../../src/gl/context'); test('VertexBuffer', (t) => { @@ -16,13 +17,13 @@ test('VertexBuffer', (t) => { t.test('constructs itself', (t) => { - const gl = require('gl')(10, 10); + const context = new Context(require('gl')(10, 10)); const array = new TestArray(); array.emplaceBack(1, 1, 1); array.emplaceBack(1, 1, 1); array.emplaceBack(1, 1, 1); - const buffer = new VertexBuffer(gl, array); + const buffer = new VertexBuffer(context, array); t.deepEqual(buffer.attributes, [ { diff --git a/test/unit/source/tile.test.js b/test/unit/source/tile.test.js index f74e86acace..07a7242612e 100644 --- a/test/unit/source/tile.test.js +++ b/test/unit/source/tile.test.js @@ -12,6 +12,7 @@ const CollisionIndex = require('../../../src/symbol/collision_index'); const Transform = require('../../../src/geo/transform'); const CollisionBoxArray = require('../../../src/symbol/collision_box'); const util = require('../../../src/util/util'); +const Context = require('../../../src/gl/context'); const {serialize} = require('../../../src/util/web_worker_transfer'); test('querySourceFeatures', (t) => { @@ -137,17 +138,17 @@ test('Tile#setMask', (t) => { t.test('simple mask', (t)=>{ const tile = new Tile(0, 0, 0); - const gl = require('gl')(10, 10); - tile.setMask([new TileCoord(1, 0, 0).id, new TileCoord(1, 1, 1).id], gl); + const context = new Context(require('gl')(10, 10)); + tile.setMask([new TileCoord(1, 0, 0).id, new TileCoord(1, 1, 1).id], context); t.deepEqual(tile.mask, [new TileCoord(1, 0, 0).id, new TileCoord(1, 1, 1).id]); t.end(); }); t.test('complex mask', (t) => { const tile = new Tile(0, 0, 0); - const gl = require('gl')(10, 10); + const context = new Context(require('gl')(10, 10)); tile.setMask([new TileCoord(1, 0, 1).id, new TileCoord(1, 1, 0).id, new TileCoord(2, 2, 3).id, - new TileCoord(2, 3, 2).id, new TileCoord(3, 6, 7).id, new TileCoord(3, 7, 6).id], gl); + new TileCoord(2, 3, 2).id, new TileCoord(3, 6, 7).id, new TileCoord(3, 7, 6).id], context); t.deepEqual(tile.mask, [new TileCoord(1, 0, 1).id, new TileCoord(1, 1, 0).id, new TileCoord(2, 2, 3).id, new TileCoord(2, 3, 2).id, new TileCoord(3, 6, 7).id, new TileCoord(3, 7, 6).id]); t.end(); From 5a314017205eefc3be55614882c65c1b5842dc69 Mon Sep 17 00:00:00 2001 From: Lauren Budorick Date: Tue, 28 Nov 2017 14:47:47 -0800 Subject: [PATCH 5/9] lint --- src/gl/index_buffer.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gl/index_buffer.js b/src/gl/index_buffer.js index 76b3ec26e23..42fc7e1fede 100644 --- a/src/gl/index_buffer.js +++ b/src/gl/index_buffer.js @@ -3,7 +3,6 @@ const assert = require('assert'); import type {StructArray} from '../util/struct_array'; import type {TriangleIndexArray, LineIndexArray} from '../data/index_array_type'; -import type {SerializedStructArray} from '../util/struct_array'; import type Context from '../gl/context'; From b6adef902294f1ff0a1f4650756a83f82f24d544 Mon Sep 17 00:00:00 2001 From: Lauren Budorick Date: Tue, 28 Nov 2017 17:45:16 -0800 Subject: [PATCH 6/9] Add state/value unit test, fix render test suite --- src/gl/state.js | 8 -- src/gl/value.js | 2 - src/render/draw_heatmap.js | 2 +- test/suite_implementation.js | 4 +- test/unit/gl/state.test.js | 176 +++++++++++++++++++++++++++++++++++ 5 files changed, 179 insertions(+), 13 deletions(-) create mode 100644 test/unit/gl/state.test.js diff --git a/src/gl/state.js b/src/gl/state.js index db998992bb8..cd591991c79 100644 --- a/src/gl/state.js +++ b/src/gl/state.js @@ -22,14 +22,6 @@ class State { this.value.set(t); } } - - setDirty(): void { - this.dirty = true; - } - - isDirty(): boolean { - return this.dirty; - } } module.exports = State; diff --git a/src/gl/value.js b/src/gl/value.js index 606c058a0e4..14878802f2f 100644 --- a/src/gl/value.js +++ b/src/gl/value.js @@ -340,7 +340,6 @@ module.exports = { Blend, BlendFunc, BlendColor, - Program, LineWidth, ActiveTextureUnit, @@ -351,7 +350,6 @@ module.exports = { BindVertexBuffer, BindElementBuffer, BindVertexArrayOES, - // VertexAttribute, PixelStoreUnpack, PixelStoreUnpackPremultiplyAlpha, }; diff --git a/src/render/draw_heatmap.js b/src/render/draw_heatmap.js index e6c26336df7..19838c52a83 100644 --- a/src/render/draw_heatmap.js +++ b/src/render/draw_heatmap.js @@ -127,7 +127,7 @@ function renderTextureToMap(context, painter, layer) { } colorRampTexture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE); - context.blendFunc.set([gl.ONE, gl.ONE_MINUS_SRC_ALPHA]); + context.blendFunc.set(painter._showOverdrawInspector ? [gl.CONSTANT_COLOR, gl.ONE] : [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]); const program = painter.useProgram('heatmapTexture'); diff --git a/test/suite_implementation.js b/test/suite_implementation.js index 5e3f42d6b66..1ca5a62dbe5 100644 --- a/test/suite_implementation.js +++ b/test/suite_implementation.js @@ -52,7 +52,7 @@ module.exports = function(style, options, _callback) { if (options.debug) map.showTileBoundaries = true; if (options.showOverdrawInspector) map.showOverdrawInspector = true; - const gl = map.painter.gl; + const gl = map.painter.context.gl; map.once('load', () => { if (options.collisionDebug) { @@ -90,7 +90,7 @@ module.exports = function(style, options, _callback) { map.remove(); gl.getExtension('STACKGL_destroy_context').destroy(); - delete map.painter.gl; + delete map.painter.context.gl; callback(null, data, results.map((feature) => { feature = feature.toJSON(); diff --git a/test/unit/gl/state.test.js b/test/unit/gl/state.test.js new file mode 100644 index 00000000000..d9969d6b038 --- /dev/null +++ b/test/unit/gl/state.test.js @@ -0,0 +1,176 @@ +'use strict'; + +const test = require('mapbox-gl-js-test').test; +const State = require('../../../src/gl/state'); +const { + ClearColor, + ClearDepth, + ClearStencil, + ColorMask, + DepthMask, + StencilMask, + StencilFunc, + StencilOp, + StencilTest, + DepthRange, + DepthTest, + DepthFunc, + Blend, + BlendFunc, + BlendColor, + Program, + LineWidth, + ActiveTextureUnit, + Viewport, + BindFramebuffer, + BindRenderbuffer, + BindTexture, + BindVertexBuffer, + BindElementBuffer, + BindVertexArrayOES, + PixelStoreUnpack, + PixelStoreUnpackPremultiplyAlpha +} = require('../../../src/gl/value'); +const Context = require('../../../src/gl/context'); +const Color = require('../../../src/style-spec/util/color'); + +const context = new Context(require('gl')(10, 10)); + +function ValueTest(Constructor, options, t) { + t.test('#constructor', (t) => { + const v = new State(new Constructor(context)); + t.ok(v); + const currentV = v.get(); + const defaultV = v.value.constructor.default(context); + t.notEqual(typeof currentV, 'undefined'); + t.notEqual(typeof defaultV, 'undefined'); + t.ok(v.value.constructor.equal(currentV, defaultV) || + // special case for BindElementBuffer, where equal always returns false + currentV === defaultV); + t.end(); + }); + + t.test('#set', (t) => { + const v = new State(new Constructor(context)); + v.set(options.setValue); + t.ok(v.value.constructor.equal(v.get(), options.setValue) || + // special case for BindElementBuffer, where equal always returns false + v.get() === options.setValue); + t.end(); + }); + + t.end(); +} + +test('ClearColor', ValueTest.bind(ValueTest, ClearColor, { + setValue: new Color(1, 1, 0, 1) +})); + + +test('ClearDepth', ValueTest.bind(ValueTest, ClearDepth, { + setValue: 0.5 +})); + +test('ClearStencil', ValueTest.bind(ValueTest, ClearStencil, { + setValue: 0.5 +})); + +test('ColorMask', ValueTest.bind(ValueTest, ColorMask, { + setValue: [false, false, true, true] +})); + +test('DepthMask', ValueTest.bind(ValueTest, DepthMask, { + setValue: false +})); + +test('StencilMask', ValueTest.bind(ValueTest, StencilMask, { + setValue: [0x00, 4] +})); + +test('StencilFunc', ValueTest.bind(ValueTest, StencilFunc, { + setValue: { + func: context.gl.LEQUAL, + ref: 1, + mask: 0xFF + } +})); + +test('StencilOp', ValueTest.bind(ValueTest, StencilOp, { + setValue: [context.gl.KEEP, context.gl.REPLACE, context.gl.REPLACE] +})); + +test('StencilTest', ValueTest.bind(ValueTest, StencilTest, { + setValue: true +})); + +test('DepthRange', ValueTest.bind(ValueTest, DepthRange, { + setValue: [0, 0.1] +})); + +test('DepthTest', ValueTest.bind(ValueTest, DepthTest, { + setValue: true +})); + +test('DepthFunc', ValueTest.bind(ValueTest, DepthFunc, { + setValue: context.gl.EQUAL +})); + +test('Blend', ValueTest.bind(ValueTest, Blend, { + setValue: false +})); + +test('BlendFunc', ValueTest.bind(ValueTest, BlendFunc, { + setValue: [context.gl.SRC_ALPHA, context.gl.SRC_ALPHA] +})); + +test('BlendColor', ValueTest.bind(ValueTest, BlendColor, { + setValue: Color.white +})); + +test('Program', ValueTest.bind(ValueTest, Program, { + setValue: context.gl.createProgram() +})); + +test('LineWidth', ValueTest.bind(ValueTest, LineWidth, { + setValue: 0.5 +})); + +test('ActiveTextureUnit', ValueTest.bind(ValueTest, ActiveTextureUnit, { + setValue: context.gl.TEXTURE1 +})); + +test('Viewport', ValueTest.bind(ValueTest, Viewport, { + setValue: [0, 0, 1, 1] +})); + +test('BindFramebuffer', ValueTest.bind(ValueTest, BindFramebuffer, { + setValue: context.gl.createFramebuffer() +})); + +test('BindRenderbuffer', ValueTest.bind(ValueTest, BindRenderbuffer, { + setValue: context.gl.createRenderbuffer() +})); + +test('BindTexture', ValueTest.bind(ValueTest, BindTexture, { + setValue: context.gl.createTexture() +})); + +test('BindVertexBuffer', ValueTest.bind(ValueTest, BindVertexBuffer, { + setValue: context.gl.createBuffer() +})); + +test('BindElementBuffer', ValueTest.bind(ValueTest, BindElementBuffer, { + setValue: context.gl.createBuffer() +})); + +test('BindVertexArrayOES', ValueTest.bind(ValueTest, BindVertexArrayOES, { + setValue: context.extVertexArrayObject +})); + +test('PixelStoreUnpack', ValueTest.bind(ValueTest, PixelStoreUnpack, { + setValue: 8 +})); + +test('PixelStoreUnpackPremultiplyAlpha', ValueTest.bind(ValueTest, PixelStoreUnpackPremultiplyAlpha, { + setValue: true +})); From 1eb9dbf7f1fc0c431bdea1cc315e7244586663a2 Mon Sep 17 00:00:00 2001 From: Lauren Budorick Date: Tue, 28 Nov 2017 18:36:16 -0800 Subject: [PATCH 7/9] Fix GL setting errors --- src/gl/value.js | 2 +- src/render/painter.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gl/value.js b/src/gl/value.js index 14878802f2f..fb15aad3843 100644 --- a/src/gl/value.js +++ b/src/gl/value.js @@ -153,7 +153,7 @@ class DepthFunc extends ContextValue implements Value { } class Blend extends ContextValue implements Value { - static default() { return true; } + static default() { return false; } set(v: boolean): void { const gl = this.context.gl; diff --git a/src/render/painter.js b/src/render/painter.js index 6b73e6eb0c3..a8c9f5c65da 100644 --- a/src/render/painter.js +++ b/src/render/painter.js @@ -145,7 +145,7 @@ class Painter { // We are blending the new pixels *behind* the existing pixels. That way we can // draw front-to-back and use then stencil buffer to cull opaque pixels early. context.blend.set(true); - context.blendFunc.set([gl.LINES, gl.ONE_MINUS_SRC_ALPHA]); + context.blendFunc.set([gl.ONE, gl.ONE_MINUS_SRC_ALPHA]); context.stencilTest.set(true); From f2fe9deebb58332e1a6eb8f61b5083b3388ae497 Mon Sep 17 00:00:00 2001 From: Lauren Budorick Date: Wed, 29 Nov 2017 15:49:40 -0800 Subject: [PATCH 8/9] Don't use context.bindTexture for now --- src/render/draw_fill_extrusion.js | 4 ++-- src/render/draw_heatmap.js | 6 +++--- src/render/draw_raster.js | 8 +++++++- src/render/line_atlas.js | 4 ++-- src/render/painter.js | 7 ++++--- src/render/render_texture.js | 4 ++-- src/render/texture.js | 4 ++-- 7 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/render/draw_fill_extrusion.js b/src/render/draw_fill_extrusion.js index eb9e545bb62..34e195669a7 100644 --- a/src/render/draw_fill_extrusion.js +++ b/src/render/draw_fill_extrusion.js @@ -48,8 +48,8 @@ function drawExtrusionTexture(painter, layer) { context.stencilTest.set(false); context.depthTest.set(false); - context.activeTexture.set(gl.TEXTURE0); - context.bindTexture.set(renderedTexture.texture); + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, renderedTexture.texture); gl.uniform1f(program.uniforms.u_opacity, layer.paint.get('fill-extrusion-opacity')); gl.uniform1i(program.uniforms.u_image, 0); diff --git a/src/render/draw_heatmap.js b/src/render/draw_heatmap.js index 19838c52a83..7f073e38ed8 100644 --- a/src/render/draw_heatmap.js +++ b/src/render/draw_heatmap.js @@ -84,7 +84,7 @@ function renderToTexture(context, painter, layer) { if (!texture) { texture = layer.heatmapTexture = gl.createTexture(); - context.bindTexture.set(texture); + gl.bindTexture(gl.TEXTURE_2D, texture); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); @@ -95,7 +95,7 @@ function renderToTexture(context, painter, layer) { bindTextureFramebuffer(context, painter, texture, fbo); } else { - context.bindTexture.set(texture); + gl.bindTexture(gl.TEXTURE_2D, texture); context.bindFramebuffer.set(fbo); } } @@ -134,7 +134,7 @@ function renderTextureToMap(context, painter, layer) { context.viewport.set([0, 0, painter.width, painter.height]); context.activeTexture.set(gl.TEXTURE0); - context.bindTexture.set(layer.heatmapTexture); + gl.bindTexture(gl.TEXTURE_2D, layer.heatmapTexture); const opacity = layer.paint.get('heatmap-opacity'); gl.uniform1f(program.uniforms.u_opacity, opacity); diff --git a/src/render/draw_raster.js b/src/render/draw_raster.js index e4eb164fac0..cb40d344e9c 100644 --- a/src/render/draw_raster.js +++ b/src/render/draw_raster.js @@ -23,7 +23,7 @@ function drawRaster(painter: Painter, sourceCache: SourceCache, layer: RasterSty context.depthTest.set(true); context.depthMask.set(layer.paint.get('raster-opacity') === 1); // Change depth function to prevent double drawing in areas where tiles overlap. - gl.depthFunc(gl.LESS); + context.depthFunc.set(gl.LESS); context.stencilTest.set(false); @@ -56,17 +56,23 @@ function drawRaster(painter: Painter, sourceCache: SourceCache, layer: RasterSty let parentScaleBy, parentTL; context.activeTexture.set(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, tile.texture); tile.texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE, gl.LINEAR_MIPMAP_NEAREST); + gl.bindTexture(gl.TEXTURE_2D, tile.texture); context.activeTexture.set(gl.TEXTURE1); if (parentTile) { + gl.bindTexture(gl.TEXTURE_2D, parentTile.texture); parentTile.texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE, gl.LINEAR_MIPMAP_NEAREST); + gl.bindTexture(gl.TEXTURE_2D, parentTile.texture); parentScaleBy = Math.pow(2, parentTile.coord.z - tile.coord.z); parentTL = [tile.coord.x * parentScaleBy % 1, tile.coord.y * parentScaleBy % 1]; } else { + gl.bindTexture(gl.TEXTURE_2D, tile.texture); tile.texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE, gl.LINEAR_MIPMAP_NEAREST); + gl.bindTexture(gl.TEXTURE_2D, tile.texture); } // cross-fade parameters diff --git a/src/render/line_atlas.js b/src/render/line_atlas.js index 0feaa6bd88b..2d41b9b2c39 100644 --- a/src/render/line_atlas.js +++ b/src/render/line_atlas.js @@ -134,7 +134,7 @@ class LineAtlas { const gl = context.gl; if (!this.texture) { this.texture = gl.createTexture(); - context.bindTexture.set(this.texture); + gl.bindTexture(gl.TEXTURE_2D, this.texture); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); @@ -142,7 +142,7 @@ class LineAtlas { gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, this.data); } else { - context.bindTexture.set(this.texture); + gl.bindTexture(gl.TEXTURE_2D, this.texture); if (this.dirty) { this.dirty = false; diff --git a/src/render/painter.js b/src/render/painter.js index a8c9f5c65da..d48eab10085 100644 --- a/src/render/painter.js +++ b/src/render/painter.js @@ -261,7 +261,7 @@ class Painter { for (const coord of coords) { const id = this._tileClippingMaskIDs[coord.id] = idNext++; - gl.stencilFunc(gl.ALWAYS, id, 0xFF); + context.stencilFunc.set({ func: gl.ALWAYS, ref: id, mask: 0xFF }); const program = this.useProgram('fill', programConfiguration); gl.uniformMatrix4fv(program.uniforms.u_matrix, false, coord.posMatrix); @@ -278,8 +278,9 @@ class Painter { } enableTileClippingMask(coord: TileCoord) { - const gl = this.context.gl; - gl.stencilFunc(gl.EQUAL, this._tileClippingMaskIDs[coord.id], 0xFF); + const context = this.context; + const gl = context.gl; + context.stencilFunc.set({ func: gl.EQUAL, ref: this._tileClippingMaskIDs[coord.id], mask: 0xFF }); } render(style: Style, options: PainterOptions) { diff --git a/src/render/render_texture.js b/src/render/render_texture.js index 552ab5c7e32..db7ec875bcd 100644 --- a/src/render/render_texture.js +++ b/src/render/render_texture.js @@ -19,14 +19,14 @@ class RenderTexture { const gl = context.gl; const texture = this.texture = gl.createTexture(); - context.bindTexture.set(texture); + gl.bindTexture(gl.TEXTURE_2D, texture); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, painter.width, painter.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - context.bindTexture.set(null); + gl.bindTexture(gl.TEXTURE_2D, null); const fbo = this.fbo = gl.createFramebuffer(); context.bindFramebuffer.set(fbo); diff --git a/src/render/texture.js b/src/render/texture.js index 17b727be68e..ce79625ce80 100644 --- a/src/render/texture.js +++ b/src/render/texture.js @@ -48,7 +48,7 @@ class Texture { const {context} = this; const {gl} = context; - context.bindTexture.set(this.texture); + gl.bindTexture(gl.TEXTURE_2D, this.texture); context.pixelStoreUnpack.set(1); if (this.format === gl.RGBA) { @@ -65,7 +65,7 @@ class Texture { bind(filter: TextureFilter, wrap: TextureWrap, minFilter: ?TextureFilter) { const {context} = this; const {gl} = context; - context.bindTexture.set(this.texture); + gl.bindTexture(gl.TEXTURE_2D, this.texture); if (filter !== this.filter) { gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filter); From 77d8d3b389052bb700eca57b68d823ae95fd271f Mon Sep 17 00:00:00 2001 From: Lauren Budorick Date: Wed, 29 Nov 2017 18:20:50 -0800 Subject: [PATCH 9/9] Remove extra bindTexture calls added accidentally in debugging --- src/render/draw_raster.js | 6 ------ src/render/draw_symbol.js | 6 +----- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/src/render/draw_raster.js b/src/render/draw_raster.js index cb40d344e9c..bc4fb239f74 100644 --- a/src/render/draw_raster.js +++ b/src/render/draw_raster.js @@ -56,23 +56,17 @@ function drawRaster(painter: Painter, sourceCache: SourceCache, layer: RasterSty let parentScaleBy, parentTL; context.activeTexture.set(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, tile.texture); tile.texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE, gl.LINEAR_MIPMAP_NEAREST); - gl.bindTexture(gl.TEXTURE_2D, tile.texture); context.activeTexture.set(gl.TEXTURE1); if (parentTile) { - gl.bindTexture(gl.TEXTURE_2D, parentTile.texture); parentTile.texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE, gl.LINEAR_MIPMAP_NEAREST); - gl.bindTexture(gl.TEXTURE_2D, parentTile.texture); parentScaleBy = Math.pow(2, parentTile.coord.z - tile.coord.z); parentTL = [tile.coord.x * parentScaleBy % 1, tile.coord.y * parentScaleBy % 1]; } else { - gl.bindTexture(gl.TEXTURE_2D, tile.texture); tile.texture.bind(gl.LINEAR, gl.CLAMP_TO_EDGE, gl.LINEAR_MIPMAP_NEAREST); - gl.bindTexture(gl.TEXTURE_2D, tile.texture); } // cross-fade parameters diff --git a/src/render/draw_symbol.js b/src/render/draw_symbol.js index 4e4899376d5..2d3e3289382 100644 --- a/src/render/draw_symbol.js +++ b/src/render/draw_symbol.js @@ -70,11 +70,7 @@ function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate const depthOn = pitchWithMap; - if (depthOn) { - context.depthTest.set(true); - } else { - context.depthTest.set(false); - } + context.depthTest.set(depthOn); let program;