diff options
author | yvt <i@yvt.jp> | 2021-07-10 17:24:27 +0900 |
---|---|---|
committer | yvt <i@yvt.jp> | 2021-07-10 17:55:42 +0900 |
commit | 01a7de50ab1843d85295f9dccad7f4c099e7208c (patch) | |
tree | ee53fb6e8889deb7b880ee969e6c662e6128d210 /components/script/dom/webgl_extensions | |
parent | ff8d2cdbbfc7a9dc7f38b7dd47cb350fde39388f (diff) | |
parent | 94b613fbdaa2b98f2179fc0bbda13c64e6fa0d38 (diff) | |
download | servo-01a7de50ab1843d85295f9dccad7f4c099e7208c.tar.gz servo-01a7de50ab1843d85295f9dccad7f4c099e7208c.zip |
Merge remote-tracking branch 'upstream/master' into feat-cow-infra
`tests/wpt/web-platform-tests/html/browsers/origin/cross-origin-objects/cross-origin-objects.html`
was reverted to the upstream version.
Diffstat (limited to 'components/script/dom/webgl_extensions')
21 files changed, 1588 insertions, 0 deletions
diff --git a/components/script/dom/webgl_extensions/ext/angleinstancedarrays.rs b/components/script/dom/webgl_extensions/ext/angleinstancedarrays.rs new file mode 100644 index 00000000000..4d03f25781b --- /dev/null +++ b/components/script/dom/webgl_extensions/ext/angleinstancedarrays.rs @@ -0,0 +1,92 @@ +/* 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::ANGLEInstancedArraysBinding::ANGLEInstancedArraysConstants; +use crate::dom::bindings::codegen::Bindings::ANGLEInstancedArraysBinding::ANGLEInstancedArraysMethods; +use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector}; +use crate::dom::bindings::root::{Dom, DomRoot}; +use crate::dom::webglrenderingcontext::WebGLRenderingContext; +use canvas_traits::webgl::WebGLVersion; +use dom_struct::dom_struct; + +#[dom_struct] +pub struct ANGLEInstancedArrays { + reflector_: Reflector, + ctx: Dom<WebGLRenderingContext>, +} + +impl ANGLEInstancedArrays { + fn new_inherited(ctx: &WebGLRenderingContext) -> Self { + Self { + reflector_: Reflector::new(), + ctx: Dom::from_ref(ctx), + } + } +} + +impl WebGLExtension for ANGLEInstancedArrays { + type Extension = Self; + + fn new(ctx: &WebGLRenderingContext) -> DomRoot<Self> { + reflect_dom_object( + Box::new(ANGLEInstancedArrays::new_inherited(ctx)), + &*ctx.global(), + ) + } + + fn spec() -> WebGLExtensionSpec { + WebGLExtensionSpec::Specific(WebGLVersion::WebGL1) + } + + fn is_supported(ext: &WebGLExtensions) -> bool { + ext.supports_any_gl_extension(&[ + "GL_ANGLE_instanced_arrays", + "GL_ARB_instanced_arrays", + "GL_EXT_instanced_arrays", + "GL_NV_instanced_arrays", + ]) + } + + fn enable(ext: &WebGLExtensions) { + ext.enable_get_vertex_attrib_name( + ANGLEInstancedArraysConstants::VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE, + ); + } + + fn name() -> &'static str { + "ANGLE_instanced_arrays" + } +} + +impl ANGLEInstancedArraysMethods for ANGLEInstancedArrays { + // https://www.khronos.org/registry/webgl/extensions/ANGLE_instanced_arrays/ + fn DrawArraysInstancedANGLE(&self, mode: u32, first: i32, count: i32, primcount: i32) { + handle_potential_webgl_error!( + self.ctx, + self.ctx + .draw_arrays_instanced(mode, first, count, primcount) + ) + } + + // https://www.khronos.org/registry/webgl/extensions/ANGLE_instanced_arrays/ + fn DrawElementsInstancedANGLE( + &self, + mode: u32, + count: i32, + type_: u32, + offset: i64, + primcount: i32, + ) { + handle_potential_webgl_error!( + self.ctx, + self.ctx + .draw_elements_instanced(mode, count, type_, offset, primcount) + ) + } + + fn VertexAttribDivisorANGLE(&self, index: u32, divisor: u32) { + self.ctx.vertex_attrib_divisor(index, divisor); + } +} diff --git a/components/script/dom/webgl_extensions/ext/extblendminmax.rs b/components/script/dom/webgl_extensions/ext/extblendminmax.rs new file mode 100644 index 00000000000..122aac6c861 --- /dev/null +++ b/components/script/dom/webgl_extensions/ext/extblendminmax.rs @@ -0,0 +1,47 @@ +/* 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::reflector::{reflect_dom_object, DomObject, Reflector}; +use crate::dom::bindings::root::DomRoot; +use crate::dom::webglrenderingcontext::WebGLRenderingContext; +use canvas_traits::webgl::WebGLVersion; +use dom_struct::dom_struct; + +#[dom_struct] +pub struct EXTBlendMinmax { + reflector_: Reflector, +} + +impl EXTBlendMinmax { + fn new_inherited() -> Self { + Self { + reflector_: Reflector::new(), + } + } +} + +impl WebGLExtension for EXTBlendMinmax { + type Extension = Self; + + fn new(ctx: &WebGLRenderingContext) -> DomRoot<Self> { + reflect_dom_object(Box::new(Self::new_inherited()), &*ctx.global()) + } + + fn spec() -> WebGLExtensionSpec { + WebGLExtensionSpec::Specific(WebGLVersion::WebGL1) + } + + fn is_supported(ext: &WebGLExtensions) -> bool { + ext.supports_gl_extension("GL_EXT_blend_minmax") + } + + fn enable(ext: &WebGLExtensions) { + ext.enable_blend_minmax(); + } + + fn name() -> &'static str { + "EXT_blend_minmax" + } +} diff --git a/components/script/dom/webgl_extensions/ext/extcolorbufferhalffloat.rs b/components/script/dom/webgl_extensions/ext/extcolorbufferhalffloat.rs new file mode 100644 index 00000000000..bb4a630d537 --- /dev/null +++ b/components/script/dom/webgl_extensions/ext/extcolorbufferhalffloat.rs @@ -0,0 +1,48 @@ +/* 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::reflector::{reflect_dom_object, DomObject, Reflector}; +use crate::dom::bindings::root::DomRoot; +use crate::dom::webgl_extensions::ext::oestexturehalffloat::OESTextureHalfFloat; +use crate::dom::webglrenderingcontext::WebGLRenderingContext; +use canvas_traits::webgl::WebGLVersion; +use dom_struct::dom_struct; + +#[dom_struct] +pub struct EXTColorBufferHalfFloat { + reflector_: Reflector, +} + +impl EXTColorBufferHalfFloat { + fn new_inherited() -> EXTColorBufferHalfFloat { + Self { + reflector_: Reflector::new(), + } + } +} + +impl WebGLExtension for EXTColorBufferHalfFloat { + type Extension = EXTColorBufferHalfFloat; + fn new(ctx: &WebGLRenderingContext) -> DomRoot<EXTColorBufferHalfFloat> { + reflect_dom_object( + Box::new(EXTColorBufferHalfFloat::new_inherited()), + &*ctx.global(), + ) + } + + fn spec() -> WebGLExtensionSpec { + WebGLExtensionSpec::Specific(WebGLVersion::WebGL1) + } + + fn is_supported(ext: &WebGLExtensions) -> bool { + OESTextureHalfFloat::is_supported(ext) + } + + fn enable(_ext: &WebGLExtensions) {} + + fn name() -> &'static str { + "EXT_color_buffer_half_float" + } +} diff --git a/components/script/dom/webgl_extensions/ext/extfragdepth.rs b/components/script/dom/webgl_extensions/ext/extfragdepth.rs new file mode 100644 index 00000000000..182b30bf754 --- /dev/null +++ b/components/script/dom/webgl_extensions/ext/extfragdepth.rs @@ -0,0 +1,62 @@ +/* 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::reflector::{reflect_dom_object, DomObject, Reflector}; +use crate::dom::bindings::root::DomRoot; +use crate::dom::webglrenderingcontext::WebGLRenderingContext; +use canvas_traits::webgl::{WebGLSLVersion, WebGLVersion}; +use dom_struct::dom_struct; + +#[dom_struct] +pub struct EXTFragDepth { + reflector_: Reflector, +} + +impl EXTFragDepth { + fn new_inherited() -> EXTFragDepth { + Self { + reflector_: Reflector::new(), + } + } +} + +impl WebGLExtension for EXTFragDepth { + type Extension = Self; + + fn new(ctx: &WebGLRenderingContext) -> DomRoot<Self> { + reflect_dom_object(Box::new(Self::new_inherited()), &*ctx.global()) + } + + fn spec() -> WebGLExtensionSpec { + WebGLExtensionSpec::Specific(WebGLVersion::WebGL1) + } + + fn is_supported(ext: &WebGLExtensions) -> bool { + let min_glsl_version = if ext.is_gles() { + WebGLSLVersion { major: 3, minor: 0 } + } else { + WebGLSLVersion { + major: 1, + minor: 10, + } + }; + match ( + ext.is_gles(), + ext.is_min_glsl_version_satisfied(min_glsl_version), + ) { + // ANGLE's shader translator can't translate ESSL1 exts to ESSL3. (bug + // 1524804) + (true, true) => false, + (true, false) => ext.supports_gl_extension("GL_EXT_frag_depth"), + (false, is_min_glsl_version_satisfied) => is_min_glsl_version_satisfied, + } + } + + fn enable(_ext: &WebGLExtensions) {} + + fn name() -> &'static str { + "EXT_frag_depth" + } +} diff --git a/components/script/dom/webgl_extensions/ext/extshadertexturelod.rs b/components/script/dom/webgl_extensions/ext/extshadertexturelod.rs new file mode 100644 index 00000000000..ea68b518dac --- /dev/null +++ b/components/script/dom/webgl_extensions/ext/extshadertexturelod.rs @@ -0,0 +1,46 @@ +/* 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::reflector::{reflect_dom_object, DomObject, Reflector}; +use crate::dom::bindings::root::DomRoot; +use crate::dom::webglrenderingcontext::WebGLRenderingContext; +use canvas_traits::webgl::WebGLVersion; +use dom_struct::dom_struct; + +#[dom_struct] +pub struct EXTShaderTextureLod { + reflector_: Reflector, +} + +impl EXTShaderTextureLod { + fn new_inherited() -> Self { + Self { + reflector_: Reflector::new(), + } + } +} + +impl WebGLExtension for EXTShaderTextureLod { + type Extension = Self; + + fn new(ctx: &WebGLRenderingContext) -> DomRoot<Self> { + reflect_dom_object(Box::new(Self::new_inherited()), &*ctx.global()) + } + + fn spec() -> WebGLExtensionSpec { + WebGLExtensionSpec::Specific(WebGLVersion::WebGL1) + } + + fn is_supported(ext: &WebGLExtensions) -> bool { + // This extension is always available on desktop GL. + !ext.is_gles() || ext.supports_gl_extension("GL_EXT_shader_texture_lod") + } + + fn enable(_ext: &WebGLExtensions) {} + + fn name() -> &'static str { + "EXT_shader_texture_lod" + } +} diff --git a/components/script/dom/webgl_extensions/ext/exttexturefilteranisotropic.rs b/components/script/dom/webgl_extensions/ext/exttexturefilteranisotropic.rs new file mode 100644 index 00000000000..89a4d3ed6a4 --- /dev/null +++ b/components/script/dom/webgl_extensions/ext/exttexturefilteranisotropic.rs @@ -0,0 +1,53 @@ +/* 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::EXTTextureFilterAnisotropicBinding::EXTTextureFilterAnisotropicConstants; +use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector}; +use crate::dom::bindings::root::DomRoot; +use crate::dom::webglrenderingcontext::WebGLRenderingContext; +use canvas_traits::webgl::WebGLVersion; +use dom_struct::dom_struct; + +#[dom_struct] +pub struct EXTTextureFilterAnisotropic { + reflector_: Reflector, +} + +impl EXTTextureFilterAnisotropic { + fn new_inherited() -> EXTTextureFilterAnisotropic { + Self { + reflector_: Reflector::new(), + } + } +} + +impl WebGLExtension for EXTTextureFilterAnisotropic { + type Extension = EXTTextureFilterAnisotropic; + + fn new(ctx: &WebGLRenderingContext) -> DomRoot<Self> { + reflect_dom_object(Box::new(Self::new_inherited()), &*ctx.global()) + } + + fn spec() -> WebGLExtensionSpec { + WebGLExtensionSpec::Specific(WebGLVersion::WebGL1) + } + + fn is_supported(ext: &WebGLExtensions) -> bool { + ext.supports_gl_extension("GL_EXT_texture_filter_anisotropic") + } + + fn enable(ext: &WebGLExtensions) { + ext.enable_get_tex_parameter_name( + EXTTextureFilterAnisotropicConstants::TEXTURE_MAX_ANISOTROPY_EXT, + ); + ext.enable_get_parameter_name( + EXTTextureFilterAnisotropicConstants::MAX_TEXTURE_MAX_ANISOTROPY_EXT, + ); + } + + fn name() -> &'static str { + "EXT_texture_filter_anisotropic" + } +} diff --git a/components/script/dom/webgl_extensions/ext/mod.rs b/components/script/dom/webgl_extensions/ext/mod.rs new file mode 100644 index 00000000000..229d09d56f5 --- /dev/null +++ b/components/script/dom/webgl_extensions/ext/mod.rs @@ -0,0 +1,23 @@ +/* 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::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants; + +pub mod angleinstancedarrays; +pub mod extblendminmax; +pub mod extcolorbufferhalffloat; +pub mod extfragdepth; +pub mod extshadertexturelod; +pub mod exttexturefilteranisotropic; +pub mod oeselementindexuint; +pub mod oesstandardderivatives; +pub mod oestexturefloat; +pub mod oestexturefloatlinear; +pub mod oestexturehalffloat; +pub mod oestexturehalffloatlinear; +pub mod oesvertexarrayobject; +pub mod webglcolorbufferfloat; +pub mod webglcompressedtextureetc1; +pub mod webglcompressedtextures3tc; diff --git a/components/script/dom/webgl_extensions/ext/oeselementindexuint.rs b/components/script/dom/webgl_extensions/ext/oeselementindexuint.rs new file mode 100644 index 00000000000..096c22d3dc5 --- /dev/null +++ b/components/script/dom/webgl_extensions/ext/oeselementindexuint.rs @@ -0,0 +1,51 @@ +/* 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::reflector::{reflect_dom_object, DomObject, Reflector}; +use crate::dom::bindings::root::DomRoot; +use crate::dom::webglrenderingcontext::WebGLRenderingContext; +use canvas_traits::webgl::WebGLVersion; +use dom_struct::dom_struct; + +#[dom_struct] +pub struct OESElementIndexUint { + reflector_: Reflector, +} + +impl OESElementIndexUint { + fn new_inherited() -> Self { + Self { + reflector_: Reflector::new(), + } + } +} + +impl WebGLExtension for OESElementIndexUint { + type Extension = Self; + + fn new(ctx: &WebGLRenderingContext) -> DomRoot<Self> { + reflect_dom_object( + Box::new(OESElementIndexUint::new_inherited()), + &*ctx.global(), + ) + } + + fn spec() -> WebGLExtensionSpec { + WebGLExtensionSpec::Specific(WebGLVersion::WebGL1) + } + + fn is_supported(ext: &WebGLExtensions) -> bool { + // This extension is always available in desktop OpenGL. + !ext.is_gles() || ext.supports_gl_extension("GL_OES_element_index_uint") + } + + fn enable(ext: &WebGLExtensions) { + ext.enable_element_index_uint(); + } + + fn name() -> &'static str { + "OES_element_index_uint" + } +} diff --git a/components/script/dom/webgl_extensions/ext/oesstandardderivatives.rs b/components/script/dom/webgl_extensions/ext/oesstandardderivatives.rs new file mode 100644 index 00000000000..dfafa7051a5 --- /dev/null +++ b/components/script/dom/webgl_extensions/ext/oesstandardderivatives.rs @@ -0,0 +1,56 @@ +/* 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::OESStandardDerivativesBinding::OESStandardDerivativesConstants; +use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector}; +use crate::dom::bindings::root::DomRoot; +use crate::dom::webglrenderingcontext::WebGLRenderingContext; +use canvas_traits::webgl::WebGLVersion; +use dom_struct::dom_struct; + +#[dom_struct] +pub struct OESStandardDerivatives { + reflector_: Reflector, +} + +impl OESStandardDerivatives { + fn new_inherited() -> OESStandardDerivatives { + Self { + reflector_: Reflector::new(), + } + } +} + +impl WebGLExtension for OESStandardDerivatives { + type Extension = OESStandardDerivatives; + fn new(ctx: &WebGLRenderingContext) -> DomRoot<OESStandardDerivatives> { + reflect_dom_object( + Box::new(OESStandardDerivatives::new_inherited()), + &*ctx.global(), + ) + } + + fn spec() -> WebGLExtensionSpec { + WebGLExtensionSpec::Specific(WebGLVersion::WebGL1) + } + + fn is_supported(ext: &WebGLExtensions) -> bool { + // The standard derivatives are always available in desktop OpenGL. + !ext.is_gles() || ext.supports_any_gl_extension(&["GL_OES_standard_derivatives"]) + } + + fn enable(ext: &WebGLExtensions) { + ext.enable_hint_target( + OESStandardDerivativesConstants::FRAGMENT_SHADER_DERIVATIVE_HINT_OES, + ); + ext.enable_get_parameter_name( + OESStandardDerivativesConstants::FRAGMENT_SHADER_DERIVATIVE_HINT_OES, + ); + } + + fn name() -> &'static str { + "OES_standard_derivatives" + } +} diff --git a/components/script/dom/webgl_extensions/ext/oestexturefloat.rs b/components/script/dom/webgl_extensions/ext/oestexturefloat.rs new file mode 100644 index 00000000000..e286095b7c7 --- /dev/null +++ b/components/script/dom/webgl_extensions/ext/oestexturefloat.rs @@ -0,0 +1,63 @@ +/* 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::{constants as webgl, WebGLExtension, WebGLExtensionSpec, WebGLExtensions}; +use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector}; +use crate::dom::bindings::root::DomRoot; +use crate::dom::webglrenderingcontext::WebGLRenderingContext; +use canvas_traits::webgl::{TexFormat, WebGLVersion}; +use dom_struct::dom_struct; + +#[dom_struct] +pub struct OESTextureFloat { + reflector_: Reflector, +} + +impl OESTextureFloat { + fn new_inherited() -> OESTextureFloat { + Self { + reflector_: Reflector::new(), + } + } +} + +impl WebGLExtension for OESTextureFloat { + type Extension = OESTextureFloat; + fn new(ctx: &WebGLRenderingContext) -> DomRoot<OESTextureFloat> { + reflect_dom_object(Box::new(OESTextureFloat::new_inherited()), &*ctx.global()) + } + + fn spec() -> WebGLExtensionSpec { + WebGLExtensionSpec::Specific(WebGLVersion::WebGL1) + } + + fn is_supported(ext: &WebGLExtensions) -> bool { + ext.supports_any_gl_extension(&[ + "GL_OES_texture_float", + "GL_ARB_texture_float", + "GL_EXT_color_buffer_float", + ]) + } + + fn enable(ext: &WebGLExtensions) { + ext.enable_tex_type(webgl::FLOAT); + ext.add_effective_tex_internal_format(TexFormat::RGBA, webgl::FLOAT, TexFormat::RGBA32f); + ext.add_effective_tex_internal_format(TexFormat::RGB, webgl::FLOAT, TexFormat::RGB32f); + ext.add_effective_tex_internal_format( + TexFormat::Luminance, + webgl::FLOAT, + TexFormat::Luminance32f, + ); + ext.add_effective_tex_internal_format(TexFormat::Alpha, webgl::FLOAT, TexFormat::Alpha32f); + ext.add_effective_tex_internal_format( + TexFormat::LuminanceAlpha, + webgl::FLOAT, + TexFormat::LuminanceAlpha32f, + ); + } + + fn name() -> &'static str { + "OES_texture_float" + } +} diff --git a/components/script/dom/webgl_extensions/ext/oestexturefloatlinear.rs b/components/script/dom/webgl_extensions/ext/oestexturefloatlinear.rs new file mode 100644 index 00000000000..9e5c021f0ef --- /dev/null +++ b/components/script/dom/webgl_extensions/ext/oestexturefloatlinear.rs @@ -0,0 +1,48 @@ +/* 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::{constants as webgl, WebGLExtension, WebGLExtensionSpec, WebGLExtensions}; +use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector}; +use crate::dom::bindings::root::DomRoot; +use crate::dom::webglrenderingcontext::WebGLRenderingContext; +use dom_struct::dom_struct; + +#[dom_struct] +pub struct OESTextureFloatLinear { + reflector_: Reflector, +} + +impl OESTextureFloatLinear { + fn new_inherited() -> OESTextureFloatLinear { + Self { + reflector_: Reflector::new(), + } + } +} + +impl WebGLExtension for OESTextureFloatLinear { + type Extension = OESTextureFloatLinear; + fn new(ctx: &WebGLRenderingContext) -> DomRoot<OESTextureFloatLinear> { + reflect_dom_object( + Box::new(OESTextureFloatLinear::new_inherited()), + &*ctx.global(), + ) + } + + fn spec() -> WebGLExtensionSpec { + WebGLExtensionSpec::All + } + + fn is_supported(ext: &WebGLExtensions) -> bool { + ext.supports_any_gl_extension(&["GL_OES_texture_float_linear", "GL_ARB_texture_float"]) + } + + fn enable(ext: &WebGLExtensions) { + ext.enable_filterable_tex_type(webgl::FLOAT); + } + + fn name() -> &'static str { + "OES_texture_float_linear" + } +} diff --git a/components/script/dom/webgl_extensions/ext/oestexturehalffloat.rs b/components/script/dom/webgl_extensions/ext/oestexturehalffloat.rs new file mode 100644 index 00000000000..4f2ef41c651 --- /dev/null +++ b/components/script/dom/webgl_extensions/ext/oestexturehalffloat.rs @@ -0,0 +1,65 @@ +/* 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::OESTextureHalfFloatBinding::OESTextureHalfFloatConstants; +use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector}; +use crate::dom::bindings::root::DomRoot; +use crate::dom::webglrenderingcontext::WebGLRenderingContext; +use canvas_traits::webgl::{TexFormat, WebGLVersion}; +use dom_struct::dom_struct; + +#[dom_struct] +pub struct OESTextureHalfFloat { + reflector_: Reflector, +} + +impl OESTextureHalfFloat { + fn new_inherited() -> OESTextureHalfFloat { + Self { + reflector_: Reflector::new(), + } + } +} + +impl WebGLExtension for OESTextureHalfFloat { + type Extension = OESTextureHalfFloat; + fn new(ctx: &WebGLRenderingContext) -> DomRoot<OESTextureHalfFloat> { + reflect_dom_object( + Box::new(OESTextureHalfFloat::new_inherited()), + &*ctx.global(), + ) + } + + fn spec() -> WebGLExtensionSpec { + WebGLExtensionSpec::Specific(WebGLVersion::WebGL1) + } + + fn is_supported(ext: &WebGLExtensions) -> bool { + ext.supports_any_gl_extension(&[ + "GL_OES_texture_half_float", + "GL_ARB_half_float_pixel", + "GL_NV_half_float", + "GL_EXT_color_buffer_half_float", + ]) + } + + fn enable(ext: &WebGLExtensions) { + let hf = OESTextureHalfFloatConstants::HALF_FLOAT_OES; + ext.enable_tex_type(hf); + ext.add_effective_tex_internal_format(TexFormat::RGBA, hf, TexFormat::RGBA16f); + ext.add_effective_tex_internal_format(TexFormat::RGB, hf, TexFormat::RGB16f); + ext.add_effective_tex_internal_format(TexFormat::Luminance, hf, TexFormat::Luminance16f); + ext.add_effective_tex_internal_format(TexFormat::Alpha, hf, TexFormat::Alpha16f); + ext.add_effective_tex_internal_format( + TexFormat::LuminanceAlpha, + hf, + TexFormat::LuminanceAlpha16f, + ); + } + + fn name() -> &'static str { + "OES_texture_half_float" + } +} diff --git a/components/script/dom/webgl_extensions/ext/oestexturehalffloatlinear.rs b/components/script/dom/webgl_extensions/ext/oestexturehalffloatlinear.rs new file mode 100644 index 00000000000..a1e5f3bf15d --- /dev/null +++ b/components/script/dom/webgl_extensions/ext/oestexturehalffloatlinear.rs @@ -0,0 +1,53 @@ +/* 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::OESTextureHalfFloatBinding::OESTextureHalfFloatConstants; +use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector}; +use crate::dom::bindings::root::DomRoot; +use crate::dom::webglrenderingcontext::WebGLRenderingContext; +use dom_struct::dom_struct; + +#[dom_struct] +pub struct OESTextureHalfFloatLinear { + reflector_: Reflector, +} + +impl OESTextureHalfFloatLinear { + fn new_inherited() -> OESTextureHalfFloatLinear { + Self { + reflector_: Reflector::new(), + } + } +} + +impl WebGLExtension for OESTextureHalfFloatLinear { + type Extension = OESTextureHalfFloatLinear; + fn new(ctx: &WebGLRenderingContext) -> DomRoot<OESTextureHalfFloatLinear> { + reflect_dom_object( + Box::new(OESTextureHalfFloatLinear::new_inherited()), + &*ctx.global(), + ) + } + + fn spec() -> WebGLExtensionSpec { + WebGLExtensionSpec::All + } + + fn is_supported(ext: &WebGLExtensions) -> bool { + ext.supports_any_gl_extension(&[ + "GL_OES_texture_float_linear", + "GL_ARB_half_float_pixel", + "GL_NV_half_float", + ]) + } + + fn enable(ext: &WebGLExtensions) { + ext.enable_filterable_tex_type(OESTextureHalfFloatConstants::HALF_FLOAT_OES); + } + + fn name() -> &'static str { + "OES_texture_half_float_linear" + } +} diff --git a/components/script/dom/webgl_extensions/ext/oesvertexarrayobject.rs b/components/script/dom/webgl_extensions/ext/oesvertexarrayobject.rs new file mode 100644 index 00000000000..57a68142609 --- /dev/null +++ b/components/script/dom/webgl_extensions/ext/oesvertexarrayobject.rs @@ -0,0 +1,80 @@ +/* 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::OESVertexArrayObjectBinding::OESVertexArrayObjectConstants; +use crate::dom::bindings::codegen::Bindings::OESVertexArrayObjectBinding::OESVertexArrayObjectMethods; +use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector}; +use crate::dom::bindings::root::{Dom, DomRoot}; +use crate::dom::webglrenderingcontext::WebGLRenderingContext; +use crate::dom::webglvertexarrayobjectoes::WebGLVertexArrayObjectOES; +use canvas_traits::webgl::WebGLVersion; +use dom_struct::dom_struct; + +#[dom_struct] +pub struct OESVertexArrayObject { + reflector_: Reflector, + ctx: Dom<WebGLRenderingContext>, +} + +impl OESVertexArrayObject { + fn new_inherited(ctx: &WebGLRenderingContext) -> OESVertexArrayObject { + Self { + reflector_: Reflector::new(), + ctx: Dom::from_ref(ctx), + } + } +} + +impl OESVertexArrayObjectMethods for OESVertexArrayObject { + // https://www.khronos.org/registry/webgl/extensions/OES_vertex_array_object/ + fn CreateVertexArrayOES(&self) -> Option<DomRoot<WebGLVertexArrayObjectOES>> { + self.ctx.create_vertex_array() + } + + // https://www.khronos.org/registry/webgl/extensions/OES_vertex_array_object/ + fn DeleteVertexArrayOES(&self, vao: Option<&WebGLVertexArrayObjectOES>) { + self.ctx.delete_vertex_array(vao); + } + + // https://www.khronos.org/registry/webgl/extensions/OES_vertex_array_object/ + fn IsVertexArrayOES(&self, vao: Option<&WebGLVertexArrayObjectOES>) -> bool { + self.ctx.is_vertex_array(vao) + } + + // https://www.khronos.org/registry/webgl/extensions/OES_vertex_array_object/ + fn BindVertexArrayOES(&self, vao: Option<&WebGLVertexArrayObjectOES>) { + self.ctx.bind_vertex_array(vao); + } +} + +impl WebGLExtension for OESVertexArrayObject { + type Extension = OESVertexArrayObject; + fn new(ctx: &WebGLRenderingContext) -> DomRoot<OESVertexArrayObject> { + reflect_dom_object( + Box::new(OESVertexArrayObject::new_inherited(ctx)), + &*ctx.global(), + ) + } + + fn spec() -> WebGLExtensionSpec { + WebGLExtensionSpec::Specific(WebGLVersion::WebGL1) + } + + fn is_supported(ext: &WebGLExtensions) -> bool { + ext.supports_any_gl_extension(&[ + "GL_OES_vertex_array_object", + "GL_ARB_vertex_array_object", + "GL_APPLE_vertex_array_object", + ]) + } + + fn enable(ext: &WebGLExtensions) { + ext.enable_get_parameter_name(OESVertexArrayObjectConstants::VERTEX_ARRAY_BINDING_OES); + } + + fn name() -> &'static str { + "OES_vertex_array_object" + } +} diff --git a/components/script/dom/webgl_extensions/ext/webglcolorbufferfloat.rs b/components/script/dom/webgl_extensions/ext/webglcolorbufferfloat.rs new file mode 100644 index 00000000000..c0d8dc13776 --- /dev/null +++ b/components/script/dom/webgl_extensions/ext/webglcolorbufferfloat.rs @@ -0,0 +1,48 @@ +/* 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::reflector::{reflect_dom_object, DomObject, Reflector}; +use crate::dom::bindings::root::DomRoot; +use crate::dom::webgl_extensions::ext::oestexturefloat::OESTextureFloat; +use crate::dom::webglrenderingcontext::WebGLRenderingContext; +use canvas_traits::webgl::WebGLVersion; +use dom_struct::dom_struct; + +#[dom_struct] +pub struct WEBGLColorBufferFloat { + reflector_: Reflector, +} + +impl WEBGLColorBufferFloat { + fn new_inherited() -> WEBGLColorBufferFloat { + Self { + reflector_: Reflector::new(), + } + } +} + +impl WebGLExtension for WEBGLColorBufferFloat { + type Extension = WEBGLColorBufferFloat; + fn new(ctx: &WebGLRenderingContext) -> DomRoot<WEBGLColorBufferFloat> { + reflect_dom_object( + Box::new(WEBGLColorBufferFloat::new_inherited()), + &*ctx.global(), + ) + } + + fn spec() -> WebGLExtensionSpec { + WebGLExtensionSpec::Specific(WebGLVersion::WebGL1) + } + + fn is_supported(ext: &WebGLExtensions) -> bool { + OESTextureFloat::is_supported(ext) + } + + fn enable(_ext: &WebGLExtensions) {} + + fn name() -> &'static str { + "WEBGL_color_buffer_float" + } +} diff --git a/components/script/dom/webgl_extensions/ext/webglcompressedtextureetc1.rs b/components/script/dom/webgl_extensions/ext/webglcompressedtextureetc1.rs new file mode 100644 index 00000000000..749c38abd82 --- /dev/null +++ b/components/script/dom/webgl_extensions/ext/webglcompressedtextureetc1.rs @@ -0,0 +1,56 @@ +/* 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::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(), + ) + } + + 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" + } +} diff --git a/components/script/dom/webgl_extensions/ext/webglcompressedtextures3tc.rs b/components/script/dom/webgl_extensions/ext/webglcompressedtextures3tc.rs new file mode 100644 index 00000000000..362dbe67117 --- /dev/null +++ b/components/script/dom/webgl_extensions/ext/webglcompressedtextures3tc.rs @@ -0,0 +1,84 @@ +/* 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::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(), + ) + } + + 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" + } +} diff --git a/components/script/dom/webgl_extensions/extension.rs b/components/script/dom/webgl_extensions/extension.rs new file mode 100644 index 00000000000..3854acee122 --- /dev/null +++ b/components/script/dom/webgl_extensions/extension.rs @@ -0,0 +1,40 @@ +/* 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::WebGLExtensions; +use crate::dom::bindings::reflector::DomObject; +use crate::dom::bindings::root::DomRoot; +use crate::dom::bindings::trace::JSTraceable; +use crate::dom::webglrenderingcontext::WebGLRenderingContext; +use canvas_traits::webgl::WebGLVersion; + +/// Trait implemented by WebGL extensions. +pub trait WebGLExtension: Sized +where + Self::Extension: DomObject + JSTraceable, +{ + type Extension; + + /// Creates the DOM object of the WebGL extension. + fn new(ctx: &WebGLRenderingContext) -> DomRoot<Self::Extension>; + + /// Returns which WebGL spec is this extension written against. + fn spec() -> WebGLExtensionSpec; + + /// Checks if the extension is supported. + fn is_supported(ext: &WebGLExtensions) -> bool; + + /// Enable the extension. + fn enable(ext: &WebGLExtensions); + + /// Name of the WebGL Extension. + fn name() -> &'static str; +} + +pub enum WebGLExtensionSpec { + /// Extensions written against both WebGL and WebGL2 specs. + All, + /// Extensions writen against a specific WebGL version spec. + Specific(WebGLVersion), +} diff --git a/components/script/dom/webgl_extensions/extensions.rs b/components/script/dom/webgl_extensions/extensions.rs new file mode 100644 index 00000000000..97e5900960f --- /dev/null +++ b/components/script/dom/webgl_extensions/extensions.rs @@ -0,0 +1,470 @@ +/* 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::wrapper::{TypedWebGLExtensionWrapper, WebGLExtensionWrapper}; +use super::{ext, WebGLExtension, WebGLExtensionSpec}; +use crate::dom::bindings::cell::DomRefCell; +use crate::dom::bindings::codegen::Bindings::ANGLEInstancedArraysBinding::ANGLEInstancedArraysConstants; +use crate::dom::bindings::codegen::Bindings::EXTTextureFilterAnisotropicBinding::EXTTextureFilterAnisotropicConstants; +use crate::dom::bindings::codegen::Bindings::OESStandardDerivativesBinding::OESStandardDerivativesConstants; +use crate::dom::bindings::codegen::Bindings::OESTextureHalfFloatBinding::OESTextureHalfFloatConstants; +use crate::dom::bindings::codegen::Bindings::OESVertexArrayObjectBinding::OESVertexArrayObjectConstants; +use crate::dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants; +use crate::dom::bindings::trace::JSTraceable; +use crate::dom::extcolorbufferhalffloat::EXTColorBufferHalfFloat; +use crate::dom::oestexturefloat::OESTextureFloat; +use crate::dom::oestexturehalffloat::OESTextureHalfFloat; +use crate::dom::webglcolorbufferfloat::WEBGLColorBufferFloat; +use crate::dom::webglrenderingcontext::WebGLRenderingContext; +use crate::dom::webgltexture::TexCompression; +use canvas_traits::webgl::{GlType, TexFormat, WebGLSLVersion, WebGLVersion}; +use fnv::{FnvHashMap, FnvHashSet}; +use js::jsapi::JSObject; +use malloc_size_of::MallocSizeOf; +use sparkle::gl::{self, GLenum}; +use std::collections::HashMap; +use std::iter::FromIterator; +use std::ptr::NonNull; + +// Data types that are implemented for texImage2D and texSubImage2D in a WebGL 1.0 context +// but must trigger a InvalidValue error until the related WebGL Extensions are enabled. +// Example: https://www.khronos.org/registry/webgl/extensions/OES_texture_float/ +const DEFAULT_DISABLED_TEX_TYPES_WEBGL1: [GLenum; 2] = [ + constants::FLOAT, + OESTextureHalfFloatConstants::HALF_FLOAT_OES, +]; + +// Data types that are implemented for textures in WebGLRenderingContext +// but not allowed to use with linear filtering until the related WebGL Extensions are enabled. +// Example: https://www.khronos.org/registry/webgl/extensions/OES_texture_float_linear/ +const DEFAULT_NOT_FILTERABLE_TEX_TYPES: [GLenum; 2] = [ + constants::FLOAT, + OESTextureHalfFloatConstants::HALF_FLOAT_OES, +]; + +// Param names that are implemented for glGetParameter in a WebGL 1.0 context +// but must trigger a InvalidEnum error until the related WebGL Extensions are enabled. +// Example: https://www.khronos.org/registry/webgl/extensions/OES_standard_derivatives/ +const DEFAULT_DISABLED_GET_PARAMETER_NAMES_WEBGL1: [GLenum; 3] = [ + EXTTextureFilterAnisotropicConstants::MAX_TEXTURE_MAX_ANISOTROPY_EXT, + OESStandardDerivativesConstants::FRAGMENT_SHADER_DERIVATIVE_HINT_OES, + OESVertexArrayObjectConstants::VERTEX_ARRAY_BINDING_OES, +]; + +// Param names that are implemented for glGetParameter in a WebGL 2.0 context +// but must trigger a InvalidEnum error until the related WebGL Extensions are enabled. +// Example: https://www.khronos.org/registry/webgl/extensions/EXT_texture_filter_anisotropic/ +const DEFAULT_DISABLED_GET_PARAMETER_NAMES_WEBGL2: [GLenum; 1] = + [EXTTextureFilterAnisotropicConstants::MAX_TEXTURE_MAX_ANISOTROPY_EXT]; + +// Param names that are implemented for glGetTexParameter in a WebGL 1.0 context +// but must trigger a InvalidEnum error until the related WebGL Extensions are enabled. +// Example: https://www.khronos.org/registry/webgl/extensions/OES_standard_derivatives/ +const DEFAULT_DISABLED_GET_TEX_PARAMETER_NAMES_WEBGL1: [GLenum; 1] = + [EXTTextureFilterAnisotropicConstants::TEXTURE_MAX_ANISOTROPY_EXT]; + +// Param names that are implemented for glGetTexParameter in a WebGL 2.0 context +// but must trigger a InvalidEnum error until the related WebGL Extensions are enabled. +// Example: https://www.khronos.org/registry/webgl/extensions/EXT_texture_filter_anisotropic/ +const DEFAULT_DISABLED_GET_TEX_PARAMETER_NAMES_WEBGL2: [GLenum; 1] = + [EXTTextureFilterAnisotropicConstants::TEXTURE_MAX_ANISOTROPY_EXT]; + +// Param names that are implemented for glGetVertexAttrib in a WebGL 1.0 context +// but must trigger a InvalidEnum error until the related WebGL Extensions are enabled. +// Example: https://www.khronos.org/registry/webgl/extensions/ANGLE_instanced_arrays/ +const DEFAULT_DISABLED_GET_VERTEX_ATTRIB_NAMES_WEBGL1: [GLenum; 1] = + [ANGLEInstancedArraysConstants::VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE]; + +/// WebGL features that are enabled/disabled by WebGL Extensions. +#[derive(JSTraceable, MallocSizeOf)] +struct WebGLExtensionFeatures { + gl_extensions: FnvHashSet<String>, + disabled_tex_types: FnvHashSet<GLenum>, + not_filterable_tex_types: FnvHashSet<GLenum>, + effective_tex_internal_formats: FnvHashMap<TexFormatType, TexFormat>, + /// WebGL Hint() targets enabled by extensions. + hint_targets: FnvHashSet<GLenum>, + /// WebGL GetParameter() names enabled by extensions. + disabled_get_parameter_names: FnvHashSet<GLenum>, + /// WebGL GetTexParameter() names enabled by extensions. + disabled_get_tex_parameter_names: FnvHashSet<GLenum>, + /// WebGL GetAttribVertex() names enabled by extensions. + disabled_get_vertex_attrib_names: FnvHashSet<GLenum>, + /// WebGL OES_element_index_uint extension. + element_index_uint_enabled: bool, + /// WebGL EXT_blend_minmax extension. + blend_minmax_enabled: bool, + /// WebGL supported texture compression formats enabled by extensions. + tex_compression_formats: FnvHashMap<GLenum, TexCompression>, +} + +impl WebGLExtensionFeatures { + fn new(webgl_version: WebGLVersion) -> Self { + let ( + disabled_tex_types, + 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 { + WebGLVersion::WebGL1 => ( + DEFAULT_DISABLED_TEX_TYPES_WEBGL1.iter().cloned().collect(), + DEFAULT_DISABLED_GET_PARAMETER_NAMES_WEBGL1 + .iter() + .cloned() + .collect(), + DEFAULT_DISABLED_GET_TEX_PARAMETER_NAMES_WEBGL1 + .iter() + .cloned() + .collect(), + DEFAULT_DISABLED_GET_VERTEX_ATTRIB_NAMES_WEBGL1 + .iter() + .cloned() + .collect(), + DEFAULT_NOT_FILTERABLE_TEX_TYPES.iter().cloned().collect(), + false, + false, + ), + WebGLVersion::WebGL2 => ( + Default::default(), + DEFAULT_DISABLED_GET_PARAMETER_NAMES_WEBGL2 + .iter() + .cloned() + .collect(), + DEFAULT_DISABLED_GET_TEX_PARAMETER_NAMES_WEBGL2 + .iter() + .cloned() + .collect(), + Default::default(), + Default::default(), + true, + true, + ), + }; + Self { + gl_extensions: Default::default(), + disabled_tex_types, + not_filterable_tex_types, + effective_tex_internal_formats: Default::default(), + hint_targets: Default::default(), + disabled_get_parameter_names, + disabled_get_tex_parameter_names, + disabled_get_vertex_attrib_names, + element_index_uint_enabled, + blend_minmax_enabled, + tex_compression_formats: Default::default(), + } + } +} + +/// Handles the list of implemented, supported and enabled WebGL extensions. +#[unrooted_must_root_lint::must_root] +#[derive(JSTraceable, MallocSizeOf)] +pub struct WebGLExtensions { + extensions: DomRefCell<HashMap<String, Box<dyn WebGLExtensionWrapper>>>, + features: DomRefCell<WebGLExtensionFeatures>, + webgl_version: WebGLVersion, + api_type: GlType, + glsl_version: WebGLSLVersion, +} + +impl WebGLExtensions { + pub fn new( + webgl_version: WebGLVersion, + api_type: GlType, + glsl_version: WebGLSLVersion, + ) -> WebGLExtensions { + Self { + extensions: DomRefCell::new(HashMap::new()), + features: DomRefCell::new(WebGLExtensionFeatures::new(webgl_version)), + webgl_version, + api_type, + glsl_version, + } + } + + pub fn init_once<F>(&self, cb: F) + where + F: FnOnce() -> String, + { + if self.extensions.borrow().len() == 0 { + let gl_str = cb(); + self.features.borrow_mut().gl_extensions = + FnvHashSet::from_iter(gl_str.split(&[',', ' '][..]).map(|s| s.into())); + self.register_all_extensions(); + } + } + + pub fn register<T: 'static + WebGLExtension + JSTraceable + MallocSizeOf>(&self) { + let name = T::name().to_uppercase(); + self.extensions + .borrow_mut() + .insert(name, Box::new(TypedWebGLExtensionWrapper::<T>::new())); + } + + pub fn get_supported_extensions(&self) -> Vec<&'static str> { + self.extensions + .borrow() + .iter() + .filter(|ref v| { + if let WebGLExtensionSpec::Specific(version) = v.1.spec() { + if self.webgl_version != version { + return false; + } + } + v.1.is_supported(&self) + }) + .map(|ref v| v.1.name()) + .collect() + } + + pub fn get_or_init_extension( + &self, + name: &str, + ctx: &WebGLRenderingContext, + ) -> Option<NonNull<JSObject>> { + let name = name.to_uppercase(); + self.extensions.borrow().get(&name).and_then(|extension| { + if extension.is_supported(self) { + Some(extension.instance_or_init(ctx, self)) + } else { + None + } + }) + } + + pub fn is_enabled<T>(&self) -> bool + where + T: 'static + WebGLExtension + JSTraceable + MallocSizeOf, + { + let name = T::name().to_uppercase(); + self.extensions + .borrow() + .get(&name) + .map_or(false, |ext| ext.is_enabled()) + } + + pub fn supports_gl_extension(&self, name: &str) -> bool { + self.features.borrow().gl_extensions.contains(name) + } + + pub fn supports_any_gl_extension(&self, names: &[&str]) -> bool { + let features = self.features.borrow(); + names + .iter() + .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) { + self.features + .borrow_mut() + .disabled_tex_types + .remove(&data_type); + } + + pub fn is_tex_type_enabled(&self, data_type: GLenum) -> bool { + self.features + .borrow() + .disabled_tex_types + .get(&data_type) + .is_none() + } + + pub fn add_effective_tex_internal_format( + &self, + source_internal_format: TexFormat, + source_data_type: u32, + effective_internal_format: TexFormat, + ) { + let format = TexFormatType(source_internal_format, source_data_type); + self.features + .borrow_mut() + .effective_tex_internal_formats + .insert(format, effective_internal_format); + } + + pub fn get_effective_tex_internal_format( + &self, + source_internal_format: TexFormat, + source_data_type: u32, + ) -> TexFormat { + let format = TexFormatType(source_internal_format, source_data_type); + *(self + .features + .borrow() + .effective_tex_internal_formats + .get(&format) + .unwrap_or(&source_internal_format)) + } + + pub fn enable_filterable_tex_type(&self, text_data_type: GLenum) { + self.features + .borrow_mut() + .not_filterable_tex_types + .remove(&text_data_type); + } + + pub fn is_filterable(&self, text_data_type: u32) -> bool { + self.features + .borrow() + .not_filterable_tex_types + .get(&text_data_type) + .is_none() + } + + pub fn enable_hint_target(&self, name: GLenum) { + self.features.borrow_mut().hint_targets.insert(name); + } + + pub fn is_hint_target_enabled(&self, name: GLenum) -> bool { + self.features.borrow().hint_targets.contains(&name) + } + + pub fn enable_get_parameter_name(&self, name: GLenum) { + self.features + .borrow_mut() + .disabled_get_parameter_names + .remove(&name); + } + + pub fn is_get_parameter_name_enabled(&self, name: GLenum) -> bool { + !self + .features + .borrow() + .disabled_get_parameter_names + .contains(&name) + } + + pub fn enable_get_tex_parameter_name(&self, name: GLenum) { + self.features + .borrow_mut() + .disabled_get_tex_parameter_names + .remove(&name); + } + + pub fn is_get_tex_parameter_name_enabled(&self, name: GLenum) -> bool { + !self + .features + .borrow() + .disabled_get_tex_parameter_names + .contains(&name) + } + + pub fn enable_get_vertex_attrib_name(&self, name: GLenum) { + self.features + .borrow_mut() + .disabled_get_vertex_attrib_names + .remove(&name); + } + + pub fn is_get_vertex_attrib_name_enabled(&self, name: GLenum) -> bool { + !self + .features + .borrow() + .disabled_get_vertex_attrib_names + .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) { + self.register::<ext::angleinstancedarrays::ANGLEInstancedArrays>(); + self.register::<ext::extblendminmax::EXTBlendMinmax>(); + self.register::<ext::extcolorbufferhalffloat::EXTColorBufferHalfFloat>(); + self.register::<ext::extfragdepth::EXTFragDepth>(); + self.register::<ext::extshadertexturelod::EXTShaderTextureLod>(); + self.register::<ext::exttexturefilteranisotropic::EXTTextureFilterAnisotropic>(); + self.register::<ext::oeselementindexuint::OESElementIndexUint>(); + self.register::<ext::oesstandardderivatives::OESStandardDerivatives>(); + self.register::<ext::oestexturefloat::OESTextureFloat>(); + self.register::<ext::oestexturefloatlinear::OESTextureFloatLinear>(); + self.register::<ext::oestexturehalffloat::OESTextureHalfFloat>(); + self.register::<ext::oestexturehalffloatlinear::OESTextureHalfFloatLinear>(); + self.register::<ext::oesvertexarrayobject::OESVertexArrayObject>(); + self.register::<ext::webglcolorbufferfloat::WEBGLColorBufferFloat>(); + self.register::<ext::webglcompressedtextureetc1::WEBGLCompressedTextureETC1>(); + self.register::<ext::webglcompressedtextures3tc::WEBGLCompressedTextureS3TC>(); + } + + pub fn enable_element_index_uint(&self) { + self.features.borrow_mut().element_index_uint_enabled = true; + } + + pub fn is_element_index_uint_enabled(&self) -> bool { + self.features.borrow().element_index_uint_enabled + } + + pub fn enable_blend_minmax(&self) { + self.features.borrow_mut().blend_minmax_enabled = true; + } + + pub fn is_blend_minmax_enabled(&self) -> bool { + self.features.borrow().blend_minmax_enabled + } + + pub fn is_float_buffer_renderable(&self) -> bool { + self.is_enabled::<WEBGLColorBufferFloat>() || self.is_enabled::<OESTextureFloat>() + } + + pub fn is_min_glsl_version_satisfied(&self, min_glsl_version: WebGLSLVersion) -> bool { + self.glsl_version >= min_glsl_version + } + + pub fn is_half_float_buffer_renderable(&self) -> bool { + self.is_enabled::<EXTColorBufferHalfFloat>() || self.is_enabled::<OESTextureHalfFloat>() + } + + pub fn effective_type(&self, type_: u32) -> u32 { + if type_ == OESTextureHalfFloatConstants::HALF_FLOAT_OES { + if !self.supports_gl_extension("GL_OES_texture_half_float") { + return gl::HALF_FLOAT; + } + } + type_ + } + + pub fn is_gles(&self) -> bool { + self.api_type == GlType::Gles + } +} + +// Helper structs +#[derive(Eq, Hash, JSTraceable, MallocSizeOf, PartialEq)] +struct TexFormatType(TexFormat, u32); diff --git a/components/script/dom/webgl_extensions/mod.rs b/components/script/dom/webgl_extensions/mod.rs new file mode 100644 index 00000000000..aa6dfd1c752 --- /dev/null +++ b/components/script/dom/webgl_extensions/mod.rs @@ -0,0 +1,12 @@ +/* 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/. */ + +pub mod ext; +mod extension; +mod extensions; +mod wrapper; + +pub use self::extension::WebGLExtension; +pub use self::extension::WebGLExtensionSpec; +pub use self::extensions::WebGLExtensions; diff --git a/components/script/dom/webgl_extensions/wrapper.rs b/components/script/dom/webgl_extensions/wrapper.rs new file mode 100644 index 00000000000..bf8db31418c --- /dev/null +++ b/components/script/dom/webgl_extensions/wrapper.rs @@ -0,0 +1,91 @@ +/* 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::reflector::DomObject; +use crate::dom::bindings::root::MutNullableDom; +use crate::dom::bindings::trace::JSTraceable; +use crate::dom::webglrenderingcontext::WebGLRenderingContext; +use js::jsapi::JSObject; +use malloc_size_of::MallocSizeOf; +use std::any::Any; +use std::ptr::NonNull; + +/// Trait used internally by WebGLExtensions to store and +/// handle the different WebGL extensions in a common list. +pub trait WebGLExtensionWrapper: JSTraceable + MallocSizeOf { + fn instance_or_init( + &self, + ctx: &WebGLRenderingContext, + ext: &WebGLExtensions, + ) -> NonNull<JSObject>; + fn spec(&self) -> WebGLExtensionSpec; + fn is_supported(&self, _: &WebGLExtensions) -> bool; + fn is_enabled(&self) -> bool; + fn enable(&self, ext: &WebGLExtensions); + fn name(&self) -> &'static str; + fn as_any(&self) -> &dyn Any; +} + +#[unrooted_must_root_lint::must_root] +#[derive(JSTraceable, MallocSizeOf)] +pub struct TypedWebGLExtensionWrapper<T: WebGLExtension> { + extension: MutNullableDom<T::Extension>, +} + +/// Typed WebGL Extension implementation. +/// Exposes the exact MutNullableDom<DOMObject> type defined by the extension. +impl<T: WebGLExtension> TypedWebGLExtensionWrapper<T> { + pub fn new() -> TypedWebGLExtensionWrapper<T> { + TypedWebGLExtensionWrapper { + extension: MutNullableDom::new(None), + } + } +} + +impl<T> WebGLExtensionWrapper for TypedWebGLExtensionWrapper<T> +where + T: WebGLExtension + JSTraceable + MallocSizeOf + 'static, +{ + #[allow(unsafe_code)] + fn instance_or_init( + &self, + ctx: &WebGLRenderingContext, + ext: &WebGLExtensions, + ) -> NonNull<JSObject> { + let mut enabled = true; + let extension = self.extension.or_init(|| { + enabled = false; + T::new(ctx) + }); + if !enabled { + self.enable(ext); + } + unsafe { NonNull::new_unchecked(extension.reflector().get_jsobject().get()) } + } + + fn spec(&self) -> WebGLExtensionSpec { + T::spec() + } + + fn is_supported(&self, ext: &WebGLExtensions) -> bool { + self.is_enabled() || T::is_supported(ext) + } + + fn is_enabled(&self) -> bool { + self.extension.get().is_some() + } + + fn enable(&self, ext: &WebGLExtensions) { + T::enable(ext); + } + + fn name(&self) -> &'static str { + T::name() + } + + fn as_any<'a>(&'a self) -> &'a dyn Any { + self + } +} |