luminance_gl/gl33/
buffer.rs1use crate::gl33::{
4 state::{Bind, GLState},
5 GL33,
6};
7use gl;
8use gl::types::*;
9use luminance::tess::TessMapError;
10use std::{
11 cell::RefCell,
12 error, fmt, mem,
13 ops::{Deref, DerefMut},
14 rc::Rc,
15 slice,
16};
17
18#[derive(Debug, Eq, PartialEq)]
19pub enum SliceBufferError {
20 MapFailed,
22}
23
24impl fmt::Display for SliceBufferError {
25 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
26 match self {
27 SliceBufferError::MapFailed => f.write_str("buffer mapping failed"),
28 }
29 }
30}
31
32impl error::Error for SliceBufferError {}
33
34impl From<SliceBufferError> for TessMapError {
35 fn from(_: SliceBufferError) -> Self {
36 TessMapError::CannotMap
37 }
38}
39
40#[derive(Debug)]
44struct BufferWrapper {
45 handle: GLuint,
46 state: Rc<RefCell<GLState>>,
47}
48
49impl Drop for BufferWrapper {
50 fn drop(&mut self) {
51 unsafe {
52 self.state.borrow_mut().unbind_buffer(self.handle);
53 gl::DeleteBuffers(1, &self.handle);
54 }
55 }
56}
57
58#[derive(Debug)]
60pub struct Buffer<T> {
61 pub(crate) buf: Vec<T>,
63 gl_buf: BufferWrapper,
64}
65
66impl<T> Buffer<T> {
67 pub(crate) unsafe fn from_vec(gl33: &mut GL33, vec: Vec<T>) -> Self {
68 let mut handle: GLuint = 0;
69
70 gl::GenBuffers(1, &mut handle);
71 gl33
72 .state
73 .borrow_mut()
74 .bind_array_buffer(handle, Bind::Forced);
75
76 let len = vec.len();
77 let bytes = mem::size_of::<T>() * len;
78 gl::BufferData(
79 gl::ARRAY_BUFFER,
80 bytes as isize,
81 vec.as_ptr() as _,
82 gl::STREAM_DRAW,
83 );
84 let state = gl33.state.clone();
85 let gl_buf = BufferWrapper { handle, state };
86
87 Buffer { gl_buf, buf: vec }
88 }
89
90 pub(crate) fn handle(&self) -> GLuint {
91 self.gl_buf.handle
92 }
93
94 #[inline]
96 pub fn len(&self) -> usize {
97 self.buf.len()
98 }
99
100 pub(crate) fn slice_buffer(&self) -> Result<BufferSlice<T>, SliceBufferError> {
101 unsafe {
102 self
103 .gl_buf
104 .state
105 .borrow_mut()
106 .bind_array_buffer(self.handle(), Bind::Cached);
107 }
108
109 mapping_buffer(gl::ARRAY_BUFFER, gl::READ_ONLY, |ptr| {
110 let handle = self.handle();
111 let state = &self.gl_buf.state;
112 let raw = BufferSliceWrapper { handle, state };
113 let len = self.buf.len();
114
115 BufferSlice { raw, len, ptr }
116 })
117 }
118
119 pub(crate) fn slice_buffer_mut(&mut self) -> Result<BufferSliceMut<T>, SliceBufferError> {
120 unsafe {
121 self
122 .gl_buf
123 .state
124 .borrow_mut()
125 .bind_array_buffer(self.handle(), Bind::Cached);
126 }
127
128 mapping_buffer(gl::ARRAY_BUFFER, gl::READ_WRITE, move |ptr| {
129 let handle = self.handle();
130 let state = &self.gl_buf.state;
131 let raw = BufferSliceWrapper { handle, state };
132 let len = self.buf.len();
133
134 BufferSliceMut { raw, len, ptr }
135 })
136 }
137}
138
139struct BufferSliceWrapper<'a> {
141 handle: GLuint,
142 state: &'a Rc<RefCell<GLState>>,
144}
145
146impl Drop for BufferSliceWrapper<'_> {
147 fn drop(&mut self) {
148 unsafe {
149 self
150 .state
151 .borrow_mut()
152 .bind_array_buffer(self.handle, Bind::Cached);
153
154 gl::UnmapBuffer(gl::ARRAY_BUFFER);
155 }
156 }
157}
158
159pub struct BufferSlice<'a, T> {
160 raw: BufferSliceWrapper<'a>,
161 len: usize,
162 ptr: *const T,
163}
164
165impl<T> Deref for BufferSlice<'_, T> {
166 type Target = [T];
167
168 fn deref(&self) -> &Self::Target {
169 unsafe { slice::from_raw_parts(self.ptr, self.len) }
170 }
171}
172
173impl<'a> BufferSlice<'a, u8> {
174 pub(crate) unsafe fn transmute<T>(self) -> BufferSlice<'a, T> {
179 let len = self.len / mem::size_of::<T>();
180 let ptr = self.ptr as _;
181
182 BufferSlice {
183 raw: self.raw,
184 len,
185 ptr,
186 }
187 }
188}
189
190pub struct BufferSliceMut<'a, T> {
191 raw: BufferSliceWrapper<'a>,
192 len: usize,
193 ptr: *mut T,
194}
195
196impl<T> Deref for BufferSliceMut<'_, T> {
197 type Target = [T];
198
199 fn deref(&self) -> &Self::Target {
200 unsafe { slice::from_raw_parts(self.ptr as *const _, self.len) }
201 }
202}
203
204impl<T> DerefMut for BufferSliceMut<'_, T> {
205 fn deref_mut(&mut self) -> &mut Self::Target {
206 unsafe { slice::from_raw_parts_mut(self.ptr, self.len) }
207 }
208}
209
210impl<'a> BufferSliceMut<'a, u8> {
211 pub(crate) unsafe fn transmute<T>(self) -> BufferSliceMut<'a, T> {
216 let len = self.len / mem::size_of::<T>();
217 let ptr = self.ptr as _;
218
219 BufferSliceMut {
220 raw: self.raw,
221 len,
222 ptr,
223 }
224 }
225}
226
227fn mapping_buffer<A, T>(
229 target: GLenum,
230 access: GLenum,
231 f: impl FnOnce(*mut T) -> A,
232) -> Result<A, SliceBufferError> {
233 let ptr = unsafe { gl::MapBuffer(target, access) } as *mut T;
234
235 if ptr.is_null() {
236 Err(SliceBufferError::MapFailed)
237 } else {
238 Ok(f(ptr))
239 }
240}