diff options
Diffstat (limited to '')
-rw-r--r-- | linden/indra/llmath/llvolumemgr.cpp | 132 |
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 | |||
41 | const F32 BASE_THRESHOLD = 0.03f; | 38 | const F32 BASE_THRESHOLD = 0.03f; |
42 | 39 | ||
43 | //static | 40 | //static |
@@ -70,11 +67,6 @@ LLVolumeMgr::~LLVolumeMgr() | |||
70 | 67 | ||
71 | BOOL LLVolumeMgr::cleanup() | 68 | BOOL 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 |
108 | LLVolume *LLVolumeMgr::getVolume(const LLVolumeParams &volume_params, const S32 detail) | 100 | // anything holding the volume and the LODGroup are destroyed |
101 | LLVolume* 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 | 144 | void LLVolumeMgr::unrefVolume(LLVolume *volumep) |
158 | void 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 |
205 | S32 LLVolumeMgr::getTotalRefCount() const | 185 | void 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 | |||
217 | S32 LLVolumeMgr::getGroupCount() const | ||
218 | { | 186 | { |
219 | return mVolumeLODGroups.size(); | 187 | mVolumeLODGroups[volgroup->getVolumeParams()] = volgroup; |
220 | } | 188 | } |
221 | #endif | ||
222 | 189 | ||
223 | // protected | 190 | // protected |
224 | LLVolumeLODGroup* LLVolumeMgr::createNewGroup(const LLVolumeParams& volume_params) | 191 | LLVolumeLODGroup* 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 | ||
293 | LLVolumeLODGroup::LLVolumeLODGroup(const LLVolumeParams ¶ms) | 258 | LLVolumeLODGroup::LLVolumeLODGroup(const LLVolumeParams ¶ms) |
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 | ||
308 | S32 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 | ||
320 | LLVolumeLODGroup::~LLVolumeLODGroup() | 269 | LLVolumeLODGroup::~LLVolumeLODGroup() |
321 | { | 270 | { |
322 | destroy(); | ||
323 | } | ||
324 | |||
325 | // protected | ||
326 | void 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 | ||
335 | LLVolume * LLVolumeLODGroup::getLOD(const S32 detail) | 277 | LLVolume* 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 | ||
348 | BOOL LLVolumeLODGroup::derefLOD(LLVolume *volumep) | 292 | BOOL 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() | |||
428 | std::ostream& operator<<(std::ostream& s, const LLVolumeLODGroup& volgroup) | 376 | std::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; |