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

visgl / luma.gl / 13874305899

15 Mar 2025 03:41PM UTC coverage: 75.087% (-0.2%) from 75.241%
13874305899

push

github

web-flow
chore(deps): bump @babel/runtime-corejs3 in /website (#2347)

Signed-off-by: dependabot[bot] <support@github.com>

2012 of 2636 branches covered (76.33%)

Branch coverage included in aggregate %.

26274 of 35035 relevant lines covered (74.99%)

44.98 hits per line

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

43.2
/modules/webgl/src/context/debug/webgl-developer-tools.ts
1
// luma.gl
1✔
2
// SPDX-License-Identifier: MIT
1✔
3
// Copyright (c) vis.gl contributors
1✔
4

1✔
5
import {log} from '@luma.gl/core';
1✔
6
// Rename constant to prevent inlining. We need the full set of constants for generating debug strings.
1✔
7
import {GL as GLEnum} from '@luma.gl/constants';
1✔
8
import {isBrowser} from '@probe.gl/env';
1✔
9
import {loadScript} from '../../utils/load-script';
1✔
10

1✔
11
const WEBGL_DEBUG_CDN_URL = 'https://unpkg.com/webgl-debug@2.0.1/index.js';
1✔
12

1✔
13
type DebugContextProps = {
1✔
14
  debugWebGL?: boolean;
1✔
15
  traceWebGL?: boolean;
1✔
16
};
1✔
17

1✔
18
type ContextData = {
1✔
19
  realContext?: WebGL2RenderingContext;
1✔
20
  debugContext?: WebGL2RenderingContext;
1✔
21
};
1✔
22

1✔
23
// Helper to get shared context data
1✔
24
function getWebGLContextData(gl: any): ContextData {
×
25
  gl.luma = gl.luma || {};
×
26
  return gl.luma;
×
27
}
×
28

1✔
29
declare global {
1✔
30
  // eslint-disable-next-line no-var
1✔
31
  var WebGLDebugUtils: any;
1✔
32
}
1✔
33

1✔
34
/**
1✔
35
 * Loads Khronos WebGLDeveloperTools from CDN if not already installed
1✔
36
 * const WebGLDebugUtils = require('webgl-debug');
1✔
37
 * @see https://github.com/KhronosGroup/WebGLDeveloperTools
1✔
38
 * @see https://github.com/vorg/webgl-debug
1✔
39
 */
1✔
40
export async function loadWebGLDeveloperTools(): Promise<void> {
1✔
41
  if (isBrowser() && !globalThis.WebGLDebugUtils) {
1✔
42
    globalThis.global = globalThis.global || globalThis;
1✔
43
    // @ts-expect-error Developer tools expects global to be set
1✔
44
    globalThis.global.module = {};
1✔
45
    await loadScript(WEBGL_DEBUG_CDN_URL);
1!
46
  }
×
47
}
1✔
48

1✔
49
// Returns (a potentially new) context with debug instrumentation turned off or on.
1✔
50
// Note that this actually returns a new context
1✔
51
export function makeDebugContext(
1✔
52
  gl: WebGL2RenderingContext,
1✔
53
  props: DebugContextProps = {}
1✔
54
): WebGL2RenderingContext {
1✔
55
  return props.debugWebGL || props.traceWebGL ? getDebugContext(gl, props) : getRealContext(gl);
1!
56
}
1✔
57

1✔
58
// Returns the real context from either of the real/debug contexts
1✔
59
function getRealContext(gl: WebGL2RenderingContext): WebGL2RenderingContext {
×
60
  const data = getWebGLContextData(gl);
×
61
  // If the context has a realContext member, it is a debug context so return the realContext
×
62
  return data.realContext ? data.realContext : gl;
×
63
}
×
64

1✔
65
// Returns the debug context from either of the real/debug contexts
1✔
66
function getDebugContext(
1✔
67
  gl: WebGL2RenderingContext,
1✔
68
  props: DebugContextProps
1✔
69
): WebGL2RenderingContext {
1✔
70
  if (!globalThis.WebGLDebugUtils) {
1✔
71
    log.warn('webgl-debug not loaded')();
1✔
72
    return gl;
1✔
73
  }
1!
74

×
75
  const data = getWebGLContextData(gl);
×
76

×
77
  // If this already has a debug context, return it.
×
78
  if (data.debugContext) {
×
79
    return data.debugContext;
×
80
  }
×
81

×
82
  // Create a new debug context
×
83
  globalThis.WebGLDebugUtils.init({...GLEnum, ...gl});
×
84
  const glDebug = globalThis.WebGLDebugUtils.makeDebugContext(
×
85
    gl,
×
86
    onGLError.bind(null, props),
×
87
    onValidateGLFunc.bind(null, props)
×
88
  );
×
89

×
90
  // Make sure we have all WebGL2 and extension constants (todo dynamic import to circumvent minification?)
×
91
  for (const key in GLEnum) {
×
92
    if (!(key in glDebug) && typeof GLEnum[key] === 'number') {
×
93
      glDebug[key] = GLEnum[key];
×
94
    }
×
95
  }
×
96

×
97
  // Ensure we have a clean prototype on the instrumented object
×
98
  // Note: setPrototypeOf does come with perf warnings, but we already take a bigger perf reduction
×
99
  // by synchronizing the WebGL errors after each WebGL call.
×
100
  class WebGLDebugContext {}
×
101
  Object.setPrototypeOf(glDebug, Object.getPrototypeOf(gl));
×
102
  Object.setPrototypeOf(WebGLDebugContext, glDebug);
×
103
  const debugContext = Object.create(WebGLDebugContext);
×
104
  // Store the debug context
×
105
  data.realContext = gl;
×
106
  data.debugContext = debugContext;
×
107
  debugContext.debug = true;
×
108

×
109
  // Return it
×
110
  return debugContext;
×
111
}
×
112

1✔
113
// DEBUG TRACING
1✔
114

1✔
115
function getFunctionString(functionName: string, functionArgs: unknown[]): string {
×
116
  // Cover bug in webgl-debug-tools
×
117
  functionArgs = Array.from(functionArgs).map(arg => (arg === undefined ? 'undefined' : arg));
×
118
  let args = globalThis.WebGLDebugUtils.glFunctionArgsToString(functionName, functionArgs);
×
119
  args = `${args.slice(0, 100)}${args.length > 100 ? '...' : ''}`;
×
120
  return `gl.${functionName}(${args})`;
×
121
}
×
122

1✔
123
function onGLError(
×
124
  props: DebugContextProps,
×
125
  err: number,
×
126
  functionName: string,
×
127
  args: unknown[]
×
128
): void {
×
129
  // Cover bug in webgl-debug-tools
×
130
  args = Array.from(args).map(arg => (arg === undefined ? 'undefined' : arg));
×
131
  const errorMessage = globalThis.WebGLDebugUtils.glEnumToString(err);
×
132
  const functionArgs = globalThis.WebGLDebugUtils.glFunctionArgsToString(functionName, args);
×
133
  const message = `${errorMessage} in gl.${functionName}(${functionArgs})`;
×
134
  // TODO - call device.reportError
×
135
  log.error(message)();
×
136
  debugger; // eslint-disable-line
×
137
  // throw new Error(message);
×
138
}
×
139

1✔
140
// Don't generate function string until it is needed
1✔
141
function onValidateGLFunc(
×
142
  props: DebugContextProps,
×
143
  functionName: string,
×
144
  functionArgs: unknown[]
×
145
): void {
×
146
  let functionString: string = '';
×
147
  if (log.level >= 1) {
×
148
    functionString = getFunctionString(functionName, functionArgs);
×
149
    if (props.traceWebGL) {
×
150
      log.log(1, functionString)();
×
151
    }
×
152
  }
×
153

×
154
  for (const arg of functionArgs) {
×
155
    if (arg === undefined) {
×
156
      functionString = functionString || getFunctionString(functionName, functionArgs);
×
157
      debugger; // eslint-disable-line
×
158
      // throw new Error(`Undefined argument: ${functionString}`);
×
159
    }
×
160
  }
×
161
}
×
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