summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXiaohong Bao <bao@lindenlab.com>2013-08-05 14:48:26 -0600
committerXiaohong Bao <bao@lindenlab.com>2013-08-05 14:48:26 -0600
commit576b9339977f50edb11a799d7a274610263f9fdc (patch)
tree873dbceba5d12cd23736b599ee76b87eaa9d247e
parent3059b59b619123caf5cc3137ab0b983c28a2962b (diff)
fix for SH-4397: Object cache occlusion culling results are not always correct
-rwxr-xr-xindra/newview/llspatialpartition.cpp6
-rwxr-xr-xindra/newview/llspatialpartition.h1
-rw-r--r--indra/newview/llvieweroctree.cpp6
-rw-r--r--indra/newview/llvieweroctree.h7
-rwxr-xr-xindra/newview/llviewerregion.cpp3
-rwxr-xr-xindra/newview/llvocache.cpp63
-rwxr-xr-xindra/newview/llvocache.h5
-rwxr-xr-xindra/newview/pipeline.cpp13
8 files changed, 71 insertions, 33 deletions
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index ad659baa9e..a5045e6a4c 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);
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index 05ed70ab59..6202fb11cb 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);
diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp
index bba3d26e09..9b8a3c9269 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..7c85231ce0 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);
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index c55ccce47a..47e59d3c00 100755
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1183,6 +1183,9 @@ BOOL LLViewerRegion::idleUpdate(F32 max_update_time)
}
max_update_time -= update_timer.getElapsedTimeF32();
+
+ //reset all occluders
+ mImpl->mVOCachePartition->resetOccluders();
//update the throttling number
static S32 throttle = new_object_creation_throttle;
diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp
index d1c27edce7..9beb81bcdd 100755
--- a/indra/newview/llvocache.cpp
+++ b/indra/newview/llvocache.cpp
@@ -490,9 +490,8 @@ public:
group->checkOcclusion();
- if (group->isOcclusionState(LLSpatialGroup::OCCLUDED))
+ if (group->isOcclusionState(LLOcclusionCullingGroup::OCCLUDED))
{
- mPartition->addOccluders(group);
return true;
}
}
@@ -530,7 +529,24 @@ public:
virtual void processGroup(LLviewerOctreeGroup* base_group)
{
- mRegionp->addVisibleGroup(base_group);
+ 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:
@@ -555,17 +571,9 @@ S32 LLVOCachePartition::cull(LLCamera &camera)
LLVector3 region_agent = mRegionp->getOriginAgent();
camera.calcRegionFrustumPlanes(region_agent);
- mOccludedGroups.clear();
-
LLVOCacheOctreeCull culler(&camera, mRegionp, region_agent, use_object_cache_occlusion, this);
culler.traverse(mOctree);
- if(!mOccludedGroups.empty())
- {
- processOccluders(&camera, &region_agent);
- mOccludedGroups.clear();
- }
-
return 0;
}
@@ -573,13 +581,6 @@ 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 +588,34 @@ 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);
- group->clearOcclusionState(LLOcclusionCullingGroup::ACTIVE_OCCLUSION);
+ 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->clearOcclusionState(LLOcclusionCullingGroup::ACTIVE_OCCLUSION);
+ }
+ mOccludedGroups.clear();
}
//-------------------------------------------------------------------
diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h
index 816ef88dc4..7de8185315 100755
--- a/indra/newview/llvocache.h
+++ b/indra/newview/llvocache.h
@@ -159,11 +159,12 @@ public:
void removeEntry(LLViewerOctreeEntry* entry);
/*virtual*/ S32 cull(LLCamera &camera);
void addOccluders(LLviewerOctreeGroup* gp);
+ void resetOccluders();
static LLTrace::MemStatHandle sMemStat;
-private:
- void processOccluders(LLCamera* camera, const LLVector3* region_agent);
+public:
+ void processOccluders(LLCamera* camera);
private:
std::set<LLOcclusionCullingGroup*> mOccludedGroups;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 1d9137c161..1696f1962c 100755
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -2719,7 +2719,7 @@ void LLPipeline::doOcclusion(LLCamera& camera, LLRenderTarget& source, LLRenderT
void LLPipeline::doOcclusion(LLCamera& camera)
{
- if (LLPipeline::sUseOcclusion > 1 && sCull->hasOcclusionGroups())
+ if (LLPipeline::sUseOcclusion > 1)
{
LLVertexBuffer::unbind();
@@ -2765,6 +2765,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)