fix for SH-4656: crash at LLVOCacheEntry::updateParentBoundingInfo() line 510
parent
5e55cfd49e
commit
10ae6a779e
|
|
@ -330,6 +330,8 @@ LLViewerOctreeEntryData::LLViewerOctreeEntryData(LLViewerOctreeEntry::eEntryData
|
|||
//virtual
|
||||
void LLViewerOctreeEntryData::setOctreeEntry(LLViewerOctreeEntry* entry)
|
||||
{
|
||||
llassert_always(mEntry.isNull());
|
||||
|
||||
if(mEntry.notNull())
|
||||
{
|
||||
return;
|
||||
|
|
@ -346,6 +348,15 @@ void LLViewerOctreeEntryData::setOctreeEntry(LLViewerOctreeEntry* entry)
|
|||
mEntry->addData(this);
|
||||
}
|
||||
|
||||
void LLViewerOctreeEntryData::removeOctreeEntry()
|
||||
{
|
||||
if(mEntry)
|
||||
{
|
||||
mEntry->removeData(this);
|
||||
mEntry = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void LLViewerOctreeEntryData::setSpatialExtents(const LLVector3& min, const LLVector3& max)
|
||||
{
|
||||
mEntry->mExtents[0].load3(min.mV);
|
||||
|
|
|
|||
|
|
@ -140,6 +140,7 @@ public:
|
|||
LLViewerOctreeEntry* getEntry() {return mEntry;}
|
||||
|
||||
virtual void setOctreeEntry(LLViewerOctreeEntry* entry);
|
||||
void removeOctreeEntry();
|
||||
|
||||
F32 getBinRadius() const {return mEntry->getBinRadius();}
|
||||
const LLVector4a* getSpatialExtents() const;
|
||||
|
|
|
|||
|
|
@ -806,50 +806,10 @@ void LLViewerRegion::dirtyHeights()
|
|||
}
|
||||
}
|
||||
|
||||
void LLViewerRegion::replaceVisibleCacheEntry(LLVOCacheEntry* old_entry, LLVOCacheEntry* 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());
|
||||
mImpl->mActiveSet.insert(new_entry);
|
||||
}
|
||||
else if(state == LLVOCacheEntry::WAITING)
|
||||
{
|
||||
mImpl->mWaitingSet.insert(new_entry);
|
||||
}
|
||||
|
||||
//process parent info
|
||||
if(!old_parent_id && new_parent_id > 0) //becomes a child
|
||||
{
|
||||
new_entry->clearChildrenList();
|
||||
}
|
||||
new_entry->setParentID(new_parent_id);
|
||||
|
||||
//update the object
|
||||
gObjectList.processObjectUpdateFromCache(new_entry, this);
|
||||
}
|
||||
|
||||
//physically delete the cache entry
|
||||
void LLViewerRegion::killCacheEntry(LLVOCacheEntry* entry, bool for_rendering)
|
||||
{
|
||||
if(!entry)
|
||||
if(!entry || !entry->isValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -889,22 +849,18 @@ void LLViewerRegion::killCacheEntry(LLVOCacheEntry* entry, bool for_rendering)
|
|||
}
|
||||
else if(entry->getNumOfChildren() > 0)//remove children from cache if has any
|
||||
{
|
||||
S32 num_child = entry->getNumOfChildren();
|
||||
|
||||
LLVOCacheEntry* child;
|
||||
for(S32 i = 0; i < num_child; i++)
|
||||
LLVOCacheEntry* child = entry->getChild();
|
||||
while(child != NULL)
|
||||
{
|
||||
child = entry->getChild(i);
|
||||
if(child)
|
||||
{
|
||||
child->setParentID(0); //disconnect from parent
|
||||
killCacheEntry(child, for_rendering);
|
||||
}
|
||||
killCacheEntry(child, for_rendering);
|
||||
child = entry->getChild();
|
||||
}
|
||||
}
|
||||
|
||||
//remove from mCacheMap, real deletion
|
||||
mImpl->mCacheMap.erase(entry->getLocalID());
|
||||
//will remove it from the object cache, real deletion
|
||||
entry->setState(LLVOCacheEntry::INACTIVE);
|
||||
entry->removeOctreeEntry();
|
||||
entry->setValid(FALSE);
|
||||
}
|
||||
|
||||
//physically delete the cache entry
|
||||
|
|
@ -924,6 +880,10 @@ void LLViewerRegion::addActiveCacheEntry(LLVOCacheEntry* entry)
|
|||
{
|
||||
return;
|
||||
}
|
||||
if(entry->isState(LLVOCacheEntry::ACTIVE))
|
||||
{
|
||||
return; //already inserted.
|
||||
}
|
||||
|
||||
if(entry->isState(LLVOCacheEntry::WAITING))
|
||||
{
|
||||
|
|
@ -939,10 +899,14 @@ void LLViewerRegion::addActiveCacheEntry(LLVOCacheEntry* entry)
|
|||
|
||||
void LLViewerRegion::removeActiveCacheEntry(LLVOCacheEntry* entry, LLDrawable* drawablep)
|
||||
{
|
||||
if(mDead || !entry)
|
||||
if(mDead || !entry || !entry->isValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(!entry->isState(LLVOCacheEntry::ACTIVE))
|
||||
{
|
||||
return; //not an active entry.
|
||||
}
|
||||
|
||||
//shift to the local regional space from agent space
|
||||
if(drawablep != NULL && drawablep->getVObj().notNull())
|
||||
|
|
@ -1004,11 +968,7 @@ void LLViewerRegion::addToVOCacheTree(LLVOCacheEntry* entry)
|
|||
return;
|
||||
}
|
||||
|
||||
if(mDead || !entry || !entry->getEntry())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(entry->getGroup()) //already in octree.
|
||||
if(mDead || !entry || !entry->getEntry() || !entry->isValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -1017,7 +977,14 @@ void LLViewerRegion::addToVOCacheTree(LLVOCacheEntry* entry)
|
|||
return; //no child prim in cache octree.
|
||||
}
|
||||
|
||||
llassert(!entry->getEntry()->hasDrawable());
|
||||
if(entry->hasState(LLVOCacheEntry::IN_VO_TREE))
|
||||
{
|
||||
return; //already in the tree.
|
||||
}
|
||||
entry->setState(LLVOCacheEntry::IN_VO_TREE);
|
||||
|
||||
llassert_always(!entry->getGroup()); //not in octree.
|
||||
llassert(!entry->getEntry()->hasDrawable()); //not have drawables
|
||||
|
||||
mImpl->mVOCachePartition->addEntry(entry->getEntry());
|
||||
}
|
||||
|
|
@ -1028,10 +995,12 @@ void LLViewerRegion::removeFromVOCacheTree(LLVOCacheEntry* entry)
|
|||
{
|
||||
return;
|
||||
}
|
||||
if(!entry->getGroup())
|
||||
|
||||
if(!entry->hasState(LLVOCacheEntry::IN_VO_TREE))
|
||||
{
|
||||
return;
|
||||
return; //not in the tree.
|
||||
}
|
||||
entry->clearState(LLVOCacheEntry::IN_VO_TREE);
|
||||
|
||||
mImpl->mVOCachePartition->removeEntry(entry->getEntry());
|
||||
}
|
||||
|
|
@ -1039,7 +1008,7 @@ void LLViewerRegion::removeFromVOCacheTree(LLVOCacheEntry* entry)
|
|||
//add the visible entries
|
||||
void LLViewerRegion::addVisibleCacheEntry(LLVOCacheEntry* entry)
|
||||
{
|
||||
if(mDead || !entry || !entry->getEntry())
|
||||
if(mDead || !entry || !entry->getEntry() || !entry->isValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
@ -1053,7 +1022,22 @@ void LLViewerRegion::addVisibleCacheEntry(LLVOCacheEntry* entry)
|
|||
{
|
||||
entry->setState(LLVOCacheEntry::IN_QUEUE);
|
||||
}
|
||||
mImpl->mVisibleEntries.insert(entry);
|
||||
|
||||
if(!entry->isState(LLVOCacheEntry::ACTIVE))
|
||||
{
|
||||
mImpl->mVisibleEntries.insert(entry);
|
||||
}
|
||||
|
||||
//add all children
|
||||
if(entry->getNumOfChildren() > 0)
|
||||
{
|
||||
LLVOCacheEntry* child = entry->getChild();
|
||||
while(child != NULL)
|
||||
{
|
||||
addVisibleCacheEntry(child);
|
||||
child = entry->getChild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLViewerRegion::updateVisibleEntries(F32 max_time)
|
||||
|
|
@ -1085,53 +1069,18 @@ void LLViewerRegion::updateVisibleEntries(F32 max_time)
|
|||
for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mVisibleEntries.begin(); iter != mImpl->mVisibleEntries.end();)
|
||||
{
|
||||
LLVOCacheEntry* vo_entry = *iter;
|
||||
|
||||
//set a large number to force to load this object.
|
||||
vo_entry->setSceneContribution(LARGE_SCENE_CONTRIBUTION);
|
||||
|
||||
if(vo_entry->getState() < LLVOCacheEntry::WAITING)
|
||||
{
|
||||
|
||||
if(vo_entry->isValid() && vo_entry->getState() < LLVOCacheEntry::WAITING)
|
||||
{
|
||||
//set a large number to force to load this object.
|
||||
vo_entry->setSceneContribution(LARGE_SCENE_CONTRIBUTION);
|
||||
|
||||
mImpl->mWaitingList.insert(vo_entry);
|
||||
}
|
||||
|
||||
LLVOCacheEntry* child;
|
||||
S32 num_child = vo_entry->getNumOfChildren();
|
||||
S32 num_done = 0;
|
||||
for(S32 i = 0; i < num_child; i++)
|
||||
{
|
||||
child = vo_entry->getChild(i);
|
||||
if(child->getState() < LLVOCacheEntry::WAITING)
|
||||
{
|
||||
child->setSceneContribution(LARGE_SCENE_CONTRIBUTION); //a large number to force to load the child.
|
||||
mImpl->mWaitingList.insert(child);
|
||||
}
|
||||
else
|
||||
{
|
||||
num_done++;
|
||||
}
|
||||
}
|
||||
if(num_done == num_child)
|
||||
{
|
||||
vo_entry->clearChildrenList();
|
||||
}
|
||||
|
||||
if(!vo_entry->getNumOfChildren())
|
||||
{
|
||||
if(vo_entry->getState() >= LLVOCacheEntry::WAITING)
|
||||
{
|
||||
LLVOCacheEntry::vocache_entry_set_t::iterator next_iter = iter;
|
||||
++next_iter;
|
||||
mImpl->mVisibleEntries.erase(iter);
|
||||
iter = next_iter;
|
||||
}
|
||||
else
|
||||
{
|
||||
++iter;
|
||||
}
|
||||
++iter;
|
||||
}
|
||||
else
|
||||
{
|
||||
++iter;
|
||||
iter = mImpl->mVisibleEntries.erase(iter);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1163,6 +1112,10 @@ void LLViewerRegion::updateVisibleEntries(F32 max_time)
|
|||
//child visibility depends on its parent.
|
||||
continue;
|
||||
}
|
||||
if(!vo_entry->isValid())
|
||||
{
|
||||
continue; //skip invalid entry.
|
||||
}
|
||||
|
||||
vo_entry->calcSceneContribution(local_origin, needs_update, last_update, dist_threshold);
|
||||
if(vo_entry->getSceneContribution() > projection_threshold)
|
||||
|
|
@ -1240,10 +1193,7 @@ void LLViewerRegion::clearCachedVisibleObjects()
|
|||
parent->addChild(entry);
|
||||
}
|
||||
|
||||
LLVOCacheEntry::vocache_entry_set_t::iterator next_iter = iter;
|
||||
++next_iter;
|
||||
mImpl->mVisibleEntries.erase(iter);
|
||||
iter = next_iter;
|
||||
iter = mImpl->mVisibleEntries.erase(iter);
|
||||
}
|
||||
else //parent is not cache-able, leave it.
|
||||
{
|
||||
|
|
@ -2044,8 +1994,7 @@ void LLViewerRegion::findOrphans(U32 parent_id)
|
|||
for(S32 i = 0; i < children->size(); i++)
|
||||
{
|
||||
//parent is visible, so is the child.
|
||||
LLVOCacheEntry* child = getCacheEntry((*children)[i]);
|
||||
addVisibleCacheEntry(child);
|
||||
addVisibleCacheEntry(getCacheEntry((*children)[i]));
|
||||
}
|
||||
children->clear();
|
||||
mOrphanMap.erase(parent_id);
|
||||
|
|
@ -2059,46 +2008,50 @@ void LLViewerRegion::decodeBoundingInfo(LLVOCacheEntry* entry)
|
|||
gObjectList.processObjectUpdateFromCache(entry, this);
|
||||
return;
|
||||
}
|
||||
if(!entry || !entry->isValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(entry != NULL && !entry->getEntry())
|
||||
if(!entry->getEntry())
|
||||
{
|
||||
entry->setOctreeEntry(NULL);
|
||||
|
||||
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());
|
||||
|
||||
//change region
|
||||
obj->setRegion(this);
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
if(entry->getEntry()->hasDrawable()) //already in the rendering pipeline
|
||||
{
|
||||
return; //already in octree, no post processing.
|
||||
}
|
||||
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());
|
||||
|
||||
//change region
|
||||
obj->setRegion(this);
|
||||
}
|
||||
}
|
||||
|
||||
addActiveCacheEntry(entry);
|
||||
|
||||
//set parent id
|
||||
U32 parent_id = 0;
|
||||
LLViewerObject::unpackParentID(entry->getDP(), parent_id);
|
||||
if(parent_id != entry->getParentID())
|
||||
{
|
||||
entry->setParentID(parent_id);
|
||||
}
|
||||
|
||||
//update the object
|
||||
gObjectList.processObjectUpdateFromCache(entry, this);
|
||||
return; //done
|
||||
}
|
||||
|
||||
//must not be active.
|
||||
llassert_always(!entry->isState(LLVOCacheEntry::ACTIVE));
|
||||
removeFromVOCacheTree(entry); //remove from cache octree if it is in.
|
||||
|
||||
LLVector3 pos;
|
||||
LLVector3 scale;
|
||||
|
|
@ -2107,27 +2060,56 @@ void LLViewerRegion::decodeBoundingInfo(LLVOCacheEntry* entry)
|
|||
//decode spatial info and parent info
|
||||
U32 parent_id = LLViewerObject::extractSpatialExtents(entry->getDP(), pos, scale, rot);
|
||||
|
||||
if(parent_id > 0) //has parent
|
||||
U32 old_parent_id = entry->getParentID();
|
||||
bool same_old_parent = false;
|
||||
if(parent_id != old_parent_id) //parent changed.
|
||||
{
|
||||
if(old_parent_id > 0) //has an old parent, disconnect it
|
||||
{
|
||||
LLVOCacheEntry* old_parent = getCacheEntry(old_parent_id);
|
||||
if(old_parent)
|
||||
{
|
||||
old_parent->removeChild(entry);
|
||||
if(!old_parent->isState(LLVOCacheEntry::INACTIVE))
|
||||
{
|
||||
mImpl->mVisibleEntries.erase(entry);
|
||||
entry->setState(LLVOCacheEntry::INACTIVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
entry->setParentID(parent_id);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
same_old_parent = true;
|
||||
}
|
||||
|
||||
if(parent_id > 0) //has a new parent
|
||||
{
|
||||
//1, find the parent in cache
|
||||
LLVOCacheEntry* parent = getCacheEntry(parent_id);
|
||||
|
||||
//2, parent is not in the cache, put into the orphan list.
|
||||
if(!parent)
|
||||
{
|
||||
//check if parent is non-cacheable and already created
|
||||
if(isNonCacheableObjectCreated(parent_id))
|
||||
if(!same_old_parent)
|
||||
{
|
||||
//parent is visible, so is the child.
|
||||
addVisibleCacheEntry(entry);
|
||||
//check if parent is non-cacheable and already created
|
||||
if(isNonCacheableObjectCreated(parent_id))
|
||||
{
|
||||
//parent is visible, so is the child.
|
||||
addVisibleCacheEntry(entry);
|
||||
}
|
||||
else
|
||||
{
|
||||
entry->setBoundingInfo(pos, scale);
|
||||
mOrphanMap[parent_id].push_back(entry->getLocalID());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
entry->setBoundingInfo(pos, scale);
|
||||
mOrphanMap[parent_id].push_back(entry->getLocalID());
|
||||
}
|
||||
}
|
||||
}
|
||||
else //parent in cache.
|
||||
{
|
||||
|
|
@ -2194,10 +2176,12 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLDataPackerB
|
|||
LLViewerObject::unpackU32(&dp, local_id, "LocalID");
|
||||
LLViewerObject::unpackU32(&dp, crc, "CRC");
|
||||
|
||||
LLVOCacheEntry* entry = getCacheEntry(local_id);
|
||||
LLVOCacheEntry* entry = getCacheEntry(local_id, false);
|
||||
|
||||
if (entry)
|
||||
{
|
||||
entry->setValid();
|
||||
|
||||
// we've seen this object before
|
||||
if (entry->getCRC() == crc)
|
||||
{
|
||||
|
|
@ -2205,31 +2189,15 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLDataPackerB
|
|||
entry->recordDupe();
|
||||
result = CACHE_UPDATE_DUPE;
|
||||
}
|
||||
else
|
||||
else //CRC changed
|
||||
{
|
||||
// Update the cache entry
|
||||
LLPointer<LLVOCacheEntry> new_entry = new LLVOCacheEntry(local_id, crc, dp);
|
||||
|
||||
//if visible, update it
|
||||
if(!entry->isState(LLVOCacheEntry::INACTIVE))
|
||||
{
|
||||
replaceVisibleCacheEntry(entry, new_entry);
|
||||
}
|
||||
else //invisible
|
||||
{
|
||||
//copy some contents from old entry
|
||||
entry->moveTo(new_entry, true);
|
||||
entry->updateEntry(crc, dp);
|
||||
|
||||
//remove old entry
|
||||
killCacheEntry(entry);
|
||||
entry = new_entry;
|
||||
|
||||
mImpl->mCacheMap[local_id] = entry;
|
||||
decodeBoundingInfo(entry);
|
||||
}
|
||||
decodeBoundingInfo(entry);
|
||||
|
||||
result = CACHE_UPDATE_CHANGED;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -2268,12 +2236,15 @@ LLVOCacheEntry* LLViewerRegion::getCacheEntryForOctree(U32 local_id)
|
|||
return entry;
|
||||
}
|
||||
|
||||
LLVOCacheEntry* LLViewerRegion::getCacheEntry(U32 local_id)
|
||||
LLVOCacheEntry* LLViewerRegion::getCacheEntry(U32 local_id, bool valid)
|
||||
{
|
||||
LLVOCacheEntry::vocache_entry_map_t::iterator iter = mImpl->mCacheMap.find(local_id);
|
||||
if(iter != mImpl->mCacheMap.end())
|
||||
{
|
||||
return iter->second;
|
||||
if(!valid || iter->second->isValid())
|
||||
{
|
||||
return iter->second;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -2323,7 +2294,7 @@ bool LLViewerRegion::probeCache(U32 local_id, U32 crc, U32 flags, U8 &cache_miss
|
|||
{
|
||||
//llassert(mCacheLoaded); This assert failes often, changing to early-out -- davep, 2010/10/18
|
||||
|
||||
LLVOCacheEntry* entry = getCacheEntry(local_id);
|
||||
LLVOCacheEntry* entry = getCacheEntry(local_id, false);
|
||||
|
||||
if (entry)
|
||||
{
|
||||
|
|
@ -2341,15 +2312,12 @@ bool LLViewerRegion::probeCache(U32 local_id, U32 crc, U32 flags, U8 &cache_miss
|
|||
return true;
|
||||
}
|
||||
|
||||
if(entry->getGroup() || !entry->isState(LLVOCacheEntry::INACTIVE)) //already probed
|
||||
if(entry->isValid())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if(entry->getParentID() > 0) //already probed
|
||||
{
|
||||
return true;
|
||||
return true; //already probed
|
||||
}
|
||||
|
||||
entry->setValid();
|
||||
decodeBoundingInfo(entry);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -331,7 +331,7 @@ public:
|
|||
eCacheUpdateResult cacheFullUpdate(LLDataPackerBinaryBuffer &dp, U32 flags);
|
||||
eCacheUpdateResult cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp, U32 flags);
|
||||
LLVOCacheEntry* getCacheEntryForOctree(U32 local_id);
|
||||
LLVOCacheEntry* getCacheEntry(U32 local_id);
|
||||
LLVOCacheEntry* getCacheEntry(U32 local_id, bool valid = true);
|
||||
bool probeCache(U32 local_id, U32 crc, U32 flags, U8 &cache_miss_type);
|
||||
void requestCacheMisses();
|
||||
void addCacheMissFull(const U32 local_id);
|
||||
|
|
@ -384,7 +384,6 @@ private:
|
|||
LLViewerObject* addNewObject(LLVOCacheEntry* entry);
|
||||
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, bool for_rendering = false); //physically delete the cache entry
|
||||
void killInvisibleObjects(F32 max_time);
|
||||
void createVisibleObjects(F32 max_time);
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ LLVOCacheEntry::LLVOCacheEntry(U32 local_id, U32 crc, LLDataPackerBinaryBuffer &
|
|||
mCRCChangeCount(0),
|
||||
mState(INACTIVE),
|
||||
mSceneContrib(0.f),
|
||||
mTouched(TRUE),
|
||||
mValid(TRUE),
|
||||
mParentID(0),
|
||||
mBSphereRadius(-1.0f)
|
||||
{
|
||||
|
|
@ -90,7 +90,7 @@ LLVOCacheEntry::LLVOCacheEntry()
|
|||
mBuffer(NULL),
|
||||
mState(INACTIVE),
|
||||
mSceneContrib(0.f),
|
||||
mTouched(TRUE),
|
||||
mValid(TRUE),
|
||||
mParentID(0),
|
||||
mBSphereRadius(-1.0f)
|
||||
{
|
||||
|
|
@ -104,7 +104,7 @@ LLVOCacheEntry::LLVOCacheEntry(LLAPRFile* apr_file)
|
|||
mUpdateFlags(-1),
|
||||
mState(INACTIVE),
|
||||
mSceneContrib(0.f),
|
||||
mTouched(FALSE),
|
||||
mValid(FALSE),
|
||||
mParentID(0),
|
||||
mBSphereRadius(-1.0f)
|
||||
{
|
||||
|
|
@ -169,14 +169,29 @@ LLVOCacheEntry::LLVOCacheEntry(LLAPRFile* apr_file)
|
|||
mCRCChangeCount = 0;
|
||||
mBuffer = NULL;
|
||||
mEntry = NULL;
|
||||
mState = 0;
|
||||
mState = INACTIVE;
|
||||
}
|
||||
}
|
||||
|
||||
LLVOCacheEntry::~LLVOCacheEntry()
|
||||
{
|
||||
mDP.freeBuffer();
|
||||
//llassert(mState == INACTIVE);
|
||||
}
|
||||
|
||||
void LLVOCacheEntry::updateEntry(U32 crc, LLDataPackerBinaryBuffer &dp)
|
||||
{
|
||||
if(mCRC != crc)
|
||||
{
|
||||
mCRC = crc;
|
||||
mCRCChangeCount++;
|
||||
}
|
||||
|
||||
mDP.freeBuffer();
|
||||
|
||||
llassert_always(dp.getBufferSize() > 0);
|
||||
mBuffer = new U8[dp.getBufferSize()];
|
||||
mDP.assignBuffer(mBuffer, dp.getBufferSize());
|
||||
mDP = dp;
|
||||
}
|
||||
|
||||
//virtual
|
||||
|
|
@ -197,27 +212,19 @@ void LLVOCacheEntry::setOctreeEntry(LLViewerOctreeEntry* entry)
|
|||
LLViewerOctreeEntryData::setOctreeEntry(entry);
|
||||
}
|
||||
|
||||
void LLVOCacheEntry::moveTo(LLVOCacheEntry* new_entry, bool no_entry_move)
|
||||
{
|
||||
//copy LLViewerOctreeEntry
|
||||
if(mEntry.notNull() && !no_entry_move)
|
||||
{
|
||||
new_entry->setOctreeEntry(mEntry);
|
||||
mEntry = NULL;
|
||||
}
|
||||
|
||||
//copy children
|
||||
S32 num_children = getNumOfChildren();
|
||||
for(S32 i = 0; i < num_children; i++)
|
||||
{
|
||||
new_entry->addChild(getChild(i));
|
||||
}
|
||||
mChildrenList.clear();
|
||||
}
|
||||
|
||||
void LLVOCacheEntry::setState(U32 state)
|
||||
{
|
||||
mState = state;
|
||||
if(state > LOW_BITS) //special states
|
||||
{
|
||||
mState |= (HIGH_BITS & state);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
//otherwise LOW_BITS states
|
||||
//
|
||||
clearState(LOW_BITS);
|
||||
mState |= (LOW_BITS & state);
|
||||
|
||||
if(getState() == ACTIVE)
|
||||
{
|
||||
|
|
@ -249,8 +256,8 @@ void LLVOCacheEntry::addChild(LLVOCacheEntry* entry)
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mChildrenList.push_back(entry);
|
||||
|
||||
mChildrenList.insert(entry);
|
||||
|
||||
//update parent bbox
|
||||
if(getEntry() != NULL && isState(INACTIVE))
|
||||
|
|
@ -262,24 +269,27 @@ void LLVOCacheEntry::addChild(LLVOCacheEntry* entry)
|
|||
|
||||
void LLVOCacheEntry::removeChild(LLVOCacheEntry* entry)
|
||||
{
|
||||
for(S32 i = 0; i < mChildrenList.size(); i++)
|
||||
entry->setParentID(0);
|
||||
|
||||
vocache_entry_set_t::iterator iter = mChildrenList.find(entry);
|
||||
if(iter != mChildrenList.end())
|
||||
{
|
||||
if(mChildrenList[i] == entry)
|
||||
{
|
||||
entry->setParentID(0);
|
||||
mChildrenList[i] = mChildrenList[mChildrenList.size() - 1];
|
||||
mChildrenList.pop_back();
|
||||
}
|
||||
mChildrenList.erase(iter);
|
||||
}
|
||||
}
|
||||
|
||||
void LLVOCacheEntry::removeAllChildren()
|
||||
//remove the first child, and return it.
|
||||
LLVOCacheEntry* LLVOCacheEntry::getChild()
|
||||
{
|
||||
for(S32 i = 0; i < mChildrenList.size(); i++)
|
||||
LLVOCacheEntry* child = NULL;
|
||||
vocache_entry_set_t::iterator iter = mChildrenList.begin();
|
||||
if(iter != mChildrenList.end())
|
||||
{
|
||||
mChildrenList[i]->setParentID(0);
|
||||
child = *iter;
|
||||
mChildrenList.erase(iter);
|
||||
}
|
||||
mChildrenList.clear();
|
||||
|
||||
return child;
|
||||
}
|
||||
|
||||
LLDataPackerBinaryBuffer *LLVOCacheEntry::getDP()
|
||||
|
|
@ -295,7 +305,6 @@ LLDataPackerBinaryBuffer *LLVOCacheEntry::getDP()
|
|||
|
||||
void LLVOCacheEntry::recordHit()
|
||||
{
|
||||
setTouched();
|
||||
mHitCount++;
|
||||
}
|
||||
|
||||
|
|
@ -505,9 +514,9 @@ void LLVOCacheEntry::updateParentBoundingInfo()
|
|||
return;
|
||||
}
|
||||
|
||||
for(S32 i = 0; i < mChildrenList.size(); i++)
|
||||
for(vocache_entry_set_t::iterator iter = mChildrenList.begin(); iter != mChildrenList.end(); ++iter)
|
||||
{
|
||||
updateParentBoundingInfo(mChildrenList[i]);
|
||||
updateParentBoundingInfo(*iter);
|
||||
}
|
||||
resetVisible();
|
||||
}
|
||||
|
|
@ -1463,7 +1472,7 @@ void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry:
|
|||
|
||||
for (LLVOCacheEntry::vocache_entry_map_t::const_iterator iter = cache_entry_map.begin(); success && iter != cache_entry_map.end(); ++iter)
|
||||
{
|
||||
if(!removal_enabled || iter->second->isTouched())
|
||||
if(!removal_enabled || iter->second->isValid())
|
||||
{
|
||||
success = iter->second->writeToFile(&apr_file) ;
|
||||
if(!success)
|
||||
|
|
|
|||
|
|
@ -42,12 +42,19 @@ class LLVOCacheEntry
|
|||
public LLTrace::MemTrackable<LLVOCacheEntry, 16>
|
||||
{
|
||||
public:
|
||||
enum //low 16-bit state
|
||||
enum
|
||||
{
|
||||
//low 16-bit state
|
||||
INACTIVE = 0x00000000, //not visible
|
||||
IN_QUEUE = 0x00000001, //in visible queue, object to be created
|
||||
WAITING = 0x00000002, //object creation request sent
|
||||
ACTIVE = 0x00000004 //object created, and in rendering pipeline.
|
||||
ACTIVE = 0x00000004, //object created, and in rendering pipeline.
|
||||
|
||||
//high 16-bit state
|
||||
IN_VO_TREE = 0x00010000, //the entry is in the object cache tree.
|
||||
|
||||
LOW_BITS = 0x0000ffff,
|
||||
HIGH_BITS = 0xffff0000
|
||||
};
|
||||
|
||||
struct CompareVOCacheEntry
|
||||
|
|
@ -79,11 +86,13 @@ public:
|
|||
LLVOCacheEntry(LLAPRFile* apr_file);
|
||||
LLVOCacheEntry();
|
||||
|
||||
void setState(U32 state);
|
||||
//void clearState(U32 state) {mState &= ~state;}
|
||||
bool isState(U32 state) {return mState == state;}
|
||||
bool hasState(U32 state) {return mState & state;}
|
||||
U32 getState() const {return mState;}
|
||||
void updateEntry(U32 crc, LLDataPackerBinaryBuffer &dp);
|
||||
|
||||
void clearState(U32 state) {mState &= ~state;}
|
||||
bool hasState(U32 state) {return mState & state;}
|
||||
void setState(U32 state);
|
||||
bool isState(U32 state) {return (mState & LOW_BITS) == state;}
|
||||
U32 getState() const {return mState & LOW_BITS;}
|
||||
|
||||
bool isAnyVisible(const LLVector4a& camera_origin, const LLVector4a& local_camera_origin, F32 dist_threshold);
|
||||
|
||||
|
|
@ -102,7 +111,6 @@ public:
|
|||
void recordHit();
|
||||
void recordDupe() { mDupeCount++; }
|
||||
|
||||
void moveTo(LLVOCacheEntry* new_entry, bool no_entry_move = false); //copy variables
|
||||
/*virtual*/ void setOctreeEntry(LLViewerOctreeEntry* entry);
|
||||
|
||||
void setParentID(U32 id) {mParentID = id;}
|
||||
|
|
@ -110,17 +118,15 @@ public:
|
|||
|
||||
void addChild(LLVOCacheEntry* entry);
|
||||
void removeChild(LLVOCacheEntry* entry);
|
||||
void removeAllChildren();
|
||||
LLVOCacheEntry* getChild(S32 i) {return mChildrenList[i];}
|
||||
S32 getNumOfChildren() {return mChildrenList.size();}
|
||||
void clearChildrenList() {mChildrenList.clear();}
|
||||
LLVOCacheEntry* getChild(); //remove the first child, and return it.
|
||||
S32 getNumOfChildren() const {return mChildrenList.size();}
|
||||
|
||||
void setBoundingInfo(const LLVector3& pos, const LLVector3& scale); //called from processing object update message
|
||||
void updateParentBoundingInfo();
|
||||
void saveBoundingSphere();
|
||||
|
||||
void setTouched(BOOL touched = TRUE) {mTouched = touched;}
|
||||
BOOL isTouched() const {return mTouched;}
|
||||
void setValid(BOOL valid = TRUE) {mValid = valid;}
|
||||
BOOL isValid() const {return mValid;}
|
||||
|
||||
void setUpdateFlags(U32 flags) {mUpdateFlags = flags;}
|
||||
U32 getUpdateFlags() const {return mUpdateFlags;}
|
||||
|
|
@ -150,9 +156,9 @@ protected:
|
|||
|
||||
F32 mSceneContrib; //projected scene contributuion of this object.
|
||||
U32 mState; //high 16 bits reserved for special use.
|
||||
std::vector<LLVOCacheEntry*> mChildrenList; //children entries in a linked set.
|
||||
vocache_entry_set_t mChildrenList; //children entries in a linked set.
|
||||
|
||||
BOOL mTouched; //if set, this entry is valid, otherwise it is invalid.
|
||||
BOOL mValid; //if set, this entry is valid, otherwise it is invalid and will be removed.
|
||||
|
||||
LLVector4a mBSphereCenter; //bounding sphere center
|
||||
F32 mBSphereRadius; //bounding sphere radius
|
||||
|
|
|
|||
Loading…
Reference in New Issue