aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/webglrenderingcontext.rs
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2019-11-05 16:52:51 -0500
committerGitHub <noreply@github.com>2019-11-05 16:52:51 -0500
commitafbcbf75eaa63ff0eec8fd3858e9155eb8dbadaa (patch)
tree8b0f5cf2b882ba3b7fc0fef8df49ac9a3a9d0e6a /components/script/dom/webglrenderingcontext.rs
parent593f8bd0f66d0c4a4f8f636a78337a7f029b9b8f (diff)
parent4050b7f9eca4c581d100fed778fa09f21d7e09dd (diff)
downloadservo-afbcbf75eaa63ff0eec8fd3858e9155eb8dbadaa.tar.gz
servo-afbcbf75eaa63ff0eec8fd3858e9155eb8dbadaa.zip
Auto merge of #24473 - mmatyas:webgl_fns_buffer, r=jdm
Implement the basic WebGL2 buffer data operations Adds support for the WebGL2 calls `bufferData`, `bufferSubData`, `copyBufferSubData` and `getBufferSubData`. Reference: https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.3 --- <!-- Please describe your changes on the following line: --> This patch depends on https://github.com/servo/sparkle/pull/8. Some tests cause a crash for me at the moment, as they depend on other, not yet implemented buffer calls and transform feedback objects. As for the code, there are a few parts I'm not sure about: - To get the element byte size of a TypedArray I've wrote a simple `match`, as the relevant field is not published in `rust-mozjs`. Is that okay or there's some other way to get this already? - The WebGL1 BufferData implementations were copied into the WebGL2 code as a workaround, due to the difference in the available buffer slots (ie. `self.bound_buffer`). An alternative could be is to pass this function and self as parameters to an internal buffer data implementation function, but personally I found that code to be quite ugly. cc @jdm @zakorgy --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: --> - [x] `./mach build -d` does not report any errors (with the sparkle patch) - [x] `./mach test-tidy` does not report any errors - [ ] These changes fix #___ (GitHub issue number if applicable) <!-- Either: --> - [x] There are tests for these changes OR - [ ] These changes do not require tests because ___ <!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.--> <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
Diffstat (limited to 'components/script/dom/webglrenderingcontext.rs')
-rw-r--r--components/script/dom/webglrenderingcontext.rs117
1 files changed, 74 insertions, 43 deletions
diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs
index b5faecc7371..f0e4887858c 100644
--- a/components/script/dom/webglrenderingcontext.rs
+++ b/components/script/dom/webglrenderingcontext.rs
@@ -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