wgpu_native_texture_interop/raw_gl/
producer.rs1use std::ffi::c_void;
8use std::rc::Rc;
9use std::sync::Arc;
10
11use dpi::PhysicalSize;
12
13use crate::{
14 FrameProducer, GlFramebufferSource, GlFramebufferSourceImpl, HostWgpuContext, ImportOptions,
15 ImportedTexture, InteropError, NativeFrame, NativeFrameKind, ProducerCapabilities,
16 SyncMechanism, TextureOrigin, UnsupportedReason,
17};
18
19pub struct RawGlFrameProducer {
53 gl: Arc<glow::Context>,
54 proc_loader: Rc<dyn Fn(&str) -> *const c_void>,
55 source_fbo: u32,
56 size: PhysicalSize<u32>,
57 generation: u64,
58}
59
60impl RawGlFrameProducer {
61 pub fn new(
71 gl: Arc<glow::Context>,
72 proc_loader: impl Fn(&str) -> *const c_void + 'static,
73 source_fbo: u32,
74 size: PhysicalSize<u32>,
75 ) -> Self {
76 Self {
77 gl,
78 proc_loader: Rc::new(proc_loader),
79 source_fbo,
80 size,
81 generation: 0,
82 }
83 }
84
85 pub fn set_source_fbo(&mut self, fbo: u32) {
87 self.source_fbo = fbo;
88 }
89
90 pub fn set_size(&mut self, size: PhysicalSize<u32>) {
92 self.size = size;
93 }
94}
95
96impl FrameProducer for RawGlFrameProducer {
97 fn capabilities(&self) -> ProducerCapabilities {
98 ProducerCapabilities {
99 supported_frames: vec![NativeFrameKind::GlFramebufferSource],
100 }
101 }
102
103 fn acquire_frame(&mut self) -> Result<NativeFrame, InteropError> {
104 self.generation += 1;
105
106 Ok(NativeFrame::GlFramebufferSource(GlFramebufferSource::new(
107 self.size,
108 self.generation,
109 SyncMechanism::None,
110 Rc::new(RawGlImportImpl {
111 gl: self.gl.clone(),
112 proc_loader: self.proc_loader.clone(),
113 source_fbo: self.source_fbo,
114 size: self.size,
115 generation: self.generation,
116 }),
117 )))
118 }
119}
120
121#[allow(dead_code)]
122struct RawGlImportImpl {
123 gl: Arc<glow::Context>,
124 proc_loader: Rc<dyn Fn(&str) -> *const c_void>,
125 source_fbo: u32,
126 size: PhysicalSize<u32>,
127 generation: u64,
128}
129
130impl GlFramebufferSourceImpl for RawGlImportImpl {
131 fn import_into(
132 &self,
133 _frame: &GlFramebufferSource,
134 host: &HostWgpuContext,
135 _options: &ImportOptions,
136 ) -> Result<ImportedTexture, InteropError> {
137 let texture = self.import_texture(host)?;
138
139 Ok(ImportedTexture {
140 texture,
141 format: wgpu::TextureFormat::Rgba8Unorm,
142 size: self.size,
143 origin: TextureOrigin::TopLeft,
144 generation: self.generation,
145 consumer_sync: SyncMechanism::ImplicitGlFlush,
146 })
147 }
148}
149
150impl RawGlImportImpl {
151 #[allow(unused_variables)]
152 fn import_texture(&self, host: &HostWgpuContext) -> Result<wgpu::Texture, InteropError> {
153 #[cfg(any(target_os = "linux", target_os = "android"))]
154 if host.backend == crate::InteropBackend::Vulkan {
155 return super::linux::import_gl_framebuffer_vulkan(
156 &self.gl,
157 &|name| (self.proc_loader)(name),
158 self.source_fbo,
159 self.size,
160 host,
161 );
162 }
163
164 #[cfg(target_os = "windows")]
165 if host.backend == crate::InteropBackend::Vulkan {
166 return super::windows::import_gl_framebuffer_vulkan_win32(
167 &self.gl,
168 &|name| (self.proc_loader)(name),
169 self.source_fbo,
170 self.size,
171 host,
172 );
173 }
174
175 #[cfg(target_os = "windows")]
176 if host.backend == crate::InteropBackend::Dx12 {
177 return super::dx12::import_gl_framebuffer_dx12(
178 &self.gl,
179 &|name| (self.proc_loader)(name),
180 self.source_fbo,
181 self.size,
182 host,
183 );
184 }
185
186 Err(InteropError::Unsupported(
187 UnsupportedReason::HostBackendMismatch,
188 ))
189 }
190}