surfman/platform/unix/generic/
device.rs

1// surfman/surfman/src/platform/unix/generic/device.rs
2//
3//! A wrapper around surfaceless Mesa `EGLDisplay`s.
4
5use super::connection::{Connection, NativeConnectionWrapper};
6use crate::{Error, GLApi};
7
8use std::env;
9use std::sync::Arc;
10
11static MESA_SOFTWARE_RENDERING_ENV_VAR: &str = "LIBGL_ALWAYS_SOFTWARE";
12static MESA_DRI_PRIME_ENV_VAR: &str = "DRI_PRIME";
13
14/// Represents a hardware display adapter that can be used for rendering (including the CPU).
15///
16/// Adapters can be sent between threads. To render with an adapter, open a thread-local `Device`.
17#[derive(Clone, Debug)]
18pub enum Adapter {
19    #[doc(hidden)]
20    Hardware,
21    #[doc(hidden)]
22    HardwarePrime,
23    #[doc(hidden)]
24    Software,
25}
26
27impl Adapter {
28    #[inline]
29    pub(crate) fn hardware() -> Adapter {
30        Adapter::HardwarePrime
31    }
32
33    #[inline]
34    pub(crate) fn low_power() -> Adapter {
35        Adapter::Hardware
36    }
37
38    #[inline]
39    pub(crate) fn software() -> Adapter {
40        Adapter::Software
41    }
42
43    pub(crate) fn set_environment_variables(&self) {
44        match *self {
45            Adapter::Hardware | Adapter::HardwarePrime => {
46                env::remove_var(MESA_SOFTWARE_RENDERING_ENV_VAR);
47            }
48            Adapter::Software => {
49                env::set_var(MESA_SOFTWARE_RENDERING_ENV_VAR, "1");
50            }
51        }
52
53        match *self {
54            Adapter::Software => {}
55            Adapter::Hardware => {
56                env::remove_var(MESA_DRI_PRIME_ENV_VAR);
57            }
58            Adapter::HardwarePrime => {
59                env::set_var(MESA_DRI_PRIME_ENV_VAR, "1");
60            }
61        }
62    }
63}
64
65/// A thread-local handle to a device.
66///
67/// Devices contain most of the relevant surface management methods.
68pub struct Device {
69    pub(crate) native_connection: Arc<NativeConnectionWrapper>,
70    pub(crate) adapter: Adapter,
71}
72
73/// Wraps an adapter.
74///
75/// On Wayland, devices and adapters are essentially identical types.
76#[derive(Clone)]
77pub struct NativeDevice {
78    /// The hardware adapter corresponding to this device.
79    pub adapter: Adapter,
80}
81
82impl Device {
83    #[inline]
84    pub(crate) fn new(connection: &Connection, adapter: &Adapter) -> Result<Device, Error> {
85        Ok(Device {
86            native_connection: connection.native_connection.clone(),
87            adapter: (*adapter).clone(),
88        })
89    }
90
91    /// Returns the native device corresponding to this device.
92    ///
93    /// This method is essentially an alias for the `adapter()` method on Mesa, since there is
94    /// no explicit concept of a device on this backend.
95    #[inline]
96    pub fn native_device(&self) -> NativeDevice {
97        NativeDevice {
98            adapter: self.adapter(),
99        }
100    }
101
102    /// Returns the display server connection that this device was created with.
103    #[inline]
104    pub fn connection(&self) -> Connection {
105        Connection {
106            native_connection: self.native_connection.clone(),
107        }
108    }
109
110    /// Returns the adapter that this device was created with.
111    #[inline]
112    pub fn adapter(&self) -> Adapter {
113        self.adapter.clone()
114    }
115
116    /// Returns the OpenGL API flavor that this device supports (OpenGL or OpenGL ES).
117    #[inline]
118    pub fn gl_api(&self) -> GLApi {
119        GLApi::GL
120    }
121}