[go: nahoru, domu]

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

GPU Aggregation (4/8): ScreenGridLayer #8942

Merged
merged 9 commits into from
Jun 24, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export default abstract class AggregationLayer<
static layerName = 'AggregationLayer';

state!: {
aggregatorType: string;
aggregator: Aggregator;
};

Expand All @@ -28,27 +29,35 @@ export default abstract class AggregationLayer<
return true;
}

abstract getAggregatorType(): string;
/** Called to create an Aggregator instance */
abstract createAggregator(): Aggregator;
abstract createAggregator(type: string): Aggregator;
/** Called when some attributes change, a chance to mark Aggregator as dirty */
abstract onAttributeChange(id: string): void;

initializeState(): void {
this.getAttributeManager()!.remove(['instancePickingColors']);
}

// Override Layer.updateState to update the GPUAggregator instance
updateState(params: UpdateParameters<this>) {
// Extend Layer.updateState to update the Aggregator instance
// returns true if aggregator is changed
updateState(params: UpdateParameters<this>): boolean {
super.updateState(params);

if (params.changeFlags.extensionsChanged) {
const aggregatorType = this.getAggregatorType();
if (params.changeFlags.extensionsChanged || this.state.aggregatorType !== aggregatorType) {
this.state.aggregator?.destroy();
this.state.aggregator = this.createAggregator();
this.getAttributeManager()!.invalidateAll();
const aggregator = this.createAggregator(aggregatorType);
aggregator.setProps({
attributes: this.getAttributeManager()?.attributes
});
this.setState({aggregator, aggregatorType});
return true;
}
return false;
}

// Override Layer.finalizeState to dispose the GPUAggregator instance
// Override Layer.finalizeState to dispose the Aggregator instance
finalizeState(context: LayerContext) {
super.finalizeState(context);
this.state.aggregator.destroy();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,19 +59,24 @@ const AGGREGATION_FUNC: Record<AggregationOperation, AggregationFunc> = {
export function aggregate({
bins,
getValue,
operation
operation,
target
}: {
/** Data points sorted by bins */
bins: Bin[];
/** Given the index of a data point, returns its value */
getValue: (index: number) => number;
/** Method used to reduce a list of values to one number */
operation: AggregationOperation;
/** Array to write the output into */
target?: Float32Array | null;
}): {
value: Float32Array;
domain: [min: number, max: number];
} {
const target = new Float32Array(bins.length);
if (!target || target.length < bins.length) {
target = new Float32Array(bins.length);
}
let min = Infinity;
let max = -Infinity;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,11 @@ export class CPUAggregator implements Aggregator {
protected needsUpdate: boolean[] | boolean;

protected bins: Bin[] = [];
protected binIds: Float32Array | null = null;
protected results: {value: Float32Array; domain: [min: number, max: number]}[] = [];
protected binIds: (BinaryAttribute & {value: Float32Array}) | null = null;
protected results: (BinaryAttribute & {
value: Float32Array;
domain: [min: number, max: number];
})[] = [];

constructor(props: CPUAggregatorProps) {
this.dimensions = props.dimensions;
Expand Down Expand Up @@ -116,22 +119,28 @@ export class CPUAggregator implements Aggregator {
this.props.binOptions
)
});
this.binIds = packBinIds({
const value = packBinIds({
bins: this.bins,
dimensions: this.dimensions
dimensions: this.dimensions,
// Reuse allocated typed array
target: this.binIds?.value
});
this.binIds = {value, type: 'float32', size: this.dimensions};
}
for (let channel = 0; channel < this.channelCount; channel++) {
if (this.needsUpdate === true || this.needsUpdate[channel]) {
this.results[channel] = aggregate({
const {value, domain} = aggregate({
bins: this.bins,
getValue: evaluateVertexAccessor(
this.props.getValue[channel],
this.props.attributes,
undefined
),
operation: this.props.operations[channel]
operation: this.props.operations[channel],
// Reuse allocated typed array
target: this.results[channel]?.value
});
this.results[channel] = {value, domain, type: 'float32', size: 1};
}
}
this.needsUpdate = false;
Expand All @@ -141,19 +150,12 @@ export class CPUAggregator implements Aggregator {

/** Returns an accessor to the bins. */
getBins(): BinaryAttribute | null {
if (!this.binIds) {
return null;
}
return {value: this.binIds, type: 'float32', size: this.dimensions};
return this.binIds;
}

/** Returns an accessor to the output for a given channel. */
getResult(channel: number): BinaryAttribute | null {
const result = this.results[channel];
if (!result) {
return null;
}
return {value: result.value, type: 'float32', size: 1};
return this.results[channel];
}

/** Returns the [min, max] of aggregated values for a given channel. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,19 @@ export function sortBins({
/** Pack bin ids into a typed array */
export function packBinIds({
bins,
dimensions
dimensions,
target
}: {
bins: Bin[];
/** Size of bin IDs */
dimensions: number;
/** Array to write output into */
target?: Float32Array | null;
}): Float32Array {
const target = new Float32Array(bins.length * dimensions);
const targetLength = bins.length * dimensions;
if (!target || target.length < targetLength) {
target = new Float32Array(targetLength);
}

for (let i = 0; i < bins.length; i++) {
const {id} = bins[i];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@
/** Step 2. (optional) calculate the min/max across all bins */
protected aggregationTransform: WebGLAggregationTransform;

/** Cached outputs */
protected binIds: BinaryAttribute | null = null;
protected results: BinaryAttribute[] = [];

constructor(device: Device, props: WebGLAggregatorProps) {
this.device = device;
this.dimensions = props.dimensions;
Expand All @@ -88,7 +92,12 @@
if (!buffer) {
return null;
}
return {buffer, type: 'float32', size: this.dimensions};
if (this.binIds?.buffer !== buffer) {
// deck.gl Attribute.setBinaryValue uses shallow comparison to determine if attribute value has changed
// For performance, only create a new binary attribute descriptor when Buffer changes
this.binIds = {buffer, type: 'float32', size: this.dimensions};
}
return this.binIds;
}

/** Returns an accessor to the output for a given channel. */
Expand All @@ -97,7 +106,16 @@
if (!buffer || channel >= this.channelCount) {
return null;
}
return {buffer, type: 'float32', size: 1, stride: this.channelCount * 4, offset: channel * 4};
if (this.results[channel]?.buffer !== buffer) {
this.results[channel] = {
buffer,
type: 'float32',
size: 1,
stride: this.channelCount * 4,
offset: channel * 4
};
}
return this.results[channel];
}

/** Returns the [min, max] of aggregated values for a given channel. */
Expand Down Expand Up @@ -147,7 +165,7 @@
}

/** Update aggregation props. Normalize prop values and set change flags. */
setProps(props: Partial<WebGLAggregationProps>) {

Check warning on line 168 in modules/aggregation-layers/src/aggregation-layer-v9/gpu-aggregator/webgl-aggregator.ts

View workflow job for this annotation

GitHub Actions / test-node

Method 'setProps' has too many statements (35). Maximum allowed is 25
const oldProps = this.props;

// Update local settings. These will set the flag this._needsUpdate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ type _GPUGridCellLayerProps = _GPUGridLayerProps<any> & {
elevationMaxMinBuffer: Buffer;
};

export default class GPUGridCellLayer extends Layer<_GPUGridCellLayerProps> {
export default class GPUGridCellLayer extends Layer<Required<_GPUGridCellLayerProps>> {
static layerName = 'GPUGridCellLayer';
static defaultProps = defaultProps;

Expand Down
5 changes: 4 additions & 1 deletion modules/aggregation-layers/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@ export type {HexagonLayerProps} from './hexagon-layer/hexagon-layer';
export type {CPUGridLayerProps} from './cpu-grid-layer/cpu-grid-layer';
export type {GridLayerProps} from './grid-layer/grid-layer';
export type {GPUGridLayerProps} from './gpu-grid-layer/gpu-grid-layer';
export type {ScreenGridLayerProps} from './screen-grid-layer/screen-grid-layer';
export type {
ScreenGridLayerProps,
ScreenGridLayerPickingInfo
} from './screen-grid-layer/screen-grid-layer';

export type {WebGLAggregatorProps} from './aggregation-layer-v9/gpu-aggregator/webgl-aggregator';
export type {CPUAggregatorProps} from './aggregation-layer-v9/cpu-aggregator/cpu-aggregator';
Loading
Loading