1use std::ffi::c_void;
2use std::marker::PhantomData;
3use std::panic::AssertUnwindSafe;
4#[cfg(not(target_os = "linux"))]
6use raw_window_handle::RawWindowHandle;
7
8#[cfg(target_os = "windows")]
9mod win;
10#[cfg(target_os = "windows")]
11use win as platform;
12
13#[cfg(target_os = "linux")]
15pub(crate) mod x11;
16#[cfg(target_os = "linux")]
17pub(crate) use self::x11 as platform;
18
19#[cfg(target_os = "macos")]
20mod macos;
21#[cfg(target_os = "macos")]
22use macos as platform;
23
24#[derive(Clone, Debug, PartialEq)]
25pub struct GlConfig {
26 pub version: (u8, u8),
27 pub profile: Profile,
28 pub red_bits: u8,
29 pub blue_bits: u8,
30 pub green_bits: u8,
31 pub alpha_bits: u8,
32 pub depth_bits: u8,
33 pub stencil_bits: u8,
34 pub samples: Option<u8>,
35 pub srgb: bool,
36 pub double_buffer: bool,
37 pub vsync: bool,
38}
39
40impl Default for GlConfig {
41 fn default() -> Self {
42 GlConfig {
43 version: (3, 2),
44 profile: Profile::Core,
45 red_bits: 8,
46 blue_bits: 8,
47 green_bits: 8,
48 alpha_bits: 8,
49 depth_bits: 24,
50 stencil_bits: 8,
51 samples: None,
52 srgb: true,
53 double_buffer: true,
54 vsync: false,
55 }
56 }
57}
58
59#[derive(Clone, Copy, Debug, PartialEq, Eq)]
60pub enum Profile {
61 Compatibility,
62 Core,
63}
64
65#[derive(Debug)]
66pub enum GlError {
67 InvalidWindowHandle,
68 VersionNotSupported,
69 CreationFailed(platform::CreationFailedError),
70}
71
72pub struct GlContext {
73 context: AssertUnwindSafe<platform::GlContext>,
76 phantom: PhantomData<*mut ()>,
77}
78
79impl GlContext {
80 #[cfg(not(target_os = "linux"))]
81 pub(crate) unsafe fn create(
82 parent: &RawWindowHandle, config: GlConfig,
83 ) -> Result<GlContext, GlError> {
84 platform::GlContext::create(parent, config)
85 .map(|context| GlContext { context: AssertUnwindSafe(context), phantom: PhantomData })
86 }
87
88 #[cfg(target_os = "linux")]
92 pub(crate) fn new(context: platform::GlContext) -> GlContext {
93 GlContext { context: AssertUnwindSafe(context), phantom: PhantomData }
94 }
95
96 pub unsafe fn make_current(&self) {
97 self.context.make_current();
98 }
99
100 pub unsafe fn make_not_current(&self) {
101 self.context.make_not_current();
102 }
103
104 pub fn get_proc_address(&self, symbol: &str) -> *const c_void {
105 self.context.get_proc_address(symbol)
106 }
107
108 pub fn swap_buffers(&self) {
109 self.context.swap_buffers();
110 }
111
112 #[cfg(target_os = "macos")]
114 pub(crate) fn resize(&self, size: objc2_foundation::NSSize) {
115 self.context.resize(size);
116 }
117
118 #[cfg(target_os = "macos")]
123 pub(crate) fn ns_view(&self) -> &objc2_app_kit::NSView {
124 self.context.ns_view()
125 }
126}