Use atomic_refcell instead of parking_lot for wasm32 targets (#1404)
Closes https://github.com/emilk/egui/issues/1401
This commit is contained in:
parent
e5aeb1618f
commit
41b178b6ec
9 changed files with 99 additions and 10 deletions
10
Cargo.lock
generated
10
Cargo.lock
generated
|
@ -203,6 +203,12 @@ dependencies = [
|
||||||
"system-deps",
|
"system-deps",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "atomic_refcell"
|
||||||
|
version = "0.1.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "73b5e5f48b927f04e952dedc932f31995a65a0bf65ec971c74436e51bf6e970d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atty"
|
name = "atty"
|
||||||
version = "0.2.14"
|
version = "0.2.14"
|
||||||
|
@ -987,7 +993,6 @@ dependencies = [
|
||||||
"epi",
|
"epi",
|
||||||
"glow",
|
"glow",
|
||||||
"image",
|
"image",
|
||||||
"parking_lot 0.12.0",
|
|
||||||
"poll-promise",
|
"poll-promise",
|
||||||
"rfd",
|
"rfd",
|
||||||
]
|
]
|
||||||
|
@ -1057,7 +1062,6 @@ version = "0.17.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"egui",
|
"egui",
|
||||||
"image",
|
"image",
|
||||||
"parking_lot 0.12.0",
|
|
||||||
"resvg",
|
"resvg",
|
||||||
"tiny-skia",
|
"tiny-skia",
|
||||||
"usvg",
|
"usvg",
|
||||||
|
@ -1086,7 +1090,6 @@ dependencies = [
|
||||||
"glow",
|
"glow",
|
||||||
"glutin",
|
"glutin",
|
||||||
"memoffset",
|
"memoffset",
|
||||||
"parking_lot 0.12.0",
|
|
||||||
"tracing",
|
"tracing",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"web-sys",
|
"web-sys",
|
||||||
|
@ -1200,6 +1203,7 @@ version = "0.17.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ab_glyph",
|
"ab_glyph",
|
||||||
"ahash 0.7.6",
|
"ahash 0.7.6",
|
||||||
|
"atomic_refcell",
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"cint",
|
"cint",
|
||||||
"criterion",
|
"criterion",
|
||||||
|
|
|
@ -71,6 +71,5 @@ image = { version = "0.24", default-features = false, features = [
|
||||||
"jpeg",
|
"jpeg",
|
||||||
"png",
|
"png",
|
||||||
] }
|
] }
|
||||||
parking_lot = "0.12"
|
|
||||||
poll-promise = "0.1"
|
poll-promise = "0.1"
|
||||||
rfd = "0.8"
|
rfd = "0.8"
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
use eframe::egui;
|
use eframe::egui;
|
||||||
|
|
||||||
use parking_lot::Mutex;
|
use egui::mutex::Mutex;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -28,7 +28,6 @@ svg = ["resvg", "tiny-skia", "usvg"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
egui = { version = "0.17.0", path = "../egui", default-features = false }
|
egui = { version = "0.17.0", path = "../egui", default-features = false }
|
||||||
parking_lot = "0.12"
|
|
||||||
|
|
||||||
# Optional dependencies:
|
# Optional dependencies:
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use parking_lot::Mutex;
|
use egui::mutex::Mutex;
|
||||||
|
|
||||||
/// An image to be shown in egui.
|
/// An image to be shown in egui.
|
||||||
///
|
///
|
||||||
|
|
|
@ -63,7 +63,6 @@ epi = { version = "0.17.0", path = "../epi", optional = true }
|
||||||
bytemuck = "1.7"
|
bytemuck = "1.7"
|
||||||
glow = "0.11"
|
glow = "0.11"
|
||||||
memoffset = "0.6"
|
memoffset = "0.6"
|
||||||
parking_lot = "0.12"
|
|
||||||
tracing = "0.1"
|
tracing = "0.1"
|
||||||
|
|
||||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||||
|
|
|
@ -54,7 +54,7 @@ pub fn run(app_name: &str, native_options: &epi::NativeOptions, app_creator: epi
|
||||||
);
|
);
|
||||||
|
|
||||||
{
|
{
|
||||||
let event_loop_proxy = parking_lot::Mutex::new(event_loop.create_proxy());
|
let event_loop_proxy = egui::mutex::Mutex::new(event_loop.create_proxy());
|
||||||
integration.egui_ctx.set_request_repaint_callback(move || {
|
integration.egui_ctx.set_request_repaint_callback(move || {
|
||||||
event_loop_proxy.lock().send_event(RequestRepaintEvent).ok();
|
event_loop_proxy.lock().send_event(RequestRepaintEvent).ok();
|
||||||
});
|
});
|
||||||
|
|
|
@ -56,9 +56,17 @@ ahash = { version = "0.7", default-features = false, features = ["std"] }
|
||||||
bytemuck = { version = "1.7.2", optional = true, features = ["derive"] }
|
bytemuck = { version = "1.7.2", optional = true, features = ["derive"] }
|
||||||
cint = { version = "^0.2.2", optional = true }
|
cint = { version = "^0.2.2", optional = true }
|
||||||
nohash-hasher = "0.2"
|
nohash-hasher = "0.2"
|
||||||
parking_lot = "0.12" # Using parking_lot over std::sync::Mutex gives 50% speedups in some real-world scenarios.
|
|
||||||
serde = { version = "1", optional = true, features = ["derive", "rc"] }
|
serde = { version = "1", optional = true, features = ["derive", "rc"] }
|
||||||
|
|
||||||
|
# native:
|
||||||
|
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||||
|
parking_lot = "0.12" # Using parking_lot over std::sync::Mutex gives 50% speedups in some real-world scenarios.
|
||||||
|
|
||||||
|
# web:
|
||||||
|
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||||
|
atomic_refcell = "0.1" # Used instead of parking_lot on on wasm. See https://github.com/emilk/egui/issues/1401
|
||||||
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
criterion = { version = "0.3", default-features = false }
|
criterion = { version = "0.3", default-features = false }
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,12 @@
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
#[cfg(not(debug_assertions))]
|
#[cfg(not(debug_assertions))]
|
||||||
mod mutex_impl {
|
mod mutex_impl {
|
||||||
/// Provides interior mutability.
|
/// Provides interior mutability.
|
||||||
|
///
|
||||||
|
/// Uses `parking_lot` crate on native targets, and `atomic_refcell` on `wasm32` targets.
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Mutex<T>(parking_lot::Mutex<T>);
|
pub struct Mutex<T>(parking_lot::Mutex<T>);
|
||||||
|
|
||||||
|
@ -24,9 +27,12 @@ mod mutex_impl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
mod mutex_impl {
|
mod mutex_impl {
|
||||||
/// Provides interior mutability.
|
/// Provides interior mutability.
|
||||||
|
///
|
||||||
|
/// Uses `parking_lot` crate on native targets, and `atomic_refcell` on `wasm32` targets.
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Mutex<T>(parking_lot::Mutex<T>);
|
pub struct Mutex<T>(parking_lot::Mutex<T>);
|
||||||
|
|
||||||
|
@ -104,6 +110,7 @@ mod mutex_impl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
mod rw_lock_impl {
|
mod rw_lock_impl {
|
||||||
/// The lock you get from [`RwLock::read`].
|
/// The lock you get from [`RwLock::read`].
|
||||||
pub use parking_lot::MappedRwLockReadGuard as RwLockReadGuard;
|
pub use parking_lot::MappedRwLockReadGuard as RwLockReadGuard;
|
||||||
|
@ -112,6 +119,8 @@ mod rw_lock_impl {
|
||||||
pub use parking_lot::MappedRwLockWriteGuard as RwLockWriteGuard;
|
pub use parking_lot::MappedRwLockWriteGuard as RwLockWriteGuard;
|
||||||
|
|
||||||
/// Provides interior mutability.
|
/// Provides interior mutability.
|
||||||
|
///
|
||||||
|
/// Uses `parking_lot` crate on native targets, and `atomic_refcell` on `wasm32` targets.
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct RwLock<T>(parking_lot::RwLock<T>);
|
pub struct RwLock<T>(parking_lot::RwLock<T>);
|
||||||
|
|
||||||
|
@ -133,12 +142,83 @@ mod rw_lock_impl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
mod arc_impl {
|
mod arc_impl {
|
||||||
pub use std::sync::Arc;
|
pub use std::sync::Arc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
mod mutex_impl {
|
||||||
|
// `atomic_refcell` will panic if multiple threads try to access the same value
|
||||||
|
|
||||||
|
/// Provides interior mutability.
|
||||||
|
///
|
||||||
|
/// Uses `parking_lot` crate on native targets, and `atomic_refcell` on `wasm32` targets.
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct Mutex<T>(atomic_refcell::AtomicRefCell<T>);
|
||||||
|
|
||||||
|
/// The lock you get from [`Mutex`].
|
||||||
|
pub use atomic_refcell::AtomicRefMut as MutexGuard;
|
||||||
|
|
||||||
|
impl<T> Mutex<T> {
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn new(val: T) -> Self {
|
||||||
|
Self(atomic_refcell::AtomicRefCell::new(val))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Panics if already locked.
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn lock(&self) -> MutexGuard<'_, T> {
|
||||||
|
self.0.borrow_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
mod rw_lock_impl {
|
||||||
|
// `atomic_refcell` will panic if multiple threads try to access the same value
|
||||||
|
|
||||||
|
/// The lock you get from [`RwLock::read`].
|
||||||
|
pub use atomic_refcell::AtomicRef as RwLockReadGuard;
|
||||||
|
|
||||||
|
/// The lock you get from [`RwLock::write`].
|
||||||
|
pub use atomic_refcell::AtomicRefMut as RwLockWriteGuard;
|
||||||
|
|
||||||
|
/// Provides interior mutability.
|
||||||
|
///
|
||||||
|
/// Uses `parking_lot` crate on native targets, and `atomic_refcell` on `wasm32` targets.
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct RwLock<T>(atomic_refcell::AtomicRefCell<T>);
|
||||||
|
|
||||||
|
impl<T> RwLock<T> {
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn new(val: T) -> Self {
|
||||||
|
Self(atomic_refcell::AtomicRefCell::new(val))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn read(&self) -> RwLockReadGuard<'_, T> {
|
||||||
|
self.0.borrow()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Panics if already locked.
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn write(&self) -> RwLockWriteGuard<'_, T> {
|
||||||
|
self.0.borrow_mut()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
mod arc_impl {
|
||||||
|
// pub use std::rc::Rc as Arc; // TODO(emilk): optimize single threaded code by using `Rc` instead of `Arc`.
|
||||||
|
pub use std::sync::Arc;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
pub use arc_impl::Arc;
|
pub use arc_impl::Arc;
|
||||||
pub use mutex_impl::{Mutex, MutexGuard};
|
pub use mutex_impl::{Mutex, MutexGuard};
|
||||||
pub use rw_lock_impl::{RwLock, RwLockReadGuard, RwLockWriteGuard};
|
pub use rw_lock_impl::{RwLock, RwLockReadGuard, RwLockWriteGuard};
|
||||||
|
|
Loading…
Reference in a new issue