mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
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
This commit is contained in:
parent
d42835b238
commit
cc07d930c8
10 changed files with 127 additions and 148 deletions
|
@ -35,7 +35,7 @@ raqote = {git = "https://github.com/jrmuizel/raqote"}
|
|||
time = { version = "0.1.0", optional = true }
|
||||
pixels = {path = "../pixels"}
|
||||
servo_config = {path = "../config"}
|
||||
sparkle = "0.1.17"
|
||||
sparkle = "0.1.19"
|
||||
webrender = {git = "https://github.com/servo/webrender"}
|
||||
webrender_api = {git = "https://github.com/servo/webrender"}
|
||||
webrender_traits = {path = "../webrender_traits"}
|
||||
|
|
|
@ -1968,6 +1968,12 @@ impl WebGLImpl {
|
|||
WebGLCommand::ClearBufferfi(buffer, draw_buffer, depth, stencil) => {
|
||||
gl.clear_buffer_fi(buffer, draw_buffer, depth, stencil)
|
||||
},
|
||||
WebGLCommand::InvalidateFramebuffer(target, ref attachments) => {
|
||||
gl.invalidate_framebuffer(target, attachments)
|
||||
},
|
||||
WebGLCommand::InvalidateSubFramebuffer(target, ref attachments, x, y, w, h) => {
|
||||
gl.invalidate_sub_framebuffer(target, attachments, x, y, w, h)
|
||||
},
|
||||
}
|
||||
|
||||
// If debug asertions are enabled, then check the error state.
|
||||
|
|
|
@ -533,6 +533,8 @@ pub enum WebGLCommand {
|
|||
ClearBufferiv(u32, i32, Vec<i32>),
|
||||
ClearBufferuiv(u32, i32, Vec<u32>),
|
||||
ClearBufferfi(u32, i32, f32, i32),
|
||||
InvalidateFramebuffer(u32, Vec<u32>),
|
||||
InvalidateSubFramebuffer(u32, Vec<u32>, i32, i32, i32, i32),
|
||||
}
|
||||
|
||||
macro_rules! nonzero_type {
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue