Skip to content

Commit

Permalink
use object instead of array for tile masks
Browse files Browse the repository at this point in the history
  • Loading branch information
Molly Lloyd committed Sep 20, 2017
1 parent 173ed49 commit 69a347b
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 57 deletions.
11 changes: 7 additions & 4 deletions src/render/tile_mask.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ const TileCoord = require('../source/tile_coord');

import type Tile from './../source/tile';

export type Mask = {
[number]: boolean
};

// Updates the TileMasks for all renderable tiles. A TileMask describes all regions
// within that tile that are *not* covered by other renderable tiles.
Expand Down Expand Up @@ -51,7 +54,7 @@ import type Tile from './../source/tile';
// │ │ │
// └─────────────────┴─────────────────┘
//
// Only other renterable tiles that are *children* of the tile we are generating the mask for will
// Only other renderable tiles that are *children* of the tile we are generating the mask for will
// be considered. For example, adding TileID 4/8/13 to renderableTiles won't affect the TileMask for
// 2/1/3, since it is not a descendant of it.

Expand All @@ -60,7 +63,7 @@ module.exports = function(renderableTiles: Array<Tile>, gl: WebGLRenderingContex
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++) {
const mask = [];
const mask = {};
const tile = sortedRenderables[i];
const childArray = sortedRenderables.slice(i + 1);
// Try to add all remaining ids as children. We sorted the tile list
Expand All @@ -73,7 +76,7 @@ module.exports = function(renderableTiles: Array<Tile>, gl: WebGLRenderingContex
}
};

