aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/webglbuffer.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/webglbuffer.rs')
-rw-r--r--components/script/dom/webglbuffer.rs111
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();
}
}