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 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