diff options
author | Xiaohong Bao <bao@lindenlab.com> | 2013-06-13 18:47:51 -0600 |
---|---|---|
committer | Xiaohong Bao <bao@lindenlab.com> | 2013-06-13 18:47:51 -0600 |
commit | fc88265cffe3553803314c6e895a1e3a3c988171 (patch) | |
tree | 8e5113ddd5c8d7a2a2f0a8132e710515bd2678b0 | |
parent | db2abd49c3b41af612cbb6fed4c1626c37b4e14b (diff) |
fix for SH-4241: viewer crash shortly after login in LLViewerRegion::addNewObject and
SH-4261: interesting: crash in LLViewerRegion::addToVOCacheTree
-rwxr-xr-x | indra/newview/lldrawable.cpp | 2 | ||||
-rwxr-xr-x | indra/newview/llviewerobjectlist.cpp | 3 | ||||
-rwxr-xr-x | indra/newview/llviewerregion.cpp | 90 | ||||
-rwxr-xr-x | indra/newview/llviewerregion.h | 2 | ||||
-rwxr-xr-x | indra/newview/llvocache.cpp | 3 |
5 files changed, 69 insertions, 31 deletions
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 598b0d2ff4..22a7c350d6 100755 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -135,7 +135,7 @@ void LLDrawable::init(bool new_entry) getRegion()->addActiveCacheEntry(vo_entry); - llassert_always(!vo_entry->getGroup()); //not in the object cache octree. + llassert(!vo_entry->getGroup()); //not in the object cache octree. } llassert(!vo_entry || vo_entry->getEntry() == mEntry); diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index 83ebfc2ec3..ea004560d2 100755 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -340,7 +340,8 @@ LLViewerObject* LLViewerObjectList::processObjectUpdateFromCache(LLVOCacheEntry* } else { - return objectp; //already loaded. + //should fall through if already loaded because may need to update the object. + //return objectp; //already loaded. } } diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 29528a1117..a2fd440895 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -797,21 +797,25 @@ void LLViewerRegion::dirtyHeights() } } -void LLViewerRegion::replaceCacheEntry(LLVOCacheEntry* old_entry, LLVOCacheEntry* new_entry) +void LLViewerRegion::replaceVisibleCacheEntry(LLVOCacheEntry* old_entry, LLVOCacheEntry* new_entry) { - U32 state = LLVOCacheEntry::INACTIVE; - bool in_vo_tree = false; - - if(old_entry) - { - old_entry->moveTo(new_entry); - state = old_entry->getState(); - in_vo_tree = (state == LLVOCacheEntry::INACTIVE && old_entry->getGroup() != NULL); - killCacheEntry(old_entry); - } - - mImpl->mCacheMap[new_entry->getLocalID()] = new_entry; + //save old entry + old_entry->moveTo(new_entry); + U32 state = old_entry->getState(); + U32 old_parent_id = old_entry->getParentID(); + //kill old entry + killCacheEntry(old_entry); + + //parse new entry + U32 new_parent_id = 0; + LLViewerObject::unpackParentID(new_entry->getDP(), new_parent_id); + + //store new entry + mImpl->mCacheMap[new_entry->getLocalID()] = new_entry; + + //process entry state + new_entry->setState(state); if(state == LLVOCacheEntry::ACTIVE) { llassert(new_entry->getEntry()->hasDrawable()); @@ -821,11 +825,16 @@ void LLViewerRegion::replaceCacheEntry(LLVOCacheEntry* old_entry, LLVOCacheEntry { mImpl->mWaitingSet.insert(new_entry); } - else if(!old_entry || in_vo_tree) + + //process parent info + if(!old_parent_id && new_parent_id > 0) //becomes a child { - addToVOCacheTree(new_entry); + new_entry->clearChildrenList(); } - new_entry->setState(state); + new_entry->setParentID(new_parent_id); + + //update the object + gObjectList.processObjectUpdateFromCache(new_entry, this); } //physically delete the cache entry @@ -901,14 +910,17 @@ void LLViewerRegion::removeActiveCacheEntry(LLVOCacheEntry* entry, LLDrawable* d return; } - if(drawablep->getParent()) //child object + if(entry->getParentID() > 0) //is a child { - LLViewerOctreeEntry* parent_oct_entry = drawablep->getParent()->getEntry(); - if(parent_oct_entry && parent_oct_entry->hasVOCacheEntry()) + LLVOCacheEntry* parent = getCacheEntry(entry->getParentID()); + if(parent) { - LLVOCacheEntry* parent = (LLVOCacheEntry*)parent_oct_entry->getVOCacheEntry(); parent->addChild(entry); } + else //parent is not in the cache, put into the orphan list. + { + mOrphanMap[entry->getParentID()].push_back(entry->getLocalID()); + } } else //insert to vo cache tree. { @@ -953,8 +965,12 @@ void LLViewerRegion::addToVOCacheTree(LLVOCacheEntry* entry) { return; } - - llassert_always(!entry->getParentID() && !entry->getEntry()->hasDrawable()); + if(entry->getParentID() > 0) + { + return; //no child prim in cache octree. + } + + llassert(!entry->getEntry()->hasDrawable()); mImpl->mVOCachePartition->addEntry(entry->getEntry()); } @@ -1264,7 +1280,12 @@ LLViewerObject* LLViewerRegion::addNewObject(LLVOCacheEntry* entry) } else { - llerrs << "Object is already created." << llendl; + //should not hit here any more, but does not hurt either, just put it back to active list + addActiveCacheEntry(entry); + + //object is already created, crash here for debug use. + llwarns << "Object is already created." << llendl; + llassert(!entry->getEntry()->hasDrawable()); } return obj; } @@ -1774,6 +1795,23 @@ void LLViewerRegion::decodeBoundingInfo(LLVOCacheEntry* entry) if(entry != NULL && !entry->getEntry()) { entry->setOctreeEntry(NULL); + + if(entry->getEntry()->hasDrawable()) //already in the rendering pipeline + { + addActiveCacheEntry(entry); + + //set parent id + U32 parent_id = 0; + LLViewerObject::unpackParentID(entry->getDP(), parent_id); + if(parent_id > 0) + { + entry->setParentID(parent_id); + } + + //update the object + gObjectList.processObjectUpdateFromCache(entry, this); + return; //done + } } else if(entry->getGroup() != NULL) { @@ -1805,8 +1843,8 @@ void LLViewerRegion::decodeBoundingInfo(LLVOCacheEntry* entry) } else { - mOrphanMap[parent_id].push_back(entry->getLocalID()); - } + mOrphanMap[parent_id].push_back(entry->getLocalID()); + } } else //parent in cache { @@ -1885,7 +1923,7 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLDataPackerB //if visible, update it if(!entry->isState(LLVOCacheEntry::INACTIVE)) { - replaceCacheEntry(entry, new_entry); + replaceVisibleCacheEntry(entry, new_entry); } else //invisible { diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index f3c4c080c1..78a6c782a9 100755 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -367,7 +367,7 @@ private: LLViewerObject* addNewObject(LLVOCacheEntry* entry); void killObject(LLVOCacheEntry* entry, std::vector<LLDrawable*>& delete_list); void removeFromVOCacheTree(LLVOCacheEntry* entry); - void replaceCacheEntry(LLVOCacheEntry* old_entry, LLVOCacheEntry* new_entry); + void replaceVisibleCacheEntry(LLVOCacheEntry* old_entry, LLVOCacheEntry* new_entry); void killCacheEntry(LLVOCacheEntry* entry); //physically delete the cache entry F32 killInvisibleObjects(F32 max_time); diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index 1f3af78e77..9816fb9af0 100755 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -102,8 +102,7 @@ LLVOCacheEntry::LLVOCacheEntry(LLAPRFile* apr_file) BOOL success; mDP.assignBuffer(mBuffer, 0); - setOctreeEntry(NULL); - + success = check_read(apr_file, &mLocalID, sizeof(U32)); if(success) { |