Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for WebGL2 getFramebufferAttachmentParameter #25785

Merged
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Add support for WebGL2 getFramebufferAttachmentParameter

Implements the WebGL2 variant of `getFramebufferAttachmentParameter`
and the related parameter checks.

See: https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.4
  • Loading branch information
mmatyas committed Feb 21, 2020
commit d5d0a788e315530de7e738643652b0adf10e2c80
@@ -21,7 +21,7 @@ use crate::dom::htmlcanvaselement::HTMLCanvasElement;
use crate::dom::htmliframeelement::HTMLIFrameElement;
use crate::dom::webglactiveinfo::WebGLActiveInfo;
use crate::dom::webglbuffer::WebGLBuffer;
use crate::dom::webglframebuffer::WebGLFramebuffer;
use crate::dom::webglframebuffer::{WebGLFramebuffer, WebGLFramebufferAttachmentRoot};
use crate::dom::webglprogram::WebGLProgram;
use crate::dom::webglquery::WebGLQuery;
use crate::dom::webglrenderbuffer::WebGLRenderbuffer;
@@ -406,6 +406,157 @@ impl WebGL2RenderingContext {
self.base
.uniform_vec_section::<u32>(vec, offset, length, uniform_size, uniform_location)
}

#[allow(unsafe_code)]
fn get_default_fb_attachment_param(&self, attachment: u32, pname: u32) -> WebGLResult<JSVal> {
match attachment {
constants::BACK | constants::DEPTH | constants::STENCIL => {},
_ => return Err(InvalidEnum),
}

if pname == constants::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME {
return Ok(NullValue());
}

let attrs = self
.GetContextAttributes()
.unwrap_or_else(WebGLContextAttributes::empty);

let intval = match pname {
constants::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE => match attachment {
constants::DEPTH if !attrs.depth => constants::NONE as _,
constants::STENCIL if !attrs.stencil => constants::NONE as _,
_ => constants::FRAMEBUFFER_DEFAULT as _,
},
constants::FRAMEBUFFER_ATTACHMENT_RED_SIZE |
constants::FRAMEBUFFER_ATTACHMENT_GREEN_SIZE |
constants::FRAMEBUFFER_ATTACHMENT_BLUE_SIZE => match attachment {
constants::BACK => 8,
_ => 0,
},
constants::FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE => match attachment {
constants::BACK if attrs.alpha => 8,
constants::BACK => return Err(InvalidOperation),
_ => 0,
},
constants::FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE => match attachment {
constants::DEPTH if attrs.depth => 24,
constants::DEPTH => return Err(InvalidOperation),
_ => 0,
},
constants::FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE => match attachment {
constants::STENCIL if attrs.stencil => 8,
constants::STENCIL => return Err(InvalidOperation),
_ => 0,
},
constants::FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE => match attachment {
constants::DEPTH if attrs.depth => constants::UNSIGNED_NORMALIZED as _,
constants::STENCIL if attrs.stencil => constants::UNSIGNED_INT as _,
constants::DEPTH => return Err(InvalidOperation),
constants::STENCIL => return Err(InvalidOperation),
_ => constants::UNSIGNED_NORMALIZED as _,
},
constants::FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING => match attachment {
constants::DEPTH if !attrs.depth => return Err(InvalidOperation),
constants::STENCIL if !attrs.stencil => return Err(InvalidOperation),
_ => constants::LINEAR as _,
},
_ => return Err(InvalidEnum),
};
Ok(Int32Value(intval))
}

