• 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

90.0
/modules/webgl/src/context/helpers/create-browser-context.ts
1
// luma.gl
2
// SPDX-License-Identifier: MIT
3
// Copyright (c) vis.gl contributors
4

5
import {getWebGLContextData} from './webgl-context-data';
6

7
/**
8
 * ContextProps
9
 * @param onContextLost
10
 * @param onContextRestored *
11
 */
12
type ContextProps = {
13
  /** Called when a context is lost */
14
  onContextLost: (event: Event) => void;
15
  /** Called when a context is restored */
16
  onContextRestored: (event: Event) => void;
17
};
18

19
/**
20
 * Create a WebGL context for a canvas
21
 * Note calling this multiple time on the same canvas does return the same context
22
 * @param canvas A canvas element or offscreen canvas
23
 */
24
export function createBrowserContext(
25
  canvas: HTMLCanvasElement | OffscreenCanvas,
26
  props: ContextProps,
27
  webglContextAttributes: WebGLContextAttributes
28
): WebGL2RenderingContext {
29
  // Try to extract any extra information about why context creation failed
30
  let errorMessage = '';
110✔
31
  const onCreateError = (event: Event) => {
110✔
32
    const statusMessage = (event as WebGLContextEvent).statusMessage;
2✔
33
    if (statusMessage) {
2!
34
      errorMessage ||= statusMessage;
2✔
35
    }
36
  };
37
  canvas.addEventListener('webglcontextcreationerror', onCreateError, false);
110✔
38

39
  const allowSoftwareRenderer = webglContextAttributes.failIfMajorPerformanceCaveat !== true;
110✔
40

41
  const webglProps: WebGLContextAttributes = {
110✔
42
    preserveDrawingBuffer: true,
43
    ...webglContextAttributes,
44
    // Always start by requesting a high-performance context.
45
    failIfMajorPerformanceCaveat: true
46
  };
47

48
  // Create the desired context
49
  let gl: WebGL2RenderingContext | null = null;
110✔
50

51
  try {
110✔
52
    // Create a webgl2 context
53
    gl ||= canvas.getContext('webgl2', webglProps);
110✔
54
    if (!gl && webglProps.failIfMajorPerformanceCaveat) {
110✔
55
      errorMessage ||=
2✔
56
        'Only software GPU is available. Set `failIfMajorPerformanceCaveat: false` to allow.';
57
    }
58

59
    // Creation failed with failIfMajorPerformanceCaveat - Try a Software GPU
60
    let softwareRenderer = false;
110✔
61
    if (!gl && allowSoftwareRenderer) {
110✔
62
      webglProps.failIfMajorPerformanceCaveat = false;
1✔
63
      gl = canvas.getContext('webgl2', webglProps);
1✔
64
      softwareRenderer = true;
1✔
65
    }
66

67
    if (!gl) {
110✔
68
      gl = canvas.getContext('webgl', {}) as WebGL2RenderingContext;
1✔
69
      if (gl) {
1!
70
        gl = null;
×
71
        errorMessage ||= 'Your browser only supports WebGL1';
×
72
      }
73
    }
74

75
    if (!gl) {
110✔
76
      errorMessage ||= 'Your browser does not support WebGL';
1✔
77
      throw new Error(`Failed to create WebGL context: ${errorMessage}`);
1✔
78
    }
79

80
    // Initialize luma.gl specific context data
81
    const luma = getWebGLContextData(gl);
109✔
82
    luma.softwareRenderer = softwareRenderer;
109✔
83

84
    // Carefully extract and wrap callbacks to prevent addEventListener from rebinding them.
85
    const {onContextLost, onContextRestored} = props;
109✔
86
    canvas.addEventListener('webglcontextlost', (event: Event) => onContextLost(event), false);
109✔
87
    canvas.addEventListener(
109✔
88
      'webglcontextrestored',
89
      (event: Event) => onContextRestored(event),
×
90
      false
91
    );
92

93
    return gl;
109✔
94
  } finally {
95
    canvas.removeEventListener('webglcontextcreationerror', onCreateError, false);
110✔
96
  }
97
}
98

99
/* TODO - can we call this asynchronously to catch the error events?
100
export async function createBrowserContextAsync(canvas: HTMLCanvasElement | OffscreenCanvas, props: ContextProps): Promise<WebGL2RenderingContext> {
101
  props = {...DEFAULT_CONTEXT_PROPS, ...props};
102

103
 // Try to extract any extra information about why context creation failed
104
 let errorMessage = null;
105
 const onCreateError = (error) => (errorMessage = error.statusMessage || errorMessage);
106
 canvas.addEventListener('webglcontextcreationerror', onCreateError, false);
107

108
 const gl = createBrowserContext(canvas, props);
109

110
 // Give the listener a chance to fire
111
 await new Promise(resolve => setTimeout(resolve, 0));
112

113
 canvas.removeEventListener('webglcontextcreationerror', onCreateError, false);
114

115
 return gl;
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