summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rwxr-xr-xindra/newview/llappviewer.cpp4
-rwxr-xr-xindra/newview/llappviewer.h2
-rw-r--r--indra/newview/llscenemonitor.cpp17
-rwxr-xr-xindra/newview/llspatialpartition.cpp8
-rwxr-xr-xindra/newview/llspatialpartition.h3
-rwxr-xr-xindra/newview/llstartup.cpp5
-rwxr-xr-xindra/newview/llviewerobjectlist.cpp5
-rw-r--r--indra/newview/llvieweroctree.cpp6
-rw-r--r--indra/newview/llvieweroctree.h9
-rwxr-xr-xindra/newview/llviewerregion.cpp139
-rwxr-xr-xindra/newview/llviewerregion.h18
-rwxr-xr-xindra/newview/llviewerstats.cpp2
-rwxr-xr-xindra/newview/llvocache.cpp132
-rwxr-xr-xindra/newview/llvocache.h15
-rwxr-xr-xindra/newview/llworld.cpp3
-rwxr-xr-xindra/newview/pipeline.cpp27
16 files changed, 290 insertions, 105 deletions
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 0a1a78c5b4..30c19ac55e 100755
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -294,7 +294,7 @@ U32 gForegroundFrameCount = 0; // number of frames that app window was in foregr
LLPumpIO* gServicePump = NULL;
LLUnitImplicit<U64, LLUnits::Microseconds> gFrameTime = 0;
-LLUnitImplicit<F32, LLUnits::Seconds> gFrameTimeSeconds = 0.f;
+F32 gFrameTimeSeconds = 0.f;
LLUnitImplicit<F32, LLUnits::Seconds> gFrameIntervalSeconds = 0.f;
F32 gFPSClamped = 10.f; // Pretend we start at target rate.
F32 gFrameDTClamped = 0.f; // Time between adjacent checks to network for packets
@@ -1464,7 +1464,7 @@ bool LLAppViewer::mainLoop()
ms_sleep(500);
}
- const F64 max_idle_time = llmin(.005*10.0*gFrameTimeSeconds, LLUnitImplicit<F32, LLUnits::Seconds>(0.005f)); // 5 ms a second
+ const F64 max_idle_time = llmin(.005f*10.0f*gFrameTimeSeconds, (0.005f)); // 5 ms a second
idleTimer.reset();
S32 total_work_pending = 0;
S32 total_io_pending = 0;
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index 60a1045f58..76724a9662 100755
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -336,7 +336,7 @@ extern LLPumpIO* gServicePump;
extern LLUnitImplicit<U64, LLUnits::Microseconds> gStartTime;
extern LLUnitImplicit<U64, LLUnits::Microseconds> gFrameTime; // The timestamp of the most-recently-processed frame
-extern LLUnitImplicit<F32, LLUnits::Seconds> gFrameTimeSeconds; // Loses msec precision after ~4.5 hours...
+extern F32 gFrameTimeSeconds; // Loses msec precision after ~4.5 hours...
extern LLUnitImplicit<F32, LLUnits::Seconds> gFrameIntervalSeconds; // Elapsed time between current and previous gFrameTimeSeconds
extern F32 gFPSClamped; // Frames per second, smoothed, weighted toward last frame
extern F32 gFrameDTClamped;
diff --git a/indra/newview/llscenemonitor.cpp b/indra/newview/llscenemonitor.cpp
index 7fdee2b2ad..f0c7a220a4 100644
--- a/indra/newview/llscenemonitor.cpp
+++ b/indra/newview/llscenemonitor.cpp
@@ -211,11 +211,19 @@ LLRenderTarget& LLSceneMonitor::getCaptureTarget()
void LLSceneMonitor::freezeAvatar(LLCharacter* avatarp)
{
- mAvatarPauseHandles.push_back(avatarp->requestPause());
+ if(mEnabled)
+ {
+ mAvatarPauseHandles.push_back(avatarp->requestPause());
+ }
}
void LLSceneMonitor::freezeScene()
{
+ if(!mEnabled)
+ {
+ return;
+ }
+
//freeze all avatars
for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
iter != LLCharacter::sInstances.end(); ++iter)
@@ -262,7 +270,7 @@ void LLSceneMonitor::capture()
static LLCachedControl<F32> scene_load_sample_time(gSavedSettings, "SceneLoadingMonitorSampleTime");
static bool force_capture = true;
- bool enabled = monitor_enabled || mDebugViewerVisible;
+ bool enabled = LLGLSLShader::sNoFixedFunction && (monitor_enabled || mDebugViewerVisible);
if(mEnabled != enabled)
{
if(mEnabled)
@@ -288,10 +296,9 @@ void LLSceneMonitor::capture()
force_capture = true;
}
- if((mRecordingTimer.getElapsedTimeF32() > scene_load_sample_time()
+ if(mEnabled
+ && (mRecordingTimer.getElapsedTimeF32() > scene_load_sample_time()
|| force_capture)
- && mEnabled
- && LLGLSLShader::sNoFixedFunction
&& last_capture_frame != gFrameCount)
{
force_capture = false;
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index f3b0108359..20a2ddc3b1 100755
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -265,12 +265,6 @@ BOOL LLSpatialGroup::isHUDGroup()
return getSpatialPartition() && getSpatialPartition()->isHUDPartition() ;
}
-BOOL LLSpatialGroup::isRecentlyVisible() const
-{
- const S32 MIN_VIS_FRAME_RANGE = 2;
- return (LLDrawable::getCurrentFrame() - mVisible[LLViewerCamera::sCurCameraID]) < MIN_VIS_FRAME_RANGE ;
-}
-
void LLSpatialGroup::validate()
{
ll_assert_aligned(this,64);
@@ -1482,7 +1476,7 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* result
return 0;
}
-S32 LLSpatialPartition::cull(LLCamera &camera)
+S32 LLSpatialPartition::cull(LLCamera &camera, bool do_occlusion)
{
#if LL_OCTREE_PARANOIA_CHECK
((LLSpatialGroup*)mOctree->getListener(0))->checkStates();
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index 8d755e74b1..5c4cdcdba1 100755
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -290,7 +290,6 @@ public:
BOOL addObject(LLDrawable *drawablep);
BOOL removeObject(LLDrawable *drawablep, BOOL from_octree = FALSE);
BOOL updateInGroup(LLDrawable *drawablep, BOOL immediate = FALSE); // Update position if it's in the group
- BOOL isRecentlyVisible() const;
void shift(const LLVector4a &offset);
void destroyGL(bool keep_occlusion = false);
@@ -423,7 +422,7 @@ public:
virtual void rebuildMesh(LLSpatialGroup* group);
BOOL visibleObjectsInFrustum(LLCamera& camera);
- /*virtual*/ S32 cull(LLCamera &camera); // Cull on arbitrary frustum
+ /*virtual*/ S32 cull(LLCamera &camera, bool do_occlusion=false); // Cull on arbitrary frustum
S32 cull(LLCamera &camera, std::vector<LLDrawable *>* results, BOOL for_select); // Cull on arbitrary frustum
BOOL isVisible(const LLVector3& v);
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 3335ff6631..ae8afd0eae 100755
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -1429,8 +1429,9 @@ bool idle_startup()
LL_DEBUGS("AppInit") << "Initializing camera..." << LL_ENDL;
gFrameTime = totalTime();
- LLUnit<F32, LLUnits::Seconds> last_time = gFrameTimeSeconds;
- gFrameTimeSeconds = (gFrameTime - gStartTime);
+ F32 last_time = gFrameTimeSeconds;
+ const F64 SEC_TO_MICROSEC = 1000000.f;
+ gFrameTimeSeconds = (F32)((gFrameTime - gStartTime) / SEC_TO_MICROSEC);
gFrameIntervalSeconds = gFrameTimeSeconds - last_time;
if (gFrameIntervalSeconds < 0.f)
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index e8f68527e9..214d4f2bf6 100755
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -999,9 +999,10 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)
// Time _can_ go backwards, for example if the user changes the system clock.
// It doesn't cause any fatal problems (just some oddness with stats), so we shouldn't assert here.
// llassert(time > gFrameTime);
- LLUnit<F64, LLUnits::Seconds> time_diff = time - gFrameTime;
+ const F64 SEC_TO_MICROSEC = 1000000.f;
+ F64 time_diff = U64_to_F64(time - gFrameTime)/SEC_TO_MICROSEC;
gFrameTime = time;
- LLUnit<F64, LLUnits::Seconds> time_since_start = gFrameTime - gStartTime;
+ F64 time_since_start = U64_to_F64(gFrameTime - gStartTime)/SEC_TO_MICROSEC;
gFrameTimeSeconds = time_since_start;
gFrameIntervalSeconds = gFrameTimeSeconds - last_time;
diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp
index 443468235a..637505a826 100644
--- a/indra/newview/llvieweroctree.cpp
+++ b/indra/newview/llvieweroctree.cpp
@@ -853,6 +853,12 @@ BOOL LLOcclusionCullingGroup::needsUpdate()
return (LLDrawable::getCurrentFrame() % mSpatialPartition->mLODPeriod == mLODHash) ? TRUE : FALSE;
}
+BOOL LLOcclusionCullingGroup::isRecentlyVisible() const
+{
+ const S32 MIN_VIS_FRAME_RANGE = 2;
+ return (LLDrawable::getCurrentFrame() - mVisible[LLViewerCamera::sCurCameraID]) < MIN_VIS_FRAME_RANGE ;
+}
+
//virtual
void LLOcclusionCullingGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* child)
{
diff --git a/indra/newview/llvieweroctree.h b/indra/newview/llvieweroctree.h
index 980a67367c..7fdb5661d8 100644
--- a/indra/newview/llvieweroctree.h
+++ b/indra/newview/llvieweroctree.h
@@ -317,14 +317,17 @@ public:
void clearOcclusionState(U32 state, S32 mode = STATE_MODE_SINGLE);
void checkOcclusion(); //read back last occlusion query (if any)
void doOcclusion(LLCamera* camera, const LLVector3* region_agent = NULL); //issue occlusion query
- BOOL isOcclusionState(U32 state) const { return mOcclusionState[LLViewerCamera::sCurCameraID] & state ? TRUE : FALSE; }
-
+ BOOL isOcclusionState(U32 state) const { return mOcclusionState[LLViewerCamera::sCurCameraID] & state ? TRUE : FALSE; }
+
BOOL needsUpdate();
U32 getLastOcclusionIssuedTime();
//virtual
void handleChildAddition(const OctreeNode* parent, OctreeNode* child);
+ //virtual
+ BOOL isRecentlyVisible() const;
+
static U32 getNewOcclusionQueryObjectName();
static void releaseOcclusionQueryObjectName(U32 name);
@@ -354,7 +357,7 @@ public:
virtual ~LLViewerOctreePartition();
// Cull on arbitrary frustum
- virtual S32 cull(LLCamera &camera) = 0;
+ virtual S32 cull(LLCamera &camera, bool do_occlusion) = 0;
BOOL isOcclusionEnabled();
public:
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 3ad1c6ab0a..5221220440 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);
@@ -866,8 +869,19 @@ void LLViewerRegion::killCacheEntry(LLVOCacheEntry* entry)
//remove from the forced visible list
mImpl->mVisibleEntries.erase(entry);
- //kill LLViewerObject if exists
- //this should be done by the rendering pipeline automatically.
+ //disconnect from parent if it is a child
+ if(entry->getParentID() > 0)
+ {
+ LLVOCacheEntry* parent = getCacheEntry(entry->getParentID());
+ if(parent)
+ {
+ parent->removeChild(entry);
+ }
+ }
+ else if(entry->getNumOfChildren() > 0)//disconnect children if has any
+ {
+ entry->removeAllChildren();
+ }
entry->setState(LLVOCacheEntry::INACTIVE);
@@ -957,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)
@@ -1128,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)
{
@@ -1139,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)
@@ -1159,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
@@ -1180,46 +1198,28 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time)
if(mImpl->mCacheMap.empty())
{
return did_update;
- }
+ }
+
+ //reset all occluders
+ mImpl->mVOCachePartition->resetOccluders();
max_update_time -= update_timer.getElapsedTimeF32();
- //update the throttling number
- static S32 throttle = new_object_creation_throttle;
- if(LLStartUp::getStartupState() < STATE_STARTED || gTeleportDisplay)
+ if(sNewObjectCreationThrottle < 0 && (LLStartUp::getStartupState() < STATE_STARTED || gTeleportDisplay))
{
- throttle = -1; //cancel the throttling
-
- S32 occlusion = LLPipeline::sUseOcclusion;
- LLPipeline::sUseOcclusion = 0; //disable occlusion
-
//apply octree cullings here to pick up visible objects because rendering pipeline stops view culling at this moment
- mImpl->mVOCachePartition->cull(*LLViewerCamera::getInstance());
-
- LLPipeline::sUseOcclusion = occlusion;
+ 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();
@@ -1227,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)
@@ -1239,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)
{
@@ -1253,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);
}
@@ -1261,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;
}
@@ -1303,6 +1340,16 @@ void LLViewerRegion::killObject(LLVOCacheEntry* entry, std::vector<LLDrawable*>&
LLViewerObject* LLViewerRegion::addNewObject(LLVOCacheEntry* entry)
{
+ if(!entry || !entry->getEntry())
+ {
+ if(entry)
+ {
+ mImpl->mVisibleEntries.erase(entry);
+ entry->setState(LLVOCacheEntry::INACTIVE);
+ }
+ return NULL;
+ }
+
LLViewerObject* obj = NULL;
if(!entry->getEntry()->hasDrawable()) //not added to the rendering pipeline yet
{
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/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index 8cb519b098..06a2dad07f 100755
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -596,7 +596,7 @@ void send_stats()
S32 window_height = gViewerWindow->getWindowHeightRaw();
S32 window_size = (window_width * window_height) / 1024;
misc["string_1"] = llformat("%d", window_size);
- misc["string_2"] = llformat("Texture Time: %.2f, Total Time: %.2f", gTextureTimer.getElapsedTimeF32(), gFrameTimeSeconds.value());
+ misc["string_2"] = llformat("Texture Time: %.2f, Total Time: %.2f", gTextureTimer.getElapsedTimeF32(), gFrameTimeSeconds);
// misc["int_1"] = LLSD::Integer(gSavedSettings.getU32("RenderQualityPerformance")); // Steve: 1.21
// misc["int_2"] = LLSD::Integer(gFrameStalls); // Steve: 1.21
diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp
index 98a924b3be..2576a69f26 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)
@@ -263,6 +264,28 @@ void LLVOCacheEntry::addChild(LLVOCacheEntry* entry)
}
}
+void LLVOCacheEntry::removeChild(LLVOCacheEntry* entry)
+{
+ for(S32 i = 0; i < mChildrenList.size(); i++)
+ {
+ if(mChildrenList[i] == entry)
+ {
+ entry->setParentID(0);
+ mChildrenList[i] = mChildrenList[mChildrenList.size() - 1];
+ mChildrenList.pop_back();
+ }
+ }
+}
+
+void LLVOCacheEntry::removeAllChildren()
+{
+ for(S32 i = 0; i < mChildrenList.size(); i++)
+ {
+ mChildrenList[i]->setParentID(0);
+ }
+ mChildrenList.clear();
+}
+
LLDataPackerBinaryBuffer *LLVOCacheEntry::getDP(U32 crc)
{
if ( (mCRC != crc)
@@ -445,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);
}
@@ -455,6 +484,7 @@ void LLVOCachePartition::addEntry(LLViewerOctreeEntry* entry)
llassert(entry->hasVOCacheEntry());
mOctree->insert(entry);
+ mDirty = TRUE;
}
void LLVOCachePartition::removeEntry(LLViewerOctreeEntry* entry)
@@ -473,7 +503,7 @@ public:
mPartition(part)
{
mLocalShift = shift;
- mUseObjectCacheOcclusion = (use_object_cache_occlusion && LLPipeline::sUseOcclusion);
+ mUseObjectCacheOcclusion = use_object_cache_occlusion;
}
virtual bool earlyFail(LLviewerOctreeGroup* base_group)
@@ -490,9 +520,8 @@ public:
group->checkOcclusion();
- if (group->isOcclusionState(LLSpatialGroup::OCCLUDED))
+ if (group->isOcclusionState(LLOcclusionCullingGroup::OCCLUDED))
{
- mPartition->addOccluders(group);
return true;
}
}
@@ -530,7 +559,32 @@ public:
virtual void processGroup(LLviewerOctreeGroup* base_group)
{
- mRegionp->addVisibleGroup(base_group);
+ if( !mUseObjectCacheOcclusion ||
+ !base_group->getOctreeNode()->getParent())
+ {
+ //no occlusion check
+ mRegionp->addVisibleGroup(base_group);
+ return;
+ }
+
+ LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*)base_group;
+ if(!group->isRecentlyVisible())//needs to issue new occlusion culling check.
+ {
+ mPartition->addOccluders(group);
+ group->setVisible();
+ return ; //wait for occlusion culling result
+ }
+
+ if(group->isOcclusionState(LLOcclusionCullingGroup::QUERY_PENDING) ||
+ group->isOcclusionState(LLOcclusionCullingGroup::ACTIVE_OCCLUSION))
+ {
+ //keep waiting
+ group->setVisible();
+ }
+ else
+ {
+ mRegionp->addVisibleGroup(base_group);
+ }
}
private:
@@ -540,46 +594,52 @@ private:
bool mUseObjectCacheOcclusion;
};
-S32 LLVOCachePartition::cull(LLCamera &camera)
+S32 LLVOCachePartition::cull(LLCamera &camera, bool do_occlusion)
{
static LLCachedControl<bool> use_object_cache_occlusion(gSavedSettings,"UseObjectCacheOcclusion");
-
+
if(!LLViewerRegion::sVOCacheCullingEnabled)
{
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();
camera.calcRegionFrustumPlanes(region_agent);
- mOccludedGroups.clear();
-
- LLVOCacheOctreeCull culler(&camera, mRegionp, region_agent, use_object_cache_occlusion, this);
+ LLVOCacheOctreeCull culler(&camera, mRegionp, region_agent, do_occlusion && use_object_cache_occlusion, this);
culler.traverse(mOctree);
- if(!mOccludedGroups.empty())
+ if(mRegionp->getNumOfVisibleGroups() > 0)
{
- processOccluders(&camera, &region_agent);
- mOccludedGroups.clear();
+ mCullHistory[LLViewerCamera::sCurCameraID] |= 1;
}
- return 0;
+ if(!sNeedsOcclusionCheck)
+ {
+ sNeedsOcclusionCheck = !mOccludedGroups.empty();
+ }
+ return 1;
}
void LLVOCachePartition::addOccluders(LLviewerOctreeGroup* gp)
{
LLOcclusionCullingGroup* group = (LLOcclusionCullingGroup*)gp;
- const U32 MIN_WAIT_TIME = 19; //wait 19 frames to issue a new occlusion request
- U32 last_issued_time = group->getLastOcclusionIssuedTime();
- if(!group->needsUpdate() && gFrameCount > last_issued_time && gFrameCount < last_issued_time + MIN_WAIT_TIME)
- {
- return;
- }
-
if(!group->isOcclusionState(LLOcclusionCullingGroup::ACTIVE_OCCLUSION))
{
group->setOcclusionState(LLOcclusionCullingGroup::ACTIVE_OCCLUSION);
@@ -587,14 +647,36 @@ void LLVOCachePartition::addOccluders(LLviewerOctreeGroup* gp)
}
}
-void LLVOCachePartition::processOccluders(LLCamera* camera, const LLVector3* region_agent)
+void LLVOCachePartition::processOccluders(LLCamera* camera)
+{
+ if(mOccludedGroups.empty())
+ {
+ return;
+ }
+
+ LLVector3 region_agent = mRegionp->getOriginAgent();
+ for(std::set<LLOcclusionCullingGroup*>::iterator iter = mOccludedGroups.begin(); iter != mOccludedGroups.end(); ++iter)
+ {
+ LLOcclusionCullingGroup* group = *iter;
+ group->doOcclusion(camera, &region_agent);
+ }
+}
+
+void LLVOCachePartition::resetOccluders()
{
+ if(mOccludedGroups.empty())
+ {
+ return;
+ }
+
for(std::set<LLOcclusionCullingGroup*>::iterator iter = mOccludedGroups.begin(); iter != mOccludedGroups.end(); ++iter)
{
LLOcclusionCullingGroup* group = *iter;
- group->doOcclusion(camera, region_agent);
group->clearOcclusionState(LLOcclusionCullingGroup::ACTIVE_OCCLUSION);
- }
+ }
+ mOccludedGroups.clear();
+ mDirty = FALSE;
+ sNeedsOcclusionCheck = FALSE;
}
//-------------------------------------------------------------------
diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h
index 816ef88dc4..c448b97b80 100755
--- a/indra/newview/llvocache.h
+++ b/indra/newview/llvocache.h
@@ -107,6 +107,8 @@ public:
U32 getParentID() const {return mParentID;}
void addChild(LLVOCacheEntry* entry);
+ void removeChild(LLVOCacheEntry* entry);
+ void removeAllChildren();
LLVOCacheEntry* getChild(S32 i) {return mChildrenList[i];}
S32 getNumOfChildren() {return mChildrenList.size();}
void clearChildrenList() {mChildrenList.clear();}
@@ -157,15 +159,22 @@ public:
void addEntry(LLViewerOctreeEntry* entry);
void removeEntry(LLViewerOctreeEntry* entry);
- /*virtual*/ S32 cull(LLCamera &camera);
+ /*virtual*/ S32 cull(LLCamera &camera, bool do_occlusion);
void addOccluders(LLviewerOctreeGroup* gp);
+ void resetOccluders();
static LLTrace::MemStatHandle sMemStat;
-private:
- void processOccluders(LLCamera* camera, const LLVector3* region_agent);
+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 101f3b203b..7e4e80240d 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 21cb19b8ec..6754918149 100755
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -2408,6 +2408,11 @@ static LLFastTimer::DeclareTimer FTM_CULL("Object Culling");
void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip, LLPlane* planep)
{
+ static LLCachedControl<bool> use_occlusion(gSavedSettings,"UseOcclusion");
+ static bool can_use_occlusion = LLGLSLShader::sNoFixedFunction
+ && LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion")
+ && gGLManager.mHasOcclusionQuery;
+
LLFastTimer t(FTM_CULL);
grabReferences(result);
@@ -2530,7 +2535,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
LLVOCachePartition* vo_part = region->getVOCachePartition();
if(vo_part)
{
- vo_part->cull(camera);
+ vo_part->cull(camera, can_use_occlusion && use_occlusion && !gUseWireframe);
}
}
@@ -2719,7 +2724,7 @@ void LLPipeline::doOcclusion(LLCamera& camera, LLRenderTarget& source, LLRenderT
void LLPipeline::doOcclusion(LLCamera& camera)
{
- if (LLPipeline::sUseOcclusion > 1 && sCull->hasOcclusionGroups())
+ if (LLPipeline::sUseOcclusion > 1 && (sCull->hasOcclusionGroups() || LLVOCachePartition::sNeedsOcclusionCheck))
{
LLVertexBuffer::unbind();
@@ -2765,6 +2770,17 @@ void LLPipeline::doOcclusion(LLCamera& camera)
group->clearOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION);
}
+ //apply occlusion culling to object cache tree
+ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
+ iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
+ {
+ LLVOCachePartition* vo_part = (*iter)->getVOCachePartition();
+ if(vo_part)
+ {
+ vo_part->processOccluders(&camera);
+ }
+ }
+
if (bind_shader)
{
if (LLPipeline::sShadowRender)
@@ -6119,6 +6135,13 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
}
}
+ //mark nearby lights not-removable.
+ for (light_set_t::iterator iter = mNearbyLights.begin();
+ iter != mNearbyLights.end(); iter++)
+ {
+ const Light* light = &(*iter);
+ ((LLViewerOctreeEntryData*) light->drawable)->setVisible();
+ }
}
}