Skip to main content

runmat_plot/
context.rs

1#[cfg(target_arch = "wasm32")]
2use runmat_thread_local::runmat_thread_local;
3#[cfg(target_arch = "wasm32")]
4use std::cell::RefCell;
5use std::sync::Arc;
6#[cfg(not(target_arch = "wasm32"))]
7use std::sync::{OnceLock, RwLock};
8
9/// Shared WGPU instance/device/queue triple exported by a host acceleration provider.
10#[derive(Clone)]
11pub struct SharedWgpuContext {
12    pub instance: Arc<wgpu::Instance>,
13    pub device: Arc<wgpu::Device>,
14    pub queue: Arc<wgpu::Queue>,
15    pub adapter: Arc<wgpu::Adapter>,
16    pub adapter_info: wgpu::AdapterInfo,
17    pub limits: wgpu::Limits,
18    pub features: wgpu::Features,
19}
20
21#[cfg(not(target_arch = "wasm32"))]
22static GLOBAL_CONTEXT: OnceLock<RwLock<Option<SharedWgpuContext>>> = OnceLock::new();
23
24#[cfg(target_arch = "wasm32")]
25runmat_thread_local! {
26    static GLOBAL_CONTEXT: RefCell<Option<SharedWgpuContext>> = RefCell::new(None);
27}
28
29#[cfg(not(target_arch = "wasm32"))]
30fn global_context() -> &'static RwLock<Option<SharedWgpuContext>> {
31    GLOBAL_CONTEXT.get_or_init(|| RwLock::new(None))
32}
33
34/// Install a shared context that other subsystems (GUI, exporters, web) can reuse.
35pub fn install_shared_wgpu_context(context: SharedWgpuContext) {
36    #[cfg(not(target_arch = "wasm32"))]
37    if let Ok(mut slot) = global_context().write() {
38        *slot = Some(context);
39    }
40    #[cfg(target_arch = "wasm32")]
41    GLOBAL_CONTEXT.with(|cell| {
42        *cell.borrow_mut() = Some(context);
43    });
44}
45
46/// Retrieve the shared context if one has been installed.
47pub fn shared_wgpu_context() -> Option<SharedWgpuContext> {
48    #[cfg(not(target_arch = "wasm32"))]
49    {
50        global_context()
51            .read()
52            .ok()
53            .and_then(|context| context.clone())
54    }
55    #[cfg(target_arch = "wasm32")]
56    {
57        GLOBAL_CONTEXT.with(|cell| cell.borrow().clone())
58    }
59}