summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXiaohong Bao <bao@lindenlab.com>2013-06-13 18:47:51 -0600
committerXiaohong Bao <bao@lindenlab.com>2013-06-13 18:47:51 -0600
commitfc88265cffe3553803314c6e895a1e3a3c988171 (patch)
tree8e5113ddd5c8d7a2a2f0a8132e710515bd2678b0
parentdb2abd49c3b41af612cbb6fed4c1626c37b4e14b (diff)
fix for SH-4241: viewer crash shortly after login in LLViewerRegion::addNewObject and
SH-4261: interesting: crash in LLViewerRegion::addToVOCacheTree
-rwxr-xr-xindra/newview/lldrawable.cpp2
-rwxr-xr-xindra/newview/llviewerobjectlist.cpp3
-rwxr-xr-xindra/newview/llviewerregion.cpp90
-rwxr-xr-xindra/newview/llviewerregion.h2
-rwxr-xr-xindra/newview/llvocache.cpp3
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)
{