aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llmath/llvolumemgr.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/indra/llmath/llvolumemgr.cpp132
1 files changed, 40 insertions, 92 deletions
diff --git a/linden/indra/llmath/llvolumemgr.cpp b/linden/indra/llmath/llvolumemgr.cpp
index d9bca70..0b49bb3 100644
--- a/linden/indra/llmath/llvolumemgr.cpp
+++ b/linden/indra/llmath/llvolumemgr.cpp
@@ -31,13 +31,10 @@
31#include "linden_common.h" 31#include "linden_common.h"
32 32
33#include "llvolumemgr.h" 33#include "llvolumemgr.h"
34#include "llmemtype.h"
34#include "llvolume.h" 35#include "llvolume.h"
35 36
36 37
37//#define DEBUG_VOLUME
38
39//LLVolumeMgr* gVolumeMgr = 0;
40
41const F32 BASE_THRESHOLD = 0.03f; 38const F32 BASE_THRESHOLD = 0.03f;
42 39
43//static 40//static
@@ -70,11 +67,6 @@ LLVolumeMgr::~LLVolumeMgr()
70 67
71BOOL LLVolumeMgr::cleanup() 68BOOL LLVolumeMgr::cleanup()
72{ 69{
73 #ifdef DEBUG_VOLUME
74 {
75 lldebugs << "LLVolumeMgr::cleanup()" << llendl;
76 }
77 #endif
78 BOOL no_refs = TRUE; 70 BOOL no_refs = TRUE;
79 if (mDataMutex) 71 if (mDataMutex)
80 { 72 {
@@ -85,14 +77,14 @@ BOOL LLVolumeMgr::cleanup()
85 iter != end; iter++) 77 iter != end; iter++)
86 { 78 {
87 LLVolumeLODGroup *volgroupp = iter->second; 79 LLVolumeLODGroup *volgroupp = iter->second;
88 if (volgroupp->getNumRefs() != 1) 80 if (volgroupp->getNumRefs() != 0)
89 { 81 {
90 llwarns << "Volume group " << volgroupp << " has " 82 llwarns << "Volume group " << volgroupp << " has "
91 << volgroupp->getNumRefs() << " remaining refs" << llendl; 83 << volgroupp->getNumRefs() << " remaining refs" << llendl;
92 llwarns << volgroupp->getParams() << llendl; 84 llwarns << *volgroupp->getVolumeParams() << llendl;
93 no_refs = FALSE; 85 no_refs = FALSE;
94 } 86 }
95 volgroupp->unref();// this ); 87 delete volgroupp;
96 } 88 }
97 mVolumeLODGroups.clear(); 89 mVolumeLODGroups.clear();
98 if (mDataMutex) 90 if (mDataMutex)
@@ -102,10 +94,11 @@ BOOL LLVolumeMgr::cleanup()
102 return no_refs; 94 return no_refs;
103} 95}
104 96
105// whatever calls getVolume() never owns the LLVolume* and 97// Always only ever store the results of refVolume in a LLPointer
106// cannot keep references for long since it may be deleted 98// Note however that LLVolumeLODGroup that contains the volume
107// later. For best results hold it in an LLPointer<LLVolume>. 99// also holds a LLPointer so the volume will only go away after
108LLVolume *LLVolumeMgr::getVolume(const LLVolumeParams &volume_params, const S32 detail) 100// anything holding the volume and the LODGroup are destroyed
101LLVolume* LLVolumeMgr::refVolume(const LLVolumeParams &volume_params, const S32 detail)
109{ 102{
110 LLVolumeLODGroup* volgroupp; 103 LLVolumeLODGroup* volgroupp;
111 if (mDataMutex) 104 if (mDataMutex)
@@ -121,17 +114,11 @@ LLVolume *LLVolumeMgr::getVolume(const LLVolumeParams &volume_params, const S32
121 { 114 {
122 volgroupp = iter->second; 115 volgroupp = iter->second;
123 } 116 }
124 volgroupp->ref();
125 if (mDataMutex) 117 if (mDataMutex)
126 { 118 {
127 mDataMutex->unlock(); 119 mDataMutex->unlock();
128 } 120 }
129 #ifdef DEBUG_VOLUME 121 return volgroupp->getLODVolume(detail);
130 {
131 lldebugs << "LLVolumeMgr::getVolume() " << (*this) << llendl;
132 }
133 #endif
134 return volgroupp->getLOD(detail);
135} 122}
136 123
137// virtual 124// virtual
@@ -154,15 +141,14 @@ LLVolumeLODGroup* LLVolumeMgr::getGroup( const LLVolumeParams& volume_params ) c
154 return volgroupp; 141 return volgroupp;
155} 142}
156 143
157// virtual 144void LLVolumeMgr::unrefVolume(LLVolume *volumep)
158void LLVolumeMgr::cleanupVolume(LLVolume *volumep)
159{ 145{
160 if (volumep->isUnique()) 146 if (volumep->isUnique())
161 { 147 {
162 // TomY: Don't need to manage this volume. It is a unique instance. 148 // TomY: Don't need to manage this volume. It is a unique instance.
163 return; 149 return;
164 } 150 }
165 LLVolumeParams* params = (LLVolumeParams*) &(volumep->getParams()); 151 const LLVolumeParams* params = &(volumep->getParams());
166 if (mDataMutex) 152 if (mDataMutex)
167 { 153 {
168 mDataMutex->lock(); 154 mDataMutex->lock();
@@ -182,11 +168,10 @@ void LLVolumeMgr::cleanupVolume(LLVolume *volumep)
182 LLVolumeLODGroup* volgroupp = iter->second; 168 LLVolumeLODGroup* volgroupp = iter->second;
183 169
184 volgroupp->derefLOD(volumep); 170 volgroupp->derefLOD(volumep);
185 volgroupp->unref();// this ); 171 if (volgroupp->getNumRefs() == 0)
186 if (volgroupp->getNumRefs() == 1)
187 { 172 {
188 mVolumeLODGroups.erase(params); 173 mVolumeLODGroups.erase(params);
189 volgroupp->unref();// this ); 174 delete volgroupp;
190 } 175 }
191 } 176 }
192 if (mDataMutex) 177 if (mDataMutex)
@@ -194,40 +179,21 @@ void LLVolumeMgr::cleanupVolume(LLVolume *volumep)
194 mDataMutex->unlock(); 179 mDataMutex->unlock();
195 } 180 }
196 181
197 #ifdef DEBUG_VOLUME
198 {
199 lldebugs << "LLVolumeMgr::cleanupVolume() " << (*this) << llendl;
200 }
201 #endif
202} 182}
203 183
204#ifdef DEBUG_VOLUME 184// protected
205S32 LLVolumeMgr::getTotalRefCount() const 185void LLVolumeMgr::insertGroup(LLVolumeLODGroup* volgroup)
206{
207 S32 total_ref_count = 0;
208 for ( volume_lod_group_map_t::const_iterator iter = mVolumeLODGroups.begin(),
209 end = mVolumeLODGroups.end();
210 iter != end; iter++)
211 {
212 total_ref_count += iter->second->getTotalVolumeRefCount();
213 }
214 return total_ref_count;
215}
216
217S32 LLVolumeMgr::getGroupCount() const
218{ 186{
219 return mVolumeLODGroups.size(); 187 mVolumeLODGroups[volgroup->getVolumeParams()] = volgroup;
220} 188}
221#endif
222 189
223// protected 190// protected
224LLVolumeLODGroup* LLVolumeMgr::createNewGroup(const LLVolumeParams& volume_params) 191LLVolumeLODGroup* LLVolumeMgr::createNewGroup(const LLVolumeParams& volume_params)
225{ 192{
226 LLVolumeLODGroup* group = new LLVolumeLODGroup(volume_params); 193 LLMemType m1(LLMemType::MTYPE_VOLUME);
227 const LLVolumeParams* params = &(group->getParams()); 194 LLVolumeLODGroup* volgroup = new LLVolumeLODGroup(volume_params);
228 mVolumeLODGroups[params] = group; 195 insertGroup(volgroup);
229 group->ref(); // initial reference 196 return volgroup;
230 return group;
231} 197}
232 198
233// virtual 199// virtual
@@ -272,9 +238,8 @@ std::ostream& operator<<(std::ostream& s, const LLVolumeMgr& volume_mgr)
272 volume_mgr.mDataMutex->lock(); 238 volume_mgr.mDataMutex->lock();
273 } 239 }
274 240
275 LLVolumeMgr::volume_lod_group_map_iter iter = volume_mgr.mVolumeLODGroups.begin(); 241 for (LLVolumeMgr::volume_lod_group_map_t::const_iterator iter = volume_mgr.mVolumeLODGroups.begin();
276 LLVolumeMgr::volume_lod_group_map_iter end = volume_mgr.mVolumeLODGroups.end(); 242 iter != volume_mgr.mVolumeLODGroups.end(); ++iter)
277 for ( ; iter != end; ++iter)
278 { 243 {
279 LLVolumeLODGroup *volgroupp = iter->second; 244 LLVolumeLODGroup *volgroupp = iter->second;
280 total_refs += volgroupp->getNumRefs(); 245 total_refs += volgroupp->getNumRefs();
@@ -291,72 +256,55 @@ std::ostream& operator<<(std::ostream& s, const LLVolumeMgr& volume_mgr)
291} 256}
292 257
293LLVolumeLODGroup::LLVolumeLODGroup(const LLVolumeParams &params) 258LLVolumeLODGroup::LLVolumeLODGroup(const LLVolumeParams &params)
259 : mVolumeParams(params),
260 mRefs(0)
294{ 261{
295 S32 i; 262 for (S32 i = 0; i < NUM_LODS; i++)
296 mParams = params;
297
298 for (i = 0; i < NUM_LODS; i++)
299 { 263 {
300 mLODRefs[i] = 0; 264 mLODRefs[i] = 0;
301 // no need to initialize mVolumeLODs, they are smart pointers
302 //mVolumeLODs[i] = NULL;
303 mAccessCount[i] = 0; 265 mAccessCount[i] = 0;
304 } 266 }
305} 267}
306 268
307#ifdef DEBUG_VOLUME
308S32 LLVolumeLODGroup::getTotalVolumeRefCount() const
309{
310 S32 total_ref_count = 0;
311 for (S32 i = 0; i < NUM_LODS; i++)
312 {
313 total_ref_count += mLODRefs[i];
314 }
315 return total_ref_count;
316}
317#endif
318
319// protected
320LLVolumeLODGroup::~LLVolumeLODGroup() 269LLVolumeLODGroup::~LLVolumeLODGroup()
321{ 270{
322 destroy();
323}
324
325// protected
326void LLVolumeLODGroup::destroy()
327{
328 for (S32 i = 0; i < NUM_LODS; i++) 271 for (S32 i = 0; i < NUM_LODS; i++)
329 { 272 {
330 // remember that mVolumeLODs are smart pointers! 273 llassert_always(mLODRefs[i] == 0);
331 mVolumeLODs[i] = NULL;
332 } 274 }
333} 275}
334 276
335LLVolume * LLVolumeLODGroup::getLOD(const S32 detail) 277LLVolume* LLVolumeLODGroup::getLODVolume(const S32 detail)
336{ 278{
337 llassert(detail >=0 && detail < NUM_LODS); 279 llassert(detail >=0 && detail < NUM_LODS);
338 mAccessCount[detail]++; 280 mAccessCount[detail]++;
339 281
340 if (!mLODRefs[detail]) 282 mRefs++;
283 if (mVolumeLODs[detail].isNull())
341 { 284 {
342 mVolumeLODs[detail] = new LLVolume(mParams, mDetailScales[detail]); 285 LLMemType m1(LLMemType::MTYPE_VOLUME);
286 mVolumeLODs[detail] = new LLVolume(mVolumeParams, mDetailScales[detail]);
343 } 287 }
344 mLODRefs[detail]++; 288 mLODRefs[detail]++;
345 return mVolumeLODs[detail].get(); 289 return mVolumeLODs[detail];
346} 290}
347 291
348BOOL LLVolumeLODGroup::derefLOD(LLVolume *volumep) 292BOOL LLVolumeLODGroup::derefLOD(LLVolume *volumep)
349{ 293{
350 S32 i; 294 llassert_always(mRefs > 0);
351 for (i = 0; i < NUM_LODS; i++) 295 mRefs--;
296 for (S32 i = 0; i < NUM_LODS; i++)
352 { 297 {
353 if (mVolumeLODs[i] == volumep) 298 if (mVolumeLODs[i] == volumep)
354 { 299 {
300 llassert_always(mLODRefs[i] > 0);
355 mLODRefs[i]--; 301 mLODRefs[i]--;
302#if 1 // SJB: Possible opt: keep other lods around
356 if (!mLODRefs[i]) 303 if (!mLODRefs[i])
357 { 304 {
358 mVolumeLODs[i] = NULL; 305 mVolumeLODs[i] = NULL;
359 } 306 }
307#endif
360 return TRUE; 308 return TRUE;
361 } 309 }
362 } 310 }
@@ -428,7 +376,7 @@ F32 LLVolumeLODGroup::dump()
428std::ostream& operator<<(std::ostream& s, const LLVolumeLODGroup& volgroup) 376std::ostream& operator<<(std::ostream& s, const LLVolumeLODGroup& volgroup)
429{ 377{
430 s << "{ numRefs=" << volgroup.getNumRefs(); 378 s << "{ numRefs=" << volgroup.getNumRefs();
431 s << ", mParams=" << volgroup.mParams; 379 s << ", mParams=" << volgroup.getVolumeParams();
432 s << " }"; 380 s << " }";
433 381
434 return s; 382 return s;