diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index ad659baa9e9f7861143053c1f64a2d7711b12a91..a5045e6a4c094980cb8063352e59ded51995a624 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 05ed70ab59eabf9b1ccbfa68e07cfefa8005628c..6202fb11cbf28060eb4e3f0de0e2d8d3478e3ccf 100755 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -290,7 +290,6 @@ class LLSpatialGroup : public LLOcclusionCullingGroup 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 bba3d26e09e3f4bd7d1e158709b16dc0d9262203..9b8a3c92699af9508a3aa9f9dedd9ce3fff9acd5 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 980a67367c1ff5cfda400ec40c711ec2aa27542e..7c85231ce0d573aa27497acea6378351ad7ec80c 100644 --- a/indra/newview/llvieweroctree.h +++ b/indra/newview/llvieweroctree.h @@ -317,14 +317,17 @@ class LLOcclusionCullingGroup : public LLviewerOctreeGroup 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 c55ccce47af032984703308c3f2a40a3461c3f36..47e59d3c00ee1169e928e09ba5da25f4fff85da6 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 d1c27edce728c747ba3835a77cc39afb28348894..9beb81bcddb0918b2d53f1cb3aa9c6e7e91ee194 100755 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -490,9 +490,8 @@ class LLVOCacheOctreeCull : public LLViewerOctreeCull group->checkOcclusion(); - if (group->isOcclusionState(LLSpatialGroup::OCCLUDED)) + if (group->isOcclusionState(LLOcclusionCullingGroup::OCCLUDED)) { - mPartition->addOccluders(group); return true; } } @@ -530,7 +529,24 @@ class LLVOCacheOctreeCull : public LLViewerOctreeCull 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<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, ®ion_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 816ef88dc4207bd3054dbe272cec42093775f64e..7de8185315409da7f44b58c5ff4f47e375a8cabc 100755 --- a/indra/newview/llvocache.h +++ b/indra/newview/llvocache.h @@ -159,11 +159,12 @@ class LLVOCachePartition : public LLViewerOctreePartition, public LLTrace::MemTr 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 1d9137c1610da904ebf8749ca710f1e77387cb9c..1696f1962c3cf336a39f120fa084525a59c12726 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)