function computeTileMasks(rootTile: TileCoord, ref: TileCoord, childArray: Array<Tile>, lowerBound: TileCoord, mask: Array<number>) {
function computeTileMasks(rootTile: TileCoord, ref: TileCoord, childArray: Array<Tile>, lowerBound: TileCoord, mask: Mask) {
// If the reference or any of its children is found in the list, we need to recurse.
for (let i = 0; i < childArray.length; i++) {
const childTile = childArray[i];
Expand All @@ -97,6 +100,6 @@ function computeTileMasks(rootTile: TileCoord, ref: TileCoord, childArray: Array
// elements are always relative (see below for explanation).
const diffZ = ref.z - rootTile.z;
const maskTileId = new TileCoord(diffZ, ref.x - (rootTile.x << diffZ), ref.y - (rootTile.y << diffZ)).id;
if (mask.indexOf(maskTileId) < 0) mask.push(maskTileId);
mask[maskTileId] = mask[maskTileId] || true;
}

18 changes: 10 additions & 8 deletions src/source/tile.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import type {Bucket} from '../data/bucket';
import type StyleLayer from '../style/style_layer';
import type {WorkerTileResult} from './worker_source';
import type {RGBAImage, AlphaImage} from '../util/image';

import type Mask from '../render/tile_mask';
export type TileState =
| 'loading' // Tile data is in the process of loading.
| 'loaded' // Tile data has been loaded. Tile can be rendered.
Expand Down Expand Up @@ -71,7 +71,7 @@ class Tile {
placementSource: any;
workerID: number;
vtLayers: {[string]: VectorTileLayer};
mask: Array<number>;
mask: Mask;
aborted: ?boolean;
maskedBoundsBuffer: ?VertexBuffer;
maskedBoundsVAO: ?VertexArrayObject;
Expand Down Expand Up @@ -362,7 +362,7 @@ class Tile {
}
}

setMask(mask: Array<number>, gl: WebGLRenderingContext) {
setMask(mask: Mask, gl: WebGLRenderingContext) {

// don't redo buffer work if the mask is the same;
if (util.deepEqual(this.mask, mask)) return;
Expand All @@ -373,14 +373,16 @@ class Tile {

// We want to render the full tile, and keeping the segments/vertices/indices empty means
// using the global shared buffers for covering the entire tile.
if (util.deepEqual(mask, [0])) return;

if (util.deepEqual(mask, {'0': true})) return;
const maskArray = Object.keys(mask);
// mask is empty because all four children are loaded
if (mask.length === 0) return;
if (maskArray.length === 0) return;


const maskedBoundsArray = new RasterBoundsArray();
for (let i = 0; i < mask.length; i++) {
const maskCoord = TileCoord.fromID(mask[i]);

for (let i = 0; i < maskArray.length; i++) {
const maskCoord = TileCoord.fromID(+maskArray[i]);
const vertexExtent = EXTENT >> maskCoord.z;
const tlVertex = new Point(maskCoord.x * vertexExtent, maskCoord.y * vertexExtent);
const brVertex = new Point(tlVertex.x + vertexExtent, tlVertex.y + vertexExtent);
Expand Down
90 changes: 45 additions & 45 deletions test/unit/source/tile_mask.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,26 +27,26 @@ test('computeTileMasks', (t) => {
t.test('no children', (t) => {
const renderables = [new Tile(0, 0, 0) ];
updateTileMasks(renderables);
t.deepEqual(renderables[0].mask, [new TileCoord(0, 0, 0).id]);
t.deepEqual(Object.keys(renderables[0].mask), [new TileCoord(0, 0, 0).id]);

const renderables2 = [new Tile(4, 3, 8)];
updateTileMasks(renderables2);
t.deepEqual(renderables[0].mask, [new TileCoord(0, 0, 0).id]);
t.deepEqual(Object.keys(renderables2[0].mask), [new TileCoord(0, 0, 0).id]);

const renderables3 = [new Tile(1, 0, 0), new Tile(1, 1, 1)];
updateTileMasks(renderables3);
t.deepEqual(renderables3.map((r)=>{ return r.mask; }), [[new TileCoord(0, 0, 0).id], [new TileCoord(0, 0, 0).id]]);
t.deepEqual(renderables3.map((r)=>{ return Object.keys(r.mask); }), [[new TileCoord(0, 0, 0).id], [new TileCoord(0, 0, 0).id]]);

const renderables4 = [new Tile(1, 0, 0), new Tile(2, 2, 3)];
updateTileMasks(renderables4);
t.deepEqual(renderables4.map((r)=>{ return r.mask; }), [[new TileCoord(0, 0, 0).id], [new TileCoord(0, 0, 0).id]]);
t.deepEqual(renderables4.map((r)=>{ return Object.keys(r.mask); }), [[new TileCoord(0, 0, 0).id], [new TileCoord(0, 0, 0).id]]);
t.end();
});

t.test('parents with all four children', (t) => {
const renderables = [new Tile(0, 0, 0), new Tile(1, 0, 0), new Tile(1, 0, 1), new Tile(1, 1, 0), new Tile(1, 1, 1)];
updateTileMasks(renderables);
t.deepEqual(renderables.map((r)=>{ return r.mask; }), [
t.deepEqual(renderables.map((r)=>{ return Object.keys(r.mask); }), [
// empty mask -- i.e. don't draw anything because child tiles cover the whole parent tile
[],
[new TileCoord(0, 0, 0).id],
Expand All @@ -59,7 +59,7 @@ test('computeTileMasks', (t) => {
t.test('parent and one child', (t) => {
const renderables = [new Tile(0, 0, 0), new Tile(1, 0, 0)];
updateTileMasks(renderables);
t.deepEqual(renderables.map((r)=>{ return r.mask; }), [
t.deepEqual(renderables.map((r)=>{ return Object.keys(r.mask); }), [
[
new TileCoord(1, 1, 0).id,
new TileCoord(1, 0, 1).id,
Expand All @@ -79,50 +79,50 @@ test('computeTileMasks', (t) => {
new Tile(14, 4114, 5824),
new Tile(14, 4114, 5825)];
updateTileMasks(renderables);
t.deepEqual(renderables.map((r)=>{ return r.mask; }), [
t.deepEqual(renderables.map((r)=>{ return Object.keys(r.mask); }), [
[
new TileCoord(2, 3, 0).id,
new TileCoord(2, 3, 1).id,
new TileCoord(1, 1, 1).id
new TileCoord(1, 1, 1).id.toString(),
new TileCoord(2, 3, 0).id.toString(),
new TileCoord(2, 3, 1).id.toString(),
],
[
new TileCoord(1, 1, 0).id,
new TileCoord(1, 0, 1).id,
new TileCoord(1, 1, 1).id
new TileCoord(1, 1, 0).id.toString(),
new TileCoord(1, 0, 1).id.toString(),
new TileCoord(1, 1, 1).id.toString()
],
[
new TileCoord(1, 0, 0).id,
new TileCoord(1, 1, 0).id,
new TileCoord(1, 1, 1).id
new TileCoord(1, 0, 0).id.toString(),
new TileCoord(1, 1, 0).id.toString(),
new TileCoord(1, 1, 1).id.toString()
],
[new TileCoord(0, 0, 0).id],
[new TileCoord(0, 0, 0).id],
[new TileCoord(0, 0, 0).id],
[new TileCoord(0, 0, 0).id]
[new TileCoord(0, 0, 0).id.toString()],
[new TileCoord(0, 0, 0).id.toString()],
[new TileCoord(0, 0, 0).id.toString()],
[new TileCoord(0, 0, 0).id.toString()]
]);
t.end();
});

t.test('deep descendent masks', (t)=>{
const renderables = [ new Tile(0, 0, 0), new Tile(4, 4, 4)];
updateTileMasks(renderables);
t.deepEqual(renderables.map((r)=>{ return r.mask; }), [
t.deepEqual(renderables.map((r)=>{ return Object.keys(r.mask); }), [
[
new TileCoord(2, 0, 0).id,
new TileCoord(2, 1, 0).id,
new TileCoord(2, 0, 1).id,
new TileCoord(4, 5, 4).id,
new TileCoord(4, 4, 5).id,
new TileCoord(4, 5, 5).id,
new TileCoord(3, 3, 2).id,
new TileCoord(3, 2, 3).id,
new TileCoord(3, 3, 3).id,
new TileCoord(1, 1, 0).id,
new TileCoord(1, 0, 1).id,
new TileCoord(1, 1, 1).id
new TileCoord(2, 0, 0).id.toString(),
new TileCoord(1, 1, 0).id.toString(),
new TileCoord(2, 1, 0).id.toString(),
new TileCoord(1, 0, 1).id.toString(),
new TileCoord(1, 1, 1).id.toString(),
new TileCoord(2, 0, 1).id.toString(),
new TileCoord(3, 3, 2).id.toString(),
new TileCoord(3, 2, 3).id.toString(),
new TileCoord(3, 3, 3).id.toString(),
new TileCoord(4, 5, 4).id.toString(),
new TileCoord(4, 4, 5).id.toString(),
new TileCoord(4, 5, 5).id.toString(),
],
[
new TileCoord(0, 0, 0).id
new TileCoord(0, 0, 0).id.toString()
]
]);
t.end();
Expand All @@ -131,19 +131,19 @@ test('computeTileMasks', (t) => {
t.test('wrapped tile masks', (t) =>{
const renderables = [new Tile(0, 0, 0, 1), new Tile(1, 0, 0, 1), new Tile(2, 2, 2, 1), new Tile(3, 7, 7, 1), new Tile(3, 6, 6, 1)];
updateTileMasks(renderables);
t.deepEqual(renderables.map((r)=>{ return r.mask; }), [
t.deepEqual(renderables.map((r)=>{ return Object.keys(r.mask); }), [
[
new TileCoord(1, 1, 0).id,
new TileCoord(1, 0, 1).id,
new TileCoord(2, 3, 2).id,
new TileCoord(2, 2, 3).id,
new TileCoord(3, 7, 6).id,
new TileCoord(3, 6, 7).id
new TileCoord(1, 1, 0).id.toString(),
new TileCoord(1, 0, 1).id.toString(),
new TileCoord(2, 3, 2).id.toString(),
new TileCoord(2, 2, 3).id.toString(),
new TileCoord(3, 7, 6).id.toString(),
new TileCoord(3, 6, 7).id.toString()
],
[new TileCoord(0, 0, 0).id],
[new TileCoord(0, 0, 0).id],
[new TileCoord(0, 0, 0).id],
[new TileCoord(0, 0, 0).id]
[new TileCoord(0, 0, 0).id.toString()],
[new TileCoord(0, 0, 0).id.toString()],
[new TileCoord(0, 0, 0).id.toString()],
[new TileCoord(0, 0, 0).id.toString()]

]);
t.end();
Expand Down

0 comments on commit 69a347b

Please sign in to comment.