mirror of
https://github.com/servo/servo.git
synced 2025-08-04 21:20:23 +01:00
Implement the basic WebGL2 buffer data operations
Adds support for `bufferData`, `bufferSubData`, `copyBufferSubData` and `getBufferSubData`. Reference: https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.3
This commit is contained in:
parent
f626355b67
commit
4050b7f9ec
13 changed files with 510 additions and 197 deletions
|
@ -255,7 +255,7 @@ impl WebGLRenderingContext {
|
|||
&self.limits
|
||||
}
|
||||
|
||||
fn current_vao(&self) -> DomRoot<WebGLVertexArrayObjectOES> {
|
||||
pub fn current_vao(&self) -> DomRoot<WebGLVertexArrayObjectOES> {
|
||||
self.current_vao.or_init(|| {
|
||||
DomRoot::from_ref(
|
||||
self.default_vao
|
||||
|
@ -1004,6 +1004,10 @@ impl WebGLRenderingContext {
|
|||
self.bound_buffer_array.get()
|
||||
}
|
||||
|
||||
pub fn array_buffer_slot(&self) -> &MutNullableDom<WebGLBuffer> {
|
||||
&self.bound_buffer_array
|
||||
}
|
||||
|
||||
pub fn bound_buffer(&self, target: u32) -> WebGLResult<Option<DomRoot<WebGLBuffer>>> {
|
||||
match target {
|
||||
constants::ARRAY_BUFFER => Ok(self.bound_buffer_array.get()),
|
||||
|
@ -1095,6 +1099,72 @@ impl WebGLRenderingContext {
|
|||
pub fn extension_manager(&self) -> &WebGLExtensions {
|
||||
&self.extension_manager
|
||||
}
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
pub fn buffer_data(
|
||||
&self,
|
||||
target: u32,
|
||||
data: Option<ArrayBufferViewOrArrayBuffer>,
|
||||
usage: u32,
|
||||
bound_buffer: Option<DomRoot<WebGLBuffer>>,
|
||||
) {
|
||||
let data = handle_potential_webgl_error!(self, data.ok_or(InvalidValue), return);
|
||||
let bound_buffer =
|
||||
handle_potential_webgl_error!(self, bound_buffer.ok_or(InvalidOperation), return);
|
||||
|
||||
let data = unsafe {
|
||||
// Safe because we don't do anything with JS until the end of the method.
|
||||
match data {
|
||||
ArrayBufferViewOrArrayBuffer::ArrayBuffer(ref data) => data.as_slice(),
|
||||
ArrayBufferViewOrArrayBuffer::ArrayBufferView(ref data) => data.as_slice(),
|
||||
}
|
||||
};
|
||||
handle_potential_webgl_error!(self, bound_buffer.buffer_data(target, data, usage));
|
||||
}
|
||||
|
||||
pub fn buffer_data_(
|
||||
&self,
|
||||
target: u32,
|
||||
size: i64,
|
||||
usage: u32,
|
||||
bound_buffer: Option<DomRoot<WebGLBuffer>>,
|
||||
) {
|
||||
let bound_buffer =
|
||||
handle_potential_webgl_error!(self, bound_buffer.ok_or(InvalidOperation), return);
|
||||
|
||||
if size < 0 {
|
||||
return self.webgl_error(InvalidValue);
|
||||
}
|
||||
|
||||
// FIXME: Allocating a buffer based on user-requested size is
|
||||
// not great, but we don't have a fallible allocation to try.
|
||||
let data = vec![0u8; size as usize];
|
||||
handle_potential_webgl_error!(self, bound_buffer.buffer_data(target, &data, usage));
|
||||
}
|
||||
|
||||
pub fn bind_buffer_maybe(
|
||||
&self,
|
||||
slot: &MutNullableDom<WebGLBuffer>,
|
||||
target: u32,
|
||||
buffer: Option<&WebGLBuffer>,
|
||||
) {
|
||||
if let Some(buffer) = buffer {
|
||||
handle_potential_webgl_error!(self, self.validate_ownership(buffer), return);
|
||||
|
||||
if buffer.is_marked_for_deletion() {
|
||||
return self.webgl_error(InvalidOperation);
|
||||
}
|
||||
handle_potential_webgl_error!(self, buffer.set_target_maybe(target), return);
|
||||
buffer.increment_attached_counter();
|
||||
}
|
||||
|
||||
self.send_command(WebGLCommand::BindBuffer(target, buffer.map(|b| b.id())));
|
||||
if let Some(old) = slot.get() {
|
||||
old.decrement_attached_counter();
|
||||
}
|
||||
|
||||
slot.set(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "webgl_backtrace"))]
|
||||
|
@ -1585,10 +1655,6 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
|||
|
||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5
|
||||
fn BindBuffer(&self, target: u32, buffer: Option<&WebGLBuffer>) {
|
||||
if let Some(buffer) = buffer {
|
||||
handle_potential_webgl_error!(self, self.validate_ownership(buffer), return);
|
||||
}
|
||||
|
||||
let current_vao;
|
||||
let slot = match target {
|
||||
constants::ARRAY_BUFFER => &self.bound_buffer_array,
|
||||
|
@ -1598,19 +1664,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
|||
},
|
||||
_ => return self.webgl_error(InvalidEnum),
|
||||
};
|
||||
|
||||
if let Some(buffer) = buffer {
|
||||
if buffer.is_marked_for_deletion() {
|
||||
return self.webgl_error(InvalidOperation);
|
||||
}
|
||||
handle_potential_webgl_error!(self, buffer.set_target(target), return);
|
||||
buffer.increment_attached_counter();
|
||||
}
|
||||
self.send_command(WebGLCommand::BindBuffer(target, buffer.map(|b| b.id())));
|
||||
if let Some(old) = slot.get() {
|
||||
old.decrement_attached_counter();
|
||||
}
|
||||
slot.set(buffer);
|
||||
self.bind_buffer_maybe(&slot, target, buffer);
|
||||
}
|
||||
|
||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6
|
||||
|
@ -1701,38 +1755,15 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
|||
}
|
||||
|
||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5
|
||||
#[allow(unsafe_code)]
|
||||
fn BufferData(&self, target: u32, data: Option<ArrayBufferViewOrArrayBuffer>, usage: u32) {
|
||||
let data = handle_potential_webgl_error!(self, data.ok_or(InvalidValue), return);
|
||||
|
||||
let bound_buffer = handle_potential_webgl_error!(self, self.bound_buffer(target), return);
|
||||
let bound_buffer =
|
||||
handle_potential_webgl_error!(self, bound_buffer.ok_or(InvalidOperation), return);
|
||||
|
||||
let data = unsafe {
|
||||
// Safe because we don't do anything with JS until the end of the method.
|
||||
match data {
|
||||
ArrayBufferViewOrArrayBuffer::ArrayBuffer(ref data) => data.as_slice(),
|
||||
ArrayBufferViewOrArrayBuffer::ArrayBufferView(ref data) => data.as_slice(),
|
||||
}
|
||||
};
|
||||
handle_potential_webgl_error!(self, bound_buffer.buffer_data(data, usage));
|
||||
self.buffer_data(target, data, usage, bound_buffer)
|
||||
}
|
||||
|
||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5
|
||||
fn BufferData_(&self, target: u32, size: i64, usage: u32) {
|
||||
let bound_buffer = handle_potential_webgl_error!(self, self.bound_buffer(target), return);
|
||||
let bound_buffer =
|
||||
handle_potential_webgl_error!(self, bound_buffer.ok_or(InvalidOperation), return);
|
||||
|
||||
if size < 0 {
|
||||
return self.webgl_error(InvalidValue);
|
||||
}
|
||||
|
||||
// FIXME: Allocating a buffer based on user-requested size is
|
||||
// not great, but we don't have a fallible allocation to try.
|
||||
let data = vec![0u8; size as usize];
|
||||
handle_potential_webgl_error!(self, bound_buffer.buffer_data(&data, usage));
|
||||
self.buffer_data_(target, size, usage, bound_buffer)
|
||||
}
|
||||
|
||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue