aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/webglframebuffer.rs
diff options
context:
space:
mode:
authorJosh Matthews <josh@joshmatthews.net>2018-08-22 14:50:11 -0400
committerJosh Matthews <josh@joshmatthews.net>2018-09-10 15:56:16 -0400
commitda3b0ef88f52d61f4f94f2fa70099d42aebae061 (patch)
tree318759cf7b97fdd9a7d702a326ad40134d9b697f /components/script/dom/webglframebuffer.rs
parent944d1d1f291f878cbb472ca77c473076f1d7a1ab (diff)
downloadservo-da3b0ef88f52d61f4f94f2fa70099d42aebae061.tar.gz
servo-da3b0ef88f52d61f4f94f2fa70099d42aebae061.zip
webgl: Clear renderbuffers on first read/write operation.
Diffstat (limited to 'components/script/dom/webglframebuffer.rs')
-rw-r--r--components/script/dom/webglframebuffer.rs45
1 files changed, 41 insertions, 4 deletions
diff --git a/components/script/dom/webglframebuffer.rs b/components/script/dom/webglframebuffer.rs
index fa66d61429f..de659e6ebd3 100644
--- a/components/script/dom/webglframebuffer.rs
+++ b/components/script/dom/webglframebuffer.rs
@@ -25,6 +25,15 @@ enum WebGLFramebufferAttachment {
Texture { texture: Dom<WebGLTexture>, level: i32 },
}
+impl WebGLFramebufferAttachment {
+ fn needs_initialization(&self) -> bool {
+ match *self {
+ WebGLFramebufferAttachment::Renderbuffer(_) => true,
+ WebGLFramebufferAttachment::Texture { .. } => false,
+ }
+ }
+}
+
#[derive(Clone, JSTraceable, MallocSizeOf)]
pub enum WebGLFramebufferAttachmentRoot {
Renderbuffer(DomRoot<WebGLRenderbuffer>),
@@ -46,6 +55,7 @@ pub struct WebGLFramebuffer {
depth: DomRefCell<Option<WebGLFramebufferAttachment>>,
stencil: DomRefCell<Option<WebGLFramebufferAttachment>>,
depthstencil: DomRefCell<Option<WebGLFramebufferAttachment>>,
+ is_initialized: Cell<bool>,
}
impl WebGLFramebuffer {
@@ -61,6 +71,7 @@ impl WebGLFramebuffer {
depth: DomRefCell::new(None),
stencil: DomRefCell::new(None),
depthstencil: DomRefCell::new(None),
+ is_initialized: Cell::new(false),
}
}
@@ -205,12 +216,36 @@ impl WebGLFramebuffer {
pub fn check_status_for_rendering(&self) -> u32 {
let result = self.check_status();
- if result == constants::FRAMEBUFFER_COMPLETE {
- if self.color.borrow().is_none() {
- return constants::FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+ if result != constants::FRAMEBUFFER_COMPLETE {
+ return result;
+ }
+
+ if self.color.borrow().is_none() {
+ return constants::FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
+ }
+
+ if !self.is_initialized.get() {
+ let attachments = [
+ (&self.color, constants::COLOR_BUFFER_BIT),
+ (&self.depth, constants::DEPTH_BUFFER_BIT),
+ (&self.stencil, constants::STENCIL_BUFFER_BIT),
+ (&self.depthstencil, constants::DEPTH_BUFFER_BIT | constants::STENCIL_BUFFER_BIT)
+ ];
+ let mut clear_bits = 0;
+ for &(attachment, bits) in &attachments {
+ if attachment.borrow().as_ref().map_or(false, |att| att.needs_initialization()) {
+ clear_bits |= bits;
+ }
}
+ if clear_bits != 0 {
+ self.upcast::<WebGLObject>().context().send_command(
+ WebGLCommand::Clear(clear_bits)
+ );
+ }
+ self.is_initialized.set(true);
}
- result
+
+ constants::FRAMEBUFFER_COMPLETE
}
pub fn renderbuffer(&self, attachment: u32, rb: Option<&WebGLRenderbuffer>) -> WebGLResult<()> {
@@ -244,6 +279,7 @@ impl WebGLFramebuffer {
);
self.update_status();
+ self.is_initialized.set(false);
Ok(())
}
@@ -344,6 +380,7 @@ impl WebGLFramebuffer {
);
self.update_status();
+ self.is_initialized.set(false);
Ok(())
}