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