surfman/platform/generic/multi/
device.rs

1// surfman/surfman/src/platform/generic/multi/device.rs
2//
3//! A device abstraction that allows the choice of backends dynamically.
4
5use super::connection::Connection;
6use super::context::{Context, ContextDescriptor, NativeContext};
7use super::surface::{NativeWidget, Surface, SurfaceTexture};
8use crate::connection::Connection as ConnectionInterface;
9use crate::context::ContextAttributes;
10use crate::device::Device as DeviceInterface;
11use crate::{ContextID, Error, GLApi, SurfaceAccess, SurfaceInfo, SurfaceType};
12use euclid::default::Size2D;
13use glow::Texture;
14
15use std::os::raw::c_void;
16
17/// Represents a hardware display adapter that can be used for rendering (including the CPU).
18///
19/// Adapters can be sent between threads. To render with an adapter, open a thread-local `Device`.
20pub enum Adapter<Def, Alt>
21where
22    Def: DeviceInterface,
23    Alt: DeviceInterface,
24{
25    /// The default adapter type.
26    Default(<Def::Connection as ConnectionInterface>::Adapter),
27    /// The alternate adapter type.
28    Alternate(<Alt::Connection as ConnectionInterface>::Adapter),
29}
30
31impl<Def, Alt> Clone for Adapter<Def, Alt>
32where
33    Def: DeviceInterface,
34    Alt: DeviceInterface,
35    <Def::Connection as ConnectionInterface>::Adapter: Clone,
36    <Alt::Connection as ConnectionInterface>::Adapter: Clone,
37{
38    fn clone(&self) -> Self {
39        match self {
40            Adapter::Default(ref adapter) => Adapter::Default(adapter.clone()),
41            Adapter::Alternate(ref adapter) => Adapter::Alternate(adapter.clone()),
42        }
43    }
44}
45
46/// A thread-local handle to a device.
47///
48/// Devices contain most of the relevant surface management methods.
49pub enum Device<Def, Alt>
50where
51    Def: DeviceInterface,
52    Alt: DeviceInterface,
53{
54    /// The default device type.
55    Default(Def),
56    /// The alternate device type.
57    Alternate(Alt),
58}
59
60/// Represents a native platform-specific device.
61pub enum NativeDevice<Def, Alt>
62where
63    Def: DeviceInterface,
64    Alt: DeviceInterface,
65{
66    /// The default native device type.
67    Default(<Def::Connection as ConnectionInterface>::NativeDevice),
68    /// The alternate native device type.
69    Alternate(<Alt::Connection as ConnectionInterface>::NativeDevice),
70}
71
72impl<Def, Alt> Device<Def, Alt>
73where
74    Def: DeviceInterface,
75    Alt: DeviceInterface,
76    Def::Connection: ConnectionInterface,
77    Alt::Connection: ConnectionInterface,
78{
79    /// Returns the native device underlying this device.
80    pub fn native_device(&self) -> NativeDevice<Def, Alt> {
81        match *self {
82            Device::Default(ref device) => NativeDevice::Default(device.native_device()),
83            Device::Alternate(ref device) => NativeDevice::Alternate(device.native_device()),
84        }
85    }
86
87    /// Returns the display server connection that this device was created with.
88    pub fn connection(&self) -> Connection<Def, Alt> {
89        match *self {
90            Device::Default(ref device) => Connection::Default(device.connection()),
91            Device::Alternate(ref device) => Connection::Alternate(device.connection()),
92        }
93    }
94
95    /// Returns the adapter that this device was created with.
96    pub fn adapter(&self) -> Adapter<Def, Alt> {
97        match *self {
98            Device::Default(ref device) => Adapter::Default(device.adapter()),
99            Device::Alternate(ref device) => Adapter::Alternate(device.adapter()),
100        }
101    }
102
103    /// Returns the OpenGL API flavor that this device supports (OpenGL or OpenGL ES).
104    pub fn gl_api(&self) -> GLApi {
105        match *self {
106            Device::Default(ref device) => device.gl_api(),
107            Device::Alternate(ref device) => device.gl_api(),
108        }
109    }
110}
111
112impl<Def, Alt> DeviceInterface for Device<Def, Alt>
113where
114    Def: DeviceInterface,
115    Alt: DeviceInterface,
116    Def::Connection: ConnectionInterface<Device = Def>,
117    Alt::Connection: ConnectionInterface<Device = Alt>,
118{
119    type Connection = Connection<Def, Alt>;
120    type Context = Context<Def, Alt>;
121    type ContextDescriptor = ContextDescriptor<Def, Alt>;
122    type NativeContext = NativeContext<Def, Alt>;
123    type Surface = Surface<Def, Alt>;
124    type SurfaceTexture = SurfaceTexture<Def, Alt>;
125
126    // device.rs
127
128    #[inline]
129    fn native_device(&self) -> NativeDevice<Def, Alt> {
130        Device::native_device(self)
131    }
132
133    #[inline]
134    fn connection(&self) -> Connection<Def, Alt> {
135        Device::connection(self)
136    }
137
138    #[inline]
139    fn adapter(&self) -> Adapter<Def, Alt> {
140        Device::adapter(self)
141    }
142
143    #[inline]
144    fn gl_api(&self) -> GLApi {
145        Device::gl_api(self)
146    }
147
148    // context.rs
149
150    #[inline]
151    fn create_context_descriptor(
152        &self,
153        attributes: &ContextAttributes,
154    ) -> Result<Self::ContextDescriptor, Error> {
155        Device::create_context_descriptor(self, attributes)
156    }
157
158    #[inline]
159    fn create_context(
160        &mut self,
161        descriptor: &ContextDescriptor<Def, Alt>,
162        share_with: Option<&Context<Def, Alt>>,
163    ) -> Result<Context<Def, Alt>, Error> {
164        Device::create_context(self, descriptor, share_with)
165    }
166
167    #[inline]
168    unsafe fn create_context_from_native_context(
169        &self,
170        native_context: Self::NativeContext,
171    ) -> Result<Context<Def, Alt>, Error> {
172        Device::create_context_from_native_context(self, native_context)
173    }
174
175    #[inline]
176    fn destroy_context(&self, context: &mut Context<Def, Alt>) -> Result<(), Error> {
177        Device::destroy_context(self, context)
178    }
179
180    #[inline]
181    fn native_context(&self, context: &Context<Def, Alt>) -> Self::NativeContext {
182        Device::native_context(self, context)
183    }
184
185    #[inline]
186    fn context_descriptor(&self, context: &Context<Def, Alt>) -> Self::ContextDescriptor {
187        Device::context_descriptor(self, context)
188    }
189
190    #[inline]
191    fn make_context_current(&self, context: &Context<Def, Alt>) -> Result<(), Error> {
192        Device::make_context_current(self, context)
193    }
194
195    #[inline]
196    fn make_no_context_current(&self) -> Result<(), Error> {
197        Device::make_no_context_current(self)
198    }
199
200    #[inline]
201    fn context_descriptor_attributes(
202        &self,
203        context_descriptor: &ContextDescriptor<Def, Alt>,
204    ) -> ContextAttributes {
205        Device::context_descriptor_attributes(self, context_descriptor)
206    }
207
208    #[inline]
209    fn get_proc_address(&self, context: &Context<Def, Alt>, symbol_name: &str) -> *const c_void {
210        Device::get_proc_address(self, context, symbol_name)
211    }
212
213    #[inline]
214    fn bind_surface_to_context(
215        &self,
216        context: &mut Context<Def, Alt>,
217        surface: Surface<Def, Alt>,
218    ) -> Result<(), (Error, Surface<Def, Alt>)> {
219        Device::bind_surface_to_context(self, context, surface)
220    }
221
222    #[inline]
223    fn unbind_surface_from_context(
224        &self,
225        context: &mut Context<Def, Alt>,
226    ) -> Result<Option<Surface<Def, Alt>>, Error> {
227        Device::unbind_surface_from_context(self, context)
228    }
229
230    #[inline]
231    fn context_id(&self, context: &Context<Def, Alt>) -> ContextID {
232        Device::context_id(self, context)
233    }
234
235    #[inline]
236    fn context_surface_info(
237        &self,
238        context: &Context<Def, Alt>,
239    ) -> Result<Option<SurfaceInfo>, Error> {
240        Device::context_surface_info(self, context)
241    }
242
243    // surface.rs
244
245    #[inline]
246    fn create_surface(
247        &mut self,
248        context: &Context<Def, Alt>,
249        surface_access: SurfaceAccess,
250        surface_type: SurfaceType<NativeWidget<Def, Alt>>,
251    ) -> Result<Surface<Def, Alt>, Error> {
252        Device::create_surface(self, context, surface_access, surface_type)
253    }
254
255    #[inline]
256    fn create_surface_texture(
257        &self,
258        context: &mut Context<Def, Alt>,
259        surface: Surface<Def, Alt>,
260    ) -> Result<SurfaceTexture<Def, Alt>, (Error, Surface<Def, Alt>)> {
261        Device::create_surface_texture(self, context, surface)
262    }
263
264    #[inline]
265    fn destroy_surface(
266        &self,
267        context: &mut Context<Def, Alt>,
268        surface: &mut Surface<Def, Alt>,
269    ) -> Result<(), Error> {
270        Device::destroy_surface(self, context, surface)
271    }
272
273    #[inline]
274    fn destroy_surface_texture(
275        &self,
276        context: &mut Context<Def, Alt>,
277        surface_texture: SurfaceTexture<Def, Alt>,
278    ) -> Result<Surface<Def, Alt>, (Error, SurfaceTexture<Def, Alt>)> {
279        Device::destroy_surface_texture(self, context, surface_texture)
280    }
281
282    #[inline]
283    fn surface_gl_texture_target(&self) -> u32 {
284        Device::surface_gl_texture_target(self)
285    }
286
287    #[inline]
288    fn present_surface(
289        &self,
290        context: &Context<Def, Alt>,
291        surface: &mut Surface<Def, Alt>,
292    ) -> Result<(), Error> {
293        Device::present_surface(self, context, surface)
294    }
295
296    #[inline]
297    fn resize_surface(
298        &self,
299        context: &Context<Def, Alt>,
300        surface: &mut Surface<Def, Alt>,
301        size: Size2D<i32>,
302    ) -> Result<(), Error> {
303        Device::resize_surface(self, context, surface, size)
304    }
305
306    #[inline]
307    fn surface_info(&self, surface: &Surface<Def, Alt>) -> SurfaceInfo {
308        Device::surface_info(self, surface)
309    }
310
311    #[inline]
312    fn surface_texture_object(
313        &self,
314        surface_texture: &SurfaceTexture<Def, Alt>,
315    ) -> Option<Texture> {
316        Device::surface_texture_object(self, surface_texture)
317    }
318}