use super::*; use std::ops::{RangeFrom, RangeFull, RangeTo}; type Args = (*const GLvoid, usize, GLenum); pub trait AllocArgs { fn geta(&self) -> Args; } impl AllocArgs for Args { fn geta(&self) -> Self { *self } } impl, T> AllocArgs for (S, GLenum) { fn geta(&self) -> Args { let slice = self.0.as_ref(); (slice.as_ptr() as *const GLvoid, slice.len(), self.1) } } impl AllocArgs for &[T] { fn geta(&self) -> Args { (*self, gl::DYNAMIC_STORAGE_BIT | gl::MAP_READ_BIT | gl::MAP_WRITE_BIT).geta() } } type UArgs = (*const GLvoid, usize, usize); pub trait UpdateArgs { fn getu(&self) -> UArgs; } impl UpdateArgs for UArgs { fn getu(&self) -> Self { *self } } impl, T, O: Copy> UpdateArgs for (S, O) where usize: Cast, { fn getu(&self) -> UArgs { let slice = self.0.as_ref(); (slice.as_ptr() as *const GLvoid, slice.len(), usize(self.1)) } } impl UpdateArgs for &[T] { fn getu(&self) -> UArgs { (*self, 0).getu() } } type RArgs = (usize, usize, GLenum); pub trait MappingArgs { fn get(self) -> RArgs; } impl MappingArgs for (Range, GLenum) where usize: Cast, { fn get(self) -> RArgs { (usize(self.0.start), usize(self.0.end), self.1) } } impl MappingArgs for (RangeTo, GLenum) where usize: Cast, { fn get(self) -> RArgs { (0..usize(self.0.end), self.1).get() } } impl MappingArgs for (RangeFrom, GLenum) where usize: Cast, { fn get(self) -> RArgs { (usize(self.0.start)..0, self.1).get() } } impl MappingArgs for (RangeFull, GLenum) { fn get(self) -> RArgs { (0..0, self.1).get() } } impl MappingArgs for Range where usize: Cast, { fn get(self) -> RArgs { (self, 0).get() } } impl MappingArgs for RangeTo where usize: Cast, { fn get(self) -> RArgs { (self, 0).get() } } impl MappingArgs for RangeFrom where usize: Cast, { fn get(self) -> RArgs { (self, 0).get() } } impl MappingArgs for RangeFull { fn get(self) -> RArgs { (self, 0).get() } } pub fn get_mapping_args(o: &ArrObject, args: impl MappingArgs) -> (isize, usize, GLenum) { let (start, end, access) = args.get(); let end = end.or_val(end != 0, o.len); ASSERT!(start < end, "Buffer {}({}) access with malformed range", o.obj, type_name::()); ASSERT!(end <= o.len, "Buffer {}({}) mapped out of bounds", o.obj, type_name::()); let tsize = type_size::(); (isize(start * tsize), (end - start) * tsize, access) }