From 28dcfa514a049e02e9cf74f7cf1ceefa975b7b97 Mon Sep 17 00:00:00 2001 From: David Rose Date: Mon, 15 Jul 2002 21:25:32 +0000 Subject: [PATCH] enable clearing of old cache items --- panda/src/pgraph/renderState.cxx | 83 ++++++++++++++++++++++++++++ panda/src/pgraph/renderState.h | 3 + panda/src/pgraph/transformState.cxx | 85 ++++++++++++++++++++++++++++- panda/src/pgraph/transformState.h | 3 + 4 files changed, 173 insertions(+), 1 deletion(-) diff --git a/panda/src/pgraph/renderState.cxx b/panda/src/pgraph/renderState.cxx index 2484ba2d02..21a72d398f 100644 --- a/panda/src/pgraph/renderState.cxx +++ b/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 diff --git a/panda/src/pgraph/renderState.h b/panda/src/pgraph/renderState.h index 8c6d0d43dc..888188f8c9 100644 --- a/panda/src/pgraph/renderState.h +++ b/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; diff --git a/panda/src/pgraph/transformState.cxx b/panda/src/pgraph/transformState.cxx index e4fdb715f1..fce4db953b 100644 --- a/panda/src/pgraph/transformState.cxx +++ b/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 diff --git a/panda/src/pgraph/transformState.h b/panda/src/pgraph/transformState.h index 89e531a004..388a2bd444 100644 --- a/panda/src/pgraph/transformState.h +++ b/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;