diff --git a/Cargo.lock b/Cargo.lock index 64e3e5d6eb..42272bac23 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -927,6 +927,7 @@ dependencies = [ "gfx-hal 0.1.0 (git+https://github.com/gfx-rs/gfx?rev=a435a05)", "gfx-memory 0.1.0 (git+https://github.com/gfx-rs/gfx-memory?rev=483d64d)", "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/wgpu-native/Cargo.toml b/wgpu-native/Cargo.toml index 58694cb0f8..1ddbec9108 100644 --- a/wgpu-native/Cargo.toml +++ b/wgpu-native/Cargo.toml @@ -11,7 +11,7 @@ crate-type = ["lib", "cdylib", "staticlib"] [features] default = [] -remote = [] +remote = ["parking_lot"] metal = ["gfx-backend-metal"] dx12 = ["gfx-backend-dx12"] vulkan = ["gfx-backend-vulkan"] @@ -19,6 +19,7 @@ vulkan = ["gfx-backend-vulkan"] [dependencies] bitflags = "1.0" lazy_static = "1.1.0" +parking_lot = { version = "0.6", optional = true } gfx-hal = { git = "https://github.com/gfx-rs/gfx", rev = "a435a05" } # required by gfx-memory gfx-backend-empty = { git = "https://github.com/gfx-rs/gfx", rev = "a435a05" } gfx-backend-vulkan = { git = "https://github.com/gfx-rs/gfx", rev = "a435a05", optional = true } diff --git a/wgpu-native/src/device.rs b/wgpu-native/src/device.rs index 8579d1dff6..15bc100854 100644 --- a/wgpu-native/src/device.rs +++ b/wgpu-native/src/device.rs @@ -36,7 +36,7 @@ pub extern "C" fn wgpu_device_create_shader_module( device_id: DeviceId, desc: pipeline::ShaderModuleDescriptor, ) -> ShaderModuleId { - let device = registry::DEVICE_REGISTRY.get(device_id).unwrap(); + let device = registry::DEVICE_REGISTRY.get_mut(device_id); let shader = device .device .create_shader_module(unsafe { diff --git a/wgpu-native/src/instance.rs b/wgpu-native/src/instance.rs index c3832f884d..a6a43f288f 100644 --- a/wgpu-native/src/instance.rs +++ b/wgpu-native/src/instance.rs @@ -51,7 +51,7 @@ pub extern "C" fn wgpu_instance_get_adapter( instance_id: InstanceId, desc: AdapterDescriptor, ) -> AdapterId { - let instance = registry::INSTANCE_REGISTRY.get(instance_id).unwrap(); + let instance = registry::INSTANCE_REGISTRY.get_mut(instance_id); let (mut low, mut high, mut other) = (None, None, None); for adapter in instance.enumerate_adapters() { match adapter.info.device_type { @@ -73,7 +73,7 @@ pub extern "C" fn wgpu_adapter_create_device( adapter_id: AdapterId, desc: DeviceDescriptor, ) -> DeviceId { - let adapter = registry::ADAPTER_REGISTRY.get_mut(adapter_id).unwrap(); + let mut adapter = registry::ADAPTER_REGISTRY.get_mut(adapter_id); let (device, queue_group) = adapter.open_with::<_, hal::General>(1, |_qf| true).unwrap(); let mem_props = adapter.physical_device.memory_properties(); registry::DEVICE_REGISTRY.register(Device::new(device, queue_group, mem_props)) diff --git a/wgpu-native/src/lib.rs b/wgpu-native/src/lib.rs index 86f8c111a5..db405f85a2 100644 --- a/wgpu-native/src/lib.rs +++ b/wgpu-native/src/lib.rs @@ -2,6 +2,8 @@ extern crate bitflags; #[macro_use] extern crate lazy_static; +#[cfg(feature = "remote")] +extern crate parking_lot; #[cfg(feature = "gfx-backend-dx12")] extern crate gfx_backend_dx12 as back; diff --git a/wgpu-native/src/registry.rs b/wgpu-native/src/registry.rs index f67ec3293c..08a072ec98 100644 --- a/wgpu-native/src/registry.rs +++ b/wgpu-native/src/registry.rs @@ -1,6 +1,9 @@ use std::marker::PhantomData; use std::os::raw::c_void; -use std::sync::{Arc, Mutex}; +#[cfg(feature = "remote")] +use std::sync::Arc; +#[cfg(feature = "remote")] +use parking_lot::{Mutex, MutexGuard, MappedMutexGuard}; use std::{borrow, cmp, fmt, ops, ptr}; use hal::backend::FastHashMap; @@ -11,11 +14,15 @@ pub(crate) type Id = *mut c_void; #[cfg(feature = "remote")] pub(crate) type Id = u32; +#[cfg(not(feature = "remote"))] +type RegistryItem<'a, T> = &'a mut T; +#[cfg(feature = "remote")] +type RegistryItem<'a, T> = MappedMutexGuard<'a, T>; + pub(crate) trait Registry { fn new() -> Self; fn register(&self, handle: T) -> Id; - fn get(&self, id: Id) -> Option<&T>; - fn get_mut(&self, id: Id) -> Option<&mut T>; + fn get_mut(&self, id: Id) -> RegistryItem; } #[cfg(not(feature = "remote"))] @@ -35,12 +42,8 @@ impl Registry for LocalRegistry { ::std::boxed::Box::into_raw(Box::new(handle)) as *mut _ as *mut c_void } - fn get(&self, id: Id) -> Option<&T> { - unsafe { (id as *const T).as_ref() } - } - - fn get_mut(&self, id: Id) -> Option<&mut T> { - unsafe { (id as *mut T).as_mut() } + fn get_mut(&self, id: Id) -> RegistryItem { + unsafe { (id as *mut T).as_mut() }.unwrap() } } @@ -74,36 +77,26 @@ impl Registry for RemoteRegistry { } fn register(&self, handle: T) -> Id { - let mut registrations = self.registrations.lock().unwrap(); + let mut registrations = self.registrations.lock(); let id = registrations.next_id; registrations.tracked.insert(id, handle); registrations.next_id += 1; id } - fn get(&self, id: Id) -> Option<&T> { - let registrations = self.registrations.lock().unwrap(); - registrations.tracked.get(&id) - } - - fn get_mut(&self, id: Id) -> Option<&mut T> { - let registrations = self.registrations.lock().unwrap(); - registrations.tracked.get_mut(&id) + fn get_mut(&self, id: Id) -> RegistryItem { + MutexGuard::map(self.registrations.lock(), |r| r.tracked.get_mut(&id).unwrap()) } } #[cfg(not(feature = "remote"))] -lazy_static! { - pub(crate) static ref ADAPTER_REGISTRY: LocalRegistry = LocalRegistry::new(); - pub(crate) static ref DEVICE_REGISTRY: LocalRegistry = LocalRegistry::new(); - pub(crate) static ref INSTANCE_REGISTRY: LocalRegistry = LocalRegistry::new(); - pub(crate) static ref SHADER_MODULE_REGISTRY: LocalRegistry = LocalRegistry::new(); -} - +type ConcreteRegistry = LocalRegistry; #[cfg(feature = "remote")] +type ConcreteRegistry = RemoteRegistry; + lazy_static! { - pub(crate) static ref ADAPTER_REGISTRY: RemoteRegistry = RemoteRegistry::new(); - pub(crate) static ref DEVICE_REGISTRY: RemoteRegistry = RemoteRegistry::new(); - pub(crate) static ref INSTANCE_REGISTRY: RemoteRegistry = RemoteRegistry::new(); - pub(crate) static ref SHADER_MODULE_REGISTRY: RemoteRegistry = RemoteRegistry::new(); + pub(crate) static ref ADAPTER_REGISTRY: ConcreteRegistry = ConcreteRegistry::new(); + pub(crate) static ref DEVICE_REGISTRY: ConcreteRegistry = ConcreteRegistry::new(); + pub(crate) static ref INSTANCE_REGISTRY: ConcreteRegistry = ConcreteRegistry::new(); + pub(crate) static ref SHADER_MODULE_REGISTRY: ConcreteRegistry = ConcreteRegistry::new(); }