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

visgl / luma.gl / 16861129258

10 Aug 2025 12:01PM UTC coverage: 51.251% (-22.6%) from 73.868%
16861129258

Pull #2416

github

web-flow
Merge 98ff12c30 into f90a93cf3
Pull Request #2416: chore: Tests for texture reads

591 of 833 branches covered (70.95%)

Branch coverage included in aggregate %.

65 of 107 new or added lines in 7 files covered. (60.75%)

8551 existing lines in 130 files now uncovered.

18665 of 36739 relevant lines covered (50.8%)

11.48 hits per line

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

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

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

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

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

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

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

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

×
UNCOV
47
    this.device = device;
×
UNCOV
48

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

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

×
UNCOV
63
    this.model.setTransformFeedback(this.transformFeedback);
×
UNCOV
64

×
UNCOV
65
    Object.seal(this);
×
UNCOV
66
  }
×
UNCOV
67

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

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

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

×
UNCOV
98
  // DEPRECATED METHODS
×
UNCOV
99

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

×
UNCOV
105
  /** @deprecated App knows what buffers it is passing in - Reads the {@link Buffer} or {@link BufferRange} for given varying name. */
×
UNCOV
106
  readAsync(varyingName: string): Promise<Uint8Array> {
×
UNCOV
107
    const result = this.getBuffer(varyingName);
×
UNCOV
108
    if (!result) {
×
109
      throw new Error('BufferTransform#getBuffer');
×
110
    }
×
UNCOV
111
    if (result instanceof Buffer) {
×
112
      return result.readAsync();
×
113
    }
×
UNCOV
114
    const {buffer, byteOffset = 0, byteLength = buffer.byteLength} = result;
×
UNCOV
115
    return buffer.readAsync(byteOffset, byteLength);
×
UNCOV
116
  }
×
UNCOV
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