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 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 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 pub unsafe fn instance_as_hal<A: HalApi>(&self) -> Option<&A::Instance> {
65 unsafe { self.instance.as_hal::<A>() }
66 }
67
68 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}