#[allow(unsafe_code)]
fn get_specific_fb_attachment_param(
&self,
cx: JSContext,
fb: &WebGLFramebuffer,
target: u32,
attachment: u32,
pname: u32,
) -> WebGLResult<JSVal> {
use crate::dom::webglframebuffer::WebGLFramebufferAttachmentRoot::{Renderbuffer, Texture};

match attachment {
constants::DEPTH_ATTACHMENT | constants::STENCIL_ATTACHMENT => {},
constants::DEPTH_STENCIL_ATTACHMENT => {
if pname == constants::FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE {
return Err(InvalidOperation);
}

let a = fb.attachment(constants::DEPTH_ATTACHMENT);
let b = fb.attachment(constants::STENCIL_ATTACHMENT);
match (a, b) {
(Some(Renderbuffer(ref a)), Some(Renderbuffer(ref b))) if a.id() == b.id() => {
},
(Some(Texture(ref a)), Some(Texture(ref b))) if a.id() == b.id() => {},
_ => return Err(InvalidOperation),
}
},
constants::COLOR_ATTACHMENT0..=constants::COLOR_ATTACHMENT15 => {
let last_slot =
constants::COLOR_ATTACHMENT0 + self.base.limits().max_color_attachments - 1;
if last_slot < attachment {
return Err(InvalidEnum);
}
},
_ => return Err(InvalidEnum),
}

let attachment = match attachment {
constants::DEPTH_STENCIL_ATTACHMENT => constants::DEPTH_ATTACHMENT,
_ => attachment,
};

if pname == constants::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME {
rooted!(in(*cx) let mut rval = NullValue());
match fb.attachment(attachment) {
Some(Renderbuffer(rb)) => unsafe {
rb.to_jsval(*cx, rval.handle_mut());
},
Some(Texture(texture)) => unsafe {
texture.to_jsval(*cx, rval.handle_mut());
},
_ => {},
}
return Ok(rval.get());
}

match pname {
constants::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE => {},
_ => match fb.attachment(attachment) {
Some(webgl_attachment) => match pname {
constants::FRAMEBUFFER_ATTACHMENT_RED_SIZE |
constants::FRAMEBUFFER_ATTACHMENT_GREEN_SIZE |
constants::FRAMEBUFFER_ATTACHMENT_BLUE_SIZE |
constants::FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE |
constants::FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE |
constants::FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE |
constants::FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE |
constants::FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING => {},
_ => match webgl_attachment {
WebGLFramebufferAttachmentRoot::Renderbuffer(_) => return Err(InvalidEnum),
WebGLFramebufferAttachmentRoot::Texture(_) => match pname {
constants::FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL |
constants::FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE |
constants::FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER => {},
_ => return Err(InvalidEnum),
},
},
},
None => return Err(InvalidOperation),
},
}

let (sender, receiver) = webgl_channel().unwrap();
self.base
.send_command(WebGLCommand::GetFramebufferAttachmentParameter(
target, attachment, pname, sender,
));

let retval = receiver.recv().unwrap();
Ok(Int32Value(retval))
}
}

impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
@@ -586,8 +737,33 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
attachment: u32,
pname: u32,
) -> JSVal {
self.base
.GetFramebufferAttachmentParameter(cx, target, attachment, pname)
let fb_slot = match target {
constants::FRAMEBUFFER | constants::DRAW_FRAMEBUFFER => {
self.base.get_draw_framebuffer_slot()
},
constants::READ_FRAMEBUFFER => &self.base.get_read_framebuffer_slot(),
_ => {
self.base.webgl_error(InvalidEnum);
return NullValue();
},
};

if let Some(fb) = fb_slot.get() {
// A selected framebuffer is bound to the target
handle_potential_webgl_error!(self.base, fb.validate_transparent(), return NullValue());
handle_potential_webgl_error!(
self.base,
self.get_specific_fb_attachment_param(cx, &fb, target, attachment, pname),
return NullValue()
)
} else {
// The default framebuffer is bound to the target
handle_potential_webgl_error!(
self.base,
self.get_default_fb_attachment_param(attachment, pname),
return NullValue()
)
}
}

/// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.7
@@ -1,43 +1,13 @@
[framebuffer-object-attachment.html]
[WebGL test #13: checkFramebufferStatus expects [FRAMEBUFFER_COMPLETE\], was FRAMEBUFFER_INCOMPLETE_ATTACHMENT]
expected: FAIL

[WebGL test #20: checkFramebufferStatus expects [FRAMEBUFFER_COMPLETE\], was FRAMEBUFFER_INCOMPLETE_ATTACHMENT]
expected: FAIL

[WebGL test #30: getError expected: NO_ERROR. Was INVALID_ENUM : ]
expected: FAIL

[WebGL test #21: checkFramebufferStatus expects [FRAMEBUFFER_COMPLETE\], was FRAMEBUFFER_UNSUPPORTED]
expected: FAIL

[WebGL test #25: checkFramebufferStatus expects [FRAMEBUFFER_COMPLETE\], was FRAMEBUFFER_UNSUPPORTED]
expected: FAIL

[WebGL test #23: checkFramebufferStatus expects [FRAMEBUFFER_COMPLETE\], was FRAMEBUFFER_UNSUPPORTED]
expected: FAIL

[WebGL test #24: checkFramebufferStatus expects [FRAMEBUFFER_COMPLETE\], was FRAMEBUFFER_UNSUPPORTED]
expected: FAIL

[WebGL test #22: checkFramebufferStatus expects [FRAMEBUFFER_COMPLETE\], was FRAMEBUFFER_UNSUPPORTED]
expected: FAIL

[WebGL test #14: getError expected: NO_ERROR. Was INVALID_ENUM : ]
expected: FAIL

[WebGL test #16: gl.getParameter(gl.RED_BITS) + gl.getParameter(gl.GREEN_BITS) + gl.getParameter(gl.BLUE_BITS) + gl.getParameter(gl.ALPHA_BITS) >= 16 should be true. Was false.]
expected: FAIL

[WebGL test #59: getError expected: NO_ERROR. Was INVALID_ENUM : Query should not generate error]
expected: FAIL

[WebGL test #13: gl.getParameter(gl.RED_BITS) + gl.getParameter(gl.GREEN_BITS) + gl.getParameter(gl.BLUE_BITS) + gl.getParameter(gl.ALPHA_BITS) >= 16 should be true. Was false.]
expected: FAIL

[WebGL test #10: checkFramebufferStatus expects [FRAMEBUFFER_COMPLETE\], was FRAMEBUFFER_INCOMPLETE_ATTACHMENT]
expected: FAIL

[WebGL test #20: checkFramebufferStatus expects [FRAMEBUFFER_COMPLETE\], was FRAMEBUFFER_INCOMPLETE_ATTACHMENT]
expected: FAIL

[WebGL test #21: checkFramebufferStatus expects [FRAMEBUFFER_COMPLETE\], was FRAMEBUFFER_INCOMPLETE_ATTACHMENT]
expected: FAIL

@@ -53,9 +23,6 @@
[WebGL test #19: checkFramebufferStatus expects [FRAMEBUFFER_COMPLETE\], was FRAMEBUFFER_INCOMPLETE_ATTACHMENT]
expected: FAIL

[WebGL test #56: getError expected: NO_ERROR. Was INVALID_ENUM : Query should not generate error]
expected: FAIL

[WebGL test #22: checkFramebufferStatus expects [FRAMEBUFFER_COMPLETE\], was FRAMEBUFFER_INCOMPLETE_ATTACHMENT]
expected: FAIL

@@ -2,63 +2,3 @@
[WebGL test #38: getError expected: INVALID_OPERATION. Was INVALID_ENUM : getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) on read framebuffer with no attachment.]
expected: FAIL

[WebGL test #1: getError expected: INVALID_ENUM. Was INVALID_OPERATION : getFramebufferAttachmentParameter(COLOR_ATTACHMENT0) on the default framebuffer.]
expected: FAIL

[WebGL test #33: getError expected: NO_ERROR. Was INVALID_ENUM : getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) on read/draw framebuffer.]
expected: FAIL

[WebGL test #42: getError expected: NO_ERROR. Was INVALID_ENUM : getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) on read/draw framebuffer.]
expected: FAIL

[WebGL test #51: getError expected: INVALID_OPERATION. Was INVALID_ENUM : getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE) on read framebuffer without depth attachment.]
expected: FAIL

[WebGL test #40: getError expected: INVALID_OPERATION. Was INVALID_ENUM : getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) on draw framebuffer with no attachment.]
expected: FAIL

[WebGL test #46: getError expected: NO_ERROR. Was INVALID_ENUM : getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) on read/draw framebuffer.]
expected: FAIL

[WebGL test #54: getError expected: INVALID_OPERATION. Was INVALID_ENUM : getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_RED_SIZE) on read framebuffer with no attachment.]
expected: FAIL

[WebGL test #20: getError expected: INVALID_OPERATION. Was INVALID_ENUM : getFramebufferAttachmentParameter(GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) with no attachment.]
expected: FAIL

[WebGL test #53: getError expected: INVALID_OPERATION. Was INVALID_ENUM : getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_RED_SIZE) on draw framebuffer without color attachment.]
expected: FAIL

[WebGL test #37: gl.getFramebufferAttachmentParameter(gl.DRAW_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_BLUE_SIZE) should be 0 (of type number). Was null (of type object).]
expected: FAIL

[WebGL test #2: getError expected: NO_ERROR. Was INVALID_OPERATION : getFramebufferAttachmentParameter(BACK) on the default framebuffer.]
expected: FAIL

[WebGL test #56: getError expected: INVALID_OPERATION. Was INVALID_ENUM : getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE) on draw framebuffer with no attachment.]
expected: FAIL

[WebGL test #15: getError expected: NO_ERROR. Was INVALID_ENUM : getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE) with no attachment.]
expected: FAIL

[WebGL test #29: getError expected: NO_ERROR. Was INVALID_ENUM : getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) on read/draw framebuffer.]
expected: FAIL

[WebGL test #43: getError expected: INVALID_OPERATION. Was INVALID_ENUM : getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) on read/draw framebuffer with no attachment.]
expected: FAIL

[WebGL test #34: getError expected: INVALID_OPERATION. Was INVALID_ENUM : getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) on read/draw framebuffer with no attachment.]
expected: FAIL

[WebGL test #47: getError expected: INVALID_OPERATION. Was INVALID_ENUM : getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) on read/draw framebuffer with no attachment.]
expected: FAIL

[WebGL test #39: getError expected: NO_ERROR. Was INVALID_ENUM : getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) on draw framebuffer.]
expected: FAIL

[WebGL test #9: getError expected: NO_ERROR. Was INVALID_ENUM : getFramebufferAttachmentParameter(READ_FRAMEBUFFER).]
expected: FAIL

[WebGL test #30: getError expected: INVALID_OPERATION. Was INVALID_ENUM : getFramebufferAttachmentParameter(FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING) on read/draw framebuffer with no attachment.]
expected: FAIL

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.