a-b-street/abstreet · error · anyhow::Error

Browser doesn't support WebGL 2.0

Error message

Browser doesn't support WebGL 2.0

What it means

After get_context("webgl2") succeeds but returns None (no JS exception), the code concludes the browser does not support WebGL 2 and raises this error via ok_or. It means the environment cannot provide a WebGL 2 context, which this renderer path requires for features like tex_storage_3d.

Solutions

  1. Use a browser with WebGL 2 support (modern Chrome, Firefox, Edge, Safari 15+).
  2. Enable hardware acceleration / WebGL in browser settings.
  3. Fall back to the WebGL 1 path (webgl1_glow_context) if the app supports GL1-compatible rendering.
  4. Note that upload_gl2 requires WebGL 2, so a GL1 fallback may also restrict texture array features.

Example fix

// before
let js_webgl2_context =
    maybe_context.ok_or(anyhow!("Browser doesn't support WebGL 2.0"))?;
// after: caller falls back to WebGL 1
let glow_ctx = match webgl2_glow_context(canvas) {
    Ok(c) => c,
    Err(_) => webgl1_glow_context(canvas)?,
};
Defensive patterns

Strategy: fallback

Validate before calling

// Check WebGL 2 support in JS before loading the wasm renderer
if (!document.createElement('canvas').getContext('webgl2')) {
  showUpgradeBrowserBanner();
}

Try / catch

// Fall back to WebGL 1 when WebGL 2 is unsupported
match webgl2_glow_context(canvas) {
    Ok(c) => c,
    Err(e) if e.to_string().contains("doesn't support WebGL 2.0") => webgl1_glow_context(canvas)?,
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: setup() runs webgl2_glow_context on a browser whose canvas.get_context("webgl2") returns null — browsers without WebGL 2 (older Safari, some mobile browsers) or with WebGL 2 disabled.

Common situations: Legacy browsers or iOS Safari before WebGL 2 support; WebGL hardware-acceleration disabled; remote-desktop/headless browsers with software GL lacking webgl2; ANGLE/driver blocks.

Understand the failure class

Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.

Related errors


AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13). Data as JSON: /api/errors/e26dec3026014f83. Report an issue: GitHub.

Appendix: source

Thrown at widgetry/src/backend_glow_wasm.rs:87

        .and_then(|gl| webgl2_program(gl))
        .or_else(|err| {
            warn!(
                "failed to build WebGL 2.0 context with error: \"{}\". Trying WebGL 1.0 instead...",
                err
            );
            webgl1_glow_context(&canvas).and_then(|gl| {
                is_gl2 = false;
                webgl1_program(gl)
            })
        })
        .unwrap();

    fn webgl2_glow_context(canvas: &web_sys::HtmlCanvasElement) -> Result<glow::Context> {
        let maybe_context: Option<_> = canvas
            .get_context("webgl2")
            .map_err(|err| anyhow!("error getting context for WebGL 2.0: {:?}", err))?;
        let js_webgl2_context =
            maybe_context.ok_or(anyhow!("Browser doesn't support WebGL 2.0"))?;
        let webgl2_context = js_webgl2_context
            .dyn_into::<web_sys::WebGl2RenderingContext>()
            .map_err(|err| anyhow!("unable to cast to WebGl2RenderingContext. error: {:?}", err))?;
        Ok(glow::Context::from_webgl2_context(webgl2_context))
    }

    fn webgl1_glow_context(canvas: &web_sys::HtmlCanvasElement) -> Result<glow::Context> {
        let maybe_context: Option<_> = canvas
            .get_context("webgl")
            .map_err(|err| anyhow!("error getting context for WebGL 1.0: {:?}", err))?;
        let js_webgl1_context =
            maybe_context.ok_or(anyhow!("Browser doesn't support WebGL 1.0"))?;
        let webgl1_context = js_webgl1_context
            .dyn_into::<web_sys::WebGlRenderingContext>()
            .map_err(|err| anyhow!("unable to cast to WebGlRenderingContext. error: {:?}", err))?;
        Ok(glow::Context::from_webgl1_context(webgl1_context))
    }

View on GitHub (pinned to 0964f29315)