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}