surfman/
context.rs

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