mallumo_gls/buffer/
mutable_buffer.rs1use 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 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 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 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}