aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2020-03-13 16:29:13 -0400
committerGitHub <noreply@github.com>2020-03-13 16:29:13 -0400
commita6736de09944e343344626a6e4233629a78678b2 (patch)
treea67e9da61ddff0f9f3465e9b715297063615b9c6 /components/script/dom
parent13a349603d986f969f522a676f356702aa69d5ac (diff)
parent6cdbab5581b642bf44ea18cb1714892962ddbaa9 (diff)
downloadservo-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.rs62
-rw-r--r--components/script/dom/webglrenderbuffer.rs40
-rw-r--r--components/script/dom/webglrenderingcontext.rs59
-rw-r--r--components/script/dom/webidls/WebGL2RenderingContext.webidl6
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,