aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/webglrenderingcontext.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/webglrenderingcontext.rs')
-rw-r--r--components/script/dom/webglrenderingcontext.rs94
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 {