• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

visgl / luma.gl / 23357510199

20 Mar 2026 06:40PM UTC coverage: 58.158% (+5.9%) from 52.213%
23357510199

push

github

web-flow
chore: Run tests on src instead of dist (#2555)

3021 of 6029 branches covered (50.11%)

Branch coverage included in aggregate %.

7102 of 11377 relevant lines covered (62.42%)

243.33 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

74.0
/modules/engine/src/compute/buffer-transform.ts
1
// luma.gl
2
// SPDX-License-Identifier: MIT
3
// Copyright (c) vis.gl contributors
4

5
import {Device, Buffer, BufferRange, TransformFeedback, RenderPassProps} from '@luma.gl/core';
6
import {getPassthroughFS} from '@luma.gl/shadertools';
7
import {Model} from '../model/model';
8
import type {ModelProps} from '../model/model';
9

10
/**
11
 * Properties for creating a {@link BufferTransform}
12
 * @note Only works under WebGL2.
13
 */
14
export type BufferTransformProps = Omit<ModelProps, 'fs'> & {
15
  /** Optional fragment shader - normally not used in transforms */
16
  fs?: ModelProps['fs']; // override as optional
17
  /** A list of named outputs corresponding to shader declarations (varyings in WebGL) */
18
  outputs?: string[];
19
  /** @deprecated Use run({outputBuffers}) instead - Map of output buffers that the shaders will write results of computations to */
20
  feedbackBuffers?: Record<string, Buffer | BufferRange>;
21
};
22

23
/**
24
 * Manages a WebGL program (pipeline) for buffer→buffer transforms.
25
 * @note Only works under WebGL2.
26
 */
27
export class BufferTransform {
28
  readonly device: Device;
29
  readonly model: Model;
30
  readonly transformFeedback: TransformFeedback;
31

32
  static defaultProps: Required<BufferTransformProps> = {
58✔
33
    ...Model.defaultProps,
34
    outputs: undefined!,
35
    feedbackBuffers: undefined!
36
  };
37

38
  static isSupported(device: Device): boolean {
39
    return device?.info?.type === 'webgl';
28✔
40
  }
41

42
  constructor(device: Device, props: BufferTransformProps = BufferTransform.defaultProps) {
13✔
43
    if (!BufferTransform.isSupported(device)) {
13!
44
      throw new Error('BufferTransform not yet implemented on WebGPU');
×
45
    }
46

47
    this.device = device;
13✔
48

49
    this.model = new Model(this.device, {
13✔
50
      id: props.id || 'buffer-transform-model',
26✔
51
      fs: props.fs || getPassthroughFS(),
24✔
52
      topology: props.topology || 'point-list',
24✔
53
      varyings: props.outputs || props.varyings,
13!
54
      ...props
55
    });
56

57
    this.transformFeedback = this.device.createTransformFeedback({
13✔
58
      layout: this.model.pipeline.shaderLayout,
59
      // @ts-expect-error TODO
60
      buffers: props.feedbackBuffers
61
    });
62

63
    this.model.setTransformFeedback(this.transformFeedback);
13✔
64

65
    Object.seal(this);
13✔
66
  }
67

68
  /** Destroy owned resources. */
69
  destroy(): void {
70
    if (this.model) {
11!
71
      this.model.destroy();
11✔
72
    }
73
  }
74

75
  /** @deprecated Use {@link destroy}. */
76
  delete(): void {
77
    this.destroy();
×
78
  }
79

80
  /** Run one transform loop. */
81
  run(
82
    options?: RenderPassProps & {
83
      inputBuffers?: Record<string, Buffer>;
84
      outputBuffers?: Record<string, Buffer>;
85
    }
86
  ): void {
87
    if (options?.inputBuffers) {
12!
88
      this.model.setAttributes(options.inputBuffers);
×
89
    }
90
    if (options?.outputBuffers) {
12!
91
      this.transformFeedback.setBuffers(options.outputBuffers);
×
92
    }
93
    const renderPass = this.device.beginRenderPass(options);
12✔
94
    this.model.draw(renderPass);
12✔
95
    renderPass.end();
12✔
96
  }
97

98
  // DEPRECATED METHODS
99

100
  /** @deprecated App knows what buffers it is passing in - Returns the {@link Buffer} or {@link BufferRange} for given varying name. */
101
  getBuffer(varyingName: string): Buffer | BufferRange | null {
102
    return this.transformFeedback.getBuffer(varyingName);
24✔
103
  }
104

105
  /** @deprecated App knows what buffers it is passing in - Reads the {@link Buffer} or {@link BufferRange} for given varying name. */
106
  readAsync(varyingName: string): Promise<Uint8Array> {
107
    const result = this.getBuffer(varyingName);
24✔
108
    if (!result) {
24!
109
      throw new Error('BufferTransform#getBuffer');
×
110
    }
111
    if (result instanceof Buffer) {
24!
112
      return result.readAsync();
×
113
    }
114
    const {buffer, byteOffset = 0, byteLength = buffer.byteLength} = result;
24✔
115
    return buffer.readAsync(byteOffset, byteLength);
24✔
116
  }
117
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc