use gl::types::*;
use std::marker::PhantomData;
use std::cell::RefCell;
use std::rc::Rc;
use ::Result;
use super::traits::*;
use super::storage::BufferStorage;
use super::map::*;
use super::range::Range;
use std::ops::Range as StdRange;
use std::mem;
use std::marker;
use std::slice;
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
#[derive(Debug, Eq, PartialEq)]
pub struct SharedBufferStorage<T>{
buffer: Rc<RefCell<BufferStorage<u8>>>,
marker: marker::PhantomData<T>,
}
impl<T> Clone for SharedBufferStorage<T>{
fn clone(&self) -> SharedBufferStorage<T>{
SharedBufferStorage{
buffer: self.buffer.clone(),
marker: marker::PhantomData,
}
}
}
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
impl<T: 'static> SharedBufferStorage<T>{
fn to_u8(data: &[T]) -> &[u8]{
let bytes = data.len() * mem::size_of::<T>();
unsafe{ slice::from_raw_parts(data.as_ptr() as *const u8, bytes) }
}
fn to_t(data: &[u8]) -> &[T]{
let len = data.len() / mem::size_of::<T>();
unsafe{ slice::from_raw_parts(data.as_ptr() as *const T, len) }
}
fn to_t_mut(data: &mut [u8]) -> &mut [T]{
let len = data.len() / mem::size_of::<T>();
unsafe{ slice::from_raw_parts_mut(data.as_mut_ptr() as *mut T, len) }
}
pub fn update(&mut self, data: &[T]){
(*self.buffer).borrow_mut().update(Self::to_u8(data));
}
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
pub fn with_map_read<F: FnMut(&[T])>(&self, flags: MapReadFlags, mut f: F) -> Result<()>{
(*self.buffer).borrow_mut().with_map_read(flags, |u8_data| f(Self::to_t(u8_data)))
}
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
pub unsafe fn map_write<F: FnMut(&mut [T])>(&mut self, flags: MapWriteFlags, mut f: F) -> Result<()>{
(*self.buffer).borrow_mut()
.map_write(flags)
.map(|mut m| f(Self::to_t_mut(m.data_mut())))
}
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
pub fn map_read_write<F: FnMut(&mut [T])>(&mut self, flags: MapReadWriteFlags, mut f: F) -> Result<()>{
(*self.buffer).borrow_mut()
.map_read_write(flags)
.map(|mut m| f(Self::to_t_mut(m.data_mut())))
}
pub fn copy_to<U,B:BufferRange<U> + WithBackendMut>(&self, dst: &mut B){
(*self.buffer).borrow().copy_to(dst);
}
pub fn len(&self) -> usize{
(*self.buffer).borrow().bytes() / self.stride()
}
pub fn is_empty(&self) -> bool{
(*self.buffer).borrow().is_empty()
}
pub fn capacity(&self) -> usize{
(*self.buffer).borrow().capacity_bytes() / self.stride()
}
pub fn bytes(&self) -> usize{
(*self.buffer).borrow().bytes()
}
pub fn capacity_bytes(&self) -> usize{
(*self.buffer).borrow().capacity_bytes()
}
pub fn id(&self) -> GLuint{
(*self.buffer).borrow().id()
}
pub fn stride(&self) -> usize{
mem::size_of::<T>()
}
pub fn range<R: InputRange>(&self, range: R) -> Range<T, SharedBufferStorage<T>, SharedBufferStorage<T>>{
Range{
buffer: self.clone(),
range: range.to_range(self),
marker_type: PhantomData,
marker_buffer: PhantomData,
}
}
pub fn range_mut<R: InputRange>(&mut self, range: R) -> Range<T, SharedBufferStorage<T>, SharedBufferStorage<T>>{
Range{
buffer: self.clone(),
range: range.to_range(self),
marker_type: PhantomData,
marker_buffer: PhantomData,
}
}
pub fn is_persistant(&self) -> bool {
(*self.buffer).borrow().is_persistant()
}
pub fn is_read_map(&self) -> bool {
(*self.buffer).borrow().is_read_map()
}
pub fn is_write_map(&self) -> bool {
(*self.buffer).borrow().is_write_map()
}
pub fn is_dynamic_storage(&self) -> bool {
(*self.buffer).borrow().is_dynamic_storage()
}
pub fn is_coherent(&self) -> bool {
(*self.buffer).borrow().is_coherent()
}
pub fn map_persistent_read(&self, flags: MapReadFlags) -> Result<MapPersistentRead<T, &Self>>{
unsafe{
(*self.buffer).borrow().unsafe_map_range_persistent_read(None, flags)
.map(|map| MapPersistentRead::new(
Self::to_t(map),
self
))
}
}
pub fn into_map_persistent_read(self, flags: MapReadFlags) -> Result<MapPersistentRead<T, Self>>{
unsafe{
(*self.buffer).borrow().unsafe_map_range_persistent_read(None, flags)
.map(|map| MapPersistentRead::new(
Self::to_t(map),
self.clone()
))
}
}
pub fn map_persistent_write(&self, flags: MapWriteFlags) -> Result<MapPersistentWrite<T, &Self>>{
unsafe{
(*self.buffer).borrow_mut().unsafe_map_range_persistent_write(None, flags)
.map(|map| MapPersistentWrite::new(
Self::to_t_mut(map),
self))
}
}
pub fn into_map_persistent_write(self, flags: MapWriteFlags) -> Result<MapPersistentWrite<T, Self>>{
unsafe{
(*self.buffer).borrow_mut().unsafe_map_range_persistent_write(None, flags)
.map(|map| MapPersistentWrite::new(
Self::to_t_mut(map),
self.clone()))
}
}
pub fn map_persistent_read_write(&self, flags: MapReadWriteFlags) -> Result<MapPersistentReadWrite<T, &Self>>{
unsafe{
(*self.buffer).borrow_mut().unsafe_map_range_persistent_read_write(None, flags)
.map(|map| MapPersistentReadWrite::new(
Self::to_t_mut(map),
self
))
}
}
pub fn into_map_persistent_read_write(self, flags: MapReadWriteFlags) -> Result<MapPersistentReadWrite<T, Self>>{
unsafe{
(*self.buffer).borrow_mut().unsafe_map_range_persistent_read_write(None, flags)
.map(|map| MapPersistentReadWrite::new(
Self::to_t_mut(map),
self.clone()
))
}
}
}
impl SharedBufferStorage<u8>{
pub fn cast<T>(self) -> SharedBufferStorage<T>{
SharedBufferStorage{
buffer: self.buffer,
marker: marker::PhantomData,
}
}
}
impl<T: 'static> Cast<T> for SharedBufferStorage<u8>{
type CastTo = SharedBufferStorage<T>;
fn cast(self) -> SharedBufferStorage<T>{
SharedBufferStorage{
buffer: self.buffer,
marker: marker::PhantomData,
}
}
}
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
impl<T: 'static> TypedBuffer<T> for SharedBufferStorage<T>{
fn id(&self) -> GLuint{
(*self).id()
}
fn len(&self) -> usize{
(*self).len()
}
fn capacity(&self) -> usize{
(*self).capacity()
}
fn with_map_read<F: FnMut(&[T])>(&self, flags: MapReadFlags, f: F) -> Result<()>{
(*self).with_map_read(flags, f)
}
fn copy_to<U,B:BufferRange<U> + WithBackendMut>(&self, dst: &mut B){
(*self).copy_to(dst)
}
#[cfg(not(feature="webgl"))]
unsafe fn unmap(&self){
self.buffer.borrow().unmap()
}
}
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
impl<T: 'static> TypedBuffer<T> for &SharedBufferStorage<T>{
fn id(&self) -> GLuint{
(*self).id()
}
fn len(&self) -> usize{
(*self).len()
}
fn capacity(&self) -> usize{
(*self).capacity()
}
fn with_map_read<F: FnMut(&[T])>(&self, flags: MapReadFlags, f: F) -> Result<()>{
(*self).with_map_read(flags, f)
}
fn copy_to<U,B:BufferRange<U> + WithBackendMut>(&self, dst: &mut B){
(*self).copy_to(dst)
}
#[cfg(not(feature="webgl"))]
unsafe fn unmap(&self){
self.buffer.borrow().unmap()
}
}
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
impl<'a, T: 'static> TypedBufferMut<T> for SharedBufferStorage<T> {
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
unsafe fn with_map_write<F: FnMut(&mut [T])>(&mut self, flags: MapWriteFlags, f: F) -> Result<()>{
(*self).map_write(flags, f)
}
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
fn with_map_read_write<F: FnMut(&mut [T])>(&mut self, flags: MapReadWriteFlags, f: F) -> Result<()>{
(*self).map_read_write(flags, f)
}
}
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
impl<T: 'static> BufferRange<T> for SharedBufferStorage<T>{
fn start(&self) -> usize{
0
}
fn end(&self) -> usize{
self.len()
}
fn into_range<R: InputRange>(self, range: R) -> super::Range<T, Self, Self> where Self: Sized{
Range{
range: range.to_range(&self),
buffer: self,
marker_type: PhantomData,
marker_buffer: PhantomData,
}
}
}
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
impl<T: 'static> BufferRange<T> for &SharedBufferStorage<T>{
fn start(&self) -> usize{
0
}
fn end(&self) -> usize{
(*self).len()
}
fn into_range<R: InputRange>(self, range: R) -> super::Range<T, Self, Self> where Self: Sized{
Range{
range: range.to_range(&self),
buffer: self,
marker_type: PhantomData,
marker_buffer: PhantomData,
}
}
}
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
impl<T:'static> BufferRangeMut<T> for SharedBufferStorage<T>{
fn update(&mut self, data: &[T]){
self.update(data);
}
}
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
impl<T> WithBackend for SharedBufferStorage<T>{
fn with_backend<F:FnMut(&dyn Backend)->R, R>(&self, f:F) -> R{
(*self.buffer).borrow().with_backend(f)
}
}
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
impl<T> WithBackendMut for SharedBufferStorage<T>{
fn with_backend_mut<F:FnMut(&mut dyn Backend)->R, R>(&mut self, f:F) -> R{
(*self.buffer).borrow_mut().with_backend_mut(f)
}
}
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
impl<T: 'static> WithMapRange<T> for SharedBufferStorage<T>{
fn with_map_range_read<F: FnMut(&[T])>(&self, offset: usize, length: usize, flags: MapReadFlags, mut f: F) -> Result<()>{
(*self.buffer)
.borrow()
.with_map_range_read(offset, length, flags, |u8_data| f(Self::to_t(u8_data)))
}
}
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
impl<T: 'static> WithMapRangeMut<T> for SharedBufferStorage<T>{
unsafe fn with_map_range_write<F: FnMut(&mut [T])>(&mut self, offset: usize, length: usize, flags: MapWriteFlags, mut f: F) -> Result<()>{
(*self.buffer)
.borrow_mut()
.with_map_range_write(offset, length, flags, |u8_data| f(Self::to_t_mut(u8_data)))
}
fn with_map_range_read_write<F: FnMut(&mut [T])>(&mut self, offset: usize, length: usize, flags: MapReadWriteFlags, mut f: F) -> Result<()>{
(*self.buffer)
.borrow_mut()
.with_map_range_read_write(offset, length, flags, |u8_data| f(Self::to_t_mut(u8_data)))
}
}
impl<T: 'static> From<BufferStorage<T>> for SharedBufferStorage<T>{
fn from(buffer: BufferStorage<T>) -> SharedBufferStorage<T>{
let buffer = BufferStorage{
len: buffer.bytes(),
reserved: buffer.capacity_bytes(),
backend: buffer.backend,
marker: marker::PhantomData,
creation_flags: buffer.creation_flags,
persistent_map_token: buffer.persistent_map_token,
};
SharedBufferStorage{
buffer: Rc::new(RefCell::new(buffer)),
marker: marker::PhantomData,
}
}
}
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
impl<T: 'static> MapPersistentRange<T> for SharedBufferStorage<T>{
unsafe fn unsafe_map_range_persistent_read(&self, range: Option<StdRange<usize>>, flags: MapReadFlags) -> Result<&'static [T]>{
(*self.buffer).borrow()
.unsafe_map_range_persistent_read(range, flags)
.map(|data| Self::to_t(data))
}
fn map_range_persistent_read(&self, offset: usize, length: usize, flags: MapReadFlags) -> Result<MapPersistentRead<T,&Self>>{
unsafe{
(*self.buffer).borrow()
.unsafe_map_range_persistent_read(Some(offset .. offset + length), flags)
.map(|map| MapPersistentRead::new(
Self::to_t(map),
self
))
}
}
fn into_map_range_persistent_read(self, offset: usize, length: usize, flags: MapReadFlags) -> Result<MapPersistentRead<T,Self>>
where Self: Sized
{
unsafe{
(*self.buffer).borrow()
.unsafe_map_range_persistent_read(Some(offset .. offset + length), flags)
.map(|map| MapPersistentRead::new(
Self::to_t(map),
self.clone()
))
}
}
}
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
impl<T: 'static> MapPersistentRangeMut<T> for SharedBufferStorage<T>{
unsafe fn unsafe_map_range_persistent_write(&self, range: Option<StdRange<usize>>, flags: MapWriteFlags) -> Result<&'static mut [T]>{
(*self.buffer).borrow()
.unsafe_map_range_persistent_write(range, flags)
.map(|data| Self::to_t_mut(data))
}
unsafe fn unsafe_map_range_persistent_read_write(&self, range: Option<StdRange<usize>>, flags: MapReadWriteFlags) -> Result<&'static mut [T]>{
(*self.buffer).borrow()
.unsafe_map_range_persistent_read_write(range, flags)
.map(|data| Self::to_t_mut(data))
}
fn map_range_persistent_write(&self, offset: usize, length: usize, flags: MapWriteFlags) -> Result<MapPersistentWrite<T,&Self>>{
unsafe{
let buffer = &*self;
(*self.buffer).borrow_mut()
.unsafe_map_range_persistent_write(Some(offset .. offset + length), flags)
.map(move |map| MapPersistentWrite::new(Self::to_t_mut(map), buffer))
}
}
fn map_range_persistent_read_write(&self, offset: usize, length: usize, flags: MapReadWriteFlags) -> Result<MapPersistentReadWrite<T,&Self>>{
unsafe{
let buffer = &*self;
(*self.buffer).borrow_mut()
.unsafe_map_range_persistent_read_write(Some(offset .. offset + length), flags)
.map(move |map| MapPersistentReadWrite::new(
Self::to_t_mut(map),
buffer,
))
}
}
fn into_map_range_persistent_write(self, offset: usize, length: usize, flags: MapWriteFlags) -> Result<MapPersistentWrite<T,Self>>{
unsafe{
(*self.buffer).borrow_mut()
.unsafe_map_range_persistent_write(Some(offset .. offset + length), flags)
.map(|map| MapPersistentWrite::new(Self::to_t_mut(map), self.clone()))
}
}
fn into_map_range_persistent_read_write(self, offset: usize, length: usize, flags: MapReadWriteFlags) -> Result<MapPersistentReadWrite<T,Self>>{
unsafe{
(*self.buffer).borrow_mut()
.unsafe_map_range_persistent_read_write(Some(offset .. offset + length), flags)
.map(|map| MapPersistentReadWrite::new(
Self::to_t_mut(map),
self.clone()
))
}
}
}
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
impl<T: 'static> MapPersistent<T> for SharedBufferStorage<T>{
fn map_persistent_read(&self, flags: MapReadFlags) -> Result<MapPersistentRead<T,&Self>>{
(*self).map_persistent_read(flags)
}
fn into_map_persistent_read(self, flags: MapReadFlags) -> Result<MapPersistentRead<T,Self>>
where Self: Sized
{
self.into_map_persistent_read(flags)
}
}
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
impl<T: 'static> MapPersistentMut<T> for SharedBufferStorage<T>{
fn map_persistent_write(&self, flags: MapWriteFlags) -> Result<MapPersistentWrite<T,&Self>>{
(*self).map_persistent_write(flags)
}
fn map_persistent_read_write(&self, flags: MapReadWriteFlags) -> Result<MapPersistentReadWrite<T,&Self>>{
(*self).map_persistent_read_write(flags)
}
fn into_map_persistent_write(self, flags: MapWriteFlags) -> Result<MapPersistentWrite<T,Self>>{
self.into_map_persistent_write(flags)
}
fn into_map_persistent_read_write(self, flags: MapReadWriteFlags) -> Result<MapPersistentReadWrite<T,Self>>{
self.into_map_persistent_read_write(flags)
}
}