diff options
Diffstat (limited to 'components/script/dom/webglbuffer.rs')
-rw-r--r-- | components/script/dom/webglbuffer.rs | 111 |
1 files changed, 45 insertions, 66 deletions
diff --git a/components/script/dom/webglbuffer.rs b/components/script/dom/webglbuffer.rs index 27fe415e8f8..66a3ce0af40 100644 --- a/components/script/dom/webglbuffer.rs +++ b/components/script/dom/webglbuffer.rs @@ -3,9 +3,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl -use canvas_traits::webgl::{WebGLBufferId, WebGLCommand, WebGLError, WebGLResult, WebGLVertexArrayId}; +use canvas_traits::webgl::{WebGLBufferId, WebGLCommand, WebGLError, WebGLResult}; use canvas_traits::webgl::webgl_channel; -use dom::bindings::cell::DomRefCell; use dom::bindings::codegen::Bindings::WebGLBufferBinding; use dom::bindings::codegen::Bindings::WebGLRenderingContextBinding::WebGLRenderingContextConstants; use dom::bindings::inheritance::Castable; @@ -15,8 +14,6 @@ use dom::webglobject::WebGLObject; use dom::webglrenderingcontext::WebGLRenderingContext; use dom_struct::dom_struct; use std::cell::Cell; -use std::collections::HashSet; - #[dom_struct] pub struct WebGLBuffer { @@ -25,10 +22,8 @@ pub struct WebGLBuffer { /// The target to which this buffer was bound the first time target: Cell<Option<u32>>, capacity: Cell<usize>, - is_deleted: Cell<bool>, - // The Vertex Array Objects that are referencing this buffer - vao_references: DomRefCell<Option<HashSet<WebGLVertexArrayId>>>, - pending_delete: Cell<bool>, + marked_for_deletion: Cell<bool>, + attached_counter: Cell<u32>, /// https://www.khronos.org/registry/OpenGL-Refpages/es2.0/xhtml/glGetBufferParameteriv.xml usage: Cell<u32>, } @@ -37,12 +32,11 @@ impl WebGLBuffer { fn new_inherited(context: &WebGLRenderingContext, id: WebGLBufferId) -> Self { Self { webgl_object: WebGLObject::new_inherited(context), - id: id, - target: Cell::new(None), - capacity: Cell::new(0), - is_deleted: Cell::new(false), - vao_references: DomRefCell::new(None), - pending_delete: Cell::new(false), + id, + target: Default::default(), + capacity: Default::default(), + marked_for_deletion: Default::default(), + attached_counter: Default::default(), usage: Cell::new(WebGLRenderingContextConstants::STATIC_DRAW), } } @@ -68,24 +62,6 @@ impl WebGLBuffer { self.id } - // NB: Only valid buffer targets come here - pub fn bind(&self, target: u32) -> WebGLResult<()> { - if self.is_deleted() || self.is_pending_delete() { - return Err(WebGLError::InvalidOperation); - } - if let Some(previous_target) = self.target.get() { - if target != previous_target { - return Err(WebGLError::InvalidOperation); - } - } else { - self.target.set(Some(target)); - } - self.upcast::<WebGLObject>() - .context() - .send_command(WebGLCommand::BindBuffer(target, Some(self.id))); - Ok(()) - } - pub fn buffer_data<T>(&self, target: u32, data: T, usage: u32) -> WebGLResult<()> where T: Into<Vec<u8>>, @@ -115,56 +91,59 @@ impl WebGLBuffer { self.capacity.get() } - pub fn delete(&self) { - if !self.is_deleted.get() { - self.is_deleted.set(true); - self.upcast::<WebGLObject>() - .context() - .send_command(WebGLCommand::DeleteBuffer(self.id)); + pub fn mark_for_deletion(&self) { + if self.marked_for_deletion.get() { + return; + } + self.marked_for_deletion.set(true); + if self.is_deleted() { + self.delete(); } } - pub fn is_deleted(&self) -> bool { - self.is_deleted.get() + fn delete(&self) { + assert!(self.is_deleted()); + self.upcast::<WebGLObject>() + .context() + .send_command(WebGLCommand::DeleteBuffer(self.id)); } - pub fn target(&self) -> Option<u32> { - self.target.get() + pub fn is_marked_for_deletion(&self) -> bool { + self.marked_for_deletion.get() } - pub fn is_attached_to_vao(&self) -> bool { - self.vao_references.borrow().as_ref().map_or(false, |vaos| !vaos.is_empty()) + pub fn is_deleted(&self) -> bool { + self.marked_for_deletion.get() && !self.is_attached() } - pub fn set_pending_delete(&self) { - self.pending_delete.set(true); + pub fn target(&self) -> Option<u32> { + self.target.get() } - pub fn is_pending_delete(&self) -> bool { - self.pending_delete.get() + pub fn set_target(&self, target: u32) -> WebGLResult<()> { + if self.target.get().map_or(false, |t| t != target) { + return Err(WebGLError::InvalidOperation); + } + self.target.set(Some(target)); + Ok(()) } - pub fn add_vao_reference(&self, id: WebGLVertexArrayId) { - let mut vao_refs = self.vao_references.borrow_mut(); - if let Some(ref mut vao_refs) = *vao_refs { - vao_refs.insert(id); - return; - } + pub fn is_attached(&self) -> bool { + self.attached_counter.get() != 0 + } - let mut map = HashSet::new(); - map.insert(id); - *vao_refs = Some(map); + pub fn increment_attached_counter(&self) { + self.attached_counter.set( + self.attached_counter.get().checked_add(1).expect("refcount overflowed"), + ); } - pub fn remove_vao_reference(&self, id: WebGLVertexArrayId) { - if let Some(ref mut vao_refs) = *self.vao_references.borrow_mut() { - if vao_refs.take(&id).is_some() && self.pending_delete.get() { - // WebGL spec: The deleted buffers should no longer be valid when the VAOs are deleted - self.upcast::<WebGLObject>() - .context() - .send_command(WebGLCommand::DeleteBuffer(self.id)); - self.is_deleted.set(true); - } + pub fn decrement_attached_counter(&self) { + self.attached_counter.set( + self.attached_counter.get().checked_sub(1).expect("refcount underflowed"), + ); + if self.is_deleted() { + self.delete(); } } |