summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorXiaohong Bao <bao@lindenlab.com>2013-11-21 11:20:45 -0700
committerXiaohong Bao <bao@lindenlab.com>2013-11-21 11:20:45 -0700
commitc14ecc817895d06b04a803a88d00d4ae1c80060a (patch)
treed360b01bb2ff7065bc2d7608d094bce960e7f16a /indra/newview
parent5979467198e9a8d4c065de908cf48c7d73101cd7 (diff)
fix for SH-4629: Interesting: crash at LLViewerRegion::killObject
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/llvieweroctree.cpp4
-rwxr-xr-xindra/newview/llviewerregion.cpp72
-rwxr-xr-xindra/newview/llviewerregion.h4
3 files changed, 51 insertions, 29 deletions
diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp
index 62d34d12b5..201677b3de 100644
--- a/indra/newview/llvieweroctree.cpp
+++ b/indra/newview/llvieweroctree.cpp
@@ -268,6 +268,10 @@ void LLViewerOctreeEntry::removeData(LLViewerOctreeEntryData* data)
{
return;
}
+ if(mData[data->getDataType()] != data)
+ {
+ return;
+ }
mData[data->getDataType()] = NULL;
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 2eb065c1ef..f1ac4328e4 100755
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -847,7 +847,7 @@ void LLViewerRegion::replaceVisibleCacheEntry(LLVOCacheEntry* old_entry, LLVOCac
}
//physically delete the cache entry
-void LLViewerRegion::killCacheEntry(LLVOCacheEntry* entry)
+void LLViewerRegion::killCacheEntry(LLVOCacheEntry* entry, bool kill_obj)
{
if(!entry)
{
@@ -857,6 +857,14 @@ void LLViewerRegion::killCacheEntry(LLVOCacheEntry* entry)
//remove from active list and waiting list
if(entry->isState(LLVOCacheEntry::ACTIVE))
{
+ if(kill_obj && entry->getEntry())
+ {
+ LLDrawable* drawablep = (LLDrawable*)entry->getEntry()->getDrawable();
+ if(drawablep)
+ {
+ gObjectList.killObject(drawablep->getVObj());
+ }
+ }
mImpl->mActiveSet.erase(entry);
}
else
@@ -887,16 +895,19 @@ void LLViewerRegion::killCacheEntry(LLVOCacheEntry* entry)
entry->removeAllChildren();
}
- entry->setState(LLVOCacheEntry::INACTIVE);
-
+ if(kill_obj)
+ {
+ entry->setState(LLVOCacheEntry::INACTIVE);
+ }
+
//remove from mCacheMap, real deletion
mImpl->mCacheMap.erase(entry->getLocalID());
}
//physically delete the cache entry
-void LLViewerRegion::killCacheEntry(U32 local_id)
+void LLViewerRegion::killCacheEntry(U32 local_id, bool kill_obj)
{
- killCacheEntry(getCacheEntry(local_id));
+ killCacheEntry(getCacheEntry(local_id), kill_obj);
}
U32 LLViewerRegion::getNumOfActiveCachedObjects() const
@@ -1458,6 +1469,7 @@ void LLViewerRegion::killObject(LLVOCacheEntry* entry, std::vector<LLDrawable*>&
//kill the object.
LLDrawable* drawablep = (LLDrawable*)entry->getEntry()->getDrawable();
llassert(drawablep);
+ llassert(drawablep->getRegion() == this);
if(drawablep && !drawablep->getParent())
{
@@ -1509,12 +1521,21 @@ LLViewerObject* LLViewerRegion::addNewObject(LLVOCacheEntry* entry)
}
else
{
+ LLViewerRegion* old_regionp = ((LLDrawable*)entry->getEntry()->getDrawable())->getRegion();
+ if(old_regionp != this)
+ {
+ //this object exists in two regions at the same time;
+ //this case can be safely ignored here because
+ //server should soon send update message to remove one region for this object.
+
+ LL_WARNS() << "Entry: " << entry->getLocalID() << " exists in two regions at the same time." << LL_ENDL;
+ return NULL;
+ }
+
+ LL_WARNS() << "Entry: " << entry->getLocalID() << " in rendering pipeline but not set to be active." << LL_ENDL;
+
//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.
- LL_WARNS() << "Object is already created." << LL_ENDL;
- llassert(!entry->getEntry()->hasDrawable());
}
return obj;
}
@@ -2027,6 +2048,20 @@ void LLViewerRegion::decodeBoundingInfo(LLVOCacheEntry* entry)
if(entry->getEntry()->hasDrawable()) //already in the rendering pipeline
{
+ LLViewerRegion* old_regionp = ((LLDrawable*)entry->getEntry()->getDrawable())->getRegion();
+ if(old_regionp != this && old_regionp)
+ {
+ LLViewerObject* obj = ((LLDrawable*)entry->getEntry()->getDrawable())->getVObj();
+ if(obj)
+ {
+ //remove from old region
+ old_regionp->killCacheEntry(obj->getLocalID(), false);
+
+ //change region
+ obj->setRegion(this);
+ }
+ }
+
addActiveCacheEntry(entry);
//set parent id
@@ -2173,7 +2208,7 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLDataPackerB
mImpl->mCacheMap[local_id] = entry;
decodeBoundingInfo(entry);
- }
+ }
result = CACHE_UPDATE_CHANGED;
}
@@ -2199,23 +2234,6 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObjec
{
eCacheUpdateResult result = cacheFullUpdate(dp, flags);
-#if 0
- LLVOCacheEntry* entry = mImpl->mCacheMap[objectp->getLocalID()];
- if(!entry)
- {
- return result;
- }
-
- if(objectp->mDrawable.notNull() && !entry->getEntry())
- {
- entry->setOctreeEntry(objectp->mDrawable->getEntry());
- }
- if(entry->getEntry() && entry->getEntry()->hasDrawable() && entry->isState(LLVOCacheEntry::INACTIVE))
- {
- addActiveCacheEntry(entry);
- }
-#endif
-
return result;
}
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index a789cc6715..0f27def8a5 100755
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -235,7 +235,7 @@ public:
void addVisibleCacheEntry(LLVOCacheEntry* entry);
void addActiveCacheEntry(LLVOCacheEntry* entry);
void removeActiveCacheEntry(LLVOCacheEntry* entry, LLDrawable* drawablep);
- void killCacheEntry(U32 local_id); //physically delete the cache entry
+ void killCacheEntry(U32 local_id, bool kill_obj = true); //physically delete the cache entry
// Like idleUpdate, but forces everything to complete regardless of
// how long it takes.
@@ -385,7 +385,7 @@ private:
void killObject(LLVOCacheEntry* entry, std::vector<LLDrawable*>& delete_list);
void removeFromVOCacheTree(LLVOCacheEntry* entry);
void replaceVisibleCacheEntry(LLVOCacheEntry* old_entry, LLVOCacheEntry* new_entry);
- void killCacheEntry(LLVOCacheEntry* entry); //physically delete the cache entry
+ void killCacheEntry(LLVOCacheEntry* entry, bool kill_obj = true); //physically delete the cache entry
void killInvisibleObjects(F32 max_time);
void createVisibleObjects(F32 max_time);
void updateVisibleEntries(F32 max_time); //update visible entries