mirror of
https://github.com/servo/servo.git
synced 2025-07-22 23:03:42 +01:00
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
This commit is contained in:
parent
afb1faf80f
commit
d5d0a788e3
3 changed files with 182 additions and 99 deletions
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue