wgpu_native_texture_interop/surfman_gl/
mod.rs1mod 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}