diff --git a/components/canvas_traits/webgl.rs b/components/canvas_traits/webgl.rs index 007f381354d..d0abdef5cc4 100644 --- a/components/canvas_traits/webgl.rs +++ b/components/canvas_traits/webgl.rs @@ -276,8 +276,8 @@ pub enum WebGLCommand { GetCurrentVertexAttrib(u32, WebGLSender<[f32; 4]>), GetTexParameterFloat(u32, TexParameterFloat, WebGLSender), GetTexParameterInt(u32, TexParameterInt, WebGLSender), - TexParameteri(u32, TexParameterInt, i32), - TexParameterf(u32, TexParameterFloat, f32), + TexParameteri(u32, u32, i32), + TexParameterf(u32, u32, f32), DrawArraysInstanced { mode: u32, first: i32, count: i32, primcount: i32 }, DrawElementsInstanced { mode: u32, count: i32, type_: u32, offset: u32, primcount: i32 }, VertexAttribDivisor { index: u32, divisor: u32 }, @@ -587,8 +587,6 @@ parameters! { TextureMaxAnisotropyExt = gl::TEXTURE_MAX_ANISOTROPY_EXT, }), Int(TexParameterInt { - TextureMagFilter = gl::TEXTURE_MAG_FILTER, - TextureMinFilter = gl::TEXTURE_MIN_FILTER, TextureWrapS = gl::TEXTURE_WRAP_S, TextureWrapT = gl::TEXTURE_WRAP_T, }), diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index 3d693f1bb96..d460aefde09 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -446,22 +446,22 @@ impl WebGLRenderingContext { handle_potential_webgl_error!(self, f(location)); } - fn tex_parameter(&self, target: u32, name: u32, value: TexParameterValue) { + fn tex_parameter(&self, target: u32, param: u32, value: TexParameterValue) { let texture = match target { constants::TEXTURE_2D | constants::TEXTURE_CUBE_MAP => self.bound_texture(target), _ => return self.webgl_error(InvalidEnum), }; - if !self.extension_manager.is_get_tex_parameter_name_enabled(name) { - return self.webgl_error(InvalidEnum); - } - - let param = handle_potential_webgl_error!(self, TexParameter::from_u32(name), return); let texture = match texture { Some(tex) => tex, None => return self.webgl_error(InvalidOperation), }; + + if !self.extension_manager.is_get_tex_parameter_name_enabled(param) { + return self.webgl_error(InvalidEnum); + } + handle_potential_webgl_error!(self, texture.tex_parameter(param, value), return); // Validate non filterable TEXTURE_2D data_types @@ -1664,9 +1664,18 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { return NullValue(); } - if self.bound_texture(target).is_none() { - self.webgl_error(InvalidOperation); - return NullValue(); + let texture = match self.bound_texture(target) { + Some(texture) => texture, + None => { + self.webgl_error(InvalidOperation); + return NullValue(); + } + }; + + match pname { + constants::TEXTURE_MAG_FILTER => return UInt32Value(texture.mag_filter()), + constants::TEXTURE_MIN_FILTER => return UInt32Value(texture.min_filter()), + _ => {} } match handle_potential_webgl_error!(self, TexParameter::from_u32(pname), return NullValue()) { diff --git a/components/script/dom/webgltexture.rs b/components/script/dom/webgltexture.rs index 60c8487676b..2ecfd0bfab2 100644 --- a/components/script/dom/webgltexture.rs +++ b/components/script/dom/webgltexture.rs @@ -4,10 +4,10 @@ // https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl -use canvas_traits::webgl::{DOMToTextureCommand, TexParameter, TexParameterFloat}; -use canvas_traits::webgl::{TexParameterInt, WebGLCommand, WebGLError}; +use canvas_traits::webgl::{DOMToTextureCommand, WebGLCommand, WebGLError}; use canvas_traits::webgl::{WebGLResult, WebGLTextureId, webgl_channel}; use dom::bindings::cell::DomRefCell; +use dom::bindings::codegen::Bindings::EXTTextureFilterAnisotropicBinding::EXTTextureFilterAnisotropicConstants; use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants; use dom::bindings::codegen::Bindings::WebGLTextureBinding; use dom::bindings::inheritance::Castable; @@ -44,8 +44,8 @@ pub struct WebGLTexture { face_count: Cell, base_mipmap_level: u32, // Store information for min and mag filters - min_filter: Cell>, - mag_filter: Cell>, + min_filter: Cell, + mag_filter: Cell, /// True if this texture is used for the DOMToTexture feature. attached_to_dom: Cell, } @@ -59,8 +59,8 @@ impl WebGLTexture { is_deleted: Cell::new(false), face_count: Cell::new(0), base_mipmap_level: 0, - min_filter: Cell::new(None), - mag_filter: Cell::new(None), + min_filter: Cell::new(constants::NEAREST_MIPMAP_LINEAR), + mag_filter: Cell::new(constants::LINEAR), image_info_array: DomRefCell::new([ImageInfo::new(); MAX_LEVEL_COUNT * MAX_FACE_COUNT]), attached_to_dom: Cell::new(false), } @@ -203,7 +203,7 @@ impl WebGLTexture { /// pub fn tex_parameter( &self, - param: TexParameter, + param: u32, value: TexParameterValue, ) -> WebGLResult<()> { let target = self.target().unwrap(); @@ -213,74 +213,77 @@ impl WebGLTexture { TexParameterValue::Float(float_value) => (float_value as i32, float_value), }; + let update_filter = |filter: &Cell| { + if filter.get() == int_value as u32 { + return Ok(()); + } + filter.set(int_value as u32); + self.upcast::() + .context() + .send_command(WebGLCommand::TexParameteri(target, param, int_value)); + Ok(()) + }; match param { - TexParameter::Int(int_param) => { - match int_param { - TexParameterInt::TextureMinFilter => { - match int_value as u32 { - constants::NEAREST | - constants::LINEAR | - constants::NEAREST_MIPMAP_NEAREST | - constants::LINEAR_MIPMAP_NEAREST | - constants::NEAREST_MIPMAP_LINEAR | - constants::LINEAR_MIPMAP_LINEAR => { - self.min_filter.set(Some(int_value as u32)); - self.upcast::() - .context() - .send_command(WebGLCommand::TexParameteri(target, int_param, int_value)); - Ok(()) - } - _ => Err(WebGLError::InvalidEnum), - } - } - TexParameterInt::TextureMagFilter => { - match int_value as u32 { - constants::NEAREST | constants::LINEAR => { - self.mag_filter.set(Some(int_value as u32)); - self.upcast::() - .context() - .send_command(WebGLCommand::TexParameteri(target, int_param, int_value)); - Ok(()) - } - _ => return Err(WebGLError::InvalidEnum), - } - } - TexParameterInt::TextureWrapS | TexParameterInt::TextureWrapT => { - match int_value as u32 { - constants::CLAMP_TO_EDGE | - constants::MIRRORED_REPEAT | - constants::REPEAT => { - self.upcast::() - .context() - .send_command(WebGLCommand::TexParameteri(target, int_param, int_value)); - Ok(()) - } - _ => Err(WebGLError::InvalidEnum), - } - } + constants::TEXTURE_MIN_FILTER => { + match int_value as u32 { + constants::NEAREST | + constants::LINEAR | + constants::NEAREST_MIPMAP_NEAREST | + constants::LINEAR_MIPMAP_NEAREST | + constants::NEAREST_MIPMAP_LINEAR | + constants::LINEAR_MIPMAP_LINEAR => update_filter(&self.min_filter), + _ => Err(WebGLError::InvalidEnum), } } - TexParameter::Float(float_param @ TexParameterFloat::TextureMaxAnisotropyExt) => { - if float_value >= 1. { - self.upcast::() - .context() - .send_command(WebGLCommand::TexParameterf(target, float_param, float_value)); - Ok(()) - } else { - Err(WebGLError::InvalidValue) + constants::TEXTURE_MAG_FILTER => { + match int_value as u32 { + constants::NEAREST | constants::LINEAR => update_filter(&self.mag_filter), + _ => return Err(WebGLError::InvalidEnum), } } + constants::TEXTURE_WRAP_S | constants::TEXTURE_WRAP_T => { + match int_value as u32 { + constants::CLAMP_TO_EDGE | + constants::MIRRORED_REPEAT | + constants::REPEAT => { + self.upcast::() + .context() + .send_command(WebGLCommand::TexParameteri(target, param, int_value)); + Ok(()) + } + _ => Err(WebGLError::InvalidEnum), + } + } + EXTTextureFilterAnisotropicConstants::TEXTURE_MAX_ANISOTROPY_EXT => { + // NaN is not less than 1., what a time to be alive. + if !(float_value >= 1.) { + return Err(WebGLError::InvalidValue); + } + self.upcast::() + .context() + .send_command(WebGLCommand::TexParameterf(target, param, float_value)); + Ok(()) + } + _ => Err(WebGLError::InvalidEnum), } } + pub fn min_filter(&self) -> u32 { + self.min_filter.get() + } + + pub fn mag_filter(&self) -> u32 { + self.mag_filter.get() + } + pub fn is_using_linear_filtering(&self) -> bool { let filters = [self.min_filter.get(), self.mag_filter.get()]; filters.iter().any(|filter| { match *filter { - Some(constants::LINEAR) | - Some(constants::NEAREST_MIPMAP_LINEAR) | - Some(constants::LINEAR_MIPMAP_NEAREST) | - Some(constants::LINEAR_MIPMAP_LINEAR) => true, + constants::LINEAR | + constants::NEAREST_MIPMAP_LINEAR | + constants::LINEAR_MIPMAP_NEAREST | + constants::LINEAR_MIPMAP_LINEAR => true, _=> false } })