Skip to content

Commit

Permalink
* Don't mutate state within pattern uniform functions; consolidate pr…
Browse files Browse the repository at this point in the history
…epare and setTile

* Address review comments: eliminate _set from Uniform interface, clarify drawFillTiles fn signature
  • Loading branch information
Lauren Budorick committed Feb 27, 2018
1 parent a9558b2 commit e8fb56e
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 67 deletions.
5 changes: 5 additions & 0 deletions src/render/draw_background.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ function drawBackground(painter: Painter, sourceCache: SourceCache, layer: Backg

const tileIDs = transform.coveringTiles({tileSize});

if (image) {
context.activeTexture.set(gl.TEXTURE0);
painter.imageManager.bind(painter.context);
}

for (const tileID of tileIDs) {
const matrix = painter.transform.calculatePosMatrix(tileID.toUnwrapped());

Expand Down
15 changes: 10 additions & 5 deletions src/render/draw_fill.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ function drawFill(painter: Painter, sourceCache: SourceCache, layer: FillStyleLa
if (painter.renderPass === pass) {
const depthMode = painter.depthModeForSublayer(
1, painter.renderPass === 'opaque' ? DepthMode.ReadWrite : DepthMode.ReadOnly);
drawFillTiles(painter, sourceCache, layer, coords, depthMode, colorMode, true);
drawFillTiles(painter, sourceCache, layer, coords, depthMode, colorMode, false);
}

// Draw stroke
Expand All @@ -53,26 +53,31 @@ function drawFill(painter: Painter, sourceCache: SourceCache, layer: FillStyleLa
// the (non-antialiased) fill.
const depthMode = painter.depthModeForSublayer(
layer.getPaintProperty('fill-outline-color') ? 2 : 0, DepthMode.ReadOnly);
drawFillTiles(painter, sourceCache, layer, coords, depthMode, colorMode, false);
drawFillTiles(painter, sourceCache, layer, coords, depthMode, colorMode, true);
}
}

function drawFillTiles(painter, sourceCache, layer, coords, depthMode, colorMode, fillTiles) {
function drawFillTiles(painter, sourceCache, layer, coords, depthMode, colorMode, isOutline) {
const gl = painter.context.gl;

const image = layer.paint.get('fill-pattern');
if (painter.isPatternMissing(image)) return;

let drawMode, programName, uniformValues, indexBuffer, segments;

if (fillTiles) {
if (!isOutline) {
programName = image ? 'fillPattern' : 'fill';
drawMode = gl.TRIANGLES;
} else {
programName = image && !layer.getPaintProperty('fill-outline-color') ? 'fillOutlinePattern' : 'fillOutline';
drawMode = gl.LINES;
}

if (image) {
painter.context.activeTexture.set(gl.TEXTURE0);
painter.imageManager.bind(painter.context);
}

for (const coord of coords) {
const tile = sourceCache.getTile(coord);
const bucket: ?FillBucket = (tile.getBucket(layer): any);
Expand All @@ -84,7 +89,7 @@ function drawFillTiles(painter, sourceCache, layer, coords, depthMode, colorMode
const tileMatrix = painter.translatePosMatrix(coord.posMatrix, tile,
layer.paint.get('fill-translate'), layer.paint.get('fill-translate-anchor'));

if (fillTiles) {
if (!isOutline) {
indexBuffer = bucket.indexBuffer;
segments = bucket.segments;
uniformValues = image ?
Expand Down
57 changes: 31 additions & 26 deletions src/render/draw_fill_extrusion.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,12 @@ function draw(painter: Painter, source: SourceCache, layer: FillExtrusionStyleLa
if (painter.renderPass === 'offscreen') {
drawToExtrusionFramebuffer(painter, layer);

for (const coord of coords) {
const tile = source.getTile(coord);
const bucket: ?FillExtrusionBucket = (tile.getBucket(layer): any);
if (!bucket) continue;
const depthMode = new DepthMode(painter.context.gl.LEQUAL, DepthMode.ReadWrite, [0, 1]),
stencilMode = StencilMode.disabled,
colorMode = painter.colorModeForRenderPass();

const depthMode = new DepthMode(painter.context.gl.LEQUAL, DepthMode.ReadWrite, [0, 1]),
stencilMode = StencilMode.disabled,
colorMode = painter.colorModeForRenderPass();
drawExtrusionTiles(painter, source, layer, coords, depthMode, stencilMode, colorMode);

drawExtrusion(painter, source, layer, tile, coord, bucket, depthMode, stencilMode, colorMode);
}
} else if (painter.renderPass === 'translucent') {
drawExtrusionTexture(painter, layer);
}
Expand Down Expand Up @@ -89,29 +84,39 @@ function drawExtrusionTexture(painter, layer) {
painter.viewportSegments, layer.paint, painter.transform.zoom);
}

function drawExtrusion(painter, source, layer, tile, coord, bucket, depthMode, stencilMode, colorMode) {
function drawExtrusionTiles(painter, source, layer, coords, depthMode, stencilMode, colorMode) {
const context = painter.context;
const gl = context.gl;

const programConfiguration = bucket.programConfigurations.get(layer.id);

const image = layer.paint.get('fill-extrusion-pattern');
if (image && painter.isPatternMissing(image)) return;
if (image) {
if (painter.isPatternMissing(image)) return;

context.activeTexture.set(gl.TEXTURE0);
painter.imageManager.bind(context);
}

const program = painter.useProgram(image ? 'fillExtrusionPattern' : 'fillExtrusion', programConfiguration);
for (const coord of coords) {
const tile = source.getTile(coord);
const bucket: ?FillExtrusionBucket = (tile.getBucket(layer): any);
if (!bucket) continue;

const matrix = painter.translatePosMatrix(
coord.posMatrix,
tile,
layer.paint.get('fill-extrusion-translate'),
layer.paint.get('fill-extrusion-translate-anchor'));
const programConfiguration = bucket.programConfigurations.get(layer.id);
const program = painter.useProgram(image ? 'fillExtrusionPattern' : 'fillExtrusion', programConfiguration);

const uniformValues = image ?
fillExtrusionPatternUniformValues(matrix, painter, coord, image, tile) :
fillExtrusionUniformValues(matrix, painter);
const matrix = painter.translatePosMatrix(
coord.posMatrix,
tile,
layer.paint.get('fill-extrusion-translate'),
layer.paint.get('fill-extrusion-translate-anchor'));

program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode,
uniformValues, layer.id, bucket.layoutVertexBuffer, bucket.indexBuffer,
bucket.segments, layer.paint, painter.transform.zoom,
programConfiguration);
const uniformValues = image ?
fillExtrusionPatternUniformValues(matrix, painter, coord, image, tile) :
fillExtrusionUniformValues(matrix, painter);

program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode,
uniformValues, layer.id, bucket.layoutVertexBuffer, bucket.indexBuffer,
bucket.segments, layer.paint, painter.transform.zoom,
programConfiguration);
}
}
6 changes: 2 additions & 4 deletions src/render/program/background_program.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
// @flow

const {patternUniforms} = require('./pattern');
const {patternUniforms, patternUniformValues} = require('./pattern');
const {
Uniform1f,
Uniform4fv,
UniformMatrix4fv,
Uniforms
} = require('../uniform_binding');
const pattern = require('./pattern');
const util = require('../../util/util');

import type Painter from '../painter';
Expand Down Expand Up @@ -52,8 +51,7 @@ function backgroundPatternUniformValues(
image: CrossFaded<string>,
tile: {tileID: OverscaledTileID, tileSize: number}
): UniformValues {
return util.extend(pattern.prepare(image, painter),
pattern.setTile(tile, painter),
return util.extend(patternUniformValues(image, painter, tile),
{
'u_matrix': matrix,
'u_opacity': opacity
Expand Down
6 changes: 2 additions & 4 deletions src/render/program/fill_extrusion_program.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// @flow

const {patternUniforms} = require('./pattern');
const {patternUniforms, patternUniformValues} = require('./pattern');
const {
Uniform1i,
Uniform1f,
Expand All @@ -14,7 +14,6 @@ const glMatrix = require('@mapbox/gl-matrix');
const mat3 = glMatrix.mat3;
const vec3 = glMatrix.vec3;
const mat4 = glMatrix.mat4;
const pattern = require('./pattern');
const util = require('../../util/util');

import type Context from '../../gl/context';
Expand Down Expand Up @@ -81,8 +80,7 @@ function fillExtrusionPatternUniformValues(
tile: {tileID: OverscaledTileID, tileSize: number}
): UniformValues {
return util.extend(fillExtrusionUniformValues(matrix, painter),
pattern.prepare(image, painter),
pattern.setTile(tile, painter),
patternUniformValues(image, painter, tile),
{
'u_height_factor': -Math.pow(2, coord.overscaledZ) / tile.tileSize / 8
});
Expand Down
6 changes: 2 additions & 4 deletions src/render/program/fill_program.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
// @flow

const {patternUniforms} = require('./pattern');
const {patternUniforms, patternUniformValues} = require('./pattern');
const {
Uniform2fv,
UniformMatrix4fv,
Uniforms
} = require('../uniform_binding');
const pattern = require('./pattern');
const util = require('../../util/util');

import type Painter from '../painter';
Expand Down Expand Up @@ -51,8 +50,7 @@ function fillPatternUniformValues(
tile: {tileID: OverscaledTileID, tileSize: number}
): UniformValues {
return util.extend(fillUniformValues(matrix),
pattern.prepare(image, painter),
pattern.setTile(tile, painter));
patternUniformValues(image, painter, tile));
}

function fillOutlineUniformValues(
Expand Down
33 changes: 10 additions & 23 deletions src/render/program/pattern.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,19 @@ function patternUniforms(context: Context): Uniforms {
});
}

function prepare(image: CrossFaded<string>, painter: Painter): UniformValues {
const context = painter.context;
const gl = context.gl;

function patternUniformValues(image: CrossFaded<string>, painter: Painter,
tile: {tileID: OverscaledTileID, tileSize: number}
): UniformValues {
const imagePosA = painter.imageManager.getPattern(image.from);
const imagePosB = painter.imageManager.getPattern(image.to);
assert(imagePosA && imagePosB);
const {width, height} = painter.imageManager.getPixelSize();

context.activeTexture.set(gl.TEXTURE0);
painter.imageManager.bind(painter.context);
const numTiles = Math.pow(2, tile.tileID.overscaledZ);
const tileSizeAtNearestZoom = tile.tileSize * Math.pow(2, painter.transform.tileZoom) / numTiles;

const pixelX = tileSizeAtNearestZoom * (tile.tileID.canonical.x + tile.tileID.wrap * numTiles);
const pixelY = tileSizeAtNearestZoom * tile.tileID.canonical.y;

return {
'u_image': 0,
Expand All @@ -57,27 +59,12 @@ function prepare(image: CrossFaded<string>, painter: Painter): UniformValues {
'u_pattern_size_a': (imagePosA: any).displaySize,
'u_pattern_size_b': (imagePosB: any).displaySize,
'u_scale_a': image.fromScale,
'u_scale_b': image.toScale
};
}

function setTile(
tile: {tileID: OverscaledTileID, tileSize: number},
painter: Painter
): UniformValues {
const numTiles = Math.pow(2, tile.tileID.overscaledZ);
const tileSizeAtNearestZoom = tile.tileSize * Math.pow(2, painter.transform.tileZoom) / numTiles;

const pixelX = tileSizeAtNearestZoom * (tile.tileID.canonical.x + tile.tileID.wrap * numTiles);
const pixelY = tileSizeAtNearestZoom * tile.tileID.canonical.y;

return {
'u_scale_b': image.toScale,
'u_tile_units_to_pixels': 1 / pixelsToTileUnits(tile, 1, painter.transform.tileZoom),
// split the pixel coord into two pairs of 16 bit numbers. The glsl spec only guarantees 16 bits of precision.
'u_pixel_coord_upper': [pixelX >> 16, pixelY >> 16],
'u_pixel_coord_lower': [pixelX & 0xFFFF, pixelY & 0xFFFF]
};
}


module.exports = { patternUniforms, prepare, setTile };
module.exports = { patternUniforms, patternUniformValues };
1 change: 0 additions & 1 deletion src/render/uniform_binding.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import type Context from '../gl/context';
export interface UniformInterface<T> {
context: Context;
set(location: WebGLUniformLocation, value: T): void;
_set(location: WebGLUniformLocation, value: T): void;
}

export type UniformValues = {[string]: number | Array<number> | Float32Array};
Expand Down

0 comments on commit e8fb56e

Please sign in to comment.