diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2020-03-13 16:29:13 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-13 16:29:13 -0400 |
commit | a6736de09944e343344626a6e4233629a78678b2 (patch) | |
tree | a67e9da61ddff0f9f3465e9b715297063615b9c6 /components/script/dom | |
parent | 13a349603d986f969f522a676f356702aa69d5ac (diff) | |
parent | 6cdbab5581b642bf44ea18cb1714892962ddbaa9 (diff) | |
download | servo-a6736de09944e343344626a6e4233629a78678b2.tar.gz servo-a6736de09944e343344626a6e4233629a78678b2.zip |
Auto merge of #25904 - mmatyas:webgl_fns_framebuf_renderbuf, r=jdm
Add support for some more WebGL2 renderbuffer functions
Adds support for the following WebGL2 calls:
- `RenderbufferStorageMultisample`
- `GetInternalFormativ`
See: https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.5
<!-- Please describe your changes on the following line: -->
The test results depend on #25903.
cc @jdm @zakorgy
---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] There are tests for these changes
<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->
<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
Diffstat (limited to 'components/script/dom')
-rw-r--r-- | components/script/dom/webgl2renderingcontext.rs | 62 | ||||
-rw-r--r-- | components/script/dom/webglrenderbuffer.rs | 40 | ||||
-rw-r--r-- | components/script/dom/webglrenderingcontext.rs | 59 | ||||
-rw-r--r-- | components/script/dom/webidls/WebGL2RenderingContext.webidl | 6 |
4 files changed, 131 insertions, 36 deletions
diff --git a/components/script/dom/webgl2renderingcontext.rs b/components/script/dom/webgl2renderingcontext.rs index 699631de5d2..dabcd4cf54e 100644 --- a/components/script/dom/webgl2renderingcontext.rs +++ b/components/script/dom/webgl2renderingcontext.rs @@ -42,7 +42,8 @@ use crate::js::conversions::ToJSValConvertible; use crate::script_runtime::JSContext; use canvas_traits::webgl::WebGLError::*; use canvas_traits::webgl::{ - webgl_channel, GLContextAttributes, WebGLCommand, WebGLResult, WebGLVersion, + webgl_channel, GLContextAttributes, InternalFormatParameter, WebGLCommand, WebGLResult, + WebGLVersion, }; use dom_struct::dom_struct; use euclid::default::{Point2D, Rect, Size2D}; @@ -51,7 +52,7 @@ use js::jsapi::{JSObject, Type}; use js::jsval::{BooleanValue, DoubleValue, Int32Value, UInt32Value}; use js::jsval::{JSVal, NullValue, ObjectValue, UndefinedValue}; use js::rust::CustomAutoRooterGuard; -use js::typedarray::{ArrayBufferView, CreateWith, Float32, Uint32, Uint32Array}; +use js::typedarray::{ArrayBufferView, CreateWith, Float32, Int32Array, Uint32, Uint32Array}; use script_layout_interface::HTMLCanvasDataSource; use std::cell::Cell; use std::cmp; @@ -2459,6 +2460,9 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { &uniform_get(triple, WebGLCommand::GetUniformFloat4x3), ) }, + constants::SAMPLER_3D | constants::SAMPLER_2D_ARRAY => { + Int32Value(uniform_get(triple, WebGLCommand::GetUniformInt)) + }, _ => self.base.GetUniform(cx, program, location), } } @@ -3753,6 +3757,60 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { None => self.base.webgl_error(InvalidOperation), } } + + /// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.5 + #[allow(unsafe_code)] + fn GetInternalformatParameter( + &self, + cx: JSContext, + target: u32, + internal_format: u32, + pname: u32, + ) -> JSVal { + if target != constants::RENDERBUFFER { + self.base.webgl_error(InvalidEnum); + return NullValue(); + } + + match handle_potential_webgl_error!( + self.base, + InternalFormatParameter::from_u32(pname), + return NullValue() + ) { + InternalFormatParameter::IntVec(param) => unsafe { + let (sender, receiver) = webgl_channel().unwrap(); + self.base + .send_command(WebGLCommand::GetInternalFormatIntVec( + target, + internal_format, + param, + sender, + )); + + rooted!(in(*cx) let mut rval = ptr::null_mut::<JSObject>()); + let _ = Int32Array::create( + *cx, + CreateWith::Slice(&receiver.recv().unwrap()), + rval.handle_mut(), + ) + .unwrap(); + ObjectValue(rval.get()) + }, + } + } + + /// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.5 + fn RenderbufferStorageMultisample( + &self, + target: u32, + samples: i32, + internal_format: u32, + width: i32, + height: i32, + ) { + self.base + .renderbuffer_storage(target, samples, internal_format, width, height) + } } impl LayoutCanvasWebGLRenderingContextHelpers for LayoutDom<WebGL2RenderingContext> { diff --git a/components/script/dom/webglrenderbuffer.rs b/components/script/dom/webglrenderbuffer.rs index bc1a11a7ecf..71e56bac1d3 100644 --- a/components/script/dom/webglrenderbuffer.rs +++ b/components/script/dom/webglrenderbuffer.rs @@ -14,7 +14,8 @@ use crate::dom::webglframebuffer::WebGLFramebuffer; use crate::dom::webglobject::WebGLObject; use crate::dom::webglrenderingcontext::WebGLRenderingContext; use canvas_traits::webgl::{ - webgl_channel, GlType, WebGLCommand, WebGLError, WebGLRenderbufferId, WebGLResult, WebGLVersion, + webgl_channel, GlType, InternalFormatIntVec, WebGLCommand, WebGLError, WebGLRenderbufferId, + WebGLResult, WebGLVersion, }; use dom_struct::dom_struct; use std::cell::Cell; @@ -133,11 +134,13 @@ impl WebGLRenderbuffer { pub fn storage( &self, api_type: GlType, + sample_count: i32, internal_format: u32, width: i32, height: i32, ) -> WebGLResult<()> { let is_gles = api_type == GlType::Gles; + let webgl_version = self.upcast().context().webgl_version(); // Validate the internal_format, and save it for completeness // validation. @@ -173,7 +176,7 @@ impl WebGLRenderbuffer { constants::DEPTH_COMPONENT24 | constants::DEPTH_COMPONENT32F | constants::DEPTH24_STENCIL8 | - constants::DEPTH32F_STENCIL8 => match self.upcast().context().webgl_version() { + constants::DEPTH32F_STENCIL8 => match webgl_version { WebGLVersion::WebGL1 => return Err(WebGLError::InvalidEnum), _ => internal_format, }, @@ -221,6 +224,22 @@ impl WebGLRenderbuffer { _ => return Err(WebGLError::InvalidEnum), }; + if webgl_version != WebGLVersion::WebGL1 { + let (sender, receiver) = webgl_channel().unwrap(); + self.upcast::<WebGLObject>().context().send_command( + WebGLCommand::GetInternalFormatIntVec( + constants::RENDERBUFFER, + internal_format, + InternalFormatIntVec::Samples, + sender, + ), + ); + let samples = receiver.recv().unwrap(); + if sample_count < 0 || sample_count as usize > samples.len() { + return Err(WebGLError::InvalidOperation); + } + } + self.internal_format.set(Some(internal_format)); self.is_initialized.set(false); @@ -228,17 +247,24 @@ impl WebGLRenderbuffer { fb.update_status(); } - self.upcast::<WebGLObject>() - .context() - .send_command(WebGLCommand::RenderbufferStorage( + let command = match sample_count { + 0 => WebGLCommand::RenderbufferStorage( constants::RENDERBUFFER, actual_format, width, height, - )); + ), + _ => WebGLCommand::RenderbufferStorageMultisample( + constants::RENDERBUFFER, + sample_count, + actual_format, + width, + height, + ), + }; + self.upcast::<WebGLObject>().context().send_command(command); self.size.set(Some((width, height))); - Ok(()) } diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index bda7c036d60..9f30edac79c 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -1476,6 +1476,40 @@ impl WebGLRenderingContext { } slot.set(framebuffer); } + + pub fn renderbuffer_storage( + &self, + target: u32, + samples: i32, + internal_format: u32, + width: i32, + height: i32, + ) { + if target != constants::RENDERBUFFER { + return self.webgl_error(InvalidEnum); + } + + let max = self.limits.max_renderbuffer_size; + + if samples < 0 || width < 0 || width as u32 > max || height < 0 || height as u32 > max { + return self.webgl_error(InvalidValue); + } + + let rb = handle_potential_webgl_error!( + self, + self.bound_renderbuffer.get().ok_or(InvalidOperation), + return + ); + handle_potential_webgl_error!( + self, + rb.storage(self.api_type, samples, internal_format, width, height) + ); + if let Some(fb) = self.bound_draw_framebuffer.get() { + fb.invalidate_renderbuffer(&*rb); + } + + // FIXME: https://github.com/servo/servo/issues/13710 + } } #[cfg(not(feature = "webgl_backtrace"))] @@ -4336,30 +4370,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.7 fn RenderbufferStorage(&self, target: u32, internal_format: u32, width: i32, height: i32) { - if target != constants::RENDERBUFFER { - return self.webgl_error(InvalidEnum); - } - - let max = self.limits.max_renderbuffer_size; - - if width < 0 || width as u32 > max || height < 0 || height as u32 > max { - return self.webgl_error(InvalidValue); - } - - let rb = handle_potential_webgl_error!( - self, - self.bound_renderbuffer.get().ok_or(InvalidOperation), - return - ); - handle_potential_webgl_error!( - self, - rb.storage(self.api_type, internal_format, width, height) - ); - if let Some(fb) = self.bound_draw_framebuffer.get() { - fb.invalidate_renderbuffer(&*rb); - } - - // FIXME: https://github.com/servo/servo/issues/13710 + self.renderbuffer_storage(target, 0, internal_format, width, height) } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6 diff --git a/components/script/dom/webidls/WebGL2RenderingContext.webidl b/components/script/dom/webidls/WebGL2RenderingContext.webidl index 72bd68a9f8a..c08bcb044b8 100644 --- a/components/script/dom/webidls/WebGL2RenderingContext.webidl +++ b/components/script/dom/webidls/WebGL2RenderingContext.webidl @@ -316,9 +316,9 @@ interface mixin WebGL2RenderingContextBase // void readBuffer(GLenum src); /* Renderbuffer objects */ - // any getInternalformatParameter(GLenum target, GLenum internalformat, GLenum pname); - // void renderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, - // GLsizei width, GLsizei height); + any getInternalformatParameter(GLenum target, GLenum internalformat, GLenum pname); + void renderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, + GLsizei width, GLsizei height); /* Texture objects */ // void texStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, |