diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ba6502f..39d6ce7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -51,6 +51,10 @@ jobs: - run: cargo build --verbose --target wasm32-unknown-unknown env: RUSTFLAGS: --cfg=web_sys_unstable_apis + - run: cargo build --verbose --no-default-features --features hashbrown + - run: cargo build --verbose --target wasm32-unknown-unknown --no-default-features --features hashbrown + env: + RUSTFLAGS: --cfg=web_sys_unstable_apis - run: cargo test --verbose - run: (cd examples/hello && cargo build --features glutin_winit) - run: (cd examples/hello && cargo build --target wasm32-unknown-unknown) diff --git a/Cargo.toml b/Cargo.toml index 16b7c89..0747eb8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,11 +27,15 @@ name = "glow" path = "src/lib.rs" [dependencies] -log = { version = "0.4.16", optional = true } +hashbrown = { version = "0.15.2", optional = true } +log = { version = "0.4.16", optional = true, default-features = false } [features] +default = ["std"] +std = ["log/std"] debug_trace_calls = [] debug_automatic_glGetError = [] +hashbrown = ["dep:hashbrown"] [target.'cfg(target_arch = "wasm32")'.dependencies] js-sys = "~0.3" diff --git a/README.md b/README.md index 43bea2a..45dcc04 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,31 @@ cargo build cargo build --target wasm32-unknown-unknown ``` +## `no_std` support + +`no_std` support can be enabled by compiling with `--no-default-features` to +disable `std` support and `--features hashbrown` for `Hash` collections that are only +defined in `std` for internal usages in crate. For example: + +```toml +[dependencies] +glow = { version = "0.16", default-features = false, features = ["hashbrown"] } +``` + +To support both `std` and `no_std` builds in project, you can use the following +in your `Cargo.toml`: + +```toml +[features] +default = ["std"] + +std = ["glow/std"] +hashbrown = ["glow/hashbrown"] + +[dependencies] +glow = { version = "0.16", default-features = false, features = ["hashbrown"] } +``` + ## License This project is licensed under any one of [Apache License, Version diff --git a/examples/hello/src/main.rs b/examples/hello/src/main.rs index 4ce99b3..8aa343c 100644 --- a/examples/hello/src/main.rs +++ b/examples/hello/src/main.rs @@ -1,6 +1,8 @@ +#[cfg(any(target_arch = "wasm32", feature = "glutin_winit", feature = "sdl2"))] use glow::*; fn main() { + #[cfg(any(target_arch = "wasm32", feature = "glutin_winit", feature = "sdl2"))] unsafe { // Create a context from a WebGL2 context on wasm32 targets #[cfg(target_arch = "wasm32")] @@ -27,6 +29,8 @@ fn main() { // Create a context from a glutin window on non-wasm32 targets #[cfg(feature = "glutin_winit")] let (gl, gl_surface, gl_context, shader_version, _window, event_loop) = { + use std::num::NonZeroU32; + use glutin::{ config::{ConfigTemplateBuilder, GlConfig}, context::{ContextApi, ContextAttributesBuilder, NotCurrentGlContext}, @@ -35,7 +39,6 @@ fn main() { }; use glutin_winit::{DisplayBuilder, GlWindow}; use raw_window_handle::HasRawWindowHandle; - use std::num::NonZeroU32; let event_loop = winit::event_loop::EventLoopBuilder::new().build().unwrap(); let window_builder = winit::window::WindowBuilder::new() diff --git a/src/lib.rs b/src/lib.rs index ec6d1e5..767e558 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,12 +1,30 @@ +#![warn( + clippy::alloc_instead_of_core, + clippy::std_instead_of_alloc, + clippy::std_instead_of_core +)] #![allow(non_upper_case_globals)] #![allow(clippy::too_many_arguments)] #![allow(clippy::trivially_copy_pass_by_ref)] #![allow(clippy::unreadable_literal)] #![allow(clippy::missing_safety_doc)] #![allow(clippy::pedantic)] // For anyone using pedantic and a source dep, this is needed +#![cfg_attr(not(feature = "std"), no_std)] +#[macro_use] +extern crate alloc; -use core::fmt::Debug; -use core::hash::Hash; +#[cfg(all(feature = "std", feature = "hashbrown"))] +compile_error!("\"hashbrown\" feature should not be enabled in \"std\" environment."); + +#[cfg(all(not(feature = "std"), not(feature = "hashbrown")))] +compile_error!("\"hashbrown\" feature should be enabled in \"no_std\" environment."); + +use alloc::{boxed::Box, string::String, vec::Vec}; +use core::{fmt::Debug, hash::Hash}; + +#[cfg(not(feature = "std"))] +use hashbrown::HashSet; +#[cfg(feature = "std")] use std::collections::HashSet; mod version; @@ -153,8 +171,12 @@ pub trait HasContext: __private::Sealed { type TransformFeedback: Copy + Clone + Debug + Eq + Hash + Ord + PartialEq + PartialOrd; type UniformLocation: Clone + Debug; + #[cfg(feature = "std")] fn supported_extensions(&self) -> &HashSet; + #[cfg(not(feature = "std"))] + fn supports_extension(&self, extension: &str) -> bool; + fn supports_debug(&self) -> bool; fn version(&self) -> &Version; diff --git a/src/native.rs b/src/native.rs index 1ac05a1..470719d 100644 --- a/src/native.rs +++ b/src/native.rs @@ -1,8 +1,13 @@ +use alloc::{ + borrow::ToOwned, + ffi::CString, + string::{String, ToString}, + vec::Vec, +}; +use core::{ffi::CStr, num::NonZeroU32, ptr}; + use super::*; use crate::{gl46 as native_gl, version::Version}; -use std::ffi::CStr; -use std::ptr; -use std::{collections::HashSet, ffi::CString, num::NonZeroU32}; #[derive(Default)] struct Constants { @@ -16,7 +21,7 @@ struct Constants { /// guarantee that it's not undefined behavior to keep a `Box` here while it's used as a raw /// pointer in the C API. struct DebugCallbackRawPtr { - callback: *mut std::os::raw::c_void, + callback: *mut core::ffi::c_void, } unsafe impl Send for DebugCallbackRawPtr {} @@ -44,13 +49,12 @@ pub struct Context { impl Context { pub unsafe fn from_loader_function_cstr(mut loader_function: F) -> Self where - F: FnMut(&CStr) -> *const std::os::raw::c_void, + F: FnMut(&CStr) -> *const core::ffi::c_void, { - let raw: native_gl::GlFns = - native_gl::GlFns::load_with(|p: *const std::os::raw::c_char| { - let c_str = std::ffi::CStr::from_ptr(p); - loader_function(c_str) as *mut std::os::raw::c_void - }); + let raw: native_gl::GlFns = native_gl::GlFns::load_with(|p: *const core::ffi::c_char| { + let c_str = core::ffi::CStr::from_ptr(p); + loader_function(c_str) as *mut core::ffi::c_void + }); // Retrieve and parse `GL_VERSION` let raw_string = raw.GetString(VERSION); @@ -59,7 +63,7 @@ impl Context { panic!("Reading GL_VERSION failed. Make sure there is a valid GL context currently active.") } - let raw_version = std::ffi::CStr::from_ptr(raw_string as *const native_gl::GLchar) + let raw_version = core::ffi::CStr::from_ptr(raw_string as *const native_gl::GLchar) .to_str() .unwrap() .to_owned(); @@ -106,7 +110,7 @@ impl Context { pub unsafe fn from_loader_function(mut loader_function: F) -> Self where - F: FnMut(&str) -> *const std::os::raw::c_void, + F: FnMut(&str) -> *const core::ffi::c_void, { Self::from_loader_function_cstr(move |name| loader_function(name.to_str().unwrap())) } @@ -139,8 +143,8 @@ impl Context { } } -impl std::fmt::Debug for Context { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { +impl core::fmt::Debug for Context { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { write!(f, "Native_GL_Context") } } @@ -201,10 +205,16 @@ impl HasContext for Context { type UniformLocation = NativeUniformLocation; type TransformFeedback = NativeTransformFeedback; + #[cfg(feature = "std")] fn supported_extensions(&self) -> &HashSet { &self.extensions } + #[cfg(not(feature = "std"))] + fn supports_extension(&self, extension: &str) -> bool { + self.extensions.contains(extension) + } + fn supports_debug(&self) -> bool { if self.extensions.contains("GL_KHR_debug") { // Supports extension (either GL or GL ES) @@ -356,7 +366,7 @@ impl HasContext for Context { gl.GetShaderiv(shader.0.get(), INFO_LOG_LENGTH, &mut length); if length > 0 { let mut log = String::with_capacity(length as usize); - log.extend(std::iter::repeat('\0').take(length as usize)); + log.extend(core::iter::repeat('\0').take(length as usize)); gl.GetShaderInfoLog( shader.0.get(), length, @@ -415,8 +425,8 @@ impl HasContext for Context { format, ty, match pixels { - PixelPackData::BufferOffset(offset) => offset as *mut std::ffi::c_void, - PixelPackData::Slice(Some(data)) => data.as_mut_ptr() as *mut std::ffi::c_void, + PixelPackData::BufferOffset(offset) => offset as *mut core::ffi::c_void, + PixelPackData::Slice(Some(data)) => data.as_mut_ptr() as *mut core::ffi::c_void, PixelPackData::Slice(None) => ptr::null_mut(), }, ); @@ -493,7 +503,7 @@ impl HasContext for Context { gl.GetProgramiv(program.0.get(), INFO_LOG_LENGTH, &mut length); if length > 0 { let mut log = String::with_capacity(length as usize); - log.extend(std::iter::repeat('\0').take(length as usize)); + log.extend(core::iter::repeat('\0').take(length as usize)); gl.GetProgramInfoLog( program.0.get(), length, @@ -1148,7 +1158,7 @@ impl HasContext for Context { ); let mut name = String::with_capacity(uniform_max_size as usize); - name.extend(std::iter::repeat('\0').take(uniform_max_size as usize)); + name.extend(core::iter::repeat('\0').take(uniform_max_size as usize)); let mut length = 0; let mut size = 0; let mut utype = 0; @@ -1423,12 +1433,12 @@ impl HasContext for Context { unsafe fn buffer_data_size(&self, target: u32, size: i32, usage: u32) { let gl = &self.raw; - gl.BufferData(target, size as isize, std::ptr::null(), usage); + gl.BufferData(target, size as isize, core::ptr::null(), usage); } unsafe fn named_buffer_data_size(&self, buffer: Self::Buffer, size: i32, usage: u32) { let gl = &self.raw; - gl.NamedBufferData(buffer.0.get(), size as isize, std::ptr::null(), usage); + gl.NamedBufferData(buffer.0.get(), size as isize, core::ptr::null(), usage); } unsafe fn buffer_data_u8_slice(&self, target: u32, data: &[u8], usage: u32) { @@ -1436,7 +1446,7 @@ impl HasContext for Context { gl.BufferData( target, data.len() as isize, - data.as_ptr() as *const std::ffi::c_void, + data.as_ptr() as *const core::ffi::c_void, usage, ); } @@ -1446,7 +1456,7 @@ impl HasContext for Context { gl.NamedBufferData( buffer.0.get(), data.len() as isize, - data.as_ptr() as *const std::ffi::c_void, + data.as_ptr() as *const core::ffi::c_void, usage, ); } @@ -1457,7 +1467,7 @@ impl HasContext for Context { target, offset as isize, src_data.len() as isize, - src_data.as_ptr() as *const std::ffi::c_void, + src_data.as_ptr() as *const core::ffi::c_void, ); } @@ -1472,7 +1482,7 @@ impl HasContext for Context { buffer.0.get(), offset as isize, src_data.len() as isize, - src_data.as_ptr() as *const std::ffi::c_void, + src_data.as_ptr() as *const core::ffi::c_void, ); } @@ -1482,14 +1492,15 @@ impl HasContext for Context { target, offset as isize, dst_data.len() as isize, - dst_data.as_mut_ptr() as *mut std::ffi::c_void, + dst_data.as_mut_ptr() as *mut core::ffi::c_void, ); } unsafe fn buffer_storage(&self, target: u32, size: i32, data: Option<&[u8]>, flags: u32) { let gl = &self.raw; let size = size as isize; - let data = data.map(|p| p.as_ptr()).unwrap_or(std::ptr::null()) as *const std::ffi::c_void; + let data = + data.map(|p| p.as_ptr()).unwrap_or(core::ptr::null()) as *const core::ffi::c_void; if gl.BufferStorage_is_loaded() { gl.BufferStorage(target, size, data, flags); } else { @@ -1818,7 +1829,7 @@ impl HasContext for Context { unsafe fn draw_arrays_indirect_offset(&self, mode: u32, offset: i32) { let gl = &self.raw; - gl.DrawArraysIndirect(mode, offset as *const std::ffi::c_void); + gl.DrawArraysIndirect(mode, offset as *const core::ffi::c_void); } unsafe fn draw_buffer(&self, draw_buffer: u32) { @@ -1859,7 +1870,7 @@ impl HasContext for Context { mode as u32, count, element_type as u32, - offset as *const std::ffi::c_void, + offset as *const core::ffi::c_void, ); } @@ -1876,7 +1887,7 @@ impl HasContext for Context { mode as u32, count, element_type as u32, - offset as *const std::ffi::c_void, + offset as *const core::ffi::c_void, base_vertex, ); } @@ -1894,7 +1905,7 @@ impl HasContext for Context { mode as u32, count, element_type as u32, - offset as *const std::ffi::c_void, + offset as *const core::ffi::c_void, instance_count, ); } @@ -1913,7 +1924,7 @@ impl HasContext for Context { mode as u32, count, element_type as u32, - offset as *const std::ffi::c_void, + offset as *const core::ffi::c_void, instance_count, base_vertex, ); @@ -1934,7 +1945,7 @@ impl HasContext for Context { mode as u32, count, element_type as u32, - offset as *const std::ffi::c_void, + offset as *const core::ffi::c_void, instance_count, base_vertex, base_instance, @@ -1943,7 +1954,7 @@ impl HasContext for Context { unsafe fn draw_elements_indirect_offset(&self, mode: u32, element_type: u32, offset: i32) { let gl = &self.raw; - gl.DrawElementsIndirect(mode, element_type, offset as *const std::ffi::c_void); + gl.DrawElementsIndirect(mode, element_type, offset as *const core::ffi::c_void); } unsafe fn enable(&self, parameter: u32) { @@ -2212,7 +2223,7 @@ impl HasContext for Context { unsafe fn get_parameter_indexed_string(&self, parameter: u32, index: u32) -> String { let gl = &self.raw; let raw_ptr = gl.GetStringi(parameter, index); - std::ffi::CStr::from_ptr(raw_ptr as *const native_gl::GLchar) + core::ffi::CStr::from_ptr(raw_ptr as *const native_gl::GLchar) .to_str() .unwrap() .to_owned() @@ -2227,7 +2238,7 @@ impl HasContext for Context { parameter ) } - std::ffi::CStr::from_ptr(raw_ptr as *const native_gl::GLchar) + core::ffi::CStr::from_ptr(raw_ptr as *const native_gl::GLchar) .to_str() .unwrap() .to_owned() @@ -2386,7 +2397,7 @@ impl HasContext for Context { &mut attribute_max_size, ); let mut name = String::with_capacity(attribute_max_size as usize); - name.extend(std::iter::repeat('\0').take(attribute_max_size as usize)); + name.extend(core::iter::repeat('\0').take(attribute_max_size as usize)); let mut length = 0; let mut size = 0; let mut atype = 0; @@ -2507,8 +2518,8 @@ impl HasContext for Context { format, ty, match pixels { - PixelUnpackData::BufferOffset(offset) => offset as *const std::ffi::c_void, - PixelUnpackData::Slice(Some(data)) => data.as_ptr() as *const std::ffi::c_void, + PixelUnpackData::BufferOffset(offset) => offset as *const core::ffi::c_void, + PixelUnpackData::Slice(Some(data)) => data.as_ptr() as *const core::ffi::c_void, PixelUnpackData::Slice(None) => ptr::null(), }, ); @@ -2532,7 +2543,7 @@ impl HasContext for Context { width, border, image_size, - pixels.as_ptr() as *const std::ffi::c_void, + pixels.as_ptr() as *const core::ffi::c_void, ); } @@ -2559,8 +2570,8 @@ impl HasContext for Context { format, ty, match pixels { - PixelUnpackData::BufferOffset(offset) => offset as *const std::ffi::c_void, - PixelUnpackData::Slice(Some(data)) => data.as_ptr() as *const std::ffi::c_void, + PixelUnpackData::BufferOffset(offset) => offset as *const core::ffi::c_void, + PixelUnpackData::Slice(Some(data)) => data.as_ptr() as *const core::ffi::c_void, PixelUnpackData::Slice(None) => ptr::null(), }, ); @@ -2606,7 +2617,7 @@ impl HasContext for Context { height, border, image_size, - pixels.as_ptr() as *const std::ffi::c_void, + pixels.as_ptr() as *const core::ffi::c_void, ); } @@ -2635,8 +2646,8 @@ impl HasContext for Context { format, ty, match pixels { - PixelUnpackData::BufferOffset(offset) => offset as *const std::ffi::c_void, - PixelUnpackData::Slice(Some(data)) => data.as_ptr() as *const std::ffi::c_void, + PixelUnpackData::BufferOffset(offset) => offset as *const core::ffi::c_void, + PixelUnpackData::Slice(Some(data)) => data.as_ptr() as *const core::ffi::c_void, PixelUnpackData::Slice(None) => ptr::null(), }, ); @@ -2664,7 +2675,7 @@ impl HasContext for Context { depth, border, image_size, - pixels.as_ptr() as *const std::ffi::c_void, + pixels.as_ptr() as *const core::ffi::c_void, ); } @@ -3317,8 +3328,8 @@ impl HasContext for Context { format, ty, match pixels { - PixelUnpackData::BufferOffset(offset) => offset as *const std::ffi::c_void, - PixelUnpackData::Slice(Some(data)) => data.as_ptr() as *const std::ffi::c_void, + PixelUnpackData::BufferOffset(offset) => offset as *const core::ffi::c_void, + PixelUnpackData::Slice(Some(data)) => data.as_ptr() as *const core::ffi::c_void, PixelUnpackData::Slice(None) => ptr::null(), }, ); @@ -3347,8 +3358,8 @@ impl HasContext for Context { format, ty, match pixels { - PixelUnpackData::BufferOffset(offset) => offset as *const std::ffi::c_void, - PixelUnpackData::Slice(Some(data)) => data.as_ptr() as *const std::ffi::c_void, + PixelUnpackData::BufferOffset(offset) => offset as *const core::ffi::c_void, + PixelUnpackData::Slice(Some(data)) => data.as_ptr() as *const core::ffi::c_void, PixelUnpackData::Slice(None) => ptr::null(), }, ); @@ -3368,11 +3379,11 @@ impl HasContext for Context { let gl = &self.raw; let (data, image_size) = match pixels { CompressedPixelUnpackData::BufferRange(ref range) => ( - range.start as *const std::ffi::c_void, + range.start as *const core::ffi::c_void, (range.end - range.start) as i32, ), CompressedPixelUnpackData::Slice(data) => { - (data.as_ptr() as *const std::ffi::c_void, data.len() as i32) + (data.as_ptr() as *const core::ffi::c_void, data.len() as i32) } }; @@ -3408,8 +3419,8 @@ impl HasContext for Context { format, ty, match pixels { - PixelUnpackData::BufferOffset(offset) => offset as *const std::ffi::c_void, - PixelUnpackData::Slice(Some(data)) => data.as_ptr() as *const std::ffi::c_void, + PixelUnpackData::BufferOffset(offset) => offset as *const core::ffi::c_void, + PixelUnpackData::Slice(Some(data)) => data.as_ptr() as *const core::ffi::c_void, PixelUnpackData::Slice(None) => ptr::null(), }, ); @@ -3442,8 +3453,8 @@ impl HasContext for Context { format, ty, match pixels { - PixelUnpackData::BufferOffset(offset) => offset as *const std::ffi::c_void, - PixelUnpackData::Slice(Some(data)) => data.as_ptr() as *const std::ffi::c_void, + PixelUnpackData::BufferOffset(offset) => offset as *const core::ffi::c_void, + PixelUnpackData::Slice(Some(data)) => data.as_ptr() as *const core::ffi::c_void, PixelUnpackData::Slice(None) => ptr::null(), }, ); @@ -3465,11 +3476,11 @@ impl HasContext for Context { let gl = &self.raw; let (data, image_size) = match pixels { CompressedPixelUnpackData::BufferRange(ref range) => ( - range.start as *const std::ffi::c_void, + range.start as *const core::ffi::c_void, (range.end - range.start) as i32, ), CompressedPixelUnpackData::Slice(data) => { - (data.as_ptr() as *const std::ffi::c_void, data.len() as i32) + (data.as_ptr() as *const core::ffi::c_void, data.len() as i32) } }; @@ -3629,7 +3640,7 @@ impl HasContext for Context { data_type, normalized as u8, stride, - offset as *const std::ffi::c_void, + offset as *const core::ffi::c_void, ); } @@ -3647,7 +3658,7 @@ impl HasContext for Context { size, data_type, stride, - offset as *const std::ffi::c_void, + offset as *const core::ffi::c_void, ); } @@ -3665,7 +3676,7 @@ impl HasContext for Context { size, data_type, stride, - offset as *const std::ffi::c_void, + offset as *const core::ffi::c_void, ); } @@ -3888,7 +3899,7 @@ impl HasContext for Context { let gl = &self.raw; let ids_ptr = if ids.is_empty() { - std::ptr::null() + core::ptr::null() } else { ids.as_ptr() }; @@ -3937,7 +3948,7 @@ impl HasContext for Context { None => { let trait_object: DebugCallback = Box::new(callback); let thin_ptr = Box::new(trait_object); - let raw_ptr = Box::into_raw(thin_ptr) as *mut _ as *mut std::ffi::c_void; + let raw_ptr = Box::into_raw(thin_ptr) as *mut _ as *mut core::ffi::c_void; let gl = &self.raw; @@ -3986,7 +3997,7 @@ impl HasContext for Context { let mut offset = 0; for i in 0..received { let message = - std::ffi::CStr::from_ptr(message_log[offset..].as_ptr()).to_string_lossy(); + core::ffi::CStr::from_ptr(message_log[offset..].as_ptr()).to_string_lossy(); offset += lengths[i] as usize; entries.push(DebugMessageLogEntry { source: sources[i], @@ -4032,7 +4043,7 @@ impl HasContext for Context { lbl.as_ptr() as *const native_gl::GLchar, ); } - None => gl.ObjectLabel(identifier, name, 0, std::ptr::null()), + None => gl.ObjectLabel(identifier, name, 0, core::ptr::null()), } } @@ -4048,7 +4059,7 @@ impl HasContext for Context { label_buf.as_mut_ptr(), ); label_buf.set_len(len as usize); - std::ffi::CStr::from_ptr(label_buf.as_ptr()) + core::ffi::CStr::from_ptr(label_buf.as_ptr()) .to_str() .unwrap() .to_owned() @@ -4065,12 +4076,12 @@ impl HasContext for Context { let lbl = l.as_ref().as_bytes(); let length = lbl.len() as i32; gl.ObjectPtrLabel( - sync.0 as *mut std::ffi::c_void, + sync.0 as *mut core::ffi::c_void, length, lbl.as_ptr() as *const native_gl::GLchar, ); } - None => gl.ObjectPtrLabel(sync.0 as *mut std::ffi::c_void, 0, std::ptr::null()), + None => gl.ObjectPtrLabel(sync.0 as *mut core::ffi::c_void, 0, core::ptr::null()), } } @@ -4079,13 +4090,13 @@ impl HasContext for Context { let mut len = 0; let mut label_buf = Vec::with_capacity(self.constants.max_label_length as usize); gl.GetObjectPtrLabel( - sync.0 as *mut std::ffi::c_void, + sync.0 as *mut core::ffi::c_void, self.constants.max_label_length, &mut len, label_buf.as_mut_ptr(), ); label_buf.set_len(len as usize); - std::ffi::CStr::from_ptr(label_buf.as_ptr()) + core::ffi::CStr::from_ptr(label_buf.as_ptr()) .to_str() .unwrap() .to_owned() @@ -4198,8 +4209,8 @@ impl HasContext for Context { format, gltype, match pixels { - PixelPackData::BufferOffset(offset) => offset as *mut std::ffi::c_void, - PixelPackData::Slice(Some(data)) => data.as_mut_ptr() as *mut std::ffi::c_void, + PixelPackData::BufferOffset(offset) => offset as *mut core::ffi::c_void, + PixelPackData::Slice(Some(data)) => data.as_mut_ptr() as *mut core::ffi::c_void, PixelPackData::Slice(None) => ptr::null_mut(), }, ); @@ -4346,7 +4357,7 @@ impl HasContext for Context { program.0.get(), index, name_bytes.len() as i32, - std::ptr::null_mut(), + core::ptr::null_mut(), &mut size, &mut tftype, name_bytes.as_mut_ptr(), @@ -4451,18 +4462,18 @@ impl HasContext for Context { if length > 0 { assert_eq!( - std::mem::size_of::(), - std::mem::size_of::(), + core::mem::size_of::(), + core::mem::size_of::(), "This operation is only safe in systems in which the length of \ a GLchar is the same as that of an u8" ); assert_eq!( - std::mem::align_of::(), - std::mem::align_of::(), + core::mem::align_of::(), + core::mem::align_of::(), "This operation is only safe in systems in which the alignment \ of a GLchar is the same as that of an u8" ); - let buffer = std::slice::from_raw_parts( + let buffer = core::slice::from_raw_parts( buffer.as_ptr() as *const u8, (length as usize + 1).min(buffer.len()), ); @@ -4524,9 +4535,9 @@ impl Drop for Context { unsafe { let gl = &self.raw; if gl.DebugMessageCallback_is_loaded() { - gl.DebugMessageCallback(None, std::ptr::null()); + gl.DebugMessageCallback(None, core::ptr::null()); } else { - gl.DebugMessageCallbackKHR(None, std::ptr::null()); + gl.DebugMessageCallbackKHR(None, core::ptr::null()); } } } @@ -4542,16 +4553,47 @@ extern "system" fn raw_debug_message_callback( severity: u32, length: i32, message: *const native_gl::GLchar, - user_param: *mut std::ffi::c_void, + user_param: *mut core::ffi::c_void, ) { - let _result = std::panic::catch_unwind(move || unsafe { + catch_unwind(move || unsafe { let callback: &DebugCallback = &*(user_param as *const DebugCallback); - let slice = std::slice::from_raw_parts(message as *const u8, length as usize); + let slice = core::slice::from_raw_parts(message as *const u8, length as usize); let msg = String::from_utf8_lossy(slice); (callback)(source, gltype, id, severity, &msg); }); } +#[cfg(feature = "std")] +fn catch_unwind(f: F) { + extern crate std; + std::panic::catch_unwind(f).ok(); +} + +#[cfg(not(feature = "std"))] +fn catch_unwind(f: F) { + // No real option here, just abort by panicking while panicking. + struct PanicOnDrop; + + impl Drop for PanicOnDrop { + fn drop(&mut self) { + panic!("Panic while panicking"); + } + } + + struct AbortOnDrop; + + impl Drop for AbortOnDrop { + fn drop(&mut self) { + let _bomb = PanicOnDrop; + panic!("Panic while panicking"); + } + } + + let _bomb = AbortOnDrop; + f(); + core::mem::forget(_bomb); +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/version.rs b/src/version.rs index b96961b..ec40e29 100644 --- a/src/version.rs +++ b/src/version.rs @@ -1,3 +1,5 @@ +use alloc::string::{String, ToString}; + /// A version number for a specific component of an OpenGL implementation #[derive(Clone, Eq, Ord, PartialEq, PartialOrd)] pub struct Version { @@ -121,8 +123,8 @@ impl Version { } } -impl std::fmt::Debug for Version { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { +impl core::fmt::Debug for Version { + fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { match ( self.major, self.minor, @@ -141,6 +143,8 @@ impl std::fmt::Debug for Version { #[cfg(test)] mod tests { + use alloc::string::{String, ToString}; + use super::Version; #[test] diff --git a/src/web_sys.rs b/src/web_sys.rs index ab2045f..5218dd7 100644 --- a/src/web_sys.rs +++ b/src/web_sys.rs @@ -1,8 +1,9 @@ -use super::*; +use core::cell::RefCell; use js_sys::{self, Array}; use slotmap::{new_key_type, SlotMap}; -use std::cell::RefCell; +#[cfg(web_sys_unstable_apis)] +use web_sys::VideoFrame; use web_sys::{ self, HtmlCanvasElement, HtmlImageElement, HtmlVideoElement, ImageBitmap, ImageData, WebGl2RenderingContext, WebGlBuffer, WebGlFramebuffer, WebGlProgram, WebGlQuery, @@ -10,8 +11,7 @@ use web_sys::{ WebGlTransformFeedback, WebGlUniformLocation, WebGlVertexArrayObject, }; -#[cfg(web_sys_unstable_apis)] -use web_sys::VideoFrame; +use super::*; #[derive(Debug)] enum RawRenderingContext { @@ -1606,8 +1606,14 @@ impl HasContext for Context { type UniformLocation = WebGlUniformLocation; type TransformFeedback = WebTransformFeedbackKey; + #[cfg(feature = "std")] fn supported_extensions(&self) -> &HashSet { - &self.supported_extensions + &self.extensions + } + + #[cfg(not(feature = "std"))] + fn supports_extension(&self, extension: &str) -> bool { + self.extensions.contains(extension) } fn supports_debug(&self) -> bool { @@ -6175,8 +6181,7 @@ impl HasContext for Context { /// This function reinterprets the byte data into the correct type for the texture. /// The lookup is generated from this table: https://www.khronos.org/registry/webgl/specs/latest/2.0/#TEXTURE_PIXELS_TYPE_TABLE unsafe fn texture_data_view(ty: u32, bytes: &[u8]) -> js_sys::Object { - use std::mem::size_of; - use std::slice::from_raw_parts; + use core::{mem::size_of, slice::from_raw_parts}; match ty { BYTE => {