summaryrefslogtreecommitdiffstats
path: root/third_party/rust/wgpu-core/src/global.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /third_party/rust/wgpu-core/src/global.rs
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/wgpu-core/src/global.rs')
-rw-r--r--third_party/rust/wgpu-core/src/global.rs172
1 files changed, 172 insertions, 0 deletions
diff --git a/third_party/rust/wgpu-core/src/global.rs b/third_party/rust/wgpu-core/src/global.rs
new file mode 100644
index 0000000000..9a8c43bf33
--- /dev/null
+++ b/third_party/rust/wgpu-core/src/global.rs
@@ -0,0 +1,172 @@
+use std::sync::Arc;
+
+use wgt::Backend;
+
+use crate::{
+ hal_api::HalApi,
+ hub::{HubReport, Hubs},
+ instance::{Instance, Surface},
+ registry::{Registry, RegistryReport},
+ resource_log,
+ storage::Element,
+};
+
+#[derive(Debug, PartialEq, Eq)]
+pub struct GlobalReport {
+ pub surfaces: RegistryReport,
+ #[cfg(vulkan)]
+ pub vulkan: Option<HubReport>,
+ #[cfg(metal)]
+ pub metal: Option<HubReport>,
+ #[cfg(dx12)]
+ pub dx12: Option<HubReport>,
+ #[cfg(gles)]
+ pub gl: Option<HubReport>,
+}
+
+impl GlobalReport {
+ pub fn surfaces(&self) -> &RegistryReport {
+ &self.surfaces
+ }
+ pub fn hub_report(&self, backend: Backend) -> &HubReport {
+ match backend {
+ #[cfg(vulkan)]
+ Backend::Vulkan => self.vulkan.as_ref().unwrap(),
+ #[cfg(metal)]
+ Backend::Metal => self.metal.as_ref().unwrap(),
+ #[cfg(dx12)]
+ Backend::Dx12 => self.dx12.as_ref().unwrap(),
+ #[cfg(gles)]
+ Backend::Gl => self.gl.as_ref().unwrap(),
+ _ => panic!("HubReport is not supported on this backend"),
+ }
+ }
+}
+
+pub struct Global {
+ pub instance: Instance,
+ pub surfaces: Registry<Surface>,
+ pub(crate) hubs: Hubs,
+}
+
+impl Global {
+ pub fn new(name: &str, instance_desc: wgt::InstanceDescriptor) -> Self {
+ profiling::scope!("Global::new");
+ Self {
+ instance: Instance::new(name, instance_desc),
+ surfaces: Registry::without_backend(),
+ hubs: Hubs::new(),
+ }
+ }
+
+ /// # Safety
+ ///
+ /// Refer to the creation of wgpu-hal Instance for every backend.
+ pub unsafe fn from_hal_instance<A: HalApi>(name: &str, hal_instance: A::Instance) -> Self {
+ profiling::scope!("Global::new");
+ Self {
+ instance: A::create_instance_from_hal(name, hal_instance),
+ surfaces: Registry::without_backend(),
+ hubs: Hubs::new(),
+ }
+ }
+
+ /// # Safety
+ ///
+ /// - The raw instance handle returned must not be manually destroyed.
+ pub unsafe fn instance_as_hal<A: HalApi>(&self) -> Option<&A::Instance> {
+ A::instance_as_hal(&self.instance)
+ }
+
+ /// # Safety
+ ///
+ /// - The raw handles obtained from the Instance must not be manually destroyed
+ pub unsafe fn from_instance(instance: Instance) -> Self {
+ profiling::scope!("Global::new");
+ Self {
+ instance,
+ surfaces: Registry::without_backend(),
+ hubs: Hubs::new(),
+ }
+ }
+
+ pub fn clear_backend<A: HalApi>(&self, _dummy: ()) {
+ let hub = A::hub(self);
+ let surfaces_locked = self.surfaces.read();
+ // this is used for tests, which keep the adapter
+ hub.clear(&surfaces_locked, false);
+ }
+
+ pub fn generate_report(&self) -> GlobalReport {
+ GlobalReport {
+ surfaces: self.surfaces.generate_report(),
+ #[cfg(vulkan)]
+ vulkan: if self.instance.vulkan.is_some() {
+ Some(self.hubs.vulkan.generate_report())
+ } else {
+ None
+ },
+ #[cfg(metal)]
+ metal: if self.instance.metal.is_some() {
+ Some(self.hubs.metal.generate_report())
+ } else {
+ None
+ },
+ #[cfg(dx12)]
+ dx12: if self.instance.dx12.is_some() {
+ Some(self.hubs.dx12.generate_report())
+ } else {
+ None
+ },
+ #[cfg(gles)]
+ gl: if self.instance.gl.is_some() {
+ Some(self.hubs.gl.generate_report())
+ } else {
+ None
+ },
+ }
+ }
+}
+
+impl Drop for Global {
+ fn drop(&mut self) {
+ profiling::scope!("Global::drop");
+ resource_log!("Global::drop");
+ let mut surfaces_locked = self.surfaces.write();
+
+ // destroy hubs before the instance gets dropped
+ #[cfg(vulkan)]
+ {
+ self.hubs.vulkan.clear(&surfaces_locked, true);
+ }
+ #[cfg(metal)]
+ {
+ self.hubs.metal.clear(&surfaces_locked, true);
+ }
+ #[cfg(dx12)]
+ {
+ self.hubs.dx12.clear(&surfaces_locked, true);
+ }
+ #[cfg(gles)]
+ {
+ self.hubs.gl.clear(&surfaces_locked, true);
+ }
+
+ // destroy surfaces
+ for element in surfaces_locked.map.drain(..) {
+ if let Element::Occupied(arc_surface, _) = element {
+ if let Some(surface) = Arc::into_inner(arc_surface) {
+ self.instance.destroy_surface(surface);
+ } else {
+ panic!("Surface cannot be destroyed because is still in use");
+ }
+ }
+ }
+ }
+}
+
+#[cfg(send_sync)]
+fn _test_send_sync(global: &Global) {
+ fn test_internal<T: Send + Sync>(_: T) {}
+ test_internal(global)
+}