Skip to main content

wgpu_native_texture_interop/surfman_gl/
mod.rs

1mod adapter;
2mod surfman_frame_context;
3
4#[cfg(any(target_os = "linux", target_os = "android"))]
5mod linux;
6
7#[cfg(target_vendor = "apple")]
8mod metal;
9
10#[cfg(target_os = "windows")]
11mod windows;
12
13#[cfg(target_os = "windows")]
14mod windows_dx12_shared;
15
16pub use adapter::select_adapter_matching_surfman_luid;
17
18use std::cell::Cell;
19use std::rc::Rc;
20
21use dpi::PhysicalSize;
22
23use crate::{
24    FrameProducer, GlFramebufferSource, GlFramebufferSourceImpl, HostWgpuContext, ImportOptions,
25    ImportedTexture, InteropBackend, InteropError, NativeFrame, NativeFrameKind,
26    ProducerCapabilities, SyncMechanism, UnsupportedReason,
27};
28
29pub use surfman_frame_context::SurfmanFrameContext;
30
31pub struct SurfmanFrameProducer {
32    context: Rc<SurfmanFrameContext>,
33    size: Rc<Cell<PhysicalSize<u32>>>,
34    generation: Cell<u64>,
35    #[cfg(target_os = "windows")]
36    angle_dx12_shared: Rc<windows_dx12_shared::AngleDx12SharedCache>,
37}
38
39#[cfg_attr(target_os = "windows", allow(dead_code))]
40struct SurfmanGlFrameSource {
41    context: Rc<SurfmanFrameContext>,
42    size: PhysicalSize<u32>,
43    generation: u64,
44    #[cfg(target_os = "windows")]
45    angle_dx12_shared: Rc<windows_dx12_shared::AngleDx12SharedCache>,
46}
47
48impl SurfmanFrameProducer {
49    pub fn new(context: Rc<SurfmanFrameContext>, initial_size: PhysicalSize<u32>) -> Self {
50        Self {
51            context,
52            size: Rc::new(Cell::new(initial_size)),
53            generation: Cell::new(0),
54            #[cfg(target_os = "windows")]
55            angle_dx12_shared: Rc::new(windows_dx12_shared::AngleDx12SharedCache::new()),
56        }
57    }
58
59    pub fn context(&self) -> Rc<SurfmanFrameContext> {
60        self.context.clone()
61    }
62
63    pub fn size(&self) -> PhysicalSize<u32> {
64        self.size.get()
65    }
66
67    pub fn set_size(&self, size: PhysicalSize<u32>) {
68        self.size.set(size);
69    }
70}
71
72impl FrameProducer for SurfmanFrameProducer {
73    fn capabilities(&self) -> ProducerCapabilities {
74        ProducerCapabilities {
75            supported_frames: vec![NativeFrameKind::GlFramebufferSource],
76        }
77    }
78
79    fn acquire_frame(&mut self) -> Result<NativeFrame, InteropError> {
80        let next_generation = self.generation.get() + 1;
81        self.generation.set(next_generation);
82
83        Ok(NativeFrame::GlFramebufferSource(GlFramebufferSource::new(
84            self.size.get(),
85            next_generation,
86            SyncMechanism::None,
87            Rc::new(SurfmanGlFrameSource {
88                context: self.context.clone(),
89                size: self.size.get(),
90                generation: next_generation,
91                #[cfg(target_os = "windows")]
92                angle_dx12_shared: self.angle_dx12_shared.clone(),
93            }),
94        )))
95    }
96}
97
98impl GlFramebufferSourceImpl for SurfmanGlFrameSource {
99    fn import_into(
100        &self,
101        _frame: &GlFramebufferSource,
102        host: &HostWgpuContext,
103        _options: &ImportOptions,
104    ) -> Result<ImportedTexture, InteropError> {
105        match host.backend {
106            #[cfg(any(target_os = "linux", target_os = "android"))]
107            InteropBackend::Vulkan => linux::import_current_frame(self, _frame, host, _options),
108
109            #[cfg(target_os = "windows")]
110            InteropBackend::Vulkan => windows::import_current_frame(self, _frame, host, _options),
111
112            #[cfg(target_vendor = "apple")]
113            InteropBackend::Metal => metal::import_current_frame(self, _frame, host, _options),
114
115            #[cfg(target_os = "windows")]
116            InteropBackend::Dx12 => {
117                windows::import_current_frame_dx12(self, _frame, host, _options)
118            }
119
120            #[cfg(not(target_os = "windows"))]
121            InteropBackend::Dx12 => Err(InteropError::Unsupported(
122                UnsupportedReason::PlatformNotImplemented,
123            )),
124            InteropBackend::Unknown => Err(InteropError::Unsupported(
125                UnsupportedReason::HostBackendUnavailable,
126            )),
127            _ => Err(InteropError::Unsupported(
128                UnsupportedReason::HostBackendMismatch,
129            )),
130        }
131    }
132}