From c0ba626c8009b22310b3923e8170e5db2a021253 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Mon, 15 Oct 2012 21:34:29 -0600 Subject: For SH-3333: Design and implement a new object cache system on viewer side --- indra/newview/llviewerregion.cpp | 478 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 441 insertions(+), 37 deletions(-) (limited to 'indra/newview/llviewerregion.cpp') diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 31e3820a21..15c95aa30a 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -70,6 +70,7 @@ #include "stringize.h" #include "llviewercontrol.h" #include "llsdserialize.h" +#include "llvieweroctree.h" #ifdef LL_WINDOWS #pragma warning(disable:4355) @@ -133,7 +134,14 @@ public: // Misc LLVLComposition *mCompositionp; // Composition layer for the surface - LLVOCacheEntry::vocache_entry_map_t mCacheMap; + LLVOCacheEntry::vocache_entry_map_t mCacheMap; //all cached entries + LLVOCacheEntry::vocache_entry_set_t mActiveSet; //all active entries; + LLVOCacheEntry::vocache_entry_set_t mWaitingSet; //entries waiting for LLDrawable to be generated. + LLVOCacheEntry::vocache_entry_set_t mVisibleEntries; //visible root entries of a linked set. + std::set< LLPointer > mDummyEntries; //dummy vo cache entries, for LLSpatialBridge use. + std::set< LLSpatialGroup* > mVisibleGroups; //visible llspatialgroup + LLVOCachePartition* mVOCachePartition; + // time? // LRU info? @@ -291,7 +299,8 @@ LLViewerRegion::LLViewerRegion(const U64 &handle, mCacheLoaded(FALSE), mCacheDirty(FALSE), mReleaseNotesRequested(FALSE), - mCapabilitiesReceived(false) + mCapabilitiesReceived(false), + mDead(FALSE) { mWidth = region_width_meters; mImpl->mOriginGlobal = from_region_handle(handle); @@ -323,17 +332,20 @@ LLViewerRegion::LLViewerRegion(const U64 &handle, //create object partitions //MUST MATCH declaration of eObjectPartitions - mImpl->mObjectPartition.push_back(new LLHUDPartition()); //PARTITION_HUD - mImpl->mObjectPartition.push_back(new LLTerrainPartition()); //PARTITION_TERRAIN - mImpl->mObjectPartition.push_back(new LLVoidWaterPartition()); //PARTITION_VOIDWATER - mImpl->mObjectPartition.push_back(new LLWaterPartition()); //PARTITION_WATER - mImpl->mObjectPartition.push_back(new LLTreePartition()); //PARTITION_TREE - mImpl->mObjectPartition.push_back(new LLParticlePartition()); //PARTITION_PARTICLE - mImpl->mObjectPartition.push_back(new LLGrassPartition()); //PARTITION_GRASS - mImpl->mObjectPartition.push_back(new LLVolumePartition()); //PARTITION_VOLUME - mImpl->mObjectPartition.push_back(new LLBridgePartition()); //PARTITION_BRIDGE - mImpl->mObjectPartition.push_back(new LLHUDParticlePartition());//PARTITION_HUD_PARTICLE + mImpl->mObjectPartition.push_back(new LLHUDPartition(this)); //PARTITION_HUD + mImpl->mObjectPartition.push_back(new LLTerrainPartition(this)); //PARTITION_TERRAIN + mImpl->mObjectPartition.push_back(new LLVoidWaterPartition(this)); //PARTITION_VOIDWATER + mImpl->mObjectPartition.push_back(new LLWaterPartition(this)); //PARTITION_WATER + mImpl->mObjectPartition.push_back(new LLTreePartition(this)); //PARTITION_TREE + mImpl->mObjectPartition.push_back(new LLParticlePartition(this)); //PARTITION_PARTICLE + mImpl->mObjectPartition.push_back(new LLGrassPartition(this)); //PARTITION_GRASS + mImpl->mObjectPartition.push_back(new LLVolumePartition(this)); //PARTITION_VOLUME + mImpl->mObjectPartition.push_back(new LLBridgePartition(this)); //PARTITION_BRIDGE + mImpl->mObjectPartition.push_back(new LLHUDParticlePartition(this));//PARTITION_HUD_PARTICLE + mImpl->mObjectPartition.push_back(new LLVOCachePartition(this)); //PARTITION_VO_CACHE mImpl->mObjectPartition.push_back(NULL); //PARTITION_NONE + + mImpl->mVOCachePartition = (LLVOCachePartition*)getSpatialPartition(PARTITION_VO_CACHE); } @@ -354,6 +366,12 @@ void LLViewerRegion::initStats() LLViewerRegion::~LLViewerRegion() { + mDead = TRUE; + mImpl->mActiveSet.clear(); + mImpl->mVisibleEntries.clear(); + mImpl->mVisibleGroups.clear(); + mImpl->mWaitingSet.clear(); + gVLManager.cleanupData(this); // Can't do this on destruction, because the neighbor pointers might be invalid. // This should be reference counted... @@ -437,10 +455,6 @@ void LLViewerRegion::saveObjectCache() mCacheDirty = FALSE; } - for(LLVOCacheEntry::vocache_entry_map_t::iterator iter = mImpl->mCacheMap.begin(); iter != mImpl->mCacheMap.end(); ++iter) - { - delete iter->second; - } mImpl->mCacheMap.clear(); } @@ -718,8 +732,199 @@ void LLViewerRegion::dirtyHeights() } } +void LLViewerRegion::replaceCacheEntry(LLVOCacheEntry* old_entry, LLVOCacheEntry* new_entry) +{ + LLPointer oct_entry; + U32 state = LLVOCacheEntry::INACTIVE; + + if(old_entry) + { + oct_entry = old_entry->getEntry(); + state = old_entry->getState(); + + while(old_entry->getNumOfChildren() > 0) + { + new_entry->addChild(old_entry->getNextChild()); + } + + killCacheEntry(old_entry); + } + + mImpl->mCacheMap[new_entry->getLocalID()] = new_entry; + if(oct_entry.notNull()) + { + new_entry->setOctreeEntry(oct_entry); + } + + if(state == LLVOCacheEntry::ACTIVE) + { + llassert(new_entry->getEntry()->hasDrawable()); + mImpl->mActiveSet.insert(new_entry); + } + else if(state == LLVOCacheEntry::WAITING) + { + mImpl->mWaitingSet.insert(new_entry); + } + else if(old_entry && oct_entry) + { + addToVOCacheTree(new_entry); + } + new_entry->setState(state); +} + +//physically delete the cache entry +void LLViewerRegion::killCacheEntry(LLVOCacheEntry* entry) +{ + if(!entry) + { + return; + } + + //1, remove from active list and waiting list + if(entry->isState(LLVOCacheEntry::ACTIVE)) + { + mImpl->mActiveSet.erase(entry); + } + else if(entry->isState(LLVOCacheEntry::WAITING)) + { + mImpl->mWaitingSet.erase(entry); + } + + //2, kill LLViewerObject if exists + //this should be done by the rendering pipeline automatically. + + //3, remove from mVOCachePartition + if(entry->isState(LLVOCacheEntry::INACTIVE) && entry->getEntry()) + { + removeFromVOCacheTree(entry); + } + + entry->setState(LLVOCacheEntry::INACTIVE); + //4, remove from mCacheMap, real deletion + mImpl->mCacheMap.erase(entry->getLocalID()); +} + +//physically delete the cache entry +void LLViewerRegion::killCacheEntry(U32 local_id) +{ + killCacheEntry(getCacheEntry(local_id)); +} + +U32 LLViewerRegion::getNumOfActiveCachedObjects() const +{ + return mImpl->mActiveSet.size(); +} + +void LLViewerRegion::addActiveCacheEntry(LLVOCacheEntry* entry) +{ + if(!entry || mDead) + { + return; + } + + if(entry->isState(LLVOCacheEntry::WAITING)) + { + mImpl->mWaitingSet.erase(entry); + } + + entry->setState(LLVOCacheEntry::ACTIVE); + entry->setVisible(); + + llassert(entry->getEntry()->hasDrawable()); + mImpl->mActiveSet.insert(entry); +} + +void LLViewerRegion::removeActiveCacheEntry(LLVOCacheEntry* entry, LLDrawable* drawablep) +{ + if(mDead) + { + return; + } + if(entry->isDummy()) + { + mImpl->mDummyEntries.insert(entry); //keep a copy to prevent from being deleted. + addToVOCacheTree(entry); + } + else if(!drawablep->getParent()) //root node + { + addToVOCacheTree(entry); + mImpl->mVisibleEntries.erase(entry); + } + else //child node + { + LLViewerOctreeEntry* parent_oct_entry = drawablep->getParent()->getEntry(); + if(parent_oct_entry && parent_oct_entry->hasVOCacheEntry()) + { + LLVOCacheEntry* parent = (LLVOCacheEntry*)parent_oct_entry->getVOCacheEntry(); + parent->addChild(entry); + } + } + + mImpl->mActiveSet.erase(entry); + mImpl->mWaitingSet.erase(entry); + entry->setState(LLVOCacheEntry::INACTIVE); +} + +void LLViewerRegion::addVisibleGroup(LLSpatialGroup* group) +{ + if(mDead || group->isEmpty() || group->isDead()) + { + return; + } + + mImpl->mVisibleGroups.insert(group); +} + +void LLViewerRegion::addToVOCacheTree(LLVOCacheEntry* entry) +{ + static BOOL vo_cache_culling_enabled = gSavedSettings.getBOOL("ObjectCacheViewCullingEnabled"); + + if(mDead || !entry || !entry->getEntry()) + { + return; + } + llassert(!entry->getGroup()); + + mImpl->mVOCachePartition->addEntry(entry->getEntry()); +} + +void LLViewerRegion::removeFromVOCacheTree(LLVOCacheEntry* entry) +{ + if(mDead || !entry || !entry->getEntry()) + { + return; + } + + mImpl->mVOCachePartition->removeEntry(entry->getEntry()); +} + +//add the visible root entry of a linked set +void LLViewerRegion::addVisibleCacheEntry(LLVOCacheEntry* entry) +{ + if(mDead || !entry || !entry->getNumOfChildren()) + { + return; //no child entries + } + + mImpl->mVisibleEntries.insert(entry); +} + +void LLViewerRegion::clearVisibleGroup(LLSpatialGroup* group) +{ + if(mDead) + { + return; + } + + llassert(!group->getOctreeNode() || group->isEmpty()); + + mImpl->mVisibleGroups.erase(group); +} + BOOL LLViewerRegion::idleUpdate(F32 max_update_time) { + LLTimer update_timer; + // did_update returns TRUE if we did at least one significant update BOOL did_update = mImpl->mLandp->idleUpdate(max_update_time); @@ -729,9 +934,168 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time) mParcelOverlay->idleUpdate(); } + if(update_timer.getElapsedTimeF32() > max_update_time) + { + return did_update; + } + + //kill invisible objects + std::vector delete_list; + for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mActiveSet.begin(); + iter != mImpl->mActiveSet.end(); ++iter) + { + if(!(*iter)->isRecentlyVisible()) + { + killObject((*iter), delete_list); + } + } + for(S32 i = 0; i < delete_list.size(); i++) + { + gObjectList.killObject(delete_list[i]->getVObj()); + } + delete_list.clear(); + + bool timeout = false; + S32 new_object_count = 64; //minimum number of new objects to be added + //add childrens of visible objects to the rendering pipeline + for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mVisibleEntries.begin(); iter != mImpl->mVisibleEntries.end();) + { + LLVOCacheEntry* entry = *iter; + LLVOCacheEntry* child = entry->getNextChild(); + while(child != NULL) + { + if(child->isState(LLVOCacheEntry::INACTIVE)) + { + addNewObject(child); + + if(new_object_count-- < 0 && update_timer.getElapsedTimeF32() > max_update_time) + { + timeout = true; + break; + } + } + child = entry->getNextChild(); + } + if(!child) + { + if(entry->isDummy()) + { + mImpl->mDummyEntries.erase(entry); + } + + iter = mImpl->mVisibleEntries.erase(iter); + } + else + { + break; //timeout + } + } + if(timeout) + { + mImpl->mVisibleGroups.clear(); + return did_update; + } + + //add objects in the visible groups to the rendering pipeline + std::set< LLSpatialGroup* >::iterator group_iter = mImpl->mVisibleGroups.begin(); + while(group_iter != mImpl->mVisibleGroups.end()) + { + LLSpatialGroup* group = *group_iter; + if(!group->getOctreeNode() || group->isEmpty()) + { + mImpl->mVisibleGroups.erase(group_iter); + group_iter = mImpl->mVisibleGroups.begin(); + continue; + } + + std::vector entry_list; + for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) + { + //group data contents could change during creating new objects, so copy all contents first. + entry_list.push_back(*i); + } + + for(S32 i = 0; i < entry_list.size(); i++) + { + LLViewerOctreeEntry* entry = entry_list[i]; + if(entry && entry->hasVOCacheEntry()) + { + LLVOCacheEntry* vo_entry = (LLVOCacheEntry*)entry->getVOCacheEntry(); + if(vo_entry->isDummy()) + { + addVisibleCacheEntry(vo_entry); //for LLSpatialBridge. + } + else if(vo_entry->isState(LLVOCacheEntry::INACTIVE)) + { + addNewObject(vo_entry); + if(new_object_count-- < 0 && update_timer.getElapsedTimeF32() > max_update_time) + { + timeout = true; + break; + } + } + } + } + entry_list.clear(); + + if(timeout) + { + break; + } + mImpl->mVisibleGroups.erase(group); + group_iter = mImpl->mVisibleGroups.begin(); + } + mImpl->mVisibleGroups.clear(); + return did_update; } +void LLViewerRegion::killObject(LLVOCacheEntry* entry, std::vector& delete_list) +{ + //kill the object. + LLDrawable* drawablep = (LLDrawable*)entry->getEntry()->getDrawable(); + llassert(drawablep); + + if(!drawablep->getParent()) + { + LLViewerObject::const_child_list_t& child_list = drawablep->getVObj()->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); iter++) + { + LLViewerObject* child = *iter; + if(child->mDrawable->isRecentlyVisible()) + { + //set the parent group visible if any of its children visible. + drawablep->getSpatialGroup()->setVisible(); + return; + } + } + delete_list.push_back(drawablep); + } +} + +LLViewerObject* LLViewerRegion::addNewObject(LLVOCacheEntry* entry) +{ + LLViewerObject* obj = NULL; + if(!entry->getEntry()->hasDrawable()) //not added to the rendering pipeline yet + { + //add the object + obj = gObjectList.processObjectUpdateFromCache(entry, this); + if(obj) + { + if(!entry->isState(LLVOCacheEntry::ACTIVE)) + { + mImpl->mWaitingSet.insert(entry); + entry->setState(LLVOCacheEntry::WAITING); + } + } + } + else + { + llerrs << "Object is already created." << llendl; + } + return obj; +} // As above, but forcibly do the update. void LLViewerRegion::forceUpdate() @@ -1191,8 +1555,9 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObjec { U32 local_id = objectp->getLocalID(); U32 crc = objectp->getCRC(); + eCacheUpdateResult result; - LLVOCacheEntry* entry = get_if_there(mImpl->mCacheMap, local_id, (LLVOCacheEntry*)NULL); + LLVOCacheEntry* entry = getCacheEntry(local_id); if (entry) { @@ -1201,41 +1566,79 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObjec { // Record a hit entry->recordDupe(); - return CACHE_UPDATE_DUPE; + result = CACHE_UPDATE_DUPE; } + else + { + // Update the cache entry + LLPointer new_entry = new LLVOCacheEntry(local_id, crc, dp); + replaceCacheEntry(entry, new_entry); + entry = new_entry; - // Update the cache entry - mImpl->mCacheMap.erase(local_id); - delete entry; + result = CACHE_UPDATE_CHANGED; + } + } + else + { + // we haven't seen this object before + // Create new entry and add to map + result = CACHE_UPDATE_ADDED; + //if (mImpl->mCacheMap.size() > MAX_OBJECT_CACHE_ENTRIES) + //{ + // delete mImpl->mCacheMap.begin()->second ; + // mImpl->mCacheMap.erase(mImpl->mCacheMap.begin()); + // result = CACHE_UPDATE_REPLACED; + // + //} entry = new LLVOCacheEntry(local_id, crc, dp); + mImpl->mCacheMap[local_id] = entry; - return CACHE_UPDATE_CHANGED; } - // we haven't seen this object before - - // Create new entry and add to map - eCacheUpdateResult result = CACHE_UPDATE_ADDED; - if (mImpl->mCacheMap.size() > MAX_OBJECT_CACHE_ENTRIES) + if(objectp->mDrawable.notNull() && !entry->getEntry()) { - delete mImpl->mCacheMap.begin()->second ; - mImpl->mCacheMap.erase(mImpl->mCacheMap.begin()); - result = CACHE_UPDATE_REPLACED; - + entry->setOctreeEntry(objectp->mDrawable->getEntry()); + } + if(entry->getEntry() && entry->getEntry()->hasDrawable() && entry->isState(LLVOCacheEntry::INACTIVE)) + { + addActiveCacheEntry(entry); } - entry = new LLVOCacheEntry(local_id, crc, dp); - mImpl->mCacheMap[local_id] = entry; return result; } +LLVOCacheEntry* LLViewerRegion::getCacheEntryForOctree(U32 local_id) +{ + static BOOL vo_cache_culling_enabled = gSavedSettings.getBOOL("ObjectCacheViewCullingEnabled"); + + if(!vo_cache_culling_enabled) + { + return NULL; + } + + LLVOCacheEntry* entry = getCacheEntry(local_id); + removeFromVOCacheTree(entry); + + return entry; +} + +LLVOCacheEntry* LLViewerRegion::getCacheEntry(U32 local_id) +{ + LLVOCacheEntry::vocache_entry_map_t::iterator iter = mImpl->mCacheMap.find(local_id); + if(iter != mImpl->mCacheMap.end()) + { + return iter->second; + } + return NULL; +} + // Get data packer for this object, if we have cached data // AND the CRC matches. JC LLDataPacker *LLViewerRegion::getDP(U32 local_id, U32 crc, U8 &cache_miss_type) { //llassert(mCacheLoaded); This assert failes often, changing to early-out -- davep, 2010/10/18 - LLVOCacheEntry* entry = get_if_there(mImpl->mCacheMap, local_id, (LLVOCacheEntry*)NULL); + LLVOCacheEntry* entry = getCacheEntry(local_id); if (entry) { @@ -1244,20 +1647,21 @@ LLDataPacker *LLViewerRegion::getDP(U32 local_id, U32 crc, U8 &cache_miss_type) { // Record a hit entry->recordHit(); - cache_miss_type = CACHE_MISS_TYPE_NONE; + cache_miss_type = CACHE_MISS_TYPE_NONE; + return entry->getDP(crc); } else { // llinfos << "CRC miss for " << local_id << llendl; - cache_miss_type = CACHE_MISS_TYPE_CRC; + cache_miss_type = CACHE_MISS_TYPE_CRC; mCacheMissCRC.put(local_id); } } else { // llinfos << "Cache miss for " << local_id << llendl; - cache_miss_type = CACHE_MISS_TYPE_FULL; + cache_miss_type = CACHE_MISS_TYPE_FULL; mCacheMissFull.put(local_id); } -- cgit v1.2.3 From 9bc8028ab52ef5d56fa8a3915d927b5a050d8ead Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Tue, 16 Oct 2012 11:40:02 -0600 Subject: Some minor performance tuning-up for SH-3333. --- indra/newview/llviewerregion.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llviewerregion.cpp') diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 15c95aa30a..0c0522d32f 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1066,7 +1066,7 @@ void LLViewerRegion::killObject(LLVOCacheEntry* entry, std::vector& if(child->mDrawable->isRecentlyVisible()) { //set the parent group visible if any of its children visible. - drawablep->getSpatialGroup()->setVisible(); + ((LLViewerOctreeEntryData*)drawablep)->setVisible(); return; } } -- cgit v1.2.3 From 5ae116f89b8459963ccb6ae9125d94ffaa79025e Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Wed, 31 Oct 2012 17:05:53 -0600 Subject: for SH-3471: create a simplified version of octree for object cache entries. --- indra/newview/llviewerregion.cpp | 174 ++++++++++++++++++++++++++------------- 1 file changed, 118 insertions(+), 56 deletions(-) (limited to 'indra/newview/llviewerregion.cpp') diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 0c0522d32f..1adab15d70 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -86,6 +86,8 @@ const F32 CAP_REQUEST_TIMEOUT = 18; // Even though we gave up on login, keep trying for caps after we are logged in: const S32 MAX_CAP_REQUEST_ATTEMPTS = 30; +LLViewerRegion* LLViewerRegion::sCurRegionp = NULL; + typedef std::map CapabilityMap; class LLViewerRegionImpl { @@ -139,7 +141,7 @@ public: LLVOCacheEntry::vocache_entry_set_t mWaitingSet; //entries waiting for LLDrawable to be generated. LLVOCacheEntry::vocache_entry_set_t mVisibleEntries; //visible root entries of a linked set. std::set< LLPointer > mDummyEntries; //dummy vo cache entries, for LLSpatialBridge use. - std::set< LLSpatialGroup* > mVisibleGroups; //visible llspatialgroup + std::set< LLviewerOctreeGroup* > mVisibleGroups; //visible llspatialgroup LLVOCachePartition* mVOCachePartition; // time? @@ -165,7 +167,7 @@ public: LLCapabilityListener mCapabilityListener; //spatial partitions for objects in this region - std::vector mObjectPartition; + std::vector mObjectPartition; }; // support for secondlife:///app/region/{REGION} SLapps @@ -345,7 +347,7 @@ LLViewerRegion::LLViewerRegion(const U64 &handle, mImpl->mObjectPartition.push_back(new LLVOCachePartition(this)); //PARTITION_VO_CACHE mImpl->mObjectPartition.push_back(NULL); //PARTITION_NONE - mImpl->mVOCachePartition = (LLVOCachePartition*)getSpatialPartition(PARTITION_VO_CACHE); + mImpl->mVOCachePartition = getVOCachePartition(); } @@ -384,12 +386,12 @@ LLViewerRegion::~LLViewerRegion() delete mParcelOverlay; delete mImpl->mLandp; delete mImpl->mEventPoll; - LLHTTPSender::clearSender(mImpl->mHost); - - saveObjectCache(); + LLHTTPSender::clearSender(mImpl->mHost); std::for_each(mImpl->mObjectPartition.begin(), mImpl->mObjectPartition.end(), DeletePointer()); + saveObjectCache(); + delete mImpl; mImpl = NULL; } @@ -865,13 +867,13 @@ void LLViewerRegion::removeActiveCacheEntry(LLVOCacheEntry* entry, LLDrawable* d entry->setState(LLVOCacheEntry::INACTIVE); } -void LLViewerRegion::addVisibleGroup(LLSpatialGroup* group) +void LLViewerRegion::addVisibleGroup(LLviewerOctreeGroup* group) { - if(mDead || group->isEmpty() || group->isDead()) + if(mDead || group->isEmpty()) { return; } - + group->setVisible(); mImpl->mVisibleGroups.insert(group); } @@ -909,7 +911,7 @@ void LLViewerRegion::addVisibleCacheEntry(LLVOCacheEntry* entry) mImpl->mVisibleEntries.insert(entry); } -void LLViewerRegion::clearVisibleGroup(LLSpatialGroup* group) +void LLViewerRegion::clearVisibleGroup(LLviewerOctreeGroup* group) { if(mDead) { @@ -920,44 +922,18 @@ void LLViewerRegion::clearVisibleGroup(LLSpatialGroup* group) mImpl->mVisibleGroups.erase(group); } - -BOOL LLViewerRegion::idleUpdate(F32 max_update_time) -{ - LLTimer update_timer; - - // did_update returns TRUE if we did at least one significant update - BOOL did_update = mImpl->mLandp->idleUpdate(max_update_time); - if (mParcelOverlay) - { - // Hopefully not a significant time sink... - mParcelOverlay->idleUpdate(); - } - - if(update_timer.getElapsedTimeF32() > max_update_time) - { - return did_update; - } - - //kill invisible objects - std::vector delete_list; - for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mActiveSet.begin(); - iter != mImpl->mActiveSet.end(); ++iter) - { - if(!(*iter)->isRecentlyVisible()) - { - killObject((*iter), delete_list); - } - } - for(S32 i = 0; i < delete_list.size(); i++) +//return time left +F32 LLViewerRegion::addLinkedSetChildren(F32 max_time, S32& max_num_objects) +{ + if(mImpl->mVisibleEntries.empty()) { - gObjectList.killObject(delete_list[i]->getVObj()); + return max_time; } - delete_list.clear(); + LLTimer update_timer; bool timeout = false; - S32 new_object_count = 64; //minimum number of new objects to be added - //add childrens of visible objects to the rendering pipeline + for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mVisibleEntries.begin(); iter != mImpl->mVisibleEntries.end();) { LLVOCacheEntry* entry = *iter; @@ -968,9 +944,9 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time) { addNewObject(child); - if(new_object_count-- < 0 && update_timer.getElapsedTimeF32() > max_update_time) + if(max_num_objects-- < 0 && update_timer.getElapsedTimeF32() > max_time) { - timeout = true; + timeout = true; //timeout break; } } @@ -982,7 +958,10 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time) { mImpl->mDummyEntries.erase(entry); } - + } + + if(!timeout) + { iter = mImpl->mVisibleEntries.erase(iter); } else @@ -990,17 +969,28 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time) break; //timeout } } + if(timeout) { - mImpl->mVisibleGroups.clear(); - return did_update; + return -1.f; } + return max_time - update_timer.getElapsedTimeF32(); //time left +} - //add objects in the visible groups to the rendering pipeline - std::set< LLSpatialGroup* >::iterator group_iter = mImpl->mVisibleGroups.begin(); +F32 LLViewerRegion::addVisibleObjects(F32 max_time, S32& max_num_objects) +{ + if(mImpl->mVisibleGroups.empty()) + { + return max_time; + } + + LLTimer update_timer; + bool timeout = false; + + std::set< LLviewerOctreeGroup* >::iterator group_iter = mImpl->mVisibleGroups.begin(); while(group_iter != mImpl->mVisibleGroups.end()) { - LLSpatialGroup* group = *group_iter; + LLviewerOctreeGroup* group = *group_iter; if(!group->getOctreeNode() || group->isEmpty()) { mImpl->mVisibleGroups.erase(group_iter); @@ -1009,7 +999,7 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time) } std::vector entry_list; - for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) + for (LLviewerOctreeGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { //group data contents could change during creating new objects, so copy all contents first. entry_list.push_back(*i); @@ -1028,7 +1018,7 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time) else if(vo_entry->isState(LLVOCacheEntry::INACTIVE)) { addNewObject(vo_entry); - if(new_object_count-- < 0 && update_timer.getElapsedTimeF32() > max_update_time) + if(max_num_objects-- < 0 && update_timer.getElapsedTimeF32() > max_time) { timeout = true; break; @@ -1044,12 +1034,75 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time) } mImpl->mVisibleGroups.erase(group); group_iter = mImpl->mVisibleGroups.begin(); + } + + if(timeout) + { + return -1.0f; } - mImpl->mVisibleGroups.clear(); + return max_time - update_timer.getElapsedTimeF32(); +} + +BOOL LLViewerRegion::idleUpdate(F32 max_update_time) +{ + LLTimer update_timer; + // did_update returns TRUE if we did at least one significant update + BOOL did_update = mImpl->mLandp->idleUpdate(max_update_time); + + if (mParcelOverlay) + { + // Hopefully not a significant time sink... + mParcelOverlay->idleUpdate(); + } + + max_update_time -= update_timer.getElapsedTimeF32(); + if(max_update_time < 0.f) + { + return did_update; + } + + sCurRegionp = this; + + //kill invisible objects + max_update_time = killInvisibleObjects(max_update_time); + + S32 new_object_count = 64; //minimum number of new objects to be added + + //add childrens of visible objects to the rendering pipeline + max_update_time = addLinkedSetChildren(max_update_time, new_object_count); + + //add objects in the visible groups to the rendering pipeline + if(max_update_time > 0.f) + { + addVisibleObjects(max_update_time, new_object_count); + } + + mImpl->mVisibleGroups.clear(); + sCurRegionp = NULL; return did_update; } +F32 LLViewerRegion::killInvisibleObjects(F32 max_time) +{ + std::vector delete_list; + for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mActiveSet.begin(); + iter != mImpl->mActiveSet.end(); ++iter) + { + if(!(*iter)->isRecentlyVisible()) + { + killObject((*iter), delete_list); + } + } + for(S32 i = 0; i < delete_list.size(); i++) + { + gObjectList.killObject(delete_list[i]->getVObj()); + } + delete_list.clear(); + + return max_time; +} + void LLViewerRegion::killObject(LLVOCacheEntry* entry, std::vector& delete_list) { //kill the object. @@ -2189,9 +2242,18 @@ void LLViewerRegion::logActiveCapabilities() const LLSpatialPartition* LLViewerRegion::getSpatialPartition(U32 type) { - if (type < mImpl->mObjectPartition.size()) + if (type < mImpl->mObjectPartition.size() && type < PARTITION_VO_CACHE) + { + return (LLSpatialPartition*)mImpl->mObjectPartition[type]; + } + return NULL; +} + +LLVOCachePartition* LLViewerRegion::getVOCachePartition() +{ + if(PARTITION_VO_CACHE < mImpl->mObjectPartition.size()) { - return mImpl->mObjectPartition[type]; + return (LLVOCachePartition*)mImpl->mObjectPartition[PARTITION_VO_CACHE]; } return NULL; } -- cgit v1.2.3 From 819adb5eb4d7f982121f3dbd82750e05d26864d9 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 1 Nov 2012 00:26:44 -0700 Subject: SH-3405 FIX convert existing stats to lltrace system final removal of remaining LLStat code --- indra/newview/llviewerregion.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'indra/newview/llviewerregion.cpp') diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 31e3820a21..652e0ee70b 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -291,7 +291,9 @@ LLViewerRegion::LLViewerRegion(const U64 &handle, mCacheLoaded(FALSE), mCacheDirty(FALSE), mReleaseNotesRequested(FALSE), - mCapabilitiesReceived(false) + mCapabilitiesReceived(false), + mBitsReceived(0.f), + mPacketsReceived(0.f) { mWidth = region_width_meters; mImpl->mOriginGlobal = from_region_handle(handle); @@ -909,9 +911,8 @@ void LLViewerRegion::updateNetStats() mPacketsLost = cdp->getPacketsLost(); mPingDelay = cdp->getPingDelay(); - mBitStat.addValue(mBitsIn - mLastBitsIn); - mPacketsStat.addValue(mPacketsIn - mLastPacketsIn); - mPacketsLostStat.addValue(mPacketsLost); + mBitsReceived += mBitsIn - mLastBitsIn; + mPacketsReceived += mPacketsIn - mLastPacketsIn; } -- cgit v1.2.3 From c2859e4663c405950b6f433270ae558852330c76 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Thu, 8 Nov 2012 21:36:47 -0700 Subject: for SH-3472: prioritize object loading --- indra/newview/llviewerregion.cpp | 317 ++++++++++++++++++++++++--------------- 1 file changed, 197 insertions(+), 120 deletions(-) (limited to 'indra/newview/llviewerregion.cpp') diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 1adab15d70..24bd68825b 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -100,6 +100,8 @@ public: mSeedCapMaxAttemptsBeforeLogin(MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN), mSeedCapAttempts(0), mHttpResponderID(0), + mLastCameraUpdate(0), + mLastCameraOrigin(), // I'd prefer to set the LLCapabilityListener name to match the region // name -- it's disappointing that's not available at construction time. // We could instead store an LLCapabilityListener*, making @@ -136,13 +138,14 @@ public: // Misc LLVLComposition *mCompositionp; // Composition layer for the surface - LLVOCacheEntry::vocache_entry_map_t mCacheMap; //all cached entries - LLVOCacheEntry::vocache_entry_set_t mActiveSet; //all active entries; - LLVOCacheEntry::vocache_entry_set_t mWaitingSet; //entries waiting for LLDrawable to be generated. - LLVOCacheEntry::vocache_entry_set_t mVisibleEntries; //visible root entries of a linked set. + LLVOCacheEntry::vocache_entry_map_t mCacheMap; //all cached entries + LLVOCacheEntry::vocache_entry_set_t mActiveSet; //all active entries; + LLVOCacheEntry::vocache_entry_set_t mWaitingSet; //entries waiting for LLDrawable to be generated. std::set< LLPointer > mDummyEntries; //dummy vo cache entries, for LLSpatialBridge use. - std::set< LLviewerOctreeGroup* > mVisibleGroups; //visible llspatialgroup - LLVOCachePartition* mVOCachePartition; + std::set< LLviewerOctreeGroup* > mVisibleGroups; //visible groupa + LLVOCachePartition* mVOCachePartition; + LLVOCacheEntry::vocache_entry_set_t mVisibleEntries; //must-be-created visible entries wait for objects creation. + LLVOCacheEntry::vocache_entry_priority_list_t mWaitingList; //transient list storing sorted visible entries waiting for object creation. // time? // LRU info? @@ -168,6 +171,9 @@ public: //spatial partitions for objects in this region std::vector mObjectPartition; + + LLVector3 mLastCameraOrigin; + U32 mLastCameraUpdate; }; // support for secondlife:///app/region/{REGION} SLapps @@ -736,27 +742,16 @@ void LLViewerRegion::dirtyHeights() void LLViewerRegion::replaceCacheEntry(LLVOCacheEntry* old_entry, LLVOCacheEntry* new_entry) { - LLPointer oct_entry; U32 state = LLVOCacheEntry::INACTIVE; if(old_entry) { - oct_entry = old_entry->getEntry(); + new_entry->copy(old_entry); state = old_entry->getState(); - - while(old_entry->getNumOfChildren() > 0) - { - new_entry->addChild(old_entry->getNextChild()); - } - killCacheEntry(old_entry); } mImpl->mCacheMap[new_entry->getLocalID()] = new_entry; - if(oct_entry.notNull()) - { - new_entry->setOctreeEntry(oct_entry); - } if(state == LLVOCacheEntry::ACTIVE) { @@ -767,7 +762,7 @@ void LLViewerRegion::replaceCacheEntry(LLVOCacheEntry* old_entry, LLVOCacheEntry { mImpl->mWaitingSet.insert(new_entry); } - else if(old_entry && oct_entry) + else if(old_entry && new_entry->getEntry()) { addToVOCacheTree(new_entry); } @@ -790,19 +785,23 @@ void LLViewerRegion::killCacheEntry(LLVOCacheEntry* entry) else if(entry->isState(LLVOCacheEntry::WAITING)) { mImpl->mWaitingSet.erase(entry); - } - - //2, kill LLViewerObject if exists - //this should be done by the rendering pipeline automatically. - - //3, remove from mVOCachePartition - if(entry->isState(LLVOCacheEntry::INACTIVE) && entry->getEntry()) + } + else if(entry->isState(LLVOCacheEntry::IN_QUEUE)) { + mImpl->mVisibleEntries.erase(entry); + } + else if(entry->isState(LLVOCacheEntry::INACTIVE)) + { + //remove from mVOCachePartition removeFromVOCacheTree(entry); } + //kill LLViewerObject if exists + //this should be done by the rendering pipeline automatically. + entry->setState(LLVOCacheEntry::INACTIVE); - //4, remove from mCacheMap, real deletion + + //remove from mCacheMap, real deletion mImpl->mCacheMap.erase(entry->getLocalID()); } @@ -885,7 +884,10 @@ void LLViewerRegion::addToVOCacheTree(LLVOCacheEntry* entry) { return; } - llassert(!entry->getGroup()); + if(entry->getGroup()) //already in octree. + { + return; + } mImpl->mVOCachePartition->addEntry(entry->getEntry()); } @@ -896,18 +898,31 @@ void LLViewerRegion::removeFromVOCacheTree(LLVOCacheEntry* entry) { return; } + if(!entry->getGroup()) + { + return; + } mImpl->mVOCachePartition->removeEntry(entry->getEntry()); } -//add the visible root entry of a linked set +//add the visible entries void LLViewerRegion::addVisibleCacheEntry(LLVOCacheEntry* entry) { - if(mDead || !entry || !entry->getNumOfChildren()) + if(mDead || !entry) { - return; //no child entries + return; } + if(entry->isState(LLVOCacheEntry::IN_QUEUE)) + { + return; + } + + if(entry->isState(LLVOCacheEntry::INACTIVE)) + { + entry->setState(LLVOCacheEntry::IN_QUEUE); + } mImpl->mVisibleEntries.insert(entry); } @@ -922,124 +937,148 @@ void LLViewerRegion::clearVisibleGroup(LLviewerOctreeGroup* group) mImpl->mVisibleGroups.erase(group); } - -//return time left -F32 LLViewerRegion::addLinkedSetChildren(F32 max_time, S32& max_num_objects) + +F32 LLViewerRegion::updateVisibleEntries(F32 max_time) { - if(mImpl->mVisibleEntries.empty()) + if(mImpl->mVisibleGroups.empty() && mImpl->mVisibleEntries.empty()) { return max_time; } LLTimer update_timer; - bool timeout = false; + + const LLVector3 camera_origin = LLViewerCamera::getInstance()->getOrigin(); + const U32 cur_frame = LLViewerOctreeEntryData::getCurrentFrame(); + bool needs_update = ((cur_frame - mImpl->mLastCameraUpdate) > 5) && ((camera_origin - mImpl->mLastCameraOrigin).lengthSquared() > 10.f); + + //process visible entries + max_time *= 0.5f; //only use up to half available time to update entries. for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mVisibleEntries.begin(); iter != mImpl->mVisibleEntries.end();) { - LLVOCacheEntry* entry = *iter; - LLVOCacheEntry* child = entry->getNextChild(); - while(child != NULL) + LLVOCacheEntry* vo_entry = *iter; + vo_entry->calcSceneContribution(camera_origin, needs_update, mImpl->mLastCameraUpdate); + + if(vo_entry->getState() < LLVOCacheEntry::WAITING && !vo_entry->isDummy()) + { + 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++) { - if(child->isState(LLVOCacheEntry::INACTIVE)) + child = vo_entry->getChild(i); + if(child->getState() < LLVOCacheEntry::WAITING) { - addNewObject(child); - - if(max_num_objects-- < 0 && update_timer.getElapsedTimeF32() > max_time) - { - timeout = true; //timeout - break; - } + child->setSceneContribution(vo_entry->getSceneContribution()); + mImpl->mWaitingList.insert(child); } - child = entry->getNextChild(); - } - if(!child) - { - if(entry->isDummy()) + else { - mImpl->mDummyEntries.erase(entry); + num_done++; } } - - if(!timeout) + if(num_done == num_child) { - iter = mImpl->mVisibleEntries.erase(iter); + vo_entry->clearChildrenList(); + } + + if(!vo_entry->getNumOfChildren()) + { + if(vo_entry->isDummy()) + { + mImpl->mDummyEntries.erase(vo_entry); + iter = mImpl->mVisibleEntries.erase(iter); + } + else if(vo_entry->getState() >= LLVOCacheEntry::WAITING) + { + iter = mImpl->mVisibleEntries.erase(iter); + } + else + { + ++iter; + } } else { - break; //timeout + ++iter; } - } - if(timeout) - { - return -1.f; - } - return max_time - update_timer.getElapsedTimeF32(); //time left -} - -F32 LLViewerRegion::addVisibleObjects(F32 max_time, S32& max_num_objects) -{ - if(mImpl->mVisibleGroups.empty()) - { - return max_time; + //if(update_timer.getElapsedTimeF32() > max_time) + //{ + // break; + //} } - LLTimer update_timer; - bool timeout = false; - + //process visible groups std::set< LLviewerOctreeGroup* >::iterator group_iter = mImpl->mVisibleGroups.begin(); - while(group_iter != mImpl->mVisibleGroups.end()) + for(; group_iter != mImpl->mVisibleGroups.end(); ++group_iter) { LLviewerOctreeGroup* group = *group_iter; if(!group->getOctreeNode() || group->isEmpty()) { - mImpl->mVisibleGroups.erase(group_iter); - group_iter = mImpl->mVisibleGroups.begin(); continue; } - std::vector entry_list; for (LLviewerOctreeGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { - //group data contents could change during creating new objects, so copy all contents first. - entry_list.push_back(*i); - } - - for(S32 i = 0; i < entry_list.size(); i++) - { - LLViewerOctreeEntry* entry = entry_list[i]; - if(entry && entry->hasVOCacheEntry()) + if((*i)->hasVOCacheEntry()) { - LLVOCacheEntry* vo_entry = (LLVOCacheEntry*)entry->getVOCacheEntry(); + LLVOCacheEntry* vo_entry = (LLVOCacheEntry*)(*i)->getVOCacheEntry(); if(vo_entry->isDummy()) { addVisibleCacheEntry(vo_entry); //for LLSpatialBridge. + continue; } - else if(vo_entry->isState(LLVOCacheEntry::INACTIVE)) - { - addNewObject(vo_entry); - if(max_num_objects-- < 0 && update_timer.getElapsedTimeF32() > max_time) - { - timeout = true; - break; - } - } + + vo_entry->calcSceneContribution(camera_origin, needs_update, mImpl->mLastCameraUpdate); + mImpl->mWaitingList.insert(vo_entry); } } - entry_list.clear(); - if(timeout) - { - break; - } - mImpl->mVisibleGroups.erase(group); - group_iter = mImpl->mVisibleGroups.begin(); - } + //if(update_timer.getElapsedTimeF32() > max_time) + //{ + // break; + //} + } + mImpl->mVisibleGroups.clear(); + + if(needs_update) + { + mImpl->mLastCameraOrigin = camera_origin; + mImpl->mLastCameraUpdate = cur_frame; + } + + return 2.0f * max_time - update_timer.getElapsedTimeF32(); +} + +F32 LLViewerRegion::createVisibleObjects(F32 max_time) +{ + if(mImpl->mWaitingList.empty()) + { + return max_time; + } - if(timeout) + LLTimer update_timer; + S32 max_num_objects = 64; //minimum number of new objects to be added + for(LLVOCacheEntry::vocache_entry_priority_list_t::iterator iter = mImpl->mWaitingList.begin(); + iter != mImpl->mWaitingList.end(); ++iter) { - return -1.0f; + LLVOCacheEntry* vo_entry = *iter; + + if(vo_entry->getState() < LLVOCacheEntry::WAITING) + { + addNewObject(vo_entry); + if(max_num_objects-- < 0 && update_timer.getElapsedTimeF32() > max_time) + { + break; + } + } } + mImpl->mWaitingList.clear(); + return max_time - update_timer.getElapsedTimeF32(); } @@ -1057,7 +1096,7 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time) } max_update_time -= update_timer.getElapsedTimeF32(); - if(max_update_time < 0.f) + if(max_update_time < 0.f || mImpl->mCacheMap.empty()) { return did_update; } @@ -1065,20 +1104,14 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time) sCurRegionp = this; //kill invisible objects - max_update_time = killInvisibleObjects(max_update_time); - - S32 new_object_count = 64; //minimum number of new objects to be added + max_update_time = killInvisibleObjects(max_update_time); - //add childrens of visible objects to the rendering pipeline - max_update_time = addLinkedSetChildren(max_update_time, new_object_count); - - //add objects in the visible groups to the rendering pipeline - if(max_update_time > 0.f) - { - addVisibleObjects(max_update_time, new_object_count); - } + max_update_time = updateVisibleEntries(max_update_time); + createVisibleObjects(max_update_time); mImpl->mVisibleGroups.clear(); + mImpl->mWaitingList.clear(); + sCurRegionp = NULL; return did_update; } @@ -1687,7 +1720,7 @@ LLVOCacheEntry* LLViewerRegion::getCacheEntry(U32 local_id) // Get data packer for this object, if we have cached data // AND the CRC matches. JC -LLDataPacker *LLViewerRegion::getDP(U32 local_id, U32 crc, U8 &cache_miss_type) +bool LLViewerRegion::probeCache(U32 local_id, U32 crc, U8 &cache_miss_type) { //llassert(mCacheLoaded); This assert failes often, changing to early-out -- davep, 2010/10/18 @@ -1702,7 +1735,51 @@ LLDataPacker *LLViewerRegion::getDP(U32 local_id, U32 crc, U8 &cache_miss_type) entry->recordHit(); cache_miss_type = CACHE_MISS_TYPE_NONE; - return entry->getDP(crc); + if(entry->getGroup() || !entry->isState(LLVOCacheEntry::INACTIVE)) + { + return true; + } + + addVisibleCacheEntry(entry); +#if 0 + if(entry->isBridgeChild()) //bridge child + { + addVisibleCacheEntry(entry); + } + else + { + U32 parent_id = entry->getParentID(); + if(parent_id > 0) //has parent + { + LLVOCacheEntry* parent = getCacheEntry(parent_id); + + if(parent) //parent cached + { + parent->addChild(entry); + + if(parent->isState(LLVOCacheEntry::INACTIVE)) + { + //addToVOCacheTree(parent); + addVisibleCacheEntry(parent); + } + else //parent visible + { + addVisibleCacheEntry(parent); + } + } + else //parent not cached. This should not happen, but just in case... + { + addVisibleCacheEntry(entry); + } + } + else //root node + { + //addToVOCacheTree(entry); + addVisibleCacheEntry(entry); + } + } +#endif + return true; } else { @@ -1718,7 +1795,7 @@ LLDataPacker *LLViewerRegion::getDP(U32 local_id, U32 crc, U8 &cache_miss_type) mCacheMissFull.put(local_id); } - return NULL; + return false; } void LLViewerRegion::addCacheMissFull(const U32 local_id) -- cgit v1.2.3 From 551411247b8e4701e4768f61717b644750af83a7 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Tue, 20 Nov 2012 21:37:04 -0700 Subject: fix a crash caused by object cache for SH-3333. --- indra/newview/llviewerregion.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llviewerregion.cpp') diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 24bd68825b..e275b44e92 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -746,7 +746,7 @@ void LLViewerRegion::replaceCacheEntry(LLVOCacheEntry* old_entry, LLVOCacheEntry if(old_entry) { - new_entry->copy(old_entry); + old_entry->copyTo(new_entry); state = old_entry->getState(); killCacheEntry(old_entry); } -- cgit v1.2.3 From f2bf13b87768c97ec6a36a183013413bf4b905f0 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Wed, 12 Dec 2012 11:00:24 -0700 Subject: fix for SH-3622: crash on LLViewerRegion::updateVisibleEntries --- indra/newview/llviewerregion.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'indra/newview/llviewerregion.cpp') diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index e275b44e92..ab692308b0 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -777,25 +777,25 @@ void LLViewerRegion::killCacheEntry(LLVOCacheEntry* entry) return; } - //1, remove from active list and waiting list + //remove from active list and waiting list if(entry->isState(LLVOCacheEntry::ACTIVE)) { mImpl->mActiveSet.erase(entry); } - else if(entry->isState(LLVOCacheEntry::WAITING)) - { - mImpl->mWaitingSet.erase(entry); - } - else if(entry->isState(LLVOCacheEntry::IN_QUEUE)) - { - mImpl->mVisibleEntries.erase(entry); - } - else if(entry->isState(LLVOCacheEntry::INACTIVE)) + else { + if(entry->isState(LLVOCacheEntry::WAITING)) + { + mImpl->mWaitingSet.erase(entry); + } + //remove from mVOCachePartition removeFromVOCacheTree(entry); } + //remove from the forced visible list + mImpl->mVisibleEntries.erase(entry); + //kill LLViewerObject if exists //this should be done by the rendering pipeline automatically. -- cgit v1.2.3 From e1247d631f24065a31d9668915cb8bc84f3abc7f Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Tue, 18 Dec 2012 14:36:46 -0700 Subject: fix for SH-3619: some objects are missing --- indra/newview/llviewerregion.cpp | 98 ++++++++++++---------------------------- 1 file changed, 28 insertions(+), 70 deletions(-) (limited to 'indra/newview/llviewerregion.cpp') diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index ab692308b0..33e8348660 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -87,6 +87,7 @@ const F32 CAP_REQUEST_TIMEOUT = 18; const S32 MAX_CAP_REQUEST_ATTEMPTS = 30; LLViewerRegion* LLViewerRegion::sCurRegionp = NULL; +BOOL LLViewerRegion::sVOCacheCullingEnabled = FALSE; typedef std::map CapabilityMap; @@ -141,7 +142,6 @@ public: LLVOCacheEntry::vocache_entry_map_t mCacheMap; //all cached entries LLVOCacheEntry::vocache_entry_set_t mActiveSet; //all active entries; LLVOCacheEntry::vocache_entry_set_t mWaitingSet; //entries waiting for LLDrawable to be generated. - std::set< LLPointer > mDummyEntries; //dummy vo cache entries, for LLSpatialBridge use. std::set< LLviewerOctreeGroup* > mVisibleGroups; //visible groupa LLVOCachePartition* mVOCachePartition; LLVOCacheEntry::vocache_entry_set_t mVisibleEntries; //must-be-created visible entries wait for objects creation. @@ -841,17 +841,8 @@ void LLViewerRegion::removeActiveCacheEntry(LLVOCacheEntry* entry, LLDrawable* d { return; } - if(entry->isDummy()) - { - mImpl->mDummyEntries.insert(entry); //keep a copy to prevent from being deleted. - addToVOCacheTree(entry); - } - else if(!drawablep->getParent()) //root node - { - addToVOCacheTree(entry); - mImpl->mVisibleEntries.erase(entry); - } - else //child node + + if(drawablep->getParent()) //child object { LLViewerOctreeEntry* parent_oct_entry = drawablep->getParent()->getEntry(); if(parent_oct_entry && parent_oct_entry->hasVOCacheEntry()) @@ -860,7 +851,19 @@ void LLViewerRegion::removeActiveCacheEntry(LLVOCacheEntry* entry, LLDrawable* d parent->addChild(entry); } } + else //insert to vo cache tree. + { + //shift to the local regional space from agent space + const LLVector3 pos = drawablep->getVObj()->getPositionRegion(); + LLVector4a vec(pos[0], pos[1], pos[2]); + LLVector4a shift; + shift.setSub(vec, entry->getPositionGroup()); + entry->shift(shift); + + addToVOCacheTree(entry); + } + mImpl->mVisibleEntries.erase(entry); mImpl->mActiveSet.erase(entry); mImpl->mWaitingSet.erase(entry); entry->setState(LLVOCacheEntry::INACTIVE); @@ -878,7 +881,10 @@ void LLViewerRegion::addVisibleGroup(LLviewerOctreeGroup* group) void LLViewerRegion::addToVOCacheTree(LLVOCacheEntry* entry) { - static BOOL vo_cache_culling_enabled = gSavedSettings.getBOOL("ObjectCacheViewCullingEnabled"); + if(!sVOCacheCullingEnabled) + { + return; + } if(mDead || !entry || !entry->getEntry()) { @@ -954,12 +960,13 @@ F32 LLViewerRegion::updateVisibleEntries(F32 max_time) //process visible entries max_time *= 0.5f; //only use up to half available time to update entries. +#if 1 for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mVisibleEntries.begin(); iter != mImpl->mVisibleEntries.end();) { LLVOCacheEntry* vo_entry = *iter; vo_entry->calcSceneContribution(camera_origin, needs_update, mImpl->mLastCameraUpdate); - if(vo_entry->getState() < LLVOCacheEntry::WAITING && !vo_entry->isDummy()) + if(vo_entry->getState() < LLVOCacheEntry::WAITING) { mImpl->mWaitingList.insert(vo_entry); } @@ -987,12 +994,7 @@ F32 LLViewerRegion::updateVisibleEntries(F32 max_time) if(!vo_entry->getNumOfChildren()) { - if(vo_entry->isDummy()) - { - mImpl->mDummyEntries.erase(vo_entry); - iter = mImpl->mVisibleEntries.erase(iter); - } - else if(vo_entry->getState() >= LLVOCacheEntry::WAITING) + if(vo_entry->getState() >= LLVOCacheEntry::WAITING) { iter = mImpl->mVisibleEntries.erase(iter); } @@ -1011,6 +1013,7 @@ F32 LLViewerRegion::updateVisibleEntries(F32 max_time) // break; //} } +#endif //process visible groups std::set< LLviewerOctreeGroup* >::iterator group_iter = mImpl->mVisibleGroups.begin(); @@ -1027,11 +1030,6 @@ F32 LLViewerRegion::updateVisibleEntries(F32 max_time) if((*i)->hasVOCacheEntry()) { LLVOCacheEntry* vo_entry = (LLVOCacheEntry*)(*i)->getVOCacheEntry(); - if(vo_entry->isDummy()) - { - addVisibleCacheEntry(vo_entry); //for LLSpatialBridge. - continue; - } vo_entry->calcSceneContribution(camera_origin, needs_update, mImpl->mLastCameraUpdate); mImpl->mWaitingList.insert(vo_entry); @@ -1118,6 +1116,11 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time) F32 LLViewerRegion::killInvisibleObjects(F32 max_time) { + if(!sVOCacheCullingEnabled) + { + return max_time; + } + std::vector delete_list; for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mActiveSet.begin(); iter != mImpl->mActiveSet.end(); ++iter) @@ -1695,13 +1698,6 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObjec LLVOCacheEntry* LLViewerRegion::getCacheEntryForOctree(U32 local_id) { - static BOOL vo_cache_culling_enabled = gSavedSettings.getBOOL("ObjectCacheViewCullingEnabled"); - - if(!vo_cache_culling_enabled) - { - return NULL; - } - LLVOCacheEntry* entry = getCacheEntry(local_id); removeFromVOCacheTree(entry); @@ -1741,44 +1737,6 @@ bool LLViewerRegion::probeCache(U32 local_id, U32 crc, U8 &cache_miss_type) } addVisibleCacheEntry(entry); -#if 0 - if(entry->isBridgeChild()) //bridge child - { - addVisibleCacheEntry(entry); - } - else - { - U32 parent_id = entry->getParentID(); - if(parent_id > 0) //has parent - { - LLVOCacheEntry* parent = getCacheEntry(parent_id); - - if(parent) //parent cached - { - parent->addChild(entry); - - if(parent->isState(LLVOCacheEntry::INACTIVE)) - { - //addToVOCacheTree(parent); - addVisibleCacheEntry(parent); - } - else //parent visible - { - addVisibleCacheEntry(parent); - } - } - else //parent not cached. This should not happen, but just in case... - { - addVisibleCacheEntry(entry); - } - } - else //root node - { - //addToVOCacheTree(entry); - addVisibleCacheEntry(entry); - } - } -#endif return true; } else -- cgit v1.2.3 From 4e22f3e3ef15e24d7e9e0ad156e60d4cd1b2d5c9 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Tue, 18 Dec 2012 23:16:50 -0700 Subject: fix for SH-3624: Object deletion does not work --- indra/newview/llviewerregion.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'indra/newview/llviewerregion.cpp') diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 33e8348660..c4b6cacae2 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -894,6 +894,10 @@ void LLViewerRegion::addToVOCacheTree(LLVOCacheEntry* entry) { return; } + if(!entry->hasState(LLVOCacheEntry::ADD_TO_CACHE_TREE)) + { + return; //can not add to vo cache tree. + } mImpl->mVOCachePartition->addEntry(entry->getEntry()); } @@ -1132,7 +1136,7 @@ F32 LLViewerRegion::killInvisibleObjects(F32 max_time) } for(S32 i = 0; i < delete_list.size(); i++) { - gObjectList.killObject(delete_list[i]->getVObj()); + gObjectList.killObject(delete_list[i]->getVObj(), true); } delete_list.clear(); -- cgit v1.2.3 From 6272ca1ad82fd9818a1dd937a890ed982f0bdc4a Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 11 Jan 2013 16:52:43 -0800 Subject: SH-3405 WIP convert existing stats to lltrace system more gcc fixes --- indra/newview/llviewerregion.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'indra/newview/llviewerregion.cpp') diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 7d2e08c1c6..570bf9264c 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1001,7 +1001,10 @@ F32 LLViewerRegion::updateVisibleEntries(F32 max_time) { if(vo_entry->getState() >= LLVOCacheEntry::WAITING) { - iter = mImpl->mVisibleEntries.erase(iter); + LLVOCacheEntry::vocache_entry_set_t::iterator next_iter = iter; + ++next_iter; + mImpl->mVisibleEntries.erase(iter); + iter = next_iter; } else { -- cgit v1.2.3 From 45a7fe901aa4cd7af14fa1cb894da46a988e3aa2 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Tue, 15 Jan 2013 23:01:40 -0700 Subject: for SH-3653: Can we repurpose ObjectUpdateCached:ObjectData:UpdateFlags field to carry spatial+size data? --- indra/newview/llviewerregion.cpp | 81 +++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 46 deletions(-) (limited to 'indra/newview/llviewerregion.cpp') diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 7d2e08c1c6..f44c8ffe46 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1718,9 +1718,26 @@ LLVOCacheEntry* LLViewerRegion::getCacheEntry(U32 local_id) return NULL; } +//estimate weight of cache missed object +F32 LLViewerRegion::calcObjectWeight(U32 flags) +{ + LLVector3 pos((F32)(flags & 0xff), (F32)((flags >> 8) & 0xff), (F32)((flags >> 16) & 0xff) * 16.f); + F32 rad = (F32)((flags >> 24) & 0xff); + + pos += getOriginAgent(); + pos -= LLViewerCamera::getInstance()->getOrigin(); + + return rad * rad / pos.lengthSquared(); +} + +void LLViewerRegion::addCacheMiss(U32 id, LLViewerRegion::eCacheMissType miss_type, F32 weight) +{ + mCacheMissList.insert(CacheMissItem(id, miss_type, weight)); +} + // Get data packer for this object, if we have cached data // AND the CRC matches. JC -bool LLViewerRegion::probeCache(U32 local_id, U32 crc, U8 &cache_miss_type) +bool LLViewerRegion::probeCache(U32 local_id, U32 crc, U32 flags, U8 &cache_miss_type) { //llassert(mCacheLoaded); This assert failes often, changing to early-out -- davep, 2010/10/18 @@ -1746,15 +1763,14 @@ bool LLViewerRegion::probeCache(U32 local_id, U32 crc, U8 &cache_miss_type) else { // llinfos << "CRC miss for " << local_id << llendl; - cache_miss_type = CACHE_MISS_TYPE_CRC; - mCacheMissCRC.put(local_id); + + addCacheMiss(local_id, CACHE_MISS_TYPE_CRC, calcObjectWeight(flags)); } } else { // llinfos << "Cache miss for " << local_id << llendl; - cache_miss_type = CACHE_MISS_TYPE_FULL; - mCacheMissFull.put(local_id); + addCacheMiss(local_id, CACHE_MISS_TYPE_FULL, calcObjectWeight(flags)); } return false; @@ -1762,49 +1778,22 @@ bool LLViewerRegion::probeCache(U32 local_id, U32 crc, U8 &cache_miss_type) void LLViewerRegion::addCacheMissFull(const U32 local_id) { - mCacheMissFull.put(local_id); + addCacheMiss(local_id, CACHE_MISS_TYPE_FULL, 100.f); } void LLViewerRegion::requestCacheMisses() { - S32 full_count = mCacheMissFull.count(); - S32 crc_count = mCacheMissCRC.count(); - if (full_count == 0 && crc_count == 0) return; + if (!mCacheMissList.size()) + { + return; + } LLMessageSystem* msg = gMessageSystem; BOOL start_new_message = TRUE; S32 blocks = 0; - S32 i; - - // Send full cache miss updates. For these, we KNOW we don't - // have a viewer object. - for (i = 0; i < full_count; i++) - { - if (start_new_message) - { - msg->newMessageFast(_PREHASH_RequestMultipleObjects); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - start_new_message = FALSE; - } - - msg->nextBlockFast(_PREHASH_ObjectData); - msg->addU8Fast(_PREHASH_CacheMissType, CACHE_MISS_TYPE_FULL); - msg->addU32Fast(_PREHASH_ID, mCacheMissFull[i]); - blocks++; - - if (blocks >= 255) - { - sendReliableMessage(); - start_new_message = TRUE; - blocks = 0; - } - } - - // Send CRC miss updates. For these, we _might_ have a viewer object, - // but probably not. - for (i = 0; i < crc_count; i++) + + //send requests for all cache-missed objects + for (CacheMissItem::cache_miss_list_t::iterator iter = mCacheMissList.begin(); iter != mCacheMissList.end(); ++iter) { if (start_new_message) { @@ -1816,8 +1805,8 @@ void LLViewerRegion::requestCacheMisses() } msg->nextBlockFast(_PREHASH_ObjectData); - msg->addU8Fast(_PREHASH_CacheMissType, CACHE_MISS_TYPE_CRC); - msg->addU32Fast(_PREHASH_ID, mCacheMissCRC[i]); + msg->addU8Fast(_PREHASH_CacheMissType, (*iter).mType); + msg->addU32Fast(_PREHASH_ID, (*iter).mID); blocks++; if (blocks >= 255) @@ -1832,14 +1821,14 @@ void LLViewerRegion::requestCacheMisses() if (!start_new_message) { sendReliableMessage(); - } - mCacheMissFull.reset(); - mCacheMissCRC.reset(); + } mCacheDirty = TRUE ; // llinfos << "KILLDEBUG Sent cache miss full " << full_count << " crc " << crc_count << llendl; - LLViewerStatsRecorder::instance().requestCacheMissesEvent(full_count + crc_count); + LLViewerStatsRecorder::instance().requestCacheMissesEvent(mCacheMissList.size()); LLViewerStatsRecorder::instance().log(0.2f); + + mCacheMissList.clear(); } void LLViewerRegion::dumpCache() -- cgit v1.2.3 From 3660f8b632d1288cefeeff66c3b62522b4bbacbc Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Thu, 24 Jan 2013 17:11:33 -0700 Subject: more for SH-3653: Can we repurpose ObjectUpdateCached:ObjectData:UpdateFlags field to carry spatial+size data? --- indra/newview/llviewerregion.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/newview/llviewerregion.cpp') diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 45d43bdf74..e5cb2a1b08 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1724,13 +1724,13 @@ LLVOCacheEntry* LLViewerRegion::getCacheEntry(U32 local_id) //estimate weight of cache missed object F32 LLViewerRegion::calcObjectWeight(U32 flags) { - LLVector3 pos((F32)(flags & 0xff), (F32)((flags >> 8) & 0xff), (F32)((flags >> 16) & 0xff) * 16.f); + LLVector3 pos((F32)(flags & 0xff) + 0.5f, (F32)((flags >> 8) & 0xff) + 0.5f, (F32)((flags >> 16) & 0xff) * 16.f + 8.0f); F32 rad = (F32)((flags >> 24) & 0xff); pos += getOriginAgent(); pos -= LLViewerCamera::getInstance()->getOrigin(); - return rad * rad / pos.lengthSquared(); + return 100.f * rad * rad / pos.lengthSquared(); } void LLViewerRegion::addCacheMiss(U32 id, LLViewerRegion::eCacheMissType miss_type, F32 weight) -- cgit v1.2.3 From bd60fdbe44d9f996686d31cf48a3f2ca664dd301 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Thu, 28 Feb 2013 22:49:05 -0700 Subject: for SH-3824: interesting: Ensure viewer can handle object updates from entire region gracefully --- indra/newview/llviewerregion.cpp | 134 +++++++++++++++++++++++++++++++++------ 1 file changed, 114 insertions(+), 20 deletions(-) (limited to 'indra/newview/llviewerregion.cpp') diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index e5cb2a1b08..040b39bc43 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -880,7 +880,7 @@ void LLViewerRegion::addVisibleGroup(LLviewerOctreeGroup* group) mImpl->mVisibleGroups.insert(group); } -void LLViewerRegion::addToVOCacheTree(LLVOCacheEntry* entry) +void LLViewerRegion::addToVOCacheTree(LLVOCacheEntry* entry, bool forced) { if(!sVOCacheCullingEnabled) { @@ -895,7 +895,7 @@ void LLViewerRegion::addToVOCacheTree(LLVOCacheEntry* entry) { return; } - if(!entry->hasState(LLVOCacheEntry::ADD_TO_CACHE_TREE)) + if(!forced && !entry->hasState(LLVOCacheEntry::ADD_TO_CACHE_TREE)) { return; //can not add to vo cache tree. } @@ -1647,14 +1647,91 @@ void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features) mSimulatorFeatures = sim_features; } -LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp) +void LLViewerRegion::postProcesNewEntry(LLVOCacheEntry* entry) +{ + if(entry != NULL && !entry->getEntry()) + { + entry->setOctreeEntry(NULL); + } + else + { + return; //not new entry, no post processing. + } + + LLVector3 pos; + LLVector3 scale; + LLQuaternion rot; + U32 parent_id = LLViewerObject::extractSpatialExtents(entry->getDP(), pos, scale, rot); + + entry->setBoundingInfo(pos, scale); + + if(parent_id > 0) //has parent + { + //1, find parent, update position + LLVOCacheEntry* parent = getCacheEntry(parent_id); + + //2, if can not, put into the orphan lists: a parents list and a children list + if(!parent) + { + std::map::iterator iter = mOrphanMap.find(parent_id); + if(iter != mOrphanMap.end()) + { + iter->second.addChild(entry->getLocalID()); + } + else + { + OrphanList o_list(entry->getLocalID()); + mOrphanMap[parent_id] = o_list; + } + + return; + } + else + { + entry->updateBoundingInfo(parent); + } + } + + if(!entry->getGroup() && entry->isState(LLVOCacheEntry::INACTIVE)) + { + addToVOCacheTree(entry, true); + } + + if(!parent_id) //a potential parent + { + //find all children and update their bounding info + std::map::iterator iter = mOrphanMap.find(entry->getLocalID()); + if(iter != mOrphanMap.end()) + { + std::set* children = mOrphanMap[parent_id].getChildList(); + for(std::set::iterator child_iter = children->begin(); child_iter != children->end(); ++child_iter) + { + LLVOCacheEntry* child = getCacheEntry(*child_iter); + if(child) + { + child->updateBoundingInfo(entry); + addToVOCacheTree(child); + } + } + + mOrphanMap.erase(entry->getLocalID()); + } + } + + return ; +} + +LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLDataPackerBinaryBuffer &dp) { - U32 local_id = objectp->getLocalID(); - U32 crc = objectp->getCRC(); eCacheUpdateResult result; + U32 crc; + U32 local_id; - LLVOCacheEntry* entry = getCacheEntry(local_id); + LLViewerObject::unpackU32(&dp, local_id, "LocalID"); + LLViewerObject::unpackU32(&dp, crc, "CRC"); + LLVOCacheEntry* entry = getCacheEntry(local_id); + if (entry) { // we've seen this object before @@ -1668,9 +1745,22 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObjec { // Update the cache entry LLPointer new_entry = new LLVOCacheEntry(local_id, crc, dp); - replaceCacheEntry(entry, new_entry); - entry = new_entry; - + + //if visible, update it + if(!entry->isState(LLVOCacheEntry::INACTIVE)) + { + replaceCacheEntry(entry, new_entry); + } + else //invisible + { + //remove old entry + killCacheEntry(entry); + entry = new_entry; + + mImpl->mCacheMap[local_id] = entry; + postProcesNewEntry(entry); + } + result = CACHE_UPDATE_CHANGED; } } @@ -1679,17 +1769,21 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObjec // we haven't seen this object before // Create new entry and add to map result = CACHE_UPDATE_ADDED; - //if (mImpl->mCacheMap.size() > MAX_OBJECT_CACHE_ENTRIES) - //{ - // delete mImpl->mCacheMap.begin()->second ; - // mImpl->mCacheMap.erase(mImpl->mCacheMap.begin()); - // result = CACHE_UPDATE_REPLACED; - // - //} entry = new LLVOCacheEntry(local_id, crc, dp); - + mImpl->mCacheMap[local_id] = entry; + + postProcesNewEntry(entry); } + + return result; +} + +LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp) +{ + eCacheUpdateResult result = cacheFullUpdate(dp); + + LLVOCacheEntry* entry = mImpl->mCacheMap[objectp->getLocalID()]; if(objectp->mDrawable.notNull() && !entry->getEntry()) { @@ -1754,13 +1848,13 @@ bool LLViewerRegion::probeCache(U32 local_id, U32 crc, U32 flags, U8 &cache_miss // Record a hit entry->recordHit(); cache_miss_type = CACHE_MISS_TYPE_NONE; - + if(entry->getGroup() || !entry->isState(LLVOCacheEntry::INACTIVE)) { return true; } - - addVisibleCacheEntry(entry); + //addVisibleCacheEntry(entry); + addToVOCacheTree(entry, true); return true; } else -- cgit v1.2.3 From 03b7fb589a9b5628418364c970ea402448f312be Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Mon, 4 Mar 2013 11:48:07 -0700 Subject: trivial: convert to unix line endings. --- indra/newview/llviewerregion.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/newview/llviewerregion.cpp') diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 040b39bc43..b287e0da9c 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1692,8 +1692,8 @@ void LLViewerRegion::postProcesNewEntry(LLVOCacheEntry* entry) } } - if(!entry->getGroup() && entry->isState(LLVOCacheEntry::INACTIVE)) - { + if(!entry->getGroup() && entry->isState(LLVOCacheEntry::INACTIVE)) + { addToVOCacheTree(entry, true); } -- cgit v1.2.3 From 50b32cf2bdb93fad14770aa0f6b92fb3815ebdf0 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Thu, 7 Mar 2013 23:54:11 -0700 Subject: for SH-3937: interesting: implement the new cache probe logic --- indra/newview/llviewerregion.cpp | 116 ++++++++++++++++++++++++++++++++------- 1 file changed, 97 insertions(+), 19 deletions(-) (limited to 'indra/newview/llviewerregion.cpp') diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index b287e0da9c..704b3b644f 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -460,7 +460,11 @@ void LLViewerRegion::saveObjectCache() if(LLVOCache::hasInstance()) { - LLVOCache::getInstance()->writeToCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap, mCacheDirty) ; + //NOTE: !!!!!!!!!! + //set this to be true when support full region cache probe!!!! + BOOL full_region_cache_probe = FALSE; + + LLVOCache::getInstance()->writeToCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap, mCacheDirty, full_region_cache_probe) ; mCacheDirty = FALSE; } @@ -744,11 +748,13 @@ void LLViewerRegion::dirtyHeights() void LLViewerRegion::replaceCacheEntry(LLVOCacheEntry* old_entry, LLVOCacheEntry* new_entry) { U32 state = LLVOCacheEntry::INACTIVE; + bool in_vo_tree = false; if(old_entry) { old_entry->copyTo(new_entry); - state = old_entry->getState(); + state = old_entry->getState(); + in_vo_tree = (state == LLVOCacheEntry::INACTIVE && old_entry->getGroup() != NULL); killCacheEntry(old_entry); } @@ -763,7 +769,7 @@ void LLViewerRegion::replaceCacheEntry(LLVOCacheEntry* old_entry, LLVOCacheEntry { mImpl->mWaitingSet.insert(new_entry); } - else if(old_entry && new_entry->getEntry()) + else if(!old_entry || in_vo_tree) { addToVOCacheTree(new_entry); } @@ -880,7 +886,7 @@ void LLViewerRegion::addVisibleGroup(LLviewerOctreeGroup* group) mImpl->mVisibleGroups.insert(group); } -void LLViewerRegion::addToVOCacheTree(LLVOCacheEntry* entry, bool forced) +void LLViewerRegion::addToVOCacheTree(LLVOCacheEntry* entry) { if(!sVOCacheCullingEnabled) { @@ -895,10 +901,6 @@ void LLViewerRegion::addToVOCacheTree(LLVOCacheEntry* entry, bool forced) { return; } - if(!forced && !entry->hasState(LLVOCacheEntry::ADD_TO_CACHE_TREE)) - { - return; //can not add to vo cache tree. - } mImpl->mVOCachePartition->addEntry(entry->getEntry()); } @@ -1039,6 +1041,17 @@ F32 LLViewerRegion::updateVisibleEntries(F32 max_time) { LLVOCacheEntry* vo_entry = (LLVOCacheEntry*)(*i)->getVOCacheEntry(); + if(vo_entry->getParentID() > 0) //is a child + { + LLVOCacheEntry* parent = getCacheEntry(vo_entry->getParentID()); + + //make sure the parent is active + if(!parent || !parent->isState(LLVOCacheEntry::ACTIVE)) + { + continue; + } + } + vo_entry->calcSceneContribution(camera_origin, needs_update, mImpl->mLastCameraUpdate); mImpl->mWaitingList.insert(vo_entry); } @@ -1140,7 +1153,7 @@ F32 LLViewerRegion::killInvisibleObjects(F32 max_time) } for(S32 i = 0; i < delete_list.size(); i++) { - gObjectList.killObject(delete_list[i]->getVObj(), true); + gObjectList.killObject(delete_list[i]->getVObj()); } delete_list.clear(); @@ -1194,6 +1207,28 @@ LLViewerObject* LLViewerRegion::addNewObject(LLVOCacheEntry* entry) return obj; } +//remove from object cache if the object receives a full-update or terse update +LLViewerObject* LLViewerRegion::forceToRemoveFromCache(U32 local_id, LLViewerObject* objectp) +{ + LLVOCacheEntry* entry = getCacheEntry(local_id); + if (!entry) + { + return objectp; //not in the cache, do nothing. + } + if(!objectp) //object not created + { + entry->setTouched(FALSE); //mark this entry invalid + + //create a new object before delete it from cache. + objectp = gObjectList.processObjectUpdateFromCache(entry, this); + } + + //remove from cache. + killCacheEntry(entry); + + return objectp; +} + // As above, but forcibly do the update. void LLViewerRegion::forceUpdate() { @@ -1647,15 +1682,32 @@ void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features) mSimulatorFeatures = sim_features; } -void LLViewerRegion::postProcesNewEntry(LLVOCacheEntry* entry) +//this is called when the parent is not cacheable. +//move all orphan children out of cache and insert to rendering octree. +void LLViewerRegion::findOrphans(U32 parent_id) +{ + std::map::iterator iter = mOrphanMap.find(parent_id); + if(iter != mOrphanMap.end()) + { + std::set* children = mOrphanMap[parent_id].getChildList(); + for(std::set::iterator child_iter = children->begin(); child_iter != children->end(); ++child_iter) + { + forceToRemoveFromCache(*child_iter, NULL); + } + + mOrphanMap.erase(parent_id); + } +} + +void LLViewerRegion::decodeBoundingInfo(LLVOCacheEntry* entry) { if(entry != NULL && !entry->getEntry()) { entry->setOctreeEntry(NULL); } - else + else if(entry->getGroup() != NULL) { - return; //not new entry, no post processing. + return; //already in octree, no post processing. } LLVector3 pos; @@ -1667,11 +1719,13 @@ void LLViewerRegion::postProcesNewEntry(LLVOCacheEntry* entry) if(parent_id > 0) //has parent { + entry->setParentID(parent_id); + //1, find parent, update position LLVOCacheEntry* parent = getCacheEntry(parent_id); - //2, if can not, put into the orphan lists: a parents list and a children list - if(!parent) + //2, if can not, put into the orphan list. + if(!parent || !parent->getGroup()) { std::map::iterator iter = mOrphanMap.find(parent_id); if(iter != mOrphanMap.end()) @@ -1680,6 +1734,24 @@ void LLViewerRegion::postProcesNewEntry(LLVOCacheEntry* entry) } else { + //check if the parent is an uncacheable object + if(!parent) + { + LLUUID parent_uuid; + LLViewerObjectList::getUUIDFromLocal(parent_uuid, + parent_id, + getHost().getAddress(), + getHost().getPort()); + LLViewerObject *parent_objp = gObjectList.findObject(parent_uuid); + if(parent_objp) + { + //parent is not cacheable, remove child from the cache. + forceToRemoveFromCache(entry->getLocalID(), NULL); + return; + } + } + + //otherwise insert to the orphan list OrphanList o_list(entry->getLocalID()); mOrphanMap[parent_id] = o_list; } @@ -1688,13 +1760,14 @@ void LLViewerRegion::postProcesNewEntry(LLVOCacheEntry* entry) } else { + //update the child position to the region space. entry->updateBoundingInfo(parent); } } if(!entry->getGroup() && entry->isState(LLVOCacheEntry::INACTIVE)) { - addToVOCacheTree(entry, true); + addToVOCacheTree(entry); } if(!parent_id) //a potential parent @@ -1709,6 +1782,7 @@ void LLViewerRegion::postProcesNewEntry(LLVOCacheEntry* entry) LLVOCacheEntry* child = getCacheEntry(*child_iter); if(child) { + //update the child position to the region space. child->updateBoundingInfo(entry); addToVOCacheTree(child); } @@ -1758,7 +1832,7 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLDataPackerB entry = new_entry; mImpl->mCacheMap[local_id] = entry; - postProcesNewEntry(entry); + decodeBoundingInfo(entry); } result = CACHE_UPDATE_CHANGED; @@ -1773,7 +1847,7 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLDataPackerB mImpl->mCacheMap[local_id] = entry; - postProcesNewEntry(entry); + decodeBoundingInfo(entry); } return result; @@ -1784,6 +1858,10 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObjec eCacheUpdateResult result = cacheFullUpdate(dp); LLVOCacheEntry* entry = mImpl->mCacheMap[objectp->getLocalID()]; + if(!entry) + { + return result; + } if(objectp->mDrawable.notNull() && !entry->getEntry()) { @@ -1853,8 +1931,8 @@ bool LLViewerRegion::probeCache(U32 local_id, U32 crc, U32 flags, U8 &cache_miss { return true; } - //addVisibleCacheEntry(entry); - addToVOCacheTree(entry, true); + + decodeBoundingInfo(entry); return true; } else -- cgit v1.2.3 From 27bb36b1e796add58f319555bf761e417f7957ef Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Mon, 11 Mar 2013 21:23:15 -0600 Subject: for SH-3979: interesting: can not edit objects with new object cache code --- indra/newview/llviewerregion.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'indra/newview/llviewerregion.cpp') diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 704b3b644f..c74e7158b6 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1795,7 +1795,7 @@ void LLViewerRegion::decodeBoundingInfo(LLVOCacheEntry* entry) return ; } -LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLDataPackerBinaryBuffer &dp) +LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLDataPackerBinaryBuffer &dp, U32 flags) { eCacheUpdateResult result; U32 crc; @@ -1849,14 +1849,16 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLDataPackerB decodeBoundingInfo(entry); } - + entry->setUpdateFlags(flags); + return result; } -LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp) +LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp, U32 flags) { - eCacheUpdateResult result = cacheFullUpdate(dp); + eCacheUpdateResult result = cacheFullUpdate(dp, flags); +#if 0 LLVOCacheEntry* entry = mImpl->mCacheMap[objectp->getLocalID()]; if(!entry) { @@ -1871,6 +1873,7 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObjec { addActiveCacheEntry(entry); } +#endif return result; } @@ -1926,7 +1929,14 @@ bool LLViewerRegion::probeCache(U32 local_id, U32 crc, U32 flags, U8 &cache_miss // Record a hit entry->recordHit(); cache_miss_type = CACHE_MISS_TYPE_NONE; + entry->setUpdateFlags(flags); + if(entry->isState(LLVOCacheEntry::ACTIVE)) + { + ((LLDrawable*)entry->getEntry()->getDrawable())->getVObj()->loadFlags(flags); + return true; + } + if(entry->getGroup() || !entry->isState(LLVOCacheEntry::INACTIVE)) { return true; -- cgit v1.2.3 From 4624848a6894be669cdb19a82101ea168c407ecd Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Wed, 13 Mar 2013 22:31:19 -0600 Subject: revert changes for SH-3653: Can we repurpose ObjectUpdateCached:ObjectData:UpdateFlags field to carry spatial+size data? --- indra/newview/llviewerregion.cpp | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) (limited to 'indra/newview/llviewerregion.cpp') diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index c74e7158b6..bf4bff60d7 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1896,21 +1896,9 @@ LLVOCacheEntry* LLViewerRegion::getCacheEntry(U32 local_id) return NULL; } -//estimate weight of cache missed object -F32 LLViewerRegion::calcObjectWeight(U32 flags) +void LLViewerRegion::addCacheMiss(U32 id, LLViewerRegion::eCacheMissType miss_type) { - LLVector3 pos((F32)(flags & 0xff) + 0.5f, (F32)((flags >> 8) & 0xff) + 0.5f, (F32)((flags >> 16) & 0xff) * 16.f + 8.0f); - F32 rad = (F32)((flags >> 24) & 0xff); - - pos += getOriginAgent(); - pos -= LLViewerCamera::getInstance()->getOrigin(); - - return 100.f * rad * rad / pos.lengthSquared(); -} - -void LLViewerRegion::addCacheMiss(U32 id, LLViewerRegion::eCacheMissType miss_type, F32 weight) -{ - mCacheMissList.insert(CacheMissItem(id, miss_type, weight)); + mCacheMissList.insert(CacheMissItem(id, miss_type)); } // Get data packer for this object, if we have cached data @@ -1949,13 +1937,13 @@ bool LLViewerRegion::probeCache(U32 local_id, U32 crc, U32 flags, U8 &cache_miss { // llinfos << "CRC miss for " << local_id << llendl; - addCacheMiss(local_id, CACHE_MISS_TYPE_CRC, calcObjectWeight(flags)); + addCacheMiss(local_id, CACHE_MISS_TYPE_CRC); } } else { // llinfos << "Cache miss for " << local_id << llendl; - addCacheMiss(local_id, CACHE_MISS_TYPE_FULL, calcObjectWeight(flags)); + addCacheMiss(local_id, CACHE_MISS_TYPE_FULL); } return false; @@ -1963,7 +1951,7 @@ bool LLViewerRegion::probeCache(U32 local_id, U32 crc, U32 flags, U8 &cache_miss void LLViewerRegion::addCacheMissFull(const U32 local_id) { - addCacheMiss(local_id, CACHE_MISS_TYPE_FULL, 100.f); + addCacheMiss(local_id, CACHE_MISS_TYPE_FULL); } void LLViewerRegion::requestCacheMisses() -- cgit v1.2.3 From bdf562036a8ce864bf211b7696b1d74334030f4b Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Wed, 13 Mar 2013 22:38:00 -0600 Subject: for SH-3913: the viewer should notify the region at connect time if it does not have a cache file --- indra/newview/llviewerregion.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'indra/newview/llviewerregion.cpp') diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index bf4bff60d7..bca2108964 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -2164,7 +2164,13 @@ void LLViewerRegion::unpackRegionHandshake() msg->addUUID("AgentID", gAgent.getID()); msg->addUUID("SessionID", gAgent.getSessionID()); msg->nextBlock("RegionInfo"); - msg->addU32("Flags", 0x0 ); + + U32 flags = 0x00000001; //set the bit 0 to be 1 to ask sim to send all cacheable objects. + if(mImpl->mCacheMap.empty()) + { + flags |= 0x00000002; //set the bit 1 to be 1 to tell sim the cache file is empty, no need to send cache probes. + } + msg->addU32("Flags", flags ); msg->sendReliable(host); } -- cgit v1.2.3 From bbfb7b9ea1dc025d672968e39908b2327d14878a Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Wed, 20 Mar 2013 22:49:45 -0600 Subject: for SH-3918: Viewer should respond to cache probes in order received (don't sort response) --- indra/newview/llviewerregion.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'indra/newview/llviewerregion.cpp') diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index bca2108964..b052c87064 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1898,7 +1898,11 @@ LLVOCacheEntry* LLViewerRegion::getCacheEntry(U32 local_id) void LLViewerRegion::addCacheMiss(U32 id, LLViewerRegion::eCacheMissType miss_type) { +#if 0 mCacheMissList.insert(CacheMissItem(id, miss_type)); +#else + mCacheMissList.push_back(CacheMissItem(id, miss_type)); +#endif } // Get data packer for this object, if we have cached data -- cgit v1.2.3 From 51e5997bd6f7f7d66a5843cf1d0b749b143460a8 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Fri, 29 Mar 2013 17:54:04 -0600 Subject: delay removing invalid objects from cache in case region is logged out too soon. --- indra/newview/llviewerregion.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'indra/newview/llviewerregion.cpp') diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index d8f9ecf248..ed67d50dfd 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -460,11 +460,10 @@ void LLViewerRegion::saveObjectCache() if(LLVOCache::hasInstance()) { - //NOTE: !!!!!!!!!! - //set this to be true when support full region cache probe!!!! - BOOL full_region_cache_probe = FALSE; + const F32 start_time_threshold = 600.0f; //seconds + bool removal_enabled = mRegionTimer.getElapsedTimeF32() > start_time_threshold; //allow to remove invalid objects from object cache file. - LLVOCache::getInstance()->writeToCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap, mCacheDirty, full_region_cache_probe) ; + LLVOCache::getInstance()->writeToCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap, mCacheDirty, removal_enabled) ; mCacheDirty = FALSE; } @@ -2176,6 +2175,8 @@ void LLViewerRegion::unpackRegionHandshake() } msg->addU32("Flags", flags ); msg->sendReliable(host); + + mRegionTimer.reset(); //reset region timer. } void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) -- cgit v1.2.3 From da02b9f69471baa407188e2921b5c56c9b8d9415 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Fri, 29 Mar 2013 17:54:55 -0600 Subject: save cache file when first login to a region. --- indra/newview/llviewerregion.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'indra/newview/llviewerregion.cpp') diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index ed67d50dfd..64cf33a9eb 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -442,6 +442,10 @@ void LLViewerRegion::loadObjectCache() if(LLVOCache::hasInstance()) { LLVOCache::getInstance()->readFromCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap) ; + if (mImpl->mCacheMap.empty()) + { + mCacheDirty = TRUE; + } } } -- cgit v1.2.3 From 449222f5f0dbe2a4bd5cbc397298c02a3f3348b0 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Mon, 1 Apr 2013 13:44:08 -0600 Subject: trivial: convert to unix line endings. --- indra/newview/llviewerregion.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'indra/newview/llviewerregion.cpp') diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 64cf33a9eb..bed047ff0b 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -442,9 +442,9 @@ void LLViewerRegion::loadObjectCache() if(LLVOCache::hasInstance()) { LLVOCache::getInstance()->readFromCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap) ; - if (mImpl->mCacheMap.empty()) - { - mCacheDirty = TRUE; + if (mImpl->mCacheMap.empty()) + { + mCacheDirty = TRUE; } } } -- cgit v1.2.3 From 81943ecbe53779a226da4bbdf2c8b1ae39eba11b Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Thu, 11 Apr 2013 11:51:16 -0600 Subject: for SH-4095: add an option to turn off new interest list code --- indra/newview/llviewerregion.cpp | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) (limited to 'indra/newview/llviewerregion.cpp') diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index bed047ff0b..84e9c8ea9a 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -465,8 +465,8 @@ void LLViewerRegion::saveObjectCache() if(LLVOCache::hasInstance()) { const F32 start_time_threshold = 600.0f; //seconds - bool removal_enabled = mRegionTimer.getElapsedTimeF32() > start_time_threshold; //allow to remove invalid objects from object cache file. - + bool removal_enabled = sVOCacheCullingEnabled && (mRegionTimer.getElapsedTimeF32() > start_time_threshold); //allow to remove invalid objects from object cache file. + LLVOCache::getInstance()->writeToCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap, mCacheDirty, removal_enabled) ; mCacheDirty = FALSE; } @@ -1120,8 +1120,13 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time) max_update_time -= update_timer.getElapsedTimeF32(); if(max_update_time < 0.f || mImpl->mCacheMap.empty()) { - return did_update; -} + return did_update; + } + + if(!sVOCacheCullingEnabled) + { + return did_update; + } sCurRegionp = this; @@ -1704,6 +1709,12 @@ void LLViewerRegion::findOrphans(U32 parent_id) void LLViewerRegion::decodeBoundingInfo(LLVOCacheEntry* entry) { + if(!sVOCacheCullingEnabled) + { + gObjectList.processObjectUpdateFromCache(entry, this); + return; + } + if(entry != NULL && !entry->getEntry()) { entry->setOctreeEntry(NULL); @@ -1882,12 +1893,17 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObjec } LLVOCacheEntry* LLViewerRegion::getCacheEntryForOctree(U32 local_id) +{ + if(!sVOCacheCullingEnabled) { + return NULL; + } + LLVOCacheEntry* entry = getCacheEntry(local_id); removeFromVOCacheTree(entry); return entry; - } +} LLVOCacheEntry* LLViewerRegion::getCacheEntry(U32 local_id) { @@ -2172,10 +2188,14 @@ void LLViewerRegion::unpackRegionHandshake() msg->addUUID("SessionID", gAgent.getSessionID()); msg->nextBlock("RegionInfo"); - U32 flags = 0x00000001; //set the bit 0 to be 1 to ask sim to send all cacheable objects. - if(mImpl->mCacheMap.empty()) + U32 flags = 0; + if(sVOCacheCullingEnabled) { - flags |= 0x00000002; //set the bit 1 to be 1 to tell sim the cache file is empty, no need to send cache probes. + flags = 0x00000001; //set the bit 0 to be 1 to ask sim to send all cacheable objects. + if(mImpl->mCacheMap.empty()) + { + flags |= 0x00000002; //set the bit 1 to be 1 to tell sim the cache file is empty, no need to send cache probes. + } } msg->addU32("Flags", flags ); msg->sendReliable(host); -- cgit v1.2.3 From 674df12bc9e81b9b4290f74a96116dbbf1e7f77c Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Wed, 17 Apr 2013 23:00:36 -0600 Subject: for SH-4105: interesting: new viewer does not handle orphaned child prims in ObjectUpdateCompressed messages --- indra/newview/llviewerregion.cpp | 105 ++++++++++++++------------------------- 1 file changed, 37 insertions(+), 68 deletions(-) (limited to 'indra/newview/llviewerregion.cpp') diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 84e9c8ea9a..a2ff232d02 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1020,11 +1020,6 @@ F32 LLViewerRegion::updateVisibleEntries(F32 max_time) { ++iter; } - - //if(update_timer.getElapsedTimeF32() > max_time) - //{ - // break; - //} } #endif @@ -1046,24 +1041,14 @@ F32 LLViewerRegion::updateVisibleEntries(F32 max_time) if(vo_entry->getParentID() > 0) //is a child { - LLVOCacheEntry* parent = getCacheEntry(vo_entry->getParentID()); - - //make sure the parent is active - if(!parent || !parent->isState(LLVOCacheEntry::ACTIVE)) - { - continue; - } + //child visibility depends on its parent. + continue; } vo_entry->calcSceneContribution(camera_origin, needs_update, mImpl->mLastCameraUpdate); mImpl->mWaitingList.insert(vo_entry); } } - - //if(update_timer.getElapsedTimeF32() > max_time) - //{ - // break; - //} } mImpl->mVisibleGroups.clear(); @@ -1145,6 +1130,7 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time) F32 LLViewerRegion::killInvisibleObjects(F32 max_time) { +#if 1 if(!sVOCacheCullingEnabled) { return max_time; @@ -1164,7 +1150,7 @@ F32 LLViewerRegion::killInvisibleObjects(F32 max_time) gObjectList.killObject(delete_list[i]->getVObj()); } delete_list.clear(); - +#endif return max_time; } @@ -1694,15 +1680,15 @@ void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features) //move all orphan children out of cache and insert to rendering octree. void LLViewerRegion::findOrphans(U32 parent_id) { - std::map::iterator iter = mOrphanMap.find(parent_id); + orphan_list_t::iterator iter = mOrphanMap.find(parent_id); if(iter != mOrphanMap.end()) { - std::set* children = mOrphanMap[parent_id].getChildList(); - for(std::set::iterator child_iter = children->begin(); child_iter != children->end(); ++child_iter) + std::vector* children = &mOrphanMap[parent_id]; + for(S32 i = 0; i < children->size(); i++) { - forceToRemoveFromCache(*child_iter, NULL); + forceToRemoveFromCache((*children)[i], NULL); } - + children->clear(); mOrphanMap.erase(parent_id); } } @@ -1727,58 +1713,42 @@ void LLViewerRegion::decodeBoundingInfo(LLVOCacheEntry* entry) LLVector3 pos; LLVector3 scale; LLQuaternion rot; + + //decode spatial info and parent info U32 parent_id = LLViewerObject::extractSpatialExtents(entry->getDP(), pos, scale, rot); - entry->setBoundingInfo(pos, scale); - if(parent_id > 0) //has parent { entry->setParentID(parent_id); - //1, find parent, update position + //1, find the parent in cache LLVOCacheEntry* parent = getCacheEntry(parent_id); - //2, if can not, put into the orphan list. - if(!parent || !parent->getGroup()) + //2, parent is not in the cache, put into the orphan list. + if(!parent) { - std::map::iterator iter = mOrphanMap.find(parent_id); - if(iter != mOrphanMap.end()) + mOrphanMap[parent_id].push_back(entry->getLocalID()); + } + else //parent in cache + { + if(!parent->isState(LLVOCacheEntry::INACTIVE)) { - iter->second.addChild(entry->getLocalID()); + //parent is visible, so is the child. + addVisibleCacheEntry(entry); } - else + else { - //check if the parent is an uncacheable object - if(!parent) - { - LLUUID parent_uuid; - LLViewerObjectList::getUUIDFromLocal(parent_uuid, - parent_id, - getHost().getAddress(), - getHost().getPort()); - LLViewerObject *parent_objp = gObjectList.findObject(parent_uuid); - if(parent_objp) - { - //parent is not cacheable, remove child from the cache. - forceToRemoveFromCache(entry->getLocalID(), NULL); - return; - } - } - - //otherwise insert to the orphan list - OrphanList o_list(entry->getLocalID()); - mOrphanMap[parent_id] = o_list; + parent->addChild(entry); } - - return; - } - else - { - //update the child position to the region space. - entry->updateBoundingInfo(parent); } + + return; } + // + //no parent + // + entry->setBoundingInfo(pos, scale); if(!entry->getGroup() && entry->isState(LLVOCacheEntry::INACTIVE)) { addToVOCacheTree(entry); @@ -1787,21 +1757,20 @@ void LLViewerRegion::decodeBoundingInfo(LLVOCacheEntry* entry) if(!parent_id) //a potential parent { //find all children and update their bounding info - std::map::iterator iter = mOrphanMap.find(entry->getLocalID()); + orphan_list_t::iterator iter = mOrphanMap.find(entry->getLocalID()); if(iter != mOrphanMap.end()) - { - std::set* children = mOrphanMap[parent_id].getChildList(); - for(std::set::iterator child_iter = children->begin(); child_iter != children->end(); ++child_iter) + { + std::vector* orphans = &mOrphanMap[entry->getLocalID()]; + S32 size = orphans->size(); + for(S32 i = 0; i < size; i++) { - LLVOCacheEntry* child = getCacheEntry(*child_iter); + LLVOCacheEntry* child = getCacheEntry((*orphans)[i]); if(child) { - //update the child position to the region space. - child->updateBoundingInfo(entry); - addToVOCacheTree(child); + entry->addChild(child); } } - + orphans->clear(); mOrphanMap.erase(entry->getLocalID()); } } -- cgit v1.2.3 From 6244679b34bfb450bc83fd1ccd8c765028bb6735 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Wed, 1 May 2013 10:57:09 -0600 Subject: performance optimization: only scan 32 objects per frame looking for invisibles. --- indra/newview/llviewerregion.cpp | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) (limited to 'indra/newview/llviewerregion.cpp') diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index a2ff232d02..57fbaefce3 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1122,7 +1122,6 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time) createVisibleObjects(max_update_time); mImpl->mVisibleGroups.clear(); - mImpl->mWaitingList.clear(); sCurRegionp = NULL; return did_update; @@ -1135,16 +1134,40 @@ F32 LLViewerRegion::killInvisibleObjects(F32 max_time) { return max_time; } + if(mImpl->mActiveSet.empty()) + { + return max_time; + } + + static LLVOCacheEntry* last_visited_entry = NULL; + const size_t MAX_UPDATE = 32; std::vector delete_list; - for(LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mActiveSet.begin(); - iter != mImpl->mActiveSet.end(); ++iter) - { + S32 update_counter = llmin(MAX_UPDATE, mImpl->mActiveSet.size()); + LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mActiveSet.upper_bound(last_visited_entry); + + for(; update_counter > 0; --update_counter, ++iter) + { + if(iter == mImpl->mActiveSet.end()) + { + iter = mImpl->mActiveSet.begin(); + } + if(!(*iter)->isRecentlyVisible()) { killObject((*iter), delete_list); } } + + if(iter == mImpl->mActiveSet.end()) + { + last_visited_entry = NULL; + } + else + { + last_visited_entry = *iter; + } + for(S32 i = 0; i < delete_list.size(); i++) { gObjectList.killObject(delete_list[i]->getVObj()); -- cgit v1.2.3 From 6b81b8629e67d82a7620e48781ded73b6e6126ea Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Sun, 5 May 2013 17:45:35 -0700 Subject: Spring cleaning: removed unused .cpp and.h files, and cleaned up header dependencies --- indra/newview/llviewerregion.cpp | 56 ++++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 25 deletions(-) (limited to 'indra/newview/llviewerregion.cpp') diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index a2ff232d02..e85c566394 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -94,28 +94,29 @@ typedef std::map CapabilityMap; class LLViewerRegionImpl { public: LLViewerRegionImpl(LLViewerRegion * region, LLHost const & host) - : mHost(host), - mCompositionp(NULL), - mEventPoll(NULL), - mSeedCapMaxAttempts(MAX_CAP_REQUEST_ATTEMPTS), - mSeedCapMaxAttemptsBeforeLogin(MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN), - mSeedCapAttempts(0), - mHttpResponderID(0), - mLastCameraUpdate(0), - mLastCameraOrigin(), - // I'd prefer to set the LLCapabilityListener name to match the region - // name -- it's disappointing that's not available at construction time. - // We could instead store an LLCapabilityListener*, making - // setRegionNameAndZone() replace the instance. Would that pose - // consistency problems? Can we even request a capability before calling - // setRegionNameAndZone()? - // For testability -- the new Michael Feathers paradigm -- - // LLCapabilityListener binds all the globals it expects to need at - // construction time. - mCapabilityListener(host.getString(), gMessageSystem, *region, - gAgent.getID(), gAgent.getSessionID()) - { - } + : mHost(host), + mCompositionp(NULL), + mEventPoll(NULL), + mSeedCapMaxAttempts(MAX_CAP_REQUEST_ATTEMPTS), + mSeedCapMaxAttemptsBeforeLogin(MAX_SEED_CAP_ATTEMPTS_BEFORE_LOGIN), + mSeedCapAttempts(0), + mHttpResponderID(0), + mLastCameraUpdate(0), + mLastCameraOrigin(), + mVOCachePartition(NULL), + mLandp(NULL), + // I'd prefer to set the LLCapabilityListener name to match the region + // name -- it's disappointing that's not available at construction time. + // We could instead store an LLCapabilityListener*, making + // setRegionNameAndZone() replace the instance. Would that pose + // consistency problems? Can we even request a capability before calling + // setRegionNameAndZone()? + // For testability -- the new Michael Feathers paradigm -- + // LLCapabilityListener binds all the globals it expects to need at + // construction time. + mCapabilityListener(host.getString(), gMessageSystem, *region, + gAgent.getID(), gAgent.getSessionID()) + {} void buildCapabilityNames(LLSD& capabilityNames); @@ -439,7 +440,7 @@ void LLViewerRegion::loadObjectCache() // Presume success. If it fails, we don't want to try again. mCacheLoaded = TRUE; - if(LLVOCache::hasInstance()) + if(LLVOCache::instanceExists()) { LLVOCache::getInstance()->readFromCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap) ; if (mImpl->mCacheMap.empty()) @@ -462,7 +463,7 @@ void LLViewerRegion::saveObjectCache() return; } - if(LLVOCache::hasInstance()) + if(LLVOCache::instanceExists()) { const F32 start_time_threshold = 600.0f; //seconds bool removal_enabled = sVOCacheCullingEnabled && (mRegionTimer.getElapsedTimeF32() > start_time_threshold); //allow to remove invalid objects from object cache file. @@ -755,7 +756,7 @@ void LLViewerRegion::replaceCacheEntry(LLVOCacheEntry* old_entry, LLVOCacheEntry if(old_entry) { - old_entry->copyTo(new_entry); + old_entry->moveTo(new_entry); state = old_entry->getState(); in_vo_tree = (state == LLVOCacheEntry::INACTIVE && old_entry->getGroup() != NULL); killCacheEntry(old_entry); @@ -942,6 +943,11 @@ void LLViewerRegion::addVisibleCacheEntry(LLVOCacheEntry* entry) mImpl->mVisibleEntries.insert(entry); } +bool LLViewerRegion::hasVisibleGroup(LLviewerOctreeGroup* group) +{ + return mImpl->mVisibleGroups.find(group) != mImpl->mVisibleGroups.end(); +} + void LLViewerRegion::clearVisibleGroup(LLviewerOctreeGroup* group) { if(mDead) -- cgit v1.2.3 From 7006cbe3a24a88da4182f5930bb0fe712c43ce8c Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Thu, 16 May 2013 16:58:04 -0600 Subject: fix for SH-4080: interesting: random crash on Mac --- indra/newview/llviewerregion.cpp | 31 +++++-------------------------- 1 file changed, 5 insertions(+), 26 deletions(-) (limited to 'indra/newview/llviewerregion.cpp') diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 2ba0d939be..85da75510b 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -86,7 +86,6 @@ const F32 CAP_REQUEST_TIMEOUT = 18; // Even though we gave up on login, keep trying for caps after we are logged in: const S32 MAX_CAP_REQUEST_ATTEMPTS = 30; -LLViewerRegion* LLViewerRegion::sCurRegionp = NULL; BOOL LLViewerRegion::sVOCacheCullingEnabled = FALSE; typedef std::map CapabilityMap; @@ -143,7 +142,7 @@ public: LLVOCacheEntry::vocache_entry_map_t mCacheMap; //all cached entries LLVOCacheEntry::vocache_entry_set_t mActiveSet; //all active entries; LLVOCacheEntry::vocache_entry_set_t mWaitingSet; //entries waiting for LLDrawable to be generated. - std::set< LLviewerOctreeGroup* > mVisibleGroups; //visible groupa + std::set< LLPointer > mVisibleGroups; //visible groupa LLVOCachePartition* mVOCachePartition; LLVOCacheEntry::vocache_entry_set_t mVisibleEntries; //must-be-created visible entries wait for objects creation. LLVOCacheEntry::vocache_entry_priority_list_t mWaitingList; //transient list storing sorted visible entries waiting for object creation. @@ -943,23 +942,6 @@ void LLViewerRegion::addVisibleCacheEntry(LLVOCacheEntry* entry) mImpl->mVisibleEntries.insert(entry); } -bool LLViewerRegion::hasVisibleGroup(LLviewerOctreeGroup* group) -{ - return mImpl->mVisibleGroups.find(group) != mImpl->mVisibleGroups.end(); -} - -void LLViewerRegion::clearVisibleGroup(LLviewerOctreeGroup* group) -{ - if(mDead) - { - return; - } - - llassert(!group->getOctreeNode() || group->isEmpty()); - - mImpl->mVisibleGroups.erase(group); -} - F32 LLViewerRegion::updateVisibleEntries(F32 max_time) { if(mImpl->mVisibleGroups.empty() && mImpl->mVisibleEntries.empty()) @@ -1030,11 +1012,12 @@ F32 LLViewerRegion::updateVisibleEntries(F32 max_time) #endif //process visible groups - std::set< LLviewerOctreeGroup* >::iterator group_iter = mImpl->mVisibleGroups.begin(); + std::set< LLPointer >::iterator group_iter = mImpl->mVisibleGroups.begin(); for(; group_iter != mImpl->mVisibleGroups.end(); ++group_iter) { - LLviewerOctreeGroup* group = *group_iter; - if(!group->getOctreeNode() || group->isEmpty()) + LLPointer group = *group_iter; + if(group->getNumRefs() < 3 || //group to be deleted + !group->getOctreeNode() || group->isEmpty()) //group empty { continue; } @@ -1056,7 +1039,6 @@ F32 LLViewerRegion::updateVisibleEntries(F32 max_time) } } } - mImpl->mVisibleGroups.clear(); if(needs_update) { @@ -1119,8 +1101,6 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time) return did_update; } - sCurRegionp = this; - //kill invisible objects max_update_time = killInvisibleObjects(max_update_time); @@ -1129,7 +1109,6 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time) mImpl->mVisibleGroups.clear(); - sCurRegionp = NULL; return did_update; } -- cgit v1.2.3 From a6dbd8e089b7d0f462a8ed753258a442b1861541 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Wed, 5 Jun 2013 18:01:25 -0600 Subject: fix for SH-4227: interesting: long delay between root and child prim loading. --- indra/newview/llviewerregion.cpp | 46 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) (limited to 'indra/newview/llviewerregion.cpp') diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 85da75510b..b7d8c470b5 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -146,6 +146,7 @@ public: LLVOCachePartition* mVOCachePartition; LLVOCacheEntry::vocache_entry_set_t mVisibleEntries; //must-be-created visible entries wait for objects creation. LLVOCacheEntry::vocache_entry_priority_list_t mWaitingList; //transient list storing sorted visible entries waiting for object creation. + std::set mNonCacheableCreatedList; //list of local ids of all non-cacheable objects // time? // LRU info? @@ -1694,7 +1695,9 @@ void LLViewerRegion::findOrphans(U32 parent_id) std::vector* children = &mOrphanMap[parent_id]; for(S32 i = 0; i < children->size(); i++) { - forceToRemoveFromCache((*children)[i], NULL); + //parent is visible, so is the child. + LLVOCacheEntry* child = getCacheEntry((*children)[i]); + addVisibleCacheEntry(child); } children->clear(); mOrphanMap.erase(parent_id); @@ -1735,7 +1738,16 @@ void LLViewerRegion::decodeBoundingInfo(LLVOCacheEntry* entry) //2, parent is not in the cache, put into the orphan list. if(!parent) { - mOrphanMap[parent_id].push_back(entry->getLocalID()); + //check if parent is non-cacheable and already created + if(isNonCacheableObjectCreated(parent_id)) + { + //parent is visible, so is the child. + addVisibleCacheEntry(entry); + } + else + { + mOrphanMap[parent_id].push_back(entry->getLocalID()); + } } else //parent in cache { @@ -1901,6 +1913,36 @@ void LLViewerRegion::addCacheMiss(U32 id, LLViewerRegion::eCacheMissType miss_ty #endif } +//check if a non-cacheable object is already created. +bool LLViewerRegion::isNonCacheableObjectCreated(U32 local_id) +{ + if(mImpl && local_id > 0 && mImpl->mNonCacheableCreatedList.find(local_id) != mImpl->mNonCacheableCreatedList.end()) + { + return true; + } + return false; +} + +void LLViewerRegion::removeFromCreatedList(U32 local_id) +{ + if(mImpl && local_id > 0) + { + std::set::iterator iter = mImpl->mNonCacheableCreatedList.find(local_id); + if(iter != mImpl->mNonCacheableCreatedList.end()) + { + mImpl->mNonCacheableCreatedList.erase(iter); + } + } +} + +void LLViewerRegion::addToCreatedList(U32 local_id) +{ + if(mImpl && local_id > 0) + { + mImpl->mNonCacheableCreatedList.insert(local_id); + } +} + // Get data packer for this object, if we have cached data // AND the CRC matches. JC bool LLViewerRegion::probeCache(U32 local_id, U32 crc, U32 flags, U8 &cache_miss_type) -- cgit v1.2.3 From 427490edb566edf18da0b879f9d30a04dda0e9e0 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Mon, 10 Jun 2013 22:43:29 -0600 Subject: possible fix and new debug code for SH-4241: viewer crash shortly after login in LLViewerRegion::addNewObject --- indra/newview/llviewerregion.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'indra/newview/llviewerregion.cpp') diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 55137168ee..29528a1117 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -953,6 +953,8 @@ void LLViewerRegion::addToVOCacheTree(LLVOCacheEntry* entry) { return; } + + llassert_always(!entry->getParentID() && !entry->getEntry()->hasDrawable()); mImpl->mVOCachePartition->addEntry(entry->getEntry()); } @@ -993,6 +995,11 @@ void LLViewerRegion::addVisibleCacheEntry(LLVOCacheEntry* entry) F32 LLViewerRegion::updateVisibleEntries(F32 max_time) { + if(mDead) + { + return max_time; + } + if(mImpl->mVisibleGroups.empty() && mImpl->mVisibleEntries.empty()) { return max_time; @@ -1100,6 +1107,10 @@ F32 LLViewerRegion::updateVisibleEntries(F32 max_time) F32 LLViewerRegion::createVisibleObjects(F32 max_time) { + if(mDead) + { + return max_time; + } if(mImpl->mWaitingList.empty()) { return max_time; @@ -1120,8 +1131,7 @@ F32 LLViewerRegion::createVisibleObjects(F32 max_time) break; } } - } - mImpl->mWaitingList.clear(); + } return max_time - update_timer.getElapsedTimeF32(); } @@ -1156,6 +1166,7 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time) max_update_time = updateVisibleEntries(max_update_time); createVisibleObjects(max_update_time); + mImpl->mWaitingList.clear(); mImpl->mVisibleGroups.clear(); return did_update; -- cgit v1.2.3 From fc88265cffe3553803314c6e895a1e3a3c988171 Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Thu, 13 Jun 2013 18:47:51 -0600 Subject: fix for SH-4241: viewer crash shortly after login in LLViewerRegion::addNewObject and SH-4261: interesting: crash in LLViewerRegion::addToVOCacheTree --- indra/newview/llviewerregion.cpp | 90 ++++++++++++++++++++++++++++------------ 1 file changed, 64 insertions(+), 26 deletions(-) (limited to 'indra/newview/llviewerregion.cpp') 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 { -- cgit v1.2.3