Auto merge of #25798 - szeged:mmatyas__webgl_fns_framebuf_invalidate, r=jdm

Add support for WebGL2 framebuffer invalidation

Adds support for the `invalidateFramebuffer` and `invalideSubFramebuffer` WebGL2 calls.

See: https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.4

<!-- Please describe your changes on the following line: -->

Depends on #25785.

cc @jdm @zakorgy

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [x] There are tests for these changes

<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
This commit is contained in:
bors-servo 2020-03-03 11:34:23 -05:00 committed by GitHub
commit 56b5d9d048
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 127 additions and 148 deletions

View file

@ -603,6 +603,51 @@ impl WebGL2RenderingContext {
self.base.send_command(msg(buffer, draw_buffer, array));
}
fn valid_fb_attachment_values(&self, target: u32, attachments: &[u32]) -> bool {
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 false;
},
};
if let Some(fb) = fb_slot.get() {
if fb.check_status() != constants::FRAMEBUFFER_COMPLETE {
return false;
}
for &attachment in attachments {
match attachment {
constants::DEPTH_ATTACHMENT |
constants::STENCIL_ATTACHMENT |
constants::DEPTH_STENCIL_ATTACHMENT => {},
constants::COLOR_ATTACHMENT0..=constants::COLOR_ATTACHMENT15 => {
let last_slot = constants::COLOR_ATTACHMENT0 +
self.base.limits().max_color_attachments -
1;
if last_slot < attachment {
return false;
}
},
_ => return false,
}
}
} else {
for &attachment in attachments {
match attachment {
constants::COLOR | constants::DEPTH | constants::STENCIL => {},
_ => return false,
}
}
}
true
}
}
impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
@ -3497,6 +3542,45 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext {
stencil,
));
}
/// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.4
fn InvalidateFramebuffer(&self, target: u32, attachments: Vec<u32>) {
if !self.valid_fb_attachment_values(target, &attachments) {
return;
}
self.base
.send_command(WebGLCommand::InvalidateFramebuffer(target, attachments))
}
/// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.4
fn InvalidateSubFramebuffer(
&self,
target: u32,
attachments: Vec<u32>,
x: i32,
y: i32,
width: i32,
height: i32,
) {
if !self.valid_fb_attachment_values(target, &attachments) {
return;
}
if width < 0 || height < 0 {
return;
}
self.base
.send_command(WebGLCommand::InvalidateSubFramebuffer(
target,
attachments,
x,
y,
width,
height,
))
}
}
impl LayoutCanvasWebGLRenderingContextHelpers for LayoutDom<WebGL2RenderingContext> {

View file

@ -314,9 +314,9 @@ interface mixin WebGL2RenderingContextBase
// GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
// void framebufferTextureLayer(GLenum target, GLenum attachment, WebGLTexture? texture, GLint level,
// GLint layer);
// void invalidateFramebuffer(GLenum target, sequence<GLenum> attachments);
// void invalidateSubFramebuffer(GLenum target, sequence<GLenum> attachments,
// GLint x, GLint y, GLsizei width, GLsizei height);
void invalidateFramebuffer(GLenum target, sequence<GLenum> attachments);
void invalidateSubFramebuffer(GLenum target, sequence<GLenum> attachments,
GLint x, GLint y, GLsizei width, GLsizei height);
// void readBuffer(GLenum src);
/* Renderbuffer objects */