Skip to content

Commit

Permalink
avoid redundant dasharray/pattern state change in draw_line
Browse files Browse the repository at this point in the history
  • Loading branch information
mourner committed Oct 30, 2016
1 parent af1020e commit cdd27c0
Showing 1 changed file with 26 additions and 33 deletions.
59 changes: 26 additions & 33 deletions js/render/draw_line.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ module.exports = function drawLine(painter, sourceCache, layer, coords) {
layer.paint['line-dasharray'] ? 'lineSDF' :
layer.paint['line-pattern'] ? 'linePattern' : 'line';

let prevTileZoom;
for (let k = 0; k < coords.length; k++) {
const tile = sourceCache.getTile(coords[k]);
const bucket = tile.getBucket(layer);
Expand All @@ -37,28 +38,45 @@ module.exports = function drawLine(painter, sourceCache, layer, coords) {
const prevProgram = painter.currentProgram;
const program = painter.useProgram(programId, layerData.programConfiguration);
const programChanged = k === 0 || program !== prevProgram;
const tileRatioChanged = prevTileZoom !== tile.coord.z;

if (programChanged) {
layerData.programConfiguration.setUniforms(painter.gl, program, layer, {zoom: painter.transform.zoom});
}
drawLineTile(program, painter, tile, bucket.buffers, layer, coords[k], layerData, programChanged);
drawLineTile(program, painter, tile, bucket.buffers, layer, coords[k], layerData, programChanged, tileRatioChanged);
prevTileZoom = tile.coord.z;
}
};

function drawLineTile(program, painter, tile, buffers, layer, coord, layerData, programChanged) {
function drawLineTile(program, painter, tile, buffers, layer, coord, layerData, programChanged, tileRatioChanged) {
const gl = painter.gl;
const dasharray = layer.paint['line-dasharray'];
const image = layer.paint['line-pattern'];

let posA, posB, imagePosA, imagePosB;

if (dasharray) {
posA = painter.lineAtlas.getDash(dasharray.from, layer.layout['line-cap'] === 'round');
posB = painter.lineAtlas.getDash(dasharray.to, layer.layout['line-cap'] === 'round');
if (programChanged || tileRatioChanged) {
const tileRatio = 1 / pixelsToTileUnits(tile, 1, painter.transform.tileZoom);

} else if (image) {
imagePosA = painter.spriteAtlas.getPosition(image.from, true);
imagePosB = painter.spriteAtlas.getPosition(image.to, true);
if (dasharray) {
posA = painter.lineAtlas.getDash(dasharray.from, layer.layout['line-cap'] === 'round');
posB = painter.lineAtlas.getDash(dasharray.to, layer.layout['line-cap'] === 'round');

const widthA = posA.width * dasharray.fromScale;
const widthB = posB.width * dasharray.toScale;

gl.uniform2f(program.u_patternscale_a, tileRatio / widthA, -posA.height / 2);
gl.uniform2f(program.u_patternscale_b, tileRatio / widthB, -posB.height / 2);
gl.uniform1f(program.u_sdfgamma, painter.lineAtlas.width / (Math.min(widthA, widthB) * 256 * browser.devicePixelRatio) / 2);

} else if (image) {
imagePosA = painter.spriteAtlas.getPosition(image.from, true);
imagePosB = painter.spriteAtlas.getPosition(image.to, true);
if (!imagePosA || !imagePosB) return;

gl.uniform2f(program.u_pattern_size_a, imagePosA.size[0] * image.fromScale / tileRatio, imagePosB.size[1]);
gl.uniform2f(program.u_pattern_size_b, imagePosB.size[0] * image.toScale / tileRatio, imagePosB.size[1]);
}
}

if (programChanged) {
Expand All @@ -76,8 +94,6 @@ function drawLineTile(program, painter, tile, buffers, layer, coord, layerData,
gl.uniform1f(program.u_mix, dasharray.t);

} else if (image) {
if (!imagePosA || !imagePosB) return;

gl.uniform1i(program.u_image, 0);
gl.activeTexture(gl.TEXTURE0);
painter.spriteAtlas.bind(gl, true);
Expand Down Expand Up @@ -105,32 +121,9 @@ function drawLineTile(program, painter, tile, buffers, layer, coord, layerData,

painter.enableTileClippingMask(coord);

// set uniforms that are different for each tile
const posMatrix = painter.translatePosMatrix(coord.posMatrix, tile, layer.paint['line-translate'], layer.paint['line-translate-anchor']);
gl.uniformMatrix4fv(program.u_matrix, false, posMatrix);

if (dasharray) {
const widthA = posA.width * dasharray.fromScale;
const widthB = posB.width * dasharray.toScale;
const scaleA = [1 / pixelsToTileUnits(tile, widthA, painter.transform.tileZoom), -posA.height / 2];
const scaleB = [1 / pixelsToTileUnits(tile, widthB, painter.transform.tileZoom), -posB.height / 2];
const gamma = painter.lineAtlas.width / (Math.min(widthA, widthB) * 256 * browser.devicePixelRatio) / 2;

gl.uniform2fv(program.u_patternscale_a, scaleA);
gl.uniform2fv(program.u_patternscale_b, scaleB);
gl.uniform1f(program.u_sdfgamma, gamma);

} else if (image) {
gl.uniform2fv(program.u_pattern_size_a, [
pixelsToTileUnits(tile, imagePosA.size[0] * image.fromScale, painter.transform.tileZoom),
imagePosB.size[1]
]);
gl.uniform2fv(program.u_pattern_size_b, [
pixelsToTileUnits(tile, imagePosB.size[0] * image.toScale, painter.transform.tileZoom),
imagePosB.size[1]
]);
}

gl.uniform1f(program.u_ratio, 1 / pixelsToTileUnits(tile, 1, painter.transform.zoom));

for (const segment of buffers.segments) {
Expand Down

0 comments on commit cdd27c0

Please sign in to comment.