slint-ui/slint · critical

Cannot proceed without WebGL - aborting

Error message

Cannot proceed without WebGL - aborting

What it means

The FemtoVG renderer's WebGL backend panics when the browser cannot provide a WebGL context, which means Slint cannot render at all in the WASM target. Before panicking it draws the message 'Slint requires WebGL to be enabled in your browser' onto a 2D canvas so end users see the reason.

Solutions

  1. Enable hardware acceleration / WebGL in the browser (chrome://gpu, about:config webgl.disabled=false)
  2. Use a WebGL-capable environment (non-headless browser or headless with --use-gl=swiftshader)
  3. Ensure the canvas is not already bound to a '2d' context before Slint initializes

Example fix

// before (headless CI)
chromium --headless app.html
// after
chromium --headless --use-gl=swiftshader --enable-unsafe-swiftshader app.html
Defensive patterns

Strategy: fallback

Validate before calling

const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
if (!gl) { showWebglRequiredBanner(); return; }

Type guard

function hasWebGL(): boolean {
  try { const c = document.createElement('canvas');
    return !!(c.getContext('webgl') || c.getContext('experimental-webgl'));
  } catch { return false; }
}

Try / catch

// Slint panics (WASM trap); pre-check before initializing
if (!hasWebGL()) { renderStaticFallback(); } else { await initSlint(); }

Prevention

When it happens

Trigger: Running a Slint WASM app in a browser/context where canvas.getContext('webgl') returns null: WebGL disabled or blocked (e.g. hardware acceleration off, headless browser, unsupported GPU/driver), or the canvas already has a different context type.

Common situations: Firefox/Chrome with webgl.disabled=true; corporate VMs or RDP sessions without GPU; headless CI browsers without SwiftShader; embedding Slint's canvas in a page that already requested a '2d' context on the same canvas.

Related errors


AI-assisted analysis of slint-ui/slint@3a7e700487 (2026-09-16). Data as JSON: /api/errors/078a13d5c6fbaa5b. Report an issue: GitHub.

Appendix: source

Thrown at internal/renderers/femtovg/opengl.rs:147

        let gl_renderer = match femtovg::renderer::OpenGl::new_from_html_canvas(&html_canvas) {
            Ok(gl_renderer) => gl_renderer,
            Err(_) => {
                use wasm_bindgen::JsCast;

                // I don't believe that there's a way of disabling the 2D canvas.
                let context_2d = html_canvas
                    .get_context("2d")
                    .unwrap()
                    .unwrap()
                    .dyn_into::<web_sys::CanvasRenderingContext2d>()
                    .unwrap();
                context_2d.set_font("20px serif");
                // We don't know if we're rendering on dark or white background, so choose a "color" in the middle for the text.
                context_2d.set_fill_style_str("red");
                context_2d
                    .fill_text("Slint requires WebGL to be enabled in your browser", 0., 30.)
                    .unwrap();
                panic!("Cannot proceed without WebGL - aborting")
            }
        };

        let femtovg_canvas = femtovg::Canvas::new_with_text_context(
            gl_renderer,
            crate::font_cache::FONT_CACHE.with(|cache| cache.borrow().text_context.clone()),
        )
        .unwrap();

        *self.opengl_context.borrow_mut() = opengl_context;
        #[cfg(target_family = "wasm")]
        {
            *self.html_canvas.borrow_mut() = Some(html_canvas);
        }

        let canvas = Rc::new(RefCell::new(femtovg_canvas));
        renderer.reset_canvas(canvas);
        Ok(())

View on GitHub (pinned to 3a7e700487)