diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index 408931d1cc..b29341c06d 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -1932,19 +1932,16 @@ close_gsg() { _closing_gsg = true; free_pointers(); - // If we're not sharing the prepared objects list with any other - // GSG, go ahead and release all the textures and geoms now. This - // isn't really a reliable test of whether we are sharing this list, - // but it's not too important if we get this wrong since this ought - // to be an optional cleanup anyway. (Presumably, the underlying - // graphics API will properly clean up outstanding textures and - // geoms when the last context using them is released.) - if (_prepared_objects->get_ref_count() == 1) { - release_all_textures(); - release_all_geoms(); - release_all_vertex_buffers(); - release_all_index_buffers(); - } + // As tempting as it may be to try to release all the textures and + // geoms now, we can't, because we might not be the currently-active + // GSG (this is particularly important in OpenGL, which maintains + // one currently-active GL state in each thread). If we start + // deleting textures, we'll be inadvertently deleting textures from + // some other OpenGL state. + + // Fortunately, it doesn't really matter, since the graphics API + // will be responsible for cleaning up anything we don't clean up + // explicitly. We'll just let them drop. } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/gobj/bufferContext.I b/panda/src/gobj/bufferContext.I index 16439a6b0f..374257ba8d 100644 --- a/panda/src/gobj/bufferContext.I +++ b/panda/src/gobj/bufferContext.I @@ -17,24 +17,6 @@ //////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////// -// Function: BufferContext::Constructor -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -INLINE BufferContext:: -BufferContext(BufferResidencyTracker *residency) : - _residency(residency), - _residency_state(0), - _data_size_bytes(0), - _owning_chain(&residency->_chains[0]) -{ -#ifdef DO_PSTATS - ++(_owning_chain->_count); - insert_before(_owning_chain); -#endif // DO_PSTATS -} - //////////////////////////////////////////////////////////////////// // Function: BufferContext::get_data_size_bytes // Access: Public @@ -110,6 +92,7 @@ set_resident(bool flag) { //////////////////////////////////////////////////////////////////// INLINE BufferContext *BufferContext:: get_next() const { + nassertr(_owning_chain != (BufferContextChain *)NULL, NULL); if ((BufferContextChain *)_next == _owning_chain) { return NULL; } @@ -124,7 +107,9 @@ get_next() const { //////////////////////////////////////////////////////////////////// INLINE void BufferContext:: update_data_size_bytes(size_t new_data_size_bytes) { - _owning_chain->adjust_bytes((int)new_data_size_bytes - (int)_data_size_bytes); + if (_owning_chain != (BufferContextChain *)NULL) { + _owning_chain->adjust_bytes((int)new_data_size_bytes - (int)_data_size_bytes); + } _data_size_bytes = new_data_size_bytes; } @@ -138,21 +123,3 @@ INLINE void BufferContext:: update_modified(UpdateSeq new_modified) { _modified = new_modified; } - -//////////////////////////////////////////////////////////////////// -// Function: BufferContext::set_owning_chain -// Access: Private -// Description: Moves this object to a different BufferContextChain. -//////////////////////////////////////////////////////////////////// -INLINE void BufferContext:: -set_owning_chain(BufferContextChain *chain) { - if (chain != _owning_chain) { - --(_owning_chain->_count); - _owning_chain->adjust_bytes(-(int)_data_size_bytes); - remove_from_list(); - _owning_chain = chain; - ++(_owning_chain->_count); - _owning_chain->adjust_bytes((int)_data_size_bytes); - insert_before(_owning_chain); - } -} diff --git a/panda/src/gobj/bufferContext.cxx b/panda/src/gobj/bufferContext.cxx index 7f53ca0078..62385a9f9d 100644 --- a/panda/src/gobj/bufferContext.cxx +++ b/panda/src/gobj/bufferContext.cxx @@ -20,6 +20,21 @@ TypeHandle BufferContext::_type_handle; +//////////////////////////////////////////////////////////////////// +// Function: BufferContext::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +BufferContext:: +BufferContext(BufferResidencyTracker *residency) : + _residency(residency), + _residency_state(0), + _data_size_bytes(0), + _owning_chain(NULL) +{ + set_owning_chain(&residency->_chains[0]); +} + //////////////////////////////////////////////////////////////////// // Function: BufferContext::Destructor // Access: Public, Virtual @@ -27,10 +42,29 @@ TypeHandle BufferContext::_type_handle; //////////////////////////////////////////////////////////////////// BufferContext:: ~BufferContext() { -#ifdef DO_PSTATS - --(_owning_chain->_count); - _owning_chain->adjust_bytes(-(int)_data_size_bytes); - remove_from_list(); -#endif // DO_PSTATS - _owning_chain = NULL; + set_owning_chain(NULL); +} + +//////////////////////////////////////////////////////////////////// +// Function: BufferContext::set_owning_chain +// Access: Private +// Description: Moves this object to a different BufferContextChain. +//////////////////////////////////////////////////////////////////// +void BufferContext:: +set_owning_chain(BufferContextChain *chain) { + if (chain != _owning_chain) { + if (_owning_chain != (BufferContextChain *)NULL){ + --(_owning_chain->_count); + _owning_chain->adjust_bytes(-(int)_data_size_bytes); + remove_from_list(); + } + + _owning_chain = chain; + + if (_owning_chain != (BufferContextChain *)NULL) { + ++(_owning_chain->_count); + _owning_chain->adjust_bytes((int)_data_size_bytes); + insert_before(_owning_chain); + } + } } diff --git a/panda/src/gobj/bufferContext.h b/panda/src/gobj/bufferContext.h index b239b40a74..6d0085bc88 100644 --- a/panda/src/gobj/bufferContext.h +++ b/panda/src/gobj/bufferContext.h @@ -44,7 +44,7 @@ class PreparedGraphicsObjects; //////////////////////////////////////////////////////////////////// class EXPCL_PANDA BufferContext : public SavedContext, private LinkedListNode { public: - INLINE BufferContext(BufferResidencyTracker *residency); + BufferContext(BufferResidencyTracker *residency); virtual ~BufferContext(); INLINE size_t get_data_size_bytes() const; @@ -59,7 +59,7 @@ public: INLINE void update_modified(UpdateSeq new_modified); private: - INLINE void set_owning_chain(BufferContextChain *chain); + void set_owning_chain(BufferContextChain *chain); private: BufferResidencyTracker *_residency; diff --git a/panda/src/gobj/bufferContextChain.cxx b/panda/src/gobj/bufferContextChain.cxx index db987bf2eb..6150f35848 100755 --- a/panda/src/gobj/bufferContextChain.cxx +++ b/panda/src/gobj/bufferContextChain.cxx @@ -54,6 +54,7 @@ take_from(BufferContextChain &other) { LinkedListNode *llnode = other._next; while (llnode != &other) { + nassertv(((BufferContext *)llnode)->_owning_chain == &other); ((BufferContext *)llnode)->_owning_chain = this; llnode = ((BufferContext *)llnode)->_next; } diff --git a/panda/src/gobj/preparedGraphicsObjects.cxx b/panda/src/gobj/preparedGraphicsObjects.cxx index e86a19ecff..d0663c45fd 100644 --- a/panda/src/gobj/preparedGraphicsObjects.cxx +++ b/panda/src/gobj/preparedGraphicsObjects.cxx @@ -56,7 +56,6 @@ PreparedGraphicsObjects:: // If this is so, then all of the GSG's that own them have already // destructed, so we can assume their resources were internally // cleaned up. Quietly erase these remaining objects. - ReMutexHolder holder(_lock); Textures::iterator tci; @@ -65,6 +64,7 @@ PreparedGraphicsObjects:: ++tci) { TextureContext *tc = (*tci); tc->get_texture()->clear_prepared(this); + tc->set_owning_chain(NULL); } _prepared_textures.clear(); @@ -101,6 +101,7 @@ PreparedGraphicsObjects:: ++vbci) { VertexBufferContext *vbc = (*vbci); vbc->_data->clear_prepared(this); + vbc->set_owning_chain(NULL); } _prepared_vertex_buffers.clear(); @@ -113,6 +114,7 @@ PreparedGraphicsObjects:: ++ibci) { IndexBufferContext *ibc = (*ibci); ibc->_data->clear_prepared(this); + ibc->set_owning_chain(NULL); } _prepared_index_buffers.clear(); @@ -840,17 +842,13 @@ begin_frame(GraphicsStateGuardianBase *gsg, Thread *current_thread) { // First, release all the textures, geoms, and buffers awaiting // release. if (!_released_textures.empty()) { - cerr << "releasing " << _released_textures.size() - << " textures, gsg = " << gsg << "\n"; Textures::iterator tci; for (tci = _released_textures.begin(); tci != _released_textures.end(); ++tci) { TextureContext *tc = (*tci); - cerr << "releasing texture " << tc << ": " << tc->_texture << "\n"; gsg->release_texture(tc); } - cerr << "done releasing textures\n"; } _released_textures.clear();