diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index bd2f8191720..7e48ba60d34 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -180,13 +180,21 @@ impl WebGLRenderingContext { .unwrap(); } + fn validate_stencil_actions(&self, action: u32) -> bool { + match action { + 0 | constants::KEEP | constants::REPLACE | constants::INCR | constants::DECR | + constants::INVERT | constants::INCR_WRAP | constants::DECR_WRAP => true, + _ => false, + } + } + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 // https://www.khronos.org/opengles/sdk/docs/man/xhtml/glUniform.xml // https://www.khronos.org/registry/gles/specs/2.0/es_full_spec_2.0.25.pdf#nameddest=section-2.10.4 fn validate_uniform_parameters(&self, - uniform: Option<&WebGLUniformLocation>, - uniform_type: UniformSetterType, - data: Option<&[T]>) -> bool { + uniform: Option<&WebGLUniformLocation>, + uniform_type: UniformSetterType, + data: Option<&[T]>) -> bool { let uniform = match uniform { Some(uniform) => uniform, None => return false, @@ -1219,6 +1227,82 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { .unwrap() } + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3 + fn StencilFunc(&self, func: u32, ref_: i32, mask: u32) { + match func { + constants::NEVER | constants::LESS | constants::EQUAL | constants::LEQUAL | + constants::GREATER | constants::NOTEQUAL | constants::GEQUAL | constants::ALWAYS => + self.ipc_renderer + .send(CanvasMsg::WebGL(WebGLCommand::StencilFunc(func, ref_, mask))) + .unwrap(), + _ => self.webgl_error(InvalidEnum), + } + } + + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3 + fn StencilFuncSeparate(&self, face: u32, func: u32, ref_: i32, mask: u32) { + match face { + constants::FRONT | constants::BACK | constants::FRONT_AND_BACK => (), + _ => return self.webgl_error(InvalidEnum), + } + + match func { + constants::NEVER | constants::LESS | constants::EQUAL | constants::LEQUAL | + constants::GREATER | constants::NOTEQUAL | constants::GEQUAL | constants::ALWAYS => + self.ipc_renderer + .send(CanvasMsg::WebGL(WebGLCommand::StencilFuncSeparate(face, func, ref_, mask))) + .unwrap(), + _ => self.webgl_error(InvalidEnum), + } + } + + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3 + fn StencilMask(&self, mask: u32) { + self.ipc_renderer + .send(CanvasMsg::WebGL(WebGLCommand::StencilMask(mask))) + .unwrap() + } + + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3 + fn StencilMaskSeparate(&self, face: u32, mask: u32) { + match face { + constants::FRONT | constants::BACK | constants::FRONT_AND_BACK => + self.ipc_renderer + .send(CanvasMsg::WebGL(WebGLCommand::StencilMaskSeparate(face, mask))) + .unwrap(), + _ => return self.webgl_error(InvalidEnum), + } + } + + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3 + fn StencilOp(&self, fail: u32, zfail: u32, zpass: u32) { + if self.validate_stencil_actions(fail) && self.validate_stencil_actions(zfail) && + self.validate_stencil_actions(zpass) { + self.ipc_renderer + .send(CanvasMsg::WebGL(WebGLCommand::StencilOp(fail, zfail, zpass))) + .unwrap() + } else { + self.webgl_error(InvalidEnum) + } + } + + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3 + fn StencilOpSeparate(&self, face: u32, fail: u32, zfail: u32, zpass: u32) { + match face { + constants::FRONT | constants::BACK | constants::FRONT_AND_BACK => (), + _ => return self.webgl_error(InvalidEnum), + } + + if self.validate_stencil_actions(fail) && self.validate_stencil_actions(zfail) && + self.validate_stencil_actions(zpass) { + self.ipc_renderer + .send(CanvasMsg::WebGL(WebGLCommand::StencilOpSeparate(face, fail, zfail, zpass))) + .unwrap() + } else { + self.webgl_error(InvalidEnum) + } + } + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 fn LinkProgram(&self, program: Option<&WebGLProgram>) { if let Some(program) = program { diff --git a/components/script/dom/webidls/WebGLRenderingContext.webidl b/components/script/dom/webidls/WebGLRenderingContext.webidl index 97cd853417f..4b29660b190 100644 --- a/components/script/dom/webidls/WebGLRenderingContext.webidl +++ b/components/script/dom/webidls/WebGLRenderingContext.webidl @@ -622,12 +622,12 @@ interface WebGLRenderingContextBase void shaderSource(WebGLShader? shader, DOMString source); - //void stencilFunc(GLenum func, GLint ref, GLuint mask); - //void stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask); - //void stencilMask(GLuint mask); - //void stencilMaskSeparate(GLenum face, GLuint mask); - //void stencilOp(GLenum fail, GLenum zfail, GLenum zpass); - //void stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass); + void stencilFunc(GLenum func, GLint ref, GLuint mask); + void stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask); + void stencilMask(GLuint mask); + void stencilMaskSeparate(GLenum face, GLuint mask); + void stencilOp(GLenum fail, GLenum zfail, GLenum zpass); + void stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass); //void texImage2D(GLenum target, GLint level, GLenum internalformat, // GLsizei width, GLsizei height, GLint border, GLenum format,