Skip to main content

surfman/
context.rs

1//! Declarations common to all platform contexts.
2
3#![allow(unused_imports)]
4
5use crate::gl;
6use crate::info::GLVersion;
7use crate::Gl;
8
9use std::ffi::CStr;
10use std::os::raw::c_char;
11use std::sync::Mutex;
12
13/// A unique ID among all currently-allocated contexts.
14///
15/// If you destroy a context, subsequently-allocated contexts might reuse the same ID.
16#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
17pub struct ContextID(pub u64);
18
19#[doc(hidden)]
20pub static CREATE_CONTEXT_MUTEX: Mutex<ContextID> = Mutex::new(ContextID(0));
21
22bitflags! {
23    /// Various flags that control attributes of the context and/or surfaces created from that
24    /// context.
25    ///
26    /// These roughly correspond to:
27    /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#WEBGLCONTEXTATTRIBUTES
28    ///
29    /// There are some extra `surfman`-specific flags as well.
30    #[derive(Debug, Copy, Clone, PartialEq, Eq)]
31    pub struct ContextAttributeFlags: u8 {
32        /// Surfaces created for this context will have an alpha channel (RGBA or BGRA; i.e. 4
33        /// channels, 32 bits per pixel, 8 bits per channel). If this is not present, surfaces will
34        /// be RGBX or BGRX (i.e. 3 channels, 32 bits per pixel, 8 bits per channel).
35        const ALPHA                 = 0x01;
36        /// Surfaces created for this context will have a 24-bit depth buffer.
37        const DEPTH                 = 0x02;
38        /// Surfaces created for this context will have an 8-bit stencil buffer, possibly using
39        /// packed depth/stencil if the GL implementation supports it.
40        const STENCIL               = 0x04;
41        /// The OpenGL compatibility profile will be used. If this is not present, the core profile
42        /// is used.
43        const COMPATIBILITY_PROFILE = 0x08;
44    }
45}
46
47/// Attributes that control aspects of a context and/or surfaces created from that context.
48///
49/// Similar to: <https://www.khronos.org/registry/webgl/specs/latest/1.0/#WEBGLCONTEXTATTRIBUTES>
50#[derive(Clone, Copy, PartialEq, Debug)]
51pub struct ContextAttributes {
52    /// The OpenGL or OpenGL ES version that this context supports.
53    ///
54    /// Keep in mind that OpenGL and OpenGL ES have different version numbering schemes. Before
55    /// filling in this field, check the result of `Device::gl_api()`.
56    pub version: GLVersion,
57    /// Various flags.
58    pub flags: ContextAttributeFlags,
59}
60
61impl ContextAttributes {
62    #[allow(dead_code)]
63    pub(crate) fn zeroed() -> ContextAttributes {
64        ContextAttributes {
65            version: GLVersion::new(0, 0),
66            flags: ContextAttributeFlags::empty(),
67        }
68    }
69}
70
71#[cfg(any(target_os = "android", target_env = "ohos"))]
72pub(crate) fn current_context_uses_compatibility_profile(_gl: &Gl) -> bool {
73    false
74}
75
76#[cfg(not(any(target_os = "android", target_env = "ohos")))]
77#[allow(dead_code)]
78pub(crate) fn current_context_uses_compatibility_profile(gl: &Gl) -> bool {
79    use glow::HasContext;
80
81    unsafe {
82        // First, try `GL_CONTEXT_PROFILE_MASK`.
83        let context_profile_mask = gl.get_parameter_i32(gl::CONTEXT_PROFILE_MASK);
84        if gl.get_error() == gl::NO_ERROR
85            && (context_profile_mask & gl::CONTEXT_COMPATIBILITY_PROFILE_BIT as i32) != 0
86        {
87            return true;
88        }
89
90        // Second, look for the `GL_ARB_compatibility` extension.
91        gl.supported_extensions().contains("GL_ARB_compatibility")
92    }
93}