diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2019-11-05 16:52:51 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-11-05 16:52:51 -0500 |
commit | afbcbf75eaa63ff0eec8fd3858e9155eb8dbadaa (patch) | |
tree | 8b0f5cf2b882ba3b7fc0fef8df49ac9a3a9d0e6a | |
parent | 593f8bd0f66d0c4a4f8f636a78337a7f029b9b8f (diff) | |
parent | 4050b7f9eca4c581d100fed778fa09f21d7e09dd (diff) | |
download | servo-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. -->
13 files changed, 509 insertions, 196 deletions
diff --git a/components/canvas/webgl_thread.rs b/components/canvas/webgl_thread.rs index 00e38dfc56f..b36df1c1b13 100644 --- a/components/canvas/webgl_thread.rs +++ b/components/canvas/webgl_thread.rs @@ -55,6 +55,7 @@ use sparkle::gl::Gl; use std::borrow::Cow; use std::cell::{Cell, RefCell}; use std::rc::Rc; +use std::slice; use std::sync::{Arc, Mutex}; use std::thread; use surfman; @@ -1013,6 +1014,26 @@ impl WebGLImpl { WebGLCommand::BufferSubData(buffer_type, offset, ref receiver) => { gl::buffer_sub_data(gl, buffer_type, offset, &receiver.recv().unwrap()) }, + WebGLCommand::CopyBufferSubData(src, dst, src_offset, dst_offset, size) => { + gl.copy_buffer_sub_data( + src, + dst, + src_offset as isize, + dst_offset as isize, + size as isize, + ); + }, + WebGLCommand::GetBufferSubData(buffer_type, offset, length, ref sender) => { + let ptr = gl.map_buffer_range( + buffer_type, + offset as isize, + length as isize, + gl::MAP_READ_BIT, + ); + let data: &[u8] = unsafe { slice::from_raw_parts(ptr as _, length) }; + sender.send(data).unwrap(); + gl.unmap_buffer(buffer_type); + }, WebGLCommand::Clear(mask) => { gl.clear(mask); }, diff --git a/components/canvas_traits/webgl.rs b/components/canvas_traits/webgl.rs index 88b5f3e0bbc..70986d78b6d 100644 --- a/components/canvas_traits/webgl.rs +++ b/components/canvas_traits/webgl.rs @@ -248,6 +248,8 @@ pub enum WebGLCommand { BindAttribLocation(WebGLProgramId, u32, String), BufferData(u32, IpcBytesReceiver, u32), BufferSubData(u32, isize, IpcBytesReceiver), + GetBufferSubData(u32, usize, usize, IpcBytesSender), + CopyBufferSubData(u32, u32, i64, i64, i64), Clear(u32), ClearColor(f32, f32, f32, f32), ClearDepth(f32), diff --git a/components/script/dom/webgl2renderingcontext.rs b/components/script/dom/webgl2renderingcontext.rs index 4c7d9fb857a..beff6ec6bfd 100644 --- a/components/script/dom/webgl2renderingcontext.rs +++ b/components/script/dom/webgl2renderingcontext.rs @@ -36,11 +36,13 @@ use crate::dom::webgluniformlocation::WebGLUniformLocation; use crate::dom::window::Window; use crate::script_runtime::JSContext; use canvas_traits::webgl::WebGLError::*; -/// https://www.khronos.org/registry/webgl/specs/latest/2.0/webgl.idl -use canvas_traits::webgl::{webgl_channel, GLContextAttributes, WebGLCommand, WebGLVersion}; +use canvas_traits::webgl::{ + webgl_channel, GLContextAttributes, WebGLCommand, WebGLResult, WebGLVersion, +}; use dom_struct::dom_struct; use euclid::default::Size2D; -use js::jsapi::JSObject; +use ipc_channel::ipc; +use js::jsapi::{JSObject, Type}; use js::jsval::{BooleanValue, DoubleValue, Int32Value, JSVal, NullValue, UInt32Value}; use js::rust::CustomAutoRooterGuard; use js::typedarray::ArrayBufferView; @@ -54,6 +56,22 @@ pub struct WebGL2RenderingContext { occlusion_query: MutNullableDom<WebGLQuery>, primitives_query: MutNullableDom<WebGLQuery>, samplers: Box<[MutNullableDom<WebGLSampler>]>, + bound_copy_read_buffer: MutNullableDom<WebGLBuffer>, + bound_copy_write_buffer: MutNullableDom<WebGLBuffer>, + bound_pixel_pack_buffer: MutNullableDom<WebGLBuffer>, + bound_pixel_unpack_buffer: MutNullableDom<WebGLBuffer>, + bound_transform_feedback_buffer: MutNullableDom<WebGLBuffer>, + bound_uniform_buffer: MutNullableDom<WebGLBuffer>, +} + +fn typedarray_elem_size(typeid: Type) -> usize { + match typeid { + Type::Int8 | Type::Uint8 | Type::Uint8Clamped => 1, + Type::Int16 | Type::Uint16 => 2, + Type::Int32 | Type::Uint32 | Type::Float32 => 4, + Type::Int64 | Type::Float64 => 8, + Type::MaxTypedArrayViewType => unreachable!(), + } } impl WebGL2RenderingContext { @@ -76,6 +94,12 @@ impl WebGL2RenderingContext { occlusion_query: MutNullableDom::new(None), primitives_query: MutNullableDom::new(None), samplers: samplers, + bound_copy_read_buffer: MutNullableDom::new(None), + bound_copy_write_buffer: MutNullableDom::new(None), + bound_pixel_pack_buffer: MutNullableDom::new(None), + bound_pixel_unpack_buffer: MutNullableDom::new(None), + bound_transform_feedback_buffer: MutNullableDom::new(None), + bound_uniform_buffer: MutNullableDom::new(None), }) } @@ -100,6 +124,25 @@ impl WebGL2RenderingContext { pub fn base_context(&self) -> DomRoot<WebGLRenderingContext> { DomRoot::from_ref(&*self.base) } + + fn bound_buffer(&self, target: u32) -> WebGLResult<Option<DomRoot<WebGLBuffer>>> { + match target { + constants::COPY_READ_BUFFER => Ok(self.bound_copy_read_buffer.get()), + constants::COPY_WRITE_BUFFER => Ok(self.bound_copy_write_buffer.get()), + constants::PIXEL_PACK_BUFFER => Ok(self.bound_pixel_pack_buffer.get()), + constants::PIXEL_UNPACK_BUFFER => Ok(self.bound_pixel_unpack_buffer.get()), + constants::TRANSFORM_FEEDBACK_BUFFER => Ok(self.bound_transform_feedback_buffer.get()), + constants::UNIFORM_BUFFER => Ok(self.bound_uniform_buffer.get()), + _ => self.base.bound_buffer(target), + } + } + + fn unbind_from(&self, slot: &MutNullableDom<WebGLBuffer>, buffer: &WebGLBuffer) { + if slot.get().map_or(false, |b| buffer == &*b) { + buffer.decrement_attached_counter(); + slot.set(None); + } + } } impl WebGL2RenderingContextMethods for WebGL2RenderingContext { @@ -146,6 +189,27 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { let sampler = self.samplers[idx].get(); optional_root_object_to_js_or_null!(*cx, sampler) }, + constants::COPY_READ_BUFFER_BINDING => unsafe { + optional_root_object_to_js_or_null!(*cx, &self.bound_copy_read_buffer.get()) + }, + constants::COPY_WRITE_BUFFER_BINDING => unsafe { + optional_root_object_to_js_or_null!(*cx, &self.bound_copy_write_buffer.get()) + }, + constants::PIXEL_PACK_BUFFER_BINDING => unsafe { + optional_root_object_to_js_or_null!(*cx, &self.bound_pixel_pack_buffer.get()) + }, + constants::PIXEL_UNPACK_BUFFER_BINDING => unsafe { + optional_root_object_to_js_or_null!(*cx, &self.bound_pixel_unpack_buffer.get()) + }, + constants::TRANSFORM_FEEDBACK_BUFFER_BINDING => unsafe { + optional_root_object_to_js_or_null!( + *cx, + &self.bound_transform_feedback_buffer.get() + ) + }, + constants::UNIFORM_BUFFER_BINDING => unsafe { + optional_root_object_to_js_or_null!(*cx, &self.bound_uniform_buffer.get()) + }, _ => self.base.GetParameter(cx, parameter), } } @@ -238,9 +302,18 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { self.base.BindAttribLocation(program, index, name) } - /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5 + /// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.2 fn BindBuffer(&self, target: u32, buffer: Option<&WebGLBuffer>) { - self.base.BindBuffer(target, buffer) + let slot = match target { + constants::COPY_READ_BUFFER => &self.bound_copy_read_buffer, + constants::COPY_WRITE_BUFFER => &self.bound_copy_write_buffer, + constants::PIXEL_PACK_BUFFER => &self.bound_pixel_pack_buffer, + constants::PIXEL_UNPACK_BUFFER => &self.bound_pixel_unpack_buffer, + constants::TRANSFORM_FEEDBACK_BUFFER => &self.bound_transform_feedback_buffer, + constants::UNIFORM_BUFFER => &self.bound_uniform_buffer, + _ => return self.base.BindBuffer(target, buffer), + }; + self.base.bind_buffer_maybe(&slot, target, buffer); } /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6 @@ -265,12 +338,59 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5 fn BufferData(&self, target: u32, data: Option<ArrayBufferViewOrArrayBuffer>, usage: u32) { - self.base.BufferData(target, data, usage) + let bound_buffer = + handle_potential_webgl_error!(self.base, self.bound_buffer(target), return); + self.base.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) { - self.base.BufferData_(target, size, usage) + let bound_buffer = + handle_potential_webgl_error!(self.base, self.bound_buffer(target), return); + self.base.buffer_data_(target, size, usage, bound_buffer) + } + + /// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.3 + #[allow(unsafe_code)] + fn BufferData__( + &self, + target: u32, + data: CustomAutoRooterGuard<ArrayBufferView>, + usage: u32, + elem_offset: u32, + length: u32, + ) { + let bound_buffer = + handle_potential_webgl_error!(self.base, self.bound_buffer(target), return); + let bound_buffer = + handle_potential_webgl_error!(self.base, bound_buffer.ok_or(InvalidOperation), return); + + let elem_size = typedarray_elem_size(data.get_array_type()); + let elem_count = data.len() / elem_size; + let elem_offset = elem_offset as usize; + let byte_offset = elem_offset * elem_size; + + if byte_offset > data.len() { + return self.base.webgl_error(InvalidValue); + } + + let copy_count = if length == 0 { + elem_count - elem_offset + } else { + length as usize + }; + if copy_count == 0 { + return; + } + let copy_bytes = copy_count * elem_size; + + if byte_offset + copy_bytes > data.len() { + return self.base.webgl_error(InvalidValue); + } + + let data_end = byte_offset + copy_bytes; + let data: &[u8] = unsafe { &data.as_slice()[byte_offset..data_end] }; + handle_potential_webgl_error!(self.base, bound_buffer.buffer_data(target, &data, usage)); } /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5 @@ -278,6 +398,171 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { self.base.BufferSubData(target, offset, data) } + /// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.3 + #[allow(unsafe_code)] + fn BufferSubData_( + &self, + target: u32, + dst_byte_offset: i64, + src_data: CustomAutoRooterGuard<ArrayBufferView>, + src_elem_offset: u32, + length: u32, + ) { + let bound_buffer = + handle_potential_webgl_error!(self.base, self.bound_buffer(target), return); + let bound_buffer = + handle_potential_webgl_error!(self.base, bound_buffer.ok_or(InvalidOperation), return); + + let src_elem_size = typedarray_elem_size(src_data.get_array_type()); + let src_elem_count = src_data.len() / src_elem_size; + let src_elem_offset = src_elem_offset as usize; + let src_byte_offset = src_elem_offset * src_elem_size; + + if dst_byte_offset < 0 || src_byte_offset > src_data.len() { + return self.base.webgl_error(InvalidValue); + } + + let copy_count = if length == 0 { + src_elem_count - src_elem_offset + } else { + length as usize + }; + if copy_count == 0 { + return; + } + let copy_bytes = copy_count * src_elem_size; + + let dst_byte_offset = dst_byte_offset as usize; + if dst_byte_offset + copy_bytes > bound_buffer.capacity() || + src_byte_offset + copy_bytes > src_data.len() + { + return self.base.webgl_error(InvalidValue); + } + + let (sender, receiver) = ipc::bytes_channel().unwrap(); + self.base.send_command(WebGLCommand::BufferSubData( + target, + dst_byte_offset as isize, + receiver, + )); + let src_end = src_byte_offset + copy_bytes; + let data: &[u8] = unsafe { &src_data.as_slice()[src_byte_offset..src_end] }; + sender.send(data).unwrap(); + } + + /// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.3 + fn CopyBufferSubData( + &self, + read_target: u32, + write_target: u32, + read_offset: i64, + write_offset: i64, + size: i64, + ) { + if read_offset < 0 || write_offset < 0 || size < 0 { + return self.base.webgl_error(InvalidValue); + } + + let read_buffer = + handle_potential_webgl_error!(self.base, self.bound_buffer(read_target), return); + let read_buffer = + handle_potential_webgl_error!(self.base, read_buffer.ok_or(InvalidOperation), return); + + let write_buffer = + handle_potential_webgl_error!(self.base, self.bound_buffer(write_target), return); + let write_buffer = + handle_potential_webgl_error!(self.base, write_buffer.ok_or(InvalidOperation), return); + + let read_until = read_offset + size; + let write_until = write_offset + size; + if read_until as usize > read_buffer.capacity() || + write_until as usize > write_buffer.capacity() + { + return self.base.webgl_error(InvalidValue); + } + + if read_target == write_target { + let is_separate = read_until <= write_offset || write_until <= read_offset; + if !is_separate { + return self.base.webgl_error(InvalidValue); + } + } + let src_is_elemarray = read_buffer + .target() + .map_or(false, |t| t == constants::ELEMENT_ARRAY_BUFFER); + let dst_is_elemarray = write_buffer + .target() + .map_or(false, |t| t == constants::ELEMENT_ARRAY_BUFFER); + if src_is_elemarray != dst_is_elemarray { + return self.base.webgl_error(InvalidOperation); + } + + self.base.send_command(WebGLCommand::CopyBufferSubData( + read_target, + write_target, + read_offset, + write_offset, + size, + )); + } + + /// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.3 + #[allow(unsafe_code)] + fn GetBufferSubData( + &self, + target: u32, + src_byte_offset: i64, + mut dst_buffer: CustomAutoRooterGuard<ArrayBufferView>, + dst_elem_offset: u32, + length: u32, + ) { + let bound_buffer = + handle_potential_webgl_error!(self.base, self.bound_buffer(target), return); + let bound_buffer = + handle_potential_webgl_error!(self.base, bound_buffer.ok_or(InvalidOperation), return); + + let dst_elem_size = typedarray_elem_size(dst_buffer.get_array_type()); + let dst_elem_count = dst_buffer.len() / dst_elem_size; + let dst_elem_offset = dst_elem_offset as usize; + let dst_byte_offset = dst_elem_offset * dst_elem_size; + + if src_byte_offset < 0 || dst_byte_offset > dst_buffer.len() { + return self.base.webgl_error(InvalidValue); + } + + let copy_count = if length == 0 { + dst_elem_count - dst_elem_offset + } else { + length as usize + }; + if copy_count == 0 { + return; + } + let copy_bytes = copy_count * dst_elem_size; + + // TODO(mmatyas): Transform Feedback + + let src_byte_offset = src_byte_offset as usize; + if src_byte_offset + copy_bytes > bound_buffer.capacity() || + dst_byte_offset + copy_bytes > dst_buffer.len() + { + return self.base.webgl_error(InvalidValue); + } + + let (sender, receiver) = ipc::bytes_channel().unwrap(); + self.base.send_command(WebGLCommand::GetBufferSubData( + target, + src_byte_offset, + copy_bytes, + sender, + )); + let data = receiver.recv().unwrap(); + let dst_end = dst_byte_offset + copy_bytes; + unsafe { + dst_buffer.as_mut_slice()[dst_byte_offset..dst_end].copy_from_slice(&data); + } + } + /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8 fn CompressedTexImage2D( &self, @@ -445,7 +730,23 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5 fn DeleteBuffer(&self, buffer: Option<&WebGLBuffer>) { - self.base.DeleteBuffer(buffer) + let buffer = match buffer { + Some(buffer) => buffer, + None => return, + }; + handle_potential_webgl_error!(self.base, self.base.validate_ownership(buffer), return); + if buffer.is_marked_for_deletion() { + return; + } + self.base.current_vao().unbind_buffer(buffer); + self.unbind_from(&self.base.array_buffer_slot(), &buffer); + self.unbind_from(&self.bound_copy_read_buffer, &buffer); + self.unbind_from(&self.bound_copy_write_buffer, &buffer); + self.unbind_from(&self.bound_pixel_pack_buffer, &buffer); + self.unbind_from(&self.bound_pixel_unpack_buffer, &buffer); + self.unbind_from(&self.bound_transform_feedback_buffer, &buffer); + self.unbind_from(&self.bound_uniform_buffer, &buffer); + buffer.mark_for_deletion(false); } /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6 diff --git a/components/script/dom/webglbuffer.rs b/components/script/dom/webglbuffer.rs index 9fd8df489d6..182100ae41f 100644 --- a/components/script/dom/webglbuffer.rs +++ b/components/script/dom/webglbuffer.rs @@ -3,6 +3,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ // https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl +use crate::dom::bindings::codegen::Bindings::WebGL2RenderingContextBinding::WebGL2RenderingContextConstants; use crate::dom::bindings::codegen::Bindings::WebGLBufferBinding; use crate::dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants; use crate::dom::bindings::inheritance::Castable; @@ -16,6 +17,11 @@ use dom_struct::dom_struct; use ipc_channel::ipc; use std::cell::Cell; +fn target_is_copy_buffer(target: u32) -> bool { + target == WebGL2RenderingContextConstants::COPY_READ_BUFFER || + target == WebGL2RenderingContextConstants::COPY_WRITE_BUFFER +} + #[dom_struct] pub struct WebGLBuffer { webgl_object: WebGLObject, @@ -65,7 +71,7 @@ impl WebGLBuffer { self.id } - pub fn buffer_data(&self, data: &[u8], usage: u32) -> WebGLResult<()> { + pub fn buffer_data(&self, target: u32, data: &[u8], usage: u32) -> WebGLResult<()> { match usage { WebGLRenderingContextConstants::STREAM_DRAW | WebGLRenderingContextConstants::STATIC_DRAW | @@ -78,11 +84,7 @@ impl WebGLBuffer { let (sender, receiver) = ipc::bytes_channel().unwrap(); self.upcast::<WebGLObject>() .context() - .send_command(WebGLCommand::BufferData( - self.target.get().unwrap(), - receiver, - usage, - )); + .send_command(WebGLCommand::BufferData(target, receiver, usage)); sender.send(data).unwrap(); Ok(()) } @@ -124,11 +126,24 @@ impl WebGLBuffer { self.target.get() } - pub fn set_target(&self, target: u32) -> WebGLResult<()> { - if self.target.get().map_or(false, |t| t != target) { + fn can_bind_to(&self, new_target: u32) -> bool { + if let Some(current_target) = self.target.get() { + if [current_target, new_target] + .contains(&WebGLRenderingContextConstants::ELEMENT_ARRAY_BUFFER) + { + return target_is_copy_buffer(new_target) || new_target == current_target; + } + } + true + } + + pub fn set_target_maybe(&self, target: u32) -> WebGLResult<()> { + if !self.can_bind_to(target) { return Err(WebGLError::InvalidOperation); } - self.target.set(Some(target)); + if !target_is_copy_buffer(target) { + self.target.set(Some(target)); + } Ok(()) } 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 diff --git a/components/script/dom/webidls/WebGL2RenderingContext.webidl b/components/script/dom/webidls/WebGL2RenderingContext.webidl index 586f260ccc2..c171a9bb866 100644 --- a/components/script/dom/webidls/WebGL2RenderingContext.webidl +++ b/components/script/dom/webidls/WebGL2RenderingContext.webidl @@ -299,18 +299,18 @@ interface mixin WebGL2RenderingContextBase void bufferData(GLenum target, GLsizeiptr size, GLenum usage); void bufferSubData(GLenum target, GLintptr dstByteOffset, /*[AllowShared]*/ BufferSource srcData); // WebGL2: - // void bufferData(GLenum target, [AllowShared] ArrayBufferView srcData, GLenum usage, GLuint srcOffset, - // optional GLuint length = 0); - // void bufferSubData(GLenum target, GLintptr dstByteOffset, [AllowShared] ArrayBufferView srcData, - // GLuint srcOffset, optional GLuint length = 0); + void bufferData(GLenum target, /*[AllowShared]*/ ArrayBufferView srcData, GLenum usage, GLuint srcOffset, + optional GLuint length = 0); + void bufferSubData(GLenum target, GLintptr dstByteOffset, /*[AllowShared]*/ ArrayBufferView srcData, + GLuint srcOffset, optional GLuint length = 0); - // void copyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, - // GLintptr writeOffset, GLsizeiptr size); + void copyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, + GLintptr writeOffset, GLsizeiptr size); // MapBufferRange, in particular its read-only and write-only modes, // can not be exposed safely to JavaScript. GetBufferSubData // replaces it for the purpose of fetching data back from the GPU. - // void getBufferSubData(GLenum target, GLintptr srcByteOffset, [AllowShared] ArrayBufferView dstBuffer, - // optional GLuint dstOffset = 0, optional GLuint length = 0); + void getBufferSubData(GLenum target, GLintptr srcByteOffset, /*[AllowShared]*/ ArrayBufferView dstBuffer, + optional GLuint dstOffset = 0, optional GLuint length = 0); /* Framebuffer objects */ // void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, diff --git a/tests/wpt/webgl/meta/conformance2/buffers/buffer-copying-contents.html.ini b/tests/wpt/webgl/meta/conformance2/buffers/buffer-copying-contents.html.ini deleted file mode 100644 index c525d53ee86..00000000000 --- a/tests/wpt/webgl/meta/conformance2/buffers/buffer-copying-contents.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[buffer-copying-contents.html] - expected: ERROR - [WebGL test #1: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).] - expected: FAIL - diff --git a/tests/wpt/webgl/meta/conformance2/buffers/buffer-copying-restrictions.html.ini b/tests/wpt/webgl/meta/conformance2/buffers/buffer-copying-restrictions.html.ini deleted file mode 100644 index 0e7a8553461..00000000000 --- a/tests/wpt/webgl/meta/conformance2/buffers/buffer-copying-restrictions.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[buffer-copying-restrictions.html] - expected: ERROR diff --git a/tests/wpt/webgl/meta/conformance2/buffers/buffer-data-and-buffer-sub-data-sub-source.html.ini b/tests/wpt/webgl/meta/conformance2/buffers/buffer-data-and-buffer-sub-data-sub-source.html.ini deleted file mode 100644 index 818080cc853..00000000000 --- a/tests/wpt/webgl/meta/conformance2/buffers/buffer-data-and-buffer-sub-data-sub-source.html.ini +++ /dev/null @@ -1,14 +0,0 @@ -[buffer-data-and-buffer-sub-data-sub-source.html] - expected: ERROR - [WebGL test #3: getError expected: INVALID_VALUE. Was NO_ERROR : calling bufferData when srcOffset + length is larger than source size] - expected: FAIL - - [WebGL test #4: getError expected: INVALID_VALUE. Was NO_ERROR : calling bufferData when srcOffset + length is larger than source size] - expected: FAIL - - [WebGL test #5: getError expected: INVALID_VALUE. Was NO_ERROR : calling bufferData when srcOffset + length is larger than source size] - expected: FAIL - - [WebGL test #7: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).] - expected: FAIL - diff --git a/tests/wpt/webgl/meta/conformance2/buffers/get-buffer-sub-data.html.ini b/tests/wpt/webgl/meta/conformance2/buffers/get-buffer-sub-data.html.ini deleted file mode 100644 index 084047aa5aa..00000000000 --- a/tests/wpt/webgl/meta/conformance2/buffers/get-buffer-sub-data.html.ini +++ /dev/null @@ -1,35 +0,0 @@ -[get-buffer-sub-data.html] - expected: ERROR - [WebGL test #2: gl.getBufferSubData(gl.ARRAY_BUFFER, 0, retArray) threw exception TypeError: gl.getBufferSubData is not a function] - expected: FAIL - - [WebGL test #7: The returned array buffer fails to match original data] - expected: FAIL - - [WebGL test #8: gl.getBufferSubData(gl.ARRAY_BUFFER, 0, retArray, 2) threw exception TypeError: gl.getBufferSubData is not a function] - expected: FAIL - - [WebGL test #10: areArraysEqual(retArray.slice(2), floatArray.slice(0, floatArray.length - 2)) should be true. Was false.] - expected: FAIL - - [WebGL test #11: gl.getBufferSubData(gl.ARRAY_BUFFER, 0, retArray, retArray.length) threw exception TypeError: gl.getBufferSubData is not a function] - expected: FAIL - - [WebGL test #13: gl.getBufferSubData(gl.ARRAY_BUFFER, 0, retArray, retArray.length + 1) threw exception TypeError: gl.getBufferSubData is not a function] - expected: FAIL - - [WebGL test #14: gl.getBufferSubData(gl.ARRAY_BUFFER, 0, retArray, 2, 2) threw exception TypeError: gl.getBufferSubData is not a function] - expected: FAIL - - [WebGL test #16: areArraysEqual(retArray.slice(2, 4), floatArray.slice(0, 2)) should be true. Was false.] - expected: FAIL - - [WebGL test #18: gl.getBufferSubData(gl.ARRAY_BUFFER, 0, retArray, retArray.length - 1, 1) threw exception TypeError: gl.getBufferSubData is not a function] - expected: FAIL - - [WebGL test #20: areArraysEqual(retArray.slice(8), floatArray.slice(0, 1)) should be true. Was false.] - expected: FAIL - - [WebGL test #21: gl.getBufferSubData(gl.ARRAY_BUFFER, 0, retArray, retArray.length - 1, 2) threw exception TypeError: gl.getBufferSubData is not a function] - expected: FAIL - diff --git a/tests/wpt/webgl/meta/conformance2/context/methods-2.html.ini b/tests/wpt/webgl/meta/conformance2/context/methods-2.html.ini index 8b7f1e817d9..80e3cd24411 100644 --- a/tests/wpt/webgl/meta/conformance2/context/methods-2.html.ini +++ b/tests/wpt/webgl/meta/conformance2/context/methods-2.html.ini @@ -1,199 +1,193 @@ [methods-2.html] - [WebGL test #46: Property either does not exist or is not a function: bindTransformFeedback] + [WebGL test #32: Property either does not exist or is not a function: vertexAttribI4ui] expected: FAIL - [WebGL test #25: Property either does not exist or is not a function: uniform4uiv] + [WebGL test #30: Property either does not exist or is not a function: vertexAttribI4i] expected: FAIL - [WebGL test #48: Property either does not exist or is not a function: endTransformFeedback] + [WebGL test #28: Property either does not exist or is not a function: uniformMatrix3x4fv] expected: FAIL - [WebGL test #28: Property either does not exist or is not a function: uniformMatrix2x4fv] + [WebGL test #58: Property either does not exist or is not a function: getActiveUniformBlockName] expected: FAIL - [WebGL test #1: Property either does not exist or is not a function: getBufferSubData] + [WebGL test #49: Property either does not exist or is not a function: pauseTransformFeedback] expected: FAIL - [WebGL test #30: Property either does not exist or is not a function: uniformMatrix3x4fv] + [WebGL test #33: Property either does not exist or is not a function: vertexAttribI4uiv] expected: FAIL - [WebGL test #14: Property either does not exist or is not a function: copyTexSubImage3D] + [WebGL test #63: Property either does not exist or is not a function: bindVertexArray] expected: FAIL - [WebGL test #27: Property either does not exist or is not a function: uniformMatrix3x2fv] + [WebGL test #2: Property either does not exist or is not a function: framebufferTextureLayer] expected: FAIL - [WebGL test #53: Property either does not exist or is not a function: bindBufferBase] + [WebGL test #15: Property either does not exist or is not a function: getFragDataLocation] expected: FAIL - [WebGL test #3: Property either does not exist or is not a function: blitFramebuffer] + [WebGL test #60: Property either does not exist or is not a function: createVertexArray] expected: FAIL - [WebGL test #33: Property either does not exist or is not a function: vertexAttribI4iv] + [WebGL test #4: Property either does not exist or is not a function: invalidateFramebuffer] expected: FAIL - [WebGL test #44: Property either does not exist or is not a function: deleteTransformFeedback] + [WebGL test #45: Property either does not exist or is not a function: beginTransformFeedback] expected: FAIL - [WebGL test #51: Property either does not exist or is not a function: pauseTransformFeedback] + [WebGL test #56: Property either does not exist or is not a function: getUniformBlockIndex] expected: FAIL - [WebGL test #49: Property either does not exist or is not a function: transformFeedbackVaryings] + [WebGL test #7: Property either does not exist or is not a function: renderbufferStorageMultisample] expected: FAIL - [WebGL test #2: Property either does not exist or is not a function: copyBufferSubData] + [WebGL test #10: Property either does not exist or is not a function: texStorage3D] expected: FAIL - [WebGL test #23: Property either does not exist or is not a function: uniform2uiv] + [WebGL test #21: Property either does not exist or is not a function: uniform2uiv] expected: FAIL - [WebGL test #55: Property either does not exist or is not a function: getIndexedParameter] + [WebGL test #46: Property either does not exist or is not a function: endTransformFeedback] expected: FAIL - [WebGL test #31: Property either does not exist or is not a function: uniformMatrix4x3fv] + [WebGL test #1: Property either does not exist or is not a function: blitFramebuffer] expected: FAIL - [WebGL test #36: Property either does not exist or is not a function: vertexAttribIPointer] + [WebGL test #55: Property either does not exist or is not a function: getActiveUniforms] expected: FAIL - [WebGL test #8: Property either does not exist or is not a function: readBuffer] + [WebGL test #11: Property either does not exist or is not a function: texSubImage3D] expected: FAIL - [WebGL test #35: Property either does not exist or is not a function: vertexAttribI4uiv] + [WebGL test #48: Property either does not exist or is not a function: getTransformFeedbackVarying] expected: FAIL - [WebGL test #5: Property either does not exist or is not a function: getInternalformatParameter] + [WebGL test #40: Property either does not exist or is not a function: clearBufferfi] expected: FAIL - [WebGL test #60: Property either does not exist or is not a function: getActiveUniformBlockName] + [WebGL test #44: Property either does not exist or is not a function: bindTransformFeedback] expected: FAIL - [WebGL test #47: Property either does not exist or is not a function: beginTransformFeedback] + [WebGL test #50: Property either does not exist or is not a function: resumeTransformFeedback] expected: FAIL - [WebGL test #32: Property either does not exist or is not a function: vertexAttribI4i] + [WebGL test #25: Property either does not exist or is not a function: uniformMatrix3x2fv] expected: FAIL - [WebGL test #43: Property either does not exist or is not a function: createTransformFeedback] + [WebGL test #3: Property either does not exist or is not a function: getInternalformatParameter] expected: FAIL - [WebGL test #59: Property either does not exist or is not a function: getActiveUniformBlockParameter] + [WebGL test #57: Property either does not exist or is not a function: getActiveUniformBlockParameter] expected: FAIL - [WebGL test #41: Property either does not exist or is not a function: clearBufferfv] + [WebGL test #53: Property either does not exist or is not a function: getIndexedParameter] expected: FAIL - [WebGL test #17: Property either does not exist or is not a function: getFragDataLocation] + [WebGL test #61: Property either does not exist or is not a function: deleteVertexArray] expected: FAIL - [WebGL test #15: Property either does not exist or is not a function: compressedTexImage3D] + [WebGL test #13: Property either does not exist or is not a function: compressedTexImage3D] expected: FAIL - [WebGL test #65: Property either does not exist or is not a function: bindVertexArray] + [WebGL test #51: Property either does not exist or is not a function: bindBufferBase] expected: FAIL - [WebGL test #34: Property either does not exist or is not a function: vertexAttribI4ui] + [WebGL test #54: Property either does not exist or is not a function: getUniformIndices] expected: FAIL - [WebGL test #6: Property either does not exist or is not a function: invalidateFramebuffer] + [WebGL test #27: Property either does not exist or is not a function: uniformMatrix4x2fv] expected: FAIL - [WebGL test #62: Property either does not exist or is not a function: createVertexArray] + [WebGL test #34: Property either does not exist or is not a function: vertexAttribIPointer] expected: FAIL - [WebGL test #42: Property either does not exist or is not a function: clearBufferfi] + [WebGL test #16: Property either does not exist or is not a function: uniform1ui] expected: FAIL - [WebGL test #24: Property either does not exist or is not a function: uniform3uiv] + [WebGL test #12: Property either does not exist or is not a function: copyTexSubImage3D] expected: FAIL - [WebGL test #37: Property either does not exist or is not a function: drawRangeElements] + [WebGL test #52: Property either does not exist or is not a function: bindBufferRange] expected: FAIL - [WebGL test #39: Property either does not exist or is not a function: clearBufferiv] + [WebGL test #8: Property either does not exist or is not a function: texImage3D] expected: FAIL - [WebGL test #58: Property either does not exist or is not a function: getUniformBlockIndex] + [WebGL test #18: Property either does not exist or is not a function: uniform3ui] expected: FAIL - [WebGL test #56: Property either does not exist or is not a function: getUniformIndices] + [WebGL test #41: Property either does not exist or is not a function: createTransformFeedback] expected: FAIL - [WebGL test #16: Property either does not exist or is not a function: compressedTexSubImage3D] - expected: FAIL - - [WebGL test #38: Property either does not exist or is not a function: drawBuffers] - expected: FAIL - - [WebGL test #54: Property either does not exist or is not a function: bindBufferRange] + [WebGL test #0: Property either does not exist or is not a function: isContextLost] expected: FAIL - [WebGL test #0: Property either does not exist or is not a function: isContextLost] + [WebGL test #36: Property either does not exist or is not a function: drawBuffers] expected: FAIL - [WebGL test #9: Property either does not exist or is not a function: renderbufferStorageMultisample] + [WebGL test #19: Property either does not exist or is not a function: uniform4ui] expected: FAIL - [WebGL test #45: Property either does not exist or is not a function: isTransformFeedback] + [WebGL test #47: Property either does not exist or is not a function: transformFeedbackVaryings] expected: FAIL - [WebGL test #18: Property either does not exist or is not a function: uniform1ui] + [WebGL test #24: Property either does not exist or is not a function: uniformMatrix2x3fv] expected: FAIL - [WebGL test #7: Property either does not exist or is not a function: invalidateSubFramebuffer] + [WebGL test #9: Property either does not exist or is not a function: texStorage2D] expected: FAIL - [WebGL test #40: Property either does not exist or is not a function: clearBufferuiv] + [WebGL test #29: Property either does not exist or is not a function: uniformMatrix4x3fv] expected: FAIL - [WebGL test #64: Property either does not exist or is not a function: isVertexArray] + [WebGL test #17: Property either does not exist or is not a function: uniform2ui] expected: FAIL - [WebGL test #21: Property either does not exist or is not a function: uniform4ui] + [WebGL test #43: Property either does not exist or is not a function: isTransformFeedback] expected: FAIL - [WebGL test #11: Property either does not exist or is not a function: texStorage2D] + [WebGL test #59: Property either does not exist or is not a function: uniformBlockBinding] expected: FAIL - [WebGL test #19: Property either does not exist or is not a function: uniform2ui] + [WebGL test #31: Property either does not exist or is not a function: vertexAttribI4iv] expected: FAIL - [WebGL test #26: Property either does not exist or is not a function: uniformMatrix2x3fv] + [WebGL test #6: Property either does not exist or is not a function: readBuffer] expected: FAIL - [WebGL test #52: Property either does not exist or is not a function: resumeTransformFeedback] + [WebGL test #38: Property either does not exist or is not a function: clearBufferuiv] expected: FAIL - [WebGL test #29: Property either does not exist or is not a function: uniformMatrix4x2fv] + [WebGL test #23: Property either does not exist or is not a function: uniform4uiv] expected: FAIL - [WebGL test #57: Property either does not exist or is not a function: getActiveUniforms] + [WebGL test #39: Property either does not exist or is not a function: clearBufferfv] expected: FAIL - [WebGL test #20: Property either does not exist or is not a function: uniform3ui] + [WebGL test #35: Property either does not exist or is not a function: drawRangeElements] expected: FAIL - [WebGL test #22: Property either does not exist or is not a function: uniform1uiv] + [WebGL test #22: Property either does not exist or is not a function: uniform3uiv] expected: FAIL - [WebGL test #4: Property either does not exist or is not a function: framebufferTextureLayer] + [WebGL test #5: Property either does not exist or is not a function: invalidateSubFramebuffer] expected: FAIL - [WebGL test #61: Property either does not exist or is not a function: uniformBlockBinding] + [WebGL test #26: Property either does not exist or is not a function: uniformMatrix2x4fv] expected: FAIL - [WebGL test #50: Property either does not exist or is not a function: getTransformFeedbackVarying] + [WebGL test #14: Property either does not exist or is not a function: compressedTexSubImage3D] expected: FAIL - [WebGL test #12: Property either does not exist or is not a function: texStorage3D] + [WebGL test #62: Property either does not exist or is not a function: isVertexArray] expected: FAIL - [WebGL test #63: Property either does not exist or is not a function: deleteVertexArray] + [WebGL test #37: Property either does not exist or is not a function: clearBufferiv] expected: FAIL - [WebGL test #10: Property either does not exist or is not a function: texImage3D] + [WebGL test #20: Property either does not exist or is not a function: uniform1uiv] expected: FAIL - [WebGL test #13: Property either does not exist or is not a function: texSubImage3D] + [WebGL test #42: Property either does not exist or is not a function: deleteTransformFeedback] expected: FAIL diff --git a/tests/wpt/webgl/meta/conformance2/reading/read-pixels-into-pixel-pack-buffer.html.ini b/tests/wpt/webgl/meta/conformance2/reading/read-pixels-into-pixel-pack-buffer.html.ini index c377ab9aef6..252d5de861f 100644 --- a/tests/wpt/webgl/meta/conformance2/reading/read-pixels-into-pixel-pack-buffer.html.ini +++ b/tests/wpt/webgl/meta/conformance2/reading/read-pixels-into-pixel-pack-buffer.html.ini @@ -1,5 +1,5 @@ [read-pixels-into-pixel-pack-buffer.html] - expected: ERROR + expected: CRASH [WebGL test #1: getError expected: INVALID_OPERATION. Was INVALID_ENUM : should generate INVALID_OPERATION if pixel pack buffer is bound] expected: FAIL diff --git a/tests/wpt/webgl/meta/conformance2/rendering/out-of-bounds-index-buffers-after-copying.html.ini b/tests/wpt/webgl/meta/conformance2/rendering/out-of-bounds-index-buffers-after-copying.html.ini index 54b959f341a..08500022f57 100644 --- a/tests/wpt/webgl/meta/conformance2/rendering/out-of-bounds-index-buffers-after-copying.html.ini +++ b/tests/wpt/webgl/meta/conformance2/rendering/out-of-bounds-index-buffers-after-copying.html.ini @@ -1,5 +1,10 @@ [out-of-bounds-index-buffers-after-copying.html] - expected: ERROR [WebGL test #4: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).] expected: FAIL + [WebGL test #9: should be 0,255,0,255\nat (0, 0) expected: 0,255,0,255 was 0,0,255,255] + expected: FAIL + + [WebGL test #6: should be 0,255,0,255\nat (0, 0) expected: 0,255,0,255 was 0,0,255,255] + expected: FAIL + |