From bc914381a8951f10bf028c31d50ab08b03a32ecf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1ty=C3=A1s=20Mustoha?= Date: Fri, 10 Jan 2020 11:47:25 +0100 Subject: 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 --- components/script/dom/webglrenderingcontext.rs | 112 ++++++++++++++----------- 1 file changed, 62 insertions(+), 50 deletions(-) (limited to 'components/script/dom/webglrenderingcontext.rs') 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(triple: (&WebGLRenderingContext, WebGLProgramId, i32), f: F) -> T +where + F: FnOnce(WebGLProgramId, i32, WebGLSender) -> 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(cx: *mut JSContext, value: &[T::Element]) -> JSVal +where + T: TypedArrayElementCreator, +{ + rooted!(in(cx) let mut rval = ptr::null_mut::()); + >::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(&self, location: Option<&WebGLUniformLocation>, f: F) + pub fn with_location(&self, location: Option<&WebGLUniformLocation>, f: F) where F: FnOnce(&WebGLUniformLocation) -> WebGLResult<()>, { @@ -1214,6 +1235,25 @@ impl WebGLRenderingContext { pub fn current_program(&self) -> Option> { 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(triple: (&WebGLRenderingContext, WebGLProgramId, i32), f: F) -> T - where - F: FnOnce(WebGLProgramId, i32, WebGLSender) -> 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(cx: *mut JSContext, value: &[T::Element]) -> JSVal - where - T: TypedArrayElementCreator, - { - rooted!(in(cx) let mut rval = ptr::null_mut::()); - >::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::(*cx, &get(triple, WebGLCommand::GetUniformInt2)) + uniform_typed::(*cx, &uniform_get(triple, WebGLCommand::GetUniformInt2)) }, constants::INT_VEC3 => unsafe { - typed::(*cx, &get(triple, WebGLCommand::GetUniformInt3)) + uniform_typed::(*cx, &uniform_get(triple, WebGLCommand::GetUniformInt3)) }, constants::INT_VEC4 => unsafe { - typed::(*cx, &get(triple, WebGLCommand::GetUniformInt4)) + uniform_typed::(*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::(*cx, &get(triple, WebGLCommand::GetUniformFloat2)) + uniform_typed::(*cx, &uniform_get(triple, WebGLCommand::GetUniformFloat2)) }, constants::FLOAT_VEC3 => unsafe { - typed::(*cx, &get(triple, WebGLCommand::GetUniformFloat3)) + uniform_typed::(*cx, &uniform_get(triple, WebGLCommand::GetUniformFloat3)) }, constants::FLOAT_VEC4 | constants::FLOAT_MAT2 => unsafe { - typed::(*cx, &get(triple, WebGLCommand::GetUniformFloat4)) + uniform_typed::(*cx, &uniform_get(triple, WebGLCommand::GetUniformFloat4)) }, constants::FLOAT_MAT3 => unsafe { - typed::(*cx, &get(triple, WebGLCommand::GetUniformFloat9)) + uniform_typed::(*cx, &uniform_get(triple, WebGLCommand::GetUniformFloat9)) }, constants::FLOAT_MAT4 => unsafe { - typed::(*cx, &get(triple, WebGLCommand::GetUniformFloat16)) + uniform_typed::(*cx, &uniform_get(triple, WebGLCommand::GetUniformFloat16)) }, _ => panic!("wrong uniform type"), } -- cgit v1.2.3