diff options
Diffstat (limited to 'components/script/dom/webglrenderingcontext.rs')
-rw-r--r-- | components/script/dom/webglrenderingcontext.rs | 94 |
1 files changed, 93 insertions, 1 deletions
diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index 64990da1504..ad572751607 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -10,6 +10,7 @@ use canvas_traits::webgl::DOMToTextureCommand; use canvas_traits::webgl::WebGLError::*; use canvas_traits::webgl::webgl_channel; use dom::bindings::cell::DomRefCell; +use dom::bindings::codegen::Bindings::WebGL2RenderingContextBinding::WebGL2RenderingContextConstants as WebGL2Constants; use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::{self, WebGLContextAttributes}; use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants; use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextMethods; @@ -33,7 +34,7 @@ use dom::webgl_validations::types::{TexDataType, TexFormat, TexImageTarget}; use dom::webglactiveinfo::WebGLActiveInfo; use dom::webglbuffer::WebGLBuffer; use dom::webglcontextevent::WebGLContextEvent; -use dom::webglframebuffer::WebGLFramebuffer; +use dom::webglframebuffer::{WebGLFramebuffer, WebGLFramebufferAttachmentRoot}; use dom::webglprogram::WebGLProgram; use dom::webglrenderbuffer::WebGLRenderbuffer; use dom::webglshader::WebGLShader; @@ -1554,6 +1555,10 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6 fn BindFramebuffer(&self, target: u32, framebuffer: Option<&WebGLFramebuffer>) { + if target == WebGL2Constants::READ_FRAMEBUFFER { + return self.webgl_error(InvalidEnum); + } + if target != constants::FRAMEBUFFER { return self.webgl_error(InvalidOperation); } @@ -2297,6 +2302,93 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { } } + #[allow(unsafe_code)] + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6 + unsafe fn GetFramebufferAttachmentParameter( + &self, + cx: *mut JSContext, + target: u32, + attachment: u32, + pname: u32 + ) -> JSVal { + // Check if currently bound framebuffer is non-zero as per spec. + if self.bound_framebuffer.get().is_none() { + self.webgl_error(InvalidOperation); + return NullValue(); + } + + // Note: commented out stuff is for the WebGL2 standard. + let target_matches = match target { + // constants::READ_FRAMEBUFFER | + // constants::DRAW_FRAMEBUFFER => true, + constants::FRAMEBUFFER => true, + _ => false + }; + let attachment_matches = match attachment { + // constants::MAX_COLOR_ATTACHMENTS ... gl::COLOR_ATTACHMENT0 | + // constants::BACK | + constants::COLOR_ATTACHMENT0 | + constants::DEPTH_STENCIL_ATTACHMENT | + constants::DEPTH_ATTACHMENT | + constants::STENCIL_ATTACHMENT => true, + _ => false, + }; + let pname_matches = match pname { + // constants::FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE | + // constants::FRAMEBUFFER_ATTACHMENT_BLUE_SIZE | + // constants::FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING | + // constants::FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE | + // constants::FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE | + // constants::FRAMEBUFFER_ATTACHMENT_GREEN_SIZE | + // constants::FRAMEBUFFER_ATTACHMENT_RED_SIZE | + // constants::FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE | + // constants::FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER | + constants::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME | + constants::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE | + constants::FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE | + constants::FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL => true, + _ => false + }; + + if !target_matches || !attachment_matches || !pname_matches { + self.webgl_error(InvalidEnum); + return NullValue(); + } + + // From the GLES2 spec: + // + // If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is NONE, + // then querying any other pname will generate INVALID_ENUM. + // + // otherwise, return `WebGLRenderbuffer` or `WebGLTexture` dom object + if pname == constants::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME { + // if fb is None, an INVALID_OPERATION is returned + // at the beggining of the function, so `.unwrap()` will never panic + let fb = self.bound_framebuffer.get().unwrap(); + if let Some(webgl_attachment) = fb.attachment(attachment) { + match webgl_attachment { + WebGLFramebufferAttachmentRoot::Renderbuffer(rb) => { + rooted!(in(cx) let mut rval = NullValue()); + rb.to_jsval(cx, rval.handle_mut()); + return rval.get(); + }, + WebGLFramebufferAttachmentRoot::Texture(texture) => { + rooted!(in(cx) let mut rval = NullValue()); + texture.to_jsval(cx, rval.handle_mut()); + return rval.get(); + }, + } + } + self.webgl_error(InvalidEnum); + return NullValue(); + } + + let (sender, receiver) = webgl_channel().unwrap(); + self.send_command(WebGLCommand::GetFramebufferAttachmentParameter(target, attachment, pname, sender)); + + Int32Value(receiver.recv().unwrap()) + } + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 fn GetProgramInfoLog(&self, program: Option<&WebGLProgram>) -> Option<DOMString> { if let Some(program) = program { |