wgpu_core/
global.rs

1use std::{fmt, sync::Arc};
2
3use crate::{
4    hal_api::HalApi,
5    hub::{Hub, HubReport},
6    instance::{Instance, Surface},
7    registry::{Registry, RegistryReport},
8    resource_log,
9};
10
11#[derive(Debug, PartialEq, Eq)]
12pub struct GlobalReport {
13    pub surfaces: RegistryReport,
14    pub hub: HubReport,
15}
16
17impl GlobalReport {
18    pub fn surfaces(&self) -> &RegistryReport {
19        &self.surfaces
20    }
21    pub fn hub_report(&self) -> &HubReport {
22        &self.hub
23    }
24}
25
26pub struct Global {
27    pub(crate) surfaces: Registry<Arc<Surface>>,
28    pub(crate) hub: Hub,
29    // the instance must be dropped last
30    pub instance: Instance,
31}
32
33impl Global {
34    pub fn new(name: &str, instance_desc: &wgt::InstanceDescriptor) -> Self {
35        profiling::scope!("Global::new");
36        Self {
37            instance: Instance::new(name, instance_desc),
38            surfaces: Registry::new(),
39            hub: Hub::new(),
40        }
41    }
42
43    /// # Safety
44    ///
45    /// Refer to the creation of wgpu-hal Instance for every backend.
46    pub unsafe fn from_hal_instance<A: HalApi>(name: &str, hal_instance: A::Instance) -> Self {
47        profiling::scope!("Global::new");
48
49        let dyn_instance: Box<dyn hal::DynInstance> = Box::new(hal_instance);
50        Self {
51            instance: Instance {
52                name: name.to_owned(),
53                instance_per_backend: std::iter::once((A::VARIANT, dyn_instance)).collect(),
54                ..Default::default()
55            },
56            surfaces: Registry::new(),
57            hub: Hub::new(),
58        }
59    }
60
61    /// # Safety
62    ///
63    /// - The raw instance handle returned must not be manually destroyed.
64    pub unsafe fn instance_as_hal<A: HalApi>(&self) -> Option<&A::Instance> {
65        unsafe { self.instance.as_hal::<A>() }
66    }
67
68    /// # Safety
69    ///
70    /// - The raw handles obtained from the Instance must not be manually destroyed
71    pub unsafe fn from_instance(instance: Instance) -> Self {
72        profiling::scope!("Global::new");
73        Self {
74            instance,
75            surfaces: Registry::new(),
76            hub: Hub::new(),
77        }
78    }
79
80    pub fn generate_report(&self) -> GlobalReport {
81        GlobalReport {
82            surfaces: self.surfaces.generate_report(),
83            hub: self.hub.generate_report(),
84        }
85    }
86}
87
88impl fmt::Debug for Global {
89    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
90        f.debug_struct("Global").finish()
91    }
92}
93
94impl Drop for Global {
95    fn drop(&mut self) {
96        profiling::scope!("Global::drop");
97        resource_log!("Global::drop");
98    }
99}
100
101#[cfg(send_sync)]
102fn _test_send_sync(global: &Global) {
103    fn test_internal<T: Send + Sync>(_: T) {}
104    test_internal(global)
105}