Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make egui work on WebGPU out of the box. #2945

Merged
merged 8 commits into from
Apr 24, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 2 additions & 11 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/eframe/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ NOTE: [`egui-winit`](../egui-winit/CHANGELOG.md), [`egui_glium`](../egui_glium/C

#### Web:
* Bug fix: modifiers keys getting stuck on alt-tab ([#2857](https://github.com/emilk/egui/pull/2857)).
* ⚠️ BREAKING: Makes WebGL for wgpu opt-in. By default wasm builds for egui will now use WebGPU. To use WebGL, you need to add `wgpu = { version = "0.16.0", features = ["webgl"] }` now to your `Cargo.toml`. ([#2945](https://github.com/emilk/egui/pull/2945))

## 0.21.3 - 2023-02-15
* Fix typing the letter 'P' on web ([#2740](https://github.com/emilk/egui/pull/2740)).
Expand Down
5 changes: 3 additions & 2 deletions crates/eframe/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ __screenshot = []

## Use [`wgpu`](https://docs.rs/wgpu) for painting (via [`egui-wgpu`](https://github.com/emilk/egui/tree/master/crates/egui-wgpu)).
## This overrides the `glow` feature.
wgpu = ["dep:wgpu", "dep:egui-wgpu", "dep:pollster"]
wgpu = ["dep:wgpu", "dep:egui-wgpu", "dep:pollster", "dep:raw-window-handle"]

# Allow crates to choose an android-activity backend via Winit
# - It's important that most applications should not have to depend on android-activity directly, and can
Expand Down Expand Up @@ -181,5 +181,6 @@ web-sys = { version = "0.3.58", features = [

# optional web:
egui-wgpu = { version = "0.21.0", path = "../egui-wgpu", optional = true } # if wgpu is used, use it without (!) winit
raw-window-handle = { version = "0.5.2", optional = true }
tts = { version = "0.25", optional = true, default-features = false }
wgpu = { version = "0.16.0", optional = true, features = ["webgl"] }
wgpu = { version = "0.16.0", optional = true }
4 changes: 2 additions & 2 deletions crates/eframe/src/epi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -498,8 +498,8 @@ impl Default for WebOptions {

#[cfg(feature = "wgpu")]
wgpu_options: egui_wgpu::WgpuConfiguration {
// WebGPU is not stable enough yet, use WebGL emulation
backends: wgpu::Backends::GL,
// Use WebGPU or WebGL. Note that WebGL needs to be opted in via a wgpu feature.
backends: wgpu::Backends::BROWSER_WEBGPU | wgpu::Backends::GL,
device_descriptor: wgpu::DeviceDescriptor {
label: Some("egui wgpu device"),
features: wgpu::Features::default(),
Expand Down
28 changes: 26 additions & 2 deletions crates/eframe/src/web/web_painter_wgpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,24 @@ use crate::WebOptions;

use super::web_painter::WebPainter;

struct EguiWebWindow(u32);

#[allow(unsafe_code)]
unsafe impl raw_window_handle::HasRawWindowHandle for EguiWebWindow {
fn raw_window_handle(&self) -> raw_window_handle::RawWindowHandle {
let mut window_handle = raw_window_handle::WebWindowHandle::empty();
window_handle.id = self.0;
raw_window_handle::RawWindowHandle::Web(window_handle)
}
}

#[allow(unsafe_code)]
unsafe impl raw_window_handle::HasRawDisplayHandle for EguiWebWindow {
fn raw_display_handle(&self) -> raw_window_handle::RawDisplayHandle {
raw_window_handle::RawDisplayHandle::Web(raw_window_handle::WebDisplayHandle::empty())
}
}

pub(crate) struct WebPainterWgpu {
canvas: HtmlCanvasElement,
canvas_id: String,
Expand Down Expand Up @@ -59,14 +77,20 @@ impl WebPainterWgpu {
pub async fn new(canvas_id: &str, options: &WebOptions) -> Result<Self, String> {
log::debug!("Creating wgpu painter");

// Workaround for https://github.com/gfx-rs/wgpu/issues/3710:
// Don't use `create_surface_from_canvas`, but `create_surface` instead!
let canvas = super::canvas_element_or_die(canvas_id);
let raw_window =
EguiWebWindow(egui::util::hash(&format!("egui on wgpu {canvas_id}")) as u32);
canvas.set_attribute("data-raw-handle", &raw_window.0.to_string());

let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
backends: options.wgpu_options.backends,
dx12_shader_compiler: Default::default(),
});
let surface = instance
.create_surface_from_canvas(canvas.clone())

#[allow(unsafe_code)]
let surface = unsafe { instance.create_surface(&raw_window) }
.map_err(|err| format!("failed to create wgpu surface: {err}"))?;

let adapter = instance
Expand Down
2 changes: 2 additions & 0 deletions crates/egui-wgpu/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ impl Default for WgpuConfiguration {
features: wgpu::Features::default(),
limits: wgpu::Limits::default(),
},
// Add GL backend, primarily because WebGPU is not stable enough yet.
// (note however, that the GL backend needs to be opted-in via a wgpu feature flag)
backends: wgpu::Backends::PRIMARY | wgpu::Backends::GL,
present_mode: wgpu::PresentMode::AutoVsync,
power_preference: wgpu::PowerPreference::HighPerformance,
Expand Down