diff --git a/components/canvas_traits/webgl.rs b/components/canvas_traits/webgl.rs index 05a1da78b1f..c95fe603a35 100644 --- a/components/canvas_traits/webgl.rs +++ b/components/canvas_traits/webgl.rs @@ -1313,7 +1313,39 @@ impl TexFormat { } } +#[derive(PartialEq)] +pub enum SizedDataType { + Int8, + Int16, + Int32, + Uint8, + Uint16, + Uint32, + Float32, +} + impl TexDataType { + /// Returns the compatible sized data type for this texture data type. + pub fn sized_data_type(&self) -> SizedDataType { + match self { + TexDataType::Byte => SizedDataType::Int8, + TexDataType::UnsignedByte => SizedDataType::Uint8, + TexDataType::Short => SizedDataType::Int16, + TexDataType::UnsignedShort | + TexDataType::UnsignedShort4444 | + TexDataType::UnsignedShort5551 | + TexDataType::UnsignedShort565 => SizedDataType::Uint16, + TexDataType::Int => SizedDataType::Int32, + TexDataType::UnsignedInt | + TexDataType::UnsignedInt10f11f11fRev | + TexDataType::UnsignedInt2101010Rev | + TexDataType::UnsignedInt5999Rev | + TexDataType::UnsignedInt248 => SizedDataType::Uint32, + TexDataType::HalfFloat => SizedDataType::Uint16, + TexDataType::Float | TexDataType::Float32UnsignedInt248Rev => SizedDataType::Float32, + } + } + /// Returns the size in bytes of each element of data. pub fn element_size(&self) -> u32 { use self::*; diff --git a/components/script/dom/webgl_extensions/extensions.rs b/components/script/dom/webgl_extensions/extensions.rs index 3a3ec2591b3..97e5900960f 100644 --- a/components/script/dom/webgl_extensions/extensions.rs +++ b/components/script/dom/webgl_extensions/extensions.rs @@ -106,6 +106,7 @@ impl WebGLExtensionFeatures { disabled_get_parameter_names, disabled_get_tex_parameter_names, disabled_get_vertex_attrib_names, + not_filterable_tex_types, element_index_uint_enabled, blend_minmax_enabled, ) = match webgl_version { @@ -123,6 +124,7 @@ impl WebGLExtensionFeatures { .iter() .cloned() .collect(), + DEFAULT_NOT_FILTERABLE_TEX_TYPES.iter().cloned().collect(), false, false, ), @@ -137,6 +139,7 @@ impl WebGLExtensionFeatures { .cloned() .collect(), Default::default(), + Default::default(), true, true, ), @@ -144,7 +147,7 @@ impl WebGLExtensionFeatures { Self { gl_extensions: Default::default(), disabled_tex_types, - not_filterable_tex_types: DEFAULT_NOT_FILTERABLE_TEX_TYPES.iter().cloned().collect(), + not_filterable_tex_types, effective_tex_internal_formats: Default::default(), hint_targets: Default::default(), disabled_get_parameter_names, diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index 57941f3c527..ae7272f0ec1 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -58,7 +58,7 @@ use backtrace::Backtrace; use canvas_traits::webgl::WebGLError::*; use canvas_traits::webgl::{ webgl_channel, AlphaTreatment, DOMToTextureCommand, GLContextAttributes, GLLimits, GlType, - Parameter, TexDataType, TexFormat, TexParameter, WebGLChan, WebGLCommand, + Parameter, SizedDataType, TexDataType, TexFormat, TexParameter, WebGLChan, WebGLCommand, WebGLCommandBacktrace, WebGLContextId, WebGLError, WebGLFramebufferBindingRequest, WebGLMsg, WebGLMsgSender, WebGLOpaqueFramebufferId, WebGLProgramId, WebGLResult, WebGLSLVersion, WebGLSendResult, WebGLSender, WebGLVersion, YAxisTreatment, @@ -717,24 +717,13 @@ impl WebGLRenderingContext { // or UNSIGNED_SHORT_5_5_5_1, a Uint16Array must be supplied. // or FLOAT, a Float32Array must be supplied. // If the types do not match, an INVALID_OPERATION error is generated. - let is_webgl2 = self.webgl_version() == WebGLVersion::WebGL2; - let received_size = match *data { - None => element_size, - Some(ref buffer) => match buffer.get_array_type() { - Type::Uint8 => 1, - Type::Uint16 => 2, - Type::Float32 => 4, - Type::Int8 if is_webgl2 => 1, - Type::Int16 if is_webgl2 => 2, - Type::Int32 | Type::Uint32 if is_webgl2 => 4, - _ => { - self.webgl_error(InvalidOperation); - return Err(()); - }, - }, - }; + let data_type_matches = data.as_ref().map_or(true, |buffer| { + Some(data_type.sized_data_type()) == + array_buffer_type_to_sized_type(buffer.get_array_type()) && + data_type.required_webgl_version() <= self.webgl_version() + }); - if received_size != element_size { + if !data_type_matches { self.webgl_error(InvalidOperation); return Err(()); } @@ -5023,3 +5012,20 @@ impl Size2DExt for Size2D { return Size2D::new(self.width as u64, self.height as u64); } } + +fn array_buffer_type_to_sized_type(type_: Type) -> Option { + match type_ { + Type::Uint8 | Type::Uint8Clamped => Some(SizedDataType::Uint8), + Type::Uint16 => Some(SizedDataType::Uint16), + Type::Uint32 => Some(SizedDataType::Uint32), + Type::Int8 => Some(SizedDataType::Int8), + Type::Int16 => Some(SizedDataType::Int16), + Type::Int32 => Some(SizedDataType::Int32), + Type::Float32 => Some(SizedDataType::Float32), + Type::Float64 | + Type::BigInt64 | + Type::BigUint64 | + Type::MaxTypedArrayViewType | + Type::Int64 => None, + } +}