From ea715a7a4cae5d2a2f41b059f36e08010d544de1 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Fri, 20 Sep 2019 01:28:06 -0400 Subject: [PATCH] webgl: Update framebuffer completion status when attached renderbuffer/texture storage changes. --- components/script/dom/webglframebuffer.rs | 24 +++++++++++++++++++++- components/script/dom/webglrenderbuffer.rs | 17 ++++++++++++++- components/script/dom/webgltexture.rs | 19 ++++++++++++++++- 3 files changed, 57 insertions(+), 3 deletions(-) diff --git a/components/script/dom/webglframebuffer.rs b/components/script/dom/webglframebuffer.rs index 284a51cf483..3a31e99be33 100644 --- a/components/script/dom/webglframebuffer.rs +++ b/components/script/dom/webglframebuffer.rs @@ -59,6 +59,15 @@ impl WebGLFramebufferAttachment { }, } } + + fn detach(&self) { + match self { + WebGLFramebufferAttachment::Renderbuffer(rb) => rb.detach_from_framebuffer(), + WebGLFramebufferAttachment::Texture { ref texture, .. } => { + texture.detach_from_framebuffer() + }, + } + } } #[derive(Clone, JSTraceable, MallocSizeOf)] @@ -161,7 +170,7 @@ impl WebGLFramebuffer { self.size.get() } - fn update_status(&self) { + pub fn update_status(&self) { let c = self.color.borrow(); let z = self.depth.borrow(); let s = self.stencil.borrow(); @@ -311,6 +320,7 @@ impl WebGLFramebuffer { } *binding.borrow_mut() = Some(WebGLFramebufferAttachment::Renderbuffer(Dom::from_ref(rb))); + rb.attach_to_framebuffer(self); Some(rb.id()) }, @@ -340,6 +350,9 @@ impl WebGLFramebuffer { binding: &DomRefCell>, attachment: u32, ) { + if let Some(att) = &*binding.borrow() { + att.detach(); + } *binding.borrow_mut() = None; if INTERESTING_ATTACHMENT_POINTS.contains(&attachment) { self.reattach_depth_stencil(); @@ -364,6 +377,7 @@ impl WebGLFramebuffer { let context = self.upcast::().context(); match *attachment { WebGLFramebufferAttachment::Renderbuffer(ref rb) => { + rb.attach_to_framebuffer(self); context.send_command(WebGLCommand::FramebufferRenderbuffer( constants::FRAMEBUFFER, attachment_point, @@ -372,6 +386,7 @@ impl WebGLFramebuffer { )); }, WebGLFramebufferAttachment::Texture { ref texture, level } => { + texture.attach_to_framebuffer(self); context.send_command(WebGLCommand::FramebufferTexture2D( constants::FRAMEBUFFER, attachment_point, @@ -464,6 +479,7 @@ impl WebGLFramebuffer { texture: Dom::from_ref(texture), level: level, }); + texture.attach_to_framebuffer(self); Some(texture.id()) }, @@ -551,6 +567,9 @@ impl WebGLFramebuffer { let mut depth_or_stencil_updated = false; self.with_matching_renderbuffers(rb, |att, name| { depth_or_stencil_updated |= INTERESTING_ATTACHMENT_POINTS.contains(&name); + if let Some(att) = &*att.borrow() { + att.detach(); + } *att.borrow_mut() = None; self.update_status(); }); @@ -564,6 +583,9 @@ impl WebGLFramebuffer { let mut depth_or_stencil_updated = false; self.with_matching_textures(texture, |att, name| { depth_or_stencil_updated |= INTERESTING_ATTACHMENT_POINTS.contains(&name); + if let Some(att) = &*att.borrow() { + att.detach(); + } *att.borrow_mut() = None; self.update_status(); }); diff --git a/components/script/dom/webglrenderbuffer.rs b/components/script/dom/webglrenderbuffer.rs index f210b579e88..07afdbccb44 100644 --- a/components/script/dom/webglrenderbuffer.rs +++ b/components/script/dom/webglrenderbuffer.rs @@ -10,7 +10,8 @@ use crate::dom::bindings::codegen::Bindings::WebGLRenderbufferBinding; use crate::dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants; use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::reflector::{reflect_dom_object, DomObject}; -use crate::dom::bindings::root::DomRoot; +use crate::dom::bindings::root::{DomRoot, MutNullableDom}; +use crate::dom::webglframebuffer::WebGLFramebuffer; use crate::dom::webglobject::WebGLObject; use crate::dom::webglrenderingcontext::WebGLRenderingContext; use canvas_traits::webgl::{ @@ -28,6 +29,7 @@ pub struct WebGLRenderbuffer { size: Cell>, internal_format: Cell>, is_initialized: Cell, + attached_framebuffer: MutNullableDom, } impl WebGLRenderbuffer { @@ -40,6 +42,7 @@ impl WebGLRenderbuffer { internal_format: Cell::new(None), size: Cell::new(None), is_initialized: Cell::new(false), + attached_framebuffer: Default::default(), } } @@ -186,6 +189,10 @@ impl WebGLRenderbuffer { self.internal_format.set(Some(internal_format)); self.is_initialized.set(false); + if let Some(fb) = self.attached_framebuffer.get() { + fb.update_status(); + } + self.upcast::() .context() .send_command(WebGLCommand::RenderbufferStorage( @@ -199,6 +206,14 @@ impl WebGLRenderbuffer { Ok(()) } + + pub fn attach_to_framebuffer(&self, fb: &WebGLFramebuffer) { + self.attached_framebuffer.set(Some(fb)); + } + + pub fn detach_from_framebuffer(&self) { + self.attached_framebuffer.set(None); + } } impl Drop for WebGLRenderbuffer { diff --git a/components/script/dom/webgltexture.rs b/components/script/dom/webgltexture.rs index a7e548dcdef..e4a18b519a3 100644 --- a/components/script/dom/webgltexture.rs +++ b/components/script/dom/webgltexture.rs @@ -10,8 +10,9 @@ use crate::dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGL use crate::dom::bindings::codegen::Bindings::WebGLTextureBinding; use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::reflector::{reflect_dom_object, DomObject}; -use crate::dom::bindings::root::DomRoot; +use crate::dom::bindings::root::{DomRoot, MutNullableDom}; use crate::dom::webgl_validations::types::TexImageTarget; +use crate::dom::webglframebuffer::WebGLFramebuffer; use crate::dom::webglobject::WebGLObject; use crate::dom::webglrenderingcontext::WebGLRenderingContext; use canvas_traits::webgl::{webgl_channel, TexDataType, TexFormat, WebGLResult, WebGLTextureId}; @@ -48,6 +49,8 @@ pub struct WebGLTexture { mag_filter: Cell, /// True if this texture is used for the DOMToTexture feature. attached_to_dom: Cell, + /// Framebuffer that this texture is attached to. + attached_framebuffer: MutNullableDom, } impl WebGLTexture { @@ -63,6 +66,7 @@ impl WebGLTexture { mag_filter: Cell::new(constants::LINEAR), image_info_array: DomRefCell::new([ImageInfo::new(); MAX_LEVEL_COUNT * MAX_FACE_COUNT]), attached_to_dom: Cell::new(false), + attached_framebuffer: Default::default(), } } @@ -138,6 +142,11 @@ impl WebGLTexture { let face_index = self.face_index_for_target(&target); self.set_image_infos_at_level_and_face(level, face_index, image_info); + + if let Some(fb) = self.attached_framebuffer.get() { + fb.update_status(); + } + Ok(()) } @@ -405,6 +414,14 @@ impl WebGLTexture { pub fn set_attached_to_dom(&self) { self.attached_to_dom.set(true); } + + pub fn attach_to_framebuffer(&self, fb: &WebGLFramebuffer) { + self.attached_framebuffer.set(Some(fb)); + } + + pub fn detach_from_framebuffer(&self) { + self.attached_framebuffer.set(None); + } } impl Drop for WebGLTexture {