mallumo_gls/buffer/
mutable_buffer.rs

1use super::Buffer;
2use super::errors::*;
3
4use std::mem::size_of;
5
6use raw::*;
7
8#[derive(Debug)]
9pub struct MutableBuffer {
10    id: BufferId,
11    size: usize,
12}
13
14impl MutableBuffer {
15    /// Creates new buffer and copies `data` to its memory on GPU
16    ///
17    /// # Errors
18    /// - GL_OUT_OF_MEMORY - if the buffer cannot be created
19    ///
20    pub fn new<T>(data: &[T]) -> Result<MutableBuffer> {
21        if data.len() * size_of::<T>() == 0 {
22            bail!("Buffer size must be greater than 0");
23        }
24
25        let id = create_buffer();
26
27        unsafe {
28            named_buffer_storage(id, BufferData::Data(data), BufferMutability::Mutable, None)
29                .chain_err(|| ErrorKind::BufferCreationError)?;
30        }
31
32        Ok(MutableBuffer {
33            id: id,
34            size: size_of::<T>() * data.len(),
35        })
36    }
37
38    /// Creates new empty buffer
39    ///
40    /// # Errors
41    /// - BufferCreationError(GL_OUT_OF_MEMORY) - if the buffer cannot be created
42    ///
43    pub fn new_empty(size: usize) -> Result<MutableBuffer> {
44        if size == 0 {
45            bail!("Buffer size must be greater than 0");
46        }
47
48        let id = create_buffer();
49
50        unsafe {
51            named_buffer_storage::<u8, Option<BufferMap>>(id, BufferData::Empty(size), BufferMutability::Mutable, None)
52                .chain_err(|| ErrorKind::BufferCreationError)?;
53        }
54
55        Ok(MutableBuffer { id: id, size: size })
56    }
57
58    pub fn new_zeroed(size: usize) -> Result<MutableBuffer> {
59        let mut buffer = MutableBuffer::new_empty(size).chain_err(|| "Could not create empty buffer")?;
60        buffer.clear_data().chain_err(|| "Could not clear buffer")?;
61        Ok(buffer)
62    }
63
64    pub fn set_data<T>(&mut self, data: &[T]) -> Result<()> {
65        unsafe {
66            named_buffer_sub_data(self.id, 0, data).chain_err(|| ErrorKind::BufferSetSubDataError)?;
67        }
68
69        Ok(())
70    }
71
72    /// Replaces part of memory with `data`
73    ///
74    /// # Errors
75    /// - BufferSetSubDataError(GL_INVALID_VALUE) - if size of `data` + offset > buffer size
76    ///
77    pub fn set_sub_data<T>(&mut self, data: &[T], offset: usize) -> Result<()> {
78        unsafe {
79            named_buffer_sub_data(self.id, offset, data).chain_err(|| ErrorKind::BufferSetSubDataError)?;
80        }
81
82        Ok(())
83    }
84
85    pub fn clear_data(&mut self) -> Result<()> {
86        let empty = vec![0u8; self.size];
87
88        self.set_sub_data(&empty, 0)
89            .chain_err(|| "Could not clear data")?;
90
91        Ok(())
92    }
93
94    pub fn copy_to(
95        &mut self,
96        other: &mut MutableBuffer,
97        read_offset: usize,
98        write_offset: usize,
99        size: usize,
100    ) -> Result<()> {
101        unsafe {
102            copy_named_buffer_sub_data(self.id, other.id, read_offset, write_offset, size)
103                .chain_err(|| ErrorKind::BufferCopyError)?;
104        }
105
106        Ok(())
107    }
108
109    pub fn get<T>(&self, size: usize, offset: usize) -> Result<Vec<T>> {
110        if size_of::<T>() * (size + offset) > self.size {
111            bail!("Trying to read out of bounds");
112        }
113
114        let mut result = Vec::with_capacity(size);
115        unsafe {
116            get_named_buffer_sub_data(
117                self.id,
118                size_of::<T>() * offset,
119                size_of::<T>() * size,
120                result.as_mut_slice(),
121            ).chain_err(|| "Could not get buffer data")?;
122
123            result.set_len(size);
124        }
125
126        Ok(result)
127    }
128
129    pub fn resize(&mut self, size: usize) -> Result<()> {
130        let new_id = create_buffer();
131
132        unsafe {
133            named_buffer_storage::<u8, Option<BufferMap>>(
134                new_id,
135                BufferData::Empty(size),
136                BufferMutability::Mutable,
137                None,
138            ).chain_err(|| ErrorKind::BufferCreationError)?;
139        }
140
141        unsafe {
142            copy_named_buffer_sub_data(self.id, new_id, 0, 0, size).chain_err(|| ErrorKind::BufferCopyError)?;
143        }
144
145        unsafe {
146            delete_buffer(self.id);
147        }
148
149        self.id = new_id;
150
151        Ok(())
152    }
153}
154
155impl Buffer for MutableBuffer {
156    fn get_id(&self) -> BufferId {
157        self.id
158    }
159}
160
161impl Drop for MutableBuffer {
162    fn drop(&mut self) {
163        unsafe {
164            delete_buffer(self.id);
165        }
166    }
167}