diff options
author | Mátyás Mustoha <matyas.mustoha@h-lab.eu> | 2020-01-10 11:47:25 +0100 |
---|---|---|
committer | Mátyás Mustoha <matyas.mustoha@h-lab.eu> | 2020-01-15 13:48:35 +0100 |
commit | bc914381a8951f10bf028c31d50ab08b03a32ecf (patch) | |
tree | 08efe61f3fbd7998fde1c8cc9d3e5d1d9b43743b /components/script/dom/webglrenderingcontext.rs | |
parent | c6192dc286ce0496b76998c900b48cdf7cdabdfe (diff) | |
download | servo-bc914381a8951f10bf028c31d50ab08b03a32ecf.tar.gz servo-bc914381a8951f10bf028c31d50ab08b03a32ecf.zip |
Add support for WebGL2 unsigned uniform operations
This adds support for the WebGL2 `uniform[1234]ui` and `uniform[1234]uiv`
operations.
See: https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.8
Diffstat (limited to 'components/script/dom/webglrenderingcontext.rs')
-rw-r--r-- | components/script/dom/webglrenderingcontext.rs | 112 |
1 files changed, 62 insertions, 50 deletions
diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index 68eccfa711d..cf01a53e0f3 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -114,6 +114,27 @@ fn has_invalid_blend_constants(arg1: u32, arg2: u32) -> bool { } } +pub fn uniform_get<T, F>(triple: (&WebGLRenderingContext, WebGLProgramId, i32), f: F) -> T +where + F: FnOnce(WebGLProgramId, i32, WebGLSender<T>) -> WebGLCommand, + T: for<'de> Deserialize<'de> + Serialize, +{ + let (sender, receiver) = webgl_channel().unwrap(); + triple.0.send_command(f(triple.1, triple.2, sender)); + receiver.recv().unwrap() +} + +#[allow(unsafe_code)] +pub unsafe fn uniform_typed<T>(cx: *mut JSContext, value: &[T::Element]) -> JSVal +where + T: TypedArrayElementCreator, +{ + rooted!(in(cx) let mut rval = ptr::null_mut::<JSObject>()); + <TypedArray<T, *mut JSObject>>::create(cx, CreateWith::Slice(&value), rval.handle_mut()) + .unwrap(); + ObjectValue(rval.get()) +} + bitflags! { /// Set of bitflags for texture unpacking (texImage2d, etc...) #[derive(JSTraceable, MallocSizeOf)] @@ -401,7 +422,7 @@ impl WebGLRenderingContext { Ok(()) } - fn with_location<F>(&self, location: Option<&WebGLUniformLocation>, f: F) + pub fn with_location<F>(&self, location: Option<&WebGLUniformLocation>, f: F) where F: FnOnce(&WebGLUniformLocation) -> WebGLResult<()>, { @@ -1214,6 +1235,25 @@ impl WebGLRenderingContext { pub fn current_program(&self) -> Option<DomRoot<WebGLProgram>> { self.current_program.get() } + + pub fn uniform_check_program( + &self, + program: &WebGLProgram, + location: &WebGLUniformLocation, + ) -> WebGLResult<()> { + self.validate_ownership(program)?; + + if program.is_deleted() || + !program.is_linked() || + self.context_id() != location.context_id() || + program.id() != location.program_id() || + program.link_generation() != location.link_generation() + { + return Err(InvalidOperation); + } + + Ok(()) + } } #[cfg(not(feature = "webgl_backtrace"))] @@ -3548,88 +3588,60 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { program: &WebGLProgram, location: &WebGLUniformLocation, ) -> JSVal { - handle_potential_webgl_error!(self, self.validate_ownership(program), return NullValue()); - - if program.is_deleted() || - !program.is_linked() || - self.context_id() != location.context_id() || - program.id() != location.program_id() || - program.link_generation() != location.link_generation() - { - self.webgl_error(InvalidOperation); - return NullValue(); - } - - fn get<T, F>(triple: (&WebGLRenderingContext, WebGLProgramId, i32), f: F) -> T - where - F: FnOnce(WebGLProgramId, i32, WebGLSender<T>) -> WebGLCommand, - T: for<'de> Deserialize<'de> + Serialize, - { - let (sender, receiver) = webgl_channel().unwrap(); - triple.0.send_command(f(triple.1, triple.2, sender)); - receiver.recv().unwrap() - } + handle_potential_webgl_error!( + self, + self.uniform_check_program(program, location), + return NullValue() + ); let triple = (self, program.id(), location.id()); - unsafe fn typed<T>(cx: *mut JSContext, value: &[T::Element]) -> JSVal - where - T: TypedArrayElementCreator, - { - rooted!(in(cx) let mut rval = ptr::null_mut::<JSObject>()); - <TypedArray<T, *mut JSObject>>::create( - cx, - CreateWith::Slice(&value), - rval.handle_mut(), - ) - .unwrap(); - ObjectValue(rval.get()) - } - match location.type_() { - constants::BOOL => BooleanValue(get(triple, WebGLCommand::GetUniformBool)), + constants::BOOL => BooleanValue(uniform_get(triple, WebGLCommand::GetUniformBool)), constants::BOOL_VEC2 => unsafe { rooted!(in(*cx) let mut rval = NullValue()); - get(triple, WebGLCommand::GetUniformBool2).to_jsval(*cx, rval.handle_mut()); + uniform_get(triple, WebGLCommand::GetUniformBool2).to_jsval(*cx, rval.handle_mut()); rval.get() }, constants::BOOL_VEC3 => unsafe { rooted!(in(*cx) let mut rval = NullValue()); - get(triple, WebGLCommand::GetUniformBool3).to_jsval(*cx, rval.handle_mut()); + uniform_get(triple, WebGLCommand::GetUniformBool3).to_jsval(*cx, rval.handle_mut()); rval.get() }, constants::BOOL_VEC4 => unsafe { rooted!(in(*cx) let mut rval = NullValue()); - get(triple, WebGLCommand::GetUniformBool4).to_jsval(*cx, rval.handle_mut()); + uniform_get(triple, WebGLCommand::GetUniformBool4).to_jsval(*cx, rval.handle_mut()); rval.get() }, constants::INT | constants::SAMPLER_2D | constants::SAMPLER_CUBE => { - Int32Value(get(triple, WebGLCommand::GetUniformInt)) + Int32Value(uniform_get(triple, WebGLCommand::GetUniformInt)) }, constants::INT_VEC2 => unsafe { - typed::<Int32>(*cx, &get(triple, WebGLCommand::GetUniformInt2)) + uniform_typed::<Int32>(*cx, &uniform_get(triple, WebGLCommand::GetUniformInt2)) }, constants::INT_VEC3 => unsafe { - typed::<Int32>(*cx, &get(triple, WebGLCommand::GetUniformInt3)) + uniform_typed::<Int32>(*cx, &uniform_get(triple, WebGLCommand::GetUniformInt3)) }, constants::INT_VEC4 => unsafe { - typed::<Int32>(*cx, &get(triple, WebGLCommand::GetUniformInt4)) + uniform_typed::<Int32>(*cx, &uniform_get(triple, WebGLCommand::GetUniformInt4)) + }, + constants::FLOAT => { + DoubleValue(uniform_get(triple, WebGLCommand::GetUniformFloat) as f64) }, - constants::FLOAT => DoubleValue(get(triple, WebGLCommand::GetUniformFloat) as f64), constants::FLOAT_VEC2 => unsafe { - typed::<Float32>(*cx, &get(triple, WebGLCommand::GetUniformFloat2)) + uniform_typed::<Float32>(*cx, &uniform_get(triple, WebGLCommand::GetUniformFloat2)) }, constants::FLOAT_VEC3 => unsafe { - typed::<Float32>(*cx, &get(triple, WebGLCommand::GetUniformFloat3)) + uniform_typed::<Float32>(*cx, &uniform_get(triple, WebGLCommand::GetUniformFloat3)) }, constants::FLOAT_VEC4 | constants::FLOAT_MAT2 => unsafe { - typed::<Float32>(*cx, &get(triple, WebGLCommand::GetUniformFloat4)) + uniform_typed::<Float32>(*cx, &uniform_get(triple, WebGLCommand::GetUniformFloat4)) }, constants::FLOAT_MAT3 => unsafe { - typed::<Float32>(*cx, &get(triple, WebGLCommand::GetUniformFloat9)) + uniform_typed::<Float32>(*cx, &uniform_get(triple, WebGLCommand::GetUniformFloat9)) }, constants::FLOAT_MAT4 => unsafe { - typed::<Float32>(*cx, &get(triple, WebGLCommand::GetUniformFloat16)) + uniform_typed::<Float32>(*cx, &uniform_get(triple, WebGLCommand::GetUniformFloat16)) }, _ => panic!("wrong uniform type"), } |