mirror of
https://github.com/servo/servo.git
synced 2025-07-23 15:23:42 +01:00
Auto merge of #26513 - jdm:webgl2-formats, r=asajeffrey
Reject incompatible webgl texture pixel data The tests that would make these changes most visibly correct unfortunately rely on texImage3D which isn't implemented yet, so they error out too soon. However, when I comment out that code, these changes avoid a bunch of panics in the webgl thread because of invalid data type combinations being accepted, and removing the incorrect non-filterable texture fallback behaviour for webgl 2 when more texture formats are supposed to be filterable. --- - [x] `./mach build -d` does not report any errors - [x] `./mach test-tidy` does not report any errors - [x] There are tests for these changes
This commit is contained in:
commit
329f081e6a
3 changed files with 60 additions and 19 deletions
|
@ -1313,7 +1313,39 @@ impl TexFormat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq)]
|
||||||
|
pub enum SizedDataType {
|
||||||
|
Int8,
|
||||||
|
Int16,
|
||||||
|
Int32,
|
||||||
|
Uint8,
|
||||||
|
Uint16,
|
||||||
|
Uint32,
|
||||||
|
Float32,
|
||||||
|
}
|
||||||
|
|
||||||
impl TexDataType {
|
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.
|
/// Returns the size in bytes of each element of data.
|
||||||
pub fn element_size(&self) -> u32 {
|
pub fn element_size(&self) -> u32 {
|
||||||
use self::*;
|
use self::*;
|
||||||
|
|
|
@ -106,6 +106,7 @@ impl WebGLExtensionFeatures {
|
||||||
disabled_get_parameter_names,
|
disabled_get_parameter_names,
|
||||||
disabled_get_tex_parameter_names,
|
disabled_get_tex_parameter_names,
|
||||||
disabled_get_vertex_attrib_names,
|
disabled_get_vertex_attrib_names,
|
||||||
|
not_filterable_tex_types,
|
||||||
element_index_uint_enabled,
|
element_index_uint_enabled,
|
||||||
blend_minmax_enabled,
|
blend_minmax_enabled,
|
||||||
) = match webgl_version {
|
) = match webgl_version {
|
||||||
|
@ -123,6 +124,7 @@ impl WebGLExtensionFeatures {
|
||||||
.iter()
|
.iter()
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect(),
|
.collect(),
|
||||||
|
DEFAULT_NOT_FILTERABLE_TEX_TYPES.iter().cloned().collect(),
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
),
|
),
|
||||||
|
@ -137,6 +139,7 @@ impl WebGLExtensionFeatures {
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect(),
|
.collect(),
|
||||||
Default::default(),
|
Default::default(),
|
||||||
|
Default::default(),
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
),
|
),
|
||||||
|
@ -144,7 +147,7 @@ impl WebGLExtensionFeatures {
|
||||||
Self {
|
Self {
|
||||||
gl_extensions: Default::default(),
|
gl_extensions: Default::default(),
|
||||||
disabled_tex_types,
|
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(),
|
effective_tex_internal_formats: Default::default(),
|
||||||
hint_targets: Default::default(),
|
hint_targets: Default::default(),
|
||||||
disabled_get_parameter_names,
|
disabled_get_parameter_names,
|
||||||
|
|
|
@ -58,7 +58,7 @@ use backtrace::Backtrace;
|
||||||
use canvas_traits::webgl::WebGLError::*;
|
use canvas_traits::webgl::WebGLError::*;
|
||||||
use canvas_traits::webgl::{
|
use canvas_traits::webgl::{
|
||||||
webgl_channel, AlphaTreatment, DOMToTextureCommand, GLContextAttributes, GLLimits, GlType,
|
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,
|
WebGLCommandBacktrace, WebGLContextId, WebGLError, WebGLFramebufferBindingRequest, WebGLMsg,
|
||||||
WebGLMsgSender, WebGLOpaqueFramebufferId, WebGLProgramId, WebGLResult, WebGLSLVersion,
|
WebGLMsgSender, WebGLOpaqueFramebufferId, WebGLProgramId, WebGLResult, WebGLSLVersion,
|
||||||
WebGLSendResult, WebGLSender, WebGLVersion, YAxisTreatment,
|
WebGLSendResult, WebGLSender, WebGLVersion, YAxisTreatment,
|
||||||
|
@ -717,24 +717,13 @@ impl WebGLRenderingContext {
|
||||||
// or UNSIGNED_SHORT_5_5_5_1, a Uint16Array must be supplied.
|
// or UNSIGNED_SHORT_5_5_5_1, a Uint16Array must be supplied.
|
||||||
// or FLOAT, a Float32Array must be supplied.
|
// or FLOAT, a Float32Array must be supplied.
|
||||||
// If the types do not match, an INVALID_OPERATION error is generated.
|
// If the types do not match, an INVALID_OPERATION error is generated.
|
||||||
let is_webgl2 = self.webgl_version() == WebGLVersion::WebGL2;
|
let data_type_matches = data.as_ref().map_or(true, |buffer| {
|
||||||
let received_size = match *data {
|
Some(data_type.sized_data_type()) ==
|
||||||
None => element_size,
|
array_buffer_type_to_sized_type(buffer.get_array_type()) &&
|
||||||
Some(ref buffer) => match buffer.get_array_type() {
|
data_type.required_webgl_version() <= self.webgl_version()
|
||||||
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(());
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
if received_size != element_size {
|
if !data_type_matches {
|
||||||
self.webgl_error(InvalidOperation);
|
self.webgl_error(InvalidOperation);
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
|
@ -5023,3 +5012,20 @@ impl Size2DExt for Size2D<u32> {
|
||||||
return Size2D::new(self.width as u64, self.height as u64);
|
return Size2D::new(self.width as u64, self.height as u64);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn array_buffer_type_to_sized_type(type_: Type) -> Option<SizedDataType> {
|
||||||
|
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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue