aboutsummaryrefslogtreecommitdiffstats
path: root/components/script
diff options
context:
space:
mode:
authorMátyás Mustoha <matyas.mustoha@h-lab.eu>2020-02-14 13:14:07 +0100
committerMátyás Mustoha <matyas.mustoha@h-lab.eu>2020-03-03 14:54:17 +0100
commitcc07d930c8aa92a27c4c5d8867ae090a5dc46f6b (patch)
treedb1e3e5efe9429bbf8b74e9a237ca2aa37f28a71 /components/script
parentd42835b238cc8a086f08e9901e19b81bc5d75be3 (diff)
downloadservo-cc07d930c8aa92a27c4c5d8867ae090a5dc46f6b.tar.gz
servo-cc07d930c8aa92a27c4c5d8867ae090a5dc46f6b.zip
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
Diffstat (limited to 'components/script')
-rw-r--r--components/script/dom/webgl2renderingcontext.rs84
-rw-r--r--components/script/dom/webidls/WebGL2RenderingContext.webidl6
2 files changed, 87 insertions, 3 deletions
diff --git a/components/script/dom/webgl2renderingcontext.rs b/components/script/dom/webgl2renderingcontext.rs
index cc735f36e41..f3c88cbb7c8 100644
--- a/components/script/dom/webgl2renderingcontext.rs
+++ b/components/script/dom/webgl2renderingcontext.rs
@@ -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> {
diff --git a/components/script/dom/webidls/WebGL2RenderingContext.webidl b/components/script/dom/webidls/WebGL2RenderingContext.webidl
index 23686adb211..6043c49cec3 100644
--- a/components/script/dom/webidls/WebGL2RenderingContext.webidl
+++ b/components/script/dom/webidls/WebGL2RenderingContext.webidl
@@ -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 */