mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-29 16:20:11 -04:00
pgraph: take advantage of constant initialization for states maps
SimpleHashMap has a constexpr default constructor, so there is no static init ordering issue that requires us to allocate the states maps on the heap and then to leak them.
This commit is contained in:
parent
441e1e3d66
commit
193ae8a3a6
@ -301,9 +301,9 @@ GraphicsStateGuardian::
|
|||||||
// Note that if uniquify-states is false, we can't iterate over all the
|
// Note that if uniquify-states is false, we can't iterate over all the
|
||||||
// states, and some GSGs will linger. Let's hope this isn't a problem.
|
// states, and some GSGs will linger. Let's hope this isn't a problem.
|
||||||
LightReMutexHolder holder(*RenderState::_states_lock);
|
LightReMutexHolder holder(*RenderState::_states_lock);
|
||||||
size_t size = RenderState::_states->get_num_entries();
|
size_t size = RenderState::_states.get_num_entries();
|
||||||
for (size_t si = 0; si < size; ++si) {
|
for (size_t si = 0; si < size; ++si) {
|
||||||
const RenderState *state = RenderState::_states->get_key(si);
|
const RenderState *state = RenderState::_states.get_key(si);
|
||||||
state->_mungers.remove(_id);
|
state->_mungers.remove(_id);
|
||||||
state->_munged_states.remove(_id);
|
state->_munged_states.remove(_id);
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
using std::ostream;
|
using std::ostream;
|
||||||
|
|
||||||
LightReMutex *RenderAttrib::_attribs_lock = nullptr;
|
LightReMutex *RenderAttrib::_attribs_lock = nullptr;
|
||||||
RenderAttrib::Attribs *RenderAttrib::_attribs = nullptr;
|
RenderAttrib::Attribs RenderAttrib::_attribs;
|
||||||
TypeHandle RenderAttrib::_type_handle;
|
TypeHandle RenderAttrib::_type_handle;
|
||||||
|
|
||||||
size_t RenderAttrib::_garbage_index = 0;
|
size_t RenderAttrib::_garbage_index = 0;
|
||||||
@ -33,7 +33,7 @@ PStatCollector RenderAttrib::_garbage_collect_pcollector("*:State Cache:Garbage
|
|||||||
*/
|
*/
|
||||||
RenderAttrib::
|
RenderAttrib::
|
||||||
RenderAttrib() {
|
RenderAttrib() {
|
||||||
if (_attribs == nullptr) {
|
if (_attribs_lock == nullptr) {
|
||||||
init_attribs();
|
init_attribs();
|
||||||
}
|
}
|
||||||
_saved_entry = -1;
|
_saved_entry = -1;
|
||||||
@ -156,11 +156,7 @@ write(ostream &out, int indent_level) const {
|
|||||||
int RenderAttrib::
|
int RenderAttrib::
|
||||||
get_num_attribs() {
|
get_num_attribs() {
|
||||||
LightReMutexHolder holder(*_attribs_lock);
|
LightReMutexHolder holder(*_attribs_lock);
|
||||||
|
return _attribs.get_num_entries();
|
||||||
if (_attribs == nullptr) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return _attribs->get_num_entries();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -172,10 +168,10 @@ void RenderAttrib::
|
|||||||
list_attribs(ostream &out) {
|
list_attribs(ostream &out) {
|
||||||
LightReMutexHolder holder(*_attribs_lock);
|
LightReMutexHolder holder(*_attribs_lock);
|
||||||
|
|
||||||
size_t size = _attribs->get_num_entries();
|
size_t size = _attribs.get_num_entries();
|
||||||
out << size << " attribs:\n";
|
out << size << " attribs:\n";
|
||||||
for (size_t si = 0; si < size; ++si) {
|
for (size_t si = 0; si < size; ++si) {
|
||||||
const RenderAttrib *attrib = _attribs->get_key(si);
|
const RenderAttrib *attrib = _attribs.get_key(si);
|
||||||
attrib->write(out, 2);
|
attrib->write(out, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -186,16 +182,16 @@ list_attribs(ostream &out) {
|
|||||||
*/
|
*/
|
||||||
int RenderAttrib::
|
int RenderAttrib::
|
||||||
garbage_collect() {
|
garbage_collect() {
|
||||||
if (_attribs == nullptr || !garbage_collect_states) {
|
if (!garbage_collect_states) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
LightReMutexHolder holder(*_attribs_lock);
|
LightReMutexHolder holder(*_attribs_lock);
|
||||||
|
|
||||||
PStatTimer timer(_garbage_collect_pcollector);
|
PStatTimer timer(_garbage_collect_pcollector);
|
||||||
size_t orig_size = _attribs->get_num_entries();
|
size_t orig_size = _attribs.get_num_entries();
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
nassertr(_attribs->validate(), 0);
|
nassertr(_attribs.validate(), 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// How many elements to process this pass?
|
// How many elements to process this pass?
|
||||||
@ -214,7 +210,7 @@ garbage_collect() {
|
|||||||
size_t stop_at_element = (si + num_this_pass) % size;
|
size_t stop_at_element = (si + num_this_pass) % size;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
RenderAttrib *attrib = (RenderAttrib *)_attribs->get_key(si);
|
RenderAttrib *attrib = (RenderAttrib *)_attribs.get_key(si);
|
||||||
if (attrib->get_ref_count() == 1) {
|
if (attrib->get_ref_count() == 1) {
|
||||||
// This attrib has recently been unreffed to 1 (the one we added when
|
// 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
|
// we stored it in the cache). Now it's time to delete it. This is
|
||||||
@ -238,15 +234,15 @@ garbage_collect() {
|
|||||||
} while (si != stop_at_element);
|
} while (si != stop_at_element);
|
||||||
_garbage_index = si;
|
_garbage_index = si;
|
||||||
|
|
||||||
nassertr(_attribs->get_num_entries() == size, 0);
|
nassertr(_attribs.get_num_entries() == size, 0);
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
nassertr(_attribs->validate(), 0);
|
nassertr(_attribs.validate(), 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// If we just cleaned up a lot of attribs, see if we can reduce the table in
|
// If we just cleaned up a lot of attribs, see if we can reduce the table in
|
||||||
// size. This will help reduce iteration overhead in the future.
|
// size. This will help reduce iteration overhead in the future.
|
||||||
_attribs->consider_shrink_table();
|
_attribs.consider_shrink_table();
|
||||||
|
|
||||||
return (int)orig_size - (int)size;
|
return (int)orig_size - (int)size;
|
||||||
}
|
}
|
||||||
@ -259,17 +255,17 @@ garbage_collect() {
|
|||||||
bool RenderAttrib::
|
bool RenderAttrib::
|
||||||
validate_attribs() {
|
validate_attribs() {
|
||||||
LightReMutexHolder holder(*_attribs_lock);
|
LightReMutexHolder holder(*_attribs_lock);
|
||||||
if (_attribs->is_empty()) {
|
if (_attribs.is_empty()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_attribs->validate()) {
|
if (!_attribs.validate()) {
|
||||||
pgraph_cat.error()
|
pgraph_cat.error()
|
||||||
<< "RenderAttrib::_attribs cache is invalid!\n";
|
<< "RenderAttrib::_attribs cache is invalid!\n";
|
||||||
|
|
||||||
size_t size = _attribs->get_num_entries();
|
size_t size = _attribs.get_num_entries();
|
||||||
for (size_t si = 0; si < size; ++si) {
|
for (size_t si = 0; si < size; ++si) {
|
||||||
const RenderAttrib *attrib = _attribs->get_key(si);
|
const RenderAttrib *attrib = _attribs.get_key(si);
|
||||||
//cerr << si << ": " << attrib << "\n";
|
//cerr << si << ": " << attrib << "\n";
|
||||||
attrib->write(std::cerr, 2);
|
attrib->write(std::cerr, 2);
|
||||||
}
|
}
|
||||||
@ -277,16 +273,16 @@ validate_attribs() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size = _attribs->get_num_entries();
|
size_t size = _attribs.get_num_entries();
|
||||||
size_t si = 0;
|
size_t si = 0;
|
||||||
nassertr(si < size, false);
|
nassertr(si < size, false);
|
||||||
nassertr(_attribs->get_key(si)->get_ref_count() >= 0, false);
|
nassertr(_attribs.get_key(si)->get_ref_count() >= 0, false);
|
||||||
size_t snext = si;
|
size_t snext = si;
|
||||||
++snext;
|
++snext;
|
||||||
while (snext < size) {
|
while (snext < size) {
|
||||||
nassertr(_attribs->get_key(snext)->get_ref_count() >= 0, false);
|
nassertr(_attribs.get_key(snext)->get_ref_count() >= 0, false);
|
||||||
const RenderAttrib *ssi = _attribs->get_key(si);
|
const RenderAttrib *ssi = _attribs.get_key(si);
|
||||||
const RenderAttrib *ssnext = _attribs->get_key(snext);
|
const RenderAttrib *ssnext = _attribs.get_key(snext);
|
||||||
int c = ssi->compare_to(*ssnext);
|
int c = ssi->compare_to(*ssnext);
|
||||||
int ci = ssnext->compare_to(*ssi);
|
int ci = ssnext->compare_to(*ssi);
|
||||||
if ((ci < 0) != (c > 0) ||
|
if ((ci < 0) != (c > 0) ||
|
||||||
@ -356,19 +352,19 @@ return_unique(RenderAttrib *attrib) {
|
|||||||
LightReMutexHolder holder(*_attribs_lock);
|
LightReMutexHolder holder(*_attribs_lock);
|
||||||
|
|
||||||
if (attrib->_saved_entry != -1) {
|
if (attrib->_saved_entry != -1) {
|
||||||
// This attrib is already in the cache. nassertr(_attribs->find(attrib)
|
// This attrib is already in the cache. nassertr(_attribs.find(attrib)
|
||||||
// == attrib->_saved_entry, attrib);
|
// == attrib->_saved_entry, attrib);
|
||||||
return attrib;
|
return attrib;
|
||||||
}
|
}
|
||||||
|
|
||||||
int si = _attribs->find(attrib);
|
int si = _attribs.find(attrib);
|
||||||
if (si != -1) {
|
if (si != -1) {
|
||||||
// There's an equivalent attrib already in the set. Return it. If this
|
// There's an equivalent attrib already in the set. Return it. If this
|
||||||
// is a newly created RenderAttrib, though, be sure to delete it.
|
// is a newly created RenderAttrib, though, be sure to delete it.
|
||||||
if (attrib->get_ref_count() == 0) {
|
if (attrib->get_ref_count() == 0) {
|
||||||
delete attrib;
|
delete attrib;
|
||||||
}
|
}
|
||||||
return _attribs->get_key(si);
|
return _attribs.get_key(si);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not already in the set; add it.
|
// Not already in the set; add it.
|
||||||
@ -378,7 +374,7 @@ return_unique(RenderAttrib *attrib) {
|
|||||||
// deleted while it's in it.
|
// deleted while it's in it.
|
||||||
attrib->ref();
|
attrib->ref();
|
||||||
}
|
}
|
||||||
si = _attribs->store(attrib, nullptr);
|
si = _attribs.store(attrib, nullptr);
|
||||||
|
|
||||||
// Save the index and return the input attrib.
|
// Save the index and return the input attrib.
|
||||||
attrib->_saved_entry = si;
|
attrib->_saved_entry = si;
|
||||||
@ -495,7 +491,7 @@ release_new() {
|
|||||||
|
|
||||||
if (_saved_entry != -1) {
|
if (_saved_entry != -1) {
|
||||||
_saved_entry = -1;
|
_saved_entry = -1;
|
||||||
nassertv_always(_attribs->remove(this));
|
nassertv_always(_attribs.remove(this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -508,8 +504,6 @@ release_new() {
|
|||||||
*/
|
*/
|
||||||
void RenderAttrib::
|
void RenderAttrib::
|
||||||
init_attribs() {
|
init_attribs() {
|
||||||
_attribs = new Attribs;
|
|
||||||
|
|
||||||
// TODO: we should have a global Panda mutex to allow us to safely create
|
// TODO: we should have a global Panda mutex to allow us to safely create
|
||||||
// _attribs_lock without a startup race condition. For the meantime, this
|
// _attribs_lock without a startup race condition. For the meantime, this
|
||||||
// is OK because we guarantee that this method is called at static init
|
// is OK because we guarantee that this method is called at static init
|
||||||
|
@ -186,7 +186,7 @@ private:
|
|||||||
// This mutex protects _attribs.
|
// This mutex protects _attribs.
|
||||||
static LightReMutex *_attribs_lock;
|
static LightReMutex *_attribs_lock;
|
||||||
typedef SimpleHashMap<const RenderAttrib *, std::nullptr_t, indirect_compare_to_hash<const RenderAttrib *> > Attribs;
|
typedef SimpleHashMap<const RenderAttrib *, std::nullptr_t, indirect_compare_to_hash<const RenderAttrib *> > Attribs;
|
||||||
static Attribs *_attribs;
|
static Attribs _attribs;
|
||||||
|
|
||||||
int _saved_entry;
|
int _saved_entry;
|
||||||
size_t _hash;
|
size_t _hash;
|
||||||
|
@ -91,9 +91,9 @@ register_slot(TypeHandle type_handle, int sort, RenderAttrib *default_attrib) {
|
|||||||
|
|
||||||
if (default_attrib->_saved_entry == -1) {
|
if (default_attrib->_saved_entry == -1) {
|
||||||
// If this attribute was already registered, something odd is going on.
|
// If this attribute was already registered, something odd is going on.
|
||||||
nassertr(RenderAttrib::_attribs->find(default_attrib) == -1, 0);
|
nassertr(RenderAttrib::_attribs.find(default_attrib) == -1, 0);
|
||||||
default_attrib->_saved_entry =
|
default_attrib->_saved_entry =
|
||||||
RenderAttrib::_attribs->store(default_attrib, nullptr);
|
RenderAttrib::_attribs.store(default_attrib, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// It effectively lives forever. Might as well make it official.
|
// It effectively lives forever. Might as well make it official.
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
using std::ostream;
|
using std::ostream;
|
||||||
|
|
||||||
LightReMutex *RenderState::_states_lock = nullptr;
|
LightReMutex *RenderState::_states_lock = nullptr;
|
||||||
RenderState::States *RenderState::_states = nullptr;
|
RenderState::States RenderState::_states;
|
||||||
const RenderState *RenderState::_empty_state = nullptr;
|
const RenderState *RenderState::_empty_state = nullptr;
|
||||||
UpdateSeq RenderState::_last_cycle_detect;
|
UpdateSeq RenderState::_last_cycle_detect;
|
||||||
size_t RenderState::_garbage_index = 0;
|
size_t RenderState::_garbage_index = 0;
|
||||||
@ -68,7 +68,7 @@ RenderState() :
|
|||||||
_flags(0),
|
_flags(0),
|
||||||
_lock("RenderState")
|
_lock("RenderState")
|
||||||
{
|
{
|
||||||
if (_states == nullptr) {
|
if (_states_lock == nullptr) {
|
||||||
init_states();
|
init_states();
|
||||||
}
|
}
|
||||||
_saved_entry = -1;
|
_saved_entry = -1;
|
||||||
@ -716,11 +716,8 @@ get_max_priority() {
|
|||||||
*/
|
*/
|
||||||
int RenderState::
|
int RenderState::
|
||||||
get_num_states() {
|
get_num_states() {
|
||||||
if (_states == nullptr) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
LightReMutexHolder holder(*_states_lock);
|
LightReMutexHolder holder(*_states_lock);
|
||||||
return _states->get_num_entries();
|
return _states.get_num_entries();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -738,9 +735,6 @@ get_num_states() {
|
|||||||
*/
|
*/
|
||||||
int RenderState::
|
int RenderState::
|
||||||
get_num_unused_states() {
|
get_num_unused_states() {
|
||||||
if (_states == nullptr) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
LightReMutexHolder holder(*_states_lock);
|
LightReMutexHolder holder(*_states_lock);
|
||||||
|
|
||||||
// First, we need to count the number of times each RenderState object is
|
// First, we need to count the number of times each RenderState object is
|
||||||
@ -748,9 +742,9 @@ get_num_unused_states() {
|
|||||||
typedef pmap<const RenderState *, int> StateCount;
|
typedef pmap<const RenderState *, int> StateCount;
|
||||||
StateCount state_count;
|
StateCount state_count;
|
||||||
|
|
||||||
size_t size = _states->get_num_entries();
|
size_t size = _states.get_num_entries();
|
||||||
for (size_t si = 0; si < size; ++si) {
|
for (size_t si = 0; si < size; ++si) {
|
||||||
const RenderState *state = _states->get_key(si);
|
const RenderState *state = _states.get_key(si);
|
||||||
|
|
||||||
size_t i;
|
size_t i;
|
||||||
size_t cache_size = state->_composition_cache.get_num_entries();
|
size_t cache_size = state->_composition_cache.get_num_entries();
|
||||||
@ -821,13 +815,10 @@ get_num_unused_states() {
|
|||||||
*/
|
*/
|
||||||
int RenderState::
|
int RenderState::
|
||||||
clear_cache() {
|
clear_cache() {
|
||||||
if (_states == nullptr) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
LightReMutexHolder holder(*_states_lock);
|
LightReMutexHolder holder(*_states_lock);
|
||||||
|
|
||||||
PStatTimer timer(_cache_update_pcollector);
|
PStatTimer timer(_cache_update_pcollector);
|
||||||
int orig_size = _states->get_num_entries();
|
int orig_size = _states.get_num_entries();
|
||||||
|
|
||||||
// First, we need to copy the entire set of states to a temporary vector,
|
// 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,
|
// reference-counting each object. That way we can walk through the copy,
|
||||||
@ -838,9 +829,9 @@ clear_cache() {
|
|||||||
TempStates temp_states;
|
TempStates temp_states;
|
||||||
temp_states.reserve(orig_size);
|
temp_states.reserve(orig_size);
|
||||||
|
|
||||||
size_t size = _states->get_num_entries();
|
size_t size = _states.get_num_entries();
|
||||||
for (size_t si = 0; si < size; ++si) {
|
for (size_t si = 0; si < size; ++si) {
|
||||||
const RenderState *state = _states->get_key(si);
|
const RenderState *state = _states.get_key(si);
|
||||||
temp_states.push_back(state);
|
temp_states.push_back(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -879,7 +870,7 @@ clear_cache() {
|
|||||||
// the various objects' caches will go away.
|
// the various objects' caches will go away.
|
||||||
}
|
}
|
||||||
|
|
||||||
int new_size = _states->get_num_entries();
|
int new_size = _states.get_num_entries();
|
||||||
return orig_size - new_size;
|
return orig_size - new_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -895,14 +886,14 @@ int RenderState::
|
|||||||
garbage_collect() {
|
garbage_collect() {
|
||||||
int num_attribs = RenderAttrib::garbage_collect();
|
int num_attribs = RenderAttrib::garbage_collect();
|
||||||
|
|
||||||
if (_states == nullptr || !garbage_collect_states) {
|
if (!garbage_collect_states) {
|
||||||
return num_attribs;
|
return num_attribs;
|
||||||
}
|
}
|
||||||
|
|
||||||
LightReMutexHolder holder(*_states_lock);
|
LightReMutexHolder holder(*_states_lock);
|
||||||
|
|
||||||
PStatTimer timer(_garbage_collect_pcollector);
|
PStatTimer timer(_garbage_collect_pcollector);
|
||||||
size_t orig_size = _states->get_num_entries();
|
size_t orig_size = _states.get_num_entries();
|
||||||
|
|
||||||
// How many elements to process this pass?
|
// How many elements to process this pass?
|
||||||
size_t size = orig_size;
|
size_t size = orig_size;
|
||||||
@ -922,7 +913,7 @@ garbage_collect() {
|
|||||||
size_t stop_at_element = (si + num_this_pass) % size;
|
size_t stop_at_element = (si + num_this_pass) % size;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
RenderState *state = (RenderState *)_states->get_key(si);
|
RenderState *state = (RenderState *)_states.get_key(si);
|
||||||
if (break_and_uniquify) {
|
if (break_and_uniquify) {
|
||||||
if (state->get_cache_ref_count() > 0 &&
|
if (state->get_cache_ref_count() > 0 &&
|
||||||
state->get_ref_count() == state->get_cache_ref_count()) {
|
state->get_ref_count() == state->get_cache_ref_count()) {
|
||||||
@ -959,15 +950,15 @@ garbage_collect() {
|
|||||||
} while (si != stop_at_element);
|
} while (si != stop_at_element);
|
||||||
_garbage_index = si;
|
_garbage_index = si;
|
||||||
|
|
||||||
nassertr(_states->get_num_entries() == size, 0);
|
nassertr(_states.get_num_entries() == size, 0);
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
nassertr(_states->validate(), 0);
|
nassertr(_states.validate(), 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// If we just cleaned up a lot of states, see if we can reduce the table in
|
// If we just cleaned up a lot of states, see if we can reduce the table in
|
||||||
// size. This will help reduce iteration overhead in the future.
|
// size. This will help reduce iteration overhead in the future.
|
||||||
_states->consider_shrink_table();
|
_states.consider_shrink_table();
|
||||||
|
|
||||||
return (int)orig_size - (int)size + num_attribs;
|
return (int)orig_size - (int)size + num_attribs;
|
||||||
}
|
}
|
||||||
@ -980,9 +971,9 @@ void RenderState::
|
|||||||
clear_munger_cache() {
|
clear_munger_cache() {
|
||||||
LightReMutexHolder holder(*_states_lock);
|
LightReMutexHolder holder(*_states_lock);
|
||||||
|
|
||||||
size_t size = _states->get_num_entries();
|
size_t size = _states.get_num_entries();
|
||||||
for (size_t si = 0; si < size; ++si) {
|
for (size_t si = 0; si < size; ++si) {
|
||||||
RenderState *state = (RenderState *)(_states->get_key(si));
|
RenderState *state = (RenderState *)(_states.get_key(si));
|
||||||
state->_mungers.clear();
|
state->_mungers.clear();
|
||||||
state->_munged_states.clear();
|
state->_munged_states.clear();
|
||||||
state->_last_mi = -1;
|
state->_last_mi = -1;
|
||||||
@ -1004,18 +995,15 @@ clear_munger_cache() {
|
|||||||
*/
|
*/
|
||||||
void RenderState::
|
void RenderState::
|
||||||
list_cycles(ostream &out) {
|
list_cycles(ostream &out) {
|
||||||
if (_states == nullptr) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
LightReMutexHolder holder(*_states_lock);
|
LightReMutexHolder holder(*_states_lock);
|
||||||
|
|
||||||
typedef pset<const RenderState *> VisitedStates;
|
typedef pset<const RenderState *> VisitedStates;
|
||||||
VisitedStates visited;
|
VisitedStates visited;
|
||||||
CompositionCycleDesc cycle_desc;
|
CompositionCycleDesc cycle_desc;
|
||||||
|
|
||||||
size_t size = _states->get_num_entries();
|
size_t size = _states.get_num_entries();
|
||||||
for (size_t si = 0; si < size; ++si) {
|
for (size_t si = 0; si < size; ++si) {
|
||||||
const RenderState *state = _states->get_key(si);
|
const RenderState *state = _states.get_key(si);
|
||||||
|
|
||||||
bool inserted = visited.insert(state).second;
|
bool inserted = visited.insert(state).second;
|
||||||
if (inserted) {
|
if (inserted) {
|
||||||
@ -1081,16 +1069,12 @@ list_cycles(ostream &out) {
|
|||||||
*/
|
*/
|
||||||
void RenderState::
|
void RenderState::
|
||||||
list_states(ostream &out) {
|
list_states(ostream &out) {
|
||||||
if (_states == nullptr) {
|
|
||||||
out << "0 states:\n";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
LightReMutexHolder holder(*_states_lock);
|
LightReMutexHolder holder(*_states_lock);
|
||||||
|
|
||||||
size_t size = _states->get_num_entries();
|
size_t size = _states.get_num_entries();
|
||||||
out << size << " states:\n";
|
out << size << " states:\n";
|
||||||
for (size_t si = 0; si < size; ++si) {
|
for (size_t si = 0; si < size; ++si) {
|
||||||
const RenderState *state = _states->get_key(si);
|
const RenderState *state = _states.get_key(si);
|
||||||
state->write(out, 2);
|
state->write(out, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1103,33 +1087,29 @@ list_states(ostream &out) {
|
|||||||
*/
|
*/
|
||||||
bool RenderState::
|
bool RenderState::
|
||||||
validate_states() {
|
validate_states() {
|
||||||
if (_states == nullptr) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
PStatTimer timer(_state_validate_pcollector);
|
PStatTimer timer(_state_validate_pcollector);
|
||||||
|
|
||||||
LightReMutexHolder holder(*_states_lock);
|
LightReMutexHolder holder(*_states_lock);
|
||||||
if (_states->is_empty()) {
|
if (_states.is_empty()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_states->validate()) {
|
if (!_states.validate()) {
|
||||||
pgraph_cat.error()
|
pgraph_cat.error()
|
||||||
<< "RenderState::_states cache is invalid!\n";
|
<< "RenderState::_states cache is invalid!\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size = _states->get_num_entries();
|
size_t size = _states.get_num_entries();
|
||||||
size_t si = 0;
|
size_t si = 0;
|
||||||
nassertr(si < size, false);
|
nassertr(si < size, false);
|
||||||
nassertr(_states->get_key(si)->get_ref_count() >= 0, false);
|
nassertr(_states.get_key(si)->get_ref_count() >= 0, false);
|
||||||
size_t snext = si;
|
size_t snext = si;
|
||||||
++snext;
|
++snext;
|
||||||
while (snext < size) {
|
while (snext < size) {
|
||||||
nassertr(_states->get_key(snext)->get_ref_count() >= 0, false);
|
nassertr(_states.get_key(snext)->get_ref_count() >= 0, false);
|
||||||
const RenderState *ssi = _states->get_key(si);
|
const RenderState *ssi = _states.get_key(si);
|
||||||
const RenderState *ssnext = _states->get_key(snext);
|
const RenderState *ssnext = _states.get_key(snext);
|
||||||
int c = ssi->compare_to(*ssnext);
|
int c = ssi->compare_to(*ssnext);
|
||||||
int ci = ssnext->compare_to(*ssi);
|
int ci = ssnext->compare_to(*ssi);
|
||||||
if ((ci < 0) != (c > 0) ||
|
if ((ci < 0) != (c > 0) ||
|
||||||
@ -1299,7 +1279,7 @@ return_unique(RenderState *state) {
|
|||||||
LightReMutexHolder holder(*_states_lock);
|
LightReMutexHolder holder(*_states_lock);
|
||||||
|
|
||||||
if (state->_saved_entry != -1) {
|
if (state->_saved_entry != -1) {
|
||||||
// This state is already in the cache. nassertr(_states->find(state) ==
|
// This state is already in the cache. nassertr(_states.find(state) ==
|
||||||
// state->_saved_entry, pt_state);
|
// state->_saved_entry, pt_state);
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
@ -1318,7 +1298,7 @@ return_unique(RenderState *state) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int si = _states->find(state);
|
int si = _states.find(state);
|
||||||
if (si != -1) {
|
if (si != -1) {
|
||||||
// There's an equivalent state already in the set. Return it. The state
|
// There's an equivalent state already in the set. Return it. The state
|
||||||
// that was passed may be newly created and therefore may not be
|
// that was passed may be newly created and therefore may not be
|
||||||
@ -1326,7 +1306,7 @@ return_unique(RenderState *state) {
|
|||||||
if (state->get_ref_count() == 0) {
|
if (state->get_ref_count() == 0) {
|
||||||
delete state;
|
delete state;
|
||||||
}
|
}
|
||||||
return _states->get_key(si);
|
return _states.get_key(si);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not already in the set; add it.
|
// Not already in the set; add it.
|
||||||
@ -1336,7 +1316,7 @@ return_unique(RenderState *state) {
|
|||||||
// deleted while it's in it.
|
// deleted while it's in it.
|
||||||
state->cache_ref();
|
state->cache_ref();
|
||||||
}
|
}
|
||||||
si = _states->store(state, nullptr);
|
si = _states.store(state, nullptr);
|
||||||
|
|
||||||
// Save the index and return the input state.
|
// Save the index and return the input state.
|
||||||
state->_saved_entry = si;
|
state->_saved_entry = si;
|
||||||
@ -1612,7 +1592,7 @@ release_new() {
|
|||||||
|
|
||||||
if (_saved_entry != -1) {
|
if (_saved_entry != -1) {
|
||||||
_saved_entry = -1;
|
_saved_entry = -1;
|
||||||
nassertv_always(_states->remove(this));
|
nassertv_always(_states.remove(this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1849,8 +1829,6 @@ update_pstats(int old_referenced_bits, int new_referenced_bits) {
|
|||||||
*/
|
*/
|
||||||
void RenderState::
|
void RenderState::
|
||||||
init_states() {
|
init_states() {
|
||||||
_states = new States;
|
|
||||||
|
|
||||||
// TODO: we should have a global Panda mutex to allow us to safely create
|
// TODO: we should have a global Panda mutex to allow us to safely create
|
||||||
// _states_lock without a startup race condition. For the meantime, this is
|
// _states_lock without a startup race condition. For the meantime, this is
|
||||||
// OK because we guarantee that this method is called at static init time,
|
// OK because we guarantee that this method is called at static init time,
|
||||||
@ -1863,7 +1841,7 @@ init_states() {
|
|||||||
// is declared globally, and lives forever.
|
// is declared globally, and lives forever.
|
||||||
RenderState *state = new RenderState;
|
RenderState *state = new RenderState;
|
||||||
state->local_object();
|
state->local_object();
|
||||||
state->_saved_entry = _states->store(state, nullptr);
|
state->_saved_entry = _states.store(state, nullptr);
|
||||||
_empty_state = state;
|
_empty_state = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,7 +232,7 @@ private:
|
|||||||
// _invert_composition_cache.
|
// _invert_composition_cache.
|
||||||
static LightReMutex *_states_lock;
|
static LightReMutex *_states_lock;
|
||||||
typedef SimpleHashMap<const RenderState *, std::nullptr_t, indirect_compare_to_hash<const RenderState *> > States;
|
typedef SimpleHashMap<const RenderState *, std::nullptr_t, indirect_compare_to_hash<const RenderState *> > States;
|
||||||
static States *_states;
|
static States _states;
|
||||||
static const RenderState *_empty_state;
|
static const RenderState *_empty_state;
|
||||||
|
|
||||||
// This iterator records the entry corresponding to this RenderState object
|
// This iterator records the entry corresponding to this RenderState object
|
||||||
|
@ -118,18 +118,15 @@ get_invert_composition_cache() const {
|
|||||||
PyObject *Extension<RenderState>::
|
PyObject *Extension<RenderState>::
|
||||||
get_states() {
|
get_states() {
|
||||||
extern struct Dtool_PyTypedObject Dtool_RenderState;
|
extern struct Dtool_PyTypedObject Dtool_RenderState;
|
||||||
if (RenderState::_states == nullptr) {
|
|
||||||
return PyList_New(0);
|
|
||||||
}
|
|
||||||
LightReMutexHolder holder(*RenderState::_states_lock);
|
LightReMutexHolder holder(*RenderState::_states_lock);
|
||||||
|
|
||||||
size_t num_states = RenderState::_states->get_num_entries();
|
size_t num_states = RenderState::_states.get_num_entries();
|
||||||
PyObject *list = PyList_New(num_states);
|
PyObject *list = PyList_New(num_states);
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
|
||||||
size_t size = RenderState::_states->get_num_entries();
|
size_t size = RenderState::_states.get_num_entries();
|
||||||
for (size_t si = 0; si < size; ++si) {
|
for (size_t si = 0; si < size; ++si) {
|
||||||
const RenderState *state = RenderState::_states->get_key(si);
|
const RenderState *state = RenderState::_states.get_key(si);
|
||||||
state->ref();
|
state->ref();
|
||||||
PyObject *a =
|
PyObject *a =
|
||||||
DTool_CreatePyInstanceTyped((void *)state, Dtool_RenderState,
|
DTool_CreatePyInstanceTyped((void *)state, Dtool_RenderState,
|
||||||
@ -142,6 +139,4 @@ get_states() {
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // HAVE_PYTHON
|
#endif // HAVE_PYTHON
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
using std::ostream;
|
using std::ostream;
|
||||||
|
|
||||||
LightReMutex *TransformState::_states_lock = nullptr;
|
LightReMutex *TransformState::_states_lock = nullptr;
|
||||||
TransformState::States *TransformState::_states = nullptr;
|
TransformState::States TransformState::_states;
|
||||||
CPT(TransformState) TransformState::_identity_state;
|
CPT(TransformState) TransformState::_identity_state;
|
||||||
CPT(TransformState) TransformState::_invalid_state;
|
CPT(TransformState) TransformState::_invalid_state;
|
||||||
UpdateSeq TransformState::_last_cycle_detect;
|
UpdateSeq TransformState::_last_cycle_detect;
|
||||||
@ -57,7 +57,7 @@ TypeHandle TransformState::_type_handle;
|
|||||||
*/
|
*/
|
||||||
TransformState::
|
TransformState::
|
||||||
TransformState() : _lock("TransformState") {
|
TransformState() : _lock("TransformState") {
|
||||||
if (_states == nullptr) {
|
if (_states_lock == nullptr) {
|
||||||
init_states();
|
init_states();
|
||||||
}
|
}
|
||||||
_saved_entry = -1;
|
_saved_entry = -1;
|
||||||
@ -988,11 +988,8 @@ write_composition_cache(ostream &out, int indent_level) const {
|
|||||||
*/
|
*/
|
||||||
int TransformState::
|
int TransformState::
|
||||||
get_num_states() {
|
get_num_states() {
|
||||||
if (_states == nullptr) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
LightReMutexHolder holder(*_states_lock);
|
LightReMutexHolder holder(*_states_lock);
|
||||||
return _states->get_num_entries();
|
return _states.get_num_entries();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1010,9 +1007,6 @@ get_num_states() {
|
|||||||
*/
|
*/
|
||||||
int TransformState::
|
int TransformState::
|
||||||
get_num_unused_states() {
|
get_num_unused_states() {
|
||||||
if (_states == nullptr) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
LightReMutexHolder holder(*_states_lock);
|
LightReMutexHolder holder(*_states_lock);
|
||||||
|
|
||||||
// First, we need to count the number of times each TransformState object is
|
// First, we need to count the number of times each TransformState object is
|
||||||
@ -1021,9 +1015,9 @@ get_num_unused_states() {
|
|||||||
typedef pmap<const TransformState *, int> StateCount;
|
typedef pmap<const TransformState *, int> StateCount;
|
||||||
StateCount state_count;
|
StateCount state_count;
|
||||||
|
|
||||||
size_t size = _states->get_num_entries();
|
size_t size = _states.get_num_entries();
|
||||||
for (size_t si = 0; si < size; ++si) {
|
for (size_t si = 0; si < size; ++si) {
|
||||||
const TransformState *state = _states->get_key(si);
|
const TransformState *state = _states.get_key(si);
|
||||||
|
|
||||||
size_t i;
|
size_t i;
|
||||||
size_t cache_size = state->_composition_cache.get_num_entries();
|
size_t cache_size = state->_composition_cache.get_num_entries();
|
||||||
@ -1095,13 +1089,10 @@ get_num_unused_states() {
|
|||||||
*/
|
*/
|
||||||
int TransformState::
|
int TransformState::
|
||||||
clear_cache() {
|
clear_cache() {
|
||||||
if (_states == nullptr) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
LightReMutexHolder holder(*_states_lock);
|
LightReMutexHolder holder(*_states_lock);
|
||||||
|
|
||||||
PStatTimer timer(_cache_update_pcollector);
|
PStatTimer timer(_cache_update_pcollector);
|
||||||
int orig_size = _states->get_num_entries();
|
int orig_size = _states.get_num_entries();
|
||||||
|
|
||||||
// First, we need to copy the entire set of states to a temporary vector,
|
// 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,
|
// reference-counting each object. That way we can walk through the copy,
|
||||||
@ -1112,9 +1103,9 @@ clear_cache() {
|
|||||||
TempStates temp_states;
|
TempStates temp_states;
|
||||||
temp_states.reserve(orig_size);
|
temp_states.reserve(orig_size);
|
||||||
|
|
||||||
size_t size = _states->get_num_entries();
|
size_t size = _states.get_num_entries();
|
||||||
for (size_t si = 0; si < size; ++si) {
|
for (size_t si = 0; si < size; ++si) {
|
||||||
const TransformState *state = _states->get_key(si);
|
const TransformState *state = _states.get_key(si);
|
||||||
temp_states.push_back(state);
|
temp_states.push_back(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1153,7 +1144,7 @@ clear_cache() {
|
|||||||
// the various objects' caches will go away.
|
// the various objects' caches will go away.
|
||||||
}
|
}
|
||||||
|
|
||||||
int new_size = _states->get_num_entries();
|
int new_size = _states.get_num_entries();
|
||||||
return orig_size - new_size;
|
return orig_size - new_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1165,14 +1156,14 @@ clear_cache() {
|
|||||||
*/
|
*/
|
||||||
int TransformState::
|
int TransformState::
|
||||||
garbage_collect() {
|
garbage_collect() {
|
||||||
if (_states == nullptr || !garbage_collect_states) {
|
if (!garbage_collect_states) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
LightReMutexHolder holder(*_states_lock);
|
LightReMutexHolder holder(*_states_lock);
|
||||||
|
|
||||||
PStatTimer timer(_garbage_collect_pcollector);
|
PStatTimer timer(_garbage_collect_pcollector);
|
||||||
size_t orig_size = _states->get_num_entries();
|
size_t orig_size = _states.get_num_entries();
|
||||||
|
|
||||||
// How many elements to process this pass?
|
// How many elements to process this pass?
|
||||||
size_t size = orig_size;
|
size_t size = orig_size;
|
||||||
@ -1192,7 +1183,7 @@ garbage_collect() {
|
|||||||
size_t stop_at_element = (si + num_this_pass) % size;
|
size_t stop_at_element = (si + num_this_pass) % size;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
TransformState *state = (TransformState *)_states->get_key(si);
|
TransformState *state = (TransformState *)_states.get_key(si);
|
||||||
if (break_and_uniquify) {
|
if (break_and_uniquify) {
|
||||||
if (state->get_cache_ref_count() > 0 &&
|
if (state->get_cache_ref_count() > 0 &&
|
||||||
state->get_ref_count() == state->get_cache_ref_count()) {
|
state->get_ref_count() == state->get_cache_ref_count()) {
|
||||||
@ -1229,15 +1220,15 @@ garbage_collect() {
|
|||||||
} while (si != stop_at_element);
|
} while (si != stop_at_element);
|
||||||
_garbage_index = si;
|
_garbage_index = si;
|
||||||
|
|
||||||
nassertr(_states->get_num_entries() == size, 0);
|
nassertr(_states.get_num_entries() == size, 0);
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
nassertr(_states->validate(), 0);
|
nassertr(_states.validate(), 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// If we just cleaned up a lot of states, see if we can reduce the table in
|
// If we just cleaned up a lot of states, see if we can reduce the table in
|
||||||
// size. This will help reduce iteration overhead in the future.
|
// size. This will help reduce iteration overhead in the future.
|
||||||
_states->consider_shrink_table();
|
_states.consider_shrink_table();
|
||||||
|
|
||||||
return (int)orig_size - (int)size;
|
return (int)orig_size - (int)size;
|
||||||
}
|
}
|
||||||
@ -1257,18 +1248,15 @@ garbage_collect() {
|
|||||||
*/
|
*/
|
||||||
void TransformState::
|
void TransformState::
|
||||||
list_cycles(ostream &out) {
|
list_cycles(ostream &out) {
|
||||||
if (_states == nullptr) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
LightReMutexHolder holder(*_states_lock);
|
LightReMutexHolder holder(*_states_lock);
|
||||||
|
|
||||||
typedef pset<const TransformState *> VisitedStates;
|
typedef pset<const TransformState *> VisitedStates;
|
||||||
VisitedStates visited;
|
VisitedStates visited;
|
||||||
CompositionCycleDesc cycle_desc;
|
CompositionCycleDesc cycle_desc;
|
||||||
|
|
||||||
size_t size = _states->get_num_entries();
|
size_t size = _states.get_num_entries();
|
||||||
for (size_t si = 0; si < size; ++si) {
|
for (size_t si = 0; si < size; ++si) {
|
||||||
const TransformState *state = _states->get_key(si);
|
const TransformState *state = _states.get_key(si);
|
||||||
|
|
||||||
bool inserted = visited.insert(state).second;
|
bool inserted = visited.insert(state).second;
|
||||||
if (inserted) {
|
if (inserted) {
|
||||||
@ -1334,16 +1322,12 @@ list_cycles(ostream &out) {
|
|||||||
*/
|
*/
|
||||||
void TransformState::
|
void TransformState::
|
||||||
list_states(ostream &out) {
|
list_states(ostream &out) {
|
||||||
if (_states == nullptr) {
|
|
||||||
out << "0 states:\n";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
LightReMutexHolder holder(*_states_lock);
|
LightReMutexHolder holder(*_states_lock);
|
||||||
|
|
||||||
size_t size = _states->get_num_entries();
|
size_t size = _states.get_num_entries();
|
||||||
out << size << " states:\n";
|
out << size << " states:\n";
|
||||||
for (size_t si = 0; si < size; ++si) {
|
for (size_t si = 0; si < size; ++si) {
|
||||||
const TransformState *state = _states->get_key(si);
|
const TransformState *state = _states.get_key(si);
|
||||||
state->write(out, 2);
|
state->write(out, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1356,36 +1340,32 @@ list_states(ostream &out) {
|
|||||||
*/
|
*/
|
||||||
bool TransformState::
|
bool TransformState::
|
||||||
validate_states() {
|
validate_states() {
|
||||||
if (_states == nullptr) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
PStatTimer timer(_transform_validate_pcollector);
|
PStatTimer timer(_transform_validate_pcollector);
|
||||||
|
|
||||||
LightReMutexHolder holder(*_states_lock);
|
LightReMutexHolder holder(*_states_lock);
|
||||||
if (_states->is_empty()) {
|
if (_states.is_empty()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_states->validate()) {
|
if (!_states.validate()) {
|
||||||
pgraph_cat.error()
|
pgraph_cat.error()
|
||||||
<< "TransformState::_states cache is invalid!\n";
|
<< "TransformState::_states cache is invalid!\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size = _states->get_num_entries();
|
size_t size = _states.get_num_entries();
|
||||||
size_t si = 0;
|
size_t si = 0;
|
||||||
nassertr(si < size, false);
|
nassertr(si < size, false);
|
||||||
nassertr(_states->get_key(si)->get_ref_count() >= 0, false);
|
nassertr(_states.get_key(si)->get_ref_count() >= 0, false);
|
||||||
size_t snext = si;
|
size_t snext = si;
|
||||||
++snext;
|
++snext;
|
||||||
while (snext < size) {
|
while (snext < size) {
|
||||||
nassertr(_states->get_key(snext)->get_ref_count() >= 0, false);
|
nassertr(_states.get_key(snext)->get_ref_count() >= 0, false);
|
||||||
const TransformState *ssi = _states->get_key(si);
|
const TransformState *ssi = _states.get_key(si);
|
||||||
if (!ssi->validate_composition_cache()) {
|
if (!ssi->validate_composition_cache()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const TransformState *ssnext = _states->get_key(snext);
|
const TransformState *ssnext = _states.get_key(snext);
|
||||||
bool c = (*ssi) == (*ssnext);
|
bool c = (*ssi) == (*ssnext);
|
||||||
bool ci = (*ssnext) == (*ssi);
|
bool ci = (*ssnext) == (*ssi);
|
||||||
if (c != ci) {
|
if (c != ci) {
|
||||||
@ -1415,8 +1395,6 @@ validate_states() {
|
|||||||
*/
|
*/
|
||||||
void TransformState::
|
void TransformState::
|
||||||
init_states() {
|
init_states() {
|
||||||
_states = new States;
|
|
||||||
|
|
||||||
ConfigVariableBool uniquify_matrix
|
ConfigVariableBool uniquify_matrix
|
||||||
("uniquify-matrix", true,
|
("uniquify-matrix", true,
|
||||||
PRC_DESC("Set this true to look up arbitrary 4x4 transform matrices in "
|
PRC_DESC("Set this true to look up arbitrary 4x4 transform matrices in "
|
||||||
@ -1483,7 +1461,7 @@ return_unique(TransformState *state) {
|
|||||||
LightReMutexHolder holder(*_states_lock);
|
LightReMutexHolder holder(*_states_lock);
|
||||||
|
|
||||||
if (state->_saved_entry != -1) {
|
if (state->_saved_entry != -1) {
|
||||||
// This state is already in the cache. nassertr(_states->find(state) ==
|
// This state is already in the cache. nassertr(_states.find(state) ==
|
||||||
// state->_saved_entry, state);
|
// state->_saved_entry, state);
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
@ -1492,10 +1470,10 @@ return_unique(TransformState *state) {
|
|||||||
// of this function if no one else uses it.
|
// of this function if no one else uses it.
|
||||||
CPT(TransformState) pt_state = state;
|
CPT(TransformState) pt_state = state;
|
||||||
|
|
||||||
int si = _states->find(state);
|
int si = _states.find(state);
|
||||||
if (si != -1) {
|
if (si != -1) {
|
||||||
// There's an equivalent state already in the set. Return it.
|
// There's an equivalent state already in the set. Return it.
|
||||||
return _states->get_key(si);
|
return _states.get_key(si);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not already in the set; add it.
|
// Not already in the set; add it.
|
||||||
@ -1505,7 +1483,7 @@ return_unique(TransformState *state) {
|
|||||||
// deleted while it's in it.
|
// deleted while it's in it.
|
||||||
state->cache_ref();
|
state->cache_ref();
|
||||||
}
|
}
|
||||||
si = _states->store(state, nullptr);
|
si = _states.store(state, nullptr);
|
||||||
|
|
||||||
// Save the index and return the input state.
|
// Save the index and return the input state.
|
||||||
state->_saved_entry = si;
|
state->_saved_entry = si;
|
||||||
@ -1893,7 +1871,7 @@ release_new() {
|
|||||||
|
|
||||||
if (_saved_entry != -1) {
|
if (_saved_entry != -1) {
|
||||||
_saved_entry = -1;
|
_saved_entry = -1;
|
||||||
nassertv_always(_states->remove(this));
|
nassertv_always(_states.remove(this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,7 +253,7 @@ private:
|
|||||||
// _invert_composition_cache.
|
// _invert_composition_cache.
|
||||||
static LightReMutex *_states_lock;
|
static LightReMutex *_states_lock;
|
||||||
typedef SimpleHashMap<const TransformState *, std::nullptr_t, indirect_equals_hash<const TransformState *> > States;
|
typedef SimpleHashMap<const TransformState *, std::nullptr_t, indirect_equals_hash<const TransformState *> > States;
|
||||||
static States *_states;
|
static States _states;
|
||||||
static CPT(TransformState) _identity_state;
|
static CPT(TransformState) _identity_state;
|
||||||
static CPT(TransformState) _invalid_state;
|
static CPT(TransformState) _invalid_state;
|
||||||
|
|
||||||
|
@ -132,18 +132,15 @@ get_invert_composition_cache() const {
|
|||||||
PyObject *Extension<TransformState>::
|
PyObject *Extension<TransformState>::
|
||||||
get_states() {
|
get_states() {
|
||||||
extern struct Dtool_PyTypedObject Dtool_TransformState;
|
extern struct Dtool_PyTypedObject Dtool_TransformState;
|
||||||
if (TransformState::_states == nullptr) {
|
|
||||||
return PyList_New(0);
|
|
||||||
}
|
|
||||||
LightReMutexHolder holder(*TransformState::_states_lock);
|
LightReMutexHolder holder(*TransformState::_states_lock);
|
||||||
|
|
||||||
size_t num_states = TransformState::_states->get_num_entries();
|
size_t num_states = TransformState::_states.get_num_entries();
|
||||||
PyObject *list = PyList_New(num_states);
|
PyObject *list = PyList_New(num_states);
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
|
||||||
size_t size = TransformState::_states->get_num_entries();
|
size_t size = TransformState::_states.get_num_entries();
|
||||||
for (size_t si = 0; si < size; ++si) {
|
for (size_t si = 0; si < size; ++si) {
|
||||||
const TransformState *state = TransformState::_states->get_key(si);
|
const TransformState *state = TransformState::_states.get_key(si);
|
||||||
state->ref();
|
state->ref();
|
||||||
PyObject *a =
|
PyObject *a =
|
||||||
DTool_CreatePyInstanceTyped((void *)state, Dtool_TransformState,
|
DTool_CreatePyInstanceTyped((void *)state, Dtool_TransformState,
|
||||||
@ -163,15 +160,12 @@ get_states() {
|
|||||||
PyObject *Extension<TransformState>::
|
PyObject *Extension<TransformState>::
|
||||||
get_unused_states() {
|
get_unused_states() {
|
||||||
extern struct Dtool_PyTypedObject Dtool_TransformState;
|
extern struct Dtool_PyTypedObject Dtool_TransformState;
|
||||||
if (TransformState::_states == nullptr) {
|
|
||||||
return PyList_New(0);
|
|
||||||
}
|
|
||||||
LightReMutexHolder holder(*TransformState::_states_lock);
|
LightReMutexHolder holder(*TransformState::_states_lock);
|
||||||
|
|
||||||
PyObject *list = PyList_New(0);
|
PyObject *list = PyList_New(0);
|
||||||
size_t size = TransformState::_states->get_num_entries();
|
size_t size = TransformState::_states.get_num_entries();
|
||||||
for (size_t si = 0; si < size; ++si) {
|
for (size_t si = 0; si < size; ++si) {
|
||||||
const TransformState *state = TransformState::_states->get_key(si);
|
const TransformState *state = TransformState::_states.get_key(si);
|
||||||
if (state->get_cache_ref_count() == state->get_ref_count()) {
|
if (state->get_cache_ref_count() == state->get_ref_count()) {
|
||||||
state->ref();
|
state->ref();
|
||||||
PyObject *a =
|
PyObject *a =
|
||||||
|
@ -580,9 +580,9 @@ rehash_generated_shaders() {
|
|||||||
|
|
||||||
// With uniquify-states turned on, we can actually go through all the states
|
// With uniquify-states turned on, we can actually go through all the states
|
||||||
// and check whether their generated shader is still OK.
|
// and check whether their generated shader is still OK.
|
||||||
size_t size = RenderState::_states->get_num_entries();
|
size_t size = RenderState::_states.get_num_entries();
|
||||||
for (size_t si = 0; si < size; ++si) {
|
for (size_t si = 0; si < size; ++si) {
|
||||||
const RenderState *state = RenderState::_states->get_key(si);
|
const RenderState *state = RenderState::_states.get_key(si);
|
||||||
|
|
||||||
if (state->_generated_shader != nullptr) {
|
if (state->_generated_shader != nullptr) {
|
||||||
ShaderKey key;
|
ShaderKey key;
|
||||||
@ -619,9 +619,9 @@ void ShaderGenerator::
|
|||||||
clear_generated_shaders() {
|
clear_generated_shaders() {
|
||||||
LightReMutexHolder holder(*RenderState::_states_lock);
|
LightReMutexHolder holder(*RenderState::_states_lock);
|
||||||
|
|
||||||
size_t size = RenderState::_states->get_num_entries();
|
size_t size = RenderState::_states.get_num_entries();
|
||||||
for (size_t si = 0; si < size; ++si) {
|
for (size_t si = 0; si < size; ++si) {
|
||||||
const RenderState *state = RenderState::_states->get_key(si);
|
const RenderState *state = RenderState::_states.get_key(si);
|
||||||
state->_generated_shader.clear();
|
state->_generated_shader.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user