mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 16:58:40 -04:00
Store munged states more efficiently, without weak key maps
This commit is contained in:
parent
8078fa2b38
commit
6ecfcb1fd3
@ -281,6 +281,11 @@ GraphicsStateGuardian(CoordinateSystem internal_coordinate_system,
|
|||||||
|
|
||||||
_gamma = 1.0f;
|
_gamma = 1.0f;
|
||||||
_texture_quality_override = Texture::QL_default;
|
_texture_quality_override = Texture::QL_default;
|
||||||
|
|
||||||
|
// Give it a unique identifier. Unlike a pointer, we can guarantee that
|
||||||
|
// this value will never be reused.
|
||||||
|
static size_t next_index = 0;
|
||||||
|
_id = next_index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -290,6 +295,19 @@ GraphicsStateGuardian::
|
|||||||
~GraphicsStateGuardian() {
|
~GraphicsStateGuardian() {
|
||||||
remove_gsg(this);
|
remove_gsg(this);
|
||||||
GeomMunger::unregister_mungers_for_gsg(this);
|
GeomMunger::unregister_mungers_for_gsg(this);
|
||||||
|
|
||||||
|
// Remove the munged states for this GSG. This requires going through all
|
||||||
|
// states, although destructing a GSG should be rare enough for this not to
|
||||||
|
// matter too much.
|
||||||
|
// 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.
|
||||||
|
LightReMutexHolder holder(*RenderState::_states_lock);
|
||||||
|
size_t size = RenderState::_states->get_num_entries();
|
||||||
|
for (size_t si = 0; si < size; ++si) {
|
||||||
|
const RenderState *state = RenderState::_states->get_key(si);
|
||||||
|
state->_mungers.remove(_id);
|
||||||
|
state->_munged_states.remove(_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -743,7 +761,7 @@ get_geom_munger(const RenderState *state, Thread *current_thread) {
|
|||||||
// multiple times during a frame. Also, this might well be the only GSG
|
// multiple times during a frame. Also, this might well be the only GSG
|
||||||
// in the world anyway.
|
// in the world anyway.
|
||||||
int mi = state->_last_mi;
|
int mi = state->_last_mi;
|
||||||
if (mi >= 0 && mungers.has_element(mi) && mungers.get_key(mi) == this) {
|
if (mi >= 0 && mi < mungers.get_num_entries() && mungers.get_key(mi) == _id) {
|
||||||
PT(GeomMunger) munger = mungers.get_data(mi);
|
PT(GeomMunger) munger = mungers.get_data(mi);
|
||||||
if (munger->is_registered()) {
|
if (munger->is_registered()) {
|
||||||
return munger;
|
return munger;
|
||||||
@ -751,7 +769,7 @@ get_geom_munger(const RenderState *state, Thread *current_thread) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Nope, we have to look it up in the map.
|
// Nope, we have to look it up in the map.
|
||||||
mi = mungers.find(this);
|
mi = mungers.find(_id);
|
||||||
if (mi >= 0) {
|
if (mi >= 0) {
|
||||||
PT(GeomMunger) munger = mungers.get_data(mi);
|
PT(GeomMunger) munger = mungers.get_data(mi);
|
||||||
if (munger->is_registered()) {
|
if (munger->is_registered()) {
|
||||||
@ -769,7 +787,7 @@ get_geom_munger(const RenderState *state, Thread *current_thread) {
|
|||||||
nassertr(munger != (GeomMunger *)NULL && munger->is_registered(), munger);
|
nassertr(munger != (GeomMunger *)NULL && munger->is_registered(), munger);
|
||||||
nassertr(munger->is_of_type(StateMunger::get_class_type()), munger);
|
nassertr(munger->is_of_type(StateMunger::get_class_type()), munger);
|
||||||
|
|
||||||
state->_last_mi = mungers.store(this, munger);
|
state->_last_mi = mungers.store(_id, munger);
|
||||||
return munger;
|
return munger;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,6 +235,8 @@ public:
|
|||||||
static void add_gsg(GraphicsStateGuardianBase *gsg);
|
static void add_gsg(GraphicsStateGuardianBase *gsg);
|
||||||
static void remove_gsg(GraphicsStateGuardianBase *gsg);
|
static void remove_gsg(GraphicsStateGuardianBase *gsg);
|
||||||
|
|
||||||
|
size_t _id;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct GSGList {
|
struct GSGList {
|
||||||
LightMutex _lock;
|
LightMutex _lock;
|
||||||
|
@ -987,6 +987,7 @@ clear_munger_cache() {
|
|||||||
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->_last_mi = -1;
|
state->_last_mi = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,10 +30,8 @@
|
|||||||
#include "lightMutex.h"
|
#include "lightMutex.h"
|
||||||
#include "deletedChain.h"
|
#include "deletedChain.h"
|
||||||
#include "simpleHashMap.h"
|
#include "simpleHashMap.h"
|
||||||
#include "weakKeyHashMap.h"
|
|
||||||
#include "cacheStats.h"
|
#include "cacheStats.h"
|
||||||
#include "renderAttribRegistry.h"
|
#include "renderAttribRegistry.h"
|
||||||
#include "graphicsStateGuardianBase.h"
|
|
||||||
|
|
||||||
class FactoryParams;
|
class FactoryParams;
|
||||||
class ShaderAttrib;
|
class ShaderAttrib;
|
||||||
@ -264,10 +262,15 @@ private:
|
|||||||
// in the RenderState pointer than vice-versa, since there are likely to be
|
// in the RenderState pointer than vice-versa, since there are likely to be
|
||||||
// far fewer GSG's than RenderStates. The code to manage this map lives in
|
// far fewer GSG's than RenderStates. The code to manage this map lives in
|
||||||
// GraphicsStateGuardian::get_geom_munger().
|
// GraphicsStateGuardian::get_geom_munger().
|
||||||
typedef WeakKeyHashMap<GraphicsStateGuardianBase, PT(GeomMunger) > Mungers;
|
typedef SimpleHashMap<size_t, PT(GeomMunger), size_t_hash> Mungers;
|
||||||
mutable Mungers _mungers;
|
mutable Mungers _mungers;
|
||||||
mutable int _last_mi;
|
mutable int _last_mi;
|
||||||
|
|
||||||
|
// Similarly, this is a cache of munged states. This map is managed by
|
||||||
|
// StateMunger::munge_state().
|
||||||
|
typedef SimpleHashMap<size_t, WCPT(RenderState), size_t_hash> MungedStates;
|
||||||
|
mutable MungedStates _munged_states;
|
||||||
|
|
||||||
// This is used to mark nodes as we visit them to detect cycles.
|
// This is used to mark nodes as we visit them to detect cycles.
|
||||||
UpdateSeq _cycle_detect;
|
UpdateSeq _cycle_detect;
|
||||||
static UpdateSeq _last_cycle_detect;
|
static UpdateSeq _last_cycle_detect;
|
||||||
@ -360,6 +363,7 @@ private:
|
|||||||
friend class GraphicsStateGuardian;
|
friend class GraphicsStateGuardian;
|
||||||
friend class RenderAttribRegistry;
|
friend class RenderAttribRegistry;
|
||||||
friend class Extension<RenderState>;
|
friend class Extension<RenderState>;
|
||||||
|
friend class StateMunger;
|
||||||
};
|
};
|
||||||
|
|
||||||
// We can safely redefine this as a no-op.
|
// We can safely redefine this as a no-op.
|
||||||
|
@ -27,15 +27,20 @@ StateMunger::
|
|||||||
*/
|
*/
|
||||||
CPT(RenderState) StateMunger::
|
CPT(RenderState) StateMunger::
|
||||||
munge_state(const RenderState *state) {
|
munge_state(const RenderState *state) {
|
||||||
int mi = _state_map.find(state);
|
RenderState::MungedStates &munged_states = state->_munged_states;
|
||||||
|
|
||||||
|
int id = get_gsg()->_id;
|
||||||
|
int mi = munged_states.find(id);
|
||||||
if (mi != -1) {
|
if (mi != -1) {
|
||||||
if (!_state_map.get_data(mi).was_deleted()) {
|
if (!munged_states.get_data(mi).was_deleted()) {
|
||||||
return _state_map.get_data(mi).p();
|
return munged_states.get_data(mi).p();
|
||||||
|
} else {
|
||||||
|
munged_states.remove_element(mi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CPT(RenderState) result = munge_state_impl(state);
|
CPT(RenderState) result = munge_state_impl(state);
|
||||||
_state_map.store(state, result.p());
|
munged_states.store(id, result.p());
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -33,8 +33,6 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
virtual CPT(RenderState) munge_state_impl(const RenderState *state);
|
virtual CPT(RenderState) munge_state_impl(const RenderState *state);
|
||||||
|
|
||||||
typedef WeakKeyHashMap<RenderState, WCPT(RenderState) > StateMap;
|
|
||||||
StateMap _state_map;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static TypeHandle get_class_type() {
|
static TypeHandle get_class_type() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user