Skip to content

Commit

Permalink
Merge 8575a6b into b842628
Browse files Browse the repository at this point in the history
  • Loading branch information
1chandu committed Oct 18, 2019
2 parents b842628 + 8575a6b commit 4c769fc
Show file tree
Hide file tree
Showing 18 changed files with 515 additions and 285 deletions.
2 changes: 1 addition & 1 deletion examples/layer-browser/src/app.js
Expand Up @@ -66,7 +66,7 @@ export default class App extends PureComponent {

this.state = props.state || {
activeExamples: {
ScatterplotLayer: true
GPUGridLayer: true
},
settings: {
shadow: false,
Expand Down
36 changes: 36 additions & 0 deletions modules/aggregation-layers/src/aggregation-layer.js
@@ -0,0 +1,36 @@
// Copyright (c) 2015 - 2017 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

import {CompositeLayer, AttributeManager} from '@deck.gl/core';

export default class GPUGridLayer extends CompositeLayer {
updateState(opts) {
super.updateState(opts); // wihtout this invalidateAll not called for data change
this._updateAttributes(opts.props);
}

// override Composite layer private method to create AttributeManager instance
_getAttributeManager() {
return new AttributeManager(this.context.gl, {
id: this.props.id,
stats: this.context.stats
});
}
}
103 changes: 75 additions & 28 deletions modules/aggregation-layers/src/contour-layer/contour-layer.js
Expand Up @@ -19,12 +19,13 @@
// THE SOFTWARE.

import {equals} from 'math.gl';
import {CompositeLayer} from '@deck.gl/core';
import {LineLayer, SolidPolygonLayer} from '@deck.gl/layers';
import GL from '@luma.gl/constants';
import {generateContours} from './contour-utils';

import GPUGridAggregator from '../utils/gpu-grid-aggregation/gpu-grid-aggregator';
import {pointToDensityGridData} from '../utils/gpu-grid-aggregation/grid-aggregation-utils';
import AggregationLayer from '../aggregation-layer';

const DEFAULT_COLOR = [255, 255, 255, 255];
const DEFAULT_STROKE_WIDTH = 1;
Expand All @@ -43,41 +44,73 @@ const defaultProps = {
zOffset: 0.005
};

export default class ContourLayer extends CompositeLayer {
export default class ContourLayer extends AggregationLayer {
initializeState() {
const {gl} = this.context;
const options = {
id: `${this.id}-gpu-aggregator`
};
this.state = {
this.setState({
contourData: {},
gridAggregator: new GPUGridAggregator(gl, options),
colorTrigger: 0,
strokeWidthTrigger: 0
};
});
const attributeManager = this.getAttributeManager();
attributeManager.add({
positions: {size: 3, accessor: 'getPosition', type: GL.DOUBLE, fp64: false},
count: {size: 3, accessor: 'getWeight'}
});
}

updateState(opts) {
// const aggregationFlags = this._getAggregationFlags({oldProps, props, changeFlags});
const aggregationChanged = this._isDataChanged(opts);
const cellSizeChanged = opts.oldProps.cellSize !== opts.props.cellSize;
if (this._shouldRebuildContours(opts)) {
this._updateThresholdData(opts.props);
this.setState({contoursDirty: true});
} else if (!aggregationChanged && !cellSizeChanged) {
// data for sublayers not changed check if color or strokeWidth need to be updated
this._updateSubLayerTriggers(opts.oldProps, opts.props);
}

this.setState({aggregationChanged, cellSizeChanged});
super.updateState(opts);
}

updateState({oldProps, props, changeFlags}) {
updateAttributes(changedAttributes) {
let dataChanged = false;
let contoursChanged = false;
const aggregationFlags = this._getAggregationFlags({oldProps, props, changeFlags});
if (aggregationFlags) {
// eslint-disable-next-line
for (const name in changedAttributes) {
// TODO: verify this and simplify isDataChanged method
dataChanged = true;
// Clear countsData cache
this.setState({countsData: null});
this._aggregateData(aggregationFlags);
break;
}

if (this._shouldRebuildContours({oldProps, props})) {
contoursChanged = true;
this._updateThresholdData(props);
// if (aggregationFlags) {
// dataChanged = true;
// // Clear countsData cache
// this.setState({countsData: null});
// this._aggregateData(aggregationFlags);
// }

if (dataChanged || this.state.aggregationChanged || this.state.cellSizeChanged) {
dataChanged = true;
this._aggregateData({
dataChanged: dataChanged || this.state.aggregationChanged,
cellSizeChanged: this.state.cellSizeChanged
});
// Clear countsData cache
this.setState({
aggregationChanged: false,
cellSizeChanged: false
});
}

if (dataChanged || contoursChanged) {
if (dataChanged || this.state.contoursDirty) {
this._generateContours();
} else {
// data for sublayers not changed check if color or strokeWidth need to be updated
this._updateSubLayerTriggers(oldProps, props);
this.setState({contoursDirty: false});
}
}

Expand All @@ -103,7 +136,7 @@ export default class ContourLayer extends CompositeLayer {
const {
data,
cellSize: cellSizeMeters,
getPosition,
// getPosition,
getWeight,
gpuAggregation,
fp64,
Expand All @@ -112,15 +145,17 @@ export default class ContourLayer extends CompositeLayer {
const {weights, gridSize, gridOrigin, cellSize, boundingBox} = pointToDensityGridData({
data,
cellSizeMeters,
getPosition,
// getPosition,
weightParams: {count: {getWeight}},
gpuAggregation,
gpuGridAggregator: this.state.gridAggregator,
fp64,
coordinateSystem,
viewport: this.context.viewport,
boundingBox: this.state.boundingBox, // avoid parsing data when it is not changed.
aggregationFlags
aggregationFlags,
vertexCount: this.getNumInstances(),
attributes: this.getAttributeManager().getAttributes()
});

this.setState({
Expand Down Expand Up @@ -156,20 +191,32 @@ export default class ContourLayer extends CompositeLayer {
this.setState({contourData});
}

_getAggregationFlags({oldProps, props, changeFlags}) {
let aggregationFlags = null;
// _getAggregationFlags({oldProps, props, changeFlags}) {
// let aggregationFlags = null;
// if (
// changeFlags.dataChanged ||
// oldProps.gpuAggregation !== props.gpuAggregation ||
// (changeFlags.updateTriggersChanged &&
// (changeFlags.updateTriggersChanged.all || changeFlags.updateTriggersChanged.getPosition))
// ) {
// aggregationFlags = Object.assign({}, aggregationFlags, {dataChanged: true});
// }
// if (oldProps.cellSize !== props.cellSize) {
// aggregationFlags = Object.assign({}, aggregationFlags, {cellSizeChanged: true});
// }
// return aggregationFlags;
// }

_isDataChanged({oldProps, props, changeFlags}) {
if (
changeFlags.dataChanged ||
oldProps.gpuAggregation !== props.gpuAggregation ||
(changeFlags.updateTriggersChanged &&
(changeFlags.updateTriggersChanged.all || changeFlags.updateTriggersChanged.getPosition))
) {
aggregationFlags = Object.assign({}, aggregationFlags, {dataChanged: true});
}
if (oldProps.cellSize !== props.cellSize) {
aggregationFlags = Object.assign({}, aggregationFlags, {cellSizeChanged: true});
return true;
}
return aggregationFlags;
return false;
}

_getLineLayerProps() {
Expand Down
71 changes: 46 additions & 25 deletions modules/aggregation-layers/src/gpu-grid-layer/gpu-grid-layer.js
Expand Up @@ -19,14 +19,16 @@
// THE SOFTWARE.

import {PhongMaterial} from '@luma.gl/core';
import {CompositeLayer, log} from '@deck.gl/core';
import GL from '@luma.gl/constants';
import {log} from '@deck.gl/core';

import GPUGridAggregator from '../utils/gpu-grid-aggregation/gpu-grid-aggregator';
import {AGGREGATION_OPERATION} from '../utils/aggregation-operation-utils';
import {pointToDensityGridData} from '../utils/gpu-grid-aggregation/grid-aggregation-utils';
import {defaultColorRange, colorRangeToFlatArray} from '../utils/color-utils';
import GPUGridCellLayer from './gpu-grid-cell-layer';
import {pointToDensityGridDataCPU} from './../cpu-grid-layer/grid-aggregator';
import AggregationLayer from '../aggregation-layer';

const defaultMaterial = new PhongMaterial();
const defaultProps = {
Expand Down Expand Up @@ -57,7 +59,7 @@ const defaultProps = {
gpuAggregation: true
};

export default class GPUGridLayer extends CompositeLayer {
export default class GPUGridLayer extends AggregationLayer {
initializeState() {
const {gl} = this.context;
const isSupported = GPUGridAggregator.isSupported(gl);
Expand All @@ -71,15 +73,47 @@ export default class GPUGridLayer extends CompositeLayer {
gpuGridAggregator: new GPUGridAggregator(gl, options),
isSupported
};
const attributeManager = this.getAttributeManager();
attributeManager.add({
positions: {size: 3, accessor: 'getPosition', type: GL.DOUBLE, fp64: false},
color: {size: 3, accessor: 'getColorWeight'},
elevation: {size: 3, accessor: 'getElevationWeight'}
});
}

updateState(opts) {
const aggregationFlags = this.getAggregationFlags(opts);
if (aggregationFlags) {
// aggregate points into grid cells
this.getLayerData(aggregationFlags);
if (this.state.isSupported === false) {
// Skip update, layer not supported
return;
}
const aggregationChanged = this._isDataChanged(opts);
const cellSizeChanged = opts.oldProps.cellSize !== opts.props.cellSize;
this.setState({aggregationChanged, cellSizeChanged});
// TODO - just run this for all layers
super.updateState(opts);
}

updateAttributes(changedAttributes) {
let dataChanged = false;
// eslint-disable-next-line
for (const name in changedAttributes) {
// TODO: verify this and simplify _isDataChanged method
dataChanged = true;
break;
}

if (dataChanged || this.state.aggregationChanged || this.state.cellSizeChanged) {
this._getLayerData({
dataChanged: dataChanged || this.state.aggregationChanged,
cellSizeChanged: this.state.cellSizeChanged
});

// reset cached CPU Aggregation results (used for picking)
this.setState({gridHash: null});
this.setState({
aggregationChanged: false,
cellSizeChanged: false,
gridHash: null
});
}
}

Expand All @@ -88,22 +122,7 @@ export default class GPUGridLayer extends CompositeLayer {
this.state.gpuGridAggregator.delete();
}

getAggregationFlags({oldProps, props, changeFlags}) {
let aggregationFlags = null;
if (!this.state.isSupported) {
// Skip update, layer not supported
return false;
}
if (this.isDataChanged({oldProps, props, changeFlags})) {
aggregationFlags = Object.assign({}, aggregationFlags, {dataChanged: true});
}
if (oldProps.cellSize !== props.cellSize) {
aggregationFlags = Object.assign({}, aggregationFlags, {cellSizeChanged: true});
}
return aggregationFlags;
}

isDataChanged({oldProps, props, changeFlags}) {
_isDataChanged({oldProps, props, changeFlags}) {
// Flags affecting aggregation data
if (changeFlags.dataChanged) {
return true;
Expand Down Expand Up @@ -194,7 +213,7 @@ export default class GPUGridLayer extends CompositeLayer {
});
}

getLayerData(aggregationFlags) {
_getLayerData(aggregationFlags) {
const {
data,
cellSize: cellSizeMeters,
Expand Down Expand Up @@ -235,7 +254,9 @@ export default class GPUGridLayer extends CompositeLayer {
gpuGridAggregator: this.state.gpuGridAggregator,
boundingBox: this.state.boundingBox, // avoid parsing data when it is not changed.
aggregationFlags,
fp64
fp64,
vertexCount: this.getNumInstances(),
attributes: this.getAttributeManager().getAttributes()
});
this.setState({weights, gridSize, gridOrigin, cellSize, boundingBox});
}
Expand Down

0 comments on commit 4c769fc

Please sign in to comment.