|
| 1 | +use super::*; |
| 2 | + |
| 3 | +/// Describes a possible format. |
| 4 | +#[allow(missing_docs)] |
| 5 | +#[derive(Debug, Clone)] |
| 6 | +pub struct SurfaceConfigAttribs { |
| 7 | + pub version: GlVersion, |
| 8 | + pub api: Api, |
| 9 | + |
| 10 | + pub hardware_accelerated: bool, |
| 11 | + /// The number of color bits. Does not include alpha bits. |
| 12 | + pub color_bits: u8, |
| 13 | + pub alpha_bits: u8, |
| 14 | + pub depth_bits: u8, |
| 15 | + pub stencil_bits: u8, |
| 16 | + pub stereoscopy: bool, |
| 17 | + pub double_buffer: bool, |
| 18 | + /// `None` if multisampling is disabled, otherwise `Some(N)` where `N` is |
| 19 | + /// the multisampling level. |
| 20 | + pub multisampling: Option<u16>, |
| 21 | + pub srgb: bool, |
| 22 | + pub vsync: bool, |
| 23 | + pub pbuffer_support: bool, |
| 24 | + pub window_surface_support: bool, |
| 25 | +} |
| 26 | + |
| 27 | +/// Describes a possible format. |
| 28 | +#[allow(missing_docs)] |
| 29 | +#[derive(Debug)] |
| 30 | +pub struct SurfaceConfigWrapper<T> { |
| 31 | + pub attribs: SurfaceConfigAttribs, |
| 32 | + pub(crate) config: T, |
| 33 | +} |
| 34 | + |
| 35 | +pub type SurfaceConfig = SurfaceConfigWrapper<platform_impl::SurfaceConfig>; |
| 36 | + |
| 37 | +impl<T> SurfaceConfigWrapper<T> { |
| 38 | + /// Turns the `config` parameter into another type by calling a closure. |
| 39 | + #[inline] |
| 40 | + pub(crate) fn map_config<F, T2>(self, f: F) -> ContextBuilderWrapper<T2> |
| 41 | + where |
| 42 | + F: FnOnce(T) -> T2, |
| 43 | + { |
| 44 | + SurfaceConfigWrapper { |
| 45 | + config: f(self.config), |
| 46 | + attribs: self.attribs, |
| 47 | + } |
| 48 | + } |
| 49 | + |
| 50 | + /// Turns the `config` parameter into another type. |
| 51 | + #[inline] |
| 52 | + pub(crate) fn with_config<T2>(&self, config: T2) -> ContextBuilderWrapper<T2> { |
| 53 | + SurfaceConfigWrapper { |
| 54 | + config, |
| 55 | + attribs: self.attribs.clone(), |
| 56 | + } |
| 57 | + } |
| 58 | +} |
| 59 | + |
| 60 | +/// Describes how the backend should choose a pixel format. |
| 61 | +// TODO: swap method? (swap, copy) |
| 62 | +#[derive(Clone, Debug)] |
| 63 | +pub struct SurfaceConfigBuilder { |
| 64 | + /// Version to try create. See [`GlRequest`] for more infos. |
| 65 | + /// |
| 66 | + /// The default is [`Latest`]. |
| 67 | + /// |
| 68 | + /// [`Latest`]: enum.GlRequest.html#variant.Latest |
| 69 | + /// [`GlRequest`]: enum.GlRequest.html |
| 70 | + pub version: GlRequest, |
| 71 | + |
| 72 | + /// If true, only hardware-accelerated formats will be considered. If |
| 73 | + /// false, only software renderers. `None` means "don't care". Default |
| 74 | + /// is `Some(true)`. |
| 75 | + pub hardware_accelerated: Option<bool>, |
| 76 | + |
| 77 | + /// Minimum number of bits for the color buffer, excluding alpha. `None` |
| 78 | + /// means "don't care". The default is `Some(24)`. |
| 79 | + pub color_bits: Option<u8>, |
| 80 | + |
| 81 | + /// If true, the color buffer must be in a floating point format. Default |
| 82 | + /// is `false`. |
| 83 | + /// |
| 84 | + /// Using floating points allows you to write values outside of the `[0.0, |
| 85 | + /// 1.0]` range. |
| 86 | + pub float_color_buffer: bool, |
| 87 | + |
| 88 | + /// Minimum number of bits for the alpha in the color buffer. `None` means |
| 89 | + /// "don't care". The default is `Some(8)`. |
| 90 | + pub alpha_bits: Option<u8>, |
| 91 | + |
| 92 | + /// Minimum number of bits for the depth buffer. `None` means "don't care". |
| 93 | + /// The default value is `Some(24)`. |
| 94 | + pub depth_bits: Option<u8>, |
| 95 | + |
| 96 | + /// Minimum number of stencil bits. `None` means "don't care". |
| 97 | + /// The default value is `Some(8)`. |
| 98 | + pub stencil_bits: Option<u8>, |
| 99 | + |
| 100 | + /// If true, only double-buffered formats will be considered. If false, |
| 101 | + /// only single-buffer formats. `None` means "don't care". The default |
| 102 | + /// is `Some(true)`. |
| 103 | + pub double_buffer: Option<bool>, |
| 104 | + |
| 105 | + /// Contains the minimum number of samples per pixel in the color, depth |
| 106 | + /// and stencil buffers. `None` means "don't care". Default is `None`. |
| 107 | + /// A value of `Some(0)` indicates that multisampling must not be enabled. |
| 108 | + pub multisampling: Option<u16>, |
| 109 | + |
| 110 | + /// If true, only stereoscopic formats will be considered. If false, only |
| 111 | + /// non-stereoscopic formats. The default is `false`. |
| 112 | + pub stereoscopy: bool, |
| 113 | + |
| 114 | + /// If sRGB-capable formats will be considered. If `None`, don't care. |
| 115 | + /// The default is `None`. |
| 116 | + pub srgb: Option<bool>, |
| 117 | + |
| 118 | + /// The behavior when changing the current context. Default is `Flush`. |
| 119 | + pub release_behavior: ReleaseBehavior, |
| 120 | + |
| 121 | + /// Whether to use vsync. If vsync is enabled, calling `swap_buffers` will |
| 122 | + /// block until the screen refreshes. This is typically used to prevent |
| 123 | + /// screen tearing. |
| 124 | + /// |
| 125 | + /// The default is `None`. |
| 126 | + pub vsync: Option<bool>, |
| 127 | + |
| 128 | + /// FIXME: missing docs |
| 129 | + pub pbuffer_support: bool, |
| 130 | + /// FIXME: missing docs |
| 131 | + pub window_surface_support: bool, |
| 132 | + |
| 133 | + pub plat_attr: platform_impl::SurfacePlatformAttributes, |
| 134 | +} |
| 135 | + |
| 136 | +impl Default for SurfaceConfigBuilder { |
| 137 | + #[inline] |
| 138 | + fn default() -> Self { |
| 139 | + SurfaceConfigBuilder { |
| 140 | + version: GlRequest::Latest, |
| 141 | + hardware_accelerated: Some(true), |
| 142 | + color_bits: Some(24), |
| 143 | + float_color_buffer: false, |
| 144 | + alpha_bits: Some(8), |
| 145 | + depth_bits: Some(24), |
| 146 | + stencil_bits: Some(8), |
| 147 | + double_buffer: None, |
| 148 | + multisampling: None, |
| 149 | + stereoscopy: false, |
| 150 | + srgb: None, |
| 151 | + vsync: None, |
| 152 | + pbuffer_support: false, |
| 153 | + window_surface_support: true, |
| 154 | + release_behavior: ReleaseBehavior::Flush, |
| 155 | + plat_attr: Default::default(), |
| 156 | + } |
| 157 | + } |
| 158 | +} |
| 159 | + |
| 160 | +impl SurfaceConfigBuilder { |
| 161 | + fn new() -> Self { |
| 162 | + Default::default() |
| 163 | + } |
| 164 | + |
| 165 | + /// Sets how the backend should choose the OpenGL API and version. |
| 166 | + #[inline] |
| 167 | + pub fn with_gl(mut self, request: GlRequest) -> Self { |
| 168 | + self.version = request; |
| 169 | + self |
| 170 | + } |
| 171 | + |
| 172 | + /// Sets the multisampling level to request. A value of `0` indicates that |
| 173 | + /// multisampling must not be enabled. |
| 174 | + /// |
| 175 | + /// # Panic |
| 176 | + /// |
| 177 | + /// Will panic if `samples` is not a power of two. |
| 178 | + #[inline] |
| 179 | + pub fn with_multisampling(mut self, samples: u16) -> Self { |
| 180 | + self.multisampling = match samples { |
| 181 | + 0 => None, |
| 182 | + _ => { |
| 183 | + assert!(samples.is_power_of_two()); |
| 184 | + Some(samples) |
| 185 | + } |
| 186 | + }; |
| 187 | + self |
| 188 | + } |
| 189 | + |
| 190 | + /// Sets the number of bits in the depth buffer. |
| 191 | + #[inline] |
| 192 | + pub fn with_depth_buffer(mut self, bits: u8) -> Self { |
| 193 | + self.depth_bits = Some(bits); |
| 194 | + self |
| 195 | + } |
| 196 | + |
| 197 | + /// Sets the number of bits in the stencil buffer. |
| 198 | + #[inline] |
| 199 | + pub fn with_stencil_buffer(mut self, bits: u8) -> Self { |
| 200 | + self.stencil_bits = Some(bits); |
| 201 | + self |
| 202 | + } |
| 203 | + |
| 204 | + /// Sets the number of bits in the color buffer. |
| 205 | + #[inline] |
| 206 | + pub fn with_pixel_format(mut self, color_bits: u8, alpha_bits: u8) -> Self { |
| 207 | + self.color_bits = Some(color_bits); |
| 208 | + self.alpha_bits = Some(alpha_bits); |
| 209 | + self |
| 210 | + } |
| 211 | + |
| 212 | + /// Request the backend to be stereoscopic. |
| 213 | + #[inline] |
| 214 | + pub fn with_stereoscopy(mut self) -> Self { |
| 215 | + self.stereoscopy = true; |
| 216 | + self |
| 217 | + } |
| 218 | + |
| 219 | + /// Sets whether sRGB should be enabled on the window. |
| 220 | + /// |
| 221 | + /// The default value is `None`. |
| 222 | + #[inline] |
| 223 | + pub fn with_srgb(mut self, srgb: Option<bool>) -> Self { |
| 224 | + self.srgb = srgb; |
| 225 | + self |
| 226 | + } |
| 227 | + |
| 228 | + /// Requests that the window has vsync enabled. |
| 229 | + /// |
| 230 | + /// By default, vsync is not enabled. |
| 231 | + #[inline] |
| 232 | + pub fn with_vsync(mut self, vsync: Option<bool>) -> Self { |
| 233 | + self.vsync = vsync; |
| 234 | + self |
| 235 | + } |
| 236 | + |
| 237 | + #[inline] |
| 238 | + pub fn with_pbuffer_support(mut self, pbuffer_support: bool) -> Self { |
| 239 | + self.pbuffer_support = pbuffer_support; |
| 240 | + self |
| 241 | + } |
| 242 | + |
| 243 | + #[inline] |
| 244 | + pub fn with_window_surface_support(mut self, window_surface_support: bool) -> Self { |
| 245 | + self.window_surface_support = window_surface_support; |
| 246 | + self |
| 247 | + } |
| 248 | + |
| 249 | + /// Sets whether double buffering should be enabled. |
| 250 | + /// |
| 251 | + /// The default value is `None`. |
| 252 | + /// |
| 253 | + /// ## Platform-specific |
| 254 | + /// |
| 255 | + /// This option will be taken into account on the following platforms: |
| 256 | + /// |
| 257 | + /// * MacOS |
| 258 | + /// * Unix operating systems using GLX with X |
| 259 | + /// * Windows using WGL |
| 260 | + #[inline] |
| 261 | + pub fn with_double_buffer(mut self, double_buffer: Option<bool>) -> Self { |
| 262 | + self.double_buffer = double_buffer; |
| 263 | + self |
| 264 | + } |
| 265 | + |
| 266 | + /// Sets whether hardware acceleration is required. |
| 267 | + /// |
| 268 | + /// The default value is `Some(true)` |
| 269 | + /// |
| 270 | + /// ## Platform-specific |
| 271 | + /// |
| 272 | + /// This option will be taken into account on the following platforms: |
| 273 | + /// |
| 274 | + /// * MacOS |
| 275 | + /// * Unix operating systems using EGL with either X or Wayland |
| 276 | + /// * Windows using EGL or WGL |
| 277 | + /// * Android using EGL |
| 278 | + #[inline] |
| 279 | + pub fn with_hardware_acceleration( |
| 280 | + mut self, |
| 281 | + acceleration: Option<bool>, |
| 282 | + ) -> Self { |
| 283 | + self.hardware_accelerated = acceleration; |
| 284 | + self |
| 285 | + } |
| 286 | + |
| 287 | + #[inline] |
| 288 | + pub fn build( |
| 289 | + self, |
| 290 | + el: &Display, |
| 291 | + ) -> SurfaceConfig { |
| 292 | + platform_impl::SurfaceConfig::new(el, self) |
| 293 | + .map(|(attribs, config)| SurfaceConfig { attribs, config }) |
| 294 | + } |
| 295 | +} |
0 commit comments