mirror of
https://github.com/italicsjenga/vello.git
synced 2025-01-09 12:21:31 +11:00
Display error message when WebGPU not enabled
Detect the case where creating the WebGPU surface fails, and insert a message explaning the failure into the DOM, rather than panicking.
This commit is contained in:
parent
299b47ea06
commit
e399f4792d
|
@ -45,4 +45,4 @@ android_logger = "0.13.0"
|
||||||
console_error_panic_hook = "0.1.7"
|
console_error_panic_hook = "0.1.7"
|
||||||
console_log = "0.2"
|
console_log = "0.2"
|
||||||
wasm-bindgen-futures = "0.4.33"
|
wasm-bindgen-futures = "0.4.33"
|
||||||
web-sys = "0.3.60"
|
web-sys = { version = "0.3.60", features = [ "HtmlCollection", "Text" ] }
|
||||||
|
|
|
@ -413,7 +413,7 @@ fn run(
|
||||||
let size = window.inner_size();
|
let size = window.inner_size();
|
||||||
let surface_future = render_cx.create_surface(&window, size.width, size.height);
|
let surface_future = render_cx.create_surface(&window, size.width, size.height);
|
||||||
// We need to block here, in case a Suspended event appeared
|
// We need to block here, in case a Suspended event appeared
|
||||||
let surface = pollster::block_on(surface_future);
|
let surface = pollster::block_on(surface_future).expect("Error creating surface");
|
||||||
render_state = {
|
render_state = {
|
||||||
let render_state = RenderState { window, surface };
|
let render_state = RenderState { window, surface };
|
||||||
renderers.resize_with(render_cx.devices.len(), || None);
|
renderers.resize_with(render_cx.devices.len(), || None);
|
||||||
|
@ -453,6 +453,23 @@ enum UserEvent {
|
||||||
HotReload,
|
HotReload,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
fn display_error_message() -> Option<()> {
|
||||||
|
let window = web_sys::window()?;
|
||||||
|
let document = window.document()?;
|
||||||
|
let elements = document.get_elements_by_tag_name("body");
|
||||||
|
let body = elements.item(0)?;
|
||||||
|
let canvas = body.first_child()?;
|
||||||
|
// TODO: style the notice at least a little, maybe link?
|
||||||
|
let text = document.create_text_node(
|
||||||
|
"WebGPU is not enabled. Make sure your browser is updated to
|
||||||
|
Chrome M113 or another browser compatible with WebGPU.",
|
||||||
|
);
|
||||||
|
let _ = body.insert_before(&text, Some(&canvas));
|
||||||
|
web_sys::console::log_1(&"got body".into());
|
||||||
|
Some(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn main() -> Result<()> {
|
pub fn main() -> Result<()> {
|
||||||
// TODO: initializing both env_logger and console_logger fails on wasm.
|
// TODO: initializing both env_logger and console_logger fails on wasm.
|
||||||
// Figure out a more principled approach.
|
// Figure out a more principled approach.
|
||||||
|
@ -496,9 +513,13 @@ pub fn main() -> Result<()> {
|
||||||
let surface = render_cx
|
let surface = render_cx
|
||||||
.create_surface(&window, size.width, size.height)
|
.create_surface(&window, size.width, size.height)
|
||||||
.await;
|
.await;
|
||||||
let render_state = RenderState { window, surface };
|
if let Ok(surface) = surface {
|
||||||
// No error handling here; if the event loop has finished, we don't need to send them the surface
|
let render_state = RenderState { window, surface };
|
||||||
run(event_loop, args, scenes, render_cx, render_state);
|
// No error handling here; if the event loop has finished, we don't need to send them the surface
|
||||||
|
run(event_loop, args, scenes, render_cx, render_state);
|
||||||
|
} else {
|
||||||
|
_ = display_error_message();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
18
src/util.rs
18
src/util.rs
|
@ -50,12 +50,20 @@ impl RenderContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new surface for the specified window and dimensions.
|
/// Creates a new surface for the specified window and dimensions.
|
||||||
pub async fn create_surface<W>(&mut self, window: &W, width: u32, height: u32) -> RenderSurface
|
pub async fn create_surface<W>(
|
||||||
|
&mut self,
|
||||||
|
window: &W,
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
) -> Result<RenderSurface>
|
||||||
where
|
where
|
||||||
W: HasRawWindowHandle + HasRawDisplayHandle,
|
W: HasRawWindowHandle + HasRawDisplayHandle,
|
||||||
{
|
{
|
||||||
let surface = unsafe { self.instance.create_surface(window) }.unwrap();
|
let surface = unsafe { self.instance.create_surface(window) }?;
|
||||||
let dev_id = self.device(Some(&surface)).await.unwrap();
|
let dev_id = self
|
||||||
|
.device(Some(&surface))
|
||||||
|
.await
|
||||||
|
.ok_or("Error creating device")?;
|
||||||
|
|
||||||
let device_handle = &self.devices[dev_id];
|
let device_handle = &self.devices[dev_id];
|
||||||
let capabilities = surface.get_capabilities(&device_handle.adapter);
|
let capabilities = surface.get_capabilities(&device_handle.adapter);
|
||||||
|
@ -75,12 +83,12 @@ impl RenderContext {
|
||||||
view_formats: vec![],
|
view_formats: vec![],
|
||||||
};
|
};
|
||||||
surface.configure(&self.devices[dev_id].device, &config);
|
surface.configure(&self.devices[dev_id].device, &config);
|
||||||
RenderSurface {
|
Ok(RenderSurface {
|
||||||
surface,
|
surface,
|
||||||
config,
|
config,
|
||||||
dev_id,
|
dev_id,
|
||||||
format,
|
format,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resizes the surface to the new dimensions.
|
/// Resizes the surface to the new dimensions.
|
||||||
|
|
Loading…
Reference in a new issue