From 576b9339977f50edb11a799d7a274610263f9fdc Mon Sep 17 00:00:00 2001 From: Xiaohong Bao Date: Mon, 5 Aug 2013 14:48:26 -0600 Subject: fix for SH-4397: Object cache occlusion culling results are not always correct --- indra/newview/llspatialpartition.cpp | 6 ---- indra/newview/llspatialpartition.h | 1 - indra/newview/llvieweroctree.cpp | 6 ++++ indra/newview/llvieweroctree.h | 7 ++-- indra/newview/llviewerregion.cpp | 3 ++ indra/newview/llvocache.cpp | 63 ++++++++++++++++++++++++------------ indra/newview/llvocache.h | 5 +-- indra/newview/pipeline.cpp | 13 +++++++- 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, ®ion_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::iterator iter = mOccludedGroups.begin(); iter != mOccludedGroups.end(); ++iter) { LLOcclusionCullingGroup* group = *iter; - group->doOcclusion(camera, region_agent); - group->clearOcclusionState(LLOcclusionCullingGroup::ACTIVE_OCCLUSION); + group->doOcclusion(camera, ®ion_agent); + } +} + +void LLVOCachePartition::resetOccluders() +{ + if(mOccludedGroups.empty()) + { + return; } + + for(std::set::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 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) -- cgit v1.2.3