use gl::types::*;
use std::mem;
use std::os::raw::c_void;
#[cfg(not(feature="webgl"))]
use ::Result;
use std::ops;
#[cfg(not(feature="webgl"))]
use super::map::*;
use std::fmt::Debug;
#[cfg(not(feature="webgl"))]
use std::ops::Range;
pub trait TypedBuffer<T>{
fn id(&self) -> GLuint;
fn len(&self) -> usize;
fn capacity(&self) -> usize;
fn is_empty(&self) -> bool{
self.len() == 0
}
fn bytes(&self) -> usize{
self.len() * self.stride()
}
fn capacity_bytes(&self) -> usize{
self.capacity() * self.stride()
}
fn stride(&self) -> usize{
mem::size_of::<T>()
}
#[cfg(not(feature="webgl"))]
fn with_map_read<F: FnMut(&[T])>(&self, flags: MapReadFlags, f: F) -> Result<()> where Self: Sized;
#[cfg(not(feature="webgl"))]
unsafe fn unmap(&self);
fn copy_to<U,B:BufferRange<U> + WithBackendMut>(&self, dst: &mut B) where Self: Sized;
}
pub trait TypedBufferMut<T>: TypedBuffer<T>{
#[cfg(not(feature="webgl"))]
unsafe fn with_map_write<F: Fn(&mut [T])>(&mut self, flags: MapWriteFlags, f: F) -> Result<()> where Self: Sized;
#[cfg(not(feature="webgl"))]
fn with_map_read_write<F: Fn(&mut [T])>(&mut self, flags: MapReadWriteFlags, f: F) -> Result<()> where Self: Sized;
}
pub trait Cast<T>{
type CastTo;
fn cast(self) -> Self::CastTo;
}
pub trait BufferRange<T>: TypedBuffer<T>{
fn start(&self) -> usize;
fn end(&self) -> usize;
fn into_range<R: InputRange>(self, range: R) -> super::Range<T, Self, Self> where Self: Sized;
}
pub trait BufferRangeMut<T>: BufferRange<T>{
fn update(&mut self, data: &[T]);
}
pub trait InputRange{
fn to_range<T, B: BufferRange<T>>(self, buffer: &B) -> ops::Range<usize>;
}
impl InputRange for ops::Range<usize>{
fn to_range<T, B: BufferRange<T>>(self, buffer: &B) -> ops::Range<usize>{
assert!(buffer.start() + self.start <= buffer.start() + self.end);
assert!(buffer.start() + self.end <= buffer.end());
buffer.start() + self.start .. buffer.start() + self.end
}
}
impl InputRange for ops::RangeFrom<usize>{
fn to_range<T, B: BufferRange<T>>(self, buffer: &B) -> ops::Range<usize>{
assert!(buffer.start() + self.start <= buffer.end());
buffer.start() + self.start .. buffer.end()
}
}
impl InputRange for ops::RangeTo<usize>{
fn to_range<T, B: BufferRange<T>>(self, buffer: &B) -> ops::Range<usize>{
assert!(buffer.start() + self.end <= buffer.end());
buffer.start() .. buffer.start() + self.end
}
}
impl InputRange for ops::RangeFull{
fn to_range<T, B: BufferRange<T>>(self, buffer: &B) -> ops::Range<usize>{
buffer.start() .. buffer.end()
}
}
pub trait Backend: Debug {
fn id(&self) -> GLuint;
fn bind(&self, target: GLenum);
fn unbind(&self, target: GLenum);
unsafe fn load(&mut self, data: *const c_void, len: usize, usage: GLenum);
unsafe fn load_target(&mut self, data: *const c_void, len: usize, usage: GLenum, target: GLenum);
unsafe fn update(&mut self, data: *const c_void, len: usize, offset: usize);
#[cfg(not(feature="webgl"))]
unsafe fn unmap(&self);
#[cfg(not(feature="webgl"))]
unsafe fn map_range(&self, offset: GLintptr, length: GLsizeiptr, flags: GLenum) -> *const c_void;
fn copy_to(&self, dst: &mut dyn Backend, read_offset: usize, write_offset: usize, size: usize);
unsafe fn get_parameter_iv(&self, parameter: GLenum, len: usize) -> Vec<GLint>;
}
pub trait WithBackend {
fn with_backend<F:FnMut(&dyn Backend)->R, R>(&self, f:F) -> R;
}
pub trait WithBackendMut {
fn with_backend_mut<F:FnMut(&mut dyn Backend)->R, R>(&mut self, f:F) -> R;
}
#[cfg(not(feature="webgl"))]
pub trait WithMapRange<T>{
fn with_map_range_read<F: FnMut(&[T])>(&self, offset: usize, length: usize, flags: MapReadFlags, f: F) -> Result<()>;
}
#[cfg(not(feature="webgl"))]
pub trait WithMapRangeMut<T>: WithMapRange<T>{
unsafe fn with_map_range_write<F: FnMut(&mut [T])>(&mut self, offset: usize, length: usize, flags: MapWriteFlags, f: F) -> Result<()>;
fn with_map_range_read_write<F: FnMut(&mut [T])>(&mut self, offset: usize, length: usize, flags: MapReadWriteFlags, f: F) -> Result<()>;
}
#[cfg(not(feature="webgl"))]
pub trait MapRange<T>: WithBackend + Sized{
fn map_range_read(&mut self, offset: usize, length: usize, flags: MapReadFlags) -> Result<MapRead<T,Self>>;
}
#[cfg(not(feature="webgl"))]
pub trait MapRangeMut<T>: MapRange<T>{
fn map_range_write(&mut self, offset: usize, length: usize, flags: MapWriteFlags) -> Result<MapWrite<T,Self>>;
fn map_range_read_write(&mut self, offset: usize, length: usize, flags: MapReadWriteFlags) -> Result<MapReadWrite<T, Self>>;
}
#[cfg(not(feature="webgl"))]
pub trait MapPersistent<T>
where
Self: TypedBuffer<T>,
for<'a> &'a Self: TypedBuffer<T>,
{
fn map_persistent_read(&self, flags: MapReadFlags) -> Result<MapPersistentRead<T,&Self>>;
fn into_map_persistent_read(self, flags: MapReadFlags) -> Result<MapPersistentRead<T,Self>> where Self: Sized;
}
#[cfg(not(feature="webgl"))]
pub trait MapPersistentMut<T>: MapPersistent<T>
where
Self: TypedBuffer<T>,
for<'a> &'a Self: TypedBuffer<T>,
{
fn map_persistent_write(&self, flags: MapWriteFlags) -> Result<MapPersistentWrite<T,&Self>>;
fn map_persistent_read_write(&self, flags: MapReadWriteFlags) -> Result<MapPersistentReadWrite<T,&Self>>;
fn into_map_persistent_write(self, flags: MapWriteFlags) -> Result<MapPersistentWrite<T,Self>> where Self: Sized;
fn into_map_persistent_read_write(self, flags: MapReadWriteFlags) -> Result<MapPersistentReadWrite<T,Self>> where Self: Sized;
}
#[cfg(not(feature="webgl"))]
pub trait MapPersistentRange<T>
where
Self: TypedBuffer<T>,
for<'a> &'a Self: TypedBuffer<T>,
{
unsafe fn unsafe_map_range_persistent_read(&self, range: Option<Range<usize>>, flags: MapReadFlags) -> Result<&'static [T]>;
fn map_range_persistent_read(&self, offset: usize, length: usize, flags: MapReadFlags) -> Result<MapPersistentRead<T,&Self>>;
fn into_map_range_persistent_read(self, offset: usize, length: usize, flags: MapReadFlags) -> Result<MapPersistentRead<T,Self>> where Self: Sized;
}
#[cfg(not(feature="webgl"))]
pub trait MapPersistentRangeMut<T>: MapPersistentRange<T>
where
Self: TypedBuffer<T>,
for<'a> &'a Self: TypedBuffer<T>,
{
unsafe fn unsafe_map_range_persistent_write(&self, range: Option<Range<usize>>, flags: MapWriteFlags) -> Result<&'static mut [T]>;
unsafe fn unsafe_map_range_persistent_read_write(&self, range: Option<Range<usize>>, flags: MapReadWriteFlags) -> Result<&'static mut [T]>;
fn map_range_persistent_write(&self, offset: usize, length: usize, flags: MapWriteFlags) -> Result<MapPersistentWrite<T,&Self>>;
fn map_range_persistent_read_write(&self, offset: usize, length: usize, flags: MapReadWriteFlags) -> Result<MapPersistentReadWrite<T,&Self>>;
fn into_map_range_persistent_write(self, offset: usize, length: usize, flags: MapWriteFlags) -> Result<MapPersistentWrite<T,Self>> where Self: Sized;
fn into_map_range_persistent_read_write(self, offset: usize, length: usize, flags: MapReadWriteFlags) -> Result<MapPersistentReadWrite<T,Self>> where Self: Sized;
}