summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
authorXiaohong Bao <bao@lindenlab.com>2013-08-08 16:45:55 -0600
committerXiaohong Bao <bao@lindenlab.com>2013-08-08 16:45:55 -0600
commita6711a894c3c32ad24b47e36b2a52225713fd3ed (patch)
tree73c6a36e202e88576ee74b4caa5a98c58cae3c80 /indra/newview
parenta2c7b0485576c6bb92f6d0eddc762f5e37d5caac (diff)
fix for SH-4402: interesting: lower FPS with lots of objects in view
Diffstat (limited to 'indra/newview')
-rwxr-xr-xindra/newview/llviewerregion.cpp108
-rwxr-xr-xindra/newview/llviewerregion.h18
-rwxr-xr-xindra/newview/llvocache.cpp37
-rwxr-xr-xindra/newview/llvocache.h6
-rwxr-xr-xindra/newview/llworld.cpp3
-rwxr-xr-xindra/newview/pipeline.cpp2
6 files changed, 126 insertions, 48 deletions
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 117ccdea33..cfe765a1cb 100755
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -90,6 +90,7 @@ const U32 DEFAULT_MAX_REGION_WIDE_PRIM_COUNT = 15000;
BOOL LLViewerRegion::sVOCacheCullingEnabled = FALSE;
S32 LLViewerRegion::sLastCameraUpdated = 0;
+S32 LLViewerRegion::sNewObjectCreationThrottle = 0;
typedef std::map<std::string, std::string> CapabilityMap;
@@ -372,7 +373,9 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,
mCapabilitiesReceived(false),
mBitsReceived(0.f),
mPacketsReceived(0.f),
- mDead(FALSE)
+ mDead(FALSE),
+ mLastVisitedEntry(NULL),
+ mInvisibilityCheckHistory(-1)
{
mWidth = region_width_meters;
mImpl->mOriginGlobal = from_region_handle(handle);
@@ -968,6 +971,11 @@ void LLViewerRegion::addVisibleGroup(LLviewerOctreeGroup* group)
mImpl->mVisibleGroups.insert(group);
}
+U32 LLViewerRegion::getNumOfVisibleGroups() const
+{
+ return mImpl ? mImpl->mVisibleGroups.size() : 0;
+}
+
void LLViewerRegion::addToVOCacheTree(LLVOCacheEntry* entry)
{
if(!sVOCacheCullingEnabled)
@@ -1139,7 +1147,7 @@ F32 LLViewerRegion::updateVisibleEntries(F32 max_time)
return 2.0f * max_time - update_timer.getElapsedTimeF32();
}
-F32 LLViewerRegion::createVisibleObjects(F32 max_time, S32 throttle)
+F32 LLViewerRegion::createVisibleObjects(F32 max_time)
{
if(mDead)
{
@@ -1150,6 +1158,7 @@ F32 LLViewerRegion::createVisibleObjects(F32 max_time, S32 throttle)
return max_time;
}
+ S32 throttle = sNewObjectCreationThrottle;
LLTimer update_timer;
for(LLVOCacheEntry::vocache_entry_priority_list_t::iterator iter = mImpl->mWaitingList.begin();
iter != mImpl->mWaitingList.end(); ++iter)
@@ -1170,9 +1179,7 @@ F32 LLViewerRegion::createVisibleObjects(F32 max_time, S32 throttle)
}
BOOL LLViewerRegion::idleUpdate(F32 max_update_time)
-{
- static LLCachedControl<S32> new_object_creation_throttle(gSavedSettings,"NewObjectCreationThrottle");
-
+{
LLTimer update_timer;
// did_update returns TRUE if we did at least one significant update
@@ -1191,44 +1198,28 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time)
if(mImpl->mCacheMap.empty())
{
return did_update;
- }
-
- max_update_time -= update_timer.getElapsedTimeF32();
+ }
//reset all occluders
mImpl->mVOCachePartition->resetOccluders();
- //update the throttling number
- static S32 throttle = new_object_creation_throttle;
- if(LLStartUp::getStartupState() < STATE_STARTED || gTeleportDisplay)
- {
- throttle = -1; //cancel the throttling
+ max_update_time -= update_timer.getElapsedTimeF32();
+ if(sNewObjectCreationThrottle < 0 && (LLStartUp::getStartupState() < STATE_STARTED || gTeleportDisplay))
+ {
//apply octree cullings here to pick up visible objects because rendering pipeline stops view culling at this moment
mImpl->mVOCachePartition->cull(*LLViewerCamera::getInstance(), false);
}
- else if(throttle < 0) //just recoved from the login/teleport screen
- {
- if(new_object_creation_throttle > 0)
- {
- throttle = 4096; //a big number
- }
- }
- else
- {
- throttle = llmax((S32)new_object_creation_throttle, (S32)(throttle >> 1));
- }
-
- if(max_update_time < 0.f && throttle > 0 && throttle < new_object_creation_throttle * 2)
+ else if(max_update_time < 0.f)
{
return did_update;
}
//kill invisible objects
- max_update_time = killInvisibleObjects(max_update_time, throttle);
+ max_update_time = killInvisibleObjects(max_update_time);
max_update_time = updateVisibleEntries(max_update_time);
- createVisibleObjects(max_update_time, throttle);
+ createVisibleObjects(max_update_time);
mImpl->mWaitingList.clear();
mImpl->mVisibleGroups.clear();
@@ -1236,7 +1227,35 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time)
return did_update;
}
-F32 LLViewerRegion::killInvisibleObjects(F32 max_time, S32 throttle)
+//update the throttling number for new object creation
+void LLViewerRegion::calcNewObjectCreationThrottle()
+{
+ static LLCachedControl<S32> new_object_creation_throttle(gSavedSettings,"NewObjectCreationThrottle");
+
+ sNewObjectCreationThrottle = new_object_creation_throttle;
+ if(LLStartUp::getStartupState() < STATE_STARTED || gTeleportDisplay)
+ {
+ sNewObjectCreationThrottle = -1; //cancel the throttling
+ }
+ else if(sNewObjectCreationThrottle < 0) //just recoved from the login/teleport screen
+ {
+ if(new_object_creation_throttle > 0)
+ {
+ sNewObjectCreationThrottle = 4096; //a big number
+ }
+ }
+ else
+ {
+ sNewObjectCreationThrottle = llmax((S32)new_object_creation_throttle, (S32)(sNewObjectCreationThrottle >> 1));
+ }
+}
+
+BOOL LLViewerRegion::isViewerCameraStatic()
+{
+ return sLastCameraUpdated < LLViewerOctreeEntryData::getCurrentFrame();
+}
+
+F32 LLViewerRegion::killInvisibleObjects(F32 max_time)
{
#if 1
if(!sVOCacheCullingEnabled)
@@ -1248,12 +1267,16 @@ F32 LLViewerRegion::killInvisibleObjects(F32 max_time, S32 throttle)
return max_time;
}
- static LLVOCacheEntry* last_visited_entry = NULL;
-
- const size_t MAX_UPDATE = throttle < 0 ? mImpl->mActiveSet.size() : 64;
+ size_t max_update = sNewObjectCreationThrottle < 0 ? mImpl->mActiveSet.size() : 64;
+ if(!mInvisibilityCheckHistory && isViewerCameraStatic())
+ {
+ //history is clean, reduce number of checking
+ max_update = llmax(max_update / 2, (size_t)8);
+ }
+
std::vector<LLDrawable*> delete_list;
- S32 update_counter = llmin(MAX_UPDATE, mImpl->mActiveSet.size());
- LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mActiveSet.upper_bound(last_visited_entry);
+ S32 update_counter = llmin(max_update, mImpl->mActiveSet.size());
+ LLVOCacheEntry::vocache_entry_set_t::iterator iter = mImpl->mActiveSet.upper_bound(mLastVisitedEntry);
for(; update_counter > 0; --update_counter, ++iter)
{
@@ -1262,7 +1285,7 @@ F32 LLViewerRegion::killInvisibleObjects(F32 max_time, S32 throttle)
iter = mImpl->mActiveSet.begin();
}
- if(!(*iter)->isRecentlyVisible() && (*iter)->mLastCameraUpdated != sLastCameraUpdated)
+ if(!(*iter)->isRecentlyVisible() && (*iter)->mLastCameraUpdated < sLastCameraUpdated)
{
killObject((*iter), delete_list);
}
@@ -1270,18 +1293,23 @@ F32 LLViewerRegion::killInvisibleObjects(F32 max_time, S32 throttle)
if(iter == mImpl->mActiveSet.end())
{
- last_visited_entry = NULL;
+ mLastVisitedEntry = NULL;
}
else
{
- last_visited_entry = *iter;
+ mLastVisitedEntry = *iter;
}
- for(S32 i = 0; i < delete_list.size(); i++)
+ mInvisibilityCheckHistory <<= 2;
+ if(!delete_list.empty())
{
- gObjectList.killObject(delete_list[i]->getVObj());
+ mInvisibilityCheckHistory |= 1;
+ for(S32 i = 0; i < delete_list.size(); i++)
+ {
+ gObjectList.killObject(delete_list[i]->getVObj());
+ }
+ delete_list.clear();
}
- delete_list.clear();
#endif
return max_time;
}
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index a8e0b7bba9..9d2a333b1b 100755
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -220,6 +220,10 @@ public:
// can process the message.
static void processRegionInfo(LLMessageSystem* msg, void**);
+ //check if the viewer camera is static
+ static BOOL isViewerCameraStatic();
+ static void calcNewObjectCreationThrottle();
+
void setCacheID(const LLUUID& id);
F32 getWidth() const { return mWidth; }
@@ -345,6 +349,7 @@ public:
virtual std::string getDescription() const;
std::string getHttpUrl() const { return mHttpUrl ;}
+ U32 getNumOfVisibleGroups() const;
U32 getNumOfActiveCachedObjects() const;
LLSpatialPartition* getSpatialPartition(U32 type);
LLVOCachePartition* getVOCachePartition();
@@ -359,7 +364,7 @@ public:
LLViewerRegionImpl * getRegionImplNC() { return mImpl; }
void removeFromCreatedList(U32 local_id);
- void addToCreatedList(U32 local_id);
+ void addToCreatedList(U32 local_id);
private:
void addToVOCacheTree(LLVOCacheEntry* entry);
@@ -369,8 +374,8 @@ private:
void replaceVisibleCacheEntry(LLVOCacheEntry* old_entry, LLVOCacheEntry* new_entry);
void killCacheEntry(LLVOCacheEntry* entry); //physically delete the cache entry
- F32 killInvisibleObjects(F32 max_time, S32 throttle);
- F32 createVisibleObjects(F32 max_time, S32 throttle);
+ F32 killInvisibleObjects(F32 max_time);
+ F32 createVisibleObjects(F32 max_time);
F32 updateVisibleEntries(F32 max_time); //update visible entries
void addCacheMiss(U32 id, LLViewerRegion::eCacheMissType miss_type);
@@ -411,6 +416,10 @@ public:
static BOOL sVOCacheCullingEnabled; //vo cache culling enabled or not.
static S32 sLastCameraUpdated;
+
+private:
+ static S32 sNewObjectCreationThrottle;
+
private:
LLViewerRegionImpl * mImpl;
LLFrameTimer mRegionTimer;
@@ -445,6 +454,9 @@ private:
F32 mCameraDistanceSquared; // updated once per frame
U8 mCentralBakeVersion;
+ LLVOCacheEntry* mLastVisitedEntry;
+ U32 mInvisibilityCheckHistory;
+
// Information for Homestead / CR-53
S32 mClassID;
S32 mCPURatio;
diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp
index 82485d7fdc..7dfa131ebf 100755
--- a/indra/newview/llvocache.cpp
+++ b/indra/newview/llvocache.cpp
@@ -34,6 +34,7 @@
#include "llviewerregion.h"
#include "pipeline.h"
+BOOL LLVOCachePartition::sNeedsOcclusionCheck = FALSE;
LLTrace::MemStatHandle LLVOCachePartition::sMemStat("LLVOCachePartition");
BOOL check_read(LLAPRFile* apr_file, void* src, S32 n_bytes)
@@ -467,8 +468,14 @@ LLVOCachePartition::LLVOCachePartition(LLViewerRegion* regionp)
{
mLODPeriod = 16;
mRegionp = regionp;
- mPartitionType = LLViewerRegion::PARTITION_VO_CACHE;
-
+ mPartitionType = LLViewerRegion::PARTITION_VO_CACHE;
+ mDirty = FALSE;
+
+ for(S32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++)
+ {
+ mCulledTime[i] = 0;
+ mCullHistory[i] = -1;
+ }
new LLOcclusionCullingGroup(mOctree, this);
}
@@ -477,6 +484,7 @@ void LLVOCachePartition::addEntry(LLViewerOctreeEntry* entry)
llassert(entry->hasVOCacheEntry());
mOctree->insert(entry);
+ mDirty = TRUE;
}
void LLVOCachePartition::removeEntry(LLViewerOctreeEntry* entry)
@@ -595,7 +603,19 @@ S32 LLVOCachePartition::cull(LLCamera &camera, bool do_occlusion)
return 0;
}
+ if(mCulledTime[LLViewerCamera::sCurCameraID] == LLViewerOctreeEntryData::getCurrentFrame())
+ {
+ return 0; //already culled
+ }
+ mCulledTime[LLViewerCamera::sCurCameraID] = LLViewerOctreeEntryData::getCurrentFrame();
+
+ if(!mDirty && !mCullHistory[LLViewerCamera::sCurCameraID] && LLViewerRegion::isViewerCameraStatic())
+ {
+ return 0; //nothing changed, skip culling
+ }
+
((LLviewerOctreeGroup*)mOctree->getListener(0))->rebound();
+ mCullHistory[LLViewerCamera::sCurCameraID] <<= 2;
//localize the camera
LLVector3 region_agent = mRegionp->getOriginAgent();
@@ -604,7 +624,16 @@ S32 LLVOCachePartition::cull(LLCamera &camera, bool do_occlusion)
LLVOCacheOctreeCull culler(&camera, mRegionp, region_agent, do_occlusion && use_object_cache_occlusion, this);
culler.traverse(mOctree);
- return 0;
+ if(mRegionp->getNumOfVisibleGroups() > 0)
+ {
+ mCullHistory[LLViewerCamera::sCurCameraID] |= 1;
+ }
+
+ if(!sNeedsOcclusionCheck)
+ {
+ sNeedsOcclusionCheck = !mOccludedGroups.empty();
+ }
+ return 1;
}
void LLVOCachePartition::addOccluders(LLviewerOctreeGroup* gp)
@@ -646,6 +675,8 @@ void LLVOCachePartition::resetOccluders()
group->clearOcclusionState(LLOcclusionCullingGroup::ACTIVE_OCCLUSION);
}
mOccludedGroups.clear();
+ mDirty = FALSE;
+ sNeedsOcclusionCheck = FALSE;
}
//-------------------------------------------------------------------
diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h
index 04463088fa..c448b97b80 100755
--- a/indra/newview/llvocache.h
+++ b/indra/newview/llvocache.h
@@ -168,7 +168,13 @@ public:
public:
void processOccluders(LLCamera* camera);
+public:
+ static BOOL sNeedsOcclusionCheck;
+
private:
+ BOOL mDirty;
+ U32 mCullHistory[LLViewerCamera::NUM_CAMERAS];
+ U32 mCulledTime[LLViewerCamera::NUM_CAMERAS];
std::set<LLOcclusionCullingGroup*> mOccludedGroups;
};
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index bfc5077c90..df5e3d835c 100755
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -668,8 +668,9 @@ void LLWorld::updateRegions(F32 max_update_time)
if(LLViewerCamera::getInstance()->isChanged())
{
- LLViewerRegion::sLastCameraUpdated = LLViewerOctreeEntryData::getCurrentFrame();
+ LLViewerRegion::sLastCameraUpdated = LLViewerOctreeEntryData::getCurrentFrame() + 1;
}
+ LLViewerRegion::calcNewObjectCreationThrottle();
// Perform idle time updates for the regions (and associated surfaces)
for (region_list_t::iterator iter = mRegionList.begin();
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 1abaaa49ac..87c3bf7bdf 100755
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -2724,7 +2724,7 @@ void LLPipeline::doOcclusion(LLCamera& camera, LLRenderTarget& source, LLRenderT
void LLPipeline::doOcclusion(LLCamera& camera)
{
- if (LLPipeline::sUseOcclusion > 1)
+ if (LLPipeline::sUseOcclusion > 1 && (sCull->hasOcclusionGroups() || LLVOCachePartition::sNeedsOcclusionCheck))
{
LLVertexBuffer::unbind();