From 0bd34f9f4b84942be7e3b3d84a858b05557464cf Mon Sep 17 00:00:00 2001 From: David Rose Date: Tue, 10 May 2005 22:43:44 +0000 Subject: [PATCH] runtime improvements --- dtool/Config.pp | 2 +- panda/src/display/graphicsStateGuardian.cxx | 42 ++++- panda/src/display/graphicsStateGuardian.h | 3 +- panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx | 4 +- panda/src/dxgsg8/dxGraphicsStateGuardian8.h | 2 +- panda/src/express/pointerTo.I | 20 +++ panda/src/express/pointerTo.h | 2 + panda/src/express/pointerToBase.I | 35 ++-- panda/src/express/pointerToBase.h | 6 +- panda/src/express/pointerToVoid.I | 151 ------------------ panda/src/express/pointerToVoid.h | 18 --- panda/src/express/referenceCount.I | 57 ++----- panda/src/express/referenceCount.cxx | 28 ++++ panda/src/express/referenceCount.h | 5 +- .../glstuff/glGraphicsStateGuardian_src.cxx | 4 +- .../src/glstuff/glGraphicsStateGuardian_src.h | 2 +- panda/src/pgraph/cullResult.I | 19 --- panda/src/pgraph/cullResult.cxx | 4 +- panda/src/pgraph/cullResult.h | 4 - panda/src/pgraph/renderState.cxx | 1 + panda/src/pgraph/renderState.h | 14 ++ .../putil/cachedTypedWritableReferenceCount.I | 57 +------ .../cachedTypedWritableReferenceCount.cxx | 27 ++++ .../putil/cachedTypedWritableReferenceCount.h | 5 +- panda/src/putil/nodeCachedReferenceCount.I | 57 +------ panda/src/putil/nodeCachedReferenceCount.cxx | 26 +++ panda/src/putil/nodeCachedReferenceCount.h | 5 +- panda/src/putil/nodePointerTo.I | 20 +++ panda/src/putil/nodePointerTo.h | 6 +- 29 files changed, 257 insertions(+), 369 deletions(-) diff --git a/dtool/Config.pp b/dtool/Config.pp index 560eacf7f1..beeb99a667 100644 --- a/dtool/Config.pp +++ b/dtool/Config.pp @@ -289,7 +289,7 @@ // to help track memory leaks, and also report total memory usage on // PStats. There is some small overhead for having this ability // available, even if it is unused. -#defer DO_MEMORY_USAGE $[<= $[OPTIMIZE], 3] +#defer DO_MEMORY_USAGE $[<= $[OPTIMIZE], 2] // Do you want to compile in support for pipelining? This enables // setting and accessing multiple different copies of frame-specific diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index e53144e92a..704106ca08 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -371,12 +371,52 @@ release_index_buffer(IndexBufferContext *) { //////////////////////////////////////////////////////////////////// // Function: GraphicsStateGuardian::get_geom_munger +// Access: Public +// Description: Looks up or creates a GeomMunger object to munge +// vertices appropriate to this GSG for the indicated +// state. +//////////////////////////////////////////////////////////////////// +PT(qpGeomMunger) GraphicsStateGuardian:: +get_geom_munger(const RenderState *state) { + // Before we even look up the map, see if the _last_mi value points + // to this GSG. This is likely because we tend to visit the same + // state multiple times during a frame. Also, this might well be + // the only GSG in the world anyway. + if (!state->_mungers.empty()) { + RenderState::Mungers::const_iterator mi = state->_last_mi; + if ((*mi).first == this && !(*mi).first.was_deleted()) { + return (*mi).second; + } + } + + // Nope, we have to loop up in the map. + RenderState::Mungers::const_iterator mi = state->_mungers.find(this); + if (mi != state->_mungers.end() && !(*mi).first.was_deleted()) { + ((RenderState *)state)->_last_mi = mi; + return (*mi).second; + } + + // Nothing in the map; create a new entry. + PT(qpGeomMunger) munger = make_geom_munger(state); + + // Cast the RenderState to a non-const object. We can do this + // because we are only updating a cache within the RenderState, not + // really changing any of its properties. + RenderState *nc_state = (RenderState *)state; + mi = nc_state->_mungers.insert(RenderState::Mungers::value_type(this, munger)).first; + nc_state->_last_mi = mi; + + return munger; +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsStateGuardian::make_geom_munger // Access: Public, Virtual // Description: Creates a new GeomMunger object to munge vertices // appropriate to this GSG for the indicated state. //////////////////////////////////////////////////////////////////// PT(qpGeomMunger) GraphicsStateGuardian:: -get_geom_munger(const RenderState *state) { +make_geom_munger(const RenderState *state) { // The default implementation returns no munger at all, but // presumably, every kind of GSG needs some special munging action, // so real GSG's will override this to return something more diff --git a/panda/src/display/graphicsStateGuardian.h b/panda/src/display/graphicsStateGuardian.h index ea254768b2..5c1c6f0086 100644 --- a/panda/src/display/graphicsStateGuardian.h +++ b/panda/src/display/graphicsStateGuardian.h @@ -122,7 +122,8 @@ public: virtual IndexBufferContext *prepare_index_buffer(qpGeomPrimitive *data); virtual void release_index_buffer(IndexBufferContext *ibc); - virtual PT(qpGeomMunger) get_geom_munger(const RenderState *state); + PT(qpGeomMunger) get_geom_munger(const RenderState *state); + virtual PT(qpGeomMunger) make_geom_munger(const RenderState *state); virtual void set_state_and_transform(const RenderState *state, const TransformState *transform); diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx index 4fb9333f43..acdaf5302b 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx @@ -3550,13 +3550,13 @@ release_index_buffer(IndexBufferContext *ibc) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian8::get_geom_munger +// Function: DXGraphicsStateGuardian8::make_geom_munger // Access: Public, Virtual // Description: Creates a new GeomMunger object to munge vertices // appropriate to this GSG for the indicated state. //////////////////////////////////////////////////////////////////// PT(qpGeomMunger) DXGraphicsStateGuardian8:: -get_geom_munger(const RenderState *state) { +make_geom_munger(const RenderState *state) { PT(DXGeomMunger8) munger = new DXGeomMunger8(this, state); return qpGeomMunger::register_munger(munger); } diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h index 453d1b887f..8079681c68 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h @@ -115,7 +115,7 @@ public: void apply_index_buffer(IndexBufferContext *ibc); virtual void release_index_buffer(IndexBufferContext *ibc); - virtual PT(qpGeomMunger) get_geom_munger(const RenderState *state); + virtual PT(qpGeomMunger) make_geom_munger(const RenderState *state); virtual void framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr, const RenderBuffer &rb); diff --git a/panda/src/express/pointerTo.I b/panda/src/express/pointerTo.I index 4db9dfeff8..edc1739146 100644 --- a/panda/src/express/pointerTo.I +++ b/panda/src/express/pointerTo.I @@ -39,6 +39,16 @@ PointerTo(const PointerTo ©) : { } +//////////////////////////////////////////////////////////////////// +// Function: PointerTo::Destructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +template +INLINE PointerTo:: +~PointerTo() { +} + //////////////////////////////////////////////////////////////////// // Function: PointerTo::Dereference operator // Access: Public @@ -138,6 +148,16 @@ ConstPointerTo(const PointerTo ©) : { } +//////////////////////////////////////////////////////////////////// +// Function: ConstPointerTo::Destructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +template +INLINE ConstPointerTo:: +~ConstPointerTo() { +} + //////////////////////////////////////////////////////////////////// // Function: ConstPointerTo::Copy Constructor // Access: Public diff --git a/panda/src/express/pointerTo.h b/panda/src/express/pointerTo.h index ac260c9dae..f7e2db2a57 100644 --- a/panda/src/express/pointerTo.h +++ b/panda/src/express/pointerTo.h @@ -85,6 +85,7 @@ public: PUBLISHED: INLINE PointerTo(To *ptr = (To *)NULL); INLINE PointerTo(const PointerTo ©); + INLINE ~PointerTo(); public: INLINE To &operator *() const; @@ -142,6 +143,7 @@ PUBLISHED: INLINE ConstPointerTo(const To *ptr = (const To *)NULL); INLINE ConstPointerTo(const PointerTo ©); INLINE ConstPointerTo(const ConstPointerTo ©); + INLINE ~ConstPointerTo(); public: INLINE const To &operator *() const; diff --git a/panda/src/express/pointerToBase.I b/panda/src/express/pointerToBase.I index b66f8a816a..ac624614ba 100644 --- a/panda/src/express/pointerToBase.I +++ b/panda/src/express/pointerToBase.I @@ -58,7 +58,7 @@ INLINE PointerToBase:: // reference count and increment the new one. //////////////////////////////////////////////////////////////////// template -void PointerToBase:: +INLINE void PointerToBase:: reassign(To *ptr) { if (ptr != (To *)_void_ptr) { // First save the old pointer; we won't delete it until we have @@ -73,16 +73,7 @@ reassign(To *ptr) { ptr->ref(); #ifdef DO_MEMORY_USAGE if (MemoryUsage::get_track_memory_usage()) { - // Make sure the MemoryUsage record knows what the TypeHandle - // is, if we know it ourselves. - TypeHandle type = get_type_handle(To); - if (type == TypeHandle::none()) { - do_init_type(To); - type = get_type_handle(To); - } - if (type != TypeHandle::none()) { - MemoryUsage::update_type(ptr, type); - } + update_type(ptr); } #endif } @@ -105,6 +96,28 @@ reassign(const PointerToBase ©) { reassign((To *)copy._void_ptr); } +#ifdef DO_MEMORY_USAGE +//////////////////////////////////////////////////////////////////// +// Function: PointerToBase::update_type +// Access: Protected +// Description: Ensures that the MemoryUsage record for the pointer +// has the right type of object, if we know the type +// ourselves. +//////////////////////////////////////////////////////////////////// +template +void PointerToBase:: +update_type(To *ptr) { + TypeHandle type = get_type_handle(To); + if (type == TypeHandle::none()) { + do_init_type(To); + type = get_type_handle(To); + } + if (type != TypeHandle::none()) { + MemoryUsage::update_type(ptr, type); + } +} +#endif // DO_MEMORY_USAGE + //////////////////////////////////////////////////////////////////// // Function: PointerToBase::clear diff --git a/panda/src/express/pointerToBase.h b/panda/src/express/pointerToBase.h index 854d1afac2..400c1dbbb0 100644 --- a/panda/src/express/pointerToBase.h +++ b/panda/src/express/pointerToBase.h @@ -42,9 +42,13 @@ protected: INLINE PointerToBase(const PointerToBase ©); INLINE ~PointerToBase(); - void reassign(To *ptr); + INLINE void reassign(To *ptr); INLINE void reassign(const PointerToBase ©); +#ifdef DO_MEMORY_USAGE + void update_type(To *ptr); +#endif // DO_MEMORY_USAGE + // No assignment or retrieval functions are declared in // PointerToBase, because we will have to specialize on const // vs. non-const later. diff --git a/panda/src/express/pointerToVoid.I b/panda/src/express/pointerToVoid.I index a81dcfaf45..9ec2fb0663 100644 --- a/panda/src/express/pointerToVoid.I +++ b/panda/src/express/pointerToVoid.I @@ -59,157 +59,6 @@ get_hash() const { return (size_t)_void_ptr; } -#if 0 -//////////////////////////////////////////////////////////////////// -// Function: PointerToVoid::Equivalence operator -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE bool PointerToVoid:: -operator == (const void *other) const { - return _void_ptr == other; -} - -//////////////////////////////////////////////////////////////////// -// Function: PointerToVoid::Nonequivalence operator -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE bool PointerToVoid:: -operator != (const void *other) const { - return _void_ptr != other; -} - -//////////////////////////////////////////////////////////////////// -// Function: PointerToVoid::Greater-than operator -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE bool PointerToVoid:: -operator > (const void *other) const { - return _void_ptr > other; -} - -//////////////////////////////////////////////////////////////////// -// Function: PointerToVoid::Less-than-or-equal operator -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE bool PointerToVoid:: -operator <= (const void *other) const { - return _void_ptr <= other; -} - -//////////////////////////////////////////////////////////////////// -// Function: PointerToVoid::Greater-than-or-equal operator -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE bool PointerToVoid:: -operator >= (const void *other) const { - return _void_ptr >= other; -} -//////////////////////////////////////////////////////////////////// -// Function: PointerToVoid::Equivalence operator -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE bool PointerToVoid:: -operator == (void *other) const { - return _void_ptr == other; -} - -//////////////////////////////////////////////////////////////////// -// Function: PointerToVoid::Nonequivalence operator -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE bool PointerToVoid:: -operator != (void *other) const { - return _void_ptr != other; -} - -//////////////////////////////////////////////////////////////////// -// Function: PointerToVoid::Greater-than operator -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE bool PointerToVoid:: -operator > (void *other) const { - return _void_ptr > other; -} - -//////////////////////////////////////////////////////////////////// -// Function: PointerToVoid::Less-than-or-equal operator -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE bool PointerToVoid:: -operator <= (void *other) const { - return _void_ptr <= other; -} - -//////////////////////////////////////////////////////////////////// -// Function: PointerToVoid::Greater-than-or-equal operator -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE bool PointerToVoid:: -operator >= (void *other) const { - return _void_ptr >= other; -} - -//////////////////////////////////////////////////////////////////// -// Function: PointerToVoid::Equivalence operator -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE bool PointerToVoid:: -operator == (const PointerToVoid &other) const { - return _void_ptr == other._void_ptr; -} - -//////////////////////////////////////////////////////////////////// -// Function: PointerToVoid::Nonequivalence operator -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE bool PointerToVoid:: -operator != (const PointerToVoid &other) const { - return _void_ptr != other._void_ptr; -} - -//////////////////////////////////////////////////////////////////// -// Function: PointerToVoid::Greater-than operator -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE bool PointerToVoid:: -operator > (const PointerToVoid &other) const { - return _void_ptr > other._void_ptr; -} - -//////////////////////////////////////////////////////////////////// -// Function: PointerToVoid::Less-than-or-equal operator -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE bool PointerToVoid:: -operator <= (const PointerToVoid &other) const { - return _void_ptr <= other._void_ptr; -} - -//////////////////////////////////////////////////////////////////// -// Function: PointerToVoid::Greater-than-or-equal operator -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE bool PointerToVoid:: -operator >= (const PointerToVoid &other) const { - return _void_ptr >= other._void_ptr; -} -#endif // WIN32_VC - //////////////////////////////////////////////////////////////////// // Function: PointerToVoid::Less-than operator // Access: Public diff --git a/panda/src/express/pointerToVoid.h b/panda/src/express/pointerToVoid.h index 9399657471..907feceed4 100644 --- a/panda/src/express/pointerToVoid.h +++ b/panda/src/express/pointerToVoid.h @@ -45,24 +45,6 @@ PUBLISHED: public: // These comparison functions are common to all things PointerTo, so // they're defined up here. -#if 0 - INLINE bool operator == (const void *other) const; - INLINE bool operator != (const void *other) const; - INLINE bool operator > (const void *other) const; - INLINE bool operator <= (const void *other) const; - INLINE bool operator >= (const void *other) const; - INLINE bool operator == (void *other) const; - INLINE bool operator != (void *other) const; - INLINE bool operator > (void *other) const; - INLINE bool operator <= (void *other) const; - INLINE bool operator >= (void *other) const; - - INLINE bool operator == (const PointerToVoid &other) const; - INLINE bool operator != (const PointerToVoid &other) const; - INLINE bool operator > (const PointerToVoid &other) const; - INLINE bool operator <= (const PointerToVoid &other) const; - INLINE bool operator >= (const PointerToVoid &other) const; -#endif // WIN32_VC INLINE bool operator < (const void *other) const; INLINE bool operator < (const PointerToVoid &other) const; diff --git a/panda/src/express/referenceCount.I b/panda/src/express/referenceCount.I index 54637f92b2..577e239520 100644 --- a/panda/src/express/referenceCount.I +++ b/panda/src/express/referenceCount.I @@ -188,21 +188,7 @@ get_ref_count() const { //////////////////////////////////////////////////////////////////// INLINE int ReferenceCount:: ref() const { - nassertr(this != NULL, 0); - - // If this assertion fails, we're trying to delete an object that - // was just deleted. Possibly you used a real pointer instead of a - // PointerTo at some point, and the object was deleted when the - // PointerTo went out of scope. Maybe you tried to create an - // automatic (local variable) instance of a class that derives from - // ReferenceCount. Or maybe your headers are out of sync, and you - // need to make clean in direct or some higher tree. - nassertr(_ref_count != deleted_ref_count, 0); - - // If this assertion fails, the reference counts are all screwed - // up altogether. Maybe some errant code stomped all over memory - // somewhere. - nassertr(_ref_count >= 0, 0); + nassertr(test_ref_count_integrity(), 0); return AtomicAdjust::inc(((ReferenceCount *)this)->_ref_count); } @@ -234,26 +220,12 @@ ref() const { //////////////////////////////////////////////////////////////////// INLINE int ReferenceCount:: unref() const { - nassertr(this != NULL, false); - - // If this assertion fails, we're trying to delete an object that - // was just deleted. Possibly you used a real pointer instead of a - // PointerTo at some point, and the object was deleted when the - // PointerTo went out of scope. Maybe you tried to create an - // automatic (local variable) instance of a class that derives from - // ReferenceCount. Or maybe your headers are out of sync, and you - // need to make clean in direct or some higher tree. - nassertr(_ref_count != deleted_ref_count, false); - - // If this assertion fails, the reference counts are all screwed - // up altogether. Maybe some errant code stomped all over memory - // somewhere. - nassertr(_ref_count >= 0, false); + nassertr(test_ref_count_integrity(), 0); // If this assertion fails, you tried to unref an object with a // zero reference count. Are you using ref() and unref() // directly? Are you sure you can't use PointerTo's? - nassertr(_ref_count > 0, false); + nassertr(_ref_count > 0, 0); return AtomicAdjust::dec(((ReferenceCount *)this)->_ref_count); } @@ -262,26 +234,15 @@ unref() const { // Function: ReferenceCount::test_ref_count_integrity // Access: Published // Description: Does some easy checks to make sure that the reference -// count isn't completely bogus. +// count isn't completely bogus. Returns true if ok, +// false otherwise. //////////////////////////////////////////////////////////////////// -INLINE void ReferenceCount:: +INLINE bool ReferenceCount:: test_ref_count_integrity() const { #ifndef NDEBUG - nassertv(this != NULL); - - // If this assertion fails, we're trying to delete an object that - // was just deleted. Possibly you used a real pointer instead of a - // PointerTo at some point, and the object was deleted when the - // PointerTo went out of scope. Maybe you tried to create an - // automatic (local variable) instance of a class that derives from - // ReferenceCount. Or maybe your headers are out of sync, and you - // need to make clean in direct or some higher tree. - nassertv(_ref_count != deleted_ref_count); - - // If this assertion fails, the reference counts are all screwed - // up altogether. Maybe some errant code stomped all over memory - // somewhere. - nassertv(_ref_count >= 0); + return do_test_ref_count_integrity(); +#else + return true; #endif } diff --git a/panda/src/express/referenceCount.cxx b/panda/src/express/referenceCount.cxx index a3c0c6422f..c36512eace 100644 --- a/panda/src/express/referenceCount.cxx +++ b/panda/src/express/referenceCount.cxx @@ -20,3 +20,31 @@ #include "referenceCount.h" TypeHandle ReferenceCount::_type_handle; + +//////////////////////////////////////////////////////////////////// +// Function: ReferenceCount::do_test_ref_count_integrity +// Access: Protected +// Description: Does some easy checks to make sure that the reference +// count isn't completely bogus. Returns true if ok, +// false otherwise. +//////////////////////////////////////////////////////////////////// +bool ReferenceCount:: +do_test_ref_count_integrity() const { + nassertr(this != NULL, false); + + // If this assertion fails, we're trying to delete an object that + // was just deleted. Possibly you used a real pointer instead of a + // PointerTo at some point, and the object was deleted when the + // PointerTo went out of scope. Maybe you tried to create an + // automatic (local variable) instance of a class that derives from + // ReferenceCount. Or maybe your headers are out of sync, and you + // need to make clean in direct or some higher tree. + nassertr(_ref_count != deleted_ref_count, false); + + // If this assertion fails, the reference counts are all screwed + // up altogether. Maybe some errant code stomped all over memory + // somewhere. + nassertr(_ref_count >= 0, false); + + return true; +} diff --git a/panda/src/express/referenceCount.h b/panda/src/express/referenceCount.h index e1d22e25e9..ac1813bacc 100644 --- a/panda/src/express/referenceCount.h +++ b/panda/src/express/referenceCount.h @@ -51,7 +51,7 @@ PUBLISHED: INLINE int ref() const; INLINE int unref() const; - INLINE void test_ref_count_integrity() const; + INLINE bool test_ref_count_integrity() const; public: INLINE void local_object(); @@ -61,6 +61,9 @@ public: INLINE void weak_ref(WeakPointerToVoid *ptv); INLINE void weak_unref(WeakPointerToVoid *ptv); +protected: + bool do_test_ref_count_integrity() const; + private: enum { // We use this value as a flag to indicate an object has been diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 33fa4725f9..d9cec26835 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -3210,13 +3210,13 @@ setup_primitive(const qpGeomPrimitive *data) { } //////////////////////////////////////////////////////////////////// -// Function: GLGraphicsStateGuardian::get_geom_munger +// Function: GLGraphicsStateGuardian::make_geom_munger // Access: Public, Virtual // Description: Creates a new GeomMunger object to munge vertices // appropriate to this GSG for the indicated state. //////////////////////////////////////////////////////////////////// PT(qpGeomMunger) CLP(GraphicsStateGuardian):: -get_geom_munger(const RenderState *state) { +make_geom_munger(const RenderState *state) { PT(CLP(GeomMunger)) munger = new CLP(GeomMunger)(this, state); return qpGeomMunger::register_munger(munger); } diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index 3374aa4129..e83507b634 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -123,7 +123,7 @@ public: virtual void release_index_buffer(IndexBufferContext *ibc); const unsigned char *setup_primitive(const qpGeomPrimitive *data); - virtual PT(qpGeomMunger) get_geom_munger(const RenderState *state); + virtual PT(qpGeomMunger) make_geom_munger(const RenderState *state); virtual void framebuffer_copy_to_texture (Texture *tex, int z, const DisplayRegion *dr, const RenderBuffer &rb); diff --git a/panda/src/pgraph/cullResult.I b/panda/src/pgraph/cullResult.I index dcd8ba9508..bdb93ebc6c 100644 --- a/panda/src/pgraph/cullResult.I +++ b/panda/src/pgraph/cullResult.I @@ -54,22 +54,3 @@ get_bin(int bin_index) { } return make_new_bin(bin_index); } - -//////////////////////////////////////////////////////////////////// -// Function: CullResult::get_geom_munger -// Access: Private -// Description: Returns a suitable GeomMunger for the indicated -// state. This will ask the GSG to create a new munger -// if we haven't already created one for this state; -// otherwise, it will return the existing one. -//////////////////////////////////////////////////////////////////// -INLINE PT(qpGeomMunger) CullResult:: -get_geom_munger(const RenderState *state) { - Mungers::iterator mi = _mungers.find(state); - if (mi != _mungers.end()) { - return (*mi).second; - } - PT(qpGeomMunger) munger = _gsg->get_geom_munger(state); - _mungers.insert(Mungers::value_type(state, munger)); - return munger; -} diff --git a/panda/src/pgraph/cullResult.cxx b/panda/src/pgraph/cullResult.cxx index df12f13be5..21a0c5c714 100644 --- a/panda/src/pgraph/cullResult.cxx +++ b/panda/src/pgraph/cullResult.cxx @@ -129,7 +129,7 @@ add_object(CullableObject *object, const CullTraverser *traverser) { get_dual_transparent_state(); transparent_part->_state = state->compose(transparent_state); transparent_part->munge_geom - (_gsg, get_geom_munger(transparent_part->_state), + (_gsg, _gsg->get_geom_munger(transparent_part->_state), traverser); CullBin *bin = get_bin(transparent_part->_state->get_bin_index()); nassertv(bin != (CullBin *)NULL); @@ -157,7 +157,7 @@ add_object(CullableObject *object, const CullTraverser *traverser) { // Munge vertices as needed for the GSG's requirements, and the // object's current state. - object->munge_geom(_gsg, get_geom_munger(object->_state), traverser); + object->munge_geom(_gsg, _gsg->get_geom_munger(object->_state), traverser); CullBin *bin = get_bin(object->_state->get_bin_index()); nassertv(bin != (CullBin *)NULL); diff --git a/panda/src/pgraph/cullResult.h b/panda/src/pgraph/cullResult.h index bbab24e9bb..3c778b1077 100644 --- a/panda/src/pgraph/cullResult.h +++ b/panda/src/pgraph/cullResult.h @@ -66,7 +66,6 @@ public: private: CullBin *make_new_bin(int bin_index); - INLINE PT(qpGeomMunger) get_geom_munger(const RenderState *state); static CPT(RenderState) get_binary_state(); static CPT(RenderState) get_dual_transparent_state(); @@ -75,9 +74,6 @@ private: GraphicsStateGuardianBase *_gsg; - typedef pmap Mungers; - Mungers _mungers; - typedef pvector< PT(CullBin) > Bins; Bins _bins; }; diff --git a/panda/src/pgraph/renderState.cxx b/panda/src/pgraph/renderState.cxx index 5470f8959f..f4013a1946 100644 --- a/panda/src/pgraph/renderState.cxx +++ b/panda/src/pgraph/renderState.cxx @@ -65,6 +65,7 @@ RenderState() { } _saved_entry = _states->end(); _flags = 0; + _last_mi = _mungers.end(); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/pgraph/renderState.h b/panda/src/pgraph/renderState.h index b6ea75c7de..aa0452d29d 100644 --- a/panda/src/pgraph/renderState.h +++ b/panda/src/pgraph/renderState.h @@ -30,6 +30,8 @@ #include "renderModeAttrib.h" #include "texGenAttrib.h" #include "texMatrixAttrib.h" +#include "qpgeomMunger.h" +#include "weakPointerTo.h" class GraphicsStateGuardianBase; class FogAttrib; @@ -215,6 +217,16 @@ private: CompositionCache _composition_cache; CompositionCache _invert_composition_cache; + // This is here to provide a quick cache of GSG + RenderState -> + // GeomMunger for the cull phase. It is here because it is faster + // to look up the GSG 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 + // GraphicsStateGuardian::get_geom_munger(). + typedef pmap Mungers; + Mungers _mungers; + Mungers::const_iterator _last_mi; + // This is used to mark nodes as we visit them to detect cycles. UpdateSeq _cycle_detect; static UpdateSeq _last_cycle_detect; @@ -305,6 +317,8 @@ public: private: static TypeHandle _type_handle; + + friend class GraphicsStateGuardian; }; INLINE ostream &operator << (ostream &out, const RenderState &state) { diff --git a/panda/src/putil/cachedTypedWritableReferenceCount.I b/panda/src/putil/cachedTypedWritableReferenceCount.I index fe650eb839..7547b06134 100644 --- a/panda/src/putil/cachedTypedWritableReferenceCount.I +++ b/panda/src/putil/cachedTypedWritableReferenceCount.I @@ -157,21 +157,7 @@ get_cache_ref_count() const { //////////////////////////////////////////////////////////////////// INLINE int CachedTypedWritableReferenceCount:: cache_ref() const { - nassertr(this != NULL, 0); - - // If this assertion fails, we're trying to delete an object that - // was just deleted. Possibly you used a real pointer instead of a - // PointerTo at some point, and the object was deleted when the - // PointerTo went out of scope. Maybe you tried to create an - // automatic (local variable) instance of a class that derives from - // ReferenceCount. Or maybe your headers are out of sync, and you - // need to make clean in direct or some higher tree. - nassertr(_cache_ref_count != -100, 0); - - // If this assertion fails, the reference counts are all screwed - // up altogether. Maybe some errant code stomped all over memory - // somewhere. - nassertr(_cache_ref_count >= 0, 0); + nassertr(test_ref_count_integrity(), 0); ref(); return AtomicAdjust::inc(((CachedTypedWritableReferenceCount *)this)->_cache_ref_count); @@ -204,58 +190,29 @@ cache_ref() const { //////////////////////////////////////////////////////////////////// INLINE int CachedTypedWritableReferenceCount:: cache_unref() const { - nassertr(this != NULL, false); - - // If this assertion fails, we're trying to delete an object that - // was just deleted. Possibly you used a real pointer instead of a - // PointerTo at some point, and the object was deleted when the - // PointerTo went out of scope. Maybe you tried to create an - // automatic (local variable) instance of a class that derives from - // ReferenceCount. Or maybe your headers are out of sync, and you - // need to make clean in direct or some higher tree. - nassertr(_cache_ref_count != -100, false); - - // If this assertion fails, the reference counts are all screwed - // up altogether. Maybe some errant code stomped all over memory - // somewhere. - nassertr(_cache_ref_count >= 0, false); + nassertr(test_ref_count_integrity(), 0); // If this assertion fails, you tried to unref an object with a // zero reference count. Are you using ref() and unref() // directly? Are you sure you can't use PointerTo's? - nassertr(_cache_ref_count > 0, false); + nassertr(_cache_ref_count > 0, 0); unref(); return AtomicAdjust::dec(((CachedTypedWritableReferenceCount *)this)->_cache_ref_count); } - //////////////////////////////////////////////////////////////////// // Function: CachedTypedWritableReferenceCount::test_ref_count_integrity // Access: Published // Description: Does some easy checks to make sure that the reference // count isn't completely bogus. //////////////////////////////////////////////////////////////////// -INLINE void CachedTypedWritableReferenceCount:: +INLINE bool CachedTypedWritableReferenceCount:: test_ref_count_integrity() const { #ifndef NDEBUG - nassertv(this != NULL); - - // If this assertion fails, we're trying to delete an object that - // was just deleted. Possibly you used a real pointer instead of a - // PointerTo at some point, and the object was deleted when the - // PointerTo went out of scope. Maybe you tried to create an - // automatic (local variable) instance of a class that derives from - // ReferenceCount. Or maybe your headers are out of sync, and you - // need to make clean in direct or some higher tree. - nassertv(_cache_ref_count != -100); - - // If this assertion fails, the reference counts are all screwed - // up altogether. Maybe some errant code stomped all over memory - // somewhere. - nassertv(_cache_ref_count >= 0); - - TypedWritableReferenceCount::test_ref_count_integrity(); + return do_test_ref_count_integrity(); +#else + return true; #endif } diff --git a/panda/src/putil/cachedTypedWritableReferenceCount.cxx b/panda/src/putil/cachedTypedWritableReferenceCount.cxx index 2672f3fe84..3cea5905df 100644 --- a/panda/src/putil/cachedTypedWritableReferenceCount.cxx +++ b/panda/src/putil/cachedTypedWritableReferenceCount.cxx @@ -19,3 +19,30 @@ #include "cachedTypedWritableReferenceCount.h" TypeHandle CachedTypedWritableReferenceCount::_type_handle; + +//////////////////////////////////////////////////////////////////// +// Function: CachedTypedWritableReferenceCount::do_test_ref_count_integrity +// Access: Protected +// Description: Does some easy checks to make sure that the reference +// count isn't completely bogus. +//////////////////////////////////////////////////////////////////// +bool CachedTypedWritableReferenceCount:: +do_test_ref_count_integrity() const { + nassertr(this != NULL, false); + + // If this assertion fails, we're trying to delete an object that + // was just deleted. Possibly you used a real pointer instead of a + // PointerTo at some point, and the object was deleted when the + // PointerTo went out of scope. Maybe you tried to create an + // automatic (local variable) instance of a class that derives from + // ReferenceCount. Or maybe your headers are out of sync, and you + // need to make clean in direct or some higher tree. + nassertr(_cache_ref_count != -100, false); + + // If this assertion fails, the reference counts are all screwed + // up altogether. Maybe some errant code stomped all over memory + // somewhere. + nassertr(_cache_ref_count >= 0, false); + + return TypedWritableReferenceCount::do_test_ref_count_integrity(); +} diff --git a/panda/src/putil/cachedTypedWritableReferenceCount.h b/panda/src/putil/cachedTypedWritableReferenceCount.h index f2c87a6e9d..f72eafc9e8 100644 --- a/panda/src/putil/cachedTypedWritableReferenceCount.h +++ b/panda/src/putil/cachedTypedWritableReferenceCount.h @@ -52,7 +52,10 @@ PUBLISHED: INLINE int get_cache_ref_count() const; INLINE int cache_ref() const; INLINE int cache_unref() const; - INLINE void test_ref_count_integrity() const; + INLINE bool test_ref_count_integrity() const; + +protected: + bool do_test_ref_count_integrity() const; private: int _cache_ref_count; diff --git a/panda/src/putil/nodeCachedReferenceCount.I b/panda/src/putil/nodeCachedReferenceCount.I index 55763dde86..59b577eb59 100644 --- a/panda/src/putil/nodeCachedReferenceCount.I +++ b/panda/src/putil/nodeCachedReferenceCount.I @@ -157,21 +157,7 @@ get_node_ref_count() const { //////////////////////////////////////////////////////////////////// INLINE int NodeCachedReferenceCount:: node_ref() const { - nassertr(this != NULL, 0); - - // If this assertion fails, we're trying to delete an object that - // was just deleted. Possibly you used a real pointer instead of a - // PointerTo at some point, and the object was deleted when the - // PointerTo went out of scope. Maybe you tried to create an - // automatic (local variable) instance of a class that derives from - // ReferenceCount. Or maybe your headers are out of sync, and you - // need to make clean in direct or some higher tree. - nassertr(_node_ref_count != -100, 0); - - // If this assertion fails, the reference counts are all screwed - // up altogether. Maybe some errant code stomped all over memory - // somewhere. - nassertr(_node_ref_count >= 0, 0); + nassertr(test_ref_count_integrity(), 0); ref(); return AtomicAdjust::inc(((NodeCachedReferenceCount *)this)->_node_ref_count); @@ -204,58 +190,29 @@ node_ref() const { //////////////////////////////////////////////////////////////////// INLINE int NodeCachedReferenceCount:: node_unref() const { - nassertr(this != NULL, false); - - // If this assertion fails, we're trying to delete an object that - // was just deleted. Possibly you used a real pointer instead of a - // PointerTo at some point, and the object was deleted when the - // PointerTo went out of scope. Maybe you tried to create an - // automatic (local variable) instance of a class that derives from - // ReferenceCount. Or maybe your headers are out of sync, and you - // need to make clean in direct or some higher tree. - nassertr(_node_ref_count != -100, false); - - // If this assertion fails, the reference counts are all screwed - // up altogether. Maybe some errant code stomped all over memory - // somewhere. - nassertr(_node_ref_count >= 0, false); + nassertr(test_ref_count_integrity(), 0); // If this assertion fails, you tried to unref an object with a // zero reference count. Are you using ref() and unref() // directly? Are you sure you can't use PointerTo's? - nassertr(_node_ref_count > 0, false); + nassertr(_node_ref_count > 0, 0); unref(); return AtomicAdjust::dec(((NodeCachedReferenceCount *)this)->_node_ref_count); } - //////////////////////////////////////////////////////////////////// // Function: NodeCachedReferenceCount::test_ref_count_integrity // Access: Published // Description: Does some easy checks to make sure that the reference // count isn't completely bogus. //////////////////////////////////////////////////////////////////// -INLINE void NodeCachedReferenceCount:: +INLINE bool NodeCachedReferenceCount:: test_ref_count_integrity() const { #ifndef NDEBUG - nassertv(this != NULL); - - // If this assertion fails, we're trying to delete an object that - // was just deleted. Possibly you used a real pointer instead of a - // PointerTo at some point, and the object was deleted when the - // PointerTo went out of scope. Maybe you tried to create an - // automatic (local variable) instance of a class that derives from - // ReferenceCount. Or maybe your headers are out of sync, and you - // need to make clean in direct or some higher tree. - nassertv(_node_ref_count != -100); - - // If this assertion fails, the reference counts are all screwed - // up altogether. Maybe some errant code stomped all over memory - // somewhere. - nassertv(_node_ref_count >= 0); - - CachedTypedWritableReferenceCount::test_ref_count_integrity(); + return do_test_ref_count_integrity(); +#else + return true; #endif } diff --git a/panda/src/putil/nodeCachedReferenceCount.cxx b/panda/src/putil/nodeCachedReferenceCount.cxx index b8f3f4be45..27ab277738 100644 --- a/panda/src/putil/nodeCachedReferenceCount.cxx +++ b/panda/src/putil/nodeCachedReferenceCount.cxx @@ -20,3 +20,29 @@ TypeHandle NodeCachedReferenceCount::_type_handle; +//////////////////////////////////////////////////////////////////// +// Function: NodeCachedReferenceCount::do_test_ref_count_integrity +// Access: Protected +// Description: Does some easy checks to make sure that the reference +// count isn't completely bogus. +//////////////////////////////////////////////////////////////////// +bool NodeCachedReferenceCount:: +do_test_ref_count_integrity() const { + nassertr(this != NULL, false); + + // If this assertion fails, we're trying to delete an object that + // was just deleted. Possibly you used a real pointer instead of a + // PointerTo at some point, and the object was deleted when the + // PointerTo went out of scope. Maybe you tried to create an + // automatic (local variable) instance of a class that derives from + // ReferenceCount. Or maybe your headers are out of sync, and you + // need to make clean in direct or some higher tree. + nassertr(_node_ref_count != -100, false); + + // If this assertion fails, the reference counts are all screwed + // up altogether. Maybe some errant code stomped all over memory + // somewhere. + nassertr(_node_ref_count >= 0, false); + + return CachedTypedWritableReferenceCount::do_test_ref_count_integrity(); +} diff --git a/panda/src/putil/nodeCachedReferenceCount.h b/panda/src/putil/nodeCachedReferenceCount.h index 76aeeb1473..c925b88216 100644 --- a/panda/src/putil/nodeCachedReferenceCount.h +++ b/panda/src/putil/nodeCachedReferenceCount.h @@ -59,7 +59,7 @@ PUBLISHED: INLINE int get_node_ref_count() const; INLINE int node_ref() const; INLINE int node_unref() const; - INLINE void test_ref_count_integrity() const; + INLINE bool test_ref_count_integrity() const; enum Referenced { R_node = 0x001, @@ -67,6 +67,9 @@ PUBLISHED: }; INLINE int get_referenced_bits() const; + +protected: + bool do_test_ref_count_integrity() const; private: int _node_ref_count; diff --git a/panda/src/putil/nodePointerTo.I b/panda/src/putil/nodePointerTo.I index b8c1d360ed..da103e59f2 100644 --- a/panda/src/putil/nodePointerTo.I +++ b/panda/src/putil/nodePointerTo.I @@ -39,6 +39,16 @@ NodePointerTo(const NodePointerTo ©) : { } +//////////////////////////////////////////////////////////////////// +// Function: NodePointerTo::Destructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +template +INLINE NodePointerTo:: +~NodePointerTo() { +} + //////////////////////////////////////////////////////////////////// // Function: NodePointerTo::Dereference operator // Access: Public @@ -150,6 +160,16 @@ NodeConstPointerTo(const NodeConstPointerTo ©) : { } +//////////////////////////////////////////////////////////////////// +// Function: NodeConstPointerTo::Destructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +template +INLINE NodeConstPointerTo:: +~NodeConstPointerTo() { +} + //////////////////////////////////////////////////////////////////// // Function: NodeConstPointerTo::Dereference operator // Access: Public diff --git a/panda/src/putil/nodePointerTo.h b/panda/src/putil/nodePointerTo.h index 1a09856a5e..aa1e7fb4d3 100644 --- a/panda/src/putil/nodePointerTo.h +++ b/panda/src/putil/nodePointerTo.h @@ -24,9 +24,7 @@ //////////////////////////////////////////////////////////////////// // Class : NodePointerTo -// Description : - -// This implements the special NodePointerTo template +// Description : This implements the special NodePointerTo template // class, which works just like PointerTo except it // manages the objects node_ref_count instead of the // normal ref_count. @@ -37,6 +35,7 @@ public: typedef TYPENAME NodePointerToBase::To To; INLINE NodePointerTo(To *ptr = (To *)NULL); INLINE NodePointerTo(const NodePointerTo ©); + INLINE ~NodePointerTo(); INLINE To &operator *() const; INLINE To *operator -> () const; @@ -61,6 +60,7 @@ public: INLINE NodeConstPointerTo(const To *ptr = (const To *)NULL); INLINE NodeConstPointerTo(const NodePointerTo ©); INLINE NodeConstPointerTo(const NodeConstPointerTo ©); + INLINE ~NodeConstPointerTo(); INLINE const To &operator *() const; INLINE const To *operator -> () const;