|
@@ -149,25 +149,15 @@ cull_callback(CullTraverser *, const CullTraverserData &) const {
|
|
|
////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////
|
|
|
bool RenderAttrib::
|
|
bool RenderAttrib::
|
|
|
unref() const {
|
|
unref() const {
|
|
|
- if (!state_cache) {
|
|
|
|
|
- // If we're not using the cache anyway, just allow the pointer to
|
|
|
|
|
- // unref normally.
|
|
|
|
|
|
|
+ if (!state_cache || garbage_collect_states) {
|
|
|
|
|
+ // If we're not using the cache at all, or if we're relying on
|
|
|
|
|
+ // garbage collection, just allow the pointer to unref normally.
|
|
|
return ReferenceCount::unref();
|
|
return ReferenceCount::unref();
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- if (garbage_collect_states) {
|
|
|
|
|
- // In the garbage collector case, we don't delete RenderStates
|
|
|
|
|
- // immediately; instead, we allow them to remain in the cache with
|
|
|
|
|
- // a ref count of 0, and we delete them later in
|
|
|
|
|
- // garbage_collect().
|
|
|
|
|
-
|
|
|
|
|
- ReferenceCount::unref();
|
|
|
|
|
- // Return true so that it is never deleted here.
|
|
|
|
|
- return true;
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
// Here is the normal refcounting case, with a normal cache, and
|
|
// Here is the normal refcounting case, with a normal cache, and
|
|
|
- // without garbage collection in effect.
|
|
|
|
|
|
|
+ // without garbage collection in effect. In this case we will pull
|
|
|
|
|
+ // the object out of the cache when its reference count goes to 0.
|
|
|
|
|
|
|
|
// We always have to grab the lock, since we will definitely need to
|
|
// We always have to grab the lock, since we will definitely need to
|
|
|
// be holding it if we happen to drop the reference count to 0.
|
|
// be holding it if we happen to drop the reference count to 0.
|
|
@@ -256,7 +246,7 @@ list_attribs(ostream &out) {
|
|
|
////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////
|
|
|
int RenderAttrib::
|
|
int RenderAttrib::
|
|
|
garbage_collect() {
|
|
garbage_collect() {
|
|
|
- if (_attribs == (Attribs *)NULL) {
|
|
|
|
|
|
|
+ if (_attribs == (Attribs *)NULL || !garbage_collect_states) {
|
|
|
return 0;
|
|
return 0;
|
|
|
}
|
|
}
|
|
|
LightReMutexHolder holder(*_attribs_lock);
|
|
LightReMutexHolder holder(*_attribs_lock);
|
|
@@ -281,15 +271,15 @@ garbage_collect() {
|
|
|
if (_attribs->has_element(si)) {
|
|
if (_attribs->has_element(si)) {
|
|
|
++num_elements;
|
|
++num_elements;
|
|
|
RenderAttrib *attrib = (RenderAttrib *)_attribs->get_key(si);
|
|
RenderAttrib *attrib = (RenderAttrib *)_attribs->get_key(si);
|
|
|
- if (attrib->get_ref_count() == 0) {
|
|
|
|
|
- // This attrib has recently been unreffed to 0, but it hasn't
|
|
|
|
|
- // been deleted yet (because we have overloaded unref(),
|
|
|
|
|
- // above, to always return true). Now it's time to delete it.
|
|
|
|
|
- // This is safe, because we're holding the _attribs_lock, so
|
|
|
|
|
- // it's not possible for some other thread to find the attrib
|
|
|
|
|
- // in the cache and ref it while we're doing this.
|
|
|
|
|
|
|
+ if (attrib->get_ref_count() == 1) {
|
|
|
|
|
+ // This attrib has recently been unreffed to 1 (the one we
|
|
|
|
|
+ // added when we stored it in the cache). Now it's time to
|
|
|
|
|
+ // delete it. This is safe, because we're holding the
|
|
|
|
|
+ // _attribs_lock, so it's not possible for some other thread to
|
|
|
|
|
+ // find the attrib in the cache and ref it while we're doing
|
|
|
|
|
+ // this.
|
|
|
attrib->release_new();
|
|
attrib->release_new();
|
|
|
- delete attrib;
|
|
|
|
|
|
|
+ unref_delete(attrib);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -444,6 +434,12 @@ return_unique(RenderAttrib *attrib) {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Not already in the set; add it.
|
|
// Not already in the set; add it.
|
|
|
|
|
+ if (garbage_collect_states) {
|
|
|
|
|
+ // If we'll be garbage collecting attribs explicitly, we'll
|
|
|
|
|
+ // increment the reference count when we store it in the cache, so
|
|
|
|
|
+ // that it won't be deleted while it's in it.
|
|
|
|
|
+ attrib->ref();
|
|
|
|
|
+ }
|
|
|
si = _attribs->store(attrib, Empty());
|
|
si = _attribs->store(attrib, Empty());
|
|
|
|
|
|
|
|
// Save the index and return the input attrib.
|
|
// Save the index and return the input attrib.
|