diff options
Diffstat (limited to 'indra/llmath/llvolumemgr.cpp')
-rw-r--r-- | indra/llmath/llvolumemgr.cpp | 148 |
1 files changed, 58 insertions, 90 deletions
diff --git a/indra/llmath/llvolumemgr.cpp b/indra/llmath/llvolumemgr.cpp index f3a6b7d157..23ed0183b8 100644 --- a/indra/llmath/llvolumemgr.cpp +++ b/indra/llmath/llvolumemgr.cpp @@ -31,13 +31,10 @@ #include "linden_common.h" #include "llvolumemgr.h" +#include "llmemtype.h" #include "llvolume.h" -//#define DEBUG_VOLUME - -//LLVolumeMgr* gVolumeMgr = 0; - const F32 BASE_THRESHOLD = 0.03f; //static @@ -70,11 +67,6 @@ LLVolumeMgr::~LLVolumeMgr() BOOL LLVolumeMgr::cleanup() { - #ifdef DEBUG_VOLUME - { - lldebugs << "LLVolumeMgr::cleanup()" << llendl; - } - #endif BOOL no_refs = TRUE; if (mDataMutex) { @@ -85,14 +77,11 @@ BOOL LLVolumeMgr::cleanup() iter != end; iter++) { LLVolumeLODGroup *volgroupp = iter->second; - if (volgroupp->getNumRefs() != 1) + if (volgroupp->cleanupRefs() == false) { - llwarns << "Volume group " << volgroupp << " has " - << volgroupp->getNumRefs() << " remaining refs" << llendl; - llwarns << volgroupp->getParams() << llendl; no_refs = FALSE; } - volgroupp->unref();// this ); + delete volgroupp; } mVolumeLODGroups.clear(); if (mDataMutex) @@ -102,10 +91,11 @@ BOOL LLVolumeMgr::cleanup() return no_refs; } -// whatever calls getVolume() never owns the LLVolume* and -// cannot keep references for long since it may be deleted -// later. For best results hold it in an LLPointer<LLVolume>. -LLVolume *LLVolumeMgr::getVolume(const LLVolumeParams &volume_params, const S32 detail) +// Always only ever store the results of refVolume in a LLPointer +// Note however that LLVolumeLODGroup that contains the volume +// also holds a LLPointer so the volume will only go away after +// anything holding the volume and the LODGroup are destroyed +LLVolume* LLVolumeMgr::refVolume(const LLVolumeParams &volume_params, const S32 detail) { LLVolumeLODGroup* volgroupp; if (mDataMutex) @@ -121,17 +111,11 @@ LLVolume *LLVolumeMgr::getVolume(const LLVolumeParams &volume_params, const S32 { volgroupp = iter->second; } - volgroupp->ref(); if (mDataMutex) { mDataMutex->unlock(); } - #ifdef DEBUG_VOLUME - { - lldebugs << "LLVolumeMgr::getVolume() " << (*this) << llendl; - } - #endif - return volgroupp->getLOD(detail); + return volgroupp->getLODVolume(detail); } // virtual @@ -154,15 +138,14 @@ LLVolumeLODGroup* LLVolumeMgr::getGroup( const LLVolumeParams& volume_params ) c return volgroupp; } -// virtual -void LLVolumeMgr::cleanupVolume(LLVolume *volumep) +void LLVolumeMgr::unrefVolume(LLVolume *volumep) { if (volumep->isUnique()) { // TomY: Don't need to manage this volume. It is a unique instance. return; } - LLVolumeParams* params = (LLVolumeParams*) &(volumep->getParams()); + const LLVolumeParams* params = &(volumep->getParams()); if (mDataMutex) { mDataMutex->lock(); @@ -182,11 +165,10 @@ void LLVolumeMgr::cleanupVolume(LLVolume *volumep) LLVolumeLODGroup* volgroupp = iter->second; volgroupp->derefLOD(volumep); - volgroupp->unref();// this ); - if (volgroupp->getNumRefs() == 1) + if (volgroupp->getNumRefs() == 0) { mVolumeLODGroups.erase(params); - volgroupp->unref();// this ); + delete volgroupp; } } if (mDataMutex) @@ -194,40 +176,21 @@ void LLVolumeMgr::cleanupVolume(LLVolume *volumep) mDataMutex->unlock(); } - #ifdef DEBUG_VOLUME - { - lldebugs << "LLVolumeMgr::cleanupVolume() " << (*this) << llendl; - } - #endif -} - -#ifdef DEBUG_VOLUME -S32 LLVolumeMgr::getTotalRefCount() const -{ - S32 total_ref_count = 0; - for ( volume_lod_group_map_t::const_iterator iter = mVolumeLODGroups.begin(), - end = mVolumeLODGroups.end(); - iter != end; iter++) - { - total_ref_count += iter->second->getTotalVolumeRefCount(); - } - return total_ref_count; } -S32 LLVolumeMgr::getGroupCount() const +// protected +void LLVolumeMgr::insertGroup(LLVolumeLODGroup* volgroup) { - return mVolumeLODGroups.size(); + mVolumeLODGroups[volgroup->getVolumeParams()] = volgroup; } -#endif // protected LLVolumeLODGroup* LLVolumeMgr::createNewGroup(const LLVolumeParams& volume_params) { - LLVolumeLODGroup* group = new LLVolumeLODGroup(volume_params); - const LLVolumeParams* params = &(group->getParams()); - mVolumeLODGroups[params] = group; - group->ref(); // initial reference - return group; + LLMemType m1(LLMemType::MTYPE_VOLUME); + LLVolumeLODGroup* volgroup = new LLVolumeLODGroup(volume_params); + insertGroup(volgroup); + return volgroup; } // virtual @@ -272,9 +235,8 @@ std::ostream& operator<<(std::ostream& s, const LLVolumeMgr& volume_mgr) volume_mgr.mDataMutex->lock(); } - LLVolumeMgr::volume_lod_group_map_iter iter = volume_mgr.mVolumeLODGroups.begin(); - LLVolumeMgr::volume_lod_group_map_iter end = volume_mgr.mVolumeLODGroups.end(); - for ( ; iter != end; ++iter) + for (LLVolumeMgr::volume_lod_group_map_t::const_iterator iter = volume_mgr.mVolumeLODGroups.begin(); + iter != volume_mgr.mVolumeLODGroups.end(); ++iter) { LLVolumeLODGroup *volgroupp = iter->second; total_refs += volgroupp->getNumRefs(); @@ -291,72 +253,78 @@ std::ostream& operator<<(std::ostream& s, const LLVolumeMgr& volume_mgr) } LLVolumeLODGroup::LLVolumeLODGroup(const LLVolumeParams ¶ms) + : mVolumeParams(params), + mRefs(0) { - S32 i; - mParams = params; - - for (i = 0; i < NUM_LODS; i++) + for (S32 i = 0; i < NUM_LODS; i++) { mLODRefs[i] = 0; - // no need to initialize mVolumeLODs, they are smart pointers - //mVolumeLODs[i] = NULL; mAccessCount[i] = 0; } } -#ifdef DEBUG_VOLUME -S32 LLVolumeLODGroup::getTotalVolumeRefCount() const +LLVolumeLODGroup::~LLVolumeLODGroup() { - S32 total_ref_count = 0; for (S32 i = 0; i < NUM_LODS; i++) { - total_ref_count += mLODRefs[i]; + llassert_always(mLODRefs[i] == 0); } - return total_ref_count; -} -#endif - -// protected -LLVolumeLODGroup::~LLVolumeLODGroup() -{ - destroy(); } -// protected -void LLVolumeLODGroup::destroy() +// Called from LLVolumeMgr::cleanup +bool LLVolumeLODGroup::cleanupRefs() { - for (S32 i = 0; i < NUM_LODS; i++) + bool res = true; + if (mRefs != 0) { - // remember that mVolumeLODs are smart pointers! - mVolumeLODs[i] = NULL; + llwarns << "Volume group has remaining refs:" << getNumRefs() << llendl; + mRefs = 0; + for (S32 i = 0; i < NUM_LODS; i++) + { + if (mLODRefs[i] > 0) + { + llwarns << " LOD " << i << " refs = " << mLODRefs[i] << llendl; + mLODRefs[i] = 0; + mVolumeLODs[i] = NULL; + } + } + llwarns << *getVolumeParams() << llendl; + res = false; } + return res; } -LLVolume * LLVolumeLODGroup::getLOD(const S32 detail) +LLVolume* LLVolumeLODGroup::getLODVolume(const S32 detail) { llassert(detail >=0 && detail < NUM_LODS); mAccessCount[detail]++; - if (!mLODRefs[detail]) + mRefs++; + if (mVolumeLODs[detail].isNull()) { - mVolumeLODs[detail] = new LLVolume(mParams, mDetailScales[detail]); + LLMemType m1(LLMemType::MTYPE_VOLUME); + mVolumeLODs[detail] = new LLVolume(mVolumeParams, mDetailScales[detail]); } mLODRefs[detail]++; - return mVolumeLODs[detail].get(); + return mVolumeLODs[detail]; } BOOL LLVolumeLODGroup::derefLOD(LLVolume *volumep) { - S32 i; - for (i = 0; i < NUM_LODS; i++) + llassert_always(mRefs > 0); + mRefs--; + for (S32 i = 0; i < NUM_LODS; i++) { if (mVolumeLODs[i] == volumep) { + llassert_always(mLODRefs[i] > 0); mLODRefs[i]--; +#if 1 // SJB: Possible opt: keep other lods around if (!mLODRefs[i]) { mVolumeLODs[i] = NULL; } +#endif return TRUE; } } @@ -428,7 +396,7 @@ F32 LLVolumeLODGroup::dump() std::ostream& operator<<(std::ostream& s, const LLVolumeLODGroup& volgroup) { s << "{ numRefs=" << volgroup.getNumRefs(); - s << ", mParams=" << volgroup.mParams; + s << ", mParams=" << volgroup.getVolumeParams(); s << " }"; return s; |