diff --git a/Cargo.lock b/Cargo.lock index f94aed2aa5d..26c8c4db824 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4883,9 +4883,9 @@ dependencies = [ [[package]] name = "sparkle" -version = "0.1.8" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25e193f97790240fc9208b077001c8331f4ccc801daa4df56efcb90e513c0989" +checksum = "84b935631ddcc08b257a331ac645cc6831e52a4ff55d4c430142575c6757a094" dependencies = [ "gl_generator 0.13.1", ] diff --git a/components/canvas/webgl_limits.rs b/components/canvas/webgl_limits.rs index 23630117515..0add74b3082 100644 --- a/components/canvas/webgl_limits.rs +++ b/components/canvas/webgl_limits.rs @@ -20,6 +20,8 @@ impl GLLimitsDetect for GLLimits { let max_renderbuffer_size = gl.get_integer(gl::MAX_RENDERBUFFER_SIZE); let max_texture_image_units = gl.get_integer(gl::MAX_TEXTURE_IMAGE_UNITS); let max_vertex_texture_image_units = gl.get_integer(gl::MAX_VERTEX_TEXTURE_IMAGE_UNITS); + let max_transform_feedback_separate_attribs = + gl.get_integer(gl::MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS); // TODO: better value for this? let max_client_wait_timeout_webgl = std::time::Duration::new(1, 0); @@ -67,6 +69,7 @@ impl GLLimitsDetect for GLLimits { max_vertex_texture_image_units, max_vertex_uniform_vectors, max_client_wait_timeout_webgl, + max_transform_feedback_separate_attribs, } } } diff --git a/components/canvas/webgl_thread.rs b/components/canvas/webgl_thread.rs index b36df1c1b13..7cf1464f372 100644 --- a/components/canvas/webgl_thread.rs +++ b/components/canvas/webgl_thread.rs @@ -1180,6 +1180,41 @@ impl WebGLImpl { WebGLCommand::GetRenderbufferParameter(target, pname, ref chan) => { Self::get_renderbuffer_parameter(gl, target, pname, chan) }, + WebGLCommand::CreateTransformFeedback(ref sender) => { + let value = gl.gen_transform_feedbacks(); + sender.send(value).unwrap() + }, + WebGLCommand::DeleteTransformFeedback(id) => { + gl.delete_transform_feedbacks(id); + }, + WebGLCommand::IsTransformFeedback(id, ref sender) => { + let value = gl.is_transform_feedback(id); + sender.send(value).unwrap() + }, + WebGLCommand::BindTransformFeedback(target, id) => { + gl.bind_transform_feedback(target, id); + }, + WebGLCommand::BeginTransformFeedback(mode) => { + gl.begin_transform_feedback(mode); + }, + WebGLCommand::EndTransformFeedback() => { + gl.end_transform_feedback(); + }, + WebGLCommand::PauseTransformFeedback() => { + gl.pause_transform_feedback(); + }, + WebGLCommand::ResumeTransformFeedback() => { + gl.resume_transform_feedback(); + }, + WebGLCommand::GetTransformFeedbackVarying(program, index, ref sender) => { + let (size, ty, mut name) = gl.get_transform_feedback_varying(program.get(), index); + // We need to split, because the name starts with '_u' prefix. + name = name.split_off(2); + sender.send((size, ty, name)).unwrap(); + }, + WebGLCommand::TransformFeedbackVaryings(program, ref varyings, buffer_mode) => { + gl.transform_feedback_varyings(program.get(), varyings.as_slice(), buffer_mode); + }, WebGLCommand::GetFramebufferAttachmentParameter( target, attachment, @@ -1814,9 +1849,10 @@ impl WebGLImpl { linked: false, active_attribs: vec![].into(), active_uniforms: vec![].into(), + transform_feedback_length: Default::default(), + transform_feedback_mode: Default::default(), }; } - let mut num_active_attribs = [0]; unsafe { gl.get_program_iv( @@ -1868,11 +1904,28 @@ impl WebGLImpl { }) .collect::>() .into(); - + let mut transform_feedback_length = [0]; + unsafe { + gl.get_program_iv( + program.get(), + gl::TRANSFORM_FEEDBACK_VARYINGS, + &mut transform_feedback_length, + ); + } + let mut transform_feedback_mode = [0]; + unsafe { + gl.get_program_iv( + program.get(), + gl::TRANSFORM_FEEDBACK_BUFFER_MODE, + &mut transform_feedback_mode, + ); + } ProgramLinkInfo { linked: true, active_attribs, active_uniforms, + transform_feedback_length: transform_feedback_length[0], + transform_feedback_mode: transform_feedback_mode[0], } } diff --git a/components/canvas_traits/webgl.rs b/components/canvas_traits/webgl.rs index 70986d78b6d..bb600ba2291 100644 --- a/components/canvas_traits/webgl.rs +++ b/components/canvas_traits/webgl.rs @@ -292,6 +292,16 @@ pub enum WebGLCommand { GetProgramInfoLog(WebGLProgramId, WebGLSender), GetFramebufferAttachmentParameter(u32, u32, u32, WebGLSender), GetRenderbufferParameter(u32, u32, WebGLSender), + CreateTransformFeedback(WebGLSender), + DeleteTransformFeedback(u32), + IsTransformFeedback(u32, WebGLSender), + BindTransformFeedback(u32, u32), + BeginTransformFeedback(u32), + EndTransformFeedback(), + PauseTransformFeedback(), + ResumeTransformFeedback(), + GetTransformFeedbackVarying(WebGLProgramId, u32, WebGLSender<(i32, u32, String)>), + TransformFeedbackVaryings(WebGLProgramId, Vec, u32), PolygonOffset(f32, f32), RenderbufferStorage(u32, u32, i32, i32), ReadPixels(Rect, u32, u32, IpcBytesSender), @@ -660,6 +670,10 @@ pub struct ProgramLinkInfo { pub active_attribs: Box<[ActiveAttribInfo]>, /// The list of active uniforms. pub active_uniforms: Box<[ActiveUniformInfo]>, + /// The number of varying variables + pub transform_feedback_length: i32, + /// The buffer mode used when transform feedback is active + pub transform_feedback_mode: i32, } /// Description of a single active attribute. @@ -733,6 +747,8 @@ parameters! { Bool(ParameterBool { DepthWritemask = gl::DEPTH_WRITEMASK, SampleCoverageInvert = gl::SAMPLE_COVERAGE_INVERT, + TransformFeedbackActive = gl::TRANSFORM_FEEDBACK_ACTIVE, + TransformFeedbackPaused = gl::TRANSFORM_FEEDBACK_PAUSED, }), Bool4(ParameterBool4 { ColorWritemask = gl::COLOR_WRITEMASK, @@ -774,6 +790,12 @@ parameters! { StencilValueMask = gl::STENCIL_VALUE_MASK, StencilWritemask = gl::STENCIL_WRITEMASK, SubpixelBits = gl::SUBPIXEL_BITS, + TransformFeedbackBinding = gl::TRANSFORM_FEEDBACK_BINDING, + MaxTransformFeedbackInterleavedComponents = gl::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, + MaxTransformFeedbackSeparateAttribs = gl::MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, + MaxTransformFeedbackSeparateComponents = gl::MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, + TransformFeedbackBufferSize = gl::TRANSFORM_FEEDBACK_BUFFER_SIZE, + TransformFeedbackBufferStart = gl::TRANSFORM_FEEDBACK_BUFFER_START, }), Int2(ParameterInt2 { MaxViewportDims = gl::MAX_VIEWPORT_DIMS, @@ -968,4 +990,5 @@ pub struct GLLimits { pub max_vertex_texture_image_units: u32, pub max_vertex_uniform_vectors: u32, pub max_client_wait_timeout_webgl: std::time::Duration, + pub max_transform_feedback_separate_attribs: u32, } diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index 302ae5baad4..16d2c6fb686 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -532,6 +532,7 @@ pub mod webglshader; pub mod webglshaderprecisionformat; pub mod webglsync; pub mod webgltexture; +pub mod webgltransformfeedback; pub mod webgluniformlocation; pub mod webglvertexarrayobjectoes; pub mod websocket; diff --git a/components/script/dom/webgl2renderingcontext.rs b/components/script/dom/webgl2renderingcontext.rs index beff6ec6bfd..d9a3e81b46a 100644 --- a/components/script/dom/webgl2renderingcontext.rs +++ b/components/script/dom/webgl2renderingcontext.rs @@ -11,8 +11,8 @@ use crate::dom::bindings::codegen::UnionTypes::ArrayBufferViewOrArrayBuffer; use crate::dom::bindings::codegen::UnionTypes::Float32ArrayOrUnrestrictedFloatSequence; use crate::dom::bindings::codegen::UnionTypes::ImageDataOrHTMLImageElementOrHTMLCanvasElementOrHTMLVideoElement; use crate::dom::bindings::codegen::UnionTypes::Int32ArrayOrLongSequence; -use crate::dom::bindings::conversions::ToJSValConvertible; use crate::dom::bindings::error::{ErrorResult, Fallible}; +use crate::dom::bindings::reflector::DomObject; use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; use crate::dom::bindings::root::{Dom, DomRoot, LayoutDom, MutNullableDom}; use crate::dom::bindings::str::DOMString; @@ -32,8 +32,10 @@ use crate::dom::webglshader::WebGLShader; use crate::dom::webglshaderprecisionformat::WebGLShaderPrecisionFormat; use crate::dom::webglsync::WebGLSync; use crate::dom::webgltexture::WebGLTexture; +use crate::dom::webgltransformfeedback::WebGLTransformFeedback; use crate::dom::webgluniformlocation::WebGLUniformLocation; use crate::dom::window::Window; +use crate::js::conversions::ToJSValConvertible; use crate::script_runtime::JSContext; use canvas_traits::webgl::WebGLError::*; use canvas_traits::webgl::{ @@ -62,6 +64,7 @@ pub struct WebGL2RenderingContext { bound_pixel_unpack_buffer: MutNullableDom, bound_transform_feedback_buffer: MutNullableDom, bound_uniform_buffer: MutNullableDom, + current_transform_feedback: MutNullableDom, } fn typedarray_elem_size(typeid: Type) -> usize { @@ -100,6 +103,7 @@ impl WebGL2RenderingContext { bound_pixel_unpack_buffer: MutNullableDom::new(None), bound_transform_feedback_buffer: MutNullableDom::new(None), bound_uniform_buffer: MutNullableDom::new(None), + current_transform_feedback: MutNullableDom::new(None), }) } @@ -210,6 +214,9 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { constants::UNIFORM_BUFFER_BINDING => unsafe { optional_root_object_to_js_or_null!(*cx, &self.bound_uniform_buffer.get()) }, + constants::TRANSFORM_FEEDBACK_BINDING => unsafe { + optional_root_object_to_js_or_null!(*cx, self.current_transform_feedback.get()) + }, _ => self.base.GetParameter(cx, parameter), } } @@ -824,7 +831,24 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 fn GetProgramParameter(&self, cx: JSContext, program: &WebGLProgram, param_id: u32) -> JSVal { - self.base.GetProgramParameter(cx, program, param_id) + handle_potential_webgl_error!( + self.base, + self.base.validate_ownership(program), + return NullValue() + ); + if program.is_deleted() { + self.base.webgl_error(InvalidOperation); + return NullValue(); + } + match param_id { + constants::TRANSFORM_FEEDBACK_VARYINGS => { + Int32Value(program.transform_feedback_varyings_length()) + }, + constants::TRANSFORM_FEEDBACK_BUFFER_MODE => { + Int32Value(program.transform_feedback_buffer_mode()) + }, + _ => self.base.GetProgramParameter(cx, program, param_id), + } } /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 @@ -1721,6 +1745,212 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { }, } } + + /// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.15 + fn CreateTransformFeedback(&self) -> Option> { + Some(WebGLTransformFeedback::new(&self.base)) + } + + /// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.15 + fn DeleteTransformFeedback(&self, tf: Option<&WebGLTransformFeedback>) { + if let Some(tf) = tf { + handle_potential_webgl_error!(self.base, self.base.validate_ownership(tf), return); + if tf.is_active() { + self.base.webgl_error(InvalidOperation); + return; + } + tf.delete(false); + self.current_transform_feedback.set(None); + } + } + + /// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.15 + fn IsTransformFeedback(&self, tf: Option<&WebGLTransformFeedback>) -> bool { + match tf { + Some(tf) => { + if !tf.is_valid() { + return false; + } + handle_potential_webgl_error!( + self.base, + self.base.validate_ownership(tf), + return false + ); + let (sender, receiver) = webgl_channel().unwrap(); + self.base + .send_command(WebGLCommand::IsTransformFeedback(tf.id(), sender)); + receiver.recv().unwrap() + }, + None => false, + } + } + + /// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.15 + fn BindTransformFeedback(&self, target: u32, tf: Option<&WebGLTransformFeedback>) { + if target != constants::TRANSFORM_FEEDBACK { + self.base.webgl_error(InvalidEnum); + return; + } + match tf { + Some(transform_feedback) => { + handle_potential_webgl_error!( + self.base, + self.base.validate_ownership(transform_feedback), + return + ); + if !transform_feedback.is_valid() { + self.base.webgl_error(InvalidOperation); + return; + } + if let Some(current_tf) = self.current_transform_feedback.get() { + if current_tf.is_active() && !current_tf.is_paused() { + self.base.webgl_error(InvalidOperation); + return; + } + } + transform_feedback.bind(&self.base, target); + self.current_transform_feedback + .set(Some(transform_feedback)); + }, + None => self + .base + .send_command(WebGLCommand::BindTransformFeedback(target, 0)), + } + } + + /// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.15 + fn BeginTransformFeedback(&self, primitiveMode: u32) { + match primitiveMode { + constants::POINTS | constants::LINES | constants::TRIANGLES => {}, + _ => { + self.base.webgl_error(InvalidEnum); + return; + }, + }; + let current_tf = match self.current_transform_feedback.get() { + Some(current_tf) => current_tf, + None => { + self.base.webgl_error(InvalidOperation); + return; + }, + }; + if current_tf.is_active() { + self.base.webgl_error(InvalidOperation); + return; + }; + let program = match self.base.current_program() { + Some(program) => program, + None => { + self.base.webgl_error(InvalidOperation); + return; + }, + }; + if !program.is_linked() || program.transform_feedback_varyings_length() != 0 { + self.base.webgl_error(InvalidOperation); + return; + }; + current_tf.begin(&self.base, primitiveMode); + } + + /// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.15 + fn EndTransformFeedback(&self) { + if let Some(current_tf) = self.current_transform_feedback.get() { + if !current_tf.is_active() { + self.base.webgl_error(InvalidOperation); + return; + } + current_tf.end(&self.base); + } + } + + /// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.15 + fn ResumeTransformFeedback(&self) { + if let Some(current_tf) = self.current_transform_feedback.get() { + if !current_tf.is_active() || !current_tf.is_paused() { + self.base.webgl_error(InvalidOperation); + return; + } + current_tf.resume(&self.base); + } + } + + /// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.15 + fn PauseTransformFeedback(&self) { + if let Some(current_tf) = self.current_transform_feedback.get() { + if !current_tf.is_active() || current_tf.is_paused() { + self.base.webgl_error(InvalidOperation); + return; + } + current_tf.pause(&self.base); + } + } + + /// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.15 + fn TransformFeedbackVaryings( + &self, + program: &WebGLProgram, + varyings: Vec, + bufferMode: u32, + ) { + handle_potential_webgl_error!(self.base, program.validate(), return); + let strs = varyings + .iter() + .map(|name| String::from(name.to_owned())) + .collect::>(); + match bufferMode { + constants::INTERLEAVED_ATTRIBS => { + self.base + .send_command(WebGLCommand::TransformFeedbackVaryings( + program.id(), + strs, + bufferMode, + )); + }, + constants::SEPARATE_ATTRIBS => { + let max_tf_sp_att = + self.base.limits().max_transform_feedback_separate_attribs as usize; + if strs.len() >= max_tf_sp_att { + self.base.webgl_error(InvalidValue); + return; + } + self.base + .send_command(WebGLCommand::TransformFeedbackVaryings( + program.id(), + strs, + bufferMode, + )); + }, + _ => self.base.webgl_error(InvalidEnum), + } + } + + /// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.15 + fn GetTransformFeedbackVarying( + &self, + program: &WebGLProgram, + index: u32, + ) -> Option> { + handle_potential_webgl_error!(self.base, program.validate(), return None); + if index >= program.transform_feedback_varyings_length() as u32 { + self.base.webgl_error(InvalidValue); + return None; + } + + let (sender, receiver) = webgl_channel().unwrap(); + self.base + .send_command(WebGLCommand::GetTransformFeedbackVarying( + program.id(), + index, + sender, + )); + let (size, ty, name) = receiver.recv().unwrap(); + Some(WebGLActiveInfo::new( + self.base.global().as_window(), + size, + ty, + DOMString::from(name), + )) + } } impl LayoutCanvasWebGLRenderingContextHelpers for LayoutDom { diff --git a/components/script/dom/webglprogram.rs b/components/script/dom/webglprogram.rs index 6863bc89e53..e4f5f89c6d3 100644 --- a/components/script/dom/webglprogram.rs +++ b/components/script/dom/webglprogram.rs @@ -34,6 +34,8 @@ pub struct WebGLProgram { vertex_shader: MutNullableDom, active_attribs: DomRefCell>, active_uniforms: DomRefCell>, + transform_feedback_varyings_length: Cell, + transform_feedback_mode: Cell, } impl WebGLProgram { @@ -50,6 +52,8 @@ impl WebGLProgram { vertex_shader: Default::default(), active_attribs: DomRefCell::new(vec![].into()), active_uniforms: DomRefCell::new(vec![].into()), + transform_feedback_varyings_length: Default::default(), + transform_feedback_mode: Default::default(), } } @@ -187,6 +191,10 @@ impl WebGLProgram { self.linked.set(link_info.linked); self.link_called.set(true); + self.transform_feedback_varyings_length + .set(link_info.transform_feedback_length); + self.transform_feedback_mode + .set(link_info.transform_feedback_mode); *self.active_attribs.borrow_mut() = link_info.active_attribs; *self.active_uniforms.borrow_mut() = link_info.active_uniforms; Ok(()) @@ -444,6 +452,14 @@ impl WebGLProgram { pub fn link_generation(&self) -> u64 { self.link_generation.get() } + + pub fn transform_feedback_varyings_length(&self) -> i32 { + self.transform_feedback_varyings_length.get() + } + + pub fn transform_feedback_buffer_mode(&self) -> i32 { + self.transform_feedback_mode.get() + } } impl Drop for WebGLProgram { diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index f0e4887858c..228ccd491b9 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -1165,6 +1165,10 @@ impl WebGLRenderingContext { slot.set(buffer); } + + pub fn current_program(&self) -> Option> { + self.current_program.get() + } } #[cfg(not(feature = "webgl_backtrace"))] diff --git a/components/script/dom/webgltransformfeedback.rs b/components/script/dom/webgltransformfeedback.rs new file mode 100644 index 00000000000..a58a8e43577 --- /dev/null +++ b/components/script/dom/webgltransformfeedback.rs @@ -0,0 +1,133 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +use crate::dom::bindings::codegen::Bindings::WebGLTransformFeedbackBinding; +use crate::dom::bindings::inheritance::Castable; +use crate::dom::bindings::reflector::{reflect_dom_object, DomObject}; +use crate::dom::bindings::root::DomRoot; +use crate::dom::webglobject::WebGLObject; +use crate::dom::webglrenderingcontext::WebGLRenderingContext; +use canvas_traits::webgl::{webgl_channel, WebGLCommand}; +use dom_struct::dom_struct; +use std::cell::Cell; + +#[dom_struct] +pub struct WebGLTransformFeedback { + webgl_object: WebGLObject, + id: u32, + marked_for_deletion: Cell, + has_been_bound: Cell, + is_active: Cell, + is_paused: Cell, +} + +impl WebGLTransformFeedback { + fn new_inherited(context: &WebGLRenderingContext, id: u32) -> Self { + Self { + webgl_object: WebGLObject::new_inherited(context), + id, + marked_for_deletion: Cell::new(false), + has_been_bound: Cell::new(false), + is_active: Cell::new(false), + is_paused: Cell::new(false), + } + } + + pub fn new(context: &WebGLRenderingContext) -> DomRoot { + let (sender, receiver) = webgl_channel().unwrap(); + context.send_command(WebGLCommand::CreateTransformFeedback(sender)); + let id = receiver.recv().unwrap(); + + reflect_dom_object( + Box::new(WebGLTransformFeedback::new_inherited(context, id)), + &*context.global(), + WebGLTransformFeedbackBinding::Wrap, + ) + } +} + +impl WebGLTransformFeedback { + pub fn bind(&self, context: &WebGLRenderingContext, target: u32) { + context.send_command(WebGLCommand::BindTransformFeedback(target, self.id())); + self.has_been_bound.set(true); + } + + pub fn begin(&self, context: &WebGLRenderingContext, primitive_mode: u32) { + if self.has_been_bound.get() && !self.is_active() { + context.send_command(WebGLCommand::BeginTransformFeedback(primitive_mode)); + self.set_active(true); + } + } + + pub fn end(&self, context: &WebGLRenderingContext) { + if self.has_been_bound.get() && self.is_active() { + if self.is_paused() { + context.send_command(WebGLCommand::ResumeTransformFeedback()); + } + context.send_command(WebGLCommand::EndTransformFeedback()); + self.set_active(false); + } + } + + pub fn resume(&self, context: &WebGLRenderingContext) { + if self.is_active() && self.is_paused() { + context.send_command(WebGLCommand::ResumeTransformFeedback()); + self.set_pause(false); + } + } + + pub fn pause(&self, context: &WebGLRenderingContext) { + if self.is_active() && !self.is_paused() { + context.send_command(WebGLCommand::PauseTransformFeedback()); + self.set_pause(true); + } + } + + pub fn id(&self) -> u32 { + self.id + } + + pub fn is_valid(&self) -> bool { + !self.marked_for_deletion.get() + } + + pub fn is_active(&self) -> bool { + self.is_active.get() + } + + pub fn is_paused(&self) -> bool { + self.is_paused.get() + } + + pub fn delete(&self, fallible: bool) { + if self.is_valid() && self.id() != 0 { + self.marked_for_deletion.set(true); + let context = self.upcast::().context(); + let cmd = WebGLCommand::DeleteTransformFeedback(self.id); + if fallible { + context.send_command_ignored(cmd); + } else { + context.send_command(cmd); + } + } + } + + pub fn set_active(&self, value: bool) { + if self.is_valid() && self.has_been_bound.get() { + self.is_active.set(value); + } + } + + pub fn set_pause(&self, value: bool) { + if self.is_valid() && self.is_active() { + self.is_active.set(value); + } + } +} + +impl Drop for WebGLTransformFeedback { + fn drop(&mut self) { + self.delete(true); + } +} diff --git a/components/script/dom/webidls/WebGL2RenderingContext.webidl b/components/script/dom/webidls/WebGL2RenderingContext.webidl index c171a9bb866..312c7b78211 100644 --- a/components/script/dom/webidls/WebGL2RenderingContext.webidl +++ b/components/script/dom/webidls/WebGL2RenderingContext.webidl @@ -12,9 +12,6 @@ typedef long long GLint64; typedef unsigned long long GLuint64; -// interface WebGLTransformFeedback : WebGLObject { -// }; - // interface WebGLVertexArrayObject : WebGLObject { // }; @@ -544,7 +541,7 @@ interface mixin WebGL2RenderingContextBase any getSyncParameter(WebGLSync sync, GLenum pname); /* Transform Feedback */ - /*WebGLTransformFeedback? createTransformFeedback(); + WebGLTransformFeedback? createTransformFeedback(); void deleteTransformFeedback(WebGLTransformFeedback? tf); [WebGLHandlesContextLoss] GLboolean isTransformFeedback(WebGLTransformFeedback? tf); void bindTransformFeedback (GLenum target, WebGLTransformFeedback? tf); @@ -553,7 +550,7 @@ interface mixin WebGL2RenderingContextBase void transformFeedbackVaryings(WebGLProgram program, sequence varyings, GLenum bufferMode); WebGLActiveInfo? getTransformFeedbackVarying(WebGLProgram program, GLuint index); void pauseTransformFeedback(); - void resumeTransformFeedback();*/ + void resumeTransformFeedback(); /* Uniform Buffer Objects and Transform Feedback Buffers */ // void bindBufferBase(GLenum target, GLuint index, WebGLBuffer? buffer); diff --git a/components/script/dom/webidls/WebGLTransformFeedback.webidl b/components/script/dom/webidls/WebGLTransformFeedback.webidl new file mode 100644 index 00000000000..871c0f15c7b --- /dev/null +++ b/components/script/dom/webidls/WebGLTransformFeedback.webidl @@ -0,0 +1,11 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +// +// WebGL IDL definitions scraped from the Khronos specification: +// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.15 +// + +[Exposed=(Window), Pref="dom.webgl2.enabled"] +interface WebGLTransformFeedback : WebGLObject { +}; diff --git a/tests/wpt/webgl/meta/conformance2/buffers/get-buffer-sub-data-validity.html.ini b/tests/wpt/webgl/meta/conformance2/buffers/get-buffer-sub-data-validity.html.ini index f257d44ffa7..4f076695b88 100644 --- a/tests/wpt/webgl/meta/conformance2/buffers/get-buffer-sub-data-validity.html.ini +++ b/tests/wpt/webgl/meta/conformance2/buffers/get-buffer-sub-data-validity.html.ini @@ -1,2 +1,50 @@ [get-buffer-sub-data-validity.html] expected: ERROR + [WebGL test #9: areArraysEqual(dest, srcData) should be true. Was false.] + expected: FAIL + + [Overall test] + expected: NOTRUN + + [WebGL test #7: areArraysEqual(dest, srcData) should be true. Was false.] + expected: FAIL + + [WebGL test #6: getError expected: NO_ERROR. Was INVALID_VALUE : after evaluating: gl.getBufferSubData(gl.COPY_WRITE_BUFFER, 0, dest)] + expected: FAIL + + [WebGL test #2: getError expected: NO_ERROR. Was INVALID_VALUE : after evaluating: gl.getBufferSubData(gl.COPY_WRITE_BUFFER, 0, dest)] + expected: FAIL + + [WebGL test #12: getError expected: NO_ERROR. Was INVALID_VALUE : after evaluating: gl.getBufferSubData(gl.COPY_WRITE_BUFFER, 0, dest)] + expected: FAIL + + [WebGL test #10: getError expected: NO_ERROR. Was INVALID_VALUE : after evaluating: gl.getBufferSubData(gl.COPY_WRITE_BUFFER, 0, dest)] + expected: FAIL + + [WebGL test #14: getError expected: NO_ERROR. Was INVALID_VALUE : after evaluating: gl.getBufferSubData(gl.COPY_WRITE_BUFFER, 0, dest)] + expected: FAIL + + [WebGL test #4: getError expected: NO_ERROR. Was INVALID_VALUE : after evaluating: gl.getBufferSubData(gl.COPY_WRITE_BUFFER, 0, dest)] + expected: FAIL + + [WebGL test #13: areArraysEqual(dest, srcData) should be true. Was false.] + expected: FAIL + + [WebGL test #15: areArraysEqual(dest, srcData) should be true. Was false.] + expected: FAIL + + [WebGL test #8: getError expected: NO_ERROR. Was INVALID_VALUE : after evaluating: gl.getBufferSubData(gl.COPY_WRITE_BUFFER, 0, dest)] + expected: FAIL + + [WebGL test #5: areArraysEqual(dest, srcData) should be true. Was false.] + expected: FAIL + + [WebGL test #0: getError expected: NO_ERROR. Was INVALID_ENUM : linking transform feedback shader should not set an error] + expected: FAIL + + [WebGL test #3: areArraysEqual(dest, srcData) should be true. Was false.] + expected: FAIL + + [WebGL test #11: areArraysEqual(dest, srcData) should be true. Was false.] + 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 80e3cd24411..dd8863b8024 100644 --- a/tests/wpt/webgl/meta/conformance2/context/methods-2.html.ini +++ b/tests/wpt/webgl/meta/conformance2/context/methods-2.html.ini @@ -191,3 +191,42 @@ [WebGL test #42: Property either does not exist or is not a function: deleteTransformFeedback] expected: FAIL + [WebGL test #41: Property either does not exist or is not a function: bindBufferBase] + expected: FAIL + + [WebGL test #51: Property either does not exist or is not a function: deleteVertexArray] + expected: FAIL + + [WebGL test #50: Property either does not exist or is not a function: createVertexArray] + expected: FAIL + + [WebGL test #42: Property either does not exist or is not a function: bindBufferRange] + expected: FAIL + + [WebGL test #53: Property either does not exist or is not a function: bindVertexArray] + expected: FAIL + + [WebGL test #48: Property either does not exist or is not a function: getActiveUniformBlockName] + expected: FAIL + + [WebGL test #52: Property either does not exist or is not a function: isVertexArray] + expected: FAIL + + [WebGL test #46: 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: uniformBlockBinding] + expected: FAIL + + [WebGL test #44: Property either does not exist or is not a function: getUniformIndices] + expected: FAIL + + [WebGL test #47: Property either does not exist or is not a function: getActiveUniformBlockParameter] + expected: FAIL + + [WebGL test #43: Property either does not exist or is not a function: getIndexedParameter] + expected: FAIL + + [WebGL test #45: Property either does not exist or is not a function: getActiveUniforms] + expected: FAIL + diff --git a/tests/wpt/webgl/meta/conformance2/misc/expando-loss-2.html.ini b/tests/wpt/webgl/meta/conformance2/misc/expando-loss-2.html.ini index 26b0934e151..b1b0bd0c2f7 100644 --- a/tests/wpt/webgl/meta/conformance2/misc/expando-loss-2.html.ini +++ b/tests/wpt/webgl/meta/conformance2/misc/expando-loss-2.html.ini @@ -3,3 +3,6 @@ [WebGL test #5: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).] expected: FAIL + [WebGL test #10: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).] + expected: FAIL + diff --git a/tests/wpt/webgl/meta/conformance2/state/gl-object-get-calls.html.ini b/tests/wpt/webgl/meta/conformance2/state/gl-object-get-calls.html.ini index de7464b81dd..595cbd1ecef 100644 --- a/tests/wpt/webgl/meta/conformance2/state/gl-object-get-calls.html.ini +++ b/tests/wpt/webgl/meta/conformance2/state/gl-object-get-calls.html.ini @@ -105,6 +105,18 @@ [WebGL test #106: getFramebufferAttachmentParameter did not generate INVALID_ENUM for invalid attachment enum: NO_ERROR] expected: FAIL - [WebGL test #121: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).] + [WebGL test #131: gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_DEPTH_SIZE) should be non-zero. Was 0] + expected: FAIL + + [WebGL test #128: gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_WIDTH) should be 2. Was 0.] + expected: FAIL + + [WebGL test #129: gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_HEIGHT) should be 2. Was 0.] + expected: FAIL + + [WebGL test #123: gl.getProgramParameter(uniformBlockProgram, gl.ACTIVE_UNIFORM_BLOCKS) should be 1 (of type number). Was null (of type object).] + expected: FAIL + + [WebGL test #138: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).] expected: FAIL diff --git a/tests/wpt/webgl/meta/conformance2/transform_feedback/non-existent-varying.html.ini b/tests/wpt/webgl/meta/conformance2/transform_feedback/non-existent-varying.html.ini deleted file mode 100644 index 01d3af8a6fe..00000000000 --- a/tests/wpt/webgl/meta/conformance2/transform_feedback/non-existent-varying.html.ini +++ /dev/null @@ -1,5 +0,0 @@ -[non-existent-varying.html] - expected: ERROR - [WebGL test #0: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).] - expected: FAIL - diff --git a/tests/wpt/webgl/meta/conformance2/transform_feedback/unwritten-output-defaults-to-zero.html.ini b/tests/wpt/webgl/meta/conformance2/transform_feedback/unwritten-output-defaults-to-zero.html.ini index 8b0e61b2cd4..5d7bbab8d4c 100644 --- a/tests/wpt/webgl/meta/conformance2/transform_feedback/unwritten-output-defaults-to-zero.html.ini +++ b/tests/wpt/webgl/meta/conformance2/transform_feedback/unwritten-output-defaults-to-zero.html.ini @@ -9,3 +9,6 @@ [WebGL test #1: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).] expected: FAIL + [WebGL test #2: successfullyParsed should be true (of type boolean). Was undefined (of type undefined).] + expected: FAIL +