1#![allow(unreachable_patterns)]
3
4use std::num::NonZeroU32;
5
6use bitflags::bitflags;
7use raw_window_handle::RawWindowHandle;
8
9use crate::display::{Display, GetGlDisplay};
10use crate::private::{gl_api_dispatch, Sealed};
11
12#[cfg(x11_platform)]
13use crate::platform::x11::{X11GlConfigExt, X11VisualInfo};
14
15#[cfg(cgl_backend)]
16use crate::api::cgl::config::Config as CglConfig;
17#[cfg(egl_backend)]
18use crate::api::egl::config::Config as EglConfig;
19#[cfg(glx_backend)]
20use crate::api::glx::config::Config as GlxConfig;
21#[cfg(wgl_backend)]
22use crate::api::wgl::config::Config as WglConfig;
23
24pub trait GlConfig: Sealed {
26 fn color_buffer_type(&self) -> Option<ColorBufferType>;
30
31 fn float_pixels(&self) -> bool;
33
34 fn alpha_size(&self) -> u8;
36
37 fn depth_size(&self) -> u8;
39
40 fn stencil_size(&self) -> u8;
42
43 fn num_samples(&self) -> u8;
47
48 fn srgb_capable(&self) -> bool;
52
53 fn supports_transparency(&self) -> Option<bool>;
58
59 fn hardware_accelerated(&self) -> bool;
66
67 fn config_surface_types(&self) -> ConfigSurfaceTypes;
69
70 fn api(&self) -> Api;
72}
73
74pub trait GetGlConfig: Sealed {
76 type Target: GlConfig;
78
79 fn config(&self) -> Self::Target;
81}
82
83pub trait AsRawConfig {
85 fn raw_config(&self) -> RawConfig;
87}
88
89#[derive(Debug, Default, Clone)]
91pub struct ConfigTemplateBuilder {
92 template: ConfigTemplate,
93}
94
95impl ConfigTemplateBuilder {
96 #[inline]
98 pub fn new() -> Self {
99 Default::default()
100 }
101
102 #[inline]
106 pub fn with_alpha_size(mut self, alpha_size: u8) -> Self {
107 self.template.alpha_size = alpha_size;
108 self
109 }
110
111 #[inline]
115 pub fn with_float_pixels(mut self, float_pixels: bool) -> Self {
116 self.template.float_pixels = float_pixels;
117 self
118 }
119
120 #[inline]
124 pub fn with_stencil_size(mut self, stencil_size: u8) -> Self {
125 self.template.stencil_size = stencil_size;
126 self
127 }
128
129 #[inline]
133 pub fn with_depth_size(mut self, depth_size: u8) -> Self {
134 self.template.depth_size = depth_size;
135 self
136 }
137
138 #[inline]
143 pub fn with_multisampling(mut self, num_samples: u8) -> Self {
144 debug_assert!(num_samples.is_power_of_two());
145 self.template.num_samples = Some(num_samples);
146 self
147 }
148
149 #[inline]
153 pub fn with_surface_type(mut self, config_surface_types: ConfigSurfaceTypes) -> Self {
154 self.template.config_surface_types = config_surface_types;
155 self
156 }
157
158 #[inline]
162 pub fn with_buffer_type(mut self, color_buffer_type: ColorBufferType) -> Self {
163 self.template.color_buffer_type = color_buffer_type;
164 self
165 }
166
167 #[inline]
179 pub fn with_api(mut self, api: Api) -> Self {
180 self.template.api = Some(api);
181 self
182 }
183
184 #[inline]
188 pub fn with_stereoscopy(mut self, stereoscopy: Option<bool>) -> Self {
189 self.template.stereoscopy = stereoscopy;
190 self
191 }
192
193 #[inline]
197 pub fn with_single_buffering(mut self, single_buffering: bool) -> Self {
198 self.template.single_buffering = single_buffering;
199 self
200 }
201
202 #[inline]
211 pub fn with_transparency(mut self, transparency: bool) -> Self {
212 self.template.transparency = transparency;
213 self
214 }
215
216 #[inline]
218 pub fn with_pbuffer_sizes(mut self, width: NonZeroU32, height: NonZeroU32) -> Self {
219 self.template.max_pbuffer_width = Some(width.into());
220 self.template.max_pbuffer_height = Some(height.into());
221 self
222 }
223
224 pub fn prefer_hardware_accelerated(mut self, hardware_accerelated: Option<bool>) -> Self {
229 self.template.hardware_accelerated = hardware_accerelated;
230 self
231 }
232
233 pub fn compatible_with_native_window(mut self, native_window: RawWindowHandle) -> Self {
244 self.template.native_window = Some(native_window);
245 self
246 }
247
248 #[inline]
256 pub fn with_swap_interval(
257 mut self,
258 min_swap_interval: Option<u16>,
259 max_swap_interval: Option<u16>,
260 ) -> Self {
261 self.template.min_swap_interval = min_swap_interval;
262 self.template.max_swap_interval = max_swap_interval;
263 self
264 }
265
266 #[must_use]
268 pub fn build(self) -> ConfigTemplate {
269 self.template
270 }
271}
272
273#[derive(Debug, Clone)]
275pub struct ConfigTemplate {
276 pub(crate) color_buffer_type: ColorBufferType,
278
279 pub(crate) alpha_size: u8,
281
282 pub(crate) depth_size: u8,
284
285 pub(crate) stencil_size: u8,
287
288 pub(crate) num_samples: Option<u8>,
290
291 pub(crate) min_swap_interval: Option<u16>,
293
294 pub(crate) max_swap_interval: Option<u16>,
296
297 pub(crate) config_surface_types: ConfigSurfaceTypes,
299
300 pub(crate) api: Option<Api>,
302
303 pub(crate) transparency: bool,
305
306 pub(crate) single_buffering: bool,
308
309 pub(crate) stereoscopy: Option<bool>,
311
312 pub(crate) float_pixels: bool,
314
315 pub(crate) max_pbuffer_width: Option<u32>,
317
318 pub(crate) hardware_accelerated: Option<bool>,
320
321 pub(crate) max_pbuffer_height: Option<u32>,
323
324 pub(crate) native_window: Option<RawWindowHandle>,
326}
327
328impl Default for ConfigTemplate {
329 fn default() -> Self {
330 ConfigTemplate {
331 color_buffer_type: ColorBufferType::Rgb { r_size: 8, g_size: 8, b_size: 8 },
332
333 alpha_size: 8,
334
335 depth_size: 24,
336
337 stencil_size: 8,
338
339 num_samples: None,
340
341 transparency: false,
342
343 stereoscopy: None,
344
345 min_swap_interval: None,
346
347 max_swap_interval: None,
348
349 single_buffering: false,
350
351 float_pixels: false,
352
353 config_surface_types: ConfigSurfaceTypes::WINDOW,
354
355 max_pbuffer_width: None,
356 max_pbuffer_height: None,
357
358 native_window: None,
359 hardware_accelerated: None,
360
361 api: None,
362 }
363 }
364}
365
366bitflags! {
367 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
369 pub struct ConfigSurfaceTypes: u8 {
370 const WINDOW = 0b00000001;
372
373 const PIXMAP = 0b00000010;
375
376 const PBUFFER = 0b00000100;
378 }
379}
380
381bitflags! {
382 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
384 pub struct Api : u8 {
385 const OPENGL = 0b00000001;
387
388 const GLES1 = 0b00000010;
390
391 const GLES2 = 0b00000100;
393
394 const GLES3 = 0b00001000;
396 }
397}
398
399#[derive(Debug, Clone, Copy, PartialEq, Eq)]
401pub enum ColorBufferType {
402 Rgb {
404 r_size: u8,
406 g_size: u8,
408 b_size: u8,
410 },
411
412 Luminance(u8),
414}
415
416#[derive(Debug, Clone, PartialEq, Eq)]
431pub enum Config {
432 #[cfg(egl_backend)]
434 Egl(EglConfig),
435
436 #[cfg(glx_backend)]
438 Glx(GlxConfig),
439
440 #[cfg(wgl_backend)]
442 Wgl(WglConfig),
443
444 #[cfg(cgl_backend)]
446 Cgl(CglConfig),
447}
448
449impl GlConfig for Config {
450 fn color_buffer_type(&self) -> Option<ColorBufferType> {
451 gl_api_dispatch!(self; Self(config) => config.color_buffer_type())
452 }
453
454 fn float_pixels(&self) -> bool {
455 gl_api_dispatch!(self; Self(config) => config.float_pixels())
456 }
457
458 fn alpha_size(&self) -> u8 {
459 gl_api_dispatch!(self; Self(config) => config.alpha_size())
460 }
461
462 fn depth_size(&self) -> u8 {
463 gl_api_dispatch!(self; Self(config) => config.depth_size())
464 }
465
466 fn stencil_size(&self) -> u8 {
467 gl_api_dispatch!(self; Self(config) => config.stencil_size())
468 }
469
470 fn num_samples(&self) -> u8 {
471 gl_api_dispatch!(self; Self(config) => config.num_samples())
472 }
473
474 fn srgb_capable(&self) -> bool {
475 gl_api_dispatch!(self; Self(config) => config.srgb_capable())
476 }
477
478 fn config_surface_types(&self) -> ConfigSurfaceTypes {
479 gl_api_dispatch!(self; Self(config) => config.config_surface_types())
480 }
481
482 fn hardware_accelerated(&self) -> bool {
483 gl_api_dispatch!(self; Self(config) => config.hardware_accelerated())
484 }
485
486 fn supports_transparency(&self) -> Option<bool> {
487 gl_api_dispatch!(self; Self(config) => config.supports_transparency())
488 }
489
490 fn api(&self) -> Api {
491 gl_api_dispatch!(self; Self(config) => config.api())
492 }
493}
494
495impl GetGlDisplay for Config {
496 type Target = Display;
497
498 fn display(&self) -> Self::Target {
499 gl_api_dispatch!(self; Self(config) => config.display(); as Display)
500 }
501}
502
503#[cfg(x11_platform)]
504impl X11GlConfigExt for Config {
505 fn x11_visual(&self) -> Option<X11VisualInfo> {
506 gl_api_dispatch!(self; Self(config) => config.x11_visual())
507 }
508}
509
510impl Sealed for Config {}
511
512#[derive(Debug, Clone, Copy, PartialEq, Eq)]
514pub enum RawConfig {
515 #[cfg(egl_backend)]
517 Egl(*const std::ffi::c_void),
518
519 #[cfg(glx_backend)]
521 Glx(*const std::ffi::c_void),
522
523 #[cfg(wgl_backend)]
525 Wgl(i32),
526
527 #[cfg(cgl_backend)]
529 Cgl(*const std::ffi::c_void),
530}
531
532impl AsRawConfig for Config {
533 fn raw_config(&self) -> RawConfig {
534 gl_api_dispatch!(self; Self(config) => config.raw_config())
535 }
536}