Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Introduce ColorMode, StencilMode, DepthMode abstractions #5826

Merged
merged 9 commits into from
Dec 13, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions src/gl/color_mode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// @flow
const Color = require('../style-spec/util/color');

import type {BlendFuncType, ColorMaskType} from './types';

const ZERO = 0x0000;
const ONE = 0x0001;
const ONE_MINUS_SRC_ALPHA = 0x0303;

class ColorMode {
blendFunction: BlendFuncType;
blendColor: Color;
mask: ColorMaskType;

constructor(blendFunction: BlendFuncType, blendColor: Color, mask: ColorMaskType) {
this.blendFunction = blendFunction;
this.blendColor = blendColor;
this.mask = mask;
}

static Replace: BlendFuncType;

static disabled(): ColorMode {
return new ColorMode(ColorMode.Replace, Color.transparent, [false, false, false, false]);
}

static unblended(): ColorMode {
return new ColorMode(ColorMode.Replace, Color.transparent, [true, true, true, true]);
}

static alphaBlended(): ColorMode {
return new ColorMode([ONE, ONE_MINUS_SRC_ALPHA], Color.transparent, [true, true, true, true]);
}
}

ColorMode.Replace = [ONE, ZERO];

module.exports = ColorMode;
44 changes: 44 additions & 0 deletions src/gl/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ const IndexBuffer = require('./index_buffer');
const VertexBuffer = require('./vertex_buffer');
const Framebuffer = require('./framebuffer');
const State = require('./state');
const DepthMode = require('./depth_mode');
const StencilMode = require('./stencil_mode');
const ColorMode = require('./color_mode');
const util = require('../util/util');
const {
ClearColor,
ClearDepth,
Expand Down Expand Up @@ -59,6 +63,7 @@ class Context {
gl: WebGLRenderingContext;
extVertexArrayObject: any;
currentNumAttributes: ?number;
lineWidthRange: [number, number];

clearColor: State<Color>;
clearDepth: State<number>;
Expand Down Expand Up @@ -95,6 +100,7 @@ class Context {
constructor(gl: WebGLRenderingContext) {
this.gl = gl;
this.extVertexArrayObject = this.gl.getExtension('OES_vertex_array_object');
this.lineWidthRange = gl.getParameter(gl.ALIASED_LINE_WIDTH_RANGE);

this.clearColor = new State(new ClearColor(this));
this.clearDepth = new State(new ClearDepth(this));
Expand Down Expand Up @@ -188,6 +194,44 @@ class Context {

gl.clear(mask);
}

setDepthMode(depthMode: DepthMode) {
if (depthMode.func === this.gl.ALWAYS && !depthMode.mask) {
this.depthTest.set(false);
} else {
this.depthTest.set(true);
this.depthFunc.set(depthMode.func);
this.depthMask.set(depthMode.mask);
this.depthRange.set(depthMode.range);
}
}

setStencilMode(stencilMode: StencilMode) {
if (stencilMode.func === this.gl.ALWAYS && !stencilMode.mask) {
this.stencilTest.set(false);
} else {
this.stencilTest.set(true);
this.stencilMask.set(stencilMode.mask);
this.stencilOp.set([stencilMode.fail, stencilMode.depthFail, stencilMode.pass]);
this.stencilFunc.set({
func: stencilMode.test.func,
ref: stencilMode.ref,
mask: stencilMode.test.mask
});
}
}

setColorMode(colorMode: ColorMode) {
if (util.deepEqual(colorMode.blendFunction, ColorMode.Replace)) {
this.blend.set(false);
} else {
this.blend.set(true);
this.blendFunc.set(colorMode.blendFunction);
this.blendColor.set(colorMode.blendColor);
}

this.colorMask.set(colorMode.mask);
}
}

module.exports = Context;
29 changes: 29 additions & 0 deletions src/gl/depth_mode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// @flow
import type { DepthFuncType, DepthMaskType, DepthRangeType } from './types';

const ALWAYS = 0x0207;

class DepthMode {
func: DepthFuncType;
mask: DepthMaskType;
range: DepthRangeType;

// DepthMask enums
static ReadOnly: boolean;
static ReadWrite: boolean;

constructor(depthFunc: DepthFuncType, depthMask: DepthMaskType, depthRange: DepthRangeType) {
this.func = depthFunc;
this.mask = depthMask;
this.range = depthRange;
}

static disabled() {
return new DepthMode(ALWAYS, DepthMode.ReadOnly, [0, 1]);
}
}

DepthMode.ReadOnly = false;
DepthMode.ReadWrite = true;

module.exports = DepthMode;
30 changes: 30 additions & 0 deletions src/gl/stencil_mode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// @flow
import type { StencilOpConstant, StencilTest } from './types';

const ALWAYS = 0x0207;
const KEEP = 0x1E00;

class StencilMode {
test: StencilTest;
ref: number;
mask: number;
fail: StencilOpConstant;
depthFail: StencilOpConstant;
pass: StencilOpConstant;

constructor(test: StencilTest, ref: number, mask: number, fail: StencilOpConstant,
depthFail: StencilOpConstant, pass: StencilOpConstant) {
this.test = test;
this.ref = ref;
this.mask = mask;
this.fail = fail;
this.depthFail = depthFail;
this.pass = pass;
}

static disabled() {
return new StencilMode({ func: ALWAYS, mask: 0 }, 0, 0, KEEP, KEEP, KEEP);
}
}

module.exports = StencilMode;
22 changes: 17 additions & 5 deletions src/gl/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ export type BlendFuncType = [BlendFuncConstant, BlendFuncConstant];

export type ColorMaskType = [boolean, boolean, boolean, boolean];

export type DepthRangeType = [number, number];

export type CompareFuncType =
| $PropertyType<WebGLRenderingContext, 'NEVER'>
| $PropertyType<WebGLRenderingContext, 'LESS'>
Expand All @@ -33,15 +31,19 @@ export type CompareFuncType =
| $PropertyType<WebGLRenderingContext, 'GEQUAL'>
| $PropertyType<WebGLRenderingContext, 'ALWAYS'>;

export type DepthMaskType = boolean;

export type DepthRangeType = [number, number];

export type DepthFuncType = CompareFuncType;

export type StencilFuncType = {
func: CompareFuncType,
ref: number,
mask: number
};

export type DepthFuncType = CompareFuncType;

type StencilOpConstant =
export type StencilOpConstant =
| $PropertyType<WebGLRenderingContext, 'KEEP'>
| $PropertyType<WebGLRenderingContext, 'ZERO'>
| $PropertyType<WebGLRenderingContext, 'REPLACE'>
Expand All @@ -56,3 +58,13 @@ export type StencilOpType = [StencilOpConstant, StencilOpConstant, StencilOpCons
export type TextureUnitType = number;

export type ViewportType = [number, number, number, number];

export type StencilTest =
| { func: $PropertyType<WebGLRenderingContext, 'NEVER'>, mask: 0 }
| { func: $PropertyType<WebGLRenderingContext, 'LESS'>, mask: number }
| { func: $PropertyType<WebGLRenderingContext, 'EQUAL'>, mask: number }
| { func: $PropertyType<WebGLRenderingContext, 'LEQUAL'>, mask: number }
| { func: $PropertyType<WebGLRenderingContext, 'GREATER'>, mask: number }
| { func: $PropertyType<WebGLRenderingContext, 'NOTEQUAL'>, mask: number }
| { func: $PropertyType<WebGLRenderingContext, 'GEQUAL'>, mask: number }
| { func: $PropertyType<WebGLRenderingContext, 'ALWAYS'>, mask: 0 };
8 changes: 5 additions & 3 deletions src/gl/value.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type {
BlendFuncType,
ColorMaskType,
DepthRangeType,
DepthMaskType,
StencilFuncType,
StencilOpType,
DepthFuncType,
Expand Down Expand Up @@ -66,10 +67,10 @@ class ColorMask extends ContextValue implements Value<ColorMaskType> {
}
}

class DepthMask extends ContextValue implements Value<boolean> {
class DepthMask extends ContextValue implements Value<DepthMaskType> {
static default() { return true; }

set(v: boolean): void {
set(v: DepthMaskType): void {
this.context.gl.depthMask(v);
}
}
Expand Down Expand Up @@ -199,7 +200,8 @@ class LineWidth extends ContextValue implements Value<number> {
static default() { return 1; }

set(v: number): void {
this.context.gl.lineWidth(v);
const range = this.context.lineWidthRange;
this.context.gl.lineWidth(util.clamp(v, range[0], range[1]));
}
}

Expand Down
8 changes: 5 additions & 3 deletions src/render/draw_background.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ const pattern = require('./pattern');
const {ProgramConfiguration} = require('../data/program_configuration');
const {PossiblyEvaluated, PossiblyEvaluatedPropertyValue} = require('../style/properties');
const fillLayerPaintProperties = require('../style/style_layer/fill_style_layer_properties').paint;
const StencilMode = require('../gl/stencil_mode');
const DepthMode = require('../gl/depth_mode');

import type Painter from './painter';
import type SourceCache from '../source/source_cache';
Expand All @@ -27,9 +29,9 @@ function drawBackground(painter: Painter, sourceCache: SourceCache, layer: Backg
const pass = (!image && color.a === 1 && opacity === 1) ? 'opaque' : 'translucent';
if (painter.renderPass !== pass) return;

context.stencilTest.set(false);
context.depthMask.set(pass === 'opaque');
painter.setDepthSublayer(0);
context.setStencilMode(StencilMode.disabled());
context.setDepthMode(painter.depthModeForSublayer(0, pass === 'opaque' ? DepthMode.ReadWrite : DepthMode.ReadOnly));
context.setColorMode(painter.colorModeForRenderPass());

const properties = new PossiblyEvaluated(fillLayerPaintProperties);

Expand Down
9 changes: 5 additions & 4 deletions src/render/draw_circle.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// @flow

const pixelsToTileUnits = require('../source/pixels_to_tile_units');
const StencilMode = require('../gl/stencil_mode');
const DepthMode = require('../gl/depth_mode');

import type Painter from './painter';
import type SourceCache from '../source/source_cache';
Expand All @@ -24,12 +26,11 @@ function drawCircles(painter: Painter, sourceCache: SourceCache, layer: CircleSt
const context = painter.context;
const gl = context.gl;

painter.setDepthSublayer(0);
context.depthMask.set(false);

context.setDepthMode(painter.depthModeForSublayer(0, DepthMode.ReadOnly));
// Allow circles to be drawn across boundaries, so that
// large circles are not clipped to tiles
context.stencilTest.set(false);
context.setStencilMode(StencilMode.disabled());
context.setColorMode(painter.colorModeForRenderPass());

for (let i = 0; i < coords.length; i++) {
const coord = coords[i];
Expand Down
10 changes: 9 additions & 1 deletion src/render/draw_collision_debug.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,20 @@ import type StyleLayer from '../style/style_layer';
import type {OverscaledTileID} from '../source/tile_id';
import type SymbolBucket from '../data/bucket/symbol_bucket';
const pixelsToTileUnits = require('../source/pixels_to_tile_units');
const DepthMode = require('../gl/depth_mode');
const StencilMode = require('../gl/stencil_mode');

module.exports = drawCollisionDebug;

function drawCollisionDebugGeometry(painter: Painter, sourceCache: SourceCache, layer: StyleLayer, coords: Array<OverscaledTileID>, drawCircles: boolean) {
const context = painter.context;
const gl = context.gl;
const program = drawCircles ? painter.useProgram('collisionCircle') : painter.useProgram('collisionBox');

context.setDepthMode(DepthMode.disabled());
context.setStencilMode(StencilMode.disabled());
context.setColorMode(painter.colorModeForRenderPass());

for (let i = 0; i < coords.length; i++) {
const coord = coords[i];
const tile = sourceCache.getTile(coord);
Expand All @@ -21,10 +28,11 @@ function drawCollisionDebugGeometry(painter: Painter, sourceCache: SourceCache,
const buffers = drawCircles ? bucket.collisionCircle : bucket.collisionBox;
if (!buffers) continue;


gl.uniformMatrix4fv(program.uniforms.u_matrix, false, coord.posMatrix);

if (!drawCircles) {
painter.lineWidth(1);
context.lineWidth.set(1);
}

gl.uniform1f(program.uniforms.u_camera_to_center_distance, painter.transform.cameraToCenterDistance);
Expand Down
9 changes: 7 additions & 2 deletions src/render/draw_debug.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ const mat4 = require('@mapbox/gl-matrix').mat4;
const EXTENT = require('../data/extent');
const VertexArrayObject = require('./vertex_array_object');
const PosArray = require('../data/pos_array');
const DepthMode = require('../gl/depth_mode');
const StencilMode = require('../gl/stencil_mode');

import type Painter from './painter';
import type SourceCache from '../source/source_cache';
Expand All @@ -22,12 +24,15 @@ function drawDebugTile(painter, sourceCache, coord) {
const context = painter.context;
const gl = context.gl;

context.stencilTest.set(false);
painter.lineWidth(1 * browser.devicePixelRatio);
context.lineWidth.set(1 * browser.devicePixelRatio);

const posMatrix = coord.posMatrix;
const program = painter.useProgram('debug');

context.setDepthMode(DepthMode.disabled());
context.setStencilMode(StencilMode.disabled());
context.setColorMode(painter.colorModeForRenderPass());

gl.uniformMatrix4fv(program.uniforms.u_matrix, false, posMatrix);
gl.uniform4f(program.uniforms.u_color, 1, 0, 0, 1);
painter.debugVAO.bind(context, program, painter.debugBuffer);
Expand Down
Loading