Browse Source

enable clearing of old cache items

David Rose 23 years ago
parent
commit
28dcfa514a

+ 83 - 0
panda/src/pgraph/renderState.cxx

@@ -621,6 +621,89 @@ get_max_priority() {
   return 1000000000;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: RenderState::get_cache_size
+//       Access: Published, Static
+//  Description: Returns the total number of unique RenderState
+//               objects allocated in the world.  This will go up and
+//               down during normal operations.
+////////////////////////////////////////////////////////////////////
+int RenderState::
+get_cache_size() {
+  if (_states == (States *)NULL) {
+    return 0;
+  }
+  return _states->size();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: RenderState::clear_cache
+//       Access: Published, Static
+//  Description: Empties the cache of composed RenderStates.  This
+//               makes every RenderState forget what results when
+//               it is composed with other RenderStates.
+//
+//               This will eliminate any RenderState objects that
+//               have been allocated but have no references outside of
+//               the internal RenderState map.  It will not
+//               eliminate RenderState objects that are still in
+//               use.
+//
+//               Normally, RenderState objects will remove
+//               themselves from the interal map when their reference
+//               counts go to 0, but since circular references are
+//               possible there may be some cycles that cannot remove
+//               themselves.  Calling this function from time to time
+//               will ensure there is no wasteful memory leakage, but
+//               calling it too often may result in decreased
+//               performance as the cache is forced to be recomputed.
+//
+//               The return value is the number of RenderStates
+//               freed by this operation.
+////////////////////////////////////////////////////////////////////
+int RenderState::
+clear_cache() {
+  if (_states == (States *)NULL) {
+    return 0;
+  }
+
+  int orig_size = _states->size();
+
+  // First, we need to copy the entire set of states to a temporary
+  // vector, reference-counting each object.  That way we can walk
+  // through the copy, without fear of dereferencing (and deleting)
+  // the objects in the map as we go.
+  {
+    typedef pvector< CPT(RenderState) > TempStates;
+    TempStates temp_states;
+    temp_states.reserve(orig_size);
+
+    copy(_states->begin(), _states->end(),
+         back_inserter(temp_states));
+
+    // Now it's safe to walk through the list, destroying the cache
+    // within each object as we go.  Nothing will be destructed till
+    // we're done.
+    TempStates::iterator ti;
+    for (ti = temp_states.begin(); ti != temp_states.end(); ++ti) {
+      RenderState *state = (RenderState *)(*ti).p();
+      state->_composition_cache.clear();
+      state->_invert_composition_cache.clear();
+      if (state->_self_compose != (RenderState *)NULL && 
+          state->_self_compose != state) {
+        unref_delete((RenderState *)state->_self_compose);
+      }
+    }
+
+    // Once this block closes and the temp_states object goes away,
+    // all the destruction will begin.  Anything whose reference was
+    // held only within the various objects' caches will go away.
+  }
+
+  int new_size = _states->size();
+  return orig_size - new_size;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: RenderState::issue_delta_modify
 //       Access: Public

+ 3 - 0
panda/src/pgraph/renderState.h

@@ -95,6 +95,9 @@ PUBLISHED:
 
   static int get_max_priority();
 
+  static int get_cache_size();
+  static int clear_cache();
+
 public:
   INLINE int get_bin_index() const;
   INLINE int get_draw_order() const;

+ 84 - 1
panda/src/pgraph/transformState.cxx

@@ -40,7 +40,7 @@ TransformState() {
   if (_states == (States *)NULL) {
     // Make sure the global _states map is allocated.  This only has
     // to be done once.  We could make this map static, but then we
-    // run into problems if anyone creates a RenderState object at
+    // run into problems if anyone creates a TransformState object at
     // static init time; it also seems to cause problems when the
     // Panda shared library is unloaded at application exit time.
     _states = new States;
@@ -652,6 +652,89 @@ write(ostream &out, int indent_level) const {
   indent(out, indent_level) << *this << "\n";
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: TransformState::get_cache_size
+//       Access: Published, Static
+//  Description: Returns the total number of unique TransformState
+//               objects allocated in the world.  This will go up and
+//               down during normal operations.
+////////////////////////////////////////////////////////////////////
+int TransformState::
+get_cache_size() {
+  if (_states == (States *)NULL) {
+    return 0;
+  }
+  return _states->size();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: TransformState::clear_cache
+//       Access: Published, Static
+//  Description: Empties the cache of composed TransformStates.  This
+//               makes every TransformState forget what results when
+//               it is composed with other TransformStates.
+//
+//               This will eliminate any TransformState objects that
+//               have been allocated but have no references outside of
+//               the internal TransformState map.  It will not
+//               eliminate TransformState objects that are still in
+//               use.
+//
+//               Normally, TransformState objects will remove
+//               themselves from the interal map when their reference
+//               counts go to 0, but since circular references are
+//               possible there may be some cycles that cannot remove
+//               themselves.  Calling this function from time to time
+//               will ensure there is no wasteful memory leakage, but
+//               calling it too often may result in decreased
+//               performance as the cache is forced to be recomputed.
+//
+//               The return value is the number of TransformStates
+//               freed by this operation.
+////////////////////////////////////////////////////////////////////
+int TransformState::
+clear_cache() {
+  if (_states == (States *)NULL) {
+    return 0;
+  }
+
+  int orig_size = _states->size();
+
+  // First, we need to copy the entire set of transforms to a
+  // temporary vector, reference-counting each object.  That way we
+  // can walk through the copy, without fear of dereferencing (and
+  // deleting) the objects in the map as we go.
+  {
+    typedef pvector< CPT(TransformState) > TempStates;
+    TempStates temp_states;
+    temp_states.reserve(orig_size);
+
+    copy(_states->begin(), _states->end(),
+         back_inserter(temp_states));
+
+    // Now it's safe to walk through the list, destroying the cache
+    // within each object as we go.  Nothing will be destructed till
+    // we're done.
+    TempStates::iterator ti;
+    for (ti = temp_states.begin(); ti != temp_states.end(); ++ti) {
+      TransformState *state = (TransformState *)(*ti).p();
+      state->_composition_cache.clear();
+      state->_invert_composition_cache.clear();
+      if (state->_self_compose != (TransformState *)NULL && 
+          state->_self_compose != state) {
+        unref_delete((TransformState *)state->_self_compose);
+      }
+    }
+
+    // Once this block closes and the temp_states object goes away,
+    // all the destruction will begin.  Anything whose reference was
+    // held only within the various objects' caches will go away.
+  }
+
+  int new_size = _states->size();
+  return orig_size - new_size;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: TransformState::return_new
 //       Access: Private, Static

+ 3 - 0
panda/src/pgraph/transformState.h

@@ -115,6 +115,9 @@ PUBLISHED:
   void output(ostream &out) const;
   void write(ostream &out, int indent_level) const;
 
+  static int get_cache_size();
+  static int clear_cache();
+
 private:
   static CPT(TransformState) return_new(TransformState *state);
   CPT(TransformState) do_compose(const TransformState *other) const;