diff options
12 files changed, 240 insertions, 32 deletions
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..d43880c5998 --- /dev/null +++ b/components/script/dom/webgl_extensions/ext/extcolorbufferhalffloat.rs @@ -0,0 +1,49 @@ +/* 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 http://mozilla.org/MPL/2.0/. */ + +use canvas_traits::webgl::WebGLVersion; +use dom::bindings::codegen::Bindings::EXTColorBufferHalfFloatBinding; +use dom::bindings::reflector::{DomObject, Reflector, reflect_dom_object}; +use dom::bindings::root::DomRoot; +use dom::webgl_extensions::ext::oestexturehalffloat::OESTextureHalfFloat; +use dom::webglrenderingcontext::WebGLRenderingContext; +use dom_struct::dom_struct; +use super::{WebGLExtension, WebGLExtensions, WebGLExtensionSpec}; + +#[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(), + EXTColorBufferHalfFloatBinding::Wrap) + } + + 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/mod.rs b/components/script/dom/webgl_extensions/ext/mod.rs index 62f75cb048a..d1a82c24756 100644 --- a/components/script/dom/webgl_extensions/ext/mod.rs +++ b/components/script/dom/webgl_extensions/ext/mod.rs @@ -7,6 +7,7 @@ use super::{ext_constants, WebGLExtension, WebGLExtensions, WebGLExtensionSpec}; pub mod angleinstancedarrays; pub mod extblendminmax; +pub mod extcolorbufferhalffloat; pub mod extshadertexturelod; pub mod exttexturefilteranisotropic; pub mod oeselementindexuint; @@ -16,3 +17,4 @@ pub mod oestexturefloatlinear; pub mod oestexturehalffloat; pub mod oestexturehalffloatlinear; pub mod oesvertexarrayobject; +pub mod webglcolorbufferfloat; diff --git a/components/script/dom/webgl_extensions/ext/oestexturefloat.rs b/components/script/dom/webgl_extensions/ext/oestexturefloat.rs index 13170f19538..643f250900f 100644 --- a/components/script/dom/webgl_extensions/ext/oestexturefloat.rs +++ b/components/script/dom/webgl_extensions/ext/oestexturefloat.rs @@ -46,11 +46,8 @@ impl WebGLExtension for OESTextureFloat { } fn enable(ext: &WebGLExtensions) { - // Enable FLOAT text data type ext.enable_tex_type(webgl::FLOAT); - let needs_replace = !ext.supports_gl_extension("GL_OES_texture_float"); - if needs_replace { - // Special internal formats must be used to avoid clamped float values + if !ext.supports_gl_extension("GL_OES_texture_float") { ext.add_effective_tex_internal_format(webgl::RGBA, webgl::FLOAT, gl::RGBA32F); ext.add_effective_tex_internal_format(webgl::RGB, webgl::FLOAT, gl::RGB32F); ext.add_effective_tex_internal_format( diff --git a/components/script/dom/webgl_extensions/ext/oestexturehalffloat.rs b/components/script/dom/webgl_extensions/ext/oestexturehalffloat.rs index 67c9521750f..15204a67836 100644 --- a/components/script/dom/webgl_extensions/ext/oestexturehalffloat.rs +++ b/components/script/dom/webgl_extensions/ext/oestexturehalffloat.rs @@ -47,12 +47,9 @@ impl WebGLExtension for OESTextureHalfFloat { } fn enable(ext: &WebGLExtensions) { - // Enable FLOAT text data type let hf = OESTextureHalfFloatConstants::HALF_FLOAT_OES; ext.enable_tex_type(hf); - let needs_replace = !ext.supports_gl_extension("GL_OES_texture_float"); - if needs_replace { - // Special internal formats must be used to avoid clamped float values + if !ext.supports_gl_extension("GL_OES_texture_half_float") { ext.add_effective_tex_internal_format(webgl::RGBA, hf, gl::RGBA16F); ext.add_effective_tex_internal_format(webgl::RGB, hf, gl::RGB16F); ext.add_effective_tex_internal_format(webgl::LUMINANCE, hf, gl::LUMINANCE16F_ARB); 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..bc754f1bb5a --- /dev/null +++ b/components/script/dom/webgl_extensions/ext/webglcolorbufferfloat.rs @@ -0,0 +1,49 @@ +/* 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 http://mozilla.org/MPL/2.0/. */ + +use canvas_traits::webgl::WebGLVersion; +use dom::bindings::codegen::Bindings::WEBGLColorBufferFloatBinding; +use dom::bindings::reflector::{DomObject, Reflector, reflect_dom_object}; +use dom::bindings::root::DomRoot; +use dom::webgl_extensions::ext::oestexturefloat::OESTextureFloat; +use dom::webglrenderingcontext::WebGLRenderingContext; +use dom_struct::dom_struct; +use super::{WebGLExtension, WebGLExtensions, WebGLExtensionSpec}; + +#[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(), + WEBGLColorBufferFloatBinding::Wrap) + } + + 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/extensions.rs b/components/script/dom/webgl_extensions/extensions.rs index 5833cccba71..560d699cedd 100644 --- a/components/script/dom/webgl_extensions/extensions.rs +++ b/components/script/dom/webgl_extensions/extensions.rs @@ -11,9 +11,13 @@ use dom::bindings::codegen::Bindings::OESTextureHalfFloatBinding::OESTextureHalf use dom::bindings::codegen::Bindings::OESVertexArrayObjectBinding::OESVertexArrayObjectConstants; use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants; use dom::bindings::trace::JSTraceable; +use dom::extcolorbufferhalffloat::EXTColorBufferHalfFloat; +use dom::oestexturefloat::OESTextureFloat; +use dom::oestexturehalffloat::OESTextureHalfFloat; +use dom::webglcolorbufferfloat::WEBGLColorBufferFloat; use dom::webglrenderingcontext::WebGLRenderingContext; use fnv::{FnvHashMap, FnvHashSet}; -use gleam::gl::GLenum; +use gleam::gl::{self, GLenum}; use js::jsapi::JSObject; use malloc_size_of::MallocSizeOf; use std::collections::HashMap; @@ -333,6 +337,7 @@ impl WebGLExtensions { fn register_all_extensions(&self) { self.register::<ext::angleinstancedarrays::ANGLEInstancedArrays>(); self.register::<ext::extblendminmax::EXTBlendMinmax>(); + self.register::<ext::extcolorbufferhalffloat::EXTColorBufferHalfFloat>(); self.register::<ext::extshadertexturelod::EXTShaderTextureLod>(); self.register::<ext::exttexturefilteranisotropic::EXTTextureFilterAnisotropic>(); self.register::<ext::oeselementindexuint::OESElementIndexUint>(); @@ -342,6 +347,7 @@ impl WebGLExtensions { self.register::<ext::oestexturehalffloat::OESTextureHalfFloat>(); self.register::<ext::oestexturehalffloatlinear::OESTextureHalfFloatLinear>(); self.register::<ext::oesvertexarrayobject::OESVertexArrayObject>(); + self.register::<ext::webglcolorbufferfloat::WEBGLColorBufferFloat>(); } pub fn enable_element_index_uint(&self) { @@ -359,6 +365,23 @@ impl WebGLExtensions { 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_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_ + } } // Helper structs diff --git a/components/script/dom/webglrenderbuffer.rs b/components/script/dom/webglrenderbuffer.rs index 7b9863257de..2447ef28c09 100644 --- a/components/script/dom/webglrenderbuffer.rs +++ b/components/script/dom/webglrenderbuffer.rs @@ -4,7 +4,9 @@ // https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl use canvas_traits::webgl::{WebGLCommand, WebGLError, WebGLRenderbufferId, WebGLResult, is_gles, webgl_channel}; -use dom::bindings::codegen::Bindings::WebGL2RenderingContextBinding::WebGL2RenderingContextConstants as WebGl2Constants; +use dom::bindings::codegen::Bindings::EXTColorBufferHalfFloatBinding::EXTColorBufferHalfFloatConstants; +use dom::bindings::codegen::Bindings::WEBGLColorBufferFloatBinding::WEBGLColorBufferFloatConstants; +use dom::bindings::codegen::Bindings::WebGL2RenderingContextBinding::WebGL2RenderingContextConstants; use dom::bindings::codegen::Bindings::WebGLRenderbufferBinding; use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants; use dom::bindings::inheritance::Castable; @@ -124,13 +126,13 @@ impl WebGLRenderbuffer { constants::DEPTH_COMPONENT16 | constants::STENCIL_INDEX8 => internal_format, // https://www.khronos.org/registry/webgl/specs/latest/1.0/#6.8 - constants::DEPTH_STENCIL => WebGl2Constants::DEPTH24_STENCIL8, + constants::DEPTH_STENCIL => WebGL2RenderingContextConstants::DEPTH24_STENCIL8, constants::RGB5_A1 => { // 16-bit RGBA formats are not supported on desktop GL. if is_gles() { constants::RGB5_A1 } else { - WebGl2Constants::RGBA8 + WebGL2RenderingContextConstants::RGBA8 } } constants::RGB565 => { @@ -138,17 +140,28 @@ impl WebGLRenderbuffer { if is_gles() { constants::RGB565 } else { - WebGl2Constants::RGB8 + WebGL2RenderingContextConstants::RGB8 } } + EXTColorBufferHalfFloatConstants::RGBA16F_EXT | + EXTColorBufferHalfFloatConstants::RGB16F_EXT => { + if !self.upcast().context().extension_manager().is_half_float_buffer_renderable() { + return Err(WebGLError::InvalidEnum); + } + internal_format + }, + WEBGLColorBufferFloatConstants::RGBA32F_EXT => { + if !self.upcast().context().extension_manager().is_float_buffer_renderable() { + return Err(WebGLError::InvalidEnum); + } + internal_format + }, _ => return Err(WebGLError::InvalidEnum), }; self.internal_format.set(Some(internal_format)); self.is_initialized.set(false); - // FIXME: Invalidate completeness after the call - self.upcast::<WebGLObject>() .context() .send_command(WebGLCommand::RenderbufferStorage( diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index 123e3e490be..786e3f71c33 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -808,7 +808,7 @@ impl WebGLRenderingContext { width as i32, height as i32, format, - data_type, + self.extension_manager.effective_type(data_type), receiver, )); sender.send(&pixels).unwrap(); @@ -1180,6 +1180,10 @@ impl WebGLRenderingContext { pub fn bound_framebuffer(&self) -> Option<DomRoot<WebGLFramebuffer>> { self.bound_framebuffer.get() } + + pub fn extension_manager(&self) -> &WebGLExtensions { + &self.extension_manager + } } #[cfg(not(feature = "webgl_backtrace"))] @@ -4059,18 +4063,13 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { return self.webgl_error(InvalidValue); } - match self.bound_renderbuffer.get() { - Some(rb) => { - handle_potential_webgl_error!(self, rb.storage(internal_format, width, height)); - if let Some(fb) = self.bound_framebuffer.get() { - fb.invalidate_renderbuffer(&*rb); - } - }, - None => self.webgl_error(InvalidOperation), - }; + let rb = handle_potential_webgl_error!(self, self.bound_renderbuffer.get().ok_or(InvalidOperation), return); + handle_potential_webgl_error!(self, rb.storage(internal_format, width, height)); + if let Some(fb) = self.bound_framebuffer.get() { + fb.invalidate_renderbuffer(&*rb); + } - // FIXME: We need to clear the renderbuffer before it can be - // accessed. See https://github.com/servo/servo/issues/13710 + // FIXME: https://github.com/servo/servo/issues/13710 } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6 diff --git a/components/script/dom/webidls/EXTColorBufferHalfFloat.webidl b/components/script/dom/webidls/EXTColorBufferHalfFloat.webidl new file mode 100644 index 00000000000..74889988543 --- /dev/null +++ b/components/script/dom/webidls/EXTColorBufferHalfFloat.webidl @@ -0,0 +1,15 @@ +/* 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 http://mozilla.org/MPL/2.0/. */ +/* + * WebGL IDL definitions from the Khronos specification: + * https://www.khronos.org/registry/webgl/extensions/EXT_color_buffer_half_float/ + */ + +[NoInterfaceObject] +interface EXTColorBufferHalfFloat { + const GLenum RGBA16F_EXT = 0x881A; + const GLenum RGB16F_EXT = 0x881B; + const GLenum FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT = 0x8211; + const GLenum UNSIGNED_NORMALIZED_EXT = 0x8C17; +}; // interface EXT_color_buffer_half_float diff --git a/components/script/dom/webidls/WEBGLColorBufferFloat.webidl b/components/script/dom/webidls/WEBGLColorBufferFloat.webidl new file mode 100644 index 00000000000..b895b879f0d --- /dev/null +++ b/components/script/dom/webidls/WEBGLColorBufferFloat.webidl @@ -0,0 +1,14 @@ +/* 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 http://mozilla.org/MPL/2.0/. */ +/* + * WebGL IDL definitions from the Khronos specification: + * https://www.khronos.org/registry/webgl/extensions/WEBGL_color_buffer_float/ + */ + +[NoInterfaceObject] +interface WEBGLColorBufferFloat { + const GLenum RGBA32F_EXT = 0x8814; + const GLenum FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT = 0x8211; + const GLenum UNSIGNED_NORMALIZED_EXT = 0x8C17; +}; // interface WEBGL_color_buffer_float diff --git a/tests/wpt/webgl/meta/conformance/extensions/oes-texture-float.html.ini b/tests/wpt/webgl/meta/conformance/extensions/oes-texture-float.html.ini deleted file mode 100644 index 46627ffc718..00000000000 --- a/tests/wpt/webgl/meta/conformance/extensions/oes-texture-float.html.ini +++ /dev/null @@ -1,4 +0,0 @@ -[oes-texture-float.html] - [WebGL test #24: RGBA/FLOAT is color renderable but WEBGL_color_buffer_float not exposed] - expected: FAIL - diff --git a/tests/wpt/webgl/meta/conformance/extensions/oes-texture-half-float.html.ini b/tests/wpt/webgl/meta/conformance/extensions/oes-texture-half-float.html.ini index ae272da2b67..541f722dbcf 100644 --- a/tests/wpt/webgl/meta/conformance/extensions/oes-texture-half-float.html.ini +++ b/tests/wpt/webgl/meta/conformance/extensions/oes-texture-half-float.html.ini @@ -1,4 +1,58 @@ [oes-texture-half-float.html] - [WebGL test #72: RGBA/HALF_FLOAT_OES is color renderable but EXT_color_buffer_half_float not exposed] + [WebGL test #84: getError expected: INVALID_OPERATION. Was NO_ERROR : IMPLEMENTATION_COLOR_READ_TYPE should fail for incomplete framebuffers.] + expected: FAIL + + [WebGL test #97: getError expected: INVALID_FRAMEBUFFER_OPERATION. Was INVALID_OPERATION : readPixels should fail on incomplete framebuffers.] + expected: FAIL + + [WebGL test #89: gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_TYPE) should be null (of type object). Was 5121 (of type number).] + expected: FAIL + + [WebGL test #100: Green channel should be 0.25 for FLOAT readPixels. Received: 0] + expected: FAIL + + [WebGL test #91: getError expected: INVALID_FRAMEBUFFER_OPERATION. Was INVALID_OPERATION : readPixels should fail on incomplete framebuffers.] + expected: FAIL + + [WebGL test #88: getError expected: INVALID_OPERATION. Was NO_ERROR : IMPLEMENTATION_COLOR_READ_FORMAT should fail for incomplete framebuffers.] + expected: FAIL + + [WebGL test #90: getError expected: INVALID_OPERATION. Was NO_ERROR : IMPLEMENTATION_COLOR_READ_TYPE should fail for incomplete framebuffers.] + expected: FAIL + + [WebGL test #95: gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_TYPE) should be null (of type object). Was 5121 (of type number).] + expected: FAIL + + [WebGL test #85: getError expected: INVALID_FRAMEBUFFER_OPERATION. Was INVALID_OPERATION : readPixels should fail on incomplete framebuffers.] + expected: FAIL + + [WebGL test #94: getError expected: INVALID_OPERATION. Was NO_ERROR : IMPLEMENTATION_COLOR_READ_FORMAT should fail for incomplete framebuffers.] + expected: FAIL + + [WebGL test #101: Blue channel should be 0.5 for FLOAT readPixels. Received: 0] + expected: FAIL + + [WebGL test #87: gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_FORMAT) should be null (of type object). Was 6408 (of type number).] + expected: FAIL + + [WebGL test #83: gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_TYPE) should be null (of type object). Was 5121 (of type number).] + expected: FAIL + + [WebGL test #81: gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_FORMAT) should be null (of type object). Was 6408 (of type number).] + expected: FAIL + + [WebGL test #98: getError expected: NO_ERROR. Was INVALID_OPERATION : readPixels should return NO_ERROR when reading FLOAT data.] + expected: FAIL + + [WebGL test #102: Alpha channel should be 0.75 for FLOAT readPixels. Received: 0] + expected: FAIL + + [WebGL test #93: gl.getParameter(gl.IMPLEMENTATION_COLOR_READ_FORMAT) should be null (of type object). Was 6408 (of type number).] + expected: FAIL + + [WebGL test #96: getError expected: INVALID_OPERATION. Was NO_ERROR : IMPLEMENTATION_COLOR_READ_TYPE should fail for incomplete framebuffers.] + expected: FAIL + + [WebGL test #82: getError expected: INVALID_OPERATION. Was NO_ERROR : IMPLEMENTATION_COLOR_READ_FORMAT should fail for incomplete framebuffers.] expected: FAIL |