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

visgl / luma.gl / 25677315527

11 May 2026 02:45PM UTC coverage: 74.394% (+0.2%) from 74.161%
25677315527

push

github

web-flow
feat(arrow) ArrowGPUTable, ArrowModel (#2607)

Co-authored-by: Ib Green <ib.green.home@gmail.com>

5402 of 8198 branches covered (65.89%)

Branch coverage included in aggregate %.

193 of 228 new or added lines in 13 files covered. (84.65%)

1 existing line in 1 file now uncovered.

12047 of 15257 relevant lines covered (78.96%)

767.58 hits per line

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

82.81
/modules/engine/src/utils/shader-module-utils.ts
1
// luma.gl
2
// SPDX-License-Identifier: MIT
3
// Copyright (c) vis.gl contributors
4

5
import type {ComputeShaderLayout, ShaderLayout} from '@luma.gl/core';
6
import type {ShaderModule} from '@luma.gl/shadertools';
7

8
type AnyShaderLayout = ShaderLayout | ComputeShaderLayout;
9

10
export function mergeShaderModuleBindingsIntoLayout<TShaderLayout extends AnyShaderLayout>(
11
  shaderLayout: TShaderLayout | null | undefined,
12
  modules: ShaderModule[]
13
): TShaderLayout | null | undefined {
14
  if (!shaderLayout || !modules.some(module => module.bindingLayout?.length)) {
123✔
15
    return shaderLayout;
121✔
16
  }
17

18
  const mergedLayout = {
2✔
19
    ...shaderLayout,
20
    bindings: shaderLayout.bindings.map(binding => ({...binding}))
5✔
21
  } as TShaderLayout;
22

23
  if ('attributes' in (shaderLayout || {})) {
2!
24
    (mergedLayout as ShaderLayout).attributes = (shaderLayout as ShaderLayout)?.attributes || [];
2!
25
  }
26

27
  for (const module of modules) {
2✔
28
    for (const bindingLayout of module.bindingLayout || []) {
3!
29
      for (const relatedBindingName of getRelatedBindingNames(bindingLayout.name)) {
20✔
30
        const binding = mergedLayout.bindings.find(
60✔
31
          candidate => candidate.name === relatedBindingName
122✔
32
        );
33
        if (binding?.group === 0) {
60✔
34
          binding.group = bindingLayout.group;
4✔
35
        }
36
      }
37
    }
38
  }
39

40
  return mergedLayout;
2✔
41
}
42

43
export function mergeInferredShaderLayout(
44
  shaderLayout: ShaderLayout | null | undefined,
45
  inferredShaderLayout: ShaderLayout | null | undefined
46
): ShaderLayout | null | undefined {
47
  if (!shaderLayout) {
9✔
48
    return inferredShaderLayout;
8✔
49
  }
50
  if (!inferredShaderLayout) {
1!
NEW
51
    return shaderLayout;
×
52
  }
53

54
  return {
1✔
55
    ...shaderLayout,
56
    attributes: shaderLayout.attributes.length
1!
57
      ? shaderLayout.attributes
58
      : inferredShaderLayout.attributes,
59
    bindings: mergeBindingLayouts(shaderLayout.bindings, inferredShaderLayout.bindings)
60
  };
61
}
62

63
export function shaderModuleHasUniforms(module: ShaderModule): boolean {
64
  return Boolean(module.uniformTypes && !isObjectEmpty(module.uniformTypes));
161✔
65
}
66

67
/** Returns binding-name aliases that should share the module-declared bind group. */
68
function getRelatedBindingNames(bindingName: string): string[] {
69
  const bindingNames = new Set<string>([bindingName, `${bindingName}Uniforms`]);
20✔
70

71
  if (!bindingName.endsWith('Uniforms')) {
20!
72
    bindingNames.add(`${bindingName}Sampler`);
20✔
73
  }
74

75
  return [...bindingNames];
20✔
76
}
77

78
function isObjectEmpty(obj: object): boolean {
79
  for (const _key in obj) {
133✔
80
    return false;
133✔
81
  }
82
  return true;
×
83
}
84

85
function mergeBindingLayouts<TBindingLayout extends ShaderLayout['bindings'][number]>(
86
  explicitBindings: TBindingLayout[],
87
  inferredBindings: TBindingLayout[]
88
): TBindingLayout[] {
89
  const mergedBindings = explicitBindings.map(binding => ({...binding}));
1✔
90
  const explicitBindingNames = new Set(explicitBindings.map(binding => binding.name));
1✔
91
  const explicitBindingLocations = new Set(
1✔
NEW
92
    explicitBindings.map(binding => `${binding.group}:${binding.location}`)
×
93
  );
94

95
  for (const inferredBinding of inferredBindings) {
1✔
96
    const inferredBindingLocation = `${inferredBinding.group}:${inferredBinding.location}`;
1✔
97
    if (
1!
98
      !explicitBindingNames.has(inferredBinding.name) &&
2✔
99
      !explicitBindingLocations.has(inferredBindingLocation)
100
    ) {
101
      mergedBindings.push({...inferredBinding});
1✔
102
    }
103
  }
104

105
  return mergedBindings;
1✔
106
}
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