webgl: Update framebuffer completion status when attached renderbuffer/texture storage changes.

This commit is contained in:
Josh Matthews 2019-09-20 01:28:06 -04:00
parent 5bd1e86d42
commit ea715a7a4c
3 changed files with 57 additions and 3 deletions

View file

@ -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)] #[derive(Clone, JSTraceable, MallocSizeOf)]
@ -161,7 +170,7 @@ impl WebGLFramebuffer {
self.size.get() self.size.get()
} }
fn update_status(&self) { pub fn update_status(&self) {
let c = self.color.borrow(); let c = self.color.borrow();
let z = self.depth.borrow(); let z = self.depth.borrow();
let s = self.stencil.borrow(); let s = self.stencil.borrow();
@ -311,6 +320,7 @@ impl WebGLFramebuffer {
} }
*binding.borrow_mut() = *binding.borrow_mut() =
Some(WebGLFramebufferAttachment::Renderbuffer(Dom::from_ref(rb))); Some(WebGLFramebufferAttachment::Renderbuffer(Dom::from_ref(rb)));
rb.attach_to_framebuffer(self);
Some(rb.id()) Some(rb.id())
}, },
@ -340,6 +350,9 @@ impl WebGLFramebuffer {
binding: &DomRefCell<Option<WebGLFramebufferAttachment>>, binding: &DomRefCell<Option<WebGLFramebufferAttachment>>,
attachment: u32, attachment: u32,
) { ) {
if let Some(att) = &*binding.borrow() {
att.detach();
}
*binding.borrow_mut() = None; *binding.borrow_mut() = None;
if INTERESTING_ATTACHMENT_POINTS.contains(&attachment) { if INTERESTING_ATTACHMENT_POINTS.contains(&attachment) {
self.reattach_depth_stencil(); self.reattach_depth_stencil();
@ -364,6 +377,7 @@ impl WebGLFramebuffer {
let context = self.upcast::<WebGLObject>().context(); let context = self.upcast::<WebGLObject>().context();
match *attachment { match *attachment {
WebGLFramebufferAttachment::Renderbuffer(ref rb) => { WebGLFramebufferAttachment::Renderbuffer(ref rb) => {
rb.attach_to_framebuffer(self);
context.send_command(WebGLCommand::FramebufferRenderbuffer( context.send_command(WebGLCommand::FramebufferRenderbuffer(
constants::FRAMEBUFFER, constants::FRAMEBUFFER,
attachment_point, attachment_point,
@ -372,6 +386,7 @@ impl WebGLFramebuffer {
)); ));
}, },
WebGLFramebufferAttachment::Texture { ref texture, level } => { WebGLFramebufferAttachment::Texture { ref texture, level } => {
texture.attach_to_framebuffer(self);
context.send_command(WebGLCommand::FramebufferTexture2D( context.send_command(WebGLCommand::FramebufferTexture2D(
constants::FRAMEBUFFER, constants::FRAMEBUFFER,
attachment_point, attachment_point,
@ -464,6 +479,7 @@ impl WebGLFramebuffer {
texture: Dom::from_ref(texture), texture: Dom::from_ref(texture),
level: level, level: level,
}); });
texture.attach_to_framebuffer(self);
Some(texture.id()) Some(texture.id())
}, },
@ -551,6 +567,9 @@ impl WebGLFramebuffer {
let mut depth_or_stencil_updated = false; let mut depth_or_stencil_updated = false;
self.with_matching_renderbuffers(rb, |att, name| { self.with_matching_renderbuffers(rb, |att, name| {
depth_or_stencil_updated |= INTERESTING_ATTACHMENT_POINTS.contains(&name); depth_or_stencil_updated |= INTERESTING_ATTACHMENT_POINTS.contains(&name);
if let Some(att) = &*att.borrow() {
att.detach();
}
*att.borrow_mut() = None; *att.borrow_mut() = None;
self.update_status(); self.update_status();
}); });
@ -564,6 +583,9 @@ impl WebGLFramebuffer {
let mut depth_or_stencil_updated = false; let mut depth_or_stencil_updated = false;
self.with_matching_textures(texture, |att, name| { self.with_matching_textures(texture, |att, name| {
depth_or_stencil_updated |= INTERESTING_ATTACHMENT_POINTS.contains(&name); depth_or_stencil_updated |= INTERESTING_ATTACHMENT_POINTS.contains(&name);
if let Some(att) = &*att.borrow() {
att.detach();
}
*att.borrow_mut() = None; *att.borrow_mut() = None;
self.update_status(); self.update_status();
}); });

View file

@ -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::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants as constants;
use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject}; 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::webglobject::WebGLObject;
use crate::dom::webglrenderingcontext::WebGLRenderingContext; use crate::dom::webglrenderingcontext::WebGLRenderingContext;
use canvas_traits::webgl::{ use canvas_traits::webgl::{
@ -28,6 +29,7 @@ pub struct WebGLRenderbuffer {
size: Cell<Option<(i32, i32)>>, size: Cell<Option<(i32, i32)>>,
internal_format: Cell<Option<u32>>, internal_format: Cell<Option<u32>>,
is_initialized: Cell<bool>, is_initialized: Cell<bool>,
attached_framebuffer: MutNullableDom<WebGLFramebuffer>,
} }
impl WebGLRenderbuffer { impl WebGLRenderbuffer {
@ -40,6 +42,7 @@ impl WebGLRenderbuffer {
internal_format: Cell::new(None), internal_format: Cell::new(None),
size: Cell::new(None), size: Cell::new(None),
is_initialized: Cell::new(false), is_initialized: Cell::new(false),
attached_framebuffer: Default::default(),
} }
} }
@ -186,6 +189,10 @@ impl WebGLRenderbuffer {
self.internal_format.set(Some(internal_format)); self.internal_format.set(Some(internal_format));
self.is_initialized.set(false); self.is_initialized.set(false);
if let Some(fb) = self.attached_framebuffer.get() {
fb.update_status();
}
self.upcast::<WebGLObject>() self.upcast::<WebGLObject>()
.context() .context()
.send_command(WebGLCommand::RenderbufferStorage( .send_command(WebGLCommand::RenderbufferStorage(
@ -199,6 +206,14 @@ impl WebGLRenderbuffer {
Ok(()) 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 { impl Drop for WebGLRenderbuffer {

View file

@ -10,8 +10,9 @@ use crate::dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGL
use crate::dom::bindings::codegen::Bindings::WebGLTextureBinding; use crate::dom::bindings::codegen::Bindings::WebGLTextureBinding;
use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::reflector::{reflect_dom_object, DomObject}; 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::webgl_validations::types::TexImageTarget;
use crate::dom::webglframebuffer::WebGLFramebuffer;
use crate::dom::webglobject::WebGLObject; use crate::dom::webglobject::WebGLObject;
use crate::dom::webglrenderingcontext::WebGLRenderingContext; use crate::dom::webglrenderingcontext::WebGLRenderingContext;
use canvas_traits::webgl::{webgl_channel, TexDataType, TexFormat, WebGLResult, WebGLTextureId}; use canvas_traits::webgl::{webgl_channel, TexDataType, TexFormat, WebGLResult, WebGLTextureId};
@ -48,6 +49,8 @@ pub struct WebGLTexture {
mag_filter: Cell<u32>, mag_filter: Cell<u32>,
/// True if this texture is used for the DOMToTexture feature. /// True if this texture is used for the DOMToTexture feature.
attached_to_dom: Cell<bool>, attached_to_dom: Cell<bool>,
/// Framebuffer that this texture is attached to.
attached_framebuffer: MutNullableDom<WebGLFramebuffer>,
} }
impl WebGLTexture { impl WebGLTexture {
@ -63,6 +66,7 @@ impl WebGLTexture {
mag_filter: Cell::new(constants::LINEAR), mag_filter: Cell::new(constants::LINEAR),
image_info_array: DomRefCell::new([ImageInfo::new(); MAX_LEVEL_COUNT * MAX_FACE_COUNT]), image_info_array: DomRefCell::new([ImageInfo::new(); MAX_LEVEL_COUNT * MAX_FACE_COUNT]),
attached_to_dom: Cell::new(false), 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); let face_index = self.face_index_for_target(&target);
self.set_image_infos_at_level_and_face(level, face_index, image_info); 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(()) Ok(())
} }
@ -405,6 +414,14 @@ impl WebGLTexture {
pub fn set_attached_to_dom(&self) { pub fn set_attached_to_dom(&self) {
self.attached_to_dom.set(true); 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 { impl Drop for WebGLTexture {