From e8be5d59e33b3d98975509367954f61db5966993 Mon Sep 17 00:00:00 2001 From: white-axe Date: Fri, 12 Jan 2024 17:47:07 -0500 Subject: [PATCH 01/20] feat: wasm32 autobuild now builds webgl fallback binary as well --- .github/workflows/build.yml | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1cb78618..e3db9d4c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -102,12 +102,21 @@ jobs: targets: wasm32-unknown-unknown components: rust-src - name: Download and install Trunk binary - run: wget -qO- https://github.com/thedodd/trunk/releases/download/v0.17.5/trunk-x86_64-unknown-linux-gnu.tar.gz | tar -xzf- + run: wget -qO- https://github.com/thedodd/trunk/releases/download/v0.18.4/trunk-x86_64-unknown-linux-gnu.tar.gz | tar -xzf- -C ${{ runner.temp }} - name: Rust Cache uses: Swatinem/rust-cache@v2 - - run: ./trunk build --release + - name: Build luminol (Release, WebGL) + run: | + mkdir -p ${{ runner.temp }}/luminol/webgl/ + ${{ runner.temp }}/trunk build --release --features webgl + mv ${{ github.workspace }}/dist/luminol.js ${{ runner.temp }}/luminol/webgl/luminol_webgl.js + mv ${{ github.workspace }}/dist/luminol_bg.wasm ${{ runner.temp }}/luminol/webgl/luminol_webgl_bg.wasm + - name: Build luminol (Release, WebGPU) + run: | + ${{ runner.temp }}/trunk build --release + mv ${{ runner.temp }}/luminol/webgl/* ${{ github.workspace }}/dist/ - name: Upload artifact uses: actions/upload-artifact@v2 with: name: luminol-trunk - path: ${{ github.workspace }}/dist/ \ No newline at end of file + path: ${{ github.workspace }}/dist/ From ed6137060980d5667c02bec60146b53d00449639 Mon Sep 17 00:00:00 2001 From: white-axe Date: Fri, 12 Jan 2024 18:36:08 -0500 Subject: [PATCH 02/20] feat: add feature detection for secure context and Firefox private browsing --- assets/compat-test.js | 45 +++++++++++++++++++++++++++++++++++++++++++ index.html | 3 +++ 2 files changed, 48 insertions(+) create mode 100644 assets/compat-test.js diff --git a/assets/compat-test.js b/assets/compat-test.js new file mode 100644 index 00000000..23226dee --- /dev/null +++ b/assets/compat-test.js @@ -0,0 +1,45 @@ +// Copyright (C) 2023 Lily Lyons +// +// This file is part of Luminol. +// +// Luminol is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Luminol is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Luminol. If not, see . + +function error(msg) { + console.error(msg); + alert(msg); + window.stop(); + throw null; +} + +// We need a secure context for several things: +// * File System API +// * Service Workers +// * WebGPU +if (!window.isSecureContext) { + error( + "Luminol does not work with http://. " + + "Please visit the https:// version of this website." + ); +} + +// Firefox in private browsing mode doesn't work because service workers aren't +// available and we need service workers +if (window.netscape !== undefined && !window.navigator.serviceWorker) { + error( + "Due to Firefox bug #1320796, you cannot use Luminol in private " + + "browsing mode in Firefox, Tor Browser, IceCat or any other " + + "Firefox-based browser.\n\nPlease exit private browsing mode or use " + + "a different browser." + ); +} diff --git a/index.html b/index.html index edd3bc29..39588f0e 100644 --- a/index.html +++ b/index.html @@ -25,6 +25,7 @@ + @@ -128,6 +129,8 @@ + + From 75ba6356135c2610212012f82bfdb61be98b85de Mon Sep 17 00:00:00 2001 From: white-axe Date: Sat, 13 Jan 2024 13:01:36 -0500 Subject: [PATCH 03/20] fix: fix panic when `handle.requestPermission()` method doesn't exist --- crates/filesystem/src/lib.rs | 2 -- crates/filesystem/src/web/events.rs | 13 +++++++------ crates/filesystem/src/web/mod.rs | 3 +-- crates/web/src/bindings.rs | 10 +++++++--- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/crates/filesystem/src/lib.rs b/crates/filesystem/src/lib.rs index 2323f367..fb51de9f 100644 --- a/crates/filesystem/src/lib.rs +++ b/crates/filesystem/src/lib.rs @@ -65,8 +65,6 @@ pub enum Error { Wasm32FilesystemNotSupported, #[error("Invalid project folder")] InvalidProjectFolder, - #[error("Could not restore project handle from IndexedDB")] - MissingIDB, } pub use color_eyre::Result; diff --git a/crates/filesystem/src/web/events.rs b/crates/filesystem/src/web/events.rs index f648bab0..16cb707a 100644 --- a/crates/filesystem/src/web/events.rs +++ b/crates/filesystem/src/web/events.rs @@ -125,24 +125,25 @@ pub fn setup_main_thread_hooks(main_channels: super::MainChannels) { store.get_owned(&idb_key) }) .await - .ok()? + .map_err(|e| color_eyre::eyre::eyre!(format!("Failed to restore directory handle from IndexedDB: {}", e.to_string())))? .await - .ok() - .flatten()?; + .map_err(|e| color_eyre::eyre::eyre!(format!("Failed to restore directory handle from IndexedDB: {}", e.to_string())))? + .ok_or(color_eyre::eyre::eyre!("Failed to restore directory handle from IndexedDB: No directory handle found for the given IndexedDB key"))?; let dir = dir.unchecked_into::(); let key = luminol_web::bindings::request_permission(&dir) .await + .map_err(|e| color_eyre::eyre::eyre!("Failed to request permission for directory handle restored from IndexedDB: {}", e.to_string()))? .then(|| { let name = dir.name(); (dirs.insert(dir), name) - })?; + }).ok_or(color_eyre::eyre::eyre!("Failed to request permission for directory handle restored from IndexedDB"))?; idb(IdbTransactionMode::Readwrite, |store| { store.delete_owned(&idb_key) }) .await - .ok()?; - Some(key) + .map_err(|e| color_eyre::eyre::eyre!(format!("Failed to remove directory handle from IndexedDB: {}", e.to_string())))?; + Ok(key) }) .await; } diff --git a/crates/filesystem/src/web/mod.rs b/crates/filesystem/src/web/mod.rs index 45e3299e..4ff3a4c8 100644 --- a/crates/filesystem/src/web/mod.rs +++ b/crates/filesystem/src/web/mod.rs @@ -87,7 +87,7 @@ enum FileSystemCommand { oneshot::Sender>, ), DirPicker(oneshot::Sender>), - DirFromIdb(String, oneshot::Sender>), + DirFromIdb(String, oneshot::Sender>), DirToIdb(usize, String, oneshot::Sender), DirSubdir( usize, @@ -184,7 +184,6 @@ impl FileSystem { name, idb_key: Some(idb_key), }) - .ok_or(Error::MissingIDB) .wrap_err(c) } diff --git a/crates/web/src/bindings.rs b/crates/web/src/bindings.rs index 12ec599b..abc5e58a 100644 --- a/crates/web/src/bindings.rs +++ b/crates/web/src/bindings.rs @@ -29,7 +29,8 @@ extern "C" { extensions: &js_sys::Array, ) -> Result; pub fn dir_values(dir: &web_sys::FileSystemDirectoryHandle) -> js_sys::AsyncIterator; - async fn _request_permission(handle: &web_sys::FileSystemHandle) -> JsValue; + #[wasm_bindgen(catch)] + async fn _request_permission(handle: &web_sys::FileSystemHandle) -> Result; pub fn cross_origin_isolated() -> bool; } @@ -54,6 +55,9 @@ pub async fn show_file_picker( .map_err(|e| e.unchecked_into()) } -pub async fn request_permission(handle: &web_sys::FileSystemHandle) -> bool { - _request_permission(handle).await.is_truthy() +pub async fn request_permission(handle: &web_sys::FileSystemHandle) -> Result { + _request_permission(handle) + .await + .map(|o| o.is_truthy()) + .map_err(|e| e.unchecked_into()) } From 013ddf1cfe7205c5e6091254253fdb8f84a4f39d Mon Sep 17 00:00:00 2001 From: white-axe Date: Sat, 13 Jan 2024 13:24:17 -0500 Subject: [PATCH 04/20] fix: use `__FILE_SYSTEM_TOOLS__.parseHandle` if it exists --- crates/web/js/bindings.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/crates/web/js/bindings.js b/crates/web/js/bindings.js index 4489509e..d33dc542 100644 --- a/crates/web/js/bindings.js +++ b/crates/web/js/bindings.js @@ -56,7 +56,12 @@ export function dir_values(dir) { } export async function _request_permission(handle) { - return (await handle.requestPermission({ mode: 'readwrite' })) === 'granted' + if (typeof window?.__FILE_SYSTEM_TOOLS__.parseHandle === 'function') { + // If the user is using https://github.com/ichaoX/ext-file without enabling `FS_CONFIG.CLONE_ENABLED`, + // this is required to restore the `.requestPermission` method on a dir handle restored from IndexedDB + handle = window.__FILE_SYSTEM_TOOLS__.parseHandle(handle); + } + return (await handle.requestPermission({ mode: 'readwrite' })) === 'granted'; } export function cross_origin_isolated() { From 135534635254790d263fba9e08eab0d1c6e528c6 Mon Sep 17 00:00:00 2001 From: white-axe Date: Sat, 13 Jan 2024 14:48:07 -0500 Subject: [PATCH 05/20] fix: update the trunk URL in the build workflow --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e3db9d4c..44952417 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -102,7 +102,7 @@ jobs: targets: wasm32-unknown-unknown components: rust-src - name: Download and install Trunk binary - run: wget -qO- https://github.com/thedodd/trunk/releases/download/v0.18.4/trunk-x86_64-unknown-linux-gnu.tar.gz | tar -xzf- -C ${{ runner.temp }} + run: wget -qO- https://github.com/trunk-rs/trunk/releases/download/v0.18.4/trunk-x86_64-unknown-linux-gnu.tar.gz | tar -xzf- -C ${{ runner.temp }} - name: Rust Cache uses: Swatinem/rust-cache@v2 - name: Build luminol (Release, WebGL) From 3d8911a7d881b714a7ca4a318860a4968347c1b4 Mon Sep 17 00:00:00 2001 From: white-axe Date: Mon, 15 Jan 2024 13:55:08 -0500 Subject: [PATCH 06/20] fix: fix `request_permission` binding being broken in Chromium --- crates/web/js/bindings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/web/js/bindings.js b/crates/web/js/bindings.js index d33dc542..127be9d1 100644 --- a/crates/web/js/bindings.js +++ b/crates/web/js/bindings.js @@ -56,7 +56,7 @@ export function dir_values(dir) { } export async function _request_permission(handle) { - if (typeof window?.__FILE_SYSTEM_TOOLS__.parseHandle === 'function') { + if (typeof window?.__FILE_SYSTEM_TOOLS__?.parseHandle === 'function') { // If the user is using https://github.com/ichaoX/ext-file without enabling `FS_CONFIG.CLONE_ENABLED`, // this is required to restore the `.requestPermission` method on a dir handle restored from IndexedDB handle = window.__FILE_SYSTEM_TOOLS__.parseHandle(handle); From f72190063824058420582b42271ed757c6526837 Mon Sep 17 00:00:00 2001 From: white-axe Date: Tue, 30 Jan 2024 20:25:15 -0500 Subject: [PATCH 07/20] merge: update eframe and egui-wgpu from 0.24.1 to 0.25.0 --- Cargo.lock | 607 +++++++++++++++--- Cargo.toml | 1 + crates/eframe/CHANGELOG.md | 13 + crates/eframe/Cargo.toml | 11 +- crates/eframe/README.md | 2 +- crates/eframe/src/epi.rs | 25 +- crates/eframe/src/lib.rs | 24 +- crates/eframe/src/native/epi_integration.rs | 7 +- crates/eframe/src/native/glow_integration.rs | 204 +++--- crates/eframe/src/native/run.rs | 230 ++++--- crates/eframe/src/native/wgpu_integration.rs | 76 +-- crates/eframe/src/native/winit_integration.rs | 14 +- crates/eframe/src/web/app_runner.rs | 12 +- crates/eframe/src/web/events.rs | 3 + crates/eframe/src/web/input.rs | 86 +-- crates/eframe/src/web/mod.rs | 2 +- crates/eframe/src/web/text_agent.rs | 8 +- crates/eframe/src/web/web_painter_glow.rs | 5 +- crates/egui-wgpu/CHANGELOG.md | 4 + crates/egui-wgpu/Cargo.toml | 4 +- crates/egui-wgpu/README.md | 2 +- crates/egui-wgpu/src/lib.rs | 113 +++- crates/egui-wgpu/src/renderer.rs | 54 +- 23 files changed, 1024 insertions(+), 483 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ec56307b..18527049 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -45,7 +45,7 @@ checksum = "cd3b6ae1eabbfbced10e840fd3fce8a93ae84f174b3e4ba892ab7bcb42e477a7" dependencies = [ "accesskit", "accesskit_consumer", - "objc2", + "objc2 0.3.0-beta.3.patch-leaks.3", "once_cell", ] @@ -90,7 +90,7 @@ dependencies = [ "accesskit_macos", "accesskit_unix", "accesskit_windows", - "winit", + "winit 0.28.7", ] [[package]] @@ -138,6 +138,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" dependencies = [ "cfg-if", + "getrandom", "once_cell", "serde", "version_check", @@ -207,12 +208,33 @@ dependencies = [ "jni-sys", "libc", "log", - "ndk", + "ndk 0.7.0", "ndk-context", - "ndk-sys", + "ndk-sys 0.4.1+23.1.7779620", "num_enum 0.6.1", ] +[[package]] +name = "android-activity" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee91c0c2905bae44f84bfa4e044536541df26b7703fd0888deeb9060fcc44289" +dependencies = [ + "android-properties", + "bitflags 2.4.1", + "cc", + "cesu8", + "jni 0.21.1", + "jni-sys", + "libc", + "log", + "ndk 0.8.0", + "ndk-context", + "ndk-sys 0.5.0+25.2.9519653", + "num_enum 0.7.1", + "thiserror", +] + [[package]] name = "android-properties" version = "0.2.2" @@ -254,7 +276,7 @@ dependencies = [ "parking_lot", "thiserror", "winapi", - "x11rb", + "x11rb 0.12.0", ] [[package]] @@ -269,6 +291,12 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +[[package]] +name = "as-raw-xcb-connection" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" + [[package]] name = "ash" version = "0.37.3+1.3.251" @@ -728,7 +756,16 @@ version = "0.1.0-beta.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fa55741ee90902547802152aaf3f8e5248aab7e21468089560d4c8840561146" dependencies = [ - "objc-sys", + "objc-sys 0.2.0-beta.2", +] + +[[package]] +name = "block-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae85a0696e7ea3b835a453750bf002770776609115e6d25c6d2ff28a8200f7e7" +dependencies = [ + "objc-sys 0.3.2", ] [[package]] @@ -737,8 +774,18 @@ version = "0.2.0-alpha.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8dd9e63c1744f755c2f60332b88de39d341e5e86239014ad839bd71c106dec42" dependencies = [ - "block-sys", - "objc2-encode", + "block-sys 0.1.0-beta.1", + "objc2-encode 2.0.0-pre.2", +] + +[[package]] +name = "block2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15b55663a85f33501257357e6421bb33e769d5c9ffb5ba0921c975a123e35e68" +dependencies = [ + "block-sys 0.2.1", + "objc2 0.4.1", ] [[package]] @@ -819,6 +866,32 @@ dependencies = [ "vec_map", ] +[[package]] +name = "calloop" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fba7adb4dd5aa98e5553510223000e7148f621165ec5f9acd7113f6ca4995298" +dependencies = [ + "bitflags 2.4.1", + "log", + "polling 3.3.1", + "rustix 0.38.26", + "slab", + "thiserror", +] + +[[package]] +name = "calloop-wayland-source" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f0ea9b9476c7fad82841a8dbb380e2eae480c21910feba80725b46931ed8f02" +dependencies = [ + "calloop 0.12.4", + "rustix 0.38.26", + "wayland-backend", + "wayland-client 0.31.2", +] + [[package]] name = "camino" version = "1.1.6" @@ -919,16 +992,16 @@ dependencies = [ [[package]] name = "cocoa" -version = "0.24.1" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f425db7937052c684daec3bd6375c8abe2d146dca4b8b143d6db777c39138f3a" +checksum = "f6140449f97a6e97f9511815c5632d84c8aacf8ac271ad77c559218161a1373c" dependencies = [ "bitflags 1.3.2", "block", "cocoa-foundation", "core-foundation", - "core-graphics", - "foreign-types 0.3.2", + "core-graphics 0.23.1", + "foreign-types 0.5.0", "libc", "objc", ] @@ -1064,6 +1137,19 @@ dependencies = [ "libc", ] +[[package]] +name = "core-graphics" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "970a29baf4110c26fedbc7f82107d42c23f7e88e404c4577ed73fe99ff85a212" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-graphics-types", + "foreign-types 0.5.0", + "libc", +] + [[package]] name = "core-graphics-types" version = "0.1.3" @@ -1108,7 +1194,7 @@ dependencies = [ "js-sys", "libc", "mach2", - "ndk", + "ndk 0.7.0", "ndk-context", "oboe", "once_cell", @@ -1230,6 +1316,12 @@ dependencies = [ "phf 0.11.2", ] +[[package]] +name = "cursor-icon" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991" + [[package]] name = "d3d12" version = "0.7.0" @@ -1474,12 +1566,12 @@ dependencies = [ "egui", "log", "puffin", - "raw-window-handle", + "raw-window-handle 0.5.2", "serde", "smithay-clipboard", "web-time", "webbrowser", - "winit", + "winit 0.28.7", ] [[package]] @@ -1506,7 +1598,7 @@ dependencies = [ "mime_guess2", "resvg", "serde", - "tiny-skia", + "tiny-skia 0.8.4", "usvg", ] @@ -2071,6 +2163,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "gethostname" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818" +dependencies = [ + "libc", + "windows-targets 0.48.5", +] + [[package]] name = "getrandom" version = "0.2.11" @@ -2207,68 +2309,60 @@ dependencies = [ [[package]] name = "glutin" -version = "0.30.10" +version = "0.31.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc93b03242719b8ad39fb26ed2b01737144ce7bd4bfc7adadcef806596760fe" +checksum = "005459a22af86adc706522d78d360101118e2638ec21df3852fcc626e0dbb212" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.1", "cfg_aliases", "cgl", "core-foundation", "dispatch", "glutin_egl_sys", "glutin_glx_sys", - "glutin_wgl_sys 0.4.0", - "libloading 0.7.4", - "objc2", + "glutin_wgl_sys", + "icrate", + "libloading 0.8.1", + "objc2 0.4.1", "once_cell", - "raw-window-handle", - "wayland-sys 0.30.1", - "windows-sys 0.45.0", + "raw-window-handle 0.5.2", + "wayland-sys 0.31.1", + "windows-sys 0.48.0", "x11-dl", ] [[package]] name = "glutin-winit" -version = "0.3.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "629a873fc04062830bfe8f97c03773bcd7b371e23bcc465d0a61448cd1588fa4" +checksum = "1ebcdfba24f73b8412c5181e56f092b5eff16671c514ce896b258a0a64bd7735" dependencies = [ "cfg_aliases", "glutin", - "raw-window-handle", - "winit", + "raw-window-handle 0.5.2", + "winit 0.29.10", ] [[package]] name = "glutin_egl_sys" -version = "0.5.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af784eb26c5a68ec85391268e074f0aa618c096eadb5d6330b0911cf34fe57c5" +checksum = "77cc5623f5309ef433c3dd4ca1223195347fe62c413da8e2fdd0eb76db2d9bcd" dependencies = [ "gl_generator", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] name = "glutin_glx_sys" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b53cb5fe568964aa066a3ba91eac5ecbac869fb0842cd0dc9e412434f1a1494" +checksum = "a165fd686c10dcc2d45380b35796e577eacfd43d4660ee741ec8ebe2201b3b4f" dependencies = [ "gl_generator", "x11-dl", ] -[[package]] -name = "glutin_wgl_sys" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef89398e90033fc6bc65e9bd42fd29bbbfd483bda5b56dc5562f455550618165" -dependencies = [ - "gl_generator", -] - [[package]] name = "glutin_wgl_sys" version = "0.5.0" @@ -2541,6 +2635,17 @@ dependencies = [ "tokio-native-tls", ] +[[package]] +name = "icrate" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d3aaff8a54577104bafdf686ff18565c3b6903ca5782a2026ef06e2c7aa319" +dependencies = [ + "block2 0.3.0", + "dispatch", + "objc2 0.4.1", +] + [[package]] name = "idna" version = "0.5.0" @@ -3130,7 +3235,7 @@ dependencies = [ "egui-winit", "egui_glow", "flume", - "glow 0.12.3", + "glow 0.13.0", "glutin", "glutin-winit", "image 0.24.7", @@ -3146,7 +3251,7 @@ dependencies = [ "pollster", "portable-atomic", "puffin", - "raw-window-handle", + "raw-window-handle 0.5.2", "ron", "serde", "static_assertions", @@ -3156,7 +3261,7 @@ dependencies = [ "web-sys", "wgpu", "winapi", - "winit", + "winit 0.29.10", ] [[package]] @@ -3172,7 +3277,7 @@ dependencies = [ "thiserror", "type-map", "wgpu", - "winit", + "winit 0.29.10", ] [[package]] @@ -3402,6 +3507,15 @@ dependencies = [ "libc", ] +[[package]] +name = "memmap2" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45fd3a57831bf88bc63f8cebc0cf956116276e97fef3966103e96416209f7c92" +dependencies = [ + "libc", +] + [[package]] name = "memmem" version = "0.1.1" @@ -3603,9 +3717,25 @@ checksum = "451422b7e4718271c8b5b3aadf5adedba43dc76312454b387e98fae0fc951aa0" dependencies = [ "bitflags 1.3.2", "jni-sys", - "ndk-sys", + "ndk-sys 0.4.1+23.1.7779620", "num_enum 0.5.11", - "raw-window-handle", + "raw-window-handle 0.5.2", + "thiserror", +] + +[[package]] +name = "ndk" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2076a31b7010b17a38c01907c45b945e8f11495ee4dd588309718901b1f7a5b7" +dependencies = [ + "bitflags 2.4.1", + "jni-sys", + "log", + "ndk-sys 0.5.0+25.2.9519653", + "num_enum 0.7.1", + "raw-window-handle 0.5.2", + "raw-window-handle 0.6.0", "thiserror", ] @@ -3624,6 +3754,15 @@ dependencies = [ "jni-sys", ] +[[package]] +name = "ndk-sys" +version = "0.5.0+25.2.9519653" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691" +dependencies = [ + "jni-sys", +] + [[package]] name = "new_debug_unreachable" version = "1.0.4" @@ -3848,15 +3987,31 @@ version = "0.2.0-beta.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b9834c1e95694a05a828b59f55fa2afec6288359cda67146126b3f90a55d7" +[[package]] +name = "objc-sys" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c71324e4180d0899963fc83d9d241ac39e699609fc1025a850aadac8257459" + [[package]] name = "objc2" version = "0.3.0-beta.3.patch-leaks.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e01640f9f2cb1220bbe80325e179e532cb3379ebcd1bf2279d703c19fe3a468" dependencies = [ - "block2", - "objc-sys", - "objc2-encode", + "block2 0.2.0-alpha.6", + "objc-sys 0.2.0-beta.2", + "objc2-encode 2.0.0-pre.2", +] + +[[package]] +name = "objc2" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "559c5a40fdd30eb5e344fbceacf7595a81e242529fb4e21cf5f43fb4f11ff98d" +dependencies = [ + "objc-sys 0.3.2", + "objc2-encode 3.0.0", ] [[package]] @@ -3865,9 +4020,15 @@ version = "2.0.0-pre.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abfcac41015b00a120608fdaa6938c44cb983fee294351cc4bac7638b4e50512" dependencies = [ - "objc-sys", + "objc-sys 0.2.0-beta.2", ] +[[package]] +name = "objc2-encode" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d079845b37af429bfe5dfa76e6d087d788031045b25cfc6fd898486fd9847666" + [[package]] name = "objc_exception" version = "0.1.2" @@ -3902,7 +4063,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8868cc237ee02e2d9618539a23a8d228b9bb3fc2e7a5b11eed3831de77c395d0" dependencies = [ "jni 0.20.0", - "ndk", + "ndk 0.7.0", "ndk-context", "num-derive", "num-traits", @@ -4571,6 +4732,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" +[[package]] +name = "raw-window-handle" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42a9830a0e1b9fb145ebb365b8bc4ccd75f290f98c0247deafbbe2c75cefb544" + [[package]] name = "rayon" version = "1.8.0" @@ -4730,7 +4897,7 @@ dependencies = [ "pico-args", "rgb", "svgtypes", - "tiny-skia", + "tiny-skia 0.8.4", "usvg", ] @@ -4750,7 +4917,7 @@ dependencies = [ "objc", "objc-foundation", "objc_id", - "raw-window-handle", + "raw-window-handle 0.5.2", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -4920,9 +5087,22 @@ checksum = "cda4e97be1fd174ccc2aae81c8b694e803fa99b34e8fd0f057a9d70698e3ed09" dependencies = [ "ab_glyph", "log", - "memmap2", - "smithay-client-toolkit", - "tiny-skia", + "memmap2 0.5.10", + "smithay-client-toolkit 0.16.1", + "tiny-skia 0.8.4", +] + +[[package]] +name = "sctk-adwaita" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82b2eaf3a5b264a521b988b2e73042e742df700c4f962cde845d1541adb46550" +dependencies = [ + "ab_glyph", + "log", + "memmap2 0.9.3", + "smithay-client-toolkit 0.18.0", + "tiny-skia 0.11.3", ] [[package]] @@ -5215,16 +5395,41 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "870427e30b8f2cbe64bf43ec4b86e88fe39b0a84b3f15efd9c9c2d020bc86eb9" dependencies = [ "bitflags 1.3.2", - "calloop", + "calloop 0.10.6", "dlib", "lazy_static", "log", - "memmap2", + "memmap2 0.5.10", "nix 0.24.3", "pkg-config", - "wayland-client", - "wayland-cursor", - "wayland-protocols", + "wayland-client 0.29.5", + "wayland-cursor 0.29.5", + "wayland-protocols 0.29.5", +] + +[[package]] +name = "smithay-client-toolkit" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60e3d9941fa3bacf7c2bf4b065304faa14164151254cd16ce1b1bc8fc381600f" +dependencies = [ + "bitflags 2.4.1", + "calloop 0.12.4", + "calloop-wayland-source", + "cursor-icon", + "libc", + "log", + "memmap2 0.9.3", + "rustix 0.38.26", + "thiserror", + "wayland-backend", + "wayland-client 0.31.2", + "wayland-csd-frame", + "wayland-cursor 0.31.1", + "wayland-protocols 0.31.2", + "wayland-protocols-wlr", + "wayland-scanner 0.31.1", + "xkeysym", ] [[package]] @@ -5233,8 +5438,17 @@ version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0a345c870a1fae0b1b779085e81b51e614767c239e93503588e54c5b17f4b0e8" dependencies = [ - "smithay-client-toolkit", - "wayland-client", + "smithay-client-toolkit 0.16.1", + "wayland-client 0.29.5", +] + +[[package]] +name = "smol_str" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6845563ada680337a52d43bb0b29f396f2d911616f6573012645b9e3d048a49" +dependencies = [ + "serde", ] [[package]] @@ -5692,7 +5906,21 @@ dependencies = [ "bytemuck", "cfg-if", "png", - "tiny-skia-path", + "tiny-skia-path 0.8.4", +] + +[[package]] +name = "tiny-skia" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6a067b809476893fce6a254cf285850ff69c847e6cfbade6a20b655b6c7e80d" +dependencies = [ + "arrayref", + "arrayvec", + "bytemuck", + "cfg-if", + "log", + "tiny-skia-path 0.11.3", ] [[package]] @@ -5706,6 +5934,17 @@ dependencies = [ "strict-num", ] +[[package]] +name = "tiny-skia-path" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de35e8a90052baaaf61f171680ac2f8e925a1e43ea9d2e3a00514772250e541" +dependencies = [ + "arrayref", + "bytemuck", + "strict-num", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -6233,6 +6472,20 @@ version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" +[[package]] +name = "wayland-backend" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d50fa61ce90d76474c87f5fc002828d81b32677340112b4ef08079a9d459a40" +dependencies = [ + "cc", + "downcast-rs", + "rustix 0.38.26", + "scoped-tls", + "smallvec", + "wayland-sys 0.31.1", +] + [[package]] name = "wayland-client" version = "0.29.5" @@ -6245,10 +6498,22 @@ dependencies = [ "nix 0.24.3", "scoped-tls", "wayland-commons", - "wayland-scanner", + "wayland-scanner 0.29.5", "wayland-sys 0.29.5", ] +[[package]] +name = "wayland-client" +version = "0.31.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82fb96ee935c2cea6668ccb470fb7771f6215d1691746c2d896b447a00ad3f1f" +dependencies = [ + "bitflags 2.4.1", + "rustix 0.38.26", + "wayland-backend", + "wayland-scanner 0.31.1", +] + [[package]] name = "wayland-commons" version = "0.29.5" @@ -6261,6 +6526,17 @@ dependencies = [ "wayland-sys 0.29.5", ] +[[package]] +name = "wayland-csd-frame" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" +dependencies = [ + "bitflags 2.4.1", + "cursor-icon", + "wayland-backend", +] + [[package]] name = "wayland-cursor" version = "0.29.5" @@ -6268,7 +6544,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6865c6b66f13d6257bef1cd40cbfe8ef2f150fb8ebbdb1e8e873455931377661" dependencies = [ "nix 0.24.3", - "wayland-client", + "wayland-client 0.29.5", + "xcursor", +] + +[[package]] +name = "wayland-cursor" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71ce5fa868dd13d11a0d04c5e2e65726d0897be8de247c0c5a65886e283231ba" +dependencies = [ + "rustix 0.38.26", + "wayland-client 0.31.2", "xcursor", ] @@ -6279,9 +6566,47 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b950621f9354b322ee817a23474e479b34be96c2e909c14f7bc0100e9a970bc6" dependencies = [ "bitflags 1.3.2", - "wayland-client", + "wayland-client 0.29.5", "wayland-commons", - "wayland-scanner", + "wayland-scanner 0.29.5", +] + +[[package]] +name = "wayland-protocols" +version = "0.31.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f81f365b8b4a97f422ac0e8737c438024b5951734506b0e1d775c73030561f4" +dependencies = [ + "bitflags 2.4.1", + "wayland-backend", + "wayland-client 0.31.2", + "wayland-scanner 0.31.1", +] + +[[package]] +name = "wayland-protocols-plasma" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23803551115ff9ea9bce586860c5c5a971e360825a0309264102a9495a5ff479" +dependencies = [ + "bitflags 2.4.1", + "wayland-backend", + "wayland-client 0.31.2", + "wayland-protocols 0.31.2", + "wayland-scanner 0.31.1", +] + +[[package]] +name = "wayland-protocols-wlr" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad1f61b76b6c2d8742e10f9ba5c3737f6530b4c243132c2a2ccc8aa96fe25cd6" +dependencies = [ + "bitflags 2.4.1", + "wayland-backend", + "wayland-client 0.31.2", + "wayland-protocols 0.31.2", + "wayland-scanner 0.31.1", ] [[package]] @@ -6295,6 +6620,17 @@ dependencies = [ "xml-rs", ] +[[package]] +name = "wayland-scanner" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63b3a62929287001986fb58c789dce9b67604a397c15c611ad9f747300b6c283" +dependencies = [ + "proc-macro2", + "quick-xml", + "quote", +] + [[package]] name = "wayland-sys" version = "0.29.5" @@ -6308,13 +6644,13 @@ dependencies = [ [[package]] name = "wayland-sys" -version = "0.30.1" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b2a02ac608e07132978689a6f9bf4214949c85998c247abadd4f4129b1aa06" +checksum = "15a0c8eaff5216d07f226cb7a549159267f3467b289d9a2e52fd3ef5aae2b7af" dependencies = [ "dlib", - "lazy_static", "log", + "once_cell", "pkg-config", ] @@ -6350,7 +6686,7 @@ dependencies = [ "log", "ndk-context", "objc", - "raw-window-handle", + "raw-window-handle 0.5.2", "url", "web-sys", ] @@ -6457,7 +6793,7 @@ dependencies = [ "naga", "parking_lot", "profiling", - "raw-window-handle", + "raw-window-handle 0.5.2", "smallvec", "static_assertions", "wasm-bindgen", @@ -6482,7 +6818,7 @@ dependencies = [ "naga", "parking_lot", "profiling", - "raw-window-handle", + "raw-window-handle 0.5.2", "rustc-hash", "smallvec", "thiserror", @@ -6506,7 +6842,7 @@ dependencies = [ "core-graphics-types", "d3d12", "glow 0.13.0", - "glutin_wgl_sys 0.5.0", + "glutin_wgl_sys", "gpu-alloc", "gpu-allocator", "gpu-descriptor", @@ -6523,7 +6859,7 @@ dependencies = [ "parking_lot", "profiling", "range-alloc", - "raw-window-handle", + "raw-window-handle 0.5.2", "renderdoc-sys", "rustc-hash", "smallvec", @@ -6856,35 +7192,84 @@ version = "0.28.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9596d90b45384f5281384ab204224876e8e8bf7d58366d9b795ad99aa9894b94" dependencies = [ - "android-activity", + "android-activity 0.4.3", "bitflags 1.3.2", "cfg_aliases", "core-foundation", - "core-graphics", + "core-graphics 0.22.3", "dispatch", "instant", "libc", "log", "mio", - "ndk", - "objc2", + "ndk 0.7.0", + "objc2 0.3.0-beta.3.patch-leaks.3", "once_cell", "orbclient", "percent-encoding", - "raw-window-handle", + "raw-window-handle 0.5.2", "redox_syscall 0.3.5", - "sctk-adwaita", - "smithay-client-toolkit", + "sctk-adwaita 0.5.4", + "smithay-client-toolkit 0.16.1", "wasm-bindgen", - "wayland-client", + "wayland-client 0.29.5", "wayland-commons", - "wayland-protocols", - "wayland-scanner", + "wayland-protocols 0.29.5", + "wayland-scanner 0.29.5", "web-sys", "windows-sys 0.45.0", "x11-dl", ] +[[package]] +name = "winit" +version = "0.29.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c824f11941eeae66ec71111cc2674373c772f482b58939bb4066b642aa2ffcf" +dependencies = [ + "ahash 0.8.6", + "android-activity 0.5.2", + "atomic-waker", + "bitflags 2.4.1", + "bytemuck", + "calloop 0.12.4", + "cfg_aliases", + "core-foundation", + "core-graphics 0.23.1", + "cursor-icon", + "icrate", + "js-sys", + "libc", + "log", + "memmap2 0.9.3", + "ndk 0.8.0", + "ndk-sys 0.5.0+25.2.9519653", + "objc2 0.4.1", + "once_cell", + "orbclient", + "percent-encoding", + "raw-window-handle 0.5.2", + "raw-window-handle 0.6.0", + "redox_syscall 0.3.5", + "rustix 0.38.26", + "sctk-adwaita 0.8.1", + "smithay-client-toolkit 0.18.0", + "smol_str", + "unicode-segmentation", + "wasm-bindgen", + "wasm-bindgen-futures", + "wayland-backend", + "wayland-client 0.31.2", + "wayland-protocols 0.31.2", + "wayland-protocols-plasma", + "web-sys", + "web-time", + "windows-sys 0.48.0", + "x11-dl", + "x11rb 0.13.0", + "xkbcommon-dl", +] + [[package]] name = "winnow" version = "0.5.19" @@ -6949,11 +7334,26 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1641b26d4dec61337c35a1b1aaf9e3cba8f46f0b43636c609ab0291a648040a" dependencies = [ - "gethostname", + "gethostname 0.3.0", "nix 0.26.4", "winapi", "winapi-wsapoll", - "x11rb-protocol", + "x11rb-protocol 0.12.0", +] + +[[package]] +name = "x11rb" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8f25ead8c7e4cba123243a6367da5d3990e0d3affa708ea19dce96356bd9f1a" +dependencies = [ + "as-raw-xcb-connection", + "gethostname 0.4.3", + "libc", + "libloading 0.8.1", + "once_cell", + "rustix 0.38.26", + "x11rb-protocol 0.13.0", ] [[package]] @@ -6965,6 +7365,12 @@ dependencies = [ "nix 0.26.4", ] +[[package]] +name = "x11rb-protocol" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e63e71c4b8bd9ffec2c963173a4dc4cbde9ee96961d4fcb4429db9929b606c34" + [[package]] name = "xcursor" version = "0.3.4" @@ -6984,6 +7390,25 @@ dependencies = [ "winapi", ] +[[package]] +name = "xkbcommon-dl" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6924668544c48c0133152e7eec86d644a056ca3d09275eb8d5cdb9855f9d8699" +dependencies = [ + "bitflags 2.4.1", + "dlib", + "log", + "once_cell", + "xkeysym", +] + +[[package]] +name = "xkeysym" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "054a8e68b76250b253f671d1268cb7f1ae089ec35e195b2efb2a4e9a836d0621" + [[package]] name = "xml-rs" version = "0.8.19" diff --git a/Cargo.toml b/Cargo.toml index a37f9af1..ff412968 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -100,6 +100,7 @@ bitflags = "2.4.0" color-eyre = "0.6.2" puffin = "0.18" raw-window-handle = "0.5.0" +glow = "0.13" parking_lot = { version = "0.12.1", features = [ "nightly", # This is required for parking_lot to work properly in WebAssembly builds with atomics support diff --git a/crates/eframe/CHANGELOG.md b/crates/eframe/CHANGELOG.md index 238ed4f8..171cf5db 100644 --- a/crates/eframe/CHANGELOG.md +++ b/crates/eframe/CHANGELOG.md @@ -7,6 +7,19 @@ This file is updated upon each release. Changes since the last release can be found at or by running the `scripts/generate_changelog.py` script. +## 0.25.0 - 2024-01-08 +* If both `glow` and `wgpu` features are enabled, default to `wgpu` [#3717](https://github.com/emilk/egui/pull/3717) + +#### Desktop/Native: +* Update to winit 0.29 [#3649](https://github.com/emilk/egui/pull/3649) (thanks [@fornwall](https://github.com/fornwall)!) +* Make glow `Send + Sync` again [#3646](https://github.com/emilk/egui/pull/3646) (thanks [@surban](https://github.com/surban)!) +* Bug fix: framebuffer clear when using glow with multi-viewports [#3713](https://github.com/emilk/egui/pull/3713) +* Fix: Let `accesskit` process window events [#3733](https://github.com/emilk/egui/pull/3733) (thanks [@DataTriny](https://github.com/DataTriny)!) + +#### Web: +* Fix building the `wasm32` docs for `docs.rs` [#3757](https://github.com/emilk/egui/pull/3757) + + ## 0.24.1 - 2023-11-30 #### Desktop/Native: * Fix window flashing white on launch [#3631](https://github.com/emilk/egui/pull/3631) (thanks [@zeozeozeo](https://github.com/zeozeozeo)!) diff --git a/crates/eframe/Cargo.toml b/crates/eframe/Cargo.toml index 3753d050..e4852151 100644 --- a/crates/eframe/Cargo.toml +++ b/crates/eframe/Cargo.toml @@ -21,6 +21,7 @@ include = [ [package.metadata.docs.rs] all-features = true +rustc-args = ["--cfg=web_sys_unstable_apis"] targets = ["x86_64-unknown-linux-gnu", "wasm32-unknown-unknown"] [lib] @@ -116,7 +117,7 @@ thiserror.workspace = true document-features = { version = "0.2", optional = true } egui_glow = { workspace = true, optional = true } -glow = { version = "0.12", optional = true } +glow = { workspace = true, optional = true } ron = { workspace = true, optional = true, features = ["integer128"] } serde = { version = "1", optional = true, features = ["derive"] } @@ -131,7 +132,7 @@ image = { version = "0.24", default-features = false, features = [ "png", ] } # Needed for app icon raw-window-handle.workspace = true -winit = { version = "0.28.1", default-features = false } +winit = { version = "0.29.4", default-features = false, features = ["rwh_05"] } # optional native: directories-next = { version = "2", optional = true } @@ -142,14 +143,14 @@ pollster = { version = "0.3", optional = true } # needed for wgpu # we can expose these to user so that they can select which backends they want to enable to avoid compiling useless deps. # this can be done at the same time we expose x11/wayland features of winit crate. -glutin = { version = "0.30", optional = true } -glutin-winit = { version = "0.3.0", optional = true } +glutin = { version = "0.31", optional = true } +glutin-winit = { version = "0.4", optional = true } puffin = { workspace = true, optional = true } wgpu = { workspace = true, optional = true } # mac: [target.'cfg(any(target_os = "macos"))'.dependencies] -cocoa = "0.24.1" # Stuck on old version until we update to winit 0.29 +cocoa = "0.25.0" objc = "0.2.7" # windows: diff --git a/crates/eframe/README.md b/crates/eframe/README.md index 66b693c5..f8ffb330 100644 --- a/crates/eframe/README.md +++ b/crates/eframe/README.md @@ -1,5 +1,5 @@ > [!IMPORTANT] -> luminol-eframe is currently based on emilk/egui@0.24.1 +> luminol-eframe is currently based on emilk/egui@0.25.0 > [!NOTE] > This is Luminol's modified version of eframe. The original version is dual-licensed under MIT and Apache 2.0. diff --git a/crates/eframe/src/epi.rs b/crates/eframe/src/epi.rs index a788e569..3abfb298 100644 --- a/crates/eframe/src/epi.rs +++ b/crates/eframe/src/epi.rs @@ -64,7 +64,7 @@ pub struct CreationContext<'s> { /// /// Only available when compiling with the `glow` feature and using [`Renderer::Glow`]. #[cfg(feature = "glow")] - pub gl: Option>, + pub gl: Option>, /// The underlying WGPU render state. /// @@ -217,7 +217,7 @@ pub enum HardwareAcceleration { /// Options controlling the behavior of a native window. /// -/// Addintional windows can be opened using (egui viewports)[`egui::viewport`]. +/// Additional windows can be opened using (egui viewports)[`egui::viewport`]. /// /// Set the window title and size using [`Self::viewport`]. /// @@ -298,7 +298,7 @@ pub struct NativeOptions { /// /// This feature was introduced in . /// - /// When `true`, [`winit::platform::run_return::EventLoopExtRunReturn::run_return`] is used. + /// When `true`, [`winit::platform::run_on_demand::EventLoopExtRunOnDemand`] is used. /// When `false`, [`winit::event_loop::EventLoop::run`] is used. pub run_and_return: bool, @@ -526,16 +526,23 @@ pub enum Renderer { #[cfg(any(feature = "glow", feature = "wgpu"))] impl Default for Renderer { fn default() -> Self { + #[cfg(not(feature = "glow"))] + #[cfg(not(feature = "wgpu"))] + compile_error!("eframe: you must enable at least one of the rendering backend features: 'glow' or 'wgpu'"); + #[cfg(feature = "glow")] + #[cfg(not(feature = "wgpu"))] return Self::Glow; #[cfg(not(feature = "glow"))] #[cfg(feature = "wgpu")] return Self::Wgpu; - #[cfg(not(feature = "glow"))] - #[cfg(not(feature = "wgpu"))] - compile_error!("eframe: you must enable at least one of the rendering backend features: 'glow' or 'wgpu'"); + // By default, only the `glow` feature is enabled, so if the user added `wgpu` to the feature list + // they probably wanted to use wgpu: + #[cfg(feature = "glow")] + #[cfg(feature = "wgpu")] + return Self::Wgpu; } } @@ -574,7 +581,7 @@ impl std::str::FromStr for Renderer { /// Represents the surroundings of your app. /// /// It provides methods to inspect the surroundings (are we on the web?), -/// allocate textures, and change settings (e.g. window size). +/// access to persistent storage, and access to the rendering backend. pub struct Frame { /// Information about the integration. pub(crate) info: IntegrationInfo, @@ -584,7 +591,7 @@ pub struct Frame { /// A reference to the underlying [`glow`] (OpenGL) context. #[cfg(feature = "glow")] - pub(crate) gl: Option>, + pub(crate) gl: Option>, /// Can be used to manage GPU resources for custom rendering with WGPU using [`egui::PaintCallback`]s. #[cfg(feature = "wgpu")] @@ -656,7 +663,7 @@ impl Frame { /// To get a [`glow`] context you need to compile with the `glow` feature flag, /// and run eframe using [`Renderer::Glow`]. #[cfg(feature = "glow")] - pub fn gl(&self) -> Option<&std::rc::Rc> { + pub fn gl(&self) -> Option<&std::sync::Arc> { self.gl.as_ref() } diff --git a/crates/eframe/src/lib.rs b/crates/eframe/src/lib.rs index c95fbe88..fa97526f 100644 --- a/crates/eframe/src/lib.rs +++ b/crates/eframe/src/lib.rs @@ -9,6 +9,21 @@ //! In short, you implement [`App`] (especially [`App::update`]) and then //! call [`crate::run_native`] from your `main.rs`, and/or use `luminol_eframe::WebRunner` from your `lib.rs`. //! +//! ## Compiling for web +//! To get copy-paste working on web, you need to compile with +//! `export RUSTFLAGS=--cfg=web_sys_unstable_apis`. +//! +//! You need to install the `wasm32` target with `rustup target add wasm32-unknown-unknown`. +//! +//! Build the `.wasm` using `cargo build --target wasm32-unknown-unknown` +//! and then use [`wasm-bindgen`](https://github.com/rustwasm/wasm-bindgen) to generate the JavaScript glue code. +//! +//! See the [`eframe_template` repository](https://github.com/emilk/eframe_template/) for more. +//! +//! ## Simplified usage +//! If your app is only for native, and you don't need advanced features like state persistence, +//! then you can use the simpler function [`run_simple_native`]. +//! //! ## Usage, native: //! ``` no_run //! use luminol_eframe::egui; @@ -114,10 +129,6 @@ //! } //! ``` //! -//! ## Simplified usage -//! If your app is only for native, and you don't need advanced features like state persistence, -//! then you can use the simpler function [`run_simple_native`]. -//! //! ## Feature flags #![cfg_attr(feature = "document-features", doc = document_features::document_features!())] //! @@ -327,6 +338,11 @@ pub enum Error { #[error("winit error: {0}")] Winit(#[from] winit::error::OsError), + /// An error from [`winit::event_loop::EventLoop`]. + #[cfg(not(target_arch = "wasm32"))] + #[error("winit EventLoopError: {0}")] + WinitEventLoop(#[from] winit::error::EventLoopError), + /// An error from [`glutin`] when using [`glow`]. #[cfg(all(feature = "glow", not(target_arch = "wasm32")))] #[error("glutin error: {0}")] diff --git a/crates/eframe/src/native/epi_integration.rs b/crates/eframe/src/native/epi_integration.rs index 4899892f..4f017536 100644 --- a/crates/eframe/src/native/epi_integration.rs +++ b/crates/eframe/src/native/epi_integration.rs @@ -152,7 +152,7 @@ impl EpiIntegration { app_name: &str, native_options: &crate::NativeOptions, storage: Option>, - #[cfg(feature = "glow")] gl: Option>, + #[cfg(feature = "glow")] gl: Option>, #[cfg(feature = "wgpu")] wgpu_render_state: Option, ) -> Self { let frame = epi::Frame { @@ -231,7 +231,7 @@ impl EpiIntegration { &mut self, window: &winit::window::Window, egui_winit: &mut egui_winit::State, - event: &winit::event::WindowEvent<'_>, + event: &winit::event::WindowEvent, ) -> EventResponse { crate::profile_function!(egui_winit::short_window_event_description(event)); @@ -255,8 +255,7 @@ impl EpiIntegration { _ => {} } - egui_winit.update_pixels_per_point(&self.egui_ctx, window); - egui_winit.on_window_event(&self.egui_ctx, event) + egui_winit.on_window_event(window, event) } pub fn pre_update(&mut self) { diff --git a/crates/eframe/src/native/glow_integration.rs b/crates/eframe/src/native/glow_integration.rs index 6bf7336a..537e7394 100644 --- a/crates/eframe/src/native/glow_integration.rs +++ b/crates/eframe/src/native/glow_integration.rs @@ -1,8 +1,19 @@ +//! Note that this file contains code very similar to [`wgpu_integration`]. +//! When making changes to one you often also want to apply it to the other. +//! +//! This is also very complex code, and not very pretty. +//! There is a bunch of improvements we could do, +//! like removing a bunch of `unwraps`. + +#![allow(clippy::arc_with_non_send_sync)] // glow::Context was accidentally non-Sync in glow 0.13, but that will be fixed in future releases of glow: https://github.com/grovesNL/glow/commit/c4a5f7151b9b4bbb380faa06ec27415235d1bf7e + use std::{cell::RefCell, rc::Rc, sync::Arc, time::Instant}; use glutin::{ + config::GlConfig, + context::NotCurrentGlContext, display::GetGlDisplay, - prelude::{GlDisplay, NotCurrentGlContextSurfaceAccessor, PossiblyCurrentGlContext}, + prelude::{GlDisplay, PossiblyCurrentGlContext}, surface::GlSurface, }; use raw_window_handle::{HasRawDisplayHandle as _, HasRawWindowHandle as _}; @@ -112,6 +123,8 @@ struct Viewport { /// None for immediate viewports. viewport_ui_cb: Option>, + // These three live and die together. + // TODO(emilk): clump them together into one struct! gl_surface: Option>, window: Option>, egui_winit: Option, @@ -160,17 +173,17 @@ impl GlowWinitApp { }; // Creates the window - must come before we create our glow context - glutin_window_context.on_resume(event_loop)?; + glutin_window_context.initialize_window(ViewportId::ROOT, event_loop)?; - if let Some(viewport) = glutin_window_context.viewports.get(&ViewportId::ROOT) { - if let Some(window) = &viewport.window { - epi_integration::apply_window_settings(window, window_settings); - } + { + let viewport = &glutin_window_context.viewports[&ViewportId::ROOT]; + let window = viewport.window.as_ref().unwrap(); // Can't fail - we just called `initialize_all_viewports` + epi_integration::apply_window_settings(window, window_settings); } let gl = unsafe { crate::profile_scope!("glow::Context::from_loader_function"); - Rc::new(glow::Context::from_loader_function(|s| { + Arc::new(glow::Context::from_loader_function(|s| { let s = std::ffi::CString::new(s) .expect("failed to construct C string from string for gl proc address"); @@ -390,9 +403,13 @@ impl WinitApp for GlowWinitApp { } } - fn run_ui_and_paint(&mut self, window_id: WindowId) -> EventResult { + fn run_ui_and_paint( + &mut self, + event_loop: &EventLoopWindowTarget, + window_id: WindowId, + ) -> EventResult { if let Some(running) = &mut self.running { - running.run_ui_and_paint(window_id) + running.run_ui_and_paint(event_loop, window_id) } else { EventResult::Wait } @@ -401,29 +418,27 @@ impl WinitApp for GlowWinitApp { fn on_event( &mut self, event_loop: &EventLoopWindowTarget, - event: &winit::event::Event<'_, UserEvent>, + event: &winit::event::Event, ) -> Result { crate::profile_function!(winit_integration::short_event_description(event)); Ok(match event { winit::event::Event::Resumed => { + log::debug!("Event::Resumed"); + let running = if let Some(running) = &mut self.running { - // not the first resume event. create whatever you need. - running.glutin.borrow_mut().on_resume(event_loop)?; + // Not the first resume event. Create all outstanding windows. + running + .glutin + .borrow_mut() + .initialize_all_windows(event_loop); running } else { - // first resume event. - // we can actually move this outside of event loop. - // and just run the on_resume fn of gl_window + // First resume event. Created our root window etc. self.init_run_state(event_loop)? }; - let window_id = running - .glutin - .borrow() - .window_from_viewport - .get(&ViewportId::ROOT) - .copied(); - EventResult::RepaintNow(window_id.unwrap()) + let window_id = running.glutin.borrow().window_from_viewport[&ViewportId::ROOT]; + EventResult::RepaintNow(window_id) } winit::event::Event::Suspended => { @@ -433,15 +448,6 @@ impl WinitApp for GlowWinitApp { EventResult::Wait } - winit::event::Event::MainEventsCleared => { - if let Some(running) = &self.running { - if let Err(err) = running.glutin.borrow_mut().on_resume(event_loop) { - log::warn!("on_resume failed {err}"); - } - } - EventResult::Wait - } - winit::event::Event::WindowEvent { event, window_id } => { if let Some(running) = &mut self.running { running.on_window_event(*window_id, event) @@ -477,7 +483,11 @@ impl WinitApp for GlowWinitApp { } impl GlowWinitRunning { - fn run_ui_and_paint(&mut self, window_id: WindowId) -> EventResult { + fn run_ui_and_paint( + &mut self, + event_loop: &EventLoopWindowTarget, + window_id: WindowId, + ) -> EventResult { crate::profile_function!(); let Some(viewport_id) = self @@ -517,7 +527,6 @@ impl GlowWinitRunning { egui_winit::update_viewport_info(&mut viewport.info, &egui_ctx, window); let egui_winit = viewport.egui_winit.as_mut().unwrap(); - egui_winit.update_pixels_per_point(&egui_ctx, window); let mut raw_input = egui_winit.take_egui_input(window); let viewport_ui_cb = viewport.viewport_ui_cb.clone(); @@ -533,12 +542,16 @@ impl GlowWinitRunning { (raw_input, viewport_ui_cb) }; - { + let clear_color = self + .app + .clear_color(&self.integration.egui_ctx.style().visuals); + + let has_many_viewports = self.glutin.borrow().viewports.len() > 1; + let clear_before_update = !has_many_viewports; // HACK: for some reason, an early clear doesn't "take" on Mac with multiple viewports. + + if clear_before_update { // clear before we call update, so users can paint between clear-color and egui windows: - let clear_color = self - .app - .clear_color(&self.integration.egui_ctx.style().visuals); let mut glutin = self.glutin.borrow_mut(); let GlutinWindowContext { viewports, @@ -600,7 +613,7 @@ impl GlowWinitRunning { let egui_winit = viewport.egui_winit.as_mut().unwrap(); integration.post_update(); - egui_winit.handle_platform_output(window, &integration.egui_ctx, platform_output); + egui_winit.handle_platform_output(window, platform_output); let clipped_primitives = integration.egui_ctx.tessellate(shapes, pixels_per_point); @@ -609,6 +622,10 @@ impl GlowWinitRunning { let screen_size_in_pixels: [u32; 2] = window.inner_size().into(); + if !clear_before_update { + painter.clear(screen_size_in_pixels, clear_color); + } + painter.paint_and_update_textures( screen_size_in_pixels, pixels_per_point, @@ -659,7 +676,7 @@ impl GlowWinitRunning { std::thread::sleep(std::time::Duration::from_millis(10)); } - glutin.handle_viewport_output(&integration.egui_ctx, viewport_output); + glutin.handle_viewport_output(event_loop, &integration.egui_ctx, viewport_output); if integration.should_close() { EventResult::Exit @@ -671,7 +688,7 @@ impl GlowWinitRunning { fn on_window_event( &mut self, window_id: WindowId, - event: &winit::event::WindowEvent<'_>, + event: &winit::event::WindowEvent, ) -> EventResult { crate::profile_function!(egui_winit::short_window_event_description(event)); @@ -710,13 +727,6 @@ impl GlowWinitRunning { } } - winit::event::WindowEvent::ScaleFactorChanged { new_inner_size, .. } => { - if let Some(viewport_id) = viewport_id { - repaint_asap = true; - glutin.resize(viewport_id, **new_inner_size); - } - } - winit::event::WindowEvent::CloseRequested => { if viewport_id == Some(ViewportId::ROOT) && self.integration.should_close() { log::debug!( @@ -761,7 +771,11 @@ impl GlowWinitRunning { { event_response = self.integration.on_window_event(window, egui_winit, event); } + } else { + log::trace!("Ignoring event: no viewport for {viewport_id:?}"); } + } else { + log::trace!("Ignoring event: no viewport_id"); } if event_response.repaint { @@ -848,7 +862,7 @@ impl GlutinWindowContext { // Create GL display. This may probably create a window too on most platforms. Definitely on `MS windows`. Never on Android. let display_builder = glutin_winit::DisplayBuilder::new() // we might want to expose this option to users in the future. maybe using an env var or using native_options. - .with_preference(glutin_winit::ApiPrefence::FallbackEgl) // https://github.com/emilk/egui/issues/2520#issuecomment-1367841150 + .with_preference(glutin_winit::ApiPreference::FallbackEgl) // https://github.com/emilk/egui/issues/2520#issuecomment-1367841150 .with_window_builder(Some(egui_winit::create_winit_window_builder( egui_ctx, event_loop, @@ -961,37 +975,29 @@ impl GlutinWindowContext { focused_viewport: Some(ViewportId::ROOT), }; - slf.on_resume(event_loop)?; + slf.initialize_window(ViewportId::ROOT, event_loop)?; Ok(slf) } - /// This will be run after `new`. on android, it might be called multiple times over the course of the app's lifetime. - /// roughly, - /// 1. check if window already exists. otherwise, create one now. - /// 2. create attributes for surface creation. - /// 3. create surface. - /// 4. make surface and context current. + /// Create a surface, window, and winit integration for all viewports lacking any of that. /// - /// we presently assume that we will - fn on_resume(&mut self, event_loop: &EventLoopWindowTarget) -> Result<()> { + /// Errors will be logged. + fn initialize_all_windows(&mut self, event_loop: &EventLoopWindowTarget) { crate::profile_function!(); - let viewports: Vec = self - .viewports - .iter() - .filter(|(_, viewport)| viewport.gl_surface.is_none()) - .map(|(id, _)| *id) - .collect(); + let viewports: Vec = self.viewports.keys().copied().collect(); for viewport_id in viewports { - self.init_viewport(viewport_id, event_loop)?; + if let Err(err) = self.initialize_window(viewport_id, event_loop) { + log::error!("Failed to initialize a window for viewport {viewport_id:?}: {err}"); + } } - Ok(()) } + /// Create a surface, window, and winit integration for the viewport, if missing. #[allow(unsafe_code)] - pub(crate) fn init_viewport( + pub(crate) fn initialize_window( &mut self, viewport_id: ViewportId, event_loop: &EventLoopWindowTarget, @@ -1006,12 +1012,16 @@ impl GlutinWindowContext { let window = if let Some(window) = &mut viewport.window { window } else { - log::trace!("Window doesn't exist yet. Creating one now with finalize_window"); + log::debug!("Creating a window for viewport {viewport_id:?}"); let window_builder = egui_winit::create_winit_window_builder( &self.egui_ctx, event_loop, viewport.builder.clone(), ); + if window_builder.transparent() && self.gl_config.supports_transparency() == Some(false) + { + log::error!("Cannot create transparent window: the GL config does not support it"); + } let window = glutin_winit::finalize_window(event_loop, window_builder, &self.gl_config)?; egui_winit::apply_viewport_builder_to_window( @@ -1024,7 +1034,20 @@ impl GlutinWindowContext { viewport.window.insert(Rc::new(window)) }; - { + viewport.egui_winit.get_or_insert_with(|| { + log::debug!("Initializing egui_winit for viewport {viewport_id:?}"); + egui_winit::State::new( + self.egui_ctx.clone(), + viewport_id, + event_loop, + Some(window.scale_factor() as f32), + self.max_texture_side, + ) + }); + + if viewport.gl_surface.is_none() { + log::debug!("Creating a gl_surface for viewport {viewport_id:?}"); + // surface attributes let (width_px, height_px): (u32, u32) = window.inner_size().into(); let width_px = std::num::NonZeroU32::new(width_px.at_least(1)).unwrap(); @@ -1064,23 +1087,14 @@ impl GlutinWindowContext { // we will reach this point only once in most platforms except android. // create window/surface/make context current once and just use them forever. - viewport.egui_winit.get_or_insert_with(|| { - egui_winit::State::new( - viewport_id, - event_loop, - Some(window.scale_factor() as f32), - self.max_texture_side, - ) - }); - viewport.gl_surface = Some(gl_surface); + self.current_gl_context = Some(current_gl_context); - self.viewport_from_window - .insert(window.id(), viewport.ids.this); - self.window_from_viewport - .insert(viewport.ids.this, window.id()); } + self.viewport_from_window.insert(window.id(), viewport_id); + self.window_from_viewport.insert(viewport_id, window.id()); + Ok(()) } @@ -1145,6 +1159,7 @@ impl GlutinWindowContext { fn handle_viewport_output( &mut self, + event_loop: &EventLoopWindowTarget, egui_ctx: &egui::Context, viewport_output: ViewportIdMap, ) { @@ -1189,6 +1204,9 @@ impl GlutinWindowContext { } } + // Create windows for any new viewports: + self.initialize_all_windows(event_loop); + // GC old viewports self.viewports .retain(|id, _| active_viewports_ids.contains(id)); @@ -1200,7 +1218,7 @@ impl GlutinWindowContext { } fn initialize_or_update_viewport<'vp>( - egu_ctx: &'_ egui::Context, + egu_ctx: &egui::Context, viewports: &'vp mut ViewportIdMap, ids: ViewportIdPair, class: ViewportClass, @@ -1287,10 +1305,12 @@ fn render_immediate_viewport( viewport_ui_cb, } = immediate_viewport; + let viewport_id = ids.this; + { let mut glutin = glutin.borrow_mut(); - let viewport = initialize_or_update_viewport( + initialize_or_update_viewport( egui_ctx, &mut glutin.viewports, ids, @@ -1300,17 +1320,18 @@ fn render_immediate_viewport( None, ); - if viewport.gl_surface.is_none() { - glutin - .init_viewport(ids.this, event_loop) - .expect("Failed to initialize window in egui::Context::show_viewport_immediate"); + if let Err(err) = glutin.initialize_window(viewport_id, event_loop) { + log::error!( + "Failed to initialize a window for immediate viewport {viewport_id:?}: {err}" + ); + return; } } let input = { let mut glutin = glutin.borrow_mut(); - let Some(viewport) = glutin.viewports.get_mut(&ids.this) else { + let Some(viewport) = glutin.viewports.get_mut(&viewport_id) else { return; }; let (Some(egui_winit), Some(window)) = (&mut viewport.egui_winit, &viewport.window) else { @@ -1318,7 +1339,6 @@ fn render_immediate_viewport( }; egui_winit::update_viewport_info(&mut viewport.info, egui_ctx, window); - egui_winit.update_pixels_per_point(egui_ctx, window); let mut raw_input = egui_winit.take_egui_input(window); raw_input.viewports = glutin .viewports @@ -1355,7 +1375,7 @@ fn render_immediate_viewport( .. } = &mut *glutin; - let Some(viewport) = viewports.get_mut(&ids.this) else { + let Some(viewport) = viewports.get_mut(&viewport_id) else { return; }; @@ -1414,9 +1434,9 @@ fn render_immediate_viewport( } } - egui_winit.handle_platform_output(window, egui_ctx, platform_output); + egui_winit.handle_platform_output(window, platform_output); - glutin.handle_viewport_output(egui_ctx, viewport_output); + glutin.handle_viewport_output(event_loop, egui_ctx, viewport_output); } #[cfg(feature = "__screenshot")] diff --git a/crates/eframe/src/native/run.rs b/crates/eframe/src/native/run.rs index 5e3dc915..95e355a1 100644 --- a/crates/eframe/src/native/run.rs +++ b/crates/eframe/src/native/run.rs @@ -1,10 +1,3 @@ -//! Note that this file contains two similar paths - one for [`glow`], one for [`wgpu`]. -//! When making changes to one you often also want to apply it to the other. -//! -//! This is also very complex code, and not very pretty. -//! There is a bunch of improvements we could do, -//! like removing a bunch of `unwraps`. - use std::{cell::RefCell, time::Instant}; use winit::event_loop::{EventLoop, EventLoopBuilder}; @@ -34,12 +27,12 @@ fn create_event_loop_builder( event_loop_builder } -fn create_event_loop(native_options: &mut epi::NativeOptions) -> EventLoop { +fn create_event_loop(native_options: &mut epi::NativeOptions) -> Result> { crate::profile_function!(); let mut builder = create_event_loop_builder(native_options); crate::profile_scope!("EventLoopBuilder::build"); - builder.build() + Ok(builder.build()?) } /// Access a thread-local event loop. @@ -49,16 +42,20 @@ fn create_event_loop(native_options: &mut epi::NativeOptions) -> EventLoop( mut native_options: epi::NativeOptions, f: impl FnOnce(&mut EventLoop, epi::NativeOptions) -> R, -) -> R { +) -> Result { thread_local!(static EVENT_LOOP: RefCell>> = RefCell::new(None)); EVENT_LOOP.with(|event_loop| { // Since we want to reference NativeOptions when creating the EventLoop we can't // do that as part of the lazy thread local storage initialization and so we instead // create the event loop lazily here - let mut event_loop = event_loop.borrow_mut(); - let event_loop = event_loop.get_or_insert_with(|| create_event_loop(&mut native_options)); - f(event_loop, native_options) + let mut event_loop_lock = event_loop.borrow_mut(); + let event_loop = if let Some(event_loop) = &mut *event_loop_lock { + event_loop + } else { + event_loop_lock.insert(create_event_loop(&mut native_options)?) + }; + Ok(f(event_loop, native_options)) }) } @@ -67,31 +64,39 @@ fn run_and_return( event_loop: &mut EventLoop, mut winit_app: impl WinitApp, ) -> Result<()> { - use winit::{event_loop::ControlFlow, platform::run_return::EventLoopExtRunReturn as _}; + use winit::{event_loop::ControlFlow, platform::run_on_demand::EventLoopExtRunOnDemand}; - log::debug!("Entering the winit event loop (run_return)…"); + log::debug!("Entering the winit event loop (run_on_demand)…"); // When to repaint what window let mut windows_next_repaint_times = HashMap::default(); let mut returned_result = Ok(()); - event_loop.run_return(|event, event_loop, control_flow| { + event_loop.run_on_demand(|event, event_loop_window_target| { crate::profile_scope!("winit_event", short_event_description(&event)); + log::trace!("winit event: {event:?}"); + + if matches!(event, winit::event::Event::AboutToWait) { + return; // early-out: don't trigger another wait + } + let event_result = match &event { - winit::event::Event::LoopDestroyed => { - // On Mac, Cmd-Q we get here and then `run_return` doesn't return (despite its name), + winit::event::Event::LoopExiting => { + // On Mac, Cmd-Q we get here and then `run_on_demand` doesn't return (despite its name), // so we need to save state now: - log::debug!("Received Event::LoopDestroyed - saving app state…"); + log::debug!("Received Event::LoopExiting - saving app state…"); winit_app.save_and_destroy(); - *control_flow = ControlFlow::Exit; return; } - winit::event::Event::RedrawRequested(window_id) => { + winit::event::Event::WindowEvent { + event: winit::event::WindowEvent::RedrawRequested, + window_id, + } => { windows_next_repaint_times.remove(window_id); - winit_app.run_ui_and_paint(*window_id) + winit_app.run_ui_and_paint(event_loop_window_target, *window_id) } winit::event::Event::UserEvent(UserEvent::RequestRepaint { @@ -120,8 +125,11 @@ fn run_and_return( EventResult::Wait } - event => match winit_app.on_event(event_loop, event) { - Ok(event_result) => event_result, + event => match winit_app.on_event(event_loop_window_target, event) { + Ok(event_result) => { + log::trace!("event_result: {event_result:?}"); + event_result + } Err(err) => { log::error!("Exiting because of error: {err} during event {event:?}"); returned_result = Err(err); @@ -132,21 +140,28 @@ fn run_and_return( match event_result { EventResult::Wait => { - control_flow.set_wait(); + event_loop_window_target.set_control_flow(ControlFlow::Wait); } EventResult::RepaintNow(window_id) => { - log::trace!("Repaint caused by {}", short_event_description(&event)); + log::trace!( + "RepaintNow of {window_id:?} caused by {}", + short_event_description(&event) + ); if cfg!(target_os = "windows") { // Fix flickering on Windows, see https://github.com/emilk/egui/pull/2280 windows_next_repaint_times.remove(&window_id); - winit_app.run_ui_and_paint(window_id); + winit_app.run_ui_and_paint(event_loop_window_target, window_id); } else { // Fix for https://github.com/emilk/egui/issues/2425 windows_next_repaint_times.insert(window_id, Instant::now()); } } EventResult::RepaintNext(window_id) => { + log::trace!( + "RepaintNext of {window_id:?} caused by {}", + short_event_description(&event) + ); windows_next_repaint_times.insert(window_id, Instant::now()); } EventResult::RepaintAt(window_id, repaint_time) => { @@ -160,45 +175,35 @@ fn run_and_return( EventResult::Exit => { log::debug!("Asking to exit event loop…"); winit_app.save_and_destroy(); - *control_flow = ControlFlow::Exit; + event_loop_window_target.exit(); return; } } let mut next_repaint_time = windows_next_repaint_times.values().min().copied(); - // This is for not duplicating redraw requests - use winit::event::Event; - if matches!( - event, - Event::RedrawEventsCleared | Event::RedrawRequested(_) | Event::Resumed - ) { - windows_next_repaint_times.retain(|window_id, repaint_time| { - if Instant::now() < *repaint_time { - return true; - }; - - next_repaint_time = None; - control_flow.set_poll(); - - if let Some(window) = winit_app.window(*window_id) { - log::trace!("request_redraw for {window_id:?}"); - window.request_redraw(); - true - } else { - false - } - }); - } + windows_next_repaint_times.retain(|window_id, repaint_time| { + if Instant::now() < *repaint_time { + return true; // not yet ready + }; + + next_repaint_time = None; + event_loop_window_target.set_control_flow(ControlFlow::Poll); + + if let Some(window) = winit_app.window(*window_id) { + log::trace!("request_redraw for {window_id:?}"); + window.request_redraw(); + true + } else { + log::trace!("No window found for {window_id:?}"); + false + } + }); if let Some(next_repaint_time) = next_repaint_time { - let time_until_next = next_repaint_time.saturating_duration_since(Instant::now()); - if time_until_next < std::time::Duration::from_secs(10_000) { - log::trace!("WaitUntil {time_until_next:?}"); - } - control_flow.set_wait_until(next_repaint_time); + event_loop_window_target.set_control_flow(ControlFlow::WaitUntil(next_repaint_time)); }; - }); + })?; log::debug!("eframe window closed"); @@ -211,32 +216,47 @@ fn run_and_return( // we only apply this approach on Windows to minimize the affect. #[cfg(target_os = "windows")] { - event_loop.run_return(|_, _, control_flow| { - control_flow.set_exit(); - }); + event_loop + .run_on_demand(|_, event_loop_window_target| { + event_loop_window_target.exit(); + }) + .ok(); } returned_result } -fn run_and_exit(event_loop: EventLoop, mut winit_app: impl WinitApp + 'static) -> ! { +fn run_and_exit( + event_loop: EventLoop, + mut winit_app: impl WinitApp + 'static, +) -> Result<()> { + use winit::event_loop::ControlFlow; log::debug!("Entering the winit event loop (run)…"); // When to repaint what window let mut windows_next_repaint_times = HashMap::default(); - event_loop.run(move |event, event_loop, control_flow| { + event_loop.run(move |event, event_loop_window_target| { crate::profile_scope!("winit_event", short_event_description(&event)); + log::trace!("winit event: {event:?}"); + + if matches!(event, winit::event::Event::AboutToWait) { + return; // early-out: don't trigger another wait + } + let event_result = match &event { - winit::event::Event::LoopDestroyed => { - log::debug!("Received Event::LoopDestroyed"); + winit::event::Event::LoopExiting => { + log::debug!("Received Event::LoopExiting"); EventResult::Exit } - winit::event::Event::RedrawRequested(window_id) => { + winit::event::Event::WindowEvent { + event: winit::event::WindowEvent::RedrawRequested, + window_id, + } => { windows_next_repaint_times.remove(window_id); - winit_app.run_ui_and_paint(*window_id) + winit_app.run_ui_and_paint(event_loop_window_target, *window_id) } winit::event::Event::UserEvent(UserEvent::RequestRepaint { @@ -264,8 +284,11 @@ fn run_and_exit(event_loop: EventLoop, mut winit_app: impl WinitApp + EventResult::Wait } - event => match winit_app.on_event(event_loop, event) { - Ok(event_result) => event_result, + event => match winit_app.on_event(event_loop_window_target, event) { + Ok(event_result) => { + log::trace!("event_result: {event_result:?}"); + event_result + } Err(err) => { panic!("eframe encountered a fatal error: {err} during event {event:?}"); } @@ -274,22 +297,22 @@ fn run_and_exit(event_loop: EventLoop, mut winit_app: impl WinitApp + match event_result { EventResult::Wait => { - control_flow.set_wait(); + event_loop_window_target.set_control_flow(ControlFlow::Wait); } EventResult::RepaintNow(window_id) => { - log::trace!("Repaint caused by {}", short_event_description(&event)); + log::trace!("RepaintNow caused by {}", short_event_description(&event)); if cfg!(target_os = "windows") { // Fix flickering on Windows, see https://github.com/emilk/egui/pull/2280 windows_next_repaint_times.remove(&window_id); - winit_app.run_ui_and_paint(window_id); + winit_app.run_ui_and_paint(event_loop_window_target, window_id); } else { // Fix for https://github.com/emilk/egui/issues/2425 windows_next_repaint_times.insert(window_id, Instant::now()); } } EventResult::RepaintNext(window_id) => { - log::trace!("Repaint caused by {}", short_event_description(&event)); + log::trace!("RepaintNext caused by {}", short_event_description(&event)); windows_next_repaint_times.insert(window_id, Instant::now()); } EventResult::RepaintAt(window_id, repaint_time) => { @@ -303,6 +326,8 @@ fn run_and_exit(event_loop: EventLoop, mut winit_app: impl WinitApp + EventResult::Exit => { log::debug!("Quitting - saving app state…"); winit_app.save_and_destroy(); + + log::debug!("Exiting with return code 0"); #[allow(clippy::exit)] std::process::exit(0); } @@ -310,36 +335,25 @@ fn run_and_exit(event_loop: EventLoop, mut winit_app: impl WinitApp + let mut next_repaint_time = windows_next_repaint_times.values().min().copied(); - // This is for not duplicating redraw requests - use winit::event::Event; - if matches!( - event, - Event::RedrawEventsCleared | Event::RedrawRequested(_) | Event::Resumed - ) { - windows_next_repaint_times.retain(|window_id, repaint_time| { - if Instant::now() < *repaint_time { - return true; - } - - next_repaint_time = None; - control_flow.set_poll(); + windows_next_repaint_times.retain(|window_id, repaint_time| { + if Instant::now() < *repaint_time { + return true; // not yet ready + } - if let Some(window) = winit_app.window(*window_id) { - log::trace!("request_redraw for {window_id:?}"); - window.request_redraw(); - true - } else { - false - } - }); - } + next_repaint_time = None; + event_loop_window_target.set_control_flow(ControlFlow::Poll); - if let Some(next_repaint_time) = next_repaint_time { - let time_until_next = next_repaint_time.saturating_duration_since(Instant::now()); - if time_until_next < std::time::Duration::from_secs(10_000) { - log::trace!("WaitUntil {time_until_next:?}"); + if let Some(window) = winit_app.window(*window_id) { + log::trace!("request_redraw for {window_id:?}"); + window.request_redraw(); + true + } else { + log::trace!("No window found for {window_id:?}"); + false } + }); + if let Some(next_repaint_time) = next_repaint_time { // WaitUntil seems to not work on iOS #[cfg(target_os = "ios")] winit_app @@ -350,9 +364,13 @@ fn run_and_exit(event_loop: EventLoop, mut winit_app: impl WinitApp + .map(|window| window.request_redraw()) }); - control_flow.set_wait_until(next_repaint_time); + event_loop_window_target.set_control_flow(ControlFlow::WaitUntil(next_repaint_time)); }; - }) + })?; + + log::debug!("winit event loop unexpectedly returned"); + + Ok(()) } // ---------------------------------------------------------------------------- @@ -370,12 +388,12 @@ pub fn run_glow( return with_event_loop(native_options, |event_loop, native_options| { let glow_eframe = GlowWinitApp::new(event_loop, app_name, native_options, app_creator); run_and_return(event_loop, glow_eframe) - }); + })?; } - let event_loop = create_event_loop(&mut native_options); + let event_loop = create_event_loop(&mut native_options)?; let glow_eframe = GlowWinitApp::new(&event_loop, app_name, native_options, app_creator); - run_and_exit(event_loop, glow_eframe); + run_and_exit(event_loop, glow_eframe) } // ---------------------------------------------------------------------------- @@ -393,10 +411,10 @@ pub fn run_wgpu( return with_event_loop(native_options, |event_loop, native_options| { let wgpu_eframe = WgpuWinitApp::new(event_loop, app_name, native_options, app_creator); run_and_return(event_loop, wgpu_eframe) - }); + })?; } - let event_loop = create_event_loop(&mut native_options); + let event_loop = create_event_loop(&mut native_options)?; let wgpu_eframe = WgpuWinitApp::new(&event_loop, app_name, native_options, app_creator); - run_and_exit(event_loop, wgpu_eframe); + run_and_exit(event_loop, wgpu_eframe) } diff --git a/crates/eframe/src/native/wgpu_integration.rs b/crates/eframe/src/native/wgpu_integration.rs index 8d422a37..7bd5b38e 100644 --- a/crates/eframe/src/native/wgpu_integration.rs +++ b/crates/eframe/src/native/wgpu_integration.rs @@ -1,3 +1,10 @@ +//! Note that this file contains code very similar to [`glow_integration`]. +//! When making changes to one you often also want to apply it to the other. +//! +//! This is also very complex code, and not very pretty. +//! There is a bunch of improvements we could do, +//! like removing a bunch of `unwraps`. + use std::{cell::RefCell, rc::Rc, sync::Arc, time::Instant}; use parking_lot::Mutex; @@ -109,7 +116,8 @@ impl WgpuWinitApp { } } - fn build_windows(&mut self, event_loop: &EventLoopWindowTarget) { + /// Create a window for all viewports lacking one. + fn initialized_all_windows(&mut self, event_loop: &EventLoopWindowTarget) { let Some(running) = &mut self.running else { return; }; @@ -122,14 +130,12 @@ impl WgpuWinitApp { } = &mut *shared; for viewport in viewports.values_mut() { - if viewport.window.is_none() { - viewport.init_window( - &running.integration.egui_ctx, - viewport_from_window, - painter, - event_loop, - ); - } + viewport.initialize_window( + event_loop, + &running.integration.egui_ctx, + viewport_from_window, + painter, + ); } } @@ -205,6 +211,7 @@ impl WgpuWinitApp { #[allow(unused_mut)] // used for accesskit let mut egui_winit = egui_winit::State::new( + egui_ctx.clone(), ViewportId::ROOT, event_loop, Some(window.scale_factor() as f32), @@ -349,7 +356,13 @@ impl WinitApp for WgpuWinitApp { } } - fn run_ui_and_paint(&mut self, window_id: WindowId) -> EventResult { + fn run_ui_and_paint( + &mut self, + event_loop: &EventLoopWindowTarget, + window_id: WindowId, + ) -> EventResult { + self.initialized_all_windows(event_loop); + if let Some(running) = &mut self.running { running.run_ui_and_paint(window_id) } else { @@ -360,14 +373,16 @@ impl WinitApp for WgpuWinitApp { fn on_event( &mut self, event_loop: &EventLoopWindowTarget, - event: &winit::event::Event<'_, UserEvent>, + event: &winit::event::Event, ) -> Result { crate::profile_function!(winit_integration::short_event_description(event)); - self.build_windows(event_loop); + self.initialized_all_windows(event_loop); Ok(match event { winit::event::Event::Resumed => { + log::debug!("Event::Resumed"); + let running = if let Some(running) = &self.running { running } else { @@ -488,10 +503,7 @@ impl WgpuWinitRunning { let mut shared_lock = shared.borrow_mut(); let SharedState { - egui_ctx, - viewports, - painter, - .. + viewports, painter, .. } = &mut *shared_lock; if viewport_id != ViewportId::ROOT { @@ -539,7 +551,6 @@ impl WgpuWinitRunning { } let egui_winit = egui_winit.as_mut().unwrap(); - egui_winit.update_pixels_per_point(egui_ctx, window); let mut raw_input = egui_winit.take_egui_input(window); integration.pre_update(); @@ -596,7 +607,7 @@ impl WgpuWinitRunning { viewport_output, } = full_output; - egui_winit.handle_platform_output(window, egui_ctx, platform_output); + egui_winit.handle_platform_output(window, platform_output); { let clipped_primitives = egui_ctx.tessellate(shapes, pixels_per_point); @@ -663,7 +674,7 @@ impl WgpuWinitRunning { fn on_window_event( &mut self, window_id: WindowId, - event: &winit::event::WindowEvent<'_>, + event: &winit::event::WindowEvent, ) -> EventResult { crate::profile_function!(egui_winit::short_window_event_description(event)); @@ -712,18 +723,6 @@ impl WgpuWinitRunning { } } - winit::event::WindowEvent::ScaleFactorChanged { new_inner_size, .. } => { - use std::num::NonZeroU32; - if let (Some(width), Some(height), Some(viewport_id)) = ( - NonZeroU32::new(new_inner_size.width), - NonZeroU32::new(new_inner_size.height), - viewport_id, - ) { - repaint_asap = true; - shared.painter.on_window_resized(viewport_id, width, height); - } - } - winit::event::WindowEvent::CloseRequested => { if viewport_id == Some(ViewportId::ROOT) && integration.should_close() { log::debug!( @@ -778,13 +777,18 @@ impl WgpuWinitRunning { } impl Viewport { - fn init_window( + /// Create winit window, if needed. + fn initialize_window( &mut self, + event_loop: &EventLoopWindowTarget, egui_ctx: &egui::Context, windows_id: &mut HashMap, painter: &mut luminol_egui_wgpu::winit::Painter, - event_loop: &EventLoopWindowTarget, ) { + if self.window.is_some() { + return; // we already have one + } + crate::profile_function!(); let viewport_id = self.ids.this; @@ -799,6 +803,7 @@ impl Viewport { } self.egui_winit = Some(egui_winit::State::new( + egui_ctx.clone(), viewport_id, event_loop, Some(window.scale_factor() as f32), @@ -872,7 +877,7 @@ fn render_immediate_viewport( None, ); if viewport.window.is_none() { - viewport.init_window(egui_ctx, viewport_from_window, painter, event_loop); + viewport.initialize_window(event_loop, egui_ctx, viewport_from_window, painter); } let (Some(window), Some(egui_winit)) = (&viewport.window, &mut viewport.egui_winit) else { @@ -880,7 +885,6 @@ fn render_immediate_viewport( }; egui_winit::update_viewport_info(&mut viewport.info, egui_ctx, window); - egui_winit.update_pixels_per_point(egui_ctx, window); let mut input = egui_winit.take_egui_input(window); input.viewports = viewports .iter() @@ -944,7 +948,7 @@ fn render_immediate_viewport( false, ); - egui_winit.handle_platform_output(window, &egui_ctx, platform_output); + egui_winit.handle_platform_output(window, platform_output); handle_viewport_output(&egui_ctx, viewport_output, viewports, *focused_viewport); } diff --git a/crates/eframe/src/native/winit_integration.rs b/crates/eframe/src/native/winit_integration.rs index 53de13cc..a7e4bb38 100644 --- a/crates/eframe/src/native/winit_integration.rs +++ b/crates/eframe/src/native/winit_integration.rs @@ -74,12 +74,16 @@ pub trait WinitApp { fn save_and_destroy(&mut self); - fn run_ui_and_paint(&mut self, window_id: WindowId) -> EventResult; + fn run_ui_and_paint( + &mut self, + event_loop: &EventLoopWindowTarget, + window_id: WindowId, + ) -> EventResult; fn on_event( &mut self, event_loop: &EventLoopWindowTarget, - event: &winit::event::Event<'_, UserEvent>, + event: &winit::event::Event, ) -> crate::Result; } @@ -117,11 +121,9 @@ pub fn system_theme(window: &Window, options: &crate::NativeOptions) -> Option) -> &'static str { - use winit::event::Event; - +pub fn short_event_description(event: &winit::event::Event) -> &'static str { match event { - Event::UserEvent(user_event) => match user_event { + winit::event::Event::UserEvent(user_event) => match user_event { UserEvent::RequestRepaint { .. } => "UserEvent::RequestRepaint", #[cfg(feature = "accesskit")] UserEvent::AccessKitActionRequest(_) => "UserEvent::AccessKitActionRequest", diff --git a/crates/eframe/src/web/app_runner.rs b/crates/eframe/src/web/app_runner.rs index 42f3cff5..b95cff68 100644 --- a/crates/eframe/src/web/app_runner.rs +++ b/crates/eframe/src/web/app_runner.rs @@ -13,7 +13,7 @@ pub struct AppRunner { app: Box, pub(crate) needs_repaint: std::sync::Arc, last_save_time: f64, - pub(crate) text_cursor_pos: Option, + pub(crate) ime: Option, pub(crate) mutable_text_under_cursor: bool, // Output for the last run: @@ -142,7 +142,7 @@ impl AppRunner { app, needs_repaint, last_save_time: now_sec(), - text_cursor_pos: None, + ime: None, mutable_text_under_cursor: false, textures_delta: Default::default(), clipped_primitives: None, @@ -281,7 +281,7 @@ impl AppRunner { copied_text, events: _, // already handled mutable_text_under_cursor, - text_cursor_pos, + ime, #[cfg(feature = "accesskit")] accesskit_update: _, // not currently implemented } = platform_output; @@ -304,9 +304,9 @@ impl AppRunner { inner.mutable_text_under_cursor = mutable_text_under_cursor; inner.wants_keyboard_input = wants_keyboard_input; - if inner.text_cursor_pos != text_cursor_pos { - super::text_agent::move_text_cursor(text_cursor_pos, &state.canvas); - inner.text_cursor_pos = text_cursor_pos; + if inner.ime != ime { + super::text_agent::move_text_cursor(ime, &state.canvas); + inner.ime = ime; } } } diff --git a/crates/eframe/src/web/events.rs b/crates/eframe/src/web/events.rs index 9b314858..7e5fade9 100644 --- a/crates/eframe/src/web/events.rs +++ b/crates/eframe/src/web/events.rs @@ -184,6 +184,7 @@ pub(crate) fn install_document_events(state: &MainState) -> Result<(), JsValue> if let Some(key) = egui_key { state.channels.send(egui::Event::Key { key, + physical_key: None, // TODO pressed: true, repeat: false, // egui will fill this in for us! modifiers, @@ -255,6 +256,7 @@ pub(crate) fn install_document_events(state: &MainState) -> Result<(), JsValue> if let Some(key) = translate_key(&event.key()) { state.channels.send(egui::Event::Key { key, + physical_key: None, // TODO pressed: false, repeat: false, modifiers, @@ -666,6 +668,7 @@ pub(crate) fn install_canvas_events(state: &MainState) -> Result<(), JsValue> { move |event: web_sys::DragEvent, runner| { if let Some(data_transfer) = event.data_transfer() { + // TODO(https://github.com/emilk/egui/issues/3702): support dropping folders runner.input.raw.hovered_files.clear(); runner.needs_repaint.repaint_asap(); diff --git a/crates/eframe/src/web/input.rs b/crates/eframe/src/web/input.rs index 52d7490e..d9fe87c1 100644 --- a/crates/eframe/src/web/input.rs +++ b/crates/eframe/src/web/input.rs @@ -118,91 +118,7 @@ pub fn should_ignore_key(key: &str) -> bool { /// Web sends all keys as strings, so it is up to us to figure out if it is /// a real text input or the name of a key. pub fn translate_key(key: &str) -> Option { - use egui::Key; - - match key { - "ArrowDown" => Some(Key::ArrowDown), - "ArrowLeft" => Some(Key::ArrowLeft), - "ArrowRight" => Some(Key::ArrowRight), - "ArrowUp" => Some(Key::ArrowUp), - - "Esc" | "Escape" => Some(Key::Escape), - "Tab" => Some(Key::Tab), - "Backspace" => Some(Key::Backspace), - "Enter" => Some(Key::Enter), - "Space" | " " => Some(Key::Space), - - "Help" | "Insert" => Some(Key::Insert), - "Delete" => Some(Key::Delete), - "Home" => Some(Key::Home), - "End" => Some(Key::End), - "PageUp" => Some(Key::PageUp), - "PageDown" => Some(Key::PageDown), - - "-" => Some(Key::Minus), - "+" | "=" => Some(Key::PlusEquals), - - "0" => Some(Key::Num0), - "1" => Some(Key::Num1), - "2" => Some(Key::Num2), - "3" => Some(Key::Num3), - "4" => Some(Key::Num4), - "5" => Some(Key::Num5), - "6" => Some(Key::Num6), - "7" => Some(Key::Num7), - "8" => Some(Key::Num8), - "9" => Some(Key::Num9), - - "a" | "A" => Some(Key::A), - "b" | "B" => Some(Key::B), - "c" | "C" => Some(Key::C), - "d" | "D" => Some(Key::D), - "e" | "E" => Some(Key::E), - "f" | "F" => Some(Key::F), - "g" | "G" => Some(Key::G), - "h" | "H" => Some(Key::H), - "i" | "I" => Some(Key::I), - "j" | "J" => Some(Key::J), - "k" | "K" => Some(Key::K), - "l" | "L" => Some(Key::L), - "m" | "M" => Some(Key::M), - "n" | "N" => Some(Key::N), - "o" | "O" => Some(Key::O), - "p" | "P" => Some(Key::P), - "q" | "Q" => Some(Key::Q), - "r" | "R" => Some(Key::R), - "s" | "S" => Some(Key::S), - "t" | "T" => Some(Key::T), - "u" | "U" => Some(Key::U), - "v" | "V" => Some(Key::V), - "w" | "W" => Some(Key::W), - "x" | "X" => Some(Key::X), - "y" | "Y" => Some(Key::Y), - "z" | "Z" => Some(Key::Z), - - "F1" => Some(Key::F1), - "F2" => Some(Key::F2), - "F3" => Some(Key::F3), - "F4" => Some(Key::F4), - "F5" => Some(Key::F5), - "F6" => Some(Key::F6), - "F7" => Some(Key::F7), - "F8" => Some(Key::F8), - "F9" => Some(Key::F9), - "F10" => Some(Key::F10), - "F11" => Some(Key::F11), - "F12" => Some(Key::F12), - "F13" => Some(Key::F13), - "F14" => Some(Key::F14), - "F15" => Some(Key::F15), - "F16" => Some(Key::F16), - "F17" => Some(Key::F17), - "F18" => Some(Key::F18), - "F19" => Some(Key::F19), - "F20" => Some(Key::F20), - - _ => None, - } + egui::Key::from_name(key) } macro_rules! modifiers { diff --git a/crates/eframe/src/web/mod.rs b/crates/eframe/src/web/mod.rs index 031aabfe..61e701a6 100644 --- a/crates/eframe/src/web/mod.rs +++ b/crates/eframe/src/web/mod.rs @@ -333,7 +333,7 @@ pub struct MainStateInner { touch_pos: egui::Pos2, /// If the user is typing something, the position of the text cursor (for IME) in screen /// coordinates. - text_cursor_pos: Option, + ime: Option, /// Whether or not the user is editing a mutable egui text box. mutable_text_under_cursor: bool, /// Whether or not egui is trying to receive text input. diff --git a/crates/eframe/src/web/text_agent.rs b/crates/eframe/src/web/text_agent.rs index 55801813..07e33b53 100644 --- a/crates/eframe/src/web/text_agent.rs +++ b/crates/eframe/src/web/text_agent.rs @@ -212,13 +212,15 @@ fn is_mobile() -> Option { // so it appears that the IME candidate window moves with text cursor. // On mobile devices, there is no need to do that. pub fn move_text_cursor( - cursor: Option, + ime: Option, canvas: &web_sys::HtmlCanvasElement, ) -> Option<()> { let style = text_agent().style(); - // Note: movint agent on mobile devices will lead to unpredictable scroll. + // Note: moving agent on mobile devices will lead to unpredictable scroll. if is_mobile() == Some(false) { - cursor.as_ref().and_then(|&egui::Pos2 { x, y }| { + ime.as_ref().and_then(|ime| { + let egui::Pos2 { x, y } = ime.cursor_rect.left_top(); + let bounding_rect = text_agent().get_bounding_client_rect(); let y = (y + (canvas.scroll_top() + canvas.offset_top()) as f32) .min(canvas.client_height() as f32 - bounding_rect.height() as f32); diff --git a/crates/eframe/src/web/web_painter_glow.rs b/crates/eframe/src/web/web_painter_glow.rs index e02c6dd9..cd627586 100644 --- a/crates/eframe/src/web/web_painter_glow.rs +++ b/crates/eframe/src/web/web_painter_glow.rs @@ -15,7 +15,7 @@ pub(crate) struct WebPainterGlow { } impl WebPainterGlow { - pub fn gl(&self) -> &std::rc::Rc { + pub fn gl(&self) -> &std::sync::Arc { self.painter.gl() } @@ -24,7 +24,8 @@ impl WebPainterGlow { let (gl, shader_prefix) = init_glow_context_from_canvas(&canvas, options.webgl_context_option)?; - let gl = std::rc::Rc::new(gl); + #[allow(clippy::arc_with_non_send_sync)] + let gl = std::sync::Arc::new(gl); let painter = egui_glow::Painter::new(gl, shader_prefix, None) .map_err(|err| format!("Error starting glow painter: {err}"))?; diff --git a/crates/egui-wgpu/CHANGELOG.md b/crates/egui-wgpu/CHANGELOG.md index 783c40c7..870d2d97 100644 --- a/crates/egui-wgpu/CHANGELOG.md +++ b/crates/egui-wgpu/CHANGELOG.md @@ -6,6 +6,10 @@ This file is updated upon each release. Changes since the last release can be found at or by running the `scripts/generate_changelog.py` script. +## 0.25.0 - 2024-01-08 +* Only call wgpu paint callback if viewport is positive [#3778](https://github.com/emilk/egui/pull/3778) (thanks [@msparkles](https://github.com/msparkles)!) + + ## 0.24.1 - 2023-11-30 * Add a few `puffin` profile scopes diff --git a/crates/egui-wgpu/Cargo.toml b/crates/egui-wgpu/Cargo.toml index 6f084b7a..fe11e70d 100644 --- a/crates/egui-wgpu/Cargo.toml +++ b/crates/egui-wgpu/Cargo.toml @@ -51,7 +51,9 @@ wgpu.workspace = true ## Enable this when generating docs. document-features = { version = "0.2", optional = true } -winit = { version = "0.28", default-features = false, optional = true } +winit = { version = "0.29.4", default-features = false, optional = true, features = [ + "rwh_05", +] } # Native: [target.'cfg(not(target_arch = "wasm32"))'.dependencies] diff --git a/crates/egui-wgpu/README.md b/crates/egui-wgpu/README.md index db2aa1f6..a6d152c4 100644 --- a/crates/egui-wgpu/README.md +++ b/crates/egui-wgpu/README.md @@ -1,5 +1,5 @@ > [!IMPORTANT] -> luminol-egui-wgpu is currently based on emilk/egui@0.24.1 +> luminol-egui-wgpu is currently based on emilk/egui@0.25.0 > [!NOTE] > This is Luminol's modified version of egui-wgpu. The original version is dual-licensed under MIT and Apache 2.0. diff --git a/crates/egui-wgpu/src/lib.rs b/crates/egui-wgpu/src/lib.rs index 8522d32f..d560f70d 100644 --- a/crates/egui-wgpu/src/lib.rs +++ b/crates/egui-wgpu/src/lib.rs @@ -72,6 +72,9 @@ impl RenderState { ) -> Result { crate::profile_scope!("RenderState::create"); // async yield give bad names using `profile_function` + #[cfg(not(target_arch = "wasm32"))] + let adapters: Vec<_> = instance.enumerate_adapters(wgpu::Backends::all()).collect(); + let adapter = { crate::profile_scope!("request_adapter"); instance @@ -81,9 +84,51 @@ impl RenderState { force_fallback_adapter: false, }) .await - .ok_or(WgpuError::NoSuitableAdapterFound)? + .ok_or_else(|| { + #[cfg(not(target_arch = "wasm32"))] + if adapters.is_empty() { + log::info!("No wgpu adapters found"); + } else if adapters.len() == 1 { + log::info!( + "The only available wgpu adapter was not suitable: {}", + adapter_info_summary(&adapters[0].get_info()) + ); + } else { + log::info!( + "No suitable wgpu adapter found out of the {} available ones: {}", + adapters.len(), + describe_adapters(&adapters) + ); + } + + WgpuError::NoSuitableAdapterFound + })? }; + #[cfg(target_arch = "wasm32")] + log::debug!( + "Picked wgpu adapter: {}", + adapter_info_summary(&adapter.get_info()) + ); + + #[cfg(not(target_arch = "wasm32"))] + if adapters.len() == 1 { + log::debug!( + "Picked the only available wgpu adapter: {}", + adapter_info_summary(&adapter.get_info()) + ); + } else { + log::info!( + "There were {} available wgpu adapters: {}", + adapters.len(), + describe_adapters(&adapters) + ); + log::debug!( + "Picked wgpu adapter: {}", + adapter_info_summary(&adapter.get_info()) + ); + } + let capabilities = { crate::profile_scope!("get_capabilities"); surface.get_capabilities(&adapter).formats @@ -109,6 +154,24 @@ impl RenderState { } } +#[cfg(not(target_arch = "wasm32"))] +fn describe_adapters(adapters: &[wgpu::Adapter]) -> String { + if adapters.is_empty() { + "(none)".to_owned() + } else if adapters.len() == 1 { + adapter_info_summary(&adapters[0].get_info()) + } else { + let mut list_string = String::new(); + for adapter in adapters { + if !list_string.is_empty() { + list_string += ", "; + } + list_string += &format!("{{{}}}", adapter_info_summary(&adapter.get_info())); + } + list_string + } +} + /// Specifies which action should be taken as consequence of a [`wgpu::SurfaceError`] pub enum SurfaceErrorAction { /// Do nothing and skip the current frame. @@ -119,6 +182,10 @@ pub enum SurfaceErrorAction { } /// Configuration for using wgpu with eframe or the egui-wgpu winit feature. +/// +/// This can be configured with the environment variables: +/// * `WGPU_BACKEND`: `vulkan`, `dx11`, `dx12`, `metal`, `opengl`, `webgpu` +/// * `WGPU_POWER_PREF`: `low`, `high` or `none` #[derive(Clone)] pub struct WgpuConfiguration { /// Backends that should be supported (wgpu will pick one of these) @@ -154,6 +221,7 @@ impl Default for WgpuConfiguration { // (note however, that the GL backend needs to be opted-in via a wgpu feature flag) supported_backends: wgpu::util::backend_bits_from_env() .unwrap_or(wgpu::Backends::PRIMARY | wgpu::Backends::GL), + device_descriptor: Arc::new(|adapter| { let base_limits = if adapter.get_info().backend == wgpu::Backend::Gl { wgpu::Limits::downlevel_webgl2_defaults() @@ -172,7 +240,9 @@ impl Default for WgpuConfiguration { }, } }), + present_mode: wgpu::PresentMode::AutoVsync, + power_preference: wgpu::util::power_preference_from_env() .unwrap_or(wgpu::PowerPreference::HighPerformance), @@ -227,6 +297,47 @@ pub fn depth_format_from_bits(depth_buffer: u8, stencil_buffer: u8) -> Option String { + let wgpu::AdapterInfo { + name, + vendor, + device, + device_type, + driver, + driver_info, + backend, + } = &info; + + // Example values: + // > name: "llvmpipe (LLVM 16.0.6, 256 bits)", device_type: Cpu, backend: Vulkan, driver: "llvmpipe", driver_info: "Mesa 23.1.6-arch1.4 (LLVM 16.0.6)" + // > name: "Apple M1 Pro", device_type: IntegratedGpu, backend: Metal, driver: "", driver_info: "" + // > name: "ANGLE (Apple, Apple M1 Pro, OpenGL 4.1)", device_type: IntegratedGpu, backend: Gl, driver: "", driver_info: "" + + let mut summary = format!("backend: {backend:?}, device_type: {device_type:?}"); + + if !name.is_empty() { + summary += &format!(", name: {name:?}"); + } + if !driver.is_empty() { + summary += &format!(", driver: {driver:?}"); + } + if !driver_info.is_empty() { + summary += &format!(", driver_info: {driver_info:?}"); + } + if *vendor != 0 { + // TODO(emilk): decode using https://github.com/gfx-rs/wgpu/blob/767ac03245ee937d3dc552edc13fe7ab0a860eec/wgpu-hal/src/auxil/mod.rs#L7 + summary += &format!(", vendor: 0x{vendor:04X}"); + } + if *device != 0 { + summary += &format!(", device: 0x{device:02X}"); + } + + summary +} + +// --------------------------------------------------------------------------- + mod profiling_scopes { #![allow(unused_macros)] #![allow(unused_imports)] diff --git a/crates/egui-wgpu/src/renderer.rs b/crates/egui-wgpu/src/renderer.rs index a886dc51..fc6a668b 100644 --- a/crates/egui-wgpu/src/renderer.rs +++ b/crates/egui-wgpu/src/renderer.rs @@ -450,39 +450,35 @@ impl Renderer { continue; }; - if callback.rect.is_positive() { + let info = PaintCallbackInfo { + viewport: callback.rect, + clip_rect: *clip_rect, + pixels_per_point, + screen_size_px: size_in_pixels, + }; + + let viewport_px = info.viewport_in_pixels(); + if viewport_px.width_px > 0 && viewport_px.height_px > 0 { crate::profile_scope!("callback"); needs_reset = true; - let info = PaintCallbackInfo { - viewport: callback.rect, - clip_rect: *clip_rect, - pixels_per_point, - screen_size_px: size_in_pixels, - }; - - { - // We're setting a default viewport for the render pass as a - // courtesy for the user, so that they don't have to think about - // it in the simple case where they just want to fill the whole - // paint area. - // - // The user still has the possibility of setting their own custom - // viewport during the paint callback, effectively overriding this - // one. - - let viewport_px = info.viewport_in_pixels(); - - render_pass.set_viewport( - viewport_px.left_px as f32, - viewport_px.top_px as f32, - viewport_px.width_px as f32, - viewport_px.height_px as f32, - 0.0, - 1.0, - ); - } + // We're setting a default viewport for the render pass as a + // courtesy for the user, so that they don't have to think about + // it in the simple case where they just want to fill the whole + // paint area. + // + // The user still has the possibility of setting their own custom + // viewport during the paint callback, effectively overriding this + // one. + render_pass.set_viewport( + viewport_px.left_px as f32, + viewport_px.top_px as f32, + viewport_px.width_px as f32, + viewport_px.height_px as f32, + 0.0, + 1.0, + ); cbfn.0.paint(info, render_pass, &self.callback_resources); } From f6b4adc0c12f24518af0f029286e4eecc1629f53 Mon Sep 17 00:00:00 2001 From: white-axe Date: Tue, 30 Jan 2024 20:37:54 -0500 Subject: [PATCH 08/20] chore: update egui, catppuccin-egui and other egui-related crates --- Cargo.lock | 487 ++++++++++------------------------------- Cargo.toml | 10 +- crates/core/Cargo.toml | 6 +- crates/ui/Cargo.toml | 2 +- 4 files changed, 130 insertions(+), 375 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 18527049..cefe047c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -82,15 +82,15 @@ dependencies = [ [[package]] name = "accesskit_winit" -version = "0.15.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88e39fcec2e10971e188730b7a76bab60647dacc973d4591855ebebcadfaa738" +checksum = "5284218aca17d9e150164428a0ebc7b955f70e3a9a78b4c20894513aabf98a67" dependencies = [ "accesskit", "accesskit_macos", "accesskit_unix", "accesskit_windows", - "winit 0.28.7", + "winit", ] [[package]] @@ -196,24 +196,6 @@ dependencies = [ "pkg-config", ] -[[package]] -name = "android-activity" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64529721f27c2314ced0890ce45e469574a73e5e6fdd6e9da1860eb29285f5e0" -dependencies = [ - "android-properties", - "bitflags 1.3.2", - "cc", - "jni-sys", - "libc", - "log", - "ndk 0.7.0", - "ndk-context", - "ndk-sys 0.4.1+23.1.7779620", - "num_enum 0.6.1", -] - [[package]] name = "android-activity" version = "0.5.2" @@ -649,12 +631,6 @@ dependencies = [ "rustc-demangle", ] -[[package]] -name = "base64" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" - [[package]] name = "base64" version = "0.21.5" @@ -852,20 +828,6 @@ dependencies = [ "system-deps", ] -[[package]] -name = "calloop" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52e0d00eb1ea24371a97d2da6201c6747a633dc6dc1988ef503403b4c59504a8" -dependencies = [ - "bitflags 1.3.2", - "log", - "nix 0.25.1", - "slotmap", - "thiserror", - "vec_map", -] - [[package]] name = "calloop" version = "0.12.4" @@ -886,10 +848,10 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f0ea9b9476c7fad82841a8dbb380e2eae480c21910feba80725b46931ed8f02" dependencies = [ - "calloop 0.12.4", + "calloop", "rustix 0.38.26", "wayland-backend", - "wayland-client 0.31.2", + "wayland-client", ] [[package]] @@ -900,8 +862,9 @@ checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" [[package]] name = "catppuccin-egui" -version = "3.1.0" -source = "git+https://github.com/catppuccin/egui?rev=bcb5849b6f96b56aa4982ec3366e238371de473e#bcb5849b6f96b56aa4982ec3366e238371de473e" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64bd5a6c2c4bd822735e69d27609fe6fc41e8ec7dd0a7c338dedfdf69fd915b6" dependencies = [ "egui", ] @@ -1000,7 +963,7 @@ dependencies = [ "block", "cocoa-foundation", "core-foundation", - "core-graphics 0.23.1", + "core-graphics", "foreign-types 0.5.0", "libc", "objc", @@ -1124,19 +1087,6 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" -[[package]] -name = "core-graphics" -version = "0.22.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "core-graphics-types", - "foreign-types 0.3.2", - "libc", -] - [[package]] name = "core-graphics" version = "0.23.1" @@ -1360,9 +1310,9 @@ checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "data-url" -version = "0.2.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d7439c3735f405729d52c3fbbe4de140eaf938a1fe47d227c27f8254d4302a5" +checksum = "5c297a1c74b71ae29df00c3e22dd9534821d60eb9af5a0192823fa2acea70c2a" [[package]] name = "delegate-display" @@ -1513,9 +1463,9 @@ dependencies = [ [[package]] name = "ecolor" -version = "0.24.1" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b7637fc2e74d17e52931bac90ff4fc061ac776ada9c7fa272f24cdca5991972" +checksum = "57539aabcdbb733b6806ef421b66dec158dc1582107ad6d51913db3600303354" dependencies = [ "bytemuck", "serde", @@ -1523,9 +1473,9 @@ dependencies = [ [[package]] name = "egui" -version = "0.24.1" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c55bcb864b764eb889515a38b8924757657a250738ad15126637ee2df291ee6b" +checksum = "e0bf640ed7f3bf3d14ebf00d73bacc09c886443ee84ca6494bde37953012c9e3" dependencies = [ "accesskit", "ahash 0.8.6", @@ -1539,27 +1489,27 @@ dependencies = [ [[package]] name = "egui-modal" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f606099ee8ae25afed745612a2854435c63bf4eb8b6f38859fd44d95f0f1d01d" +checksum = "5e4dd394948863624a7269cedfaeb5c6a568e6d1d7accfac6fa70c283699c78b" dependencies = [ "egui", ] [[package]] name = "egui-notify" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bedb26510c661d5d69958aae802d768aa1c344673e9029a20b356fa7f8a4a8e1" +checksum = "5e978910d93935cb5a73322d885a9804616c9b15570428a9c5cd68fb3b5cd1e8" dependencies = [ "egui", ] [[package]] name = "egui-winit" -version = "0.24.1" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b673606b6606b12b95e3a3194d7882bf5cff302db36a520b8144c7c342e4e84" +checksum = "1d95d9762056c541bd2724de02910d8bccf3af8e37689dc114b21730e64f80a0" dependencies = [ "accesskit_winit", "arboard", @@ -1571,14 +1521,14 @@ dependencies = [ "smithay-clipboard", "web-time", "webbrowser", - "winit 0.28.7", + "winit", ] [[package]] name = "egui_dock" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cabf77568b8da81f419596357583fbc14fd761c72c3433856d30c7669e5b5679" +checksum = "727ea33d9940fb3eea4ba59c78e47db5d0c25bdcb3f3169be68d0ee7088f5e61" dependencies = [ "duplicate", "egui", @@ -1587,9 +1537,9 @@ dependencies = [ [[package]] name = "egui_extras" -version = "0.24.2" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97624eaf17a16058265d3a3e712e167798655baf7c8f693de25be75cdd6c57b5" +checksum = "753c36d3e2f7a32425af5290af2e52efb3471ea3a263b87f003b5433351b0fd7" dependencies = [ "egui", "enum-map", @@ -1598,20 +1548,18 @@ dependencies = [ "mime_guess2", "resvg", "serde", - "tiny-skia 0.8.4", - "usvg", ] [[package]] name = "egui_glow" -version = "0.24.1" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "262151f9d57c557c02a40a46f27b9e050a6eb0b006b94dced9c6f4519a04d489" +checksum = "cb2ef815e80d117339c7d6b813f7678d23522d699ccd3243e267ef06166009b9" dependencies = [ "bytemuck", "egui", "egui-winit", - "glow 0.12.3", + "glow", "log", "memoffset 0.7.1", "puffin", @@ -1627,9 +1575,9 @@ checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "emath" -version = "0.24.1" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a045c6c0b44b35e98513fc1e9d183ab42881ac27caccb9fa345465601f56cce4" +checksum = "3ee58355767587db7ba3738930d93cad3052cd834c2b48b9ef6ef26fe4823b7e" dependencies = [ "bytemuck", "serde", @@ -1711,9 +1659,9 @@ dependencies = [ [[package]] name = "epaint" -version = "0.24.1" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d1b9e000d21bab9b535ce78f9f7745be28b3f777f6c7223936561c5c7fefab8" +checksum = "e638cb066bff0903bbb6143116cfd134a42279c7d68f19c0352a94f15a402de7" dependencies = [ "ab_glyph", "ahash 0.8.6", @@ -2283,18 +2231,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "glow" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca0fe580e4b60a8ab24a868bc08e2f03cbcb20d3d676601fa909386713333728" -dependencies = [ - "js-sys", - "slotmap", - "wasm-bindgen", - "web-sys", -] - [[package]] name = "glow" version = "0.13.0" @@ -2326,7 +2262,7 @@ dependencies = [ "objc2 0.4.1", "once_cell", "raw-window-handle 0.5.2", - "wayland-sys 0.31.1", + "wayland-sys", "windows-sys 0.48.0", "x11-dl", ] @@ -2340,7 +2276,7 @@ dependencies = [ "cfg_aliases", "glutin", "raw-window-handle 0.5.2", - "winit 0.29.10", + "winit", ] [[package]] @@ -2695,9 +2631,9 @@ dependencies = [ [[package]] name = "imagesize" -version = "0.10.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df19da1e92fbfec043ca97d622955381b1f3ee72a180ec999912df31b1ccd951" +checksum = "029d73f573d8e8d63e6d5020011d3255b28c3ba85d6cf870a07184ed23de9284" [[package]] name = "indenter" @@ -2746,9 +2682,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", ] [[package]] @@ -2894,9 +2827,9 @@ checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" [[package]] name = "kurbo" -version = "0.8.3" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a53776d271cfb873b17c618af0298445c88afc52837f3e948fa3fafd131f449" +checksum = "bd85a5776cd9500c2e2059c8c76c3b01528566b7fcbaf8098b55a33fc298849b" dependencies = [ "arrayvec", ] @@ -3235,7 +3168,7 @@ dependencies = [ "egui-winit", "egui_glow", "flume", - "glow 0.13.0", + "glow", "glutin", "glutin-winit", "image 0.24.7", @@ -3261,7 +3194,7 @@ dependencies = [ "web-sys", "wgpu", "winapi", - "winit 0.29.10", + "winit", ] [[package]] @@ -3277,7 +3210,7 @@ dependencies = [ "thiserror", "type-map", "wgpu", - "winit 0.29.10", + "winit", ] [[package]] @@ -3498,15 +3431,6 @@ version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" -[[package]] -name = "memmap2" -version = "0.5.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" -dependencies = [ - "libc", -] - [[package]] name = "memmap2" version = "0.9.3" @@ -3636,7 +3560,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" dependencies = [ "libc", - "log", "wasi", "windows-sys 0.48.0", ] @@ -3906,15 +3829,6 @@ dependencies = [ "num_enum_derive 0.5.11", ] -[[package]] -name = "num_enum" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" -dependencies = [ - "num_enum_derive 0.6.1", -] - [[package]] name = "num_enum" version = "0.7.1" @@ -3936,18 +3850,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "num_enum_derive" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" -dependencies = [ - "proc-macro-crate 1.3.1", - "proc-macro2", - "quote", - "syn 2.0.39", -] - [[package]] name = "num_enum_derive" version = "0.7.1" @@ -4460,7 +4362,7 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5699cc8a63d1aa2b1ee8e12b9ad70ac790d65788cd36101fa37f87ea46c4cef" dependencies = [ - "base64 0.21.5", + "base64", "indexmap", "line-wrap", "quick-xml", @@ -4855,7 +4757,7 @@ version = "0.11.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" dependencies = [ - "base64 0.21.5", + "base64", "bytes", "encoding_rs", "futures-core", @@ -4889,15 +4791,15 @@ dependencies = [ [[package]] name = "resvg" -version = "0.28.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c115863f2d3621999cf187e318bc92b16402dfeff6a48c74df700d77381394c1" +checksum = "cadccb3d99a9efb8e5e00c16fbb732cbe400db2ec7fc004697ee7d97d86cf1f4" dependencies = [ "log", "pico-args", "rgb", "svgtypes", - "tiny-skia 0.8.4", + "tiny-skia", "usvg", ] @@ -4952,7 +4854,7 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" dependencies = [ - "base64 0.21.5", + "base64", "bitflags 2.4.1", "serde", "serde_derive", @@ -4960,12 +4862,9 @@ dependencies = [ [[package]] name = "roxmltree" -version = "0.15.1" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b9de9831a129b122e7e61f242db509fa9d0838008bf0b29bb0624669edfe48a" -dependencies = [ - "xmlparser", -] +checksum = "3cd14fd5e3b777a7422cca79358c57a8f6e3a703d9ac187448d0daf220c2407f" [[package]] name = "rust-ini" @@ -5079,19 +4978,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "sctk-adwaita" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda4e97be1fd174ccc2aae81c8b694e803fa99b34e8fd0f057a9d70698e3ed09" -dependencies = [ - "ab_glyph", - "log", - "memmap2 0.5.10", - "smithay-client-toolkit 0.16.1", - "tiny-skia 0.8.4", -] - [[package]] name = "sctk-adwaita" version = "0.8.1" @@ -5100,9 +4986,9 @@ checksum = "82b2eaf3a5b264a521b988b2e73042e742df700c4f962cde845d1541adb46550" dependencies = [ "ab_glyph", "log", - "memmap2 0.9.3", - "smithay-client-toolkit 0.18.0", - "tiny-skia 0.11.3", + "memmap2", + "smithay-client-toolkit", + "tiny-skia", ] [[package]] @@ -5388,25 +5274,6 @@ version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" -[[package]] -name = "smithay-client-toolkit" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "870427e30b8f2cbe64bf43ec4b86e88fe39b0a84b3f15efd9c9c2d020bc86eb9" -dependencies = [ - "bitflags 1.3.2", - "calloop 0.10.6", - "dlib", - "lazy_static", - "log", - "memmap2 0.5.10", - "nix 0.24.3", - "pkg-config", - "wayland-client 0.29.5", - "wayland-cursor 0.29.5", - "wayland-protocols 0.29.5", -] - [[package]] name = "smithay-client-toolkit" version = "0.18.0" @@ -5414,32 +5281,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60e3d9941fa3bacf7c2bf4b065304faa14164151254cd16ce1b1bc8fc381600f" dependencies = [ "bitflags 2.4.1", - "calloop 0.12.4", + "calloop", "calloop-wayland-source", "cursor-icon", "libc", "log", - "memmap2 0.9.3", + "memmap2", "rustix 0.38.26", "thiserror", "wayland-backend", - "wayland-client 0.31.2", + "wayland-client", "wayland-csd-frame", - "wayland-cursor 0.31.1", - "wayland-protocols 0.31.2", + "wayland-cursor", + "wayland-protocols", "wayland-protocols-wlr", - "wayland-scanner 0.31.1", + "wayland-scanner", "xkeysym", ] [[package]] name = "smithay-clipboard" -version = "0.6.6" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a345c870a1fae0b1b779085e81b51e614767c239e93503588e54c5b17f4b0e8" +checksum = "0bb62b280ce5a5cba847669933a0948d00904cf83845c944eae96a4738cea1a6" dependencies = [ - "smithay-client-toolkit 0.16.1", - "wayland-client 0.29.5", + "libc", + "smithay-client-toolkit", + "wayland-backend", ] [[package]] @@ -5559,10 +5427,11 @@ dependencies = [ [[package]] name = "svgtypes" -version = "0.8.2" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22975e8a2bac6a76bb54f898a6b18764633b00e780330f0b689f65afb3975564" +checksum = "6e44e288cd960318917cbd540340968b90becc8bc81f171345d706e7a89d9d70" dependencies = [ + "kurbo", "siphasher", ] @@ -5758,7 +5627,7 @@ version = "0.22.0" source = "git+https://github.com/wez/wezterm?rev=3666303c7b26c6c966b3f136dbb954686d334cc3#3666303c7b26c6c966b3f136dbb954686d334cc3" dependencies = [ "anyhow", - "base64 0.21.5", + "base64", "bitflags 1.3.2", "filedescriptor", "finl_unicode", @@ -5895,20 +5764,6 @@ dependencies = [ "crunchy", ] -[[package]] -name = "tiny-skia" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df8493a203431061e901613751931f047d1971337153f96d0e5e363d6dbf6a67" -dependencies = [ - "arrayref", - "arrayvec", - "bytemuck", - "cfg-if", - "png", - "tiny-skia-path 0.8.4", -] - [[package]] name = "tiny-skia" version = "0.11.3" @@ -5920,18 +5775,8 @@ dependencies = [ "bytemuck", "cfg-if", "log", - "tiny-skia-path 0.11.3", -] - -[[package]] -name = "tiny-skia-path" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adbfb5d3f3dd57a0e11d12f4f13d4ebbbc1b5c15b7ab0a156d030b21da5f677c" -dependencies = [ - "arrayref", - "bytemuck", - "strict-num", + "png", + "tiny-skia-path", ] [[package]] @@ -6290,22 +6135,46 @@ dependencies = [ [[package]] name = "usvg" -version = "0.28.0" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b0a51b72ab80ca511d126b77feeeb4fb1e972764653e61feac30adc161a756" +dependencies = [ + "base64", + "log", + "pico-args", + "usvg-parser", + "usvg-tree", + "xmlwriter", +] + +[[package]] +name = "usvg-parser" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b5b7c2b30845b3348c067ca3d09e20cc6e327c288f0ca4c48698712abf432e9" +checksum = "9bd4e3c291f45d152929a31f0f6c819245e2921bfd01e7bd91201a9af39a2bdc" dependencies = [ - "base64 0.13.1", "data-url", "flate2", "imagesize", "kurbo", "log", - "rctree", "roxmltree", "simplecss", "siphasher", + "svgtypes", + "usvg-tree", +] + +[[package]] +name = "usvg-tree" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ee3d202ebdb97a6215604b8f5b4d6ef9024efd623cf2e373a6416ba976ec7d3" +dependencies = [ + "rctree", "strict-num", "svgtypes", + "tiny-skia-path", ] [[package]] @@ -6343,12 +6212,6 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - [[package]] name = "version-compare" version = "0.1.1" @@ -6483,23 +6346,7 @@ dependencies = [ "rustix 0.38.26", "scoped-tls", "smallvec", - "wayland-sys 0.31.1", -] - -[[package]] -name = "wayland-client" -version = "0.29.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f3b068c05a039c9f755f881dc50f01732214f5685e379829759088967c46715" -dependencies = [ - "bitflags 1.3.2", - "downcast-rs", - "libc", - "nix 0.24.3", - "scoped-tls", - "wayland-commons", - "wayland-scanner 0.29.5", - "wayland-sys 0.29.5", + "wayland-sys", ] [[package]] @@ -6511,19 +6358,7 @@ dependencies = [ "bitflags 2.4.1", "rustix 0.38.26", "wayland-backend", - "wayland-scanner 0.31.1", -] - -[[package]] -name = "wayland-commons" -version = "0.29.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8691f134d584a33a6606d9d717b95c4fa20065605f798a3f350d78dced02a902" -dependencies = [ - "nix 0.24.3", - "once_cell", - "smallvec", - "wayland-sys 0.29.5", + "wayland-scanner", ] [[package]] @@ -6537,17 +6372,6 @@ dependencies = [ "wayland-backend", ] -[[package]] -name = "wayland-cursor" -version = "0.29.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6865c6b66f13d6257bef1cd40cbfe8ef2f150fb8ebbdb1e8e873455931377661" -dependencies = [ - "nix 0.24.3", - "wayland-client 0.29.5", - "xcursor", -] - [[package]] name = "wayland-cursor" version = "0.31.1" @@ -6555,22 +6379,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71ce5fa868dd13d11a0d04c5e2e65726d0897be8de247c0c5a65886e283231ba" dependencies = [ "rustix 0.38.26", - "wayland-client 0.31.2", + "wayland-client", "xcursor", ] -[[package]] -name = "wayland-protocols" -version = "0.29.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b950621f9354b322ee817a23474e479b34be96c2e909c14f7bc0100e9a970bc6" -dependencies = [ - "bitflags 1.3.2", - "wayland-client 0.29.5", - "wayland-commons", - "wayland-scanner 0.29.5", -] - [[package]] name = "wayland-protocols" version = "0.31.2" @@ -6579,8 +6391,8 @@ checksum = "8f81f365b8b4a97f422ac0e8737c438024b5951734506b0e1d775c73030561f4" dependencies = [ "bitflags 2.4.1", "wayland-backend", - "wayland-client 0.31.2", - "wayland-scanner 0.31.1", + "wayland-client", + "wayland-scanner", ] [[package]] @@ -6591,9 +6403,9 @@ checksum = "23803551115ff9ea9bce586860c5c5a971e360825a0309264102a9495a5ff479" dependencies = [ "bitflags 2.4.1", "wayland-backend", - "wayland-client 0.31.2", - "wayland-protocols 0.31.2", - "wayland-scanner 0.31.1", + "wayland-client", + "wayland-protocols", + "wayland-scanner", ] [[package]] @@ -6604,20 +6416,9 @@ checksum = "ad1f61b76b6c2d8742e10f9ba5c3737f6530b4c243132c2a2ccc8aa96fe25cd6" dependencies = [ "bitflags 2.4.1", "wayland-backend", - "wayland-client 0.31.2", - "wayland-protocols 0.31.2", - "wayland-scanner 0.31.1", -] - -[[package]] -name = "wayland-scanner" -version = "0.29.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f4303d8fa22ab852f789e75a967f0a2cdc430a607751c0499bada3e451cbd53" -dependencies = [ - "proc-macro2", - "quote", - "xml-rs", + "wayland-client", + "wayland-protocols", + "wayland-scanner", ] [[package]] @@ -6631,17 +6432,6 @@ dependencies = [ "quote", ] -[[package]] -name = "wayland-sys" -version = "0.29.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be12ce1a3c39ec7dba25594b97b42cb3195d54953ddb9d3d95a7c3902bc6e9d4" -dependencies = [ - "dlib", - "lazy_static", - "pkg-config", -] - [[package]] name = "wayland-sys" version = "0.31.1" @@ -6841,7 +6631,7 @@ dependencies = [ "block", "core-graphics-types", "d3d12", - "glow 0.13.0", + "glow", "glutin_wgl_sys", "gpu-alloc", "gpu-allocator", @@ -7186,41 +6976,6 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" -[[package]] -name = "winit" -version = "0.28.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9596d90b45384f5281384ab204224876e8e8bf7d58366d9b795ad99aa9894b94" -dependencies = [ - "android-activity 0.4.3", - "bitflags 1.3.2", - "cfg_aliases", - "core-foundation", - "core-graphics 0.22.3", - "dispatch", - "instant", - "libc", - "log", - "mio", - "ndk 0.7.0", - "objc2 0.3.0-beta.3.patch-leaks.3", - "once_cell", - "orbclient", - "percent-encoding", - "raw-window-handle 0.5.2", - "redox_syscall 0.3.5", - "sctk-adwaita 0.5.4", - "smithay-client-toolkit 0.16.1", - "wasm-bindgen", - "wayland-client 0.29.5", - "wayland-commons", - "wayland-protocols 0.29.5", - "wayland-scanner 0.29.5", - "web-sys", - "windows-sys 0.45.0", - "x11-dl", -] - [[package]] name = "winit" version = "0.29.10" @@ -7228,20 +6983,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c824f11941eeae66ec71111cc2674373c772f482b58939bb4066b642aa2ffcf" dependencies = [ "ahash 0.8.6", - "android-activity 0.5.2", + "android-activity", "atomic-waker", "bitflags 2.4.1", "bytemuck", - "calloop 0.12.4", + "calloop", "cfg_aliases", "core-foundation", - "core-graphics 0.23.1", + "core-graphics", "cursor-icon", "icrate", "js-sys", "libc", "log", - "memmap2 0.9.3", + "memmap2", "ndk 0.8.0", "ndk-sys 0.5.0+25.2.9519653", "objc2 0.4.1", @@ -7252,15 +7007,15 @@ dependencies = [ "raw-window-handle 0.6.0", "redox_syscall 0.3.5", "rustix 0.38.26", - "sctk-adwaita 0.8.1", - "smithay-client-toolkit 0.18.0", + "sctk-adwaita", + "smithay-client-toolkit", "smol_str", "unicode-segmentation", "wasm-bindgen", "wasm-bindgen-futures", "wayland-backend", - "wayland-client 0.31.2", - "wayland-protocols 0.31.2", + "wayland-client", + "wayland-protocols", "wayland-protocols-plasma", "web-sys", "web-time", @@ -7416,10 +7171,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a" [[package]] -name = "xmlparser" -version = "0.13.6" +name = "xmlwriter" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4" +checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9" [[package]] name = "yaml-rust" diff --git a/Cargo.toml b/Cargo.toml index ff412968..08fa3e82 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,9 +60,9 @@ categories = ["games"] # Shared dependencies [workspace.dependencies] -egui = "0.24.1" -egui_extras = { version = "0.24.1", features = ["svg", "image"] } -epaint = "0.24.1" +egui = "0.25.0" +egui_extras = { version = "0.25.0", features = ["svg", "image"] } +epaint = "0.25.0" luminol-eframe = { version = "0.4.0", path = "crates/eframe/", features = [ "wgpu", @@ -73,8 +73,8 @@ luminol-eframe = { version = "0.4.0", path = "crates/eframe/", features = [ "wayland", ], default-features = false } luminol-egui-wgpu = { version = "0.4.0", path = "crates/egui-wgpu/" } -egui_glow = "0.24.1" -egui-winit = "0.24.1" +egui_glow = "0.25.0" +egui-winit = "0.25.0" wgpu = { version = "0.18.0", features = ["naga"] } glam = { version = "0.24.2", features = ["bytemuck"] } diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index b26979e3..cda0e472 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -19,9 +19,9 @@ workspace = true [dependencies] egui.workspace = true -egui_dock = "0.9.0" -egui-notify = "0.11.0" -egui-modal = "0.3.1" +egui_dock = "0.10.0" +egui-notify = "0.12.0" +egui-modal = "0.3.2" poll-promise.workspace = true diff --git a/crates/ui/Cargo.toml b/crates/ui/Cargo.toml index b80e1fa6..86975edb 100644 --- a/crates/ui/Cargo.toml +++ b/crates/ui/Cargo.toml @@ -28,7 +28,7 @@ luminol-modals.workspace = true egui.workspace = true -catppuccin-egui = { version = "3.1.0", git = "https://github.com/catppuccin/egui", rev = "bcb5849b6f96b56aa4982ec3366e238371de473e" } +catppuccin-egui = "4.0.0" camino.workspace = true From 14490622106cdbd26c37bdb03dfd0cd395baa197 Mon Sep 17 00:00:00 2001 From: white-axe Date: Tue, 30 Jan 2024 20:39:12 -0500 Subject: [PATCH 09/20] chore: fix update-induced compilation errors --- crates/components/src/ui_ext.rs | 1 - crates/term/src/_impl/mod.rs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/crates/components/src/ui_ext.rs b/crates/components/src/ui_ext.rs index 6d852913..669234ea 100644 --- a/crates/components/src/ui_ext.rs +++ b/crates/components/src/ui_ext.rs @@ -59,7 +59,6 @@ impl UiExt for egui::Ui { ) -> f32 { Into::::into(text) .into_galley(self, None, f32::INFINITY, font) - .galley .rect .width() } diff --git a/crates/term/src/_impl/mod.rs b/crates/term/src/_impl/mod.rs index 5f6c66a1..f61aed68 100644 --- a/crates/term/src/_impl/mod.rs +++ b/crates/term/src/_impl/mod.rs @@ -341,7 +341,7 @@ impl Terminal { palette.background.into_egui(), ); - painter.galley(response.rect.min, galley); + painter.galley(response.rect.min, galley, egui::Color32::TRANSPARENT); painter.rect_stroke( egui::Rect::from_min_size( From 5be5eedfe963574d4d51825a22db95d918d6ae90 Mon Sep 17 00:00:00 2001 From: white-axe Date: Tue, 30 Jan 2024 21:26:49 -0500 Subject: [PATCH 10/20] chore: clippy --- crates/eframe/src/native/run.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/crates/eframe/src/native/run.rs b/crates/eframe/src/native/run.rs index 95e355a1..d5c172c3 100644 --- a/crates/eframe/src/native/run.rs +++ b/crates/eframe/src/native/run.rs @@ -385,10 +385,11 @@ pub fn run_glow( #[cfg(not(target_os = "ios"))] if native_options.run_and_return { - return with_event_loop(native_options, |event_loop, native_options| { + let result = with_event_loop(native_options, |event_loop, native_options| { let glow_eframe = GlowWinitApp::new(event_loop, app_name, native_options, app_creator); run_and_return(event_loop, glow_eframe) })?; + return result; } let event_loop = create_event_loop(&mut native_options)?; @@ -408,10 +409,11 @@ pub fn run_wgpu( #[cfg(not(target_os = "ios"))] if native_options.run_and_return { - return with_event_loop(native_options, |event_loop, native_options| { + let result = with_event_loop(native_options, |event_loop, native_options| { let wgpu_eframe = WgpuWinitApp::new(event_loop, app_name, native_options, app_creator); run_and_return(event_loop, wgpu_eframe) })?; + return result; } let event_loop = create_event_loop(&mut native_options)?; From b86131555d2c4fb5e35f4d2bfcee6891bea0de75 Mon Sep 17 00:00:00 2001 From: white-axe Date: Tue, 30 Jan 2024 21:54:36 -0500 Subject: [PATCH 11/20] merge: update wgpu to 0.19 Based on https://github.com/emilk/egui/pull/3824 --- Cargo.lock | 224 ++++++++++-------- Cargo.toml | 5 +- crates/eframe/Cargo.toml | 31 ++- crates/eframe/README.md | 2 +- crates/eframe/src/epi.rs | 45 ++-- crates/eframe/src/native/epi_integration.rs | 6 +- crates/eframe/src/native/glow_integration.rs | 37 +-- crates/eframe/src/native/wgpu_integration.rs | 30 ++- crates/eframe/src/native/winit_integration.rs | 4 +- crates/eframe/src/web/web_logger.rs | 17 +- crates/eframe/src/web/web_painter_wgpu.rs | 48 +++- crates/eframe/src/web/web_runner.rs | 4 +- crates/egui-wgpu/Cargo.toml | 4 +- crates/egui-wgpu/README.md | 2 +- crates/egui-wgpu/src/lib.rs | 66 ++++-- crates/egui-wgpu/src/renderer.rs | 6 + crates/egui-wgpu/src/winit.rs | 166 +++++++------ crates/graphics/Cargo.toml | 4 +- 18 files changed, 437 insertions(+), 264 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cefe047c..bb43301d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -102,7 +102,7 @@ dependencies = [ "macroific", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -464,7 +464,7 @@ checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -525,7 +525,7 @@ checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -663,7 +663,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -803,7 +803,7 @@ checksum = "965ab7eb5f8f97d2a083c799f3a1b994fc397b2fe2da5d1da1626ce15a39f2b1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -1027,10 +1027,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" [[package]] -name = "com-rs" -version = "0.2.1" +name = "com" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e17887fd17353b65b1b2ef1c526c83e26cd72e74f598a8dc1bee13a48f3d9f6" +dependencies = [ + "com_macros", +] + +[[package]] +name = "com_macros" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf43edc576402991846b093a7ca18a3477e0ef9c588cde84964b5d3e43016642" +checksum = "d375883580a668c7481ea6631fc1a8863e33cc335bf56bfad8d7e6d4b04b13a5" +dependencies = [ + "com_macros_support", + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "com_macros_support" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad899a1087a9296d5644792d7cb72b8e34c1bec8e7d4fbc002230169a6e8710c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] [[package]] name = "combine" @@ -1274,9 +1299,9 @@ checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991" [[package]] name = "d3d12" -version = "0.7.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e16e44ab292b1dddfdaf7be62cfd8877df52f2f3fde5858d95bab606be259f20" +checksum = "3e3d747f100290a1ca24b752186f61f6637e1deffe3bf6320de6fcb29510a307" dependencies = [ "bitflags 2.4.1", "libloading 0.8.1", @@ -1323,7 +1348,7 @@ dependencies = [ "macroific", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -1601,7 +1626,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -1622,7 +1647,7 @@ checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -1643,7 +1668,7 @@ checksum = "f95e2801cd355d4a1a3e3953ce6ee5ae9603a5c833455343a8bfe3f44d418246" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -1654,7 +1679,7 @@ checksum = "c2ad8cef1d801a4686bfd8919f0b30eac4c8e48968c437a6405ded4fb5272d2b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -1783,7 +1808,7 @@ dependencies = [ "macroific", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -1892,7 +1917,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -2006,7 +2031,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -2180,7 +2205,7 @@ checksum = "53010ccb100b96a67bc32c0175f0ed1426b31b655d562898e57325f81c023ac0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -2233,9 +2258,9 @@ dependencies = [ [[package]] name = "glow" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "886c2a30b160c4c6fec8f987430c26b526b7988ca71f664e6a699ddf6f9601e4" +checksum = "bd348e04c43b32574f2de31c8bb397d96c9fcfa1371bd4ca6d8bdc464ab121b1" dependencies = [ "js-sys", "slotmap", @@ -2340,11 +2365,10 @@ dependencies = [ [[package]] name = "gpu-allocator" -version = "0.23.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40fe17c8a05d60c38c0a4e5a3c802f2f1ceb66b76c67d96ffb34bef0475a7fad" +checksum = "6f56f6318968d03c18e1bcf4857ff88c61157e9da8e47c5f29055d60e1228884" dependencies = [ - "backtrace", "log", "presser", "thiserror", @@ -2439,14 +2463,14 @@ dependencies = [ [[package]] name = "hassle-rs" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1397650ee315e8891a0df210707f0fc61771b0cc518c3023896064c5407cb3b0" +checksum = "af2a7e73e1f34c48da31fb668a907f250794837e08faa144fd24f0b8b741e890" dependencies = [ - "bitflags 1.3.2", - "com-rs", + "bitflags 2.4.1", + "com", "libc", - "libloading 0.7.4", + "libloading 0.8.1", "thiserror", "widestring", "winapi", @@ -2801,9 +2825,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.66" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" +checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" dependencies = [ "wasm-bindgen", ] @@ -3185,6 +3209,7 @@ dependencies = [ "portable-atomic", "puffin", "raw-window-handle 0.5.2", + "raw-window-handle 0.6.0", "ron", "serde", "static_assertions", @@ -3380,7 +3405,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -3391,7 +3416,7 @@ checksum = "13198c120864097a565ccb3ff947672d969932b7975ebd4085732c9f09435e55" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -3404,7 +3429,7 @@ dependencies = [ "macroific_core", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -3508,7 +3533,7 @@ checksum = "49e7bc1560b95a3c4a25d03de42fe76ca718ab92d1a22a55b9b4cf67b3ae635c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -3566,9 +3591,9 @@ dependencies = [ [[package]] name = "naga" -version = "0.14.1" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cd05939c491da968a42986204b7431678be21fdcd4b10cc84997ba130ada5a4" +checksum = "8878eb410fc90853da3908aebfe61d73d26d4437ef850b70050461f939509899" dependencies = [ "bit-set", "bitflags 2.4.1", @@ -3587,9 +3612,9 @@ dependencies = [ [[package]] name = "naga_oil" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fff3f369dd665ee365daeab786466a6f70ff53e4a95a76117363b1077e1b0492" +checksum = "86343242cc8fe7c38de0324f0c13a789729f3d360d98de12c464a815ad52feda" dependencies = [ "bit-set", "codespan-reporting", @@ -3598,7 +3623,7 @@ dependencies = [ "naga", "once_cell", "regex", - "regex-syntax 0.7.5", + "regex-syntax 0.8.2", "rustc-hash", "thiserror", "tracing", @@ -3859,7 +3884,7 @@ dependencies = [ "proc-macro-crate 2.0.0", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -3992,9 +4017,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "oneshot" @@ -4034,7 +4059,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -4207,7 +4232,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -4280,7 +4305,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -4324,7 +4349,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -4530,9 +4555,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.70" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] @@ -4585,9 +4610,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -5055,7 +5080,7 @@ checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -5077,7 +5102,7 @@ checksum = "3081f5ffbb02284dda55132aa26daecedd7372a42417bbbab6f14ab7d6bb9145" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -5350,12 +5375,11 @@ dependencies = [ [[package]] name = "spirv" -version = "0.2.0+1.5.4" +version = "0.3.0+sdk-1.3.268.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "246bfa38fe3db3f1dfc8ca5a2cdeb7348c78be2112740cc0ec8ef18b6d94f830" +checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" dependencies = [ - "bitflags 1.3.2", - "num-traits", + "bitflags 2.4.1", ] [[package]] @@ -5422,7 +5446,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -5498,9 +5522,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.39" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", @@ -5583,9 +5607,9 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] @@ -5666,22 +5690,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.50" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.50" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -5831,7 +5855,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -5948,7 +5972,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] @@ -6271,9 +6295,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" +checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -6281,24 +6305,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" +checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.39" +version = "0.4.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12" +checksum = "bde2032aeb86bdfaecc8b261eef3cba735cc426c1f3a3416d1e0791be95fc461" dependencies = [ "cfg-if", "js-sys", @@ -6308,9 +6332,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" +checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -6318,22 +6342,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" +checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" +checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" [[package]] name = "wayland-backend" @@ -6446,9 +6470,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.64" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" dependencies = [ "js-sys", "wasm-bindgen", @@ -6571,19 +6595,19 @@ dependencies = [ [[package]] name = "wgpu" -version = "0.18.0" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30e7d227c9f961f2061c26f4cb0fbd4df0ef37e056edd0931783599d6c94ef24" +checksum = "0bfe9a310dcf2e6b85f00c46059aaeaf4184caa8e29a1ecd4b7a704c3482332d" dependencies = [ "arrayvec", "cfg-if", - "flume", + "cfg_aliases", "js-sys", "log", "naga", "parking_lot", "profiling", - "raw-window-handle 0.5.2", + "raw-window-handle 0.6.0", "smallvec", "static_assertions", "wasm-bindgen", @@ -6596,19 +6620,22 @@ dependencies = [ [[package]] name = "wgpu-core" -version = "0.18.1" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef91c1d62d1e9e81c79e600131a258edf75c9531cbdbde09c44a011a47312726" +checksum = "6b15e451d4060ada0d99a64df44e4d590213496da7c4f245572d51071e8e30ed" dependencies = [ "arrayvec", "bit-vec", "bitflags 2.4.1", + "cfg_aliases", "codespan-reporting", + "indexmap", "log", "naga", + "once_cell", "parking_lot", "profiling", - "raw-window-handle 0.5.2", + "raw-window-handle 0.6.0", "rustc-hash", "smallvec", "thiserror", @@ -6619,9 +6646,9 @@ dependencies = [ [[package]] name = "wgpu-hal" -version = "0.18.1" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b84ecc802da3eb67b4cf3dd9ea6fe45bbb47ef13e6c49c5c3240868a9cc6cdd9" +checksum = "e3bb47856236bfafc0bc591a925eb036ac19cd987624a447ff353e7a7e7e6f72" dependencies = [ "android_system_properties", "arrayvec", @@ -6629,6 +6656,7 @@ dependencies = [ "bit-set", "bitflags 2.4.1", "block", + "cfg_aliases", "core-graphics-types", "d3d12", "glow", @@ -6649,7 +6677,7 @@ dependencies = [ "parking_lot", "profiling", "range-alloc", - "raw-window-handle 0.5.2", + "raw-window-handle 0.6.0", "renderdoc-sys", "rustc-hash", "smallvec", @@ -6662,9 +6690,9 @@ dependencies = [ [[package]] name = "wgpu-types" -version = "0.18.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d5ed5f0edf0de351fe311c53304986315ce866f394a2e6df0c4b3c70774bcdd" +checksum = "895fcbeb772bfb049eb80b2d6e47f6c9af235284e9703c96fc0218a42ffd5af2" dependencies = [ "bitflags 2.4.1", "js-sys", @@ -7268,7 +7296,7 @@ checksum = "b3c129550b3e6de3fd0ba67ba5c81818f9805e58b8d7fee80a3a59d2c9fc601a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.48", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 08fa3e82..48b13244 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -76,7 +76,7 @@ luminol-egui-wgpu = { version = "0.4.0", path = "crates/egui-wgpu/" } egui_glow = "0.25.0" egui-winit = "0.25.0" -wgpu = { version = "0.18.0", features = ["naga"] } +wgpu = { version = "0.19.1", features = ["naga-ir"] } glam = { version = "0.24.2", features = ["bytemuck"] } image = "0.24.7" @@ -99,7 +99,8 @@ thiserror = "1.0.37" bitflags = "2.4.0" color-eyre = "0.6.2" puffin = "0.18" -raw-window-handle = "0.5.0" +raw-window-handle = "0.6.0" +winit = { version = "0.29.4", default-features = false } glow = "0.13" parking_lot = { version = "0.12.1", features = [ diff --git a/crates/eframe/Cargo.toml b/crates/eframe/Cargo.toml index e4852151..b32eeaea 100644 --- a/crates/eframe/Cargo.toml +++ b/crates/eframe/Cargo.toml @@ -56,7 +56,14 @@ android-native-activity = ["egui-winit/android-native-activity"] default_fonts = ["egui/default_fonts"] ## Use [`glow`](https://github.com/grovesNL/glow) for painting, via [`egui_glow`](https://github.com/emilk/egui/tree/master/crates/egui_glow). -#glow = ["dep:glow", "dep:egui_glow", "dep:glutin", "dep:glutin-winit"] +#glow = [ +# "dep:egui_glow", +# "dep:glow", +# "dep:glutin-winit", +# "dep:glutin", +# "dep:rwh_05", +# "winit/rwh_05", +#] ## Enable saving app state to disk. persistence = [ @@ -92,8 +99,19 @@ web_screen_reader = [ ] ## 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:luminol-egui-wgpu", "dep:pollster", "dep:raw-window-handle"] +## +## By default, only WebGPU is enabled on web. +## If you want to enable WebGL, you need to turn on the `webgl` feature of crate `wgpu`: +## +## ```ignore +## wgpu = { version = "*", features = ["webgpu", "webgl"] } +## ``` +## +## By default, eframe will prefer WebGPU over WebGL, but +## you can configure this at run-time with [`NativeOptions::wgpu_options`]. +wgpu = ["dep:wgpu", "dep:luminol-egui-wgpu", "dep:pollster"] ## Enables compiling for x11. x11 = ["egui-winit/x11"] @@ -109,6 +127,7 @@ egui = { workspace = true, features = [ ] } log = { version = "0.4", features = ["std"] } parking_lot = "0.12" +raw-window-handle.workspace = true static_assertions = "1.1.0" thiserror.workspace = true @@ -118,6 +137,10 @@ document-features = { version = "0.2", optional = true } egui_glow = { workspace = true, optional = true } glow = { workspace = true, optional = true } +# glutin stuck on old version of raw-window-handle: +rwh_05 = { package = "raw-window-handle", version = "0.5.2", optional = true, features = [ + "std", +] } ron = { workspace = true, optional = true, features = ["integer128"] } serde = { version = "1", optional = true, features = ["derive"] } @@ -131,8 +154,7 @@ egui-winit = { workspace = true, features = [ image = { version = "0.24", default-features = false, features = [ "png", ] } # Needed for app icon -raw-window-handle.workspace = true -winit = { version = "0.29.4", default-features = false, features = ["rwh_05"] } +winit = { workspace = true, default-features = false, features = ["rwh_06"] } # optional native: directories-next = { version = "2", optional = true } @@ -227,5 +249,4 @@ luminol-web = { version = "0.4.0", path = "../web/" } # optional web: luminol-egui-wgpu = { workspace = true, optional = true } # if wgpu is used, use it without (!) winit -raw-window-handle = { workspace = true, optional = true } wgpu = { workspace = true, optional = true } diff --git a/crates/eframe/README.md b/crates/eframe/README.md index f8ffb330..775a65dd 100644 --- a/crates/eframe/README.md +++ b/crates/eframe/README.md @@ -1,5 +1,5 @@ > [!IMPORTANT] -> luminol-eframe is currently based on emilk/egui@0.25.0 +> luminol-eframe is currently based on emilk/egui@b766a48fa7fe4f6a25622ebe2e5677c09553cda9 > [!NOTE] > This is Luminol's modified version of eframe. The original version is dual-licensed under MIT and Apache 2.0. diff --git a/crates/eframe/src/epi.rs b/crates/eframe/src/epi.rs index 3abfb298..6b86c0b5 100644 --- a/crates/eframe/src/epi.rs +++ b/crates/eframe/src/epi.rs @@ -15,7 +15,8 @@ pub use crate::native::winit_integration::UserEvent; #[cfg(not(target_arch = "wasm32"))] use raw_window_handle::{ - HasRawDisplayHandle, HasRawWindowHandle, RawDisplayHandle, RawWindowHandle, + DisplayHandle, HandleError, HasDisplayHandle, HasWindowHandle, RawDisplayHandle, + RawWindowHandle, WindowHandle, }; #[cfg(not(target_arch = "wasm32"))] use static_assertions::assert_not_impl_any; @@ -76,30 +77,28 @@ pub struct CreationContext<'s> { /// Raw platform window handle #[cfg(not(target_arch = "wasm32"))] - pub(crate) raw_window_handle: RawWindowHandle, + pub(crate) raw_window_handle: Result, /// Raw platform display handle for window #[cfg(not(target_arch = "wasm32"))] - pub(crate) raw_display_handle: RawDisplayHandle, + pub(crate) raw_display_handle: Result, } -// Implementing `Clone` would violate the guarantees of `HasRawWindowHandle` and `HasRawDisplayHandle`. -#[cfg(not(target_arch = "wasm32"))] -assert_not_impl_any!(CreationContext<'_>: Clone); - #[allow(unsafe_code)] #[cfg(not(target_arch = "wasm32"))] -unsafe impl HasRawWindowHandle for CreationContext<'_> { - fn raw_window_handle(&self) -> RawWindowHandle { - self.raw_window_handle +impl HasWindowHandle for CreationContext<'_> { + fn window_handle(&self) -> Result, HandleError> { + // Safety: the lifetime is correct. + unsafe { Ok(WindowHandle::borrow_raw(self.raw_window_handle.clone()?)) } } } #[allow(unsafe_code)] #[cfg(not(target_arch = "wasm32"))] -unsafe impl HasRawDisplayHandle for CreationContext<'_> { - fn raw_display_handle(&self) -> RawDisplayHandle { - self.raw_display_handle +impl HasDisplayHandle for CreationContext<'_> { + fn display_handle(&self) -> Result, HandleError> { + // Safety: the lifetime is correct. + unsafe { Ok(DisplayHandle::borrow_raw(self.raw_display_handle.clone()?)) } } } @@ -599,30 +598,32 @@ pub struct Frame { /// Raw platform window handle #[cfg(not(target_arch = "wasm32"))] - pub(crate) raw_window_handle: RawWindowHandle, + pub(crate) raw_window_handle: Result, /// Raw platform display handle for window #[cfg(not(target_arch = "wasm32"))] - pub(crate) raw_display_handle: RawDisplayHandle, + pub(crate) raw_display_handle: Result, } -// Implementing `Clone` would violate the guarantees of `HasRawWindowHandle` and `HasRawDisplayHandle`. +// Implementing `Clone` would violate the guarantees of `HasWindowHandle` and `HasDisplayHandle`. #[cfg(not(target_arch = "wasm32"))] assert_not_impl_any!(Frame: Clone); #[allow(unsafe_code)] #[cfg(not(target_arch = "wasm32"))] -unsafe impl HasRawWindowHandle for Frame { - fn raw_window_handle(&self) -> RawWindowHandle { - self.raw_window_handle +impl HasWindowHandle for Frame { + fn window_handle(&self) -> Result, HandleError> { + // Safety: the lifetime is correct. + unsafe { Ok(WindowHandle::borrow_raw(self.raw_window_handle.clone()?)) } } } #[allow(unsafe_code)] #[cfg(not(target_arch = "wasm32"))] -unsafe impl HasRawDisplayHandle for Frame { - fn raw_display_handle(&self) -> RawDisplayHandle { - self.raw_display_handle +impl HasDisplayHandle for Frame { + fn display_handle(&self) -> Result, HandleError> { + // Safety: the lifetime is correct. + unsafe { Ok(DisplayHandle::borrow_raw(self.raw_display_handle.clone()?)) } } } diff --git a/crates/eframe/src/native/epi_integration.rs b/crates/eframe/src/native/epi_integration.rs index 4f017536..c5b98063 100644 --- a/crates/eframe/src/native/epi_integration.rs +++ b/crates/eframe/src/native/epi_integration.rs @@ -4,7 +4,7 @@ use std::time::Instant; use winit::event_loop::EventLoopWindowTarget; -use raw_window_handle::{HasRawDisplayHandle as _, HasRawWindowHandle as _}; +use raw_window_handle::{HasDisplayHandle as _, HasWindowHandle as _}; use egui::{DeferredViewportUiCallback, NumExt as _, ViewportBuilder, ViewportId}; use egui_winit::{EventResponse, WindowSettings}; @@ -165,8 +165,8 @@ impl EpiIntegration { gl, #[cfg(feature = "wgpu")] wgpu_render_state, - raw_display_handle: window.raw_display_handle(), - raw_window_handle: window.raw_window_handle(), + raw_display_handle: window.display_handle().map(|h| h.as_raw()), + raw_window_handle: window.window_handle().map(|h| h.as_raw()), }; let icon = native_options diff --git a/crates/eframe/src/native/glow_integration.rs b/crates/eframe/src/native/glow_integration.rs index 537e7394..75820bec 100644 --- a/crates/eframe/src/native/glow_integration.rs +++ b/crates/eframe/src/native/glow_integration.rs @@ -16,7 +16,6 @@ use glutin::{ prelude::{GlDisplay, PossiblyCurrentGlContext}, surface::GlSurface, }; -use raw_window_handle::{HasRawDisplayHandle as _, HasRawWindowHandle as _}; use winit::{ event_loop::{EventLoop, EventLoopProxy, EventLoopWindowTarget}, window::{Window, WindowId}, @@ -126,7 +125,7 @@ struct Viewport { // These three live and die together. // TODO(emilk): clump them together into one struct! gl_surface: Option>, - window: Option>, + window: Option>, egui_winit: Option, } @@ -294,6 +293,9 @@ impl GlowWinitApp { .expect("Single-use AppCreator has unexpectedly already been taken"); let app = { + // Use latest raw_window_handle for eframe compatibility + use raw_window_handle::{HasDisplayHandle as _, HasWindowHandle as _}; + let window = glutin.window(ViewportId::ROOT); let cc = CreationContext { egui_ctx: integration.egui_ctx.clone(), @@ -302,8 +304,8 @@ impl GlowWinitApp { gl: Some(gl), #[cfg(feature = "wgpu")] wgpu_render_state: None, - raw_display_handle: window.raw_display_handle(), - raw_window_handle: window.raw_window_handle(), + raw_display_handle: window.display_handle().map(|h| h.as_raw()), + raw_window_handle: window.window_handle().map(|h| h.as_raw()), }; crate::profile_scope!("app_creator"); app_creator(&cc) @@ -373,7 +375,7 @@ impl WinitApp for GlowWinitApp { self.running.as_ref().map(|r| &r.integration) } - fn window(&self, window_id: WindowId) -> Option> { + fn window(&self, window_id: WindowId) -> Option> { let running = self.running.as_ref()?; let glutin = running.glutin.borrow(); let viewport_id = *glutin.viewport_from_window.get(&window_id)?; @@ -898,15 +900,18 @@ impl GlutinWindowContext { gl_display.version_string(), gl_display.supported_features() ); - let raw_window_handle = window.as_ref().map(|w| w.raw_window_handle()); - log::debug!("creating gl context using raw window handle: {raw_window_handle:?}"); + let glutin_raw_window_handle = window.as_ref().map(|w| { + use rwh_05::HasRawWindowHandle as _; // glutin stuck on old version of raw-window-handle + w.raw_window_handle() + }); + log::debug!("creating gl context using raw window handle: {glutin_raw_window_handle:?}"); // create gl context. if core context cannot be created, try gl es context as fallback. let context_attributes = - glutin::context::ContextAttributesBuilder::new().build(raw_window_handle); + glutin::context::ContextAttributesBuilder::new().build(glutin_raw_window_handle); let fallback_context_attributes = glutin::context::ContextAttributesBuilder::new() .with_context_api(glutin::context::ContextApi::Gles(None)) - .build(raw_window_handle); + .build(glutin_raw_window_handle); let gl_context_result = unsafe { crate::profile_scope!("create_context"); @@ -952,7 +957,7 @@ impl GlutinWindowContext { screenshot_requested: false, viewport_ui_cb: None, gl_surface: None, - window: window.map(Rc::new), + window: window.map(Arc::new), egui_winit: None, }, ); @@ -962,7 +967,7 @@ impl GlutinWindowContext { // help us start from scratch again if we fail context creation and go back to preferEgl or try with different config etc.. // https://github.com/emilk/egui/pull/2541#issuecomment-1370767582 - let mut slf = GlutinWindowContext { + let mut slf = Self { egui_ctx: egui_ctx.clone(), swap_interval, gl_config, @@ -1031,7 +1036,7 @@ impl GlutinWindowContext { ); viewport.info.minimized = window.is_minimized(); viewport.info.maximized = Some(window.is_maximized()); - viewport.window.insert(Rc::new(window)) + viewport.window.insert(Arc::new(window)) }; viewport.egui_winit.get_or_insert_with(|| { @@ -1052,9 +1057,11 @@ impl GlutinWindowContext { let (width_px, height_px): (u32, u32) = window.inner_size().into(); let width_px = std::num::NonZeroU32::new(width_px.at_least(1)).unwrap(); let height_px = std::num::NonZeroU32::new(height_px.at_least(1)).unwrap(); - let surface_attributes = + let surface_attributes = { + use rwh_05::HasRawWindowHandle as _; // glutin stuck on old version of raw-window-handle glutin::surface::SurfaceAttributesBuilder::::new() - .build(window.raw_window_handle(), width_px, height_px); + .build(window.raw_window_handle(), width_px, height_px) + }; log::trace!("creating surface with attributes: {surface_attributes:?}"); let gl_surface = unsafe { @@ -1120,7 +1127,7 @@ impl GlutinWindowContext { .expect("viewport doesn't exist") } - fn window(&self, viewport_id: ViewportId) -> Rc { + fn window(&self, viewport_id: ViewportId) -> Arc { self.viewport(viewport_id) .window .clone() diff --git a/crates/eframe/src/native/wgpu_integration.rs b/crates/eframe/src/native/wgpu_integration.rs index 7bd5b38e..d0a6d27c 100644 --- a/crates/eframe/src/native/wgpu_integration.rs +++ b/crates/eframe/src/native/wgpu_integration.rs @@ -8,7 +8,7 @@ use std::{cell::RefCell, rc::Rc, sync::Arc, time::Instant}; use parking_lot::Mutex; -use raw_window_handle::{HasRawDisplayHandle as _, HasRawWindowHandle as _}; +use raw_window_handle::{HasDisplayHandle as _, HasWindowHandle as _}; use winit::{ event_loop::{EventLoop, EventLoopProxy, EventLoopWindowTarget}, window::{Window, WindowId}, @@ -84,7 +84,7 @@ pub struct Viewport { /// Window surface state that's initialized when the app starts running via a Resumed event /// and on Android will also be destroyed if the application is paused. - window: Option>, + window: Option>, /// `window` and `egui_winit` are initialized together. egui_winit: Option, @@ -170,9 +170,11 @@ impl WgpuWinitApp { self.native_options.viewport.transparent.unwrap_or(false), ); + let window = Arc::new(window); + { crate::profile_scope!("set_window"); - pollster::block_on(painter.set_window(ViewportId::ROOT, Some(&window)))?; + pollster::block_on(painter.set_window(ViewportId::ROOT, Some(window.clone())))?; } let wgpu_render_state = painter.render_state(); @@ -235,8 +237,8 @@ impl WgpuWinitApp { #[cfg(feature = "glow")] gl: None, wgpu_render_state, - raw_display_handle: window.raw_display_handle(), - raw_window_handle: window.raw_window_handle(), + raw_display_handle: window.display_handle().map(|h| h.as_raw()), + raw_window_handle: window.window_handle().map(|h| h.as_raw()), }; let app = { crate::profile_scope!("user_app_creator"); @@ -260,7 +262,7 @@ impl WgpuWinitApp { }, screenshot_requested: false, viewport_ui_cb: None, - window: Some(Rc::new(window)), + window: Some(window), egui_winit: Some(egui_winit), }, ); @@ -323,7 +325,7 @@ impl WinitApp for WgpuWinitApp { self.running.as_ref().map(|r| &r.integration) } - fn window(&self, window_id: WindowId) -> Option> { + fn window(&self, window_id: WindowId) -> Option> { self.running .as_ref() .and_then(|r| { @@ -492,7 +494,7 @@ impl WgpuWinitRunning { #[cfg(feature = "puffin")] puffin::GlobalProfiler::lock().new_frame(); - let WgpuWinitRunning { + let Self { app, integration, shared, @@ -544,7 +546,8 @@ impl WgpuWinitRunning { { crate::profile_scope!("set_window"); - if let Err(err) = pollster::block_on(painter.set_window(viewport_id, Some(window))) + if let Err(err) = + pollster::block_on(painter.set_window(viewport_id, Some(window.clone()))) { log::warn!("Failed to set window: {err}"); } @@ -797,7 +800,10 @@ impl Viewport { Ok(window) => { windows_id.insert(window.id(), viewport_id); - if let Err(err) = pollster::block_on(painter.set_window(viewport_id, Some(&window))) + let window = Arc::new(window); + + if let Err(err) = + pollster::block_on(painter.set_window(viewport_id, Some(window.clone()))) { log::error!("on set_window: viewport_id {viewport_id:?} {err}"); } @@ -813,7 +819,7 @@ impl Viewport { self.info.minimized = window.is_minimized(); self.info.maximized = Some(window.is_maximized()); - self.window = Some(Rc::new(window)); + self.window = Some(window); } Err(err) => { log::error!("Failed to create window: {err}"); @@ -930,7 +936,7 @@ fn render_immediate_viewport( { crate::profile_scope!("set_window"); - if let Err(err) = pollster::block_on(painter.set_window(ids.this, Some(window))) { + if let Err(err) = pollster::block_on(painter.set_window(ids.this, Some(window.clone()))) { log::error!( "when rendering viewport_id={:?}, set_window Error {err}", ids.this diff --git a/crates/eframe/src/native/winit_integration.rs b/crates/eframe/src/native/winit_integration.rs index a7e4bb38..541253c0 100644 --- a/crates/eframe/src/native/winit_integration.rs +++ b/crates/eframe/src/native/winit_integration.rs @@ -1,4 +1,4 @@ -use std::{rc::Rc, time::Instant}; +use std::{sync::Arc, time::Instant}; use winit::{ event_loop::EventLoopWindowTarget, @@ -68,7 +68,7 @@ pub trait WinitApp { fn integration(&self) -> Option<&EpiIntegration>; - fn window(&self, window_id: WindowId) -> Option>; + fn window(&self, window_id: WindowId) -> Option>; fn window_id_from_viewport_id(&self, id: ViewportId) -> Option; diff --git a/crates/eframe/src/web/web_logger.rs b/crates/eframe/src/web/web_logger.rs index 90dfc1b3..18936495 100644 --- a/crates/eframe/src/web/web_logger.rs +++ b/crates/eframe/src/web/web_logger.rs @@ -7,7 +7,7 @@ impl WebLogger { /// Install a new `WebLogger`, piping all [`log`] events to the web console. pub fn init(filter: log::LevelFilter) -> Result<(), log::SetLoggerError> { log::set_max_level(filter); - log::set_boxed_logger(Box::new(WebLogger::new(filter))) + log::set_boxed_logger(Box::new(Self::new(filter))) } /// Create a new [`WebLogger`] with the given filter, @@ -19,6 +19,21 @@ impl WebLogger { impl log::Log for WebLogger { fn enabled(&self, metadata: &log::Metadata<'_>) -> bool { + /// Never log anything less serious than a `INFO` from these crates. + const CRATES_AT_INFO_LEVEL: &[&str] = &[ + // wgpu crates spam a lot on debug level, which is really annoying + "naga", + "wgpu_core", + "wgpu_hal", + ]; + + if CRATES_AT_INFO_LEVEL + .iter() + .any(|crate_name| metadata.target().starts_with(crate_name)) + { + return metadata.level() <= log::LevelFilter::Info; + } + metadata.level() <= self.filter } diff --git a/crates/eframe/src/web/web_painter_wgpu.rs b/crates/eframe/src/web/web_painter_wgpu.rs index 343d8031..28c150cf 100644 --- a/crates/eframe/src/web/web_painter_wgpu.rs +++ b/crates/eframe/src/web/web_painter_wgpu.rs @@ -1,5 +1,9 @@ use std::sync::Arc; +use raw_window_handle::{ + DisplayHandle, HandleError, HasDisplayHandle, HasWindowHandle, RawDisplayHandle, + RawWindowHandle, WebDisplayHandle, WebWindowHandle, WindowHandle, +}; use wasm_bindgen::JsValue; use luminol_egui_wgpu::{renderer::ScreenDescriptor, RenderState, SurfaceErrorAction}; @@ -11,24 +15,32 @@ 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) +impl HasWindowHandle for EguiWebWindow { + fn window_handle(&self) -> Result, HandleError> { + // SAFETY: there is no lifetime here. + unsafe { + Ok(WindowHandle::borrow_raw(RawWindowHandle::Web( + WebWindowHandle::new(self.0), + ))) + } } } #[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()) +impl HasDisplayHandle for EguiWebWindow { + fn display_handle(&self) -> Result, HandleError> { + // SAFETY: there is no lifetime here. + unsafe { + Ok(DisplayHandle::borrow_raw(RawDisplayHandle::Web( + WebDisplayHandle::new(), + ))) + } } } pub(crate) struct WebPainterWgpu { canvas: web_sys::OffscreenCanvas, - surface: wgpu::Surface, + surface: wgpu::Surface<'static>, pub(super) surface_configuration: wgpu::SurfaceConfiguration, render_state: Option, on_surface_error: Arc SurfaceErrorAction>, @@ -84,13 +96,22 @@ impl WebPainterWgpu { ) -> Result { log::debug!("Creating wgpu painter"); + { + let is_secure_context = web_sys::window().map_or(false, |w| w.is_secure_context()); + if !is_secure_context { + log::info!( + "WebGPU is only available in secure contexts, i.e. on HTTPS and on localhost" + ); + } + } + let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { backends: options.wgpu_options.supported_backends, ..Default::default() }); let surface = instance - .create_surface_from_offscreen_canvas(canvas.clone()) + .create_surface(wgpu::SurfaceTarget::OffscreenCanvas(canvas.clone())) .map_err(|err| format!("failed to create wgpu surface: {err}"))?; let depth_format = luminol_egui_wgpu::depth_format_from_bits(options.depth_buffer, 0); @@ -99,14 +120,17 @@ impl WebPainterWgpu { .await .map_err(|err| err.to_string())?; + let (width, height) = (0, 0); + let surface_configuration = wgpu::SurfaceConfiguration { usage: wgpu::TextureUsages::RENDER_ATTACHMENT, format: render_state.target_format, - width: 0, - height: 0, present_mode: options.wgpu_options.present_mode, alpha_mode: wgpu::CompositeAlphaMode::Auto, view_formats: vec![render_state.target_format], + ..surface + .get_default_config(&render_state.adapter, width, height) + .ok_or("The surface isn't supported by this adapter")? }; log::debug!("wgpu painter initialized."); diff --git a/crates/eframe/src/web/web_runner.rs b/crates/eframe/src/web/web_runner.rs index c0d827bb..df8c963f 100644 --- a/crates/eframe/src/web/web_runner.rs +++ b/crates/eframe/src/web/web_runner.rs @@ -247,14 +247,14 @@ enum EventToUnsubscribe { impl EventToUnsubscribe { pub fn unsubscribe(self) -> Result<(), JsValue> { match self { - EventToUnsubscribe::TargetEvent(handle) => { + Self::TargetEvent(handle) => { handle.target.remove_event_listener_with_callback( handle.event_name.as_str(), handle.closure.as_ref().unchecked_ref(), )?; Ok(()) } - EventToUnsubscribe::IntervalHandle(handle) => { + Self::IntervalHandle(handle) => { let window = web_sys::window().unwrap(); window.clear_interval_with_handle(handle.handle); Ok(()) diff --git a/crates/egui-wgpu/Cargo.toml b/crates/egui-wgpu/Cargo.toml index fe11e70d..95f70e3e 100644 --- a/crates/egui-wgpu/Cargo.toml +++ b/crates/egui-wgpu/Cargo.toml @@ -51,8 +51,8 @@ wgpu.workspace = true ## Enable this when generating docs. document-features = { version = "0.2", optional = true } -winit = { version = "0.29.4", default-features = false, optional = true, features = [ - "rwh_05", +winit = { workspace = true, optional = true, default-features = false, features = [ + "rwh_06", ] } # Native: diff --git a/crates/egui-wgpu/README.md b/crates/egui-wgpu/README.md index a6d152c4..1315daf4 100644 --- a/crates/egui-wgpu/README.md +++ b/crates/egui-wgpu/README.md @@ -1,5 +1,5 @@ > [!IMPORTANT] -> luminol-egui-wgpu is currently based on emilk/egui@0.25.0 +> luminol-egui-wgpu is currently based on emilk/egui@b766a48fa7fe4f6a25622ebe2e5677c09553cda9 > [!NOTE] > This is Luminol's modified version of egui-wgpu. The original version is dual-licensed under MIT and Apache 2.0. diff --git a/crates/egui-wgpu/src/lib.rs b/crates/egui-wgpu/src/lib.rs index d560f70d..da3e4763 100644 --- a/crates/egui-wgpu/src/lib.rs +++ b/crates/egui-wgpu/src/lib.rs @@ -1,5 +1,17 @@ //! This crates provides bindings between [`egui`](https://github.com/emilk/egui) and [wgpu](https://crates.io/crates/wgpu). //! +//! If you're targeting WebGL you also need to turn on the +//! `webgl` feature of the `wgpu` crate: +//! +//! ```ignore +//! # Enable both WebGL and WebGPU backends on web. +//! wgpu = { version = "*", features = ["webgpu", "webgl"] } +//! ``` +//! +//! You can control whether WebGL or WebGPU will be picked at runtime by setting +//! [`WgpuConfiguration::supported_backends`]. +//! The default is to prefer WebGPU and fall back on WebGL. +//! //! ## Feature flags #![cfg_attr(feature = "document-features", doc = document_features::document_features!())] //! @@ -24,6 +36,7 @@ use std::sync::Arc; use epaint::mutex::RwLock; +/// An error produced by egui-wgpu. #[derive(thiserror::Error, Debug)] pub enum WgpuError { #[error("Failed to create wgpu adapter, no suitable adapter found.")] @@ -37,6 +50,10 @@ pub enum WgpuError { #[error(transparent)] CreateSurfaceError(#[from] wgpu::CreateSurfaceError), + + #[cfg(feature = "winit")] + #[error(transparent)] + HandleError(#[from] ::winit::raw_window_handle::HandleError), } /// Access to the render state for egui. @@ -45,6 +62,13 @@ pub struct RenderState { /// Wgpu adapter used for rendering. pub adapter: Arc, + /// All the available adapters. + /// + /// This is not available on web. + /// On web, we always select WebGPU is available, then fall back to WebGL if not. + #[cfg(not(target_arch = "wasm32"))] + pub available_adapters: Arc<[wgpu::Adapter]>, + /// Wgpu device used for rendering, created from the adapter. pub device: Arc, @@ -66,14 +90,15 @@ impl RenderState { pub async fn create( config: &WgpuConfiguration, instance: &wgpu::Instance, - surface: &wgpu::Surface, + surface: &wgpu::Surface<'static>, depth_format: Option, msaa_samples: u32, ) -> Result { crate::profile_scope!("RenderState::create"); // async yield give bad names using `profile_function` + // This is always an empty list on web. #[cfg(not(target_arch = "wasm32"))] - let adapters: Vec<_> = instance.enumerate_adapters(wgpu::Backends::all()).collect(); + let available_adapters = instance.enumerate_adapters(wgpu::Backends::all()); let adapter = { crate::profile_scope!("request_adapter"); @@ -86,18 +111,18 @@ impl RenderState { .await .ok_or_else(|| { #[cfg(not(target_arch = "wasm32"))] - if adapters.is_empty() { + if available_adapters.is_empty() { log::info!("No wgpu adapters found"); - } else if adapters.len() == 1 { + } else if available_adapters.len() == 1 { log::info!( "The only available wgpu adapter was not suitable: {}", - adapter_info_summary(&adapters[0].get_info()) + adapter_info_summary(&available_adapters[0].get_info()) ); } else { log::info!( "No suitable wgpu adapter found out of the {} available ones: {}", - adapters.len(), - describe_adapters(&adapters) + available_adapters.len(), + describe_adapters(&available_adapters) ); } @@ -112,7 +137,7 @@ impl RenderState { ); #[cfg(not(target_arch = "wasm32"))] - if adapters.len() == 1 { + if available_adapters.len() == 1 { log::debug!( "Picked the only available wgpu adapter: {}", adapter_info_summary(&adapter.get_info()) @@ -120,8 +145,8 @@ impl RenderState { } else { log::info!( "There were {} available wgpu adapters: {}", - adapters.len(), - describe_adapters(&adapters) + available_adapters.len(), + describe_adapters(&available_adapters) ); log::debug!( "Picked wgpu adapter: {}", @@ -144,8 +169,10 @@ impl RenderState { let renderer = Renderer::new(&device, target_format, depth_format, msaa_samples); - Ok(RenderState { + Ok(Self { adapter: Arc::new(adapter), + #[cfg(not(target_arch = "wasm32"))] + available_adapters: available_adapters.into(), device: Arc::new(device), queue: Arc::new(queue), target_format, @@ -183,12 +210,19 @@ pub enum SurfaceErrorAction { /// Configuration for using wgpu with eframe or the egui-wgpu winit feature. /// -/// This can be configured with the environment variables: +/// This can also be configured with the environment variables: /// * `WGPU_BACKEND`: `vulkan`, `dx11`, `dx12`, `metal`, `opengl`, `webgpu` /// * `WGPU_POWER_PREF`: `low`, `high` or `none` #[derive(Clone)] pub struct WgpuConfiguration { - /// Backends that should be supported (wgpu will pick one of these) + /// Backends that should be supported (wgpu will pick one of these). + /// + /// For instance, if you only want to support WebGL (and not WebGPU), + /// you can set this to [`wgpu::Backends::GL`]. + /// + /// By default on web, WebGPU will be used if available. + /// WebGL will only be used as a fallback, + /// and only if you have enabled the `webgl` feature of crate `wgpu`. pub supported_backends: wgpu::Backends, /// Configuration passed on device request, given an adapter @@ -218,7 +252,7 @@ impl Default for WgpuConfiguration { fn default() -> Self { Self { // 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) + // (note however, that the GL backend needs to be opted-in via the wgpu feature flag "webgl") supported_backends: wgpu::util::backend_bits_from_env() .unwrap_or(wgpu::Backends::PRIMARY | wgpu::Backends::GL), @@ -231,8 +265,8 @@ impl Default for WgpuConfiguration { wgpu::DeviceDescriptor { label: Some("egui wgpu device"), - features: wgpu::Features::default(), - limits: wgpu::Limits { + required_features: wgpu::Features::default(), + required_limits: wgpu::Limits { // When using a depth buffer, we have to be able to create a texture // large enough for the entire surface, and we want to support 4k+ displays. max_texture_dimension_2d: 8192, diff --git a/crates/egui-wgpu/src/renderer.rs b/crates/egui-wgpu/src/renderer.rs index fc6a668b..780c9086 100644 --- a/crates/egui-wgpu/src/renderer.rs +++ b/crates/egui-wgpu/src/renderer.rs @@ -7,8 +7,14 @@ use epaint::{ahash::HashMap, emath::NumExt, PaintCallbackInfo, Primitive, Vertex use wgpu; use wgpu::util::DeviceExt as _; +/// You can use this for storage when implementing [`CallbackTrait`]. pub type CallbackResources = type_map::concurrent::TypeMap; +/// You can use this to do custom `wgpu` rendering in an egui app. +/// +/// Implement [`CallbackTrait`] and call [`Callback::new_paint_callback`]. +/// +/// This can be turned into a [`epaint::PaintCallback`] and [`epaint::Shape`]. pub struct Callback(Box); impl Callback { diff --git a/crates/egui-wgpu/src/winit.rs b/crates/egui-wgpu/src/winit.rs index 5cf71b64..15460686 100644 --- a/crates/egui-wgpu/src/winit.rs +++ b/crates/egui-wgpu/src/winit.rs @@ -5,7 +5,7 @@ use egui::{ViewportId, ViewportIdMap, ViewportIdSet}; use crate::{renderer, RenderState, SurfaceErrorAction, WgpuConfiguration}; struct SurfaceState { - surface: wgpu::Surface, + surface: wgpu::Surface<'static>, alpha_mode: wgpu::CompositeAlphaMode, width: u32, height: u32, @@ -151,16 +151,23 @@ impl Painter { } else { wgpu::TextureUsages::RENDER_ATTACHMENT }; + + let width = surface_state.width; + let height = surface_state.height; + surface_state.surface.configure( &render_state.device, &wgpu::SurfaceConfiguration { + // TODO(emilk): expose `desired_maximum_frame_latency` to eframe users usage, format: render_state.target_format, - width: surface_state.width, - height: surface_state.height, present_mode, alpha_mode: surface_state.alpha_mode, view_formats: vec![render_state.target_format], + ..surface_state + .surface + .get_default_config(&render_state.adapter, width, height) + .expect("The surface isn't supported by this adapter") }, ); } @@ -189,79 +196,44 @@ impl Painter { pub async fn set_window( &mut self, viewport_id: ViewportId, - window: Option<&winit::window::Window>, + window: Option>, ) -> Result<(), crate::WgpuError> { - crate::profile_scope!("Painter::set_window"); // profle_function gives bad names for async functions + crate::profile_scope!("Painter::set_window"); // profile_function gives bad names for async functions if let Some(window) = window { let size = window.inner_size(); if self.surfaces.get(&viewport_id).is_none() { - let surface = unsafe { - crate::profile_scope!("create_surface"); - self.instance.create_surface(&window)? - }; - - let render_state = if let Some(render_state) = &self.render_state { - render_state - } else { - let render_state = RenderState::create( - &self.configuration, - &self.instance, - &surface, - self.depth_format, - self.msaa_samples, - ) - .await?; - self.render_state.get_or_insert(render_state) - }; - - let alpha_mode = if self.support_transparent_backbuffer { - let supported_alpha_modes = - surface.get_capabilities(&render_state.adapter).alpha_modes; - - // Prefer pre multiplied over post multiplied! - if supported_alpha_modes.contains(&wgpu::CompositeAlphaMode::PreMultiplied) { - wgpu::CompositeAlphaMode::PreMultiplied - } else if supported_alpha_modes - .contains(&wgpu::CompositeAlphaMode::PostMultiplied) - { - wgpu::CompositeAlphaMode::PostMultiplied - } else { - log::warn!("Transparent window was requested, but the active wgpu surface does not support a `CompositeAlphaMode` with transparency."); - wgpu::CompositeAlphaMode::Auto - } - } else { - wgpu::CompositeAlphaMode::Auto - }; + let surface = self.instance.create_surface(window)?; + self.add_surface(surface, viewport_id, size).await?; + } + } else { + log::warn!("No window - clearing all surfaces"); + self.surfaces.clear(); + } + Ok(()) + } - let supports_screenshot = - !matches!(render_state.adapter.get_info().backend, wgpu::Backend::Gl); - - self.surfaces.insert( - viewport_id, - SurfaceState { - surface, - width: size.width, - height: size.height, - alpha_mode, - supports_screenshot, - }, - ); + /// Updates (or clears) the [`winit::window::Window`] associated with the [`Painter`] without taking ownership of the window. + /// + /// Like [`set_window`](Self::set_window) except: + /// + /// # Safety + /// The user is responsible for ensuring that the window is alive for as long as it is set. + pub async unsafe fn set_window_unsafe( + &mut self, + viewport_id: ViewportId, + window: Option<&winit::window::Window>, + ) -> Result<(), crate::WgpuError> { + crate::profile_scope!("Painter::set_window_unsafe"); // profile_function gives bad names for async functions - let Some(width) = NonZeroU32::new(size.width) else { - log::debug!("The window width was zero; skipping generate textures"); - return Ok(()); - }; - let Some(height) = NonZeroU32::new(size.height) else { - log::debug!("The window height was zero; skipping generate textures"); - return Ok(()); + if let Some(window) = window { + let size = window.inner_size(); + if self.surfaces.get(&viewport_id).is_none() { + let surface = unsafe { + self.instance + .create_surface_unsafe(wgpu::SurfaceTargetUnsafe::from_window(&window)?)? }; - - self.resize_and_generate_depth_texture_view_and_msaa_view( - viewport_id, - width, - height, - ); + self.add_surface(surface, viewport_id, size).await?; } } else { log::warn!("No window - clearing all surfaces"); @@ -270,6 +242,64 @@ impl Painter { Ok(()) } + async fn add_surface( + &mut self, + surface: wgpu::Surface<'static>, + viewport_id: ViewportId, + size: winit::dpi::PhysicalSize, + ) -> Result<(), crate::WgpuError> { + let render_state = if let Some(render_state) = &self.render_state { + render_state + } else { + let render_state = RenderState::create( + &self.configuration, + &self.instance, + &surface, + self.depth_format, + self.msaa_samples, + ) + .await?; + self.render_state.get_or_insert(render_state) + }; + let alpha_mode = if self.support_transparent_backbuffer { + let supported_alpha_modes = surface.get_capabilities(&render_state.adapter).alpha_modes; + + // Prefer pre multiplied over post multiplied! + if supported_alpha_modes.contains(&wgpu::CompositeAlphaMode::PreMultiplied) { + wgpu::CompositeAlphaMode::PreMultiplied + } else if supported_alpha_modes.contains(&wgpu::CompositeAlphaMode::PostMultiplied) { + wgpu::CompositeAlphaMode::PostMultiplied + } else { + log::warn!("Transparent window was requested, but the active wgpu surface does not support a `CompositeAlphaMode` with transparency."); + wgpu::CompositeAlphaMode::Auto + } + } else { + wgpu::CompositeAlphaMode::Auto + }; + let supports_screenshot = + !matches!(render_state.adapter.get_info().backend, wgpu::Backend::Gl); + self.surfaces.insert( + viewport_id, + SurfaceState { + surface, + width: size.width, + height: size.height, + alpha_mode, + supports_screenshot, + }, + ); + let Some(width) = NonZeroU32::new(size.width) else { + log::debug!("The window width was zero; skipping generate textures"); + return Ok(()); + }; + let Some(height) = NonZeroU32::new(size.height) else { + log::debug!("The window height was zero; skipping generate textures"); + return Ok(()); + }; + self.resize_and_generate_depth_texture_view_and_msaa_view(viewport_id, width, height); + Ok(()) + } + /// Returns the maximum texture dimension supported if known /// /// This API will only return a known dimension after `set_window()` has been called diff --git a/crates/graphics/Cargo.toml b/crates/graphics/Cargo.toml index 193a1ddb..9efca02d 100644 --- a/crates/graphics/Cargo.toml +++ b/crates/graphics/Cargo.toml @@ -24,8 +24,8 @@ luminol-egui-wgpu.workspace = true wgpu.workspace = true glam.workspace = true -naga_oil = "0.11.0" -naga = "0.14.1" +naga_oil = "0.12.0" +naga = "0.19.0" crossbeam.workspace = true dashmap.workspace = true From 749d5906ca5451d5c323a324ac54557e1a86eb62 Mon Sep 17 00:00:00 2001 From: white-axe Date: Tue, 30 Jan 2024 22:28:51 -0500 Subject: [PATCH 12/20] chore: fix more update-induced errors --- crates/graphics/src/texture_loader.rs | 1 + src/main.rs | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/crates/graphics/src/texture_loader.rs b/crates/graphics/src/texture_loader.rs index aff7c5c4..35d0e613 100644 --- a/crates/graphics/src/texture_loader.rs +++ b/crates/graphics/src/texture_loader.rs @@ -76,6 +76,7 @@ fn load_wgpu_texture_from_path( | wgpu::TextureUsages::TEXTURE_BINDING, view_formats: &[], }, + wgpu::util::TextureDataOrder::LayerMajor, &texture_data, )) } diff --git a/src/main.rs b/src/main.rs index b0e2b024..a61b8306 100644 --- a/src/main.rs +++ b/src/main.rs @@ -243,8 +243,8 @@ fn main() { .unwrap_or(wgpu::Backends::PRIMARY), device_descriptor: std::sync::Arc::new(|_| wgpu::DeviceDescriptor { label: Some("luminol device descriptor"), - features: wgpu::Features::PUSH_CONSTANTS, - limits: wgpu::Limits { + required_features: wgpu::Features::PUSH_CONSTANTS, + required_limits: wgpu::Limits { max_push_constant_size: 128, ..wgpu::Limits::default() }, From eec2ba96ad5815e1dfe91261ce3788ca1fa34bcd Mon Sep 17 00:00:00 2001 From: white-axe Date: Tue, 30 Jan 2024 22:56:37 -0500 Subject: [PATCH 13/20] chore: remove DX12 push constants workaround (fixed in wgpu 0.19) --- crates/graphics/src/lib.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/crates/graphics/src/lib.rs b/crates/graphics/src/lib.rs index 2882aaf2..1627759b 100644 --- a/crates/graphics/src/lib.rs +++ b/crates/graphics/src/lib.rs @@ -111,10 +111,8 @@ impl GraphicsState { } pub fn push_constants_supported(render_state: &luminol_egui_wgpu::RenderState) -> bool { - let feature_supported = render_state + render_state .device .features() - .contains(wgpu::Features::PUSH_CONSTANTS); - let is_dx_12 = render_state.adapter.get_info().backend == wgpu::Backend::Dx12; - feature_supported && !is_dx_12 + .contains(wgpu::Features::PUSH_CONSTANTS) } From c2fd4388c25c315055413d8f3cdcf1720cda169f Mon Sep 17 00:00:00 2001 From: white-axe Date: Tue, 30 Jan 2024 23:32:19 -0500 Subject: [PATCH 14/20] feat: web build now has WebGPU and WebGL support in one binary --- .github/workflows/build.yml | 12 ++---------- Cargo.toml | 6 +----- assets/main.js | 36 +++--------------------------------- assets/worker.js | 10 +++++----- src/main.rs | 3 +-- 5 files changed, 12 insertions(+), 55 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 44952417..e9474f8d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -105,16 +105,8 @@ jobs: run: wget -qO- https://github.com/trunk-rs/trunk/releases/download/v0.18.4/trunk-x86_64-unknown-linux-gnu.tar.gz | tar -xzf- -C ${{ runner.temp }} - name: Rust Cache uses: Swatinem/rust-cache@v2 - - name: Build luminol (Release, WebGL) - run: | - mkdir -p ${{ runner.temp }}/luminol/webgl/ - ${{ runner.temp }}/trunk build --release --features webgl - mv ${{ github.workspace }}/dist/luminol.js ${{ runner.temp }}/luminol/webgl/luminol_webgl.js - mv ${{ github.workspace }}/dist/luminol_bg.wasm ${{ runner.temp }}/luminol/webgl/luminol_webgl_bg.wasm - - name: Build luminol (Release, WebGPU) - run: | - ${{ runner.temp }}/trunk build --release - mv ${{ runner.temp }}/luminol/webgl/* ${{ github.workspace }}/dist/ + - name: Build luminol (Release) + run: ${{ runner.temp }}/trunk build --release - name: Upload artifact uses: actions/upload-artifact@v2 with: diff --git a/Cargo.toml b/Cargo.toml index 48b13244..780d7bb3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -231,16 +231,12 @@ web-sys = { version = "0.3", features = [ "WorkerType", ] } -# Enable wgpu's `webgl` feature if Luminol's `webgl` feature is enabled, -# enabling its WebGL backend and disabling its WebGPU backend [target.'cfg(target_arch = "wasm32")'.dependencies.wgpu] workspace = true -optional = true -features = ["webgl"] +features = ["webgpu", "webgl"] [features] steamworks = ["dep:steamworks"] -webgl = ["dep:wgpu"] [target.'cfg(windows)'.build-dependencies] winres = "0.1" diff --git a/assets/main.js b/assets/main.js index 0bc1d068..e1f9769a 100644 --- a/assets/main.js +++ b/assets/main.js @@ -15,37 +15,7 @@ // You should have received a copy of the GNU General Public License // along with Luminol. If not, see . -// Check if the user's browser supports WebGPU -console.log('Checking for WebGPU support in web workers…'); -const worker = new Worker('/webgpu-test-worker.js'); -const promise = new Promise(function (resolve) { - worker.onmessage = function (e) { - resolve(e.data); - }; -}); -worker.postMessage(null); -const gpu = await promise; -worker.terminate(); -if (gpu) { - console.log('WebGPU is supported. Using WebGPU backend if available.'); -} else { - console.log('No support detected. Using WebGL backend if available.'); -} +import wasm_bindgen, { luminol_main_start } from '/luminol.js'; -// If WebGPU is supported, always use luminol.js -// If WebGPU is not supported, use luminol_webgl.js if it's available or fallback to luminol.js -let fallback = false; -let luminol; -if (gpu) { - luminol = await import('/luminol.js'); -} else { - try { - luminol = await import('/luminol_webgl.js'); - fallback = true; - } catch (e) { - luminol = await import('/luminol.js'); - } -} - -await luminol.default(fallback ? '/luminol_webgl_bg.wasm' : '/luminol_bg.wasm'); -luminol.luminol_main_start(fallback); +await wasm_bindgen(); +luminol_main_start(); diff --git a/assets/worker.js b/assets/worker.js index 809d4d31..15eb6cf7 100644 --- a/assets/worker.js +++ b/assets/worker.js @@ -15,11 +15,11 @@ // You should have received a copy of the GNU General Public License // along with Luminol. If not, see . -onmessage = async function (e) { - const [fallback, memory, canvas] = e.data; +import wasm_bindgen, { luminol_worker_start } from '/luminol.js'; - const luminol = await import(fallback ? '/luminol_webgl.js' : '/luminol.js'); +onmessage = async function (e) { + const [memory, canvas] = e.data; - await luminol.default(fallback ? '/luminol_webgl_bg.wasm' : '/luminol_bg.wasm', memory); - await luminol.luminol_worker_start(canvas); + await wasm_bindgen(undefined, memory); + await luminol_worker_start(canvas); }; diff --git a/src/main.rs b/src/main.rs index a61b8306..34d0b451 100644 --- a/src/main.rs +++ b/src/main.rs @@ -291,7 +291,7 @@ static WORKER_DATA: parking_lot::Mutex> = parking_lot::Mutex: #[cfg(target_arch = "wasm32")] #[wasm_bindgen] -pub fn luminol_main_start(fallback: bool) { +pub fn luminol_main_start() { let (panic_tx, panic_rx) = flume::unbounded(); wasm_bindgen_futures::spawn_local(async move { @@ -390,7 +390,6 @@ pub fn luminol_main_start(fallback: bool) { .expect("failed to spawn web worker"); let message = js_sys::Array::new(); - message.push(&JsValue::from(fallback)); message.push(&wasm_bindgen::memory()); message.push(&offscreen_canvas); let transfer = js_sys::Array::new(); From 0245fa4a0768eda42e48ed8774c8f33ee5b7ff7f Mon Sep 17 00:00:00 2001 From: white-axe Date: Tue, 30 Jan 2024 23:32:30 -0500 Subject: [PATCH 15/20] fix: make eframe's secure context check use worker context --- crates/eframe/src/web/web_painter_wgpu.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/eframe/src/web/web_painter_wgpu.rs b/crates/eframe/src/web/web_painter_wgpu.rs index 28c150cf..b1a8bd67 100644 --- a/crates/eframe/src/web/web_painter_wgpu.rs +++ b/crates/eframe/src/web/web_painter_wgpu.rs @@ -97,7 +97,9 @@ impl WebPainterWgpu { log::debug!("Creating wgpu painter"); { - let is_secure_context = web_sys::window().map_or(false, |w| w.is_secure_context()); + let is_secure_context = luminol_web::bindings::worker() + .expect("failed to get worker context") + .is_secure_context(); if !is_secure_context { log::info!( "WebGPU is only available in secure contexts, i.e. on HTTPS and on localhost" From f8de2c7b861dc534d95395c1417625ec83e4f8fb Mon Sep 17 00:00:00 2001 From: white-axe Date: Tue, 30 Jan 2024 23:33:38 -0500 Subject: [PATCH 16/20] chore: write upstream eframe and egui-wgpu version as 0.25.0 Chances are when the wgpu update changes land into a stable release of egui, they're going to use a squash merge, so we have no choice but to use commits from the egui master branch as the base commits for merges. --- crates/eframe/README.md | 2 +- crates/egui-wgpu/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/eframe/README.md b/crates/eframe/README.md index 775a65dd..f8ffb330 100644 --- a/crates/eframe/README.md +++ b/crates/eframe/README.md @@ -1,5 +1,5 @@ > [!IMPORTANT] -> luminol-eframe is currently based on emilk/egui@b766a48fa7fe4f6a25622ebe2e5677c09553cda9 +> luminol-eframe is currently based on emilk/egui@0.25.0 > [!NOTE] > This is Luminol's modified version of eframe. The original version is dual-licensed under MIT and Apache 2.0. diff --git a/crates/egui-wgpu/README.md b/crates/egui-wgpu/README.md index 1315daf4..a6d152c4 100644 --- a/crates/egui-wgpu/README.md +++ b/crates/egui-wgpu/README.md @@ -1,5 +1,5 @@ > [!IMPORTANT] -> luminol-egui-wgpu is currently based on emilk/egui@b766a48fa7fe4f6a25622ebe2e5677c09553cda9 +> luminol-egui-wgpu is currently based on emilk/egui@0.25.0 > [!NOTE] > This is Luminol's modified version of egui-wgpu. The original version is dual-licensed under MIT and Apache 2.0. From 1eb1976e48b18ae3de364769387f0ce85c199a2c Mon Sep 17 00:00:00 2001 From: white-axe Date: Tue, 30 Jan 2024 23:45:02 -0500 Subject: [PATCH 17/20] chore: update Trunk to latest version --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e9474f8d..1ce8ec22 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -102,7 +102,7 @@ jobs: targets: wasm32-unknown-unknown components: rust-src - name: Download and install Trunk binary - run: wget -qO- https://github.com/trunk-rs/trunk/releases/download/v0.18.4/trunk-x86_64-unknown-linux-gnu.tar.gz | tar -xzf- -C ${{ runner.temp }} + run: wget -qO- https://github.com/trunk-rs/trunk/releases/download/v0.18.7/trunk-x86_64-unknown-linux-gnu.tar.gz | tar -xzf- -C ${{ runner.temp }} - name: Rust Cache uses: Swatinem/rust-cache@v2 - name: Build luminol (Release) From fce0dfd4bc258112bee3462e63814205b5006f77 Mon Sep 17 00:00:00 2001 From: white-axe Date: Wed, 31 Jan 2024 00:01:15 -0500 Subject: [PATCH 18/20] chore: remove unnecessary dependency on glow --- Cargo.lock | 19 ------------------- Cargo.toml | 2 -- crates/eframe/Cargo.toml | 6 +++--- 3 files changed, 3 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bb43301d..d1bcd43a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1575,23 +1575,6 @@ dependencies = [ "serde", ] -[[package]] -name = "egui_glow" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb2ef815e80d117339c7d6b813f7678d23522d699ccd3243e267ef06166009b9" -dependencies = [ - "bytemuck", - "egui", - "egui-winit", - "glow", - "log", - "memoffset 0.7.1", - "puffin", - "wasm-bindgen", - "web-sys", -] - [[package]] name = "either" version = "1.9.0" @@ -3190,9 +3173,7 @@ dependencies = [ "document-features", "egui", "egui-winit", - "egui_glow", "flume", - "glow", "glutin", "glutin-winit", "image 0.24.7", diff --git a/Cargo.toml b/Cargo.toml index 780d7bb3..84991939 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -73,7 +73,6 @@ luminol-eframe = { version = "0.4.0", path = "crates/eframe/", features = [ "wayland", ], default-features = false } luminol-egui-wgpu = { version = "0.4.0", path = "crates/egui-wgpu/" } -egui_glow = "0.25.0" egui-winit = "0.25.0" wgpu = { version = "0.19.1", features = ["naga-ir"] } @@ -101,7 +100,6 @@ color-eyre = "0.6.2" puffin = "0.18" raw-window-handle = "0.6.0" winit = { version = "0.29.4", default-features = false } -glow = "0.13" parking_lot = { version = "0.12.1", features = [ "nightly", # This is required for parking_lot to work properly in WebAssembly builds with atomics support diff --git a/crates/eframe/Cargo.toml b/crates/eframe/Cargo.toml index b32eeaea..17499140 100644 --- a/crates/eframe/Cargo.toml +++ b/crates/eframe/Cargo.toml @@ -82,7 +82,7 @@ persistence = [ puffin = [ "dep:puffin", "egui/puffin", - "egui_glow?/puffin", + #"egui_glow?/puffin", "luminol-egui-wgpu?/puffin", "egui-winit/puffin", ] @@ -135,8 +135,8 @@ thiserror.workspace = true ## Enable this when generating docs. document-features = { version = "0.2", optional = true } -egui_glow = { workspace = true, optional = true } -glow = { workspace = true, optional = true } +#egui_glow = { workspace = true, optional = true } +#glow = { workspace = true, optional = true } # glutin stuck on old version of raw-window-handle: rwh_05 = { package = "raw-window-handle", version = "0.5.2", optional = true, features = [ "std", From 3b699c764ee77736fdc46d2425f75359d7fb622f Mon Sep 17 00:00:00 2001 From: white-axe Date: Wed, 31 Jan 2024 00:14:57 -0500 Subject: [PATCH 19/20] chore: remove assets/webgpu-test-worker.js --- assets/webgpu-test-worker.js | 25 ------------------------- index.html | 1 - 2 files changed, 26 deletions(-) delete mode 100644 assets/webgpu-test-worker.js diff --git a/assets/webgpu-test-worker.js b/assets/webgpu-test-worker.js deleted file mode 100644 index f3fe6fd5..00000000 --- a/assets/webgpu-test-worker.js +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (C) 2023 Lily Lyons -// -// This file is part of Luminol. -// -// Luminol is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Luminol is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Luminol. If not, see . - -onmessage = async function () { - let gpu = false; - try { - let adapter = await navigator.gpu?.requestAdapter(); - gpu = typeof GPUAdapter === 'function' && adapter instanceof GPUAdapter; - } catch (e) {} - postMessage(gpu); -} diff --git a/index.html b/index.html index 39588f0e..2acdac6d 100644 --- a/index.html +++ b/index.html @@ -24,7 +24,6 @@ - From 42e4bad701abdd76f07ea99a0b59dd60fcdfbd87 Mon Sep 17 00:00:00 2001 From: white-axe Date: Wed, 31 Jan 2024 11:40:35 -0500 Subject: [PATCH 20/20] refactor: use relative public path This allows easily serving Luminol web builds under any path (e.g. https://example.com/luminol/ instead of https://example.com/). --- assets/main.js | 2 +- assets/worker.js | 2 +- index.html | 18 +++++++----------- src/main.rs | 2 +- 4 files changed, 10 insertions(+), 14 deletions(-) diff --git a/assets/main.js b/assets/main.js index e1f9769a..6663047b 100644 --- a/assets/main.js +++ b/assets/main.js @@ -15,7 +15,7 @@ // You should have received a copy of the GNU General Public License // along with Luminol. If not, see . -import wasm_bindgen, { luminol_main_start } from '/luminol.js'; +import wasm_bindgen, { luminol_main_start } from './luminol.js'; await wasm_bindgen(); luminol_main_start(); diff --git a/assets/worker.js b/assets/worker.js index 15eb6cf7..4a076705 100644 --- a/assets/worker.js +++ b/assets/worker.js @@ -15,7 +15,7 @@ // You should have received a copy of the GNU General Public License // along with Luminol. If not, see . -import wasm_bindgen, { luminol_worker_start } from '/luminol.js'; +import wasm_bindgen, { luminol_worker_start } from './luminol.js'; onmessage = async function (e) { const [memory, canvas] = e.data; diff --git a/index.html b/index.html index 2acdac6d..9ad4d580 100644 --- a/index.html +++ b/index.html @@ -12,29 +12,25 @@ - - - - - + - - - + + + @@ -128,13 +124,13 @@ - + - + - + diff --git a/src/main.rs b/src/main.rs index 34d0b451..85926f19 100644 --- a/src/main.rs +++ b/src/main.rs @@ -386,7 +386,7 @@ pub fn luminol_main_start() { let mut worker_options = web_sys::WorkerOptions::new(); worker_options.name("luminol-primary"); worker_options.type_(web_sys::WorkerType::Module); - let worker = web_sys::Worker::new_with_options("/worker.js", &worker_options) + let worker = web_sys::Worker::new_with_options("./worker.js", &worker_options) .expect("failed to spawn web worker"); let message = js_sys::Array::new();