mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Add initial support for WebGL compressed textures
This commit is contained in:
parent
a14b952fa3
commit
7f0b820d4e
16 changed files with 792 additions and 37 deletions
|
@ -1168,6 +1168,43 @@ impl WebGLImpl {
|
||||||
&pixels,
|
&pixels,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
WebGLCommand::CompressedTexImage2D {
|
||||||
|
target,
|
||||||
|
level,
|
||||||
|
internal_format,
|
||||||
|
size,
|
||||||
|
ref data,
|
||||||
|
} => {
|
||||||
|
ctx.gl().compressed_tex_image_2d(
|
||||||
|
target,
|
||||||
|
level as i32,
|
||||||
|
internal_format,
|
||||||
|
size.width as i32,
|
||||||
|
size.height as i32,
|
||||||
|
0,
|
||||||
|
&*data,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
WebGLCommand::CompressedTexSubImage2D {
|
||||||
|
target,
|
||||||
|
level,
|
||||||
|
xoffset,
|
||||||
|
yoffset,
|
||||||
|
size,
|
||||||
|
format,
|
||||||
|
ref data,
|
||||||
|
} => {
|
||||||
|
ctx.gl().compressed_tex_sub_image_2d(
|
||||||
|
target,
|
||||||
|
level as i32,
|
||||||
|
xoffset as i32,
|
||||||
|
yoffset as i32,
|
||||||
|
size.width as i32,
|
||||||
|
size.height as i32,
|
||||||
|
format,
|
||||||
|
&*data,
|
||||||
|
);
|
||||||
|
},
|
||||||
WebGLCommand::DrawingBufferWidth(ref sender) => sender
|
WebGLCommand::DrawingBufferWidth(ref sender) => sender
|
||||||
.send(ctx.borrow_draw_buffer().unwrap().size().width)
|
.send(ctx.borrow_draw_buffer().unwrap().size().width)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
|
|
|
@ -331,6 +331,22 @@ pub enum WebGLCommand {
|
||||||
pixel_format: Option<PixelFormat>,
|
pixel_format: Option<PixelFormat>,
|
||||||
data: TruncatedDebug<IpcSharedMemory>,
|
data: TruncatedDebug<IpcSharedMemory>,
|
||||||
},
|
},
|
||||||
|
CompressedTexImage2D {
|
||||||
|
target: u32,
|
||||||
|
level: u32,
|
||||||
|
internal_format: u32,
|
||||||
|
size: Size2D<u32>,
|
||||||
|
data: TruncatedDebug<IpcSharedMemory>,
|
||||||
|
},
|
||||||
|
CompressedTexSubImage2D {
|
||||||
|
target: u32,
|
||||||
|
level: i32,
|
||||||
|
xoffset: i32,
|
||||||
|
yoffset: i32,
|
||||||
|
size: Size2D<u32>,
|
||||||
|
format: u32,
|
||||||
|
data: TruncatedDebug<IpcSharedMemory>,
|
||||||
|
},
|
||||||
DrawingBufferWidth(WebGLSender<i32>),
|
DrawingBufferWidth(WebGLSender<i32>),
|
||||||
DrawingBufferHeight(WebGLSender<i32>),
|
DrawingBufferHeight(WebGLSender<i32>),
|
||||||
Finish(WebGLSender<()>),
|
Finish(WebGLSender<()>),
|
||||||
|
@ -736,6 +752,25 @@ macro_rules! gl_enums {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: These should come from gleam
|
||||||
|
mod gl_ext_constants {
|
||||||
|
use gleam::gl::types::GLenum;
|
||||||
|
|
||||||
|
pub const COMPRESSED_RGB_S3TC_DXT1_EXT: GLenum = 0x83F0;
|
||||||
|
pub const COMPRESSED_RGBA_S3TC_DXT1_EXT: GLenum = 0x83F1;
|
||||||
|
pub const COMPRESSED_RGBA_S3TC_DXT3_EXT: GLenum = 0x83F2;
|
||||||
|
pub const COMPRESSED_RGBA_S3TC_DXT5_EXT: GLenum = 0x83F3;
|
||||||
|
pub const COMPRESSED_RGB_ETC1_WEBGL: GLenum = 0x8D64;
|
||||||
|
|
||||||
|
pub static COMPRESSIONS: &'static [GLenum] = &[
|
||||||
|
COMPRESSED_RGB_S3TC_DXT1_EXT,
|
||||||
|
COMPRESSED_RGBA_S3TC_DXT1_EXT,
|
||||||
|
COMPRESSED_RGBA_S3TC_DXT3_EXT,
|
||||||
|
COMPRESSED_RGBA_S3TC_DXT5_EXT,
|
||||||
|
COMPRESSED_RGB_ETC1_WEBGL,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
gl_enums! {
|
gl_enums! {
|
||||||
pub enum TexFormat {
|
pub enum TexFormat {
|
||||||
DepthComponent = gl::DEPTH_COMPONENT,
|
DepthComponent = gl::DEPTH_COMPONENT,
|
||||||
|
@ -744,6 +779,11 @@ gl_enums! {
|
||||||
RGBA = gl::RGBA,
|
RGBA = gl::RGBA,
|
||||||
Luminance = gl::LUMINANCE,
|
Luminance = gl::LUMINANCE,
|
||||||
LuminanceAlpha = gl::LUMINANCE_ALPHA,
|
LuminanceAlpha = gl::LUMINANCE_ALPHA,
|
||||||
|
CompressedRgbS3tcDxt1 = gl_ext_constants::COMPRESSED_RGB_S3TC_DXT1_EXT,
|
||||||
|
CompressedRgbaS3tcDxt1 = gl_ext_constants::COMPRESSED_RGBA_S3TC_DXT1_EXT,
|
||||||
|
CompressedRgbaS3tcDxt3 = gl_ext_constants::COMPRESSED_RGBA_S3TC_DXT3_EXT,
|
||||||
|
CompressedRgbaS3tcDxt5 = gl_ext_constants::COMPRESSED_RGBA_S3TC_DXT5_EXT,
|
||||||
|
CompressedRgbEtc1 = gl_ext_constants::COMPRESSED_RGB_ETC1_WEBGL,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum TexDataType {
|
pub enum TexDataType {
|
||||||
|
@ -767,8 +807,14 @@ impl TexFormat {
|
||||||
TexFormat::LuminanceAlpha => 2,
|
TexFormat::LuminanceAlpha => 2,
|
||||||
TexFormat::RGB => 3,
|
TexFormat::RGB => 3,
|
||||||
TexFormat::RGBA => 4,
|
TexFormat::RGBA => 4,
|
||||||
|
_ => 1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns whether this format is a known texture compression format.
|
||||||
|
pub fn is_compressed(&self) -> bool {
|
||||||
|
gl_ext_constants::COMPRESSIONS.contains(&self.as_gl_constant())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TexDataType {
|
impl TexDataType {
|
||||||
|
|
|
@ -18,3 +18,5 @@ pub mod oestexturehalffloat;
|
||||||
pub mod oestexturehalffloatlinear;
|
pub mod oestexturehalffloatlinear;
|
||||||
pub mod oesvertexarrayobject;
|
pub mod oesvertexarrayobject;
|
||||||
pub mod webglcolorbufferfloat;
|
pub mod webglcolorbufferfloat;
|
||||||
|
pub mod webglcompressedtextureetc1;
|
||||||
|
pub mod webglcompressedtextures3tc;
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
/* 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 super::{WebGLExtension, WebGLExtensionSpec, WebGLExtensions};
|
||||||
|
use crate::dom::bindings::codegen::Bindings::WEBGLCompressedTextureETC1Binding;
|
||||||
|
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
|
||||||
|
use crate::dom::bindings::root::DomRoot;
|
||||||
|
use crate::dom::webglrenderingcontext::WebGLRenderingContext;
|
||||||
|
use crate::dom::webgltexture::{TexCompression, TexCompressionValidation};
|
||||||
|
use canvas_traits::webgl::{TexFormat, WebGLVersion};
|
||||||
|
use dom_struct::dom_struct;
|
||||||
|
|
||||||
|
#[dom_struct]
|
||||||
|
pub struct WEBGLCompressedTextureETC1 {
|
||||||
|
reflector_: Reflector,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WEBGLCompressedTextureETC1 {
|
||||||
|
fn new_inherited() -> WEBGLCompressedTextureETC1 {
|
||||||
|
Self {
|
||||||
|
reflector_: Reflector::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebGLExtension for WEBGLCompressedTextureETC1 {
|
||||||
|
type Extension = WEBGLCompressedTextureETC1;
|
||||||
|
fn new(ctx: &WebGLRenderingContext) -> DomRoot<WEBGLCompressedTextureETC1> {
|
||||||
|
reflect_dom_object(
|
||||||
|
Box::new(WEBGLCompressedTextureETC1::new_inherited()),
|
||||||
|
&*ctx.global(),
|
||||||
|
WEBGLCompressedTextureETC1Binding::Wrap,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn spec() -> WebGLExtensionSpec {
|
||||||
|
WebGLExtensionSpec::Specific(WebGLVersion::WebGL1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_supported(ext: &WebGLExtensions) -> bool {
|
||||||
|
ext.supports_gl_extension("GL_OES_compressed_ETC1_RGB8_texture")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn enable(ext: &WebGLExtensions) {
|
||||||
|
ext.add_tex_compression_formats(&[TexCompression {
|
||||||
|
format: TexFormat::CompressedRgbEtc1,
|
||||||
|
bytes_per_block: 8,
|
||||||
|
block_width: 4,
|
||||||
|
block_height: 4,
|
||||||
|
validation: TexCompressionValidation::None,
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn name() -> &'static str {
|
||||||
|
"WEBGL_compressed_texture_etc1"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,86 @@
|
||||||
|
/* 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 super::{WebGLExtension, WebGLExtensionSpec, WebGLExtensions};
|
||||||
|
use crate::dom::bindings::codegen::Bindings::WEBGLCompressedTextureS3TCBinding;
|
||||||
|
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector};
|
||||||
|
use crate::dom::bindings::root::DomRoot;
|
||||||
|
use crate::dom::webglrenderingcontext::WebGLRenderingContext;
|
||||||
|
use crate::dom::webgltexture::{TexCompression, TexCompressionValidation};
|
||||||
|
use canvas_traits::webgl::{TexFormat, WebGLVersion};
|
||||||
|
use dom_struct::dom_struct;
|
||||||
|
|
||||||
|
#[dom_struct]
|
||||||
|
pub struct WEBGLCompressedTextureS3TC {
|
||||||
|
reflector_: Reflector,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WEBGLCompressedTextureS3TC {
|
||||||
|
fn new_inherited() -> WEBGLCompressedTextureS3TC {
|
||||||
|
Self {
|
||||||
|
reflector_: Reflector::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WebGLExtension for WEBGLCompressedTextureS3TC {
|
||||||
|
type Extension = WEBGLCompressedTextureS3TC;
|
||||||
|
fn new(ctx: &WebGLRenderingContext) -> DomRoot<WEBGLCompressedTextureS3TC> {
|
||||||
|
reflect_dom_object(
|
||||||
|
Box::new(WEBGLCompressedTextureS3TC::new_inherited()),
|
||||||
|
&*ctx.global(),
|
||||||
|
WEBGLCompressedTextureS3TCBinding::Wrap,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn spec() -> WebGLExtensionSpec {
|
||||||
|
WebGLExtensionSpec::Specific(WebGLVersion::WebGL1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_supported(ext: &WebGLExtensions) -> bool {
|
||||||
|
ext.supports_gl_extension("GL_EXT_texture_compression_s3tc") ||
|
||||||
|
ext.supports_all_gl_extension(&[
|
||||||
|
"GL_EXT_texture_compression_dxt1",
|
||||||
|
"GL_ANGLE_texture_compression_dxt3",
|
||||||
|
"GL_ANGLE_texture_compression_dxt5",
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn enable(ext: &WebGLExtensions) {
|
||||||
|
ext.add_tex_compression_formats(&[
|
||||||
|
TexCompression {
|
||||||
|
format: TexFormat::CompressedRgbS3tcDxt1,
|
||||||
|
bytes_per_block: 8,
|
||||||
|
block_width: 4,
|
||||||
|
block_height: 4,
|
||||||
|
validation: TexCompressionValidation::S3TC,
|
||||||
|
},
|
||||||
|
TexCompression {
|
||||||
|
format: TexFormat::CompressedRgbaS3tcDxt1,
|
||||||
|
bytes_per_block: 8,
|
||||||
|
block_width: 4,
|
||||||
|
block_height: 4,
|
||||||
|
validation: TexCompressionValidation::S3TC,
|
||||||
|
},
|
||||||
|
TexCompression {
|
||||||
|
format: TexFormat::CompressedRgbaS3tcDxt3,
|
||||||
|
bytes_per_block: 16,
|
||||||
|
block_width: 4,
|
||||||
|
block_height: 4,
|
||||||
|
validation: TexCompressionValidation::S3TC,
|
||||||
|
},
|
||||||
|
TexCompression {
|
||||||
|
format: TexFormat::CompressedRgbaS3tcDxt5,
|
||||||
|
bytes_per_block: 16,
|
||||||
|
block_width: 4,
|
||||||
|
block_height: 4,
|
||||||
|
validation: TexCompressionValidation::S3TC,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn name() -> &'static str {
|
||||||
|
"WEBGL_compressed_texture_s3tc"
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,6 +17,7 @@ use crate::dom::oestexturefloat::OESTextureFloat;
|
||||||
use crate::dom::oestexturehalffloat::OESTextureHalfFloat;
|
use crate::dom::oestexturehalffloat::OESTextureHalfFloat;
|
||||||
use crate::dom::webglcolorbufferfloat::WEBGLColorBufferFloat;
|
use crate::dom::webglcolorbufferfloat::WEBGLColorBufferFloat;
|
||||||
use crate::dom::webglrenderingcontext::WebGLRenderingContext;
|
use crate::dom::webglrenderingcontext::WebGLRenderingContext;
|
||||||
|
use crate::dom::webgltexture::TexCompression;
|
||||||
use canvas_traits::webgl::WebGLVersion;
|
use canvas_traits::webgl::WebGLVersion;
|
||||||
use fnv::{FnvHashMap, FnvHashSet};
|
use fnv::{FnvHashMap, FnvHashSet};
|
||||||
use gleam::gl::{self, GLenum};
|
use gleam::gl::{self, GLenum};
|
||||||
|
@ -82,6 +83,8 @@ struct WebGLExtensionFeatures {
|
||||||
element_index_uint_enabled: bool,
|
element_index_uint_enabled: bool,
|
||||||
/// WebGL EXT_blend_minmax extension.
|
/// WebGL EXT_blend_minmax extension.
|
||||||
blend_minmax_enabled: bool,
|
blend_minmax_enabled: bool,
|
||||||
|
/// WebGL supported texture compression formats enabled by extensions.
|
||||||
|
tex_compression_formats: FnvHashMap<GLenum, TexCompression>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WebGLExtensionFeatures {
|
impl WebGLExtensionFeatures {
|
||||||
|
@ -131,6 +134,7 @@ impl WebGLExtensionFeatures {
|
||||||
disabled_get_vertex_attrib_names,
|
disabled_get_vertex_attrib_names,
|
||||||
element_index_uint_enabled,
|
element_index_uint_enabled,
|
||||||
blend_minmax_enabled,
|
blend_minmax_enabled,
|
||||||
|
tex_compression_formats: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -225,6 +229,13 @@ impl WebGLExtensions {
|
||||||
.any(|name| features.gl_extensions.contains(*name))
|
.any(|name| features.gl_extensions.contains(*name))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn supports_all_gl_extension(&self, names: &[&str]) -> bool {
|
||||||
|
let features = self.features.borrow();
|
||||||
|
names
|
||||||
|
.iter()
|
||||||
|
.all(|name| features.gl_extensions.contains(*name))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn enable_tex_type(&self, data_type: GLenum) {
|
pub fn enable_tex_type(&self, data_type: GLenum) {
|
||||||
self.features
|
self.features
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
|
@ -335,6 +346,35 @@ impl WebGLExtensions {
|
||||||
.contains(&name)
|
.contains(&name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add_tex_compression_formats(&self, formats: &[TexCompression]) {
|
||||||
|
let formats: FnvHashMap<GLenum, TexCompression> = formats
|
||||||
|
.iter()
|
||||||
|
.map(|&compression| (compression.format.as_gl_constant(), compression))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
self.features
|
||||||
|
.borrow_mut()
|
||||||
|
.tex_compression_formats
|
||||||
|
.extend(formats.iter());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_tex_compression_format(&self, format_id: GLenum) -> Option<TexCompression> {
|
||||||
|
self.features
|
||||||
|
.borrow()
|
||||||
|
.tex_compression_formats
|
||||||
|
.get(&format_id)
|
||||||
|
.cloned()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_tex_compression_ids(&self) -> Vec<GLenum> {
|
||||||
|
self.features
|
||||||
|
.borrow()
|
||||||
|
.tex_compression_formats
|
||||||
|
.keys()
|
||||||
|
.map(|&k| k)
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
fn register_all_extensions(&self) {
|
fn register_all_extensions(&self) {
|
||||||
self.register::<ext::angleinstancedarrays::ANGLEInstancedArrays>();
|
self.register::<ext::angleinstancedarrays::ANGLEInstancedArrays>();
|
||||||
self.register::<ext::extblendminmax::EXTBlendMinmax>();
|
self.register::<ext::extblendminmax::EXTBlendMinmax>();
|
||||||
|
@ -349,6 +389,8 @@ impl WebGLExtensions {
|
||||||
self.register::<ext::oestexturehalffloatlinear::OESTextureHalfFloatLinear>();
|
self.register::<ext::oestexturehalffloatlinear::OESTextureHalfFloatLinear>();
|
||||||
self.register::<ext::oesvertexarrayobject::OESVertexArrayObject>();
|
self.register::<ext::oesvertexarrayobject::OESVertexArrayObject>();
|
||||||
self.register::<ext::webglcolorbufferfloat::WEBGLColorBufferFloat>();
|
self.register::<ext::webglcolorbufferfloat::WEBGLColorBufferFloat>();
|
||||||
|
self.register::<ext::webglcompressedtextureetc1::WEBGLCompressedTextureETC1>();
|
||||||
|
self.register::<ext::webglcompressedtextures3tc::WEBGLCompressedTextureS3TC>();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn enable_element_index_uint(&self) {
|
pub fn enable_element_index_uint(&self) {
|
||||||
|
|
|
@ -6,7 +6,8 @@ use super::types::TexImageTarget;
|
||||||
use super::WebGLValidator;
|
use super::WebGLValidator;
|
||||||
use crate::dom::bindings::root::DomRoot;
|
use crate::dom::bindings::root::DomRoot;
|
||||||
use crate::dom::webglrenderingcontext::WebGLRenderingContext;
|
use crate::dom::webglrenderingcontext::WebGLRenderingContext;
|
||||||
use crate::dom::webgltexture::WebGLTexture;
|
use crate::dom::webgltexture::{ImageInfo, WebGLTexture};
|
||||||
|
use crate::dom::webgltexture::{TexCompression, TexCompressionValidation};
|
||||||
use canvas_traits::webgl::{TexDataType, TexFormat, WebGLError::*};
|
use canvas_traits::webgl::{TexDataType, TexFormat, WebGLError::*};
|
||||||
use std::{self, fmt};
|
use std::{self, fmt};
|
||||||
|
|
||||||
|
@ -40,6 +41,10 @@ pub enum TexImageValidationError {
|
||||||
InvalidBorder,
|
InvalidBorder,
|
||||||
/// Expected a power of two texture.
|
/// Expected a power of two texture.
|
||||||
NonPotTexture,
|
NonPotTexture,
|
||||||
|
/// Unrecognized texture compression format.
|
||||||
|
InvalidCompressionFormat,
|
||||||
|
/// Invalid X/Y texture offset parameters.
|
||||||
|
InvalidOffsets,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::error::Error for TexImageValidationError {
|
impl std::error::Error for TexImageValidationError {
|
||||||
|
@ -61,6 +66,8 @@ impl std::error::Error for TexImageValidationError {
|
||||||
InvalidTypeForFormat => "Invalid type for the given format",
|
InvalidTypeForFormat => "Invalid type for the given format",
|
||||||
InvalidBorder => "Invalid border",
|
InvalidBorder => "Invalid border",
|
||||||
NonPotTexture => "Expected a power of two texture",
|
NonPotTexture => "Expected a power of two texture",
|
||||||
|
InvalidCompressionFormat => "Unrecognized texture compression format",
|
||||||
|
InvalidOffsets => "Invalid X/Y texture offset parameters",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -357,3 +364,303 @@ impl<'a> WebGLValidator for TexImage2DValidator<'a> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct CommonCompressedTexImage2DValidator<'a> {
|
||||||
|
common_validator: CommonTexImage2DValidator<'a>,
|
||||||
|
data_len: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> CommonCompressedTexImage2DValidator<'a> {
|
||||||
|
pub fn new(
|
||||||
|
context: &'a WebGLRenderingContext,
|
||||||
|
target: u32,
|
||||||
|
level: i32,
|
||||||
|
width: i32,
|
||||||
|
height: i32,
|
||||||
|
border: i32,
|
||||||
|
compression_format: u32,
|
||||||
|
data_len: usize,
|
||||||
|
) -> Self {
|
||||||
|
CommonCompressedTexImage2DValidator {
|
||||||
|
common_validator: CommonTexImage2DValidator::new(
|
||||||
|
context,
|
||||||
|
target,
|
||||||
|
level,
|
||||||
|
compression_format,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
border,
|
||||||
|
),
|
||||||
|
data_len,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct CommonCompressedTexImage2DValidatorResult {
|
||||||
|
pub texture: DomRoot<WebGLTexture>,
|
||||||
|
pub target: TexImageTarget,
|
||||||
|
pub level: u32,
|
||||||
|
pub width: u32,
|
||||||
|
pub height: u32,
|
||||||
|
pub compression: TexCompression,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn valid_s3tc_dimension(level: u32, side_length: u32, block_size: u32) -> bool {
|
||||||
|
(side_length % block_size == 0) || (level > 0 && [0, 1, 2].contains(&side_length))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn valid_compressed_data_len(
|
||||||
|
data_len: usize,
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
compression: &TexCompression,
|
||||||
|
) -> bool {
|
||||||
|
let block_width = compression.block_width as u32;
|
||||||
|
let block_height = compression.block_height as u32;
|
||||||
|
|
||||||
|
let required_blocks_hor = (width + block_width - 1) / block_width;
|
||||||
|
let required_blocks_ver = (height + block_height - 1) / block_height;
|
||||||
|
let required_blocks = required_blocks_hor * required_blocks_ver;
|
||||||
|
|
||||||
|
let required_bytes = required_blocks * compression.bytes_per_block as u32;
|
||||||
|
data_len == required_bytes as usize
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_subimage_blockaligned(
|
||||||
|
xoffset: u32,
|
||||||
|
yoffset: u32,
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
compression: &TexCompression,
|
||||||
|
tex_info: &ImageInfo,
|
||||||
|
) -> bool {
|
||||||
|
let block_width = compression.block_width as u32;
|
||||||
|
let block_height = compression.block_height as u32;
|
||||||
|
|
||||||
|
(xoffset % block_width == 0 && yoffset % block_height == 0) &&
|
||||||
|
(width % block_width == 0 || xoffset + width == tex_info.width()) &&
|
||||||
|
(height % block_height == 0 || yoffset + height == tex_info.height())
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> WebGLValidator for CommonCompressedTexImage2DValidator<'a> {
|
||||||
|
type Error = TexImageValidationError;
|
||||||
|
type ValidatedOutput = CommonCompressedTexImage2DValidatorResult;
|
||||||
|
|
||||||
|
fn validate(self) -> Result<Self::ValidatedOutput, TexImageValidationError> {
|
||||||
|
let context = self.common_validator.context;
|
||||||
|
let CommonTexImage2DValidatorResult {
|
||||||
|
texture,
|
||||||
|
target,
|
||||||
|
level,
|
||||||
|
internal_format,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
border: _,
|
||||||
|
} = self.common_validator.validate()?;
|
||||||
|
|
||||||
|
// GL_INVALID_ENUM is generated if internalformat is not a supported
|
||||||
|
// format returned in GL_COMPRESSED_TEXTURE_FORMATS.
|
||||||
|
let compression = context
|
||||||
|
.extension_manager()
|
||||||
|
.get_tex_compression_format(internal_format.as_gl_constant());
|
||||||
|
let compression = match compression {
|
||||||
|
Some(compression) => compression,
|
||||||
|
None => {
|
||||||
|
context.webgl_error(InvalidEnum);
|
||||||
|
return Err(TexImageValidationError::InvalidCompressionFormat);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// GL_INVALID_VALUE is generated if imageSize is not consistent with the
|
||||||
|
// format, dimensions, and contents of the specified compressed image data.
|
||||||
|
if !valid_compressed_data_len(self.data_len, width, height, &compression) {
|
||||||
|
context.webgl_error(InvalidValue);
|
||||||
|
return Err(TexImageValidationError::TextureFormatMismatch);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(CommonCompressedTexImage2DValidatorResult {
|
||||||
|
texture,
|
||||||
|
target,
|
||||||
|
level,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
compression,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct CompressedTexImage2DValidator<'a> {
|
||||||
|
compression_validator: CommonCompressedTexImage2DValidator<'a>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> CompressedTexImage2DValidator<'a> {
|
||||||
|
pub fn new(
|
||||||
|
context: &'a WebGLRenderingContext,
|
||||||
|
target: u32,
|
||||||
|
level: i32,
|
||||||
|
width: i32,
|
||||||
|
height: i32,
|
||||||
|
border: i32,
|
||||||
|
compression_format: u32,
|
||||||
|
data_len: usize,
|
||||||
|
) -> Self {
|
||||||
|
CompressedTexImage2DValidator {
|
||||||
|
compression_validator: CommonCompressedTexImage2DValidator::new(
|
||||||
|
context,
|
||||||
|
target,
|
||||||
|
level,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
border,
|
||||||
|
compression_format,
|
||||||
|
data_len,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> WebGLValidator for CompressedTexImage2DValidator<'a> {
|
||||||
|
type Error = TexImageValidationError;
|
||||||
|
type ValidatedOutput = CommonCompressedTexImage2DValidatorResult;
|
||||||
|
|
||||||
|
fn validate(self) -> Result<Self::ValidatedOutput, TexImageValidationError> {
|
||||||
|
let context = self.compression_validator.common_validator.context;
|
||||||
|
let CommonCompressedTexImage2DValidatorResult {
|
||||||
|
texture,
|
||||||
|
target,
|
||||||
|
level,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
compression,
|
||||||
|
} = self.compression_validator.validate()?;
|
||||||
|
|
||||||
|
// GL_INVALID_OPERATION is generated if parameter combinations are not
|
||||||
|
// supported by the specific compressed internal format as specified
|
||||||
|
// in the specific texture compression extension.
|
||||||
|
let compression_valid = match compression.validation {
|
||||||
|
TexCompressionValidation::S3TC => {
|
||||||
|
let valid_width =
|
||||||
|
valid_s3tc_dimension(level, width, compression.block_width as u32);
|
||||||
|
let valid_height =
|
||||||
|
valid_s3tc_dimension(level, height, compression.block_height as u32);
|
||||||
|
valid_width && valid_height
|
||||||
|
},
|
||||||
|
TexCompressionValidation::None => true,
|
||||||
|
};
|
||||||
|
if !compression_valid {
|
||||||
|
context.webgl_error(InvalidOperation);
|
||||||
|
return Err(TexImageValidationError::TextureFormatMismatch);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(CommonCompressedTexImage2DValidatorResult {
|
||||||
|
texture,
|
||||||
|
target,
|
||||||
|
level,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
compression,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct CompressedTexSubImage2DValidator<'a> {
|
||||||
|
compression_validator: CommonCompressedTexImage2DValidator<'a>,
|
||||||
|
xoffset: i32,
|
||||||
|
yoffset: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> CompressedTexSubImage2DValidator<'a> {
|
||||||
|
pub fn new(
|
||||||
|
context: &'a WebGLRenderingContext,
|
||||||
|
target: u32,
|
||||||
|
level: i32,
|
||||||
|
xoffset: i32,
|
||||||
|
yoffset: i32,
|
||||||
|
width: i32,
|
||||||
|
height: i32,
|
||||||
|
compression_format: u32,
|
||||||
|
data_len: usize,
|
||||||
|
) -> Self {
|
||||||
|
CompressedTexSubImage2DValidator {
|
||||||
|
compression_validator: CommonCompressedTexImage2DValidator::new(
|
||||||
|
context,
|
||||||
|
target,
|
||||||
|
level,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
0,
|
||||||
|
compression_format,
|
||||||
|
data_len,
|
||||||
|
),
|
||||||
|
xoffset,
|
||||||
|
yoffset,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> WebGLValidator for CompressedTexSubImage2DValidator<'a> {
|
||||||
|
type Error = TexImageValidationError;
|
||||||
|
type ValidatedOutput = CommonCompressedTexImage2DValidatorResult;
|
||||||
|
|
||||||
|
fn validate(self) -> Result<Self::ValidatedOutput, TexImageValidationError> {
|
||||||
|
let context = self.compression_validator.common_validator.context;
|
||||||
|
let CommonCompressedTexImage2DValidatorResult {
|
||||||
|
texture,
|
||||||
|
target,
|
||||||
|
level,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
compression,
|
||||||
|
} = self.compression_validator.validate()?;
|
||||||
|
|
||||||
|
let tex_info = texture.image_info_for_target(&target, level);
|
||||||
|
|
||||||
|
// GL_INVALID_VALUE is generated if:
|
||||||
|
// - xoffset or yoffset is less than 0
|
||||||
|
// - x offset plus the width is greater than the texture width
|
||||||
|
// - y offset plus the height is greater than the texture height
|
||||||
|
if self.xoffset < 0 ||
|
||||||
|
(self.xoffset as u32 + width) > tex_info.width() ||
|
||||||
|
self.yoffset < 0 ||
|
||||||
|
(self.yoffset as u32 + height) > tex_info.height()
|
||||||
|
{
|
||||||
|
context.webgl_error(InvalidValue);
|
||||||
|
return Err(TexImageValidationError::InvalidOffsets);
|
||||||
|
}
|
||||||
|
|
||||||
|
// GL_INVALID_OPERATION is generated if format does not match
|
||||||
|
// internal_format.
|
||||||
|
if compression.format != tex_info.internal_format().unwrap() {
|
||||||
|
context.webgl_error(InvalidOperation);
|
||||||
|
return Err(TexImageValidationError::TextureFormatMismatch);
|
||||||
|
}
|
||||||
|
|
||||||
|
// GL_INVALID_OPERATION is generated if parameter combinations are not
|
||||||
|
// supported by the specific compressed internal format as specified
|
||||||
|
// in the specific texture compression extension.
|
||||||
|
let compression_valid = match compression.validation {
|
||||||
|
TexCompressionValidation::S3TC => is_subimage_blockaligned(
|
||||||
|
self.xoffset as u32,
|
||||||
|
self.yoffset as u32,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
&compression,
|
||||||
|
&tex_info,
|
||||||
|
),
|
||||||
|
TexCompressionValidation::None => true,
|
||||||
|
};
|
||||||
|
if !compression_valid {
|
||||||
|
context.webgl_error(InvalidOperation);
|
||||||
|
return Err(TexImageValidationError::TextureFormatMismatch);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(CommonCompressedTexImage2DValidatorResult {
|
||||||
|
texture,
|
||||||
|
target,
|
||||||
|
level,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
compression,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -26,9 +26,10 @@ use crate::dom::htmliframeelement::HTMLIFrameElement;
|
||||||
use crate::dom::node::{document_from_node, window_from_node, Node, NodeDamage};
|
use crate::dom::node::{document_from_node, window_from_node, Node, NodeDamage};
|
||||||
use crate::dom::webgl_extensions::WebGLExtensions;
|
use crate::dom::webgl_extensions::WebGLExtensions;
|
||||||
use crate::dom::webgl_validations::tex_image_2d::{
|
use crate::dom::webgl_validations::tex_image_2d::{
|
||||||
CommonTexImage2DValidator, CommonTexImage2DValidatorResult,
|
CommonCompressedTexImage2DValidatorResult, CommonTexImage2DValidator,
|
||||||
|
CommonTexImage2DValidatorResult, CompressedTexImage2DValidator,
|
||||||
|
CompressedTexSubImage2DValidator, TexImage2DValidator, TexImage2DValidatorResult,
|
||||||
};
|
};
|
||||||
use crate::dom::webgl_validations::tex_image_2d::{TexImage2DValidator, TexImage2DValidatorResult};
|
|
||||||
use crate::dom::webgl_validations::types::TexImageTarget;
|
use crate::dom::webgl_validations::types::TexImageTarget;
|
||||||
use crate::dom::webgl_validations::WebGLValidator;
|
use crate::dom::webgl_validations::WebGLValidator;
|
||||||
use crate::dom::webglactiveinfo::WebGLActiveInfo;
|
use crate::dom::webglactiveinfo::WebGLActiveInfo;
|
||||||
|
@ -1227,9 +1228,11 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
return Int32Value(constants::UNSIGNED_BYTE as i32);
|
return Int32Value(constants::UNSIGNED_BYTE as i32);
|
||||||
},
|
},
|
||||||
constants::COMPRESSED_TEXTURE_FORMATS => {
|
constants::COMPRESSED_TEXTURE_FORMATS => {
|
||||||
// FIXME(nox): https://github.com/servo/servo/issues/20594
|
let format_ids = self.extension_manager.get_tex_compression_ids();
|
||||||
|
|
||||||
rooted!(in(cx) let mut rval = ptr::null_mut::<JSObject>());
|
rooted!(in(cx) let mut rval = ptr::null_mut::<JSObject>());
|
||||||
let _ = Uint32Array::create(cx, CreateWith::Slice(&[]), rval.handle_mut()).unwrap();
|
let _ = Uint32Array::create(cx, CreateWith::Slice(&format_ids), rval.handle_mut())
|
||||||
|
.unwrap();
|
||||||
return ObjectValue(rval.get());
|
return ObjectValue(rval.get());
|
||||||
},
|
},
|
||||||
constants::VERSION => {
|
constants::VERSION => {
|
||||||
|
@ -1756,36 +1759,116 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8
|
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8
|
||||||
|
#[allow(unsafe_code)]
|
||||||
fn CompressedTexImage2D(
|
fn CompressedTexImage2D(
|
||||||
&self,
|
&self,
|
||||||
_target: u32,
|
target: u32,
|
||||||
_level: i32,
|
level: i32,
|
||||||
_internal_format: u32,
|
internal_format: u32,
|
||||||
_width: i32,
|
width: i32,
|
||||||
_height: i32,
|
height: i32,
|
||||||
_border: i32,
|
border: i32,
|
||||||
_data: CustomAutoRooterGuard<ArrayBufferView>,
|
data: CustomAutoRooterGuard<ArrayBufferView>,
|
||||||
) {
|
) {
|
||||||
// FIXME: No compressed texture format is currently supported, so error out as per
|
let validator = CompressedTexImage2DValidator::new(
|
||||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#COMPRESSED_TEXTURE_SUPPORT
|
self,
|
||||||
self.webgl_error(InvalidEnum);
|
target,
|
||||||
|
level,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
border,
|
||||||
|
internal_format,
|
||||||
|
data.len(),
|
||||||
|
);
|
||||||
|
let CommonCompressedTexImage2DValidatorResult {
|
||||||
|
texture,
|
||||||
|
target,
|
||||||
|
level,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
compression,
|
||||||
|
} = match validator.validate() {
|
||||||
|
Ok(result) => result,
|
||||||
|
Err(_) => return,
|
||||||
|
};
|
||||||
|
|
||||||
|
let buff = IpcSharedMemory::from_bytes(unsafe { data.as_slice() });
|
||||||
|
let pixels = TexPixels::from_array(buff, Size2D::new(width, height));
|
||||||
|
|
||||||
|
handle_potential_webgl_error!(
|
||||||
|
self,
|
||||||
|
texture.initialize(
|
||||||
|
target,
|
||||||
|
pixels.size.width,
|
||||||
|
pixels.size.height,
|
||||||
|
1,
|
||||||
|
compression.format,
|
||||||
|
level,
|
||||||
|
Some(TexDataType::UnsignedByte)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
self.send_command(WebGLCommand::CompressedTexImage2D {
|
||||||
|
target: target.as_gl_constant(),
|
||||||
|
level,
|
||||||
|
internal_format,
|
||||||
|
size: Size2D::new(width, height),
|
||||||
|
data: pixels.data.into(),
|
||||||
|
});
|
||||||
|
|
||||||
|
if let Some(fb) = self.bound_framebuffer.get() {
|
||||||
|
fb.invalidate_texture(&*texture);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8
|
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8
|
||||||
|
#[allow(unsafe_code)]
|
||||||
fn CompressedTexSubImage2D(
|
fn CompressedTexSubImage2D(
|
||||||
&self,
|
&self,
|
||||||
_target: u32,
|
target: u32,
|
||||||
_level: i32,
|
level: i32,
|
||||||
_xoffset: i32,
|
xoffset: i32,
|
||||||
_yoffset: i32,
|
yoffset: i32,
|
||||||
_width: i32,
|
width: i32,
|
||||||
_height: i32,
|
height: i32,
|
||||||
_format: u32,
|
format: u32,
|
||||||
_data: CustomAutoRooterGuard<ArrayBufferView>,
|
data: CustomAutoRooterGuard<ArrayBufferView>,
|
||||||
) {
|
) {
|
||||||
// FIXME: No compressed texture format is currently supported, so error out as per
|
let validator = CompressedTexSubImage2DValidator::new(
|
||||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#COMPRESSED_TEXTURE_SUPPORT
|
self,
|
||||||
self.webgl_error(InvalidEnum);
|
target,
|
||||||
|
level,
|
||||||
|
xoffset,
|
||||||
|
yoffset,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
format,
|
||||||
|
data.len(),
|
||||||
|
);
|
||||||
|
let CommonCompressedTexImage2DValidatorResult {
|
||||||
|
texture: _,
|
||||||
|
target,
|
||||||
|
level,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
..
|
||||||
|
} = match validator.validate() {
|
||||||
|
Ok(result) => result,
|
||||||
|
Err(_) => return,
|
||||||
|
};
|
||||||
|
|
||||||
|
let buff = IpcSharedMemory::from_bytes(unsafe { data.as_slice() });
|
||||||
|
let pixels = TexPixels::from_array(buff, Size2D::new(width, height));
|
||||||
|
|
||||||
|
self.send_command(WebGLCommand::CompressedTexSubImage2D {
|
||||||
|
target: target.as_gl_constant(),
|
||||||
|
level: level as i32,
|
||||||
|
xoffset,
|
||||||
|
yoffset,
|
||||||
|
size: Size2D::new(width, height),
|
||||||
|
format,
|
||||||
|
data: pixels.data.into(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8
|
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8
|
||||||
|
|
|
@ -470,7 +470,24 @@ impl ImageInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_compressed_format(&self) -> bool {
|
fn is_compressed_format(&self) -> bool {
|
||||||
// TODO: Once Servo supports compressed formats, check for them here
|
match self.internal_format {
|
||||||
false
|
Some(format) => format.is_compressed(),
|
||||||
|
None => false,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, JSTraceable, MallocSizeOf)]
|
||||||
|
pub enum TexCompressionValidation {
|
||||||
|
None,
|
||||||
|
S3TC,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, JSTraceable, MallocSizeOf)]
|
||||||
|
pub struct TexCompression {
|
||||||
|
pub format: TexFormat,
|
||||||
|
pub bytes_per_block: u8,
|
||||||
|
pub block_width: u8,
|
||||||
|
pub block_height: u8,
|
||||||
|
pub validation: TexCompressionValidation,
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
/* 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 from the Khronos specification:
|
||||||
|
* https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_etc1/
|
||||||
|
*/
|
||||||
|
|
||||||
|
[NoInterfaceObject]
|
||||||
|
interface WEBGLCompressedTextureETC1 {
|
||||||
|
/* Compressed Texture Format */
|
||||||
|
const GLenum COMPRESSED_RGB_ETC1_WEBGL = 0x8D64;
|
||||||
|
}; // interface WEBGLCompressedTextureETC1
|
|
@ -0,0 +1,16 @@
|
||||||
|
/* 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 from the Khronos specification:
|
||||||
|
* https://www.khronos.org/registry/webgl/extensions/WEBGL_compressed_texture_s3tc/
|
||||||
|
*/
|
||||||
|
|
||||||
|
[NoInterfaceObject]
|
||||||
|
interface WEBGLCompressedTextureS3TC {
|
||||||
|
/* Compressed Texture Formats */
|
||||||
|
const GLenum COMPRESSED_RGB_S3TC_DXT1_EXT = 0x83F0;
|
||||||
|
const GLenum COMPRESSED_RGBA_S3TC_DXT1_EXT = 0x83F1;
|
||||||
|
const GLenum COMPRESSED_RGBA_S3TC_DXT3_EXT = 0x83F2;
|
||||||
|
const GLenum COMPRESSED_RGBA_S3TC_DXT5_EXT = 0x83F3;
|
||||||
|
}; // interface WEBGLCompressedTextureS3TC
|
|
@ -10888,7 +10888,9 @@
|
||||||
"conformance/extensions/webgl-compressed-texture-s3tc.html": [
|
"conformance/extensions/webgl-compressed-texture-s3tc.html": [
|
||||||
[
|
[
|
||||||
"conformance/extensions/webgl-compressed-texture-s3tc.html",
|
"conformance/extensions/webgl-compressed-texture-s3tc.html",
|
||||||
{}
|
{
|
||||||
|
"timeout": "long"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
"conformance/extensions/webgl-compressed-texture-size-limit.html": [
|
"conformance/extensions/webgl-compressed-texture-size-limit.html": [
|
||||||
|
@ -27817,7 +27819,7 @@
|
||||||
"testharness"
|
"testharness"
|
||||||
],
|
],
|
||||||
"conformance/extensions/webgl-compressed-texture-s3tc.html": [
|
"conformance/extensions/webgl-compressed-texture-s3tc.html": [
|
||||||
"28e3cfc5628760d1ae27166612f17ed46fa12b88",
|
"ea56180224af7537748a649a724563a86c431710",
|
||||||
"testharness"
|
"testharness"
|
||||||
],
|
],
|
||||||
"conformance/extensions/webgl-compressed-texture-size-limit.html": [
|
"conformance/extensions/webgl-compressed-texture-size-limit.html": [
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
|
<meta name="timeout" content="long">
|
||||||
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||||
<script src=/resources/testharness.js></script>
|
<script src=/resources/testharness.js></script>
|
||||||
<script src=/resources/testharnessreport.js></script>
|
<script src=/resources/testharnessreport.js></script>
|
||||||
|
@ -694,13 +695,6 @@ function compareRect(width, height, channels, expectedData, filteringMode) {
|
||||||
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, actual);
|
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, actual);
|
||||||
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "reading back pixels");
|
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "reading back pixels");
|
||||||
|
|
||||||
var div = document.createElement("div");
|
|
||||||
div.className = "testimages";
|
|
||||||
insertImg(div, "expected", makeImage(width, height, expectedData, channels == 4));
|
|
||||||
insertImg(div, "actual", makeImage(width, height, actual, channels == 4));
|
|
||||||
div.appendChild(document.createElement('br'));
|
|
||||||
document.getElementById("console").appendChild(div);
|
|
||||||
|
|
||||||
var failed = false;
|
var failed = false;
|
||||||
for (var yy = 0; yy < height; ++yy) {
|
for (var yy = 0; yy < height; ++yy) {
|
||||||
for (var xx = 0; xx < width; ++xx) {
|
for (var xx = 0; xx < width; ++xx) {
|
||||||
|
@ -714,6 +708,13 @@ function compareRect(width, height, channels, expectedData, filteringMode) {
|
||||||
for (var jj = 0; jj < 4; ++jj) {
|
for (var jj = 0; jj < 4; ++jj) {
|
||||||
if (actual[offset + jj] != expected[jj]) {
|
if (actual[offset + jj] != expected[jj]) {
|
||||||
failed = true;
|
failed = true;
|
||||||
|
var div = document.createElement("div");
|
||||||
|
div.className = "testimages";
|
||||||
|
insertImg(div, "expected", makeImage(width, height, expectedData, channels == 4));
|
||||||
|
insertImg(div, "actual", makeImage(width, height, actual, channels == 4));
|
||||||
|
div.appendChild(document.createElement('br'));
|
||||||
|
document.getElementById("console").appendChild(div);
|
||||||
|
|
||||||
var was = actual[offset + 0].toString();
|
var was = actual[offset + 0].toString();
|
||||||
for (var j = 1; j < 4; ++j) {
|
for (var j = 1; j < 4; ++j) {
|
||||||
was += "," + actual[offset + j];
|
was += "," + actual[offset + j];
|
||||||
|
|
32
tests/wpt/webgl/tools/compressed-images.patch
Normal file
32
tests/wpt/webgl/tools/compressed-images.patch
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
diff --git a/tests/wpt/webgl/tests/conformance/extensions/webgl-compressed-texture-s3tc.html b/tests/wpt/webgl/tests/conformance/extensions/webgl-compressed-texture-s3tc.html
|
||||||
|
index 308e8577a8..ea56180224 100644
|
||||||
|
--- a/tests/wpt/webgl/tests/conformance/extensions/webgl-compressed-texture-s3tc.html
|
||||||
|
+++ b/tests/wpt/webgl/tests/conformance/extensions/webgl-compressed-texture-s3tc.html
|
||||||
|
@@ -695,13 +695,6 @@ function compareRect(width, height, channels, expectedData, filteringMode) {
|
||||||
|
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, actual);
|
||||||
|
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "reading back pixels");
|
||||||
|
|
||||||
|
- var div = document.createElement("div");
|
||||||
|
- div.className = "testimages";
|
||||||
|
- insertImg(div, "expected", makeImage(width, height, expectedData, channels == 4));
|
||||||
|
- insertImg(div, "actual", makeImage(width, height, actual, channels == 4));
|
||||||
|
- div.appendChild(document.createElement('br'));
|
||||||
|
- document.getElementById("console").appendChild(div);
|
||||||
|
-
|
||||||
|
var failed = false;
|
||||||
|
for (var yy = 0; yy < height; ++yy) {
|
||||||
|
for (var xx = 0; xx < width; ++xx) {
|
||||||
|
@@ -715,6 +708,13 @@ function compareRect(width, height, channels, expectedData, filteringMode) {
|
||||||
|
for (var jj = 0; jj < 4; ++jj) {
|
||||||
|
if (actual[offset + jj] != expected[jj]) {
|
||||||
|
failed = true;
|
||||||
|
+ var div = document.createElement("div");
|
||||||
|
+ div.className = "testimages";
|
||||||
|
+ insertImg(div, "expected", makeImage(width, height, expectedData, channels == 4));
|
||||||
|
+ insertImg(div, "actual", makeImage(width, height, actual, channels == 4));
|
||||||
|
+ div.appendChild(document.createElement('br'));
|
||||||
|
+ document.getElementById("console").appendChild(div);
|
||||||
|
+
|
||||||
|
var was = actual[offset + 0].toString();
|
||||||
|
for (var j = 1; j < 4; ++j) {
|
||||||
|
was += "," + actual[offset + j];
|
|
@ -15,6 +15,7 @@ PATCHES = [
|
||||||
("unit.patch", "conformance/more/unit.js"),
|
("unit.patch", "conformance/more/unit.js"),
|
||||||
("timeout.patch", None),
|
("timeout.patch", None),
|
||||||
("set-zero-timeout.patch", "js/webgl-test-utils.js"),
|
("set-zero-timeout.patch", "js/webgl-test-utils.js"),
|
||||||
|
("compressed-images.patch", "conformance/extensions/webgl-compressed-texture-s3tc.html"),
|
||||||
]
|
]
|
||||||
|
|
||||||
# Fix for 'UnicodeDecodeError: 'ascii' codec can't decode byte'
|
# Fix for 'UnicodeDecodeError: 'ascii' codec can't decode byte'
|
||||||
|
|
|
@ -92,3 +92,15 @@ index c1542f4fa9..b3ee786e0b 100644
|
||||||
<title>WebGL uniform packing restrctions Conformance Test</title>
|
<title>WebGL uniform packing restrctions Conformance Test</title>
|
||||||
<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
|
<link rel="stylesheet" href="../../../resources/js-test-style.css"/>
|
||||||
<link rel="stylesheet" href="../../../resources/glsl-feature-tests.css"/>
|
<link rel="stylesheet" href="../../../resources/glsl-feature-tests.css"/>
|
||||||
|
diff --git i/conformance/extensions/webgl-compressed-texture-s3tc.html w/conformance/extensions/webgl-compressed-texture-s3tc.html
|
||||||
|
index 28e3cfc562..308e8577a8 100644
|
||||||
|
--- i/conformance/extensions/webgl-compressed-texture-s3tc.html
|
||||||
|
+++ w/conformance/extensions/webgl-compressed-texture-s3tc.html
|
||||||
|
@@ -29,6 +29,7 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
+<meta name="timeout" content="long">
|
||||||
|
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
|
||||||
|
<script src=/resources/testharness.js></script>
|
||||||
|
<script src=/resources/testharnessreport.js></script>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue