Skip to main content

wgpu_native_texture_interop/surfman_gl/
mod.rs